code finished for testing, added serial monitor and debug output
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
#include <Arduino.h>
|
||||
#include <unity.h>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace fakeit;
|
||||
|
||||
#include <IndexNetworkLayer.h>
|
||||
#include <IndexFeederProtocol.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t destination_address;
|
||||
uint8_t *data;
|
||||
size_t length;
|
||||
} transmit_arg_capture_t;
|
||||
|
||||
static std::vector<transmit_arg_capture_t> args;
|
||||
|
||||
static void reset_transmit_arg_capture() {
|
||||
for (transmit_arg_capture_t arg : args) {
|
||||
if (arg.data != NULL) {
|
||||
free(arg.data);
|
||||
}
|
||||
}
|
||||
args.clear();
|
||||
}
|
||||
|
||||
#define GET_FEEDER_ID 0x01
|
||||
#define INITIALIZE_FEEDER_ID 0x02
|
||||
#define GET_VERSION_ID 0x03
|
||||
#define MOVE_FEED_FORWARD_ID 0x04
|
||||
#define MOVE_FEED_BACKWARD_ID 0x05
|
||||
#define GET_FEEDER_ADDRESS_ID 0xC0
|
||||
|
||||
#define ERROR_SUCCESS 0x00
|
||||
#define ERROR_WRONG_FEEDER_UUID 0x01
|
||||
#define ERROR_MOTOR_FAULT 0x02
|
||||
#define ERROR_UNINITIALIZED_FEEDER 0x03
|
||||
|
||||
std::function<bool(uint8_t destination_address, const uint8_t *buffer, size_t buffer_length)> transmit_capture = [](uint8_t destination_address, const uint8_t *buffer, size_t buffer_length) {
|
||||
transmit_arg_capture_t arg_entry;
|
||||
arg_entry.destination_address = destination_address;
|
||||
arg_entry.length = buffer_length;
|
||||
|
||||
if (buffer_length > 0 && buffer != NULL) {
|
||||
arg_entry.data = (uint8_t *)malloc(buffer_length);
|
||||
memcpy(arg_entry.data, buffer, buffer_length);
|
||||
}
|
||||
|
||||
args.push_back(arg_entry);
|
||||
return true;
|
||||
};
|
||||
|
||||
static uint8_t feeder_address = 0x01;
|
||||
static uint8_t feeder_uuid[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb};
|
||||
|
||||
static Mock<Feeder> feeder_mock;
|
||||
static Feeder &feeder = feeder_mock.get();
|
||||
|
||||
static Mock<IndexNetworkLayer> network_mock;
|
||||
static IndexNetworkLayer &network = network_mock.get();
|
||||
|
||||
static void test_index_feeder_protocol_setup() {
|
||||
feeder_mock.Reset();
|
||||
When(Method(feeder_mock, init)).AlwaysReturn(true);
|
||||
|
||||
network_mock.Reset();
|
||||
reset_transmit_arg_capture();
|
||||
When(Method(network_mock, transmitPacket)).AlwaysDo(transmit_capture);
|
||||
When(Method(network_mock, getLocalAddress)).AlwaysReturn(feeder_address);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_teardown() {
|
||||
reset_transmit_arg_capture();
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_get_feeder_id() {
|
||||
IndexFeederProtocol protocol(&feeder, feeder_uuid, sizeof(feeder_uuid));
|
||||
|
||||
uint8_t get_feeder[] = {GET_FEEDER_ID};
|
||||
protocol.handle(&network, get_feeder, sizeof(get_feeder));
|
||||
|
||||
Verify(Method(network_mock, transmitPacket)).Once();
|
||||
uint8_t expected[2 + sizeof(feeder_uuid)];
|
||||
expected[0] = feeder_address;
|
||||
expected[1] = ERROR_SUCCESS;
|
||||
memcpy(&expected[2], feeder_uuid, sizeof(feeder_uuid));
|
||||
TEST_ASSERT_EQUAL_UINT8(0, args[0].destination_address);
|
||||
TEST_ASSERT_EQUAL(sizeof(expected), args[0].length);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected, args[0].data, sizeof(expected));
|
||||
}
|
||||
|
||||
static void test_initialize_feeder(uint8_t *uuid, size_t uuid_length, uint8_t expected_status) {
|
||||
|
||||
if (uuid_length != 12) {
|
||||
TEST_FAIL_MESSAGE("Only 12 byte UUIDs are supported");
|
||||
}
|
||||
|
||||
IndexFeederProtocol protocol(&feeder, feeder_uuid, sizeof(feeder_uuid));
|
||||
|
||||
uint8_t init_feeder[1 + uuid_length];
|
||||
init_feeder[0] = INITIALIZE_FEEDER_ID;
|
||||
memcpy(&init_feeder[1], uuid, uuid_length);
|
||||
protocol.handle(&network, init_feeder, sizeof(init_feeder));
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT8(0, args[0].destination_address);
|
||||
Verify(Method(network_mock, transmitPacket)).Once();
|
||||
|
||||
switch (expected_status)
|
||||
{
|
||||
case ERROR_SUCCESS: // SUCCESS
|
||||
{
|
||||
uint8_t expected[] = { feeder_address, expected_status };
|
||||
TEST_ASSERT_EQUAL(sizeof(expected), args[0].length);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected, args[0].data, sizeof(expected));
|
||||
|
||||
TEST_ASSERT_TRUE(protocol.isInitialized());
|
||||
Verify(Method(feeder_mock, init)).Once();
|
||||
}
|
||||
break;
|
||||
|
||||
case ERROR_WRONG_FEEDER_UUID: // Wrong Feeder Id
|
||||
{
|
||||
uint8_t expected[2 + sizeof(feeder_uuid)];
|
||||
expected[0] = feeder_address;
|
||||
expected[1] = ERROR_WRONG_FEEDER_UUID; // Wrong Feeder Id
|
||||
memcpy(&expected[2], feeder_uuid, sizeof(feeder_uuid));
|
||||
TEST_ASSERT_EQUAL(sizeof(expected), args[0].length);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected, args[0].data, sizeof(expected));
|
||||
|
||||
TEST_ASSERT_FALSE(protocol.isInitialized());
|
||||
Verify(Method(feeder_mock, init)).Never();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
TEST_FAIL_MESSAGE("Unsupported Return Code");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_initialize_feeder_good_uuid() {
|
||||
test_initialize_feeder(feeder_uuid, sizeof(feeder_uuid), ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_initialize_feeder_zero_uuid() {
|
||||
uint8_t uuid[12];
|
||||
memset(uuid, 0, sizeof(uuid));
|
||||
test_initialize_feeder(uuid, sizeof(uuid), ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_initialize_feeder_invalid_uuid() {
|
||||
uint8_t uuid[12];
|
||||
memset(uuid, 0x11, sizeof(uuid));
|
||||
test_initialize_feeder(uuid, sizeof(uuid), ERROR_WRONG_FEEDER_UUID);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_get_version() {
|
||||
IndexFeederProtocol protocol(&feeder, feeder_uuid, sizeof(feeder_uuid));
|
||||
|
||||
uint8_t get_version[] = {GET_VERSION_ID};
|
||||
protocol.handle(&network, get_version, sizeof(get_version));
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT8(0, args[0].destination_address);
|
||||
Verify(Method(network_mock, transmitPacket)).Once();
|
||||
uint8_t expected[] = { feeder_address, ERROR_SUCCESS, 0x01};
|
||||
TEST_ASSERT_EQUAL_UINT8(0, args[0].destination_address);
|
||||
TEST_ASSERT_EQUAL(sizeof(expected), args[0].length);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected, args[0].data, sizeof(expected));
|
||||
}
|
||||
|
||||
static void index_feeder_move_test(uint8_t distance, bool forward, bool initialized, Feeder::FeedResult feeder_status, uint8_t expected_status) {
|
||||
When(Method(feeder_mock, feedDistance)).AlwaysReturn(feeder_status);
|
||||
IndexFeederProtocol protocol(&feeder, feeder_uuid, sizeof(feeder_uuid));
|
||||
|
||||
// Initialize Feeder
|
||||
if (initialized) {
|
||||
uint8_t init_feeder[1 + sizeof(feeder_uuid)];
|
||||
init_feeder[0] = INITIALIZE_FEEDER_ID;
|
||||
memcpy(&init_feeder[1], feeder_uuid, sizeof(feeder_uuid));
|
||||
protocol.handle(&network, init_feeder, sizeof(init_feeder));
|
||||
|
||||
// Reset To Only Track The Move Commands
|
||||
reset_transmit_arg_capture();
|
||||
feeder_mock.ClearInvocationHistory();
|
||||
network_mock.ClearInvocationHistory();
|
||||
}
|
||||
|
||||
uint8_t move_feed[2];
|
||||
move_feed[0] = (forward) ? MOVE_FEED_FORWARD_ID : MOVE_FEED_BACKWARD_ID; // Adjust command based on direction
|
||||
move_feed[1] = distance;
|
||||
protocol.handle(&network, move_feed, sizeof(move_feed));
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT8(0, args[0].destination_address);
|
||||
Verify(Method(network_mock, transmitPacket)).Once();
|
||||
|
||||
switch (expected_status) {
|
||||
case ERROR_SUCCESS: // SUCCESS
|
||||
{
|
||||
uint8_t expected[] = { feeder_address, expected_status };
|
||||
TEST_ASSERT_EQUAL(sizeof(expected), args[0].length);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected, args[0].data, sizeof(expected));
|
||||
Verify(Method(feeder_mock, feedDistance).Using(distance, forward)).Once();
|
||||
}
|
||||
break;
|
||||
case ERROR_MOTOR_FAULT: // Motor Fault
|
||||
{
|
||||
uint8_t expected[] = { feeder_address, ERROR_MOTOR_FAULT };
|
||||
TEST_ASSERT_EQUAL(sizeof(expected), args[0].length);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected, args[0].data, sizeof(expected));
|
||||
Verify(Method(feeder_mock, feedDistance).Using(distance, forward)).Once();
|
||||
}
|
||||
break;
|
||||
case ERROR_UNINITIALIZED_FEEDER: // Uninitialized Feeder
|
||||
{
|
||||
uint8_t expected[2 + sizeof(feeder_uuid)];
|
||||
expected[0] = feeder_address;
|
||||
expected[1] = ERROR_UNINITIALIZED_FEEDER;
|
||||
memcpy(&expected[2], feeder_uuid, sizeof(feeder_uuid));
|
||||
TEST_ASSERT_EQUAL(sizeof(expected), args[0].length);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected, args[0].data, sizeof(expected));
|
||||
Verify(Method(feeder_mock, feedDistance)).Never();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_move_feed_forward_ok() {
|
||||
index_feeder_move_test(40, true, true, Feeder::FeedResult::SUCCESS, ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_move_feed_forward_motor_error() {
|
||||
index_feeder_move_test(40, true, true, Feeder::FeedResult::MOTOR_FAULT, ERROR_MOTOR_FAULT);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_move_feed_forward_invalid_distance() {
|
||||
index_feeder_move_test(39, true, true, Feeder::FeedResult::INVALID_LENGTH, ERROR_MOTOR_FAULT);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_move_feed_forward_uninitialized_feeder() {
|
||||
index_feeder_move_test(40, true, false, Feeder::FeedResult::SUCCESS, ERROR_UNINITIALIZED_FEEDER);
|
||||
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_move_feed_backward_ok() {
|
||||
index_feeder_move_test(40, false, true, Feeder::FeedResult::SUCCESS, ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_move_feed_backward_motor_error() {
|
||||
index_feeder_move_test(40, false, true, Feeder::FeedResult::MOTOR_FAULT, ERROR_MOTOR_FAULT);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_move_feed_backward_invalid_distance() {
|
||||
index_feeder_move_test(39, false, true, Feeder::FeedResult::INVALID_LENGTH, ERROR_MOTOR_FAULT);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_move_feed_backward_uninitialized_feeder() {
|
||||
index_feeder_move_test(40, false, false, Feeder::FeedResult::SUCCESS, ERROR_UNINITIALIZED_FEEDER);
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_get_feeder_address_match() {
|
||||
IndexFeederProtocol protocol(&feeder, feeder_uuid, sizeof(feeder_uuid));
|
||||
|
||||
uint8_t payload[1 + sizeof(feeder_uuid)];
|
||||
payload[0] = GET_FEEDER_ADDRESS_ID;
|
||||
memcpy(&payload[1], feeder_uuid, sizeof(feeder_uuid));
|
||||
protocol.handle(&network, payload, sizeof(payload));
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT8(0, args[0].destination_address);
|
||||
Verify(Method(network_mock, transmitPacket)).Once();
|
||||
|
||||
uint8_t expected[2 + sizeof(feeder_uuid)];
|
||||
expected[0] = feeder_address;
|
||||
expected[1] = ERROR_SUCCESS;
|
||||
memcpy(&expected[2], feeder_uuid, sizeof(feeder_uuid));
|
||||
TEST_ASSERT_EQUAL(sizeof(expected), args[0].length);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected, args[0].data, sizeof(expected));
|
||||
}
|
||||
|
||||
static void test_index_feeder_protocol_get_feeder_address_no_match() {
|
||||
IndexFeederProtocol protocol(&feeder, feeder_uuid, sizeof(feeder_uuid));
|
||||
|
||||
uint8_t payload[1 + sizeof(feeder_uuid)];
|
||||
payload[0] = GET_FEEDER_ADDRESS_ID;
|
||||
memset(&payload[1], 0, sizeof(feeder_uuid));
|
||||
protocol.handle(&network, payload, sizeof(payload));
|
||||
|
||||
Verify(Method(network_mock, transmitPacket)).Never();
|
||||
}
|
||||
|
||||
#define RUN_FEEDER_TEST(func) { test_index_feeder_protocol_setup(); RUN_TEST(func); test_index_feeder_protocol_teardown(); }
|
||||
|
||||
void index_feeder_protocol_tests() {
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_get_feeder_id);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_initialize_feeder_good_uuid);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_initialize_feeder_zero_uuid);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_initialize_feeder_invalid_uuid);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_get_version);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_move_feed_forward_ok);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_move_feed_forward_motor_error);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_move_feed_forward_invalid_distance);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_move_feed_forward_uninitialized_feeder);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_move_feed_backward_ok);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_move_feed_backward_motor_error);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_move_feed_backward_invalid_distance);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_move_feed_backward_uninitialized_feeder);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_get_feeder_address_match);
|
||||
RUN_FEEDER_TEST(test_index_feeder_protocol_get_feeder_address_no_match);
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
#include <Arduino.h>
|
||||
#include <unity.h>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace fakeit;
|
||||
|
||||
#include <IndexNetworkLayer.h>
|
||||
|
||||
static void test_index_network_single_message_good_crc() {
|
||||
|
||||
// Validate A Good CRC
|
||||
uint8_t buf[] = {0x00, 0x01, 0x01, 0xb1, 0x90};
|
||||
|
||||
|
||||
Mock<IndexPacketHandler> handler_mock;
|
||||
When(Method(handler_mock, handle)).AlwaysReturn();
|
||||
IndexPacketHandler &handler = handler_mock.get();
|
||||
|
||||
When(Method(ArduinoFake(), millis)).Return(1);
|
||||
|
||||
Stream* stream = ArduinoFakeMock(Stream);
|
||||
IndexNetworkLayer network(stream, 0, &handler);
|
||||
|
||||
When(Method(ArduinoFake(Stream), available)).AlwaysReturn(0);
|
||||
network.tick();
|
||||
|
||||
Verify(Method(handler_mock, handle)).Never();
|
||||
|
||||
When(Method(ArduinoFake(Stream), available)).Return(sizeof(buf), 0);
|
||||
|
||||
std::function<size_t(char* buffer, size_t buffer_length)> fn = [buf](char *buffer, size_t buffer_length) {
|
||||
if (buffer_length >= sizeof(buf)) {
|
||||
memcpy(buffer, buf, buffer_length);
|
||||
return buffer_length;
|
||||
}
|
||||
return (size_t)0;
|
||||
};
|
||||
|
||||
When(Method(ArduinoFake(Stream), readBytes)).Do(fn);
|
||||
|
||||
network.tick();
|
||||
|
||||
Verify(Method(handler_mock, handle)).Once();
|
||||
}
|
||||
|
||||
static void test_index_network_multiple_message_good_crc() {
|
||||
// Validate Multiple Messages At Once
|
||||
uint8_t buf[] = {
|
||||
0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x50, 0xd4,
|
||||
0x00, 0x02, 0x05, 0x06, 0x22, 0xb6
|
||||
};
|
||||
|
||||
Mock<IndexPacketHandler> handler_mock;
|
||||
When(Method(handler_mock, handle)).AlwaysReturn();
|
||||
IndexPacketHandler &handler = handler_mock.get();
|
||||
|
||||
When(Method(ArduinoFake(), millis)).Return(1);
|
||||
|
||||
Stream* stream = ArduinoFakeMock(Stream);
|
||||
IndexNetworkLayer network(stream, 0, &handler);
|
||||
|
||||
When(Method(ArduinoFake(Stream), available)).AlwaysReturn(0);
|
||||
When(Method(ArduinoFake(Stream), available)).Return(sizeof(buf), 0);
|
||||
|
||||
std::function<size_t(char* buffer, size_t buffer_length)> fn = [buf](char *buffer, size_t buffer_length) {
|
||||
if (buffer_length >= sizeof(buf)) {
|
||||
memcpy(buffer, buf, buffer_length);
|
||||
return buffer_length;
|
||||
}
|
||||
return (size_t)0;
|
||||
};
|
||||
|
||||
When(Method(ArduinoFake(Stream), readBytes)).Do(fn);
|
||||
|
||||
network.tick();
|
||||
|
||||
Verify(Method(handler_mock, handle)).Exactly(2);
|
||||
}
|
||||
|
||||
static void test_index_network_single_message_bad_crc() {
|
||||
// Validate A Bad CRC
|
||||
uint8_t buf[] = {0x00, 0x01, 0x01, 0xb1, 0x91};
|
||||
|
||||
Mock<IndexPacketHandler> handler_mock;
|
||||
When(Method(handler_mock, handle)).AlwaysReturn();
|
||||
IndexPacketHandler &handler = handler_mock.get();
|
||||
|
||||
When(Method(ArduinoFake(), millis)).Return(1);
|
||||
|
||||
Stream* stream = ArduinoFakeMock(Stream);
|
||||
IndexNetworkLayer network(stream, 0, &handler);
|
||||
|
||||
When(Method(ArduinoFake(Stream), available)).Return(sizeof(buf)).AlwaysReturn(0);
|
||||
|
||||
std::function<size_t(char* buffer, size_t buffer_length)> fn = [buf](char *buffer, size_t buffer_length) {
|
||||
if (buffer_length >= sizeof(buf)) {
|
||||
memcpy(buffer, buf, buffer_length);
|
||||
return buffer_length;
|
||||
}
|
||||
return (size_t)0;
|
||||
};
|
||||
|
||||
When(Method(ArduinoFake(Stream), readBytes)).Do(fn);
|
||||
|
||||
network.tick();
|
||||
|
||||
Verify(Method(handler_mock, handle)).Never();
|
||||
}
|
||||
|
||||
static void test_index_network_bad_crc_followed_by_good_crc() {
|
||||
Mock<IndexPacketHandler> handler_mock;
|
||||
When(Method(handler_mock, handle)).AlwaysReturn();
|
||||
IndexPacketHandler &handler = handler_mock.get();
|
||||
|
||||
// Validate A Bad CRC followed by a good CRC
|
||||
uint8_t buf[] = {
|
||||
0x00, 0x01, 0x01, 0xb1, 0x91,
|
||||
0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x50, 0xd4
|
||||
};
|
||||
|
||||
When(Method(ArduinoFake(), millis)).Return(1);
|
||||
|
||||
Stream* stream = ArduinoFakeMock(Stream);
|
||||
IndexNetworkLayer network(stream, 0, &handler);
|
||||
|
||||
When(Method(ArduinoFake(Stream), available)).Return(sizeof(buf)).AlwaysReturn(0);
|
||||
|
||||
std::function<size_t(char* buffer, size_t buffer_length)> fn = [buf](char *buffer, size_t buffer_length) {
|
||||
if (buffer_length >= sizeof(buf)) {
|
||||
memcpy(buffer, buf, buffer_length);
|
||||
return buffer_length;
|
||||
}
|
||||
return (size_t)0;
|
||||
};
|
||||
|
||||
When(Method(ArduinoFake(Stream), readBytes)).Do(fn);
|
||||
|
||||
network.tick();
|
||||
|
||||
Verify(Method(handler_mock, handle)).Once();
|
||||
}
|
||||
|
||||
static void test_malformed_frame_with_interframe_time(unsigned long interframe_time, bool should_return) {
|
||||
Mock<IndexPacketHandler> handler_mock;
|
||||
When(Method(handler_mock, handle)).AlwaysReturn();
|
||||
IndexPacketHandler &handler = handler_mock.get();
|
||||
|
||||
// Message That Is 1 Octet To Short
|
||||
uint8_t buf[] = {0x00, 0x01, 0x01, 0xb1 };
|
||||
// Message That Is Valid
|
||||
uint8_t buf2[] = { 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x50, 0xd4 };
|
||||
|
||||
When(Method(ArduinoFake(), millis)).Return(1);
|
||||
|
||||
Stream* stream = ArduinoFakeMock(Stream);
|
||||
IndexNetworkLayer network(stream, 0, &handler);
|
||||
|
||||
When(Method(ArduinoFake(Stream), available)).Return(sizeof(buf)).AlwaysReturn(0);
|
||||
|
||||
std::function<size_t(char* buffer, size_t buffer_length)> fn = [buf](char *buffer, size_t buffer_length) {
|
||||
if (buffer_length >= sizeof(buf)) {
|
||||
memcpy(buffer, buf, buffer_length);
|
||||
return buffer_length;
|
||||
}
|
||||
return (size_t)0;
|
||||
};
|
||||
|
||||
When(Method(ArduinoFake(Stream), readBytes)).Do(fn);
|
||||
|
||||
network.tick();
|
||||
|
||||
// Check The Method Is Never Called Because We're In Mid Frame
|
||||
Verify(Method(handler_mock, handle)).Never();
|
||||
|
||||
// Call The Second Frame 200ms later which is after the timeout
|
||||
std::function<size_t(char* buffer, size_t buffer_length)> fn2 = [buf2](char *buffer, size_t buffer_length) {
|
||||
if (buffer_length >= sizeof(buf2)) {
|
||||
memcpy(buffer, buf2, buffer_length);
|
||||
return buffer_length;
|
||||
}
|
||||
return (size_t)0;
|
||||
};
|
||||
When(Method(ArduinoFake(Stream), available)).Return(sizeof(buf2)).AlwaysReturn(0);
|
||||
When(Method(ArduinoFake(Stream), readBytes)).Do(fn2);
|
||||
When(Method(ArduinoFake(), millis)).Return(interframe_time + 1);
|
||||
|
||||
network.tick();
|
||||
if (should_return) {
|
||||
Verify(Method(handler_mock, handle)).Once();
|
||||
} else {
|
||||
Verify(Method(handler_mock, handle)).Never();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void test_malformed_frame_timeout() {
|
||||
test_malformed_frame_with_interframe_time(200, true);
|
||||
}
|
||||
|
||||
static void test_malformed_frame_just_past_timeout() {
|
||||
test_malformed_frame_with_interframe_time(101, true);
|
||||
}
|
||||
|
||||
static void test_malformed_frame_at_timeout() {
|
||||
test_malformed_frame_with_interframe_time(100, false);
|
||||
}
|
||||
|
||||
static void test_malformed_frame_without_timeout() {
|
||||
test_malformed_frame_with_interframe_time(10, false);
|
||||
}
|
||||
|
||||
static void test_transmit_packet() {
|
||||
Stream* stream = ArduinoFakeMock(Stream);
|
||||
IndexNetworkLayer network(stream, 0, NULL);
|
||||
|
||||
const uint8_t payload[] = {0x01, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
|
||||
|
||||
When(OverloadedMethod(ArduinoFake(Stream), write, size_t(const uint8_t *, size_t)) ).Return(1, 1, sizeof(payload), 2);
|
||||
When(Method(ArduinoFake(Stream), flush)).Return();
|
||||
|
||||
bool result = network.transmitPacket(0x00, payload, sizeof(payload));
|
||||
|
||||
// Assert That It Transmitted
|
||||
TEST_ASSERT_TRUE(result);
|
||||
|
||||
// Verify The Address
|
||||
auto length_is_one = [](const uint8_t *buffer, size_t buffer_length) { return (buffer_length == 1); };
|
||||
auto payload_match = [&](const uint8_t *buffer, size_t buffer_length) { return ((buffer == payload) && (buffer_length == sizeof(payload))); };
|
||||
auto length_is_two = [](const uint8_t *buffer, size_t buffer_length) { return (buffer_length == 2); };
|
||||
|
||||
//TODO: Figure Out How To Validate The CRC
|
||||
Verify(
|
||||
OverloadedMethod(ArduinoFake(Stream), write, size_t(const uint8_t *, size_t)).Matching(length_is_one) * 2 +
|
||||
OverloadedMethod(ArduinoFake(Stream), write, size_t(const uint8_t *, size_t)).Matching(payload_match) +
|
||||
OverloadedMethod(ArduinoFake(Stream), write, size_t(const uint8_t *, size_t)).Matching(length_is_two)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
static void test_transmit_null() {
|
||||
Stream* stream = ArduinoFakeMock(Stream);
|
||||
IndexNetworkLayer network(stream, 0, NULL);
|
||||
bool result = network.transmitPacket(0x00, NULL, 0);
|
||||
TEST_ASSERT_FALSE(result);
|
||||
}
|
||||
|
||||
static void test_transmit_too_long() {
|
||||
#define TEST_LENGTH (INDEX_NETWORK_MAX_PDU + 1)
|
||||
Stream* stream = ArduinoFakeMock(Stream);
|
||||
IndexNetworkLayer network(stream, 0, NULL);
|
||||
uint8_t payload[TEST_LENGTH];
|
||||
memset(payload, 0, TEST_LENGTH);
|
||||
bool result = network.transmitPacket(0x00, payload, sizeof(payload));
|
||||
TEST_ASSERT_FALSE(result);
|
||||
}
|
||||
|
||||
void index_network_layer_tests() {
|
||||
RUN_TEST(test_index_network_single_message_good_crc);
|
||||
RUN_TEST(test_index_network_multiple_message_good_crc);
|
||||
RUN_TEST(test_index_network_single_message_bad_crc);
|
||||
RUN_TEST(test_index_network_bad_crc_followed_by_good_crc);
|
||||
RUN_TEST(test_malformed_frame_timeout);
|
||||
RUN_TEST(test_malformed_frame_just_past_timeout);
|
||||
RUN_TEST(test_malformed_frame_at_timeout);
|
||||
RUN_TEST(test_malformed_frame_without_timeout);
|
||||
RUN_TEST(test_transmit_packet);
|
||||
RUN_TEST(test_transmit_null);
|
||||
RUN_TEST(test_transmit_too_long);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <Arduino.h>
|
||||
#include <unity.h>
|
||||
|
||||
extern void index_network_layer_tests();
|
||||
extern void index_feeder_protocol_tests();
|
||||
|
||||
void setUp(void) {
|
||||
ArduinoFakeReset();
|
||||
}
|
||||
|
||||
int process() {
|
||||
UNITY_BEGIN();
|
||||
index_network_layer_tests();
|
||||
index_feeder_protocol_tests();
|
||||
return UNITY_END();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return process();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <Arduino.h>
|
||||
#include <unity.h>
|
||||
|
||||
int process() {
|
||||
UNITY_BEGIN();
|
||||
//index_protocol_tests();
|
||||
return UNITY_END();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// NOTE!!! Wait for >2 secs
|
||||
// if board doesn't support software reset via Serial.DTR/RTS
|
||||
|
||||
delay(2000);
|
||||
process();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
digitalWrite(13, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(13, LOW);
|
||||
delay(500);
|
||||
}
|
||||
Reference in New Issue
Block a user