first commit
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "test_arp_util.h"
|
||||
|
||||
void arp_testcase_init(arp_testcase_t *tcase,
|
||||
const char mac[static 6],
|
||||
const char ip[static 4])
|
||||
{
|
||||
memcpy(&tcase->self_ip, ip, 4);
|
||||
memcpy(&tcase->self_mac, mac, 6);
|
||||
tcase->failed = false;
|
||||
tcase->count = 0;
|
||||
}
|
||||
|
||||
void arp_testcase_free(arp_testcase_t *tcase)
|
||||
{
|
||||
(void) tcase;
|
||||
}
|
||||
|
||||
void arp_testcase_send(arp_testcase_t *tcase, const char data[static sizeof(arp_packet_t)])
|
||||
{
|
||||
if (tcase->failed)
|
||||
return;
|
||||
|
||||
if (tcase->count == ARP_TESTCASE_MAX_PACKETS) {
|
||||
tcase->failed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
arp_testcase_packet_t *packet = tcase->packets + tcase->count;
|
||||
packet->sender = ARP_TESTCASE_SENDER_PEER;
|
||||
packet->data = data;
|
||||
|
||||
tcase->count++;
|
||||
}
|
||||
|
||||
void arp_testcase_recv(arp_testcase_t *tcase, const char data[static sizeof(arp_packet_t)])
|
||||
{
|
||||
if (tcase->failed)
|
||||
return;
|
||||
|
||||
if (tcase->count == ARP_TESTCASE_MAX_PACKETS) {
|
||||
tcase->failed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
arp_testcase_packet_t *packet = tcase->packets + tcase->count;
|
||||
packet->sender = ARP_TESTCASE_SENDER_HOST;
|
||||
packet->data = data;
|
||||
|
||||
tcase->count++;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *msg;
|
||||
size_t msgmax;
|
||||
const arp_packet_t *output;
|
||||
const arp_testcase_t *tcase;
|
||||
size_t cursor;
|
||||
bool output_as_expected;
|
||||
bool aborted_while_checking_sent_packets;
|
||||
} testcase_contex_t;
|
||||
|
||||
static void send_packet(void *data, mac_address_t dest)
|
||||
{
|
||||
(void) dest; // Is this ok?
|
||||
|
||||
testcase_contex_t *context = data;
|
||||
|
||||
context->aborted_while_checking_sent_packets = false;
|
||||
|
||||
if (context->cursor == context->tcase->count) {
|
||||
snprintf(context->msg, context->msgmax, "ARP module sent an unexpected packet");
|
||||
context->output_as_expected = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const arp_testcase_packet_t *packet = context->tcase->packets + context->cursor;
|
||||
|
||||
if (packet->sender != ARP_TESTCASE_SENDER_HOST) {
|
||||
snprintf(context->msg, context->msgmax, "ARP module sent an unexpected packet");
|
||||
context->output_as_expected = false;
|
||||
return;
|
||||
}
|
||||
context->cursor++;
|
||||
|
||||
if (!memcmp(context->output, packet->data, sizeof(arp_packet_t)))
|
||||
context->output_as_expected = true;
|
||||
else {
|
||||
snprintf(context->msg, context->msgmax, "ARP module sent a different packet than expected");
|
||||
context->output_as_expected = false;
|
||||
}
|
||||
}
|
||||
|
||||
arp_testcase_result_t arp_testcase_run(arp_testcase_t tcase, char *msg, size_t msgmax)
|
||||
{
|
||||
if (tcase.failed)
|
||||
return ARP_TESTCASE_ABORTED;
|
||||
|
||||
arp_packet_t output;
|
||||
|
||||
testcase_contex_t context = {
|
||||
.output = &output,
|
||||
.tcase = &tcase,
|
||||
.cursor = 0,
|
||||
.msg = msg,
|
||||
.msgmax = msgmax,
|
||||
};
|
||||
|
||||
if (msgmax > 0)
|
||||
msg[0] = '\0';
|
||||
|
||||
arp_state_t state;
|
||||
arp_init(&state, tcase.self_ip, tcase.self_mac, &context, send_packet);
|
||||
arp_change_output_buffer(&state, &output, sizeof(output));
|
||||
|
||||
while (context.cursor < tcase.count) {
|
||||
|
||||
arp_testcase_packet_t *packet = tcase.packets + context.cursor++;
|
||||
|
||||
if (packet->sender != ARP_TESTCASE_SENDER_PEER) {
|
||||
snprintf(msg, msgmax, "ARP module didn't send packet");
|
||||
return ARP_TESTCASE_FAILED;
|
||||
}
|
||||
|
||||
// Initialize these
|
||||
context.output_as_expected = true;
|
||||
context.aborted_while_checking_sent_packets = false;
|
||||
|
||||
arp_process_result_t status = arp_process_packet(&state, packet->data, sizeof(arp_packet_t));
|
||||
|
||||
(void) status; // Not useful yet
|
||||
|
||||
// Before this point the arp_process_packet will have
|
||||
// sent some packets that were validated in the send_packet
|
||||
// callback. If the testcase didn't fail, the next
|
||||
// packet in the list will be sent by the peer.
|
||||
if (context.aborted_while_checking_sent_packets)
|
||||
return ARP_TESTCASE_ABORTED;
|
||||
if (!context.output_as_expected)
|
||||
return ARP_TESTCASE_FAILED;
|
||||
}
|
||||
|
||||
arp_free(&state);
|
||||
return ARP_TESTCASE_PASSED;
|
||||
}
|
||||
Reference in New Issue
Block a user