From 7b03f5283eb62a780cfdc2b9d21d6e7ae79cef00 Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Thu, 14 Sep 2023 15:07:06 -0500 Subject: [PATCH 1/4] chore: Add AUX throttling --- src/Notecard.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Notecard.cpp b/src/Notecard.cpp index e9af699..87368c3 100644 --- a/src/Notecard.cpp +++ b/src/Notecard.cpp @@ -248,6 +248,15 @@ void Notecard::begin(NoteSerial * noteSerial_) } else { NoteSetFnSerial(nullptr, nullptr, nullptr, nullptr); } + + // Set the default debug serial throttling + J *req = NoteNewRequest("card.aux.serial"); + if (req != NULL) + { + JAddIntToObject(req, "max", SERIAL_RX_BUFFER_SIZE - 1); + JAddIntToObject(req, "ms", 1); + NoteRequestWithRetry(req, 15); + } } /**************************************************************************/ From c220c51701a60cd1da40754f3ad9645c7a89bfe1 Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Thu, 28 Sep 2023 18:54:17 -0500 Subject: [PATCH 2/4] feat: Serial AUX Throttling --- src/Notecard.cpp | 18 +-- test/Notecard.test.cpp | 208 ++++++++++++++++++++++++++++++++++ test/mock/mock-arduino.hpp | 2 + test/mock/mock-note-c-note.c | 23 ++++ test/mock/mock-parameters.hpp | 28 +++++ 5 files changed, 270 insertions(+), 9 deletions(-) diff --git a/src/Notecard.cpp b/src/Notecard.cpp index 87368c3..9d5f48a 100644 --- a/src/Notecard.cpp +++ b/src/Notecard.cpp @@ -245,18 +245,18 @@ void Notecard::begin(NoteSerial * noteSerial_) if (noteSerial) { NoteSetFnSerial(noteSerialReset, noteSerialTransmit, noteSerialAvailable, noteSerialReceive); + + // Set the default debug serial throttling + J *req = NoteNewRequest("card.aux.serial"); + if (req != NULL) + { + JAddIntToObject(req, "max", SERIAL_RX_BUFFER_SIZE - 1); + JAddIntToObject(req, "ms", 1); + NoteRequestWithRetry(req, 15); + } } else { NoteSetFnSerial(nullptr, nullptr, nullptr, nullptr); } - - // Set the default debug serial throttling - J *req = NoteNewRequest("card.aux.serial"); - if (req != NULL) - { - JAddIntToObject(req, "max", SERIAL_RX_BUFFER_SIZE - 1); - JAddIntToObject(req, "ms", 1); - NoteRequestWithRetry(req, 15); - } } /**************************************************************************/ diff --git a/test/Notecard.test.cpp b/test/Notecard.test.cpp index 0546c67..3ad7c8a 100644 --- a/test/Notecard.test.cpp +++ b/test/Notecard.test.cpp @@ -1372,6 +1372,209 @@ int test_notecard_begin_serial_sets_serial_receive_function_pointer_to_nullptr_w return result; } +int test_notecard_begin_serial_sends_a_card_aux_serial_request_to_throttle_aux_serial_data() +{ + int result; + + // Arrange + //////////// + + Notecard notecard; + NoteSerial_Mock mockSerial; // Instantiate NoteSerial (mocked) + jAddNumberToObject_Parameters.reset(); + noteNewRequest_Parameters.reset(); + noteRequestWithRetry_Parameters.reset(); + noteSetFnDefault_Parameters.reset(); + + noteNewRequest_Parameters.result = reinterpret_cast(malloc(sizeof(J))); + + // Action + /////////// + + notecard.begin(&mockSerial); + + // Assert + /////////// + + if (noteRequestWithRetry_Parameters.invoked) + { + result = 0; + } + else + { + result = static_cast('n' + 'o' + 't' + 'e' + 'c' + 'a' + 'r' + 'd'); + std::cout << "\33[31mFAILED\33[0m] " << __FILE__ << ":" << __LINE__ << std::endl; + std::cout << "\tnoteRequestWithRetry_Parameters.invoked == " << std::dec << noteRequestWithRetry_Parameters.invoked << ", EXPECTED: > 0" << std::endl; + std::cout << "["; + } + + free(noteNewRequest_Parameters.result); + return result; +} + +int test_notecard_begin_serial_sends_a_card_aux_serial_request_with_15_second_retry() +{ + int result; + + // Arrange + //////////// + + Notecard notecard; + NoteSerial_Mock mockSerial; // Instantiate NoteSerial (mocked) + jAddNumberToObject_Parameters.reset(); + noteNewRequest_Parameters.reset(); + noteRequestWithRetry_Parameters.reset(); + noteSetFnDefault_Parameters.reset(); + + noteNewRequest_Parameters.result = reinterpret_cast(malloc(sizeof(J))); + + // Action + /////////// + + notecard.begin(&mockSerial); + + // Assert + /////////// + + if (15 == noteRequestWithRetry_Parameters.timeoutSeconds) + { + result = 0; + } + else + { + result = static_cast('n' + 'o' + 't' + 'e' + 'c' + 'a' + 'r' + 'd'); + std::cout << "\33[31mFAILED\33[0m] " << __FILE__ << ":" << __LINE__ << std::endl; + std::cout << "\tnoteRequestWithRetry_Parameters.timeoutSeconds == " << std::dec << noteRequestWithRetry_Parameters.timeoutSeconds << ", EXPECTED: 15" << std::endl; + std::cout << "["; + } + + free(noteNewRequest_Parameters.result); + return result; +} + +int test_notecard_begin_serial_sends_a_card_aux_serial_request_with_max_parameter_set_to_arduino_serial_rx_buffer_size_constant_minus_one() +{ + int result; + + // Arrange + //////////// + + Notecard notecard; + NoteSerial_Mock mockSerial; // Instantiate NoteSerial (mocked) + jAddNumberToObject_Parameters.reset(); + noteNewRequest_Parameters.reset(); + noteRequestWithRetry_Parameters.reset(); + noteSetFnDefault_Parameters.reset(); + + noteNewRequest_Parameters.result = reinterpret_cast(malloc(sizeof(J))); + + // Action + /////////// + + notecard.begin(&mockSerial); + + // Assert + /////////// + + if ("max" == jAddNumberToObject_Parameters.name[0] + && (SERIAL_RX_BUFFER_SIZE - 1) == jAddNumberToObject_Parameters.number[0] + ) { + result = 0; + } + else + { + result = static_cast('n' + 'o' + 't' + 'e' + 'c' + 'a' + 'r' + 'd'); + std::cout << "\33[31mFAILED\33[0m] " << __FILE__ << ":" << __LINE__ << std::endl; + std::cout << "\tjAddNumberToObject_Parameters.name == \"" << std::dec << jAddNumberToObject_Parameters.name[0] << "\", EXPECTED: \"max\"" << std::endl; + std::cout << "\tjAddNumberToObject_Parameters.number == " << std::dec << jAddNumberToObject_Parameters.number[0] << ", EXPECTED: " << (SERIAL_RX_BUFFER_SIZE - 1) << std::endl; + std::cout << "["; + } + + free(noteNewRequest_Parameters.result); + return result; +} + +int test_notecard_begin_serial_sends_a_card_aux_serial_request_with_ms_parameter_set_to_one() +{ + int result; + + // Arrange + //////////// + + Notecard notecard; + NoteSerial_Mock mockSerial; // Instantiate NoteSerial (mocked) + jAddNumberToObject_Parameters.reset(); + noteNewRequest_Parameters.reset(); + noteRequestWithRetry_Parameters.reset(); + noteSetFnDefault_Parameters.reset(); + + noteNewRequest_Parameters.result = reinterpret_cast(malloc(sizeof(J))); + + // Action + /////////// + + notecard.begin(&mockSerial); + + // Assert + /////////// + + if ("ms" == jAddNumberToObject_Parameters.name[1] + && 1 == jAddNumberToObject_Parameters.number[1] + ) { + result = 0; + } + else + { + result = static_cast('n' + 'o' + 't' + 'e' + 'c' + 'a' + 'r' + 'd'); + std::cout << "\33[31mFAILED\33[0m] " << __FILE__ << ":" << __LINE__ << std::endl; + std::cout << "\tjAddNumberToObject_Parameters.name == \"" << std::dec << jAddNumberToObject_Parameters.name[1] << "\", EXPECTED: \"ms\"" << std::endl; + std::cout << "\tjAddNumberToObject_Parameters.number == " << std::dec << jAddNumberToObject_Parameters.number[1] << ", EXPECTED: 1" << std::endl; + std::cout << "["; + } + + free(noteNewRequest_Parameters.result); + return result; +} + +int test_notecard_begin_serial_does_not_send_a_card_aux_serial_request_when_interface_has_not_been_instantiated() +{ + int result; + + // Arrange + //////////// + + Notecard notecard; + jAddNumberToObject_Parameters.reset(); + noteNewRequest_Parameters.reset(); + noteRequestWithRetry_Parameters.reset(); + noteSetFnDefault_Parameters.reset(); + + noteNewRequest_Parameters.result = reinterpret_cast(malloc(sizeof(J))); + + // Action + /////////// + + notecard.begin(static_cast(nullptr)); + + // Assert + /////////// + + if (!noteRequestWithRetry_Parameters.invoked) + { + result = 0; + } + else + { + result = static_cast('n' + 'o' + 't' + 'e' + 'c' + 'a' + 'r' + 'd'); + std::cout << "\33[31mFAILED\33[0m] " << __FILE__ << ":" << __LINE__ << std::endl; + std::cout << "\tnoteRequestWithRetry_Parameters.invoked == " << std::dec << noteRequestWithRetry_Parameters.invoked << ", EXPECTED: 0" << std::endl; + std::cout << "["; + } + + free(noteNewRequest_Parameters.result); + return result; +} + int test_notecard_setDebugOutputStream_shares_a_debug_log_function_pointer() { int result; @@ -4635,6 +4838,11 @@ int main(void) {test_notecard_begin_serial_sets_serial_available_function_pointer_to_nullptr_when_interface_has_not_been_instantiated, "test_notecard_begin_serial_sets_serial_available_function_pointer_to_nullptr_when_interface_has_not_been_instantiated"}, {test_notecard_begin_serial_shares_a_serial_receive_function_pointer, "test_notecard_begin_serial_shares_a_serial_receive_function_pointer"}, {test_notecard_begin_serial_sets_serial_receive_function_pointer_to_nullptr_when_interface_has_not_been_instantiated, "test_notecard_begin_serial_sets_serial_receive_function_pointer_to_nullptr_when_interface_has_not_been_instantiated"}, + {test_notecard_begin_serial_sends_a_card_aux_serial_request_to_throttle_aux_serial_data, "test_notecard_begin_serial_sends_a_card_aux_serial_request_to_throttle_aux_serial_data"}, + {test_notecard_begin_serial_sends_a_card_aux_serial_request_with_15_second_retry, "test_notecard_begin_serial_sends_a_card_aux_serial_request_with_15_second_retry"}, + {test_notecard_begin_serial_sends_a_card_aux_serial_request_with_max_parameter_set_to_arduino_serial_rx_buffer_size_constant_minus_one, "test_notecard_begin_serial_sends_a_card_aux_serial_request_with_max_parameter_set_to_arduino_serial_rx_buffer_size_constant_minus_one"}, + {test_notecard_begin_serial_sends_a_card_aux_serial_request_with_ms_parameter_set_to_one, "test_notecard_begin_serial_sends_a_card_aux_serial_request_with_ms_parameter_set_to_one"}, + {test_notecard_begin_serial_does_not_send_a_card_aux_serial_request_when_interface_has_not_been_instantiated, "test_notecard_begin_serial_does_not_send_a_card_aux_serial_request_when_interface_has_not_been_instantiated"}, {test_notecard_setDebugOutputStream_shares_a_debug_log_function_pointer, "test_notecard_setDebugOutputStream_shares_a_debug_log_function_pointer"}, {test_notecard_setDebugOutputStream_clears_the_debug_log_function_pointer_when_nullptr_is_provided, "test_notecard_setDebugOutputStream_clears_the_debug_log_function_pointer_when_nullptr_is_provided"}, {test_notecard_clearDebugOutputStream_clears_the_debug_log_function_pointer, "test_notecard_clearDebugOutputStream_clears_the_debug_log_function_pointer"}, diff --git a/test/mock/mock-arduino.hpp b/test/mock/mock-arduino.hpp index 49d7b9b..fe37fb9 100644 --- a/test/mock/mock-arduino.hpp +++ b/test/mock/mock-arduino.hpp @@ -8,6 +8,8 @@ #include #include +#define SERIAL_RX_BUFFER_SIZE 79 + enum PinMode { INPUT = 0x19, INPUT_PULLUP, diff --git a/test/mock/mock-note-c-note.c b/test/mock/mock-note-c-note.c index 535cecb..1a6f292 100644 --- a/test/mock/mock-note-c-note.c +++ b/test/mock/mock-note-c-note.c @@ -1,5 +1,6 @@ #include "mock-parameters.hpp" +JAddNumberToObject_Parameters jAddNumberToObject_Parameters; NoteDebug_Parameters noteDebug_Parameters; NoteDebugSyncStatus_Parameters noteDebugSyncStatus_Parameters; NoteDeleteResponse_Parameters noteDeleteResponse_Parameters; @@ -19,6 +20,28 @@ NoteSetFnSerial_Parameters noteSetFnSerial_Parameters; NoteSetFnTransaction_Parameters noteSetFnTransaction_Parameters; NoteSetUserAgent_Parameters noteSetUserAgent_Parameters; +J * +JAddNumberToObject ( + J * const object_, + const char * const name_, + const JNUMBER number_ +) { + // Record invocation(s) + ++jAddNumberToObject_Parameters.invoked; + + // Stash parameter(s) + jAddNumberToObject_Parameters.object.push_back(object_); + jAddNumberToObject_Parameters.name.push_back(name_); + jAddNumberToObject_Parameters.number.push_back(number_); + + // Return user-supplied result + if (jAddNumberToObject_Parameters.result.size() < jAddNumberToObject_Parameters.invoked) { + return jAddNumberToObject_Parameters.default_result; + } else { + return jAddNumberToObject_Parameters.result[(jAddNumberToObject_Parameters.invoked - 1)]; + } +} + void MockNoteDeleteResponse ( J * response_ diff --git a/test/mock/mock-parameters.hpp b/test/mock/mock-parameters.hpp index 5a7731f..bb35413 100644 --- a/test/mock/mock-parameters.hpp +++ b/test/mock/mock-parameters.hpp @@ -2,6 +2,7 @@ #define MOCK_PARAMETERS_HPP #include +#include #include "note-c/note.h" @@ -19,6 +20,32 @@ void MockNoteDeleteResponse(J*); bool MockNoteResponseError(J*); #define NoteResponseError(x) MockNoteResponseError(x) +struct JAddNumberToObject_Parameters { + JAddNumberToObject_Parameters( + void + ) : + invoked(0), + default_result(nullptr) + { } + void + reset ( + void + ) { + invoked = 0; + object.clear(); + name.clear(); + number.clear(); + result.clear(); + default_result = nullptr; + } + size_t invoked; + std::vector object; + std::vector name; + std::vector number; + std::vector result; + J *default_result; +}; + struct NoteDebug_Parameters { NoteDebug_Parameters( void @@ -423,6 +450,7 @@ struct NoteSetUserAgent_Parameters { std::string agent_cache; }; +extern JAddNumberToObject_Parameters jAddNumberToObject_Parameters; extern NoteDebug_Parameters noteDebug_Parameters; extern NoteDebugSyncStatus_Parameters noteDebugSyncStatus_Parameters; extern NoteDeleteResponse_Parameters noteDeleteResponse_Parameters; From c02bc9d37c2f911339614aa8ae6b1d1e6bff6a4d Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Thu, 28 Sep 2023 19:38:00 -0500 Subject: [PATCH 3/4] fix: missing define --- src/Notecard.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Notecard.cpp b/src/Notecard.cpp index 9d5f48a..428d93b 100644 --- a/src/Notecard.cpp +++ b/src/Notecard.cpp @@ -44,6 +44,14 @@ #include "NoteTime.h" +// AUX serial throttling is based on the Arduino define `SERIAL_RX_BUFFER_SIZE`. +// Unfortunately, some platforms do NOT specify the define. In this case, 64 +// bytes is selected as the default value, because it is a common buffer size +// across several platforms. +#ifndef SERIAL_RX_BUFFER_SIZE +#define SERIAL_RX_BUFFER_SIZE 64 +#endif + /*************************************************************************** SINGLETON ABSTRACTION (REQUIRED BY NOTE-C) ***************************************************************************/ From b147b7de3c0a72299e377a2ae20a49863d7f6aa8 Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Fri, 29 Sep 2023 06:05:57 -0500 Subject: [PATCH 4/4] chore: warn SERIAL_RX_BUFFER_SIZE is missing provides a compiler message indicating SERIAL_RX_BUFFER_SIZE was not found, and that a default value has been provided. --- src/Notecard.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Notecard.cpp b/src/Notecard.cpp index 428d93b..48df25f 100644 --- a/src/Notecard.cpp +++ b/src/Notecard.cpp @@ -50,6 +50,7 @@ // across several platforms. #ifndef SERIAL_RX_BUFFER_SIZE #define SERIAL_RX_BUFFER_SIZE 64 +#pragma message "\n\x1B[0;33mSERIAL_RX_BUFFER_SIZE has not been specified for this platform!\n\nThe value is used to set the default Notecard AUX Serial write speeds.\nA value (" NOTE_C_STRINGIZE(SERIAL_RX_BUFFER_SIZE) ") has been specified on your behalf. Use the 'card.aux.serial'\nrequest to tailor the AUX Serial speed to your board and/or application.\nhttps://dev.blues.io/api-reference/notecard-api/card-requests/#card-aux-serial\x1B[0;0m" #endif /***************************************************************************