diff --git a/Tools/autotest/autotest.py b/Tools/autotest/autotest.py index 676747bfb77e6..97d71b66e48d1 100755 --- a/Tools/autotest/autotest.py +++ b/Tools/autotest/autotest.py @@ -143,7 +143,7 @@ def build_examples(**kwargs): def build_unit_tests(**kwargs): """Build tests.""" - for target in ['linux']: + for target in ['linux', 'sitl']: print("Running build.unit_tests for %s" % target) try: util.build_tests(target, **kwargs) @@ -163,20 +163,22 @@ def run_unit_test(test): def run_unit_tests(): """Run all unit tests files.""" - binary_dir = util.reltopdir(os.path.join('build', - 'linux', - 'tests', - )) - tests = glob.glob("%s/*" % binary_dir) success = True fail_list = [] - for test in tests: - try: - run_unit_test(test) - except subprocess.CalledProcessError: - print("Exception running (%s)" % test) - fail_list.append(os.path.basename(test)) - success = False + for target in ['linux', 'sitl']: + binary_dir = util.reltopdir(os.path.join('build', + target, + 'tests', + )) + tests = glob.glob("%s/*" % binary_dir) + for test in tests: + try: + run_unit_test(test) + except subprocess.CalledProcessError: + print("Exception running (%s)" % test) + fail_list.append(target + '/' + os.path.basename(test)) + success = False + print("Failing tests:") for failure in fail_list: print(" %s" % failure) diff --git a/libraries/AP_Common/tests/test_bitmask.cpp b/libraries/AP_Common/tests/test_bitmask.cpp index 334e177015568..525ab9dd660fd 100644 --- a/libraries/AP_Common/tests/test_bitmask.cpp +++ b/libraries/AP_Common/tests/test_bitmask.cpp @@ -45,10 +45,22 @@ TEST(Bitmask, Tests) Bitmask<49> x2; x2 = x; + +#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX x.set(50); - for (uint8_t i=0; i<50; i++) { +#elif CONFIG_HAL_BOARD == HAL_BOARD_SITL + EXPECT_EXIT(x.set(50), testing::KilledBySignal(SIGABRT), "AP_InternalError::error_t::bitmask_range"); +#endif + + for (uint8_t i=0; i<49; i++) { EXPECT_EQ(x2.get(i), x.get(i)); } + +#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX + EXPECT_EQ(x2.get(50), x.get(50)); +#elif CONFIG_HAL_BOARD == HAL_BOARD_SITL + EXPECT_EXIT(x2.get(50), testing::KilledBySignal(SIGABRT), "AP_InternalError::error_t::bitmask_range"); +#endif } TEST(Bitmask, SetAll) @@ -87,4 +99,5 @@ TEST(Bitmask, Assignment) EXPECT_EQ(true, y.get(48)); } +AP_GTEST_PANIC() AP_GTEST_MAIN() diff --git a/libraries/AP_HAL_Linux/system.cpp b/libraries/AP_HAL_Linux/system.cpp index d649cdaf4c6a5..faa42d49ffb0d 100644 --- a/libraries/AP_HAL_Linux/system.cpp +++ b/libraries/AP_HAL_Linux/system.cpp @@ -21,7 +21,7 @@ void init() clock_gettime(CLOCK_MONOTONIC, &state.start_time); } -void panic(const char *errormsg, ...) +void WEAK panic(const char *errormsg, ...) { va_list ap; diff --git a/libraries/AP_HAL_SITL/system.cpp b/libraries/AP_HAL_SITL/system.cpp index 4cf62433fc45b..7113d6a26f94a 100644 --- a/libraries/AP_HAL_SITL/system.cpp +++ b/libraries/AP_HAL_SITL/system.cpp @@ -25,7 +25,7 @@ void init() gettimeofday(&state.start_time, nullptr); } -void panic(const char *errormsg, ...) +void WEAK panic(const char *errormsg, ...) { va_list ap; diff --git a/libraries/AP_InternalError/AP_InternalError.cpp b/libraries/AP_InternalError/AP_InternalError.cpp index 525d03ecb7f2b..6d8bf2968b50d 100644 --- a/libraries/AP_InternalError/AP_InternalError.cpp +++ b/libraries/AP_InternalError/AP_InternalError.cpp @@ -17,7 +17,9 @@ void AP_InternalError::error(const AP_InternalError::error_t e, uint16_t line) { // don't panic on these to facilitate watchdog testing break; default: - AP_HAL::panic("internal error %u", unsigned(e)); + char buffer[50]; + AP::internalerror().error_to_string(buffer, ARRAY_SIZE(buffer), e); + AP_HAL::panic("AP_InternalError::error_t::%s", buffer); } #endif internal_errors |= uint32_t(e); @@ -29,43 +31,49 @@ void AP_InternalError::error(const AP_InternalError::error_t e, uint16_t line) { hal.util->persistent_data.internal_error_last_line = line; } -void AP_InternalError::errors_as_string(uint8_t *buffer, const uint16_t len) const -{ - static const char * const error_bit_descriptions[] { - "mapfailure", // logger_mapfailure - "miss_struct", // logger_missing_logstructure - "write_mssfmt", // logger_logwrite_missingfmt - "many_deletes", // logger_too_many_deletions - "bad_getfile", // logger_bad_getfilename - "panic", - "flush_no_sem", // logger_flushing_without_sem - "bad_curr_blk", // logger_bad_current_block - "blkcnt_bad", // logger_blockcount_mismatch - "dq_failure", // logger_dequeue_failure - "cnstring_nan", // constraining_nan - "watchdog_rst", // watchdog_reset - "iomcu_reset", - "iomcu_fail", - "spi_fail", - "main_loop_stk", // main_loop_stuck - "gcs_bad_link", // gcs_bad_missionprotocol_link - "bitmask_range", - "gcs_offset", - "i2c_isr", - "flow_of_ctrl", // flow_of_control - "sfs_recursion", // switch_full_sector_recursion - "bad_rotation", - "stack_ovrflw", // stack_overflow - "imu_reset", // imu_reset - "gpio_isr", - "mem_guard", - "dma_fail", - "params_restored", - "invalid arguments", - }; +static const char * const error_bit_descriptions[] { + "mapfailure", // logger_mapfailure + "miss_struct", // logger_missing_logstructure + "write_mssfmt", // logger_logwrite_missingfmt + "many_deletes", // logger_too_many_deletions + "bad_getfile", // logger_bad_getfilename + "panic", + "flush_no_sem", // logger_flushing_without_sem + "bad_curr_blk", // logger_bad_current_block + "blkcnt_bad", // logger_blockcount_mismatch + "dq_failure", // logger_dequeue_failure + "cnstring_nan", // constraining_nan + "watchdog_rst", // watchdog_reset + "iomcu_reset", + "iomcu_fail", + "spi_fail", + "main_loop_stk", // main_loop_stuck + "gcs_bad_link", // gcs_bad_missionprotocol_link + "bitmask_range", + "gcs_offset", + "i2c_isr", + "flow_of_ctrl", // flow_of_control + "sfs_recursion", // switch_full_sector_recursion + "bad_rotation", + "stack_ovrflw", // stack_overflow + "imu_reset", // imu_reset + "gpio_isr", + "mem_guard", + "dma_fail", + "params_restored", + "invalid arguments", +}; + +static_assert((1U<<(ARRAY_SIZE(error_bit_descriptions))) == uint32_t(AP_InternalError::error_t::__LAST__), "too few descriptions for bits"); - static_assert((1U<<(ARRAY_SIZE(error_bit_descriptions))) == uint32_t(AP_InternalError::error_t::__LAST__), "too few descriptions for bits"); +void AP_InternalError::error_to_string(char *buffer, const uint16_t len, error_t error_code) const +{ + uint32_t temp = log2f(int(error_code)); + strncpy(buffer, error_bit_descriptions[temp], len - 1); +} +void AP_InternalError::errors_as_string(uint8_t *buffer, const uint16_t len) const +{ buffer[0] = 0; uint32_t buffer_used = 0; for (uint8_t i=0; i +#include #define AP_GTEST_PRINTATBLE_PARAM_MEMBER(class_name_, printable_member_) \ @@ -14,6 +15,27 @@ ::std::ostream& operator<<(::std::ostream& os, const class_name_& param) \ return os << param.printable_member_; \ } +/* +* Override the WEAK version of AP_HAL_SITL/system.cpp panic() instead of staying in an infinite loop +* This is used by the gtest suite to test for an exit signal caused by a test statement and continue testing +* Printing to stderr is required for gtest matching +*/ +#define AP_GTEST_PANIC() \ +void AP_HAL::panic(const char *errormsg, ...) \ +{ \ + va_list ap; \ + auto outputs = {stdout, stderr}; \ + for( auto output : outputs) { \ + fflush(stdout); \ + fprintf(output, "PANIC: "); \ + va_start(ap, errormsg); \ + vfprintf(output, errormsg, ap); \ + va_end(ap); \ + fprintf(output, "\n"); \ + } \ + abort(); \ +} + #define AP_GTEST_MAIN() \ int main(int argc, char *argv[]) \ { \