mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
tests/coding: add tests for XOR codding
This commit is contained in:
parent
d18a304267
commit
24cb2dada8
1
tests/unittests/tests-coding/Makefile
Normal file
1
tests/unittests/tests-coding/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
1
tests/unittests/tests-coding/Makefile.include
Normal file
1
tests/unittests/tests-coding/Makefile.include
Normal file
@ -0,0 +1 @@
|
||||
USEMODULE += coding
|
190
tests/unittests/tests-coding/tests-coding-xor.c
Normal file
190
tests/unittests/tests-coding/tests-coding-xor.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "embUnit/embUnit.h"
|
||||
|
||||
#include "bitfield.h"
|
||||
#include "coding/xor.h"
|
||||
#include "tests-coding.h"
|
||||
|
||||
static void test_coding_xor_building_blocks(void)
|
||||
{
|
||||
char string[] = "0123456789AB";
|
||||
uint8_t parity[CODING_XOR_PARITY_LEN(sizeof(string) - 1)];
|
||||
|
||||
coding_xor_generate(string, sizeof(string) - 1, parity);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0x33, parity[0]);
|
||||
TEST_ASSERT_EQUAL_INT(0x32, parity[1]);
|
||||
TEST_ASSERT_EQUAL_INT(0x39, parity[2]);
|
||||
TEST_ASSERT_EQUAL_INT(0x3A, parity[3]);
|
||||
TEST_ASSERT_EQUAL_STRING("0369147A258B", string);
|
||||
|
||||
uint8_t blocks = 0x80;
|
||||
bool success = coding_xor_recover(string, sizeof(string) - 1, parity,
|
||||
&blocks, sizeof(string) - 1, false);
|
||||
TEST_ASSERT(success);
|
||||
TEST_ASSERT_EQUAL_STRING("0123456789AB", string);
|
||||
}
|
||||
|
||||
static void test_coding_xor_recovery(void)
|
||||
{
|
||||
char string[] = "0123456789AB";
|
||||
char string_rx[sizeof(string)];
|
||||
uint8_t parity[CODING_XOR_PARITY_LEN(sizeof(string) - 1)];
|
||||
const uint8_t chunk_size = 4;
|
||||
const uint8_t num_chunks = sizeof(string) / chunk_size;
|
||||
const uint8_t num_parity_chunks = sizeof(parity) / chunk_size;
|
||||
|
||||
BITFIELD(chunks, num_chunks + num_parity_chunks);
|
||||
memset(chunks, 0, sizeof(chunks));
|
||||
memset(string_rx, 0, sizeof(string_rx));
|
||||
|
||||
coding_xor_generate(string, sizeof(string) - 1, parity);
|
||||
|
||||
for (unsigned i = 0; i < num_chunks; ++i) {
|
||||
/* lose a single chunk / packet */
|
||||
if (i == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(string_rx + i * chunk_size,
|
||||
string + i * chunk_size,
|
||||
chunk_size);
|
||||
bf_set(chunks, i);
|
||||
}
|
||||
/* we have all parity chunks */
|
||||
for (unsigned i = 0; i < num_parity_chunks; ++i) {
|
||||
bf_set(chunks, num_chunks + i);
|
||||
}
|
||||
|
||||
bool success = coding_xor_recover(string_rx, sizeof(string_rx) - 1,
|
||||
parity, chunks, chunk_size, false);
|
||||
TEST_ASSERT(success);
|
||||
TEST_ASSERT_EQUAL_STRING("0123456789AB", string_rx);
|
||||
}
|
||||
|
||||
static void test_coding_xor_recovery_failed(void)
|
||||
{
|
||||
char string[] = "0123456789AB";
|
||||
char string_rx[sizeof(string)];
|
||||
uint8_t parity[CODING_XOR_PARITY_LEN(sizeof(string) - 1)];
|
||||
const uint8_t chunk_size = 4;
|
||||
const uint8_t num_chunks = sizeof(string) / chunk_size;
|
||||
const uint8_t num_parity_chunks = sizeof(parity) / chunk_size;
|
||||
|
||||
BITFIELD(chunks, num_chunks + num_parity_chunks);
|
||||
memset(chunks, 0, sizeof(chunks));
|
||||
memset(string_rx, 0, sizeof(string_rx));
|
||||
|
||||
coding_xor_generate(string, sizeof(string) - 1, parity);
|
||||
|
||||
for (unsigned i = 0; i < num_chunks; ++i) {
|
||||
/* lose two chunks / packets */
|
||||
if (i == 1 || i == 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(string_rx + i * chunk_size,
|
||||
string + i * chunk_size,
|
||||
chunk_size);
|
||||
bf_set(chunks, i);
|
||||
}
|
||||
/* we have all parity chunks */
|
||||
for (unsigned i = 0; i < num_parity_chunks; ++i) {
|
||||
bf_set(chunks, num_chunks + i);
|
||||
}
|
||||
|
||||
bool success = coding_xor_recover(string_rx, sizeof(string_rx) - 1,
|
||||
parity, chunks, chunk_size, false);
|
||||
TEST_ASSERT(!success);
|
||||
}
|
||||
|
||||
static void test_coding_xor_recovery_parity(void)
|
||||
{
|
||||
char string[] = "0123456789AB";
|
||||
uint8_t parity[CODING_XOR_PARITY_LEN(sizeof(string) - 1)];
|
||||
uint8_t parity_rx[CODING_XOR_PARITY_LEN(sizeof(string) - 1)];
|
||||
const uint8_t chunk_size = 4;
|
||||
const uint8_t num_chunks = sizeof(string) / chunk_size;
|
||||
const uint8_t num_parity_chunks = sizeof(parity) / chunk_size;
|
||||
|
||||
BITFIELD(chunks, num_chunks + num_parity_chunks);
|
||||
memset(chunks, 0, sizeof(chunks));
|
||||
|
||||
coding_xor_generate(string, sizeof(string) - 1, parity);
|
||||
|
||||
/* we have all data chunks */
|
||||
for (unsigned i = 0; i < num_chunks; ++i) {
|
||||
bf_set(chunks, i);
|
||||
}
|
||||
|
||||
bool success = coding_xor_recover(string, sizeof(string) - 1, parity_rx,
|
||||
chunks, chunk_size, true);
|
||||
TEST_ASSERT(success);
|
||||
TEST_ASSERT_EQUAL_STRING("0123456789AB", string);
|
||||
TEST_ASSERT(memcmp(parity, parity_rx, sizeof(parity)) == 0);
|
||||
}
|
||||
|
||||
static void test_coding_xor_recovery_large(void)
|
||||
{
|
||||
uint8_t txbuf[1024];
|
||||
const size_t data_len = 768;
|
||||
|
||||
const size_t parity_len = CODING_XOR_PARITY_LEN(data_len);
|
||||
uint8_t *parity = &txbuf[data_len];
|
||||
|
||||
const uint8_t chunk_size = 64;
|
||||
const size_t num_chunks = (data_len + parity_len) / chunk_size;
|
||||
BITFIELD(chunks, num_chunks);
|
||||
memset(chunks, 0, sizeof(chunks));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(txbuf), data_len + parity_len);
|
||||
|
||||
/* fill TX buffer with known pattern */
|
||||
for (unsigned i = 0; i < data_len; ++i) {
|
||||
txbuf[i] = i & 0xFF;
|
||||
}
|
||||
coding_xor_generate(txbuf, data_len, parity);
|
||||
|
||||
for (unsigned i = 0; i < num_chunks; ++i) {
|
||||
uint8_t *data = &txbuf[i * chunk_size];
|
||||
|
||||
/* lose some chunks */
|
||||
if (i == 3 || i == 10 || i == 13) {
|
||||
memset(data, 0, chunk_size);
|
||||
} else {
|
||||
bf_set(chunks, i);
|
||||
}
|
||||
}
|
||||
|
||||
bool success = coding_xor_recover(txbuf, data_len, parity, chunks,
|
||||
chunk_size, true);
|
||||
TEST_ASSERT(success);
|
||||
for (unsigned i = 0; i < data_len; ++i) {
|
||||
TEST_ASSERT_EQUAL_INT(i & 0xFF, txbuf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Test *tests_coding_xor_tests(void)
|
||||
{
|
||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||
new_TestFixture(test_coding_xor_building_blocks),
|
||||
new_TestFixture(test_coding_xor_recovery),
|
||||
new_TestFixture(test_coding_xor_recovery_failed),
|
||||
new_TestFixture(test_coding_xor_recovery_parity),
|
||||
new_TestFixture(test_coding_xor_recovery_large),
|
||||
};
|
||||
|
||||
EMB_UNIT_TESTCALLER(coding_xor_tests, NULL, NULL, fixtures);
|
||||
|
||||
return (Test *)&coding_xor_tests;
|
||||
}
|
14
tests/unittests/tests-coding/tests-coding.c
Normal file
14
tests/unittests/tests-coding/tests-coding.c
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2021 Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#include "tests-coding.h"
|
||||
|
||||
void tests_coding(void)
|
||||
{
|
||||
TESTS_RUN(tests_coding_xor_tests());
|
||||
}
|
44
tests/unittests/tests-coding/tests-coding.h
Normal file
44
tests/unittests/tests-coding/tests-coding.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2021 Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup unittests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Unittests for the ``coding`` module
|
||||
*
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*/
|
||||
#ifndef TESTS_CODING_H
|
||||
#define TESTS_CODING_H
|
||||
|
||||
#include "embUnit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The entry point of this test suite.
|
||||
*/
|
||||
void tests_coding(void);
|
||||
|
||||
/**
|
||||
* @brief Generates tests for coding/xor.h
|
||||
*
|
||||
* @return embUnit tests if successful, NULL if not.
|
||||
*/
|
||||
Test *tests_coding_xor_tests(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TESTS_CODING_H */
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user