test: add recv module unit tests
This commit is contained in:
parent
d938d0ca4d
commit
a3c60158e9
5 changed files with 300 additions and 0 deletions
51
tests/recv/test_build_reply.c
Normal file
51
tests/recv/test_build_reply.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include "icmp.h"
|
||||
#include "internal/icmp_recv.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
Test(build_reply, basic_reply)
|
||||
{
|
||||
icmp_reply_t reply;
|
||||
uint8_t buffer[64];
|
||||
struct in_addr src;
|
||||
const char *payload_data = "test";
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
inet_pton(AF_INET, "192.168.1.1", &src);
|
||||
recv_build_reply(&reply, 0, 0, 64, src, payload_data, 4, buffer, 20);
|
||||
cr_assert_eq(reply.type, 0);
|
||||
cr_assert_eq(reply.code, 0);
|
||||
cr_assert_eq(reply.ttl, 64);
|
||||
cr_assert_eq(reply.from.s_addr, src.s_addr);
|
||||
cr_assert_eq(reply.payload, payload_data);
|
||||
cr_assert_eq(reply.payload_len, 4);
|
||||
cr_assert_not_null(reply.ip_payload);
|
||||
}
|
||||
|
||||
Test(build_reply, different_types)
|
||||
{
|
||||
icmp_reply_t reply;
|
||||
uint8_t buffer[64];
|
||||
struct in_addr src;
|
||||
|
||||
inet_pton(AF_INET, "8.8.8.8", &src);
|
||||
recv_build_reply(&reply, 3, 1, 128, src, NULL, 0, buffer, 20);
|
||||
cr_assert_eq(reply.type, 3);
|
||||
cr_assert_eq(reply.code, 1);
|
||||
cr_assert_eq(reply.ttl, 128);
|
||||
cr_assert_null(reply.payload);
|
||||
cr_assert_eq(reply.payload_len, 0);
|
||||
}
|
||||
|
||||
Test(build_reply, timestamp_set)
|
||||
{
|
||||
icmp_reply_t reply;
|
||||
uint8_t buffer[64];
|
||||
struct in_addr src;
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &src);
|
||||
recv_build_reply(&reply, 0, 0, 64, src, NULL, 0, buffer, 20);
|
||||
cr_assert(reply.timestamp.tv_sec > 0 || reply.timestamp.tv_nsec > 0,
|
||||
"Timestamp should be set");
|
||||
}
|
||||
74
tests/recv/test_parse_packet.c
Normal file
74
tests/recv/test_parse_packet.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include "icmp.h"
|
||||
#include "internal/icmp_recv.h"
|
||||
#include "internal/icmp_packet.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
build_test_packet(uint8_t *buffer, size_t *len)
|
||||
{
|
||||
struct ip_header *ip;
|
||||
struct icmp_header *icmp;
|
||||
|
||||
memset(buffer, 0, 64);
|
||||
ip = (struct ip_header *)buffer;
|
||||
ip->version_ihl = 0x45;
|
||||
ip->ttl = 64;
|
||||
ip->protocol = 1;
|
||||
inet_pton(AF_INET, "192.168.1.1", &ip->saddr);
|
||||
icmp = (struct icmp_header *)(buffer + 20);
|
||||
icmp->type = 0;
|
||||
icmp->code = 0;
|
||||
*len = 28;
|
||||
}
|
||||
|
||||
Test(parse_packet, valid_packet)
|
||||
{
|
||||
uint8_t buffer[64];
|
||||
size_t buffer_len;
|
||||
uint8_t type, code, ttl;
|
||||
struct in_addr src_addr;
|
||||
const void *payload;
|
||||
size_t payload_len, ip_hdr_len;
|
||||
int ret;
|
||||
|
||||
build_test_packet(buffer, &buffer_len);
|
||||
ret = recv_parse_packet(buffer, buffer_len, &type, &code, &ttl,
|
||||
&src_addr, &payload, &payload_len, &ip_hdr_len);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(type, 0);
|
||||
cr_assert_eq(code, 0);
|
||||
cr_assert_eq(ttl, 64);
|
||||
cr_assert_eq(ip_hdr_len, 20);
|
||||
}
|
||||
|
||||
Test(parse_packet, buffer_too_small)
|
||||
{
|
||||
uint8_t buffer[10];
|
||||
uint8_t type, code, ttl;
|
||||
struct in_addr src_addr;
|
||||
const void *payload;
|
||||
size_t payload_len, ip_hdr_len;
|
||||
int ret;
|
||||
|
||||
ret = recv_parse_packet(buffer, sizeof(buffer), &type, &code, &ttl,
|
||||
&src_addr, &payload, &payload_len, &ip_hdr_len);
|
||||
cr_assert_eq(ret, -1);
|
||||
}
|
||||
|
||||
Test(parse_packet, invalid_ip_version)
|
||||
{
|
||||
uint8_t buffer[64];
|
||||
uint8_t type, code, ttl;
|
||||
struct in_addr src_addr;
|
||||
const void *payload;
|
||||
size_t payload_len, ip_hdr_len;
|
||||
int ret;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
buffer[0] = 0x35;
|
||||
ret = recv_parse_packet(buffer, 40, &type, &code, &ttl,
|
||||
&src_addr, &payload, &payload_len, &ip_hdr_len);
|
||||
cr_assert_eq(ret, -1);
|
||||
}
|
||||
82
tests/recv/test_process.c
Normal file
82
tests/recv/test_process.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include "icmp.h"
|
||||
#include "test_helpers.h"
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void
|
||||
dummy_callback(const icmp_reply_t *reply, void *userdata)
|
||||
{
|
||||
(void)reply;
|
||||
(void)userdata;
|
||||
}
|
||||
|
||||
static void
|
||||
counter_callback(const icmp_reply_t *reply, void *userdata)
|
||||
{
|
||||
int *count;
|
||||
|
||||
(void)reply;
|
||||
count = (int *)userdata;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
Test(process, null_handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = icmp_process(NULL, dummy_callback, NULL);
|
||||
cr_assert_eq(ret, -1);
|
||||
}
|
||||
|
||||
Test(process, null_callback)
|
||||
{
|
||||
icmp_handle_t *h;
|
||||
int ret;
|
||||
|
||||
if (0 == has_net_raw_capability())
|
||||
cr_skip("Test requires CAP_NET_RAW or root privileges");
|
||||
h = icmp_create();
|
||||
cr_assert_not_null(h);
|
||||
ret = icmp_process(h, NULL, NULL);
|
||||
cr_assert_eq(ret, -1);
|
||||
cr_assert_str_eq(icmp_strerror(h), "Callback cannot be NULL");
|
||||
icmp_destroy(h);
|
||||
}
|
||||
|
||||
Test(process, no_packets_available)
|
||||
{
|
||||
icmp_handle_t *h;
|
||||
int ret;
|
||||
|
||||
if (0 == has_net_raw_capability())
|
||||
cr_skip("Test requires CAP_NET_RAW or root privileges");
|
||||
h = icmp_create();
|
||||
cr_assert_not_null(h);
|
||||
ret = icmp_process(h, dummy_callback, NULL);
|
||||
cr_assert_eq(ret, 0);
|
||||
icmp_destroy(h);
|
||||
}
|
||||
|
||||
Test(process, echo_loopback, .disabled = true)
|
||||
{
|
||||
icmp_handle_t *h;
|
||||
struct in_addr dest;
|
||||
int ret;
|
||||
int count;
|
||||
|
||||
if (0 == has_net_raw_capability())
|
||||
cr_skip("Test requires CAP_NET_RAW or root privileges");
|
||||
h = icmp_create();
|
||||
cr_assert_not_null(h);
|
||||
inet_pton(AF_INET, "127.0.0.1", &dest);
|
||||
ret = icmp_send_echo(h, dest, 1234, 1, 64);
|
||||
cr_assert_eq(ret, 0);
|
||||
sleep(1);
|
||||
count = 0;
|
||||
ret = icmp_process(h, counter_callback, &count);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_geq(count, 1, "Should receive at least one packet");
|
||||
icmp_destroy(h);
|
||||
}
|
||||
32
tests/recv/test_receive_packet.c
Normal file
32
tests/recv/test_receive_packet.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include "icmp.h"
|
||||
#include "internal/icmp_internal.h"
|
||||
#include "internal/icmp_recv.h"
|
||||
#include "test_helpers.h"
|
||||
|
||||
Test(receive_packet, invalid_fd)
|
||||
{
|
||||
uint8_t buffer[64];
|
||||
struct sockaddr_in from;
|
||||
ssize_t ret;
|
||||
|
||||
ret = recv_receive_packet(-1, buffer, sizeof(buffer), &from);
|
||||
cr_assert_eq(ret, -1);
|
||||
}
|
||||
|
||||
Test(receive_packet, no_data_available)
|
||||
{
|
||||
icmp_handle_t *h;
|
||||
uint8_t buffer[64];
|
||||
struct sockaddr_in from;
|
||||
ssize_t ret;
|
||||
|
||||
if (0 == has_net_raw_capability())
|
||||
cr_skip("Test requires CAP_NET_RAW or root privileges");
|
||||
h = icmp_create();
|
||||
cr_assert_not_null(h);
|
||||
ret = recv_receive_packet(((struct icmp_handle *)h)->fd, buffer,
|
||||
sizeof(buffer), &from);
|
||||
cr_assert_eq(ret, 0, "Should return 0 when no data (EAGAIN)");
|
||||
icmp_destroy(h);
|
||||
}
|
||||
61
tests/recv/test_validate_params.c
Normal file
61
tests/recv/test_validate_params.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#include <criterion/criterion.h>
|
||||
#include "icmp.h"
|
||||
#include "internal/icmp_internal.h"
|
||||
#include "internal/icmp_recv.h"
|
||||
#include "test_helpers.h"
|
||||
|
||||
static void
|
||||
dummy_callback(const icmp_reply_t *reply, void *userdata)
|
||||
{
|
||||
(void)reply;
|
||||
(void)userdata;
|
||||
}
|
||||
|
||||
Test(validate_params, null_handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = recv_validate_params(NULL, dummy_callback);
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
Test(validate_params, null_callback)
|
||||
{
|
||||
icmp_handle_t *h;
|
||||
int ret;
|
||||
|
||||
if (0 == has_net_raw_capability())
|
||||
cr_skip("Test requires CAP_NET_RAW or root privileges");
|
||||
h = icmp_create();
|
||||
cr_assert_not_null(h);
|
||||
ret = recv_validate_params((struct icmp_handle *)h, NULL);
|
||||
cr_assert_eq(ret, 0);
|
||||
icmp_destroy(h);
|
||||
}
|
||||
|
||||
Test(validate_params, invalid_fd)
|
||||
{
|
||||
struct icmp_handle h;
|
||||
int ret;
|
||||
|
||||
h.fd = -1;
|
||||
h.last_error = ICMP_OK;
|
||||
h.error_msg[0] = '\0';
|
||||
ret = recv_validate_params(&h, dummy_callback);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(h.last_error, ICMP_ERR_INVALID);
|
||||
}
|
||||
|
||||
Test(validate_params, valid_params)
|
||||
{
|
||||
icmp_handle_t *h;
|
||||
int ret;
|
||||
|
||||
if (0 == has_net_raw_capability())
|
||||
cr_skip("Test requires CAP_NET_RAW or root privileges");
|
||||
h = icmp_create();
|
||||
cr_assert_not_null(h);
|
||||
ret = recv_validate_params((struct icmp_handle *)h, dummy_callback);
|
||||
cr_assert_eq(ret, 1);
|
||||
icmp_destroy(h);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue