Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tools: Enable Unit Testing for SITL #18404

Merged
merged 8 commits into from
Sep 27, 2021
Merged
28 changes: 15 additions & 13 deletions Tools/autotest/autotest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
15 changes: 14 additions & 1 deletion libraries/AP_Common/tests/test_bitmask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -87,4 +99,5 @@ TEST(Bitmask, Assignment)
EXPECT_EQ(true, y.get(48));
}

AP_GTEST_PANIC()
AP_GTEST_MAIN()
2 changes: 1 addition & 1 deletion libraries/AP_HAL_Linux/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion libraries/AP_HAL_SITL/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
80 changes: 44 additions & 36 deletions libraries/AP_InternalError/AP_InternalError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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<ARRAY_SIZE(error_bit_descriptions); i++) {
Expand Down
3 changes: 3 additions & 0 deletions libraries/AP_InternalError/AP_InternalError.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class AP_InternalError {
// internal errors. buffer will always be null-terminated.
void errors_as_string(uint8_t *buffer, uint16_t len) const;

// convert an error code to a string
void error_to_string(char *buffer, uint16_t len, error_t error_code) const;

uint32_t count() const { return total_error_count; }

// internal_errors - return mask of internal errors seen
Expand Down
15 changes: 14 additions & 1 deletion libraries/AP_Math/tests/test_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,15 @@ TEST(VectorTest, Rotations)
TEST_ROTATION(ROTATION_ROLL_45, 1, 0, SQRT_2);
TEST_ROTATION(ROTATION_ROLL_315, 1, SQRT_2, 0);
EXPECT_EQ(ROTATION_MAX, rotation_count) << "All rotations are expect to be tested";
TEST_ROTATION(ROTATION_CUSTOM, 1, 1, 1); // TODO look at internal error ?

#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
TEST_ROTATION(ROTATION_CUSTOM, 1, 1, 1);
TEST_ROTATION(ROTATION_MAX, 1, 1, 1);
#elif CONFIG_HAL_BOARD == HAL_BOARD_SITL
Vector3F v {1, 1, 1};
EXPECT_EXIT(v.rotate(ROTATION_CUSTOM), testing::KilledBySignal(SIGABRT), "AP_InternalError::error_t::flow_of_ctrl");
EXPECT_EXIT(v.rotate(ROTATION_MAX), testing::KilledBySignal(SIGABRT), "AP_InternalError::error_t::bad_rotation");
#endif
}

TEST(MathTest, IsZero)
Expand Down Expand Up @@ -370,8 +377,13 @@ TEST(MathTest, Constrain)
EXPECT_EQ(19.9, constrain_value(19.8, 19.9, 20.1));
EXPECT_EQ(19.9f, constrain_value(19.8f, 19.9f, 20.1f));

#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
EXPECT_EQ(1.0f, constrain_float(nanf("0x4152"), 1.0f, 1.0f));
EXPECT_EQ(1.0f, constrain_value(nanf("0x4152"), 1.0f, 1.0f));
#elif CONFIG_HAL_BOARD == HAL_BOARD_SITL
EXPECT_EXIT(constrain_float(nanf("0x4152"), 1.0f, 1.0f), testing::KilledBySignal(SIGABRT), "AP_InternalError::error_t::cnstring_nan");
EXPECT_EXIT(constrain_value(nanf("0x4152"), 1.0f, 1.0f), testing::KilledBySignal(SIGABRT), "AP_InternalError::error_t::cnstring_nan");
#endif
}

TEST(MathWrapTest, Angle180)
Expand Down Expand Up @@ -660,6 +672,7 @@ TEST(MathTest, FIXEDWINGTURNRATE)
EXPECT_NEAR(56.187965393066406f, fixedwing_turn_rate(45, 10.0f), accuracy);
}

AP_GTEST_PANIC()
AP_GTEST_MAIN()

#pragma GCC diagnostic pop
5 changes: 5 additions & 0 deletions libraries/AP_Math/tests/test_math_double.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ TEST(MathTest, ConstrainDouble)

EXPECT_EQ(19.9, constrain_value(19.8, 19.9, 20.1));

#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
EXPECT_EQ(1.0, constrain_value(nan("0x4152"), 1.0, 1.0));
#elif CONFIG_HAL_BOARD == HAL_BOARD_SITL
EXPECT_EXIT(constrain_value(nan("0x4152"), 1.0, 1.0), testing::KilledBySignal(SIGABRT), "AP_InternalError::error_t::cnstring_nan");
#endif
}

TEST(MathWrapTest, Angle180Double)
Expand Down Expand Up @@ -232,6 +236,7 @@ TEST(MathTest, NormDouble)
EXPECT_DOUBLE_EQ(norm_6, 13.0);
}

AP_GTEST_PANIC()
AP_GTEST_MAIN()

#pragma GCC diagnostic pop
4 changes: 2 additions & 2 deletions libraries/SITL/tests/test_sim_ms5611.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const struct forward_check {
float P_Pa;
float Temp_C;
} conversion_table [] = {
{3897939, 7529942, 1200, -20}, // < -15 deg C Temperature, Low Pressure
{10398464, 7529942, 115200, -20}, // < -15 deg C Temperatures, High Pressure
{3894332, 7304992, 1200, -30}, // < -15 deg C Temperature, Low Pressure
{10566581, 7304992, 115200, -30}, // < -15 deg C Temperatures, High Pressure

{3919542, 8425824, 1200, 15.15}, // < 20 deg C Temperatures, Low Pressure
{9937566, 8425824, 115200, 15.15}, // < 20 deg C Temperatures, High Pressure
Expand Down
22 changes: 22 additions & 0 deletions tests/AP_gtest.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

#include <gtest/gtest.h>
#include <gtest/gtest-spi.h>


#define AP_GTEST_PRINTATBLE_PARAM_MEMBER(class_name_, printable_member_) \
Expand All @@ -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[]) \
{ \
Expand Down