From 46aecf2338e92a93f8012d0e26869a382e568497 Mon Sep 17 00:00:00 2001 From: Eyal Gerber Date: Sun, 18 Dec 2022 10:37:09 +0200 Subject: [PATCH 1/3] Modified simpletest so that it would build successfully with ARM compiler V6.16 and V6.6.4 using ARM FuSa library --- simpletest.cpp | 233 ++++++++++++------------------------------------- simpletest.h | 121 ++++++++++--------------- 2 files changed, 104 insertions(+), 250 deletions(-) diff --git a/simpletest.cpp b/simpletest.cpp index 85abbb4..245f771 100644 --- a/simpletest.cpp +++ b/simpletest.cpp @@ -1,20 +1,53 @@ #include "simpletest.h" -#include -#include -#include -#include -#include +#ifdef __cplusplus + extern "C" { + #include + #include + #include + } ; +#endif // __cplusplus + +extern "C" void __cxa_pure_virtual() { while (1); } // added to support setting virtual functions as pure (by adding ' = 0 ' at the end of their declaration. + //--------------------------------------------------------------------------------- // statics //--------------------------------------------------------------------------------- -void DefaultPrint(char const* string) { printf("%s", string); } +void DefaultPrint(char const* string) { printf("%s", string); } // switch printf with any other printing solution you want. TestFixture* TestFixture::ourFirstTest; TestFixture* TestFixture::ourLastTest; -thread_local TestFixture* TestFixture::ourCurrentTest; +//thread_local TestFixture* TestFixture::ourCurrentTest; +TestFixture* TestFixture::ourCurrentTest; void (*TestFixture::Print)(char const* string) = DefaultPrint; +//--------------------------------------------------------------------------------- +// helper to get the number of decimal places to print for floats and doubles +//--------------------------------------------------------------------------------- +template +static int locDecimals(T value) +{ + const T eps = 0.00001f; + T remainder = value - (int)value; + if (remainder == 0) + return 0; + + int decimals = 0; + + // add decimals until hitting the first non-zero number that shouldn't be rounded (close to 0 or 1) + bool hitsomething = int(remainder * 10) != 0; + while (!hitsomething || + ((remainder > eps && remainder < (1 - eps)) || + (remainder < -eps && remainder >(-1 + eps)))) + { + remainder = remainder * 10; + remainder = remainder - (int)remainder; + hitsomething |= int(remainder * 10) != 0; + ++decimals; + } + return decimals; +} + //--------------------------------------------------------------------------------- // Standard type printers //--------------------------------------------------------------------------------- @@ -33,67 +66,37 @@ TempString::TempString(const TempString& other) TempString TypeToString(int value) { TempString tempString; - if (TestFixture::GetCurrentTest()->GetPrintMethod() == TestFixture::PrintHexadecimal) - snprintf(tempString.myTextBuffer, STRING_LENGTH, "0x%08X", value); - else - snprintf(tempString.myTextBuffer, STRING_LENGTH, "%d", value); - return tempString; -} -TempString TypeToString(unsigned int value) -{ - TempString tempString; - if (TestFixture::GetCurrentTest()->GetPrintMethod() == TestFixture::PrintHexadecimal) - snprintf(tempString.myTextBuffer, STRING_LENGTH, "0x%08X", value); - else - snprintf(tempString.myTextBuffer, STRING_LENGTH, "%u", value); - return tempString; -} -TempString TypeToString(long value) -{ - TempString tempString; - if (TestFixture::GetCurrentTest()->GetPrintMethod() == TestFixture::PrintHexadecimal) - snprintf(tempString.myTextBuffer, STRING_LENGTH, "0x%016lX", value); - else - snprintf(tempString.myTextBuffer, STRING_LENGTH, "%ld", value); + sprintf(tempString.myTextBuffer, "%d", value); return tempString; } -TempString TypeToString(unsigned long value) +TempString TypeToString(int64 value) { TempString tempString; - if (TestFixture::GetCurrentTest()->GetPrintMethod() == TestFixture::PrintHexadecimal) - snprintf(tempString.myTextBuffer, STRING_LENGTH, "0x%016lX", value); - else - snprintf(tempString.myTextBuffer, STRING_LENGTH, "%lu", value); + sprintf(tempString.myTextBuffer, "%lld", value); return tempString; } -TempString TypeToString(long long value) +TempString TypeToString(uint value) { TempString tempString; - if (TestFixture::GetCurrentTest()->GetPrintMethod() == TestFixture::PrintHexadecimal) - snprintf(tempString.myTextBuffer, STRING_LENGTH, "0x%016llX", value); - else - snprintf(tempString.myTextBuffer, STRING_LENGTH, "%lld", value); + sprintf(tempString.myTextBuffer, "%u", value); return tempString; } -TempString TypeToString(unsigned long long value) +TempString TypeToString(uint64 value) { TempString tempString; - if (TestFixture::GetCurrentTest()->GetPrintMethod() == TestFixture::PrintHexadecimal) - snprintf(tempString.myTextBuffer, STRING_LENGTH, "0x%016llX", value); - else - snprintf(tempString.myTextBuffer, STRING_LENGTH, "%llu", value); + sprintf(tempString.myTextBuffer, "%llu", value); return tempString; } TempString TypeToString(float value) { TempString tempString; - snprintf(tempString.myTextBuffer, STRING_LENGTH, "%.16g", value); + sprintf(tempString.myTextBuffer, "%0.*f", locDecimals(value), value); return tempString; } TempString TypeToString(double value) { TempString tempString; - snprintf(tempString.myTextBuffer, STRING_LENGTH, "%.16g", value); + sprintf(tempString.myTextBuffer, "%0.*f", locDecimals(value), value); return tempString; } TempString TypeToString(bool value) @@ -109,15 +112,7 @@ TempString TypeToString(void const* value) if (value == nullptr) return TempString("(nullptr)"); TempString tempString; - snprintf(tempString.myTextBuffer, STRING_LENGTH, "0x%p", value); - return tempString; -} -TempString TypeToString(void const* value, char const* extra) -{ - if (value == nullptr) - return TempString("(nullptr)"); - TempString tempString; - snprintf(tempString.myTextBuffer, STRING_LENGTH, "(0x%p) %s", value, extra); + sprintf(tempString.myTextBuffer, "0x%p", value); return tempString; } @@ -126,10 +121,9 @@ TempString TypeToString(void const* value, char const* extra) //--------------------------------------------------------------------------------- TestFixture::TestFixture() : myNextTest(nullptr) - , myNextError(nullptr) , myNumTestsChecked(0) , myNumErrors(0) - , myPrintMethod(PrintDefault) + , myNextError(nullptr) { // global link list registration, add in order of discovery if (ourFirstTest == nullptr) @@ -143,121 +137,14 @@ TestFixture::TestFixture() ourLastTest = this; } } -//--------------------------------------------------------------------------------- -bool TestFixture::ExecuteTest() -{ - myNumTestsChecked = myNumErrors = 0; - myNextError = (TestError*)myMessageSpace; - - TestFixture* lastCurrent = ourCurrentTest; - ourCurrentTest = this; - Setup(); - RunTest(); - TearDown(); - ourCurrentTest = lastCurrent; - - return myNumErrors == 0; -} -//--------------------------------------------------------------------------------- -// Utility to print a part of a string to show where the error is and put elipse -// where the string is truncated -//--------------------------------------------------------------------------------- -static void locCopyStringWithElipse(char dest[STRING_EQ_PRINT_LENGTH], char const* string, size_t offset = 0) -{ - char const* start = string + offset - STRING_EQ_PRINT_LENGTH / 2; - if (start < string) - start = string; - - int i = 0; - for (; i < STRING_EQ_PRINT_LENGTH - 1 && start[i]; ++i) - { - if (i < 3 && start > string) - dest[i] = '.'; - else if (start[i] == '\r' || start[i] == '\n' || start[i] == '\t') - dest[i] = '\\'; // simply replace this with '\', we're just aiming for a general idea not an exact representation - else - dest[i] = start[i]; - } - - dest[i] = 0; - - if (i == STRING_EQ_PRINT_LENGTH - 1 && start[i]) - { - dest[i - 1] = '.'; - dest[i - 2] = '.'; - dest[i - 3] = '.'; - } -} -//--------------------------------------------------------------------------------- -// Instead of just check for error and printing the string, try go be smart about -// how the information is written out: -// ... quick brown fox jumps over ... -// ^ -// ... quick brown fox jamps over ... -//--------------------------------------------------------------------------------- -bool TestFixture::TestStrings(char const* left, char const* right, char const* prefix, char const* condition) -{ - AddTest(); - if (left == right) - { - return true; - } - - char leftLine[STRING_EQ_PRINT_LENGTH]; - char rightLine[STRING_EQ_PRINT_LENGTH]; - char locationLine[STRING_EQ_PRINT_LENGTH]; - - if (left == nullptr || right == nullptr) - { - locationLine[0] = '^'; - locationLine[1] = 0; - if (left == nullptr) - { - strcpy(leftLine, "nullptr"); - locCopyStringWithElipse(rightLine, right); - } - else - { - locCopyStringWithElipse(leftLine, left); - strcpy(rightLine, "nullptr"); - } - } - else - { - char const* testLeft = left; - char const* testRight = right; - - int offset = 0; - for (; *testLeft && *testRight; ++offset, ++testLeft, ++testRight) - { - if (*testLeft != *testRight) - break; - } - - // reached the end of both strings, so they're the same - if (!*testLeft && !*testRight) - return true; - - locCopyStringWithElipse(leftLine, left, offset); - locCopyStringWithElipse(rightLine, right, offset); - - if (offset > STRING_EQ_PRINT_LENGTH / 2) - offset = STRING_EQ_PRINT_LENGTH / 2; - memset(locationLine, ' ', offset); - locationLine[offset] = '^'; - locationLine[offset + 1] = 0; - } - - AddError(); - LogMessage(prefix, condition, leftLine, locationLine, rightLine); - return false; -} //--------------------------------------------------------------------------------- // Write error into current error object and advance pointer if there's still enough space //--------------------------------------------------------------------------------- -void TestFixture::LogMessage(char const* string, ...) +void TestFixture::LogError(char const* string, ...) { + ++myNumErrors; + uintptr_t spaceLeft = (myMessageSpace + MESSAGE_SPACE) - (char*)myNextError; if (spaceLeft == 0) @@ -302,20 +189,13 @@ TestFixture const* TestFixture::LinkTest(TestFixture* test) //--------------------------------------------------------------------------------- static bool locExecuteTest(TestFixture* test, TestFixture::OutputMode output) { - clock_t start = 0; if (output == TestFixture::Verbose) - { TestFixture::Printf("Running [%s/%s]", test->TestGroup(), test->TestName()); - start = clock(); - } if (test->ExecuteTest()) { if (output == TestFixture::Verbose) - { - clock_t end = clock(); - TestFixture::Printf(": Passed %d out of %d tests in %g seconds\n", test->NumTests(), test->NumTests(), float(end - start) / (float)CLOCKS_PER_SEC); - } + TestFixture::Printf(": Passed %d out of %d tests\n", test->NumTests(), test->NumTests()); return true; } @@ -334,9 +214,10 @@ static bool locExecuteTest(TestFixture* test, TestFixture::OutputMode output) return false; } + void TestFixture::Printf(char const* string, ...) { - char tempSpace[4096]; + char tempSpace[100]; va_list args; va_start(args, string); diff --git a/simpletest.h b/simpletest.h index 4659561..96cc015 100644 --- a/simpletest.h +++ b/simpletest.h @@ -1,23 +1,25 @@ -#pragma once +//#pragma once +#ifndef _SIMPLETEST_H_ +#define _SIMPLETEST_H_ + //--------------------------------------------------------------------------------- // Config //--------------------------------------------------------------------------------- #if !defined(MESSAGE_SPACE) -#define MESSAGE_SPACE 10 * 1024 // default 10k of message space is reserved per test +//#define MESSAGE_SPACE 10 * 1024 // default 10k of message space is reserved per test +#define MESSAGE_SPACE 100 // default 100 bytes of message space is reserved per test #endif #if !defined(STRING_LENGTH) #define STRING_LENGTH 64 // size of temp strings for converting types #endif -#if !defined(STRING_EQ_PRINT_LENGTH) -#define STRING_EQ_PRINT_LENGTH 80 // max line length to show when comparing two strings -#endif #if !defined(BASE_FIXTURE) #define BASE_FIXTURE TestFixture // use TestFixture as the test base class by default #endif -#if !defined(ERROR_ACTION) -#define ERROR_ACTION // Defined any code to run on error. You can use this to debug break or do anything really -#endif + +typedef long long int64; +typedef unsigned int uint; +typedef unsigned long long uint64; //--------------------------------------------------------------------------------- // Link list of errors build into MESSAGE_SPACE @@ -34,7 +36,7 @@ struct TestError //--------------------------------------------------------------------------------- struct TempString { - TempString() : myTextPointer(myTextBuffer) { myTextBuffer[0] = 0; } + TempString() : myTextPointer(myTextBuffer) {} TempString(const TempString& other); TempString(char const* string) : myTextPointer(string) {} @@ -45,41 +47,27 @@ struct TempString }; TempString TypeToString(int value); -TempString TypeToString(unsigned int value); -TempString TypeToString(long value); -TempString TypeToString(unsigned long value); -TempString TypeToString(long long value); -TempString TypeToString(unsigned long long value); +TempString TypeToString(int64 value); +TempString TypeToString(uint value); +TempString TypeToString(uint64 value); TempString TypeToString(float value); TempString TypeToString(double value); TempString TypeToString(bool value); TempString TypeToString(char const* value); TempString TypeToString(void const* value); -TempString TypeToString(void const* value, char const* extra); -inline TempString TypeToString(char value) { return TypeToString((int)value); } -inline TempString TypeToString(unsigned char value) { return TypeToString((unsigned int)value); } -inline TempString TypeToString(short value) { return TypeToString((int)value); } -inline TempString TypeToString(unsigned short value) { return TypeToString((unsigned int)value); } inline TempString TypeToString(char* value) { return TypeToString((char const*)value); } inline TempString TypeToString(void* value) { return TypeToString((void const*)value); } // if nothing specified then print some memory template -TempString TypeToString(T const&) { return TempString(); } +TempString TypeToString(T const&) { return TempString("(unknown type)"); } template -TempString TypeToString(T const* pointer) -{ - return pointer == nullptr ? - TypeToString((void const*)pointer) : - TypeToString((void const*)pointer, *TypeToString(*pointer)); -} +TempString TypeToString(T const* pointer) { return pointer == nullptr ? TempString("(nullptr)") : TypeToString(*pointer); } template -TempString TypeToString(T* pointer) { return TypeToString((T const*)pointer); } - -inline TempString TypeToStringFallback(TempString string, char const* fallback) { return (*string)[0] ? string : TempString(fallback); } +TempString TypeToString(T* pointer) { return pointer == nullptr ? TempString("(nullptr)") : TypeToString(*pointer); } //--------------------------------------------------------------------------------- // Test fixture is the core of SimpleTest. It provides fixture behavior, access @@ -90,20 +78,27 @@ class TestFixture { public: TestFixture(); - virtual ~TestFixture() {}; + //virtual ~TestFixture() {;} + + virtual bool ExecuteTest() { + myNumTestsChecked = myNumErrors = 0; + myNextError = (TestError*)myMessageSpace; - virtual bool ExecuteTest(); + TestFixture* lastCurrent = ourCurrentTest; + ourCurrentTest = this; + Setup(); + RunTest(); + TearDown(); + ourCurrentTest = lastCurrent; - virtual char const* TestName() const = 0; - virtual char const* TestGroup() const = 0; + return myNumErrors == 0;} + + virtual char const* TestName() {return nullptr;}//const = 0; + virtual char const* TestGroup() {return nullptr;}//const = 0; // Reporting used during testing process void AddTest() { ++myNumTestsChecked; } - void AddError() { ++myNumErrors; } - void LogMessage(char const* string, ...); - - // Custom test for strings to print out where the comparison failed - bool TestStrings(char const* left, char const* right, char const* prefix, char const* condition); + void LogError(char const* string, ...); // Stats from execution int NumTests() const { return myNumTestsChecked; } @@ -125,15 +120,6 @@ class TestFixture Verbose }; - enum PrintMethod - { - PrintDefault, - PrintHexadecimal, - }; - - PrintMethod GetPrintMethod() const { return myPrintMethod; } - void SetPrintMethod(PrintMethod aPrintMethod) { myPrintMethod = aPrintMethod; } - // Default execution implementation static void (*Print)(char const* string); static void Printf(char const* string, ...); @@ -144,7 +130,7 @@ class TestFixture static bool ExecuteTestGroup(char const* groupFilter, OutputMode output = Normal) { return ExecuteAllTests(groupFilter, nullptr, output); } protected: - virtual void RunTest() = 0; + virtual void RunTest() {}//= 0; virtual void Setup() {} virtual void TearDown() {} @@ -154,17 +140,16 @@ class TestFixture static TestFixture* ourLastTest; TestFixture* myNextTest; - TestError* myNextError; int myNumTestsChecked; int myNumErrors; - PrintMethod myPrintMethod; - + TestError* myNextError; char myMessageSpace[MESSAGE_SPACE]; // allow access to current test outside of main code block - static thread_local TestFixture* ourCurrentTest; + //static thread_local TestFixture* ourCurrentTest; + static TestFixture* ourCurrentTest; }; //--------------------------------------------------------------------------------- @@ -172,8 +157,8 @@ class TestFixture //--------------------------------------------------------------------------------- #define DEFINE_TEST_FULL(name, group, fixture) \ struct TOK(group, name) final : public fixture { \ - char const* TestName() const override { return #name; } \ - char const* TestGroup() const override { return #group; } \ + char const* TestName() /*const*/ override { return #name; } \ + char const* TestGroup() /*const*/ override { return #group; } \ void RunTest() override; \ } TOK(TOK(group, name), Instance); \ void TOK(group, name)::RunTest() @@ -187,7 +172,7 @@ void TOK(group, name)::RunTest() // Utils //--------------------------------------------------------------------------------- template -T TestDifference(T const& a, T const& b) { return a > b ? a - b : b - a; } +T TestDifference(T const& a, T const& b) { T tmp = a - b; return tmp < 0 ? -tmp : tmp; } // why are these still needed? #define STR2(x) #x @@ -197,30 +182,18 @@ T TestDifference(T const& a, T const& b) { return a > b ? a - b : b - a; } #define TOK(a, b) TOK2(a, b) //--------------------------------------------------------------------------------- -// Error reporting and setup, don't call directly +// Error reporting don't call directly //--------------------------------------------------------------------------------- -#define TEST_TYPE_TO_STRING(var, arg) *TypeToStringFallback(TypeToString(var), STR(arg)) #define TEST_ERROR_PREFIX_ __FILE__ "(" STR(__LINE__) "): Condition [%s] Failed. " -#define TEST_ERROR_(message, ...) do { TestFixture* __fx = TestFixture::GetCurrentTest(); __fx->AddError(); __fx->LogMessage(TEST_ERROR_PREFIX_ message, ##__VA_ARGS__); ERROR_ACTION; } while(0) -#define TEST_BEGIN_(a) do { auto const& test_value_ = a +#define TEST_ERROR_(message, ...) do { TestFixture::GetCurrentTest()->LogError(TEST_ERROR_PREFIX_ message, ##__VA_ARGS__); } while(0) #define TEST_CHECK_(cond, condtext, message, ...) do { TestFixture::GetCurrentTest()->AddTest(); if (!(cond)) TEST_ERROR_(message, condtext, ##__VA_ARGS__); } while(0) -#define TEST_END_ } while(0) //--------------------------------------------------------------------------------- // Tests -// -// Note: Value caching is only enabled on left hand side. This splits the difference -// between preventing side effects (i.e. x++ double incrementing) and allowing the -// compiler to infer values (i.e. TEST_EQ(unsigned(1), 1) will try to cache 1 as an int then omit a compile warning). -// This means that the right hand side will get evaluated multiple times, so please avoid -// expressions like: TEST_EQ(a++, b++) as they won't work. Tests should always be written -// as following: -// TEST_EQ(expression, constant) //--------------------------------------------------------------------------------- -#define TEST_OPERATOR(a, b, op1, op2) TEST_BEGIN_(a); TEST_CHECK_((test_value_) op1 (b), STR(a) " " STR(op1) " " STR(b), "'%s' " STR(op2) " '%s'", TEST_TYPE_TO_STRING(test_value_, a), TEST_TYPE_TO_STRING(b, b)); TEST_END_ +#define TEST_OPERATOR(a, b, op1, op2) TEST_CHECK_((a) op1 (b), STR(a) " " STR(op1) " " STR(b), "%s " STR(op2) " %s", *TypeToString(a), *TypeToString(b)) #define TEST(cond) TEST_EQ(cond, true) -#define TEST_FAIL(cond) TEST_EQ(cond, false) #define TEST_EQ(a, b) TEST_OPERATOR(a, b, ==, !=) #define TEST_NEQ(a, b) TEST_OPERATOR(a, b, !=, ==) @@ -229,7 +202,7 @@ T TestDifference(T const& a, T const& b) { return a > b ? a - b : b - a; } #define TEST_LESS(a, b) TEST_OPERATOR(a, b, <, >=) #define TEST_LESS_EQUAL(a, b) TEST_OPERATOR(a, b, <=, >) -#define TEST_STR_EQ(a, b) do { if(!TestFixture::GetCurrentTest()->TestStrings(a, b, TEST_ERROR_PREFIX_ "\n%s\n%s\n%s", STR(a) " == " STR(b))) { ERROR_ACTION; } } while(0) -#define TEST_CLOSE(a, b, eps) TEST_BEGIN_(TestDifference(a, b)); TEST_CHECK_(test_value_ <= eps, STR(a) " Close to " STR(b), "Difference of %s is greater than expected amount of " STR(eps) " when comparing %s and %s", TEST_TYPE_TO_STRING(test_value_, TestDifference(a, b)), TEST_TYPE_TO_STRING(a, a), TEST_TYPE_TO_STRING(b, b)); TEST_END_ -#define TEST_DIFFERS(a, b, eps) TEST_BEGIN_(TestDifference(a, b)); TEST_CHECK_(test_value_ >= eps, STR(a) " Differs from " STR(b), "Difference of %s is less than expected amount of " STR(eps) " when comparing %s and %s", TEST_TYPE_TO_STRING(test_value_, TestDifference(a, b)), TEST_TYPE_TO_STRING(a, a), TEST_TYPE_TO_STRING(b, b)); TEST_END_ -#define TEST_MESSAGE(cond, message, ...) TEST_BEGIN_(cond); TEST_CHECK_(test_value_, STR(cond), message, ##__VA_ARGS__); TEST_END_ +#define TEST_CLOSE(a, b, eps) TEST_CHECK_(TestDifference(a,b) <= eps, STR(a) " Close to " STR(b), "Difference of %s is greater than " STR(eps), *TypeToString(TestDifference(a,b))) +#define TEST_MESSAGE(cond, message, ...) TEST_CHECK_(cond, STR(cond), message, ##__VA_ARGS__) + +#endif // _SIMPLETEST_H_ \ No newline at end of file From 0d7fd6e6aaa60abcc53a5f82010bae6cc5e0bc60 Mon Sep 17 00:00:00 2001 From: Eyal Gerber <35224049+Novodes@users.noreply.github.com> Date: Sun, 18 Dec 2022 11:06:56 +0200 Subject: [PATCH 2/3] Updated readme of EmbeddedSafety version --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2bbf1c2..91cca4e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# simpletest +# simpletest-EmbeddedSafety -_**A super simple framwork for implementing Unit Tests**_ +_**A super simple framwork for implementing Unit Tests ON embedded systems**_ [![Build Status](https://travis-ci.org/kudaba/simpletest_test.svg?branch=master)](https://travis-ci.org/kudaba/simpletest_test) [![Build Status](https://ci.appveyor.com/api/projects/status/github/kudaba/simpletest_test?branch=master&svg=true)](https://ci.appveyor.com/project/kudaba/simpletest-test) @@ -15,7 +15,7 @@ A lot of c++ unit tests claim to be simple, but when I went searching for the pe * Simple, isolated test declaration * No memory allocations, at all * Very few, if any dependencies -* Bonus: Threadable +* Bonus: Threadable (not in the EmbeddedSafety version) Head over to [simpletest_test](https://github.com/kudaba/simpletest_test) for more complete usage examples. @@ -94,7 +94,7 @@ One of the main reason I want a unit test is to make sure my code doesn't leak. # Very few dependencies After seeing unit tests that need perl or python to generate test harnesses, or other crazy code dependencies, I wanted to use the most limited set of dependencies I could. I didn't go as far as a single header implementation, but even the cpp only depends on two standard headers, stdio.h and string.h. -# Threadable +# Threadable (not applicable to the EmbeddedSafety version) By keeping the fixture, test and results in a single object it means that the execution of a single test is threadable as long that the test code itself is contained and threadable. There is no default threaded implementation of test execution, but you can see the simpletest_test project for more advanced examples. # Notable Differences @@ -113,7 +113,7 @@ Global configuration is generally done by defininy macros before including simpl If you want all tests to use the same fixture, for default memory checking or exception catching, then simply define the macro BASE_FIXTURE. ## Static memory usage -To achieve allocation free tests I needed to give each test a memory area to write their error messages. The default is (probably out of date) 10k per test. You can override this by defining the MESSAGE_SPACE macro. +To achieve allocation free tests I needed to give each test a memory area to write their error messages. The default is (probably out of date) 10k per test (in the EmbeddedSafety version it is much smaller at 100 bytes). You can override this by defining the MESSAGE_SPACE macro. ## Temporary string length -The buffer size of the temporary string object can be set by defining STRING_LENGTH. I figured 64 bytes is a decent size for anything that isn't already a string. \ No newline at end of file +The buffer size of the temporary string object can be set by defining STRING_LENGTH. I figured 64 bytes is a decent size for anything that isn't already a string. From 5b6ce1596f4adda99f37e950ecddb041c43fca2e Mon Sep 17 00:00:00 2001 From: Eyal Gerber <35224049+Novodes@users.noreply.github.com> Date: Sun, 18 Dec 2022 11:24:32 +0200 Subject: [PATCH 3/3] Updated ReadMe.md to include info about functional safety with the EmbeddedSafety version of simpletest --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 91cca4e..b7254a1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # simpletest-EmbeddedSafety -_**A super simple framwork for implementing Unit Tests ON embedded systems**_ +_**A super simple framwork for implementing Unit Tests ON embedded systems with functional safety requirements**_ [![Build Status](https://travis-ci.org/kudaba/simpletest_test.svg?branch=master)](https://travis-ci.org/kudaba/simpletest_test) [![Build Status](https://ci.appveyor.com/api/projects/status/github/kudaba/simpletest_test?branch=master&svg=true)](https://ci.appveyor.com/project/kudaba/simpletest-test) @@ -10,6 +10,8 @@ _**A super simple framwork for implementing Unit Tests ON embedded systems**_ src="https://scan.coverity.com/projects/15803/badge.svg"/> +Tested with ARM compiler 6.6 and 6.6.4 using ARM FuSa (Functional Safety) library. + A lot of c++ unit tests claim to be simple, but when I went searching for the perfect one there was always something that prevented me from using it. They were either overly complicated or had some critical flaw like excess memory allocations or dependencies on external programs. So here is the simplest form of unit test I could come up with to cover basic development. My rules for simple were the following: * Basic test features only: fixtures and test * Simple, isolated test declaration