[FL-2274] Inventing streams and moving FFF to them (#981)

* Streams: string stream
* String stream: updated insert/delete api
* Streams: generic stream interface and string stream implementation
* Streams: helpers for insert and delete_and_insert
* FFF: now compatible with streams
* MinUnit: introduced tests with arguments
* FFF: stream access violation
* Streams: copy data between streams
* Streams: file stream
* FFF: documentation
* FFStream: documentation
* FFF: alloc as file
* MinUnit: support for nested tests
* Streams: changed delete_and_insert, now it returns success flag. Added ability dump stream inner parameters and data to cout.
* FFF: simplified file open function
* Streams: unit tests
* FFF: tests
* Streams: declare cache_size constant as define, to allow variable modified arrays
* FFF: lib moved to a separate folder
* iButton: new FFF
* RFID: new FFF
* Animations: new FFF
* IR: new FFF
* NFC: new FFF
* Flipper file format: delete lib
* U2F: new FFF
* Subghz: new FFF and streams
* Streams: read line
* Streams: split
* FuriCore: implement memset with extra asserts
* FuriCore: implement extra heap asserts without inventing memset
* Scene manager: protected access to the scene id stack with a size check
* NFC worker: dirty fix for issue where hal_nfc was busy on app start
* Furi: update allocator to erase memory on allocation. Replace furi_alloc with malloc.
* FuriCore: cleanup memmgr code.
* Furi HAL: furi_hal_init is split into critical and non-critical parts. The critical part is currently clock and console.
* Memmgr: added ability to track allocations and deallocations through console.
* FFStream: some speedup
* Streams, FF: minor fixes
* Tests: restore
* File stream: a slightly more thread-safe version of file_stream_delete_and_insert

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
SG
2022-02-19 05:53:46 +10:00
committed by GitHub
parent 242241987e
commit 274c12fc56
257 changed files with 4480 additions and 2657 deletions

View File

@@ -0,0 +1,227 @@
#include <furi.h>
#include <flipper_format/flipper_format.h>
#include <flipper_format/flipper_format_i.h>
#include <toolbox/stream/stream.h>
#include <storage/storage.h>
#include "../minunit.h"
static const char* test_filetype = "Flipper Format test";
static const uint32_t test_version = 666;
static const char* test_string_key = "String data";
static const char* test_string_data = "String";
static const char* test_string_updated_data = "New string";
static const char* test_int_key = "Int32 data";
static const int32_t test_int_data[] = {1234, -6345, 7813, 0};
static const int32_t test_int_updated_data[] = {-1337, 69};
static const char* test_uint_key = "Uint32 data";
static const uint32_t test_uint_data[] = {1234, 0, 5678, 9098, 7654321};
static const uint32_t test_uint_updated_data[] = {8, 800, 555, 35, 35};
static const char* test_float_key = "Float data";
static const float test_float_data[] = {1.5f, 1000.0f};
static const float test_float_updated_data[] = {1.2f};
static const char* test_hex_key = "Hex data";
static const uint8_t test_hex_data[] = {0xDE, 0xAD, 0xBE};
static const uint8_t test_hex_updated_data[] = {0xFE, 0xCA};
static const char* test_data_nix = "Filetype: Flipper Format test\n"
"Version: 666\n"
"# This is comment\n"
"String data: String\n"
"Int32 data: 1234 -6345 7813 0\n"
"Uint32 data: 1234 0 5678 9098 7654321\n"
"Float data: 1.5 1000.0\n"
"Hex data: DE AD BE";
static const char* test_data_win = "Filetype: Flipper Format test\r\n"
"Version: 666\r\n"
"# This is comment\r\n"
"String data: String\r\n"
"Int32 data: 1234 -6345 7813 0\r\n"
"Uint32 data: 1234 0 5678 9098 7654321\r\n"
"Float data: 1.5 1000.0\r\n"
"Hex data: DE AD BE";
#define ARRAY_W_COUNT(x) (x), (COUNT_OF(x))
#define ARRAY_W_BSIZE(x) (x), (sizeof(x))
MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) {
string_t tmpstr;
uint32_t version;
uint32_t uint32_data[COUNT_OF(test_uint_data)];
int32_t int32_data[COUNT_OF(test_int_data)];
float float_data[COUNT_OF(test_float_data)];
uint8_t hex_data[COUNT_OF(test_hex_data)];
uint32_t count;
mu_check(flipper_format_rewind(flipper_format));
string_init(tmpstr);
mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr));
mu_assert_int_eq(test_version, version);
mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
mu_assert_string_eq(test_string_data, string_get_cstr(tmpstr));
mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
mu_assert_int_eq(COUNT_OF(test_int_data), count);
mu_check(flipper_format_read_int32(flipper_format, test_int_key, ARRAY_W_COUNT(int32_data)));
mu_check(memcmp(test_int_data, ARRAY_W_BSIZE(int32_data)) == 0);
mu_check(flipper_format_get_value_count(flipper_format, test_uint_key, &count));
mu_assert_int_eq(COUNT_OF(test_uint_data), count);
mu_check(
flipper_format_read_uint32(flipper_format, test_uint_key, ARRAY_W_COUNT(uint32_data)));
mu_check(memcmp(test_uint_data, ARRAY_W_BSIZE(uint32_data)) == 0);
mu_check(flipper_format_get_value_count(flipper_format, test_float_key, &count));
mu_assert_int_eq(COUNT_OF(test_float_data), count);
mu_check(flipper_format_read_float(flipper_format, test_float_key, ARRAY_W_COUNT(float_data)));
mu_check(memcmp(test_float_data, ARRAY_W_BSIZE(float_data)) == 0);
mu_check(flipper_format_get_value_count(flipper_format, test_hex_key, &count));
mu_assert_int_eq(COUNT_OF(test_hex_data), count);
mu_check(flipper_format_read_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(hex_data)));
mu_check(memcmp(test_hex_data, ARRAY_W_BSIZE(hex_data)) == 0);
mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
string_clear(tmpstr);
mu_check(flipper_format_rewind(flipper_format));
mu_check(flipper_format_update_string_cstr(
flipper_format, test_string_key, test_string_updated_data));
mu_check(flipper_format_update_int32(
flipper_format, test_int_key, ARRAY_W_COUNT(test_int_updated_data)));
mu_check(flipper_format_update_uint32(
flipper_format, test_uint_key, ARRAY_W_COUNT(test_uint_updated_data)));
mu_check(flipper_format_update_float(
flipper_format, test_float_key, ARRAY_W_COUNT(test_float_updated_data)));
mu_check(flipper_format_update_hex(
flipper_format, test_hex_key, ARRAY_W_COUNT(test_hex_updated_data)));
uint32_t uint32_updated_data[COUNT_OF(test_uint_updated_data)];
int32_t int32_updated_data[COUNT_OF(test_int_updated_data)];
float float_updated_data[COUNT_OF(test_float_updated_data)];
uint8_t hex_updated_data[COUNT_OF(test_hex_updated_data)];
mu_check(flipper_format_rewind(flipper_format));
string_init(tmpstr);
mu_check(flipper_format_read_header(flipper_format, tmpstr, &version));
mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr));
mu_assert_int_eq(test_version, version);
mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr));
mu_assert_string_eq(test_string_updated_data, string_get_cstr(tmpstr));
mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count));
mu_assert_int_eq(COUNT_OF(test_int_updated_data), count);
mu_check(flipper_format_read_int32(
flipper_format, test_int_key, ARRAY_W_COUNT(int32_updated_data)));
mu_check(memcmp(test_int_updated_data, ARRAY_W_BSIZE(int32_updated_data)) == 0);
mu_check(flipper_format_get_value_count(flipper_format, test_uint_key, &count));
mu_assert_int_eq(COUNT_OF(test_uint_updated_data), count);
mu_check(flipper_format_read_uint32(
flipper_format, test_uint_key, ARRAY_W_COUNT(uint32_updated_data)));
mu_check(memcmp(test_uint_updated_data, ARRAY_W_BSIZE(uint32_updated_data)) == 0);
mu_check(flipper_format_get_value_count(flipper_format, test_float_key, &count));
mu_assert_int_eq(COUNT_OF(test_float_updated_data), count);
mu_check(flipper_format_read_float(
flipper_format, test_float_key, ARRAY_W_COUNT(float_updated_data)));
mu_check(memcmp(test_float_updated_data, ARRAY_W_BSIZE(float_updated_data)) == 0);
mu_check(flipper_format_get_value_count(flipper_format, test_hex_key, &count));
mu_assert_int_eq(COUNT_OF(test_hex_updated_data), count);
mu_check(
flipper_format_read_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(hex_updated_data)));
mu_check(memcmp(test_hex_updated_data, ARRAY_W_BSIZE(hex_updated_data)) == 0);
mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr));
string_clear(tmpstr);
mu_check(flipper_format_rewind(flipper_format));
mu_check(flipper_format_delete_key(flipper_format, test_uint_key));
mu_check(flipper_format_rewind(flipper_format));
mu_check(!flipper_format_read_uint32(
flipper_format, test_uint_key, ARRAY_W_COUNT(uint32_updated_data)));
}
MU_TEST(flipper_format_string_test) {
FlipperFormat* flipper_format = flipper_format_string_alloc();
Stream* stream = flipper_format_get_raw_stream(flipper_format);
mu_check(flipper_format_write_header_cstr(flipper_format, test_filetype, test_version));
mu_check(flipper_format_write_comment_cstr(flipper_format, "This is comment"));
mu_check(flipper_format_write_string_cstr(flipper_format, test_string_key, test_string_data));
mu_check(
flipper_format_write_int32(flipper_format, test_int_key, ARRAY_W_COUNT(test_int_data)));
mu_check(
flipper_format_write_uint32(flipper_format, test_uint_key, ARRAY_W_COUNT(test_uint_data)));
mu_check(flipper_format_write_float(
flipper_format, test_float_key, ARRAY_W_COUNT(test_float_data)));
mu_check(flipper_format_write_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(test_hex_data)));
MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
stream_clean(stream);
stream_write_cstring(stream, test_data_nix);
MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
stream_clean(stream);
stream_write_cstring(stream, test_data_win);
MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
flipper_format_free(flipper_format);
}
MU_TEST(flipper_format_file_test) {
Storage* storage = furi_record_open("storage");
FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
mu_check(flipper_format_file_open_always(flipper_format, "/ext/flipper.fff"));
Stream* stream = flipper_format_get_raw_stream(flipper_format);
mu_check(flipper_format_write_header_cstr(flipper_format, test_filetype, test_version));
mu_check(flipper_format_write_comment_cstr(flipper_format, "This is comment"));
mu_check(flipper_format_write_string_cstr(flipper_format, test_string_key, test_string_data));
mu_check(
flipper_format_write_int32(flipper_format, test_int_key, ARRAY_W_COUNT(test_int_data)));
mu_check(
flipper_format_write_uint32(flipper_format, test_uint_key, ARRAY_W_COUNT(test_uint_data)));
mu_check(flipper_format_write_float(
flipper_format, test_float_key, ARRAY_W_COUNT(test_float_data)));
mu_check(flipper_format_write_hex(flipper_format, test_hex_key, ARRAY_W_COUNT(test_hex_data)));
MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
stream_clean(stream);
stream_write_cstring(stream, test_data_nix);
MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
stream_clean(stream);
stream_write_cstring(stream, test_data_win);
MU_RUN_TEST_1(flipper_format_read_and_update_test, flipper_format);
flipper_format_free(flipper_format);
furi_record_close("storage");
}
MU_TEST_SUITE(flipper_format_string_suite) {
MU_RUN_TEST(flipper_format_string_test);
MU_RUN_TEST(flipper_format_file_test);
}
int run_minunit_test_flipper_format_string() {
MU_RUN_SUITE(flipper_format_string_suite);
return MU_EXIT_CODE;
}

View File

@@ -1,5 +1,7 @@
#include <furi.h>
#include <flipper_file/flipper_file.h>
#include <flipper_format/flipper_format.h>
#include <flipper_format/flipper_format_i.h>
#include <toolbox/stream/stream.h>
#include "../minunit.h"
#define TEST_DIR TEST_DIR_NAME "/"
@@ -28,8 +30,8 @@ static const char* test_hex_key = "Hex data";
static const uint8_t test_hex_data[] = {0xDE, 0xAD, 0xBE};
static const uint8_t test_hex_updated_data[] = {0xFE, 0xCA};
#define READ_TEST_WIN "ff_win.test"
static const char* test_data_win = "Filetype: Flipper File test\n"
#define READ_TEST_NIX "ff_nix.test"
static const char* test_data_nix = "Filetype: Flipper File test\n"
"Version: 666\n"
"# This is comment\n"
"String data: String\n"
@@ -38,8 +40,8 @@ static const char* test_data_win = "Filetype: Flipper File test\n"
"Float data: 1.5 1000.0\n"
"Hex data: DE AD BE";
#define READ_TEST_NIX "ff_nix.test"
static const char* test_data_nix = "Filetype: Flipper File test\r\n"
#define READ_TEST_WIN "ff_win.test"
static const char* test_data_win = "Filetype: Flipper File test\r\n"
"Version: 666\r\n"
"# This is comment\r\n"
"String data: String\r\n"
@@ -51,11 +53,11 @@ static const char* test_data_nix = "Filetype: Flipper File test\r\n"
#define READ_TEST_FLP "ff_flp.test"
// data created by user on linux machine
const char* test_file_linux = TEST_DIR READ_TEST_WIN;
static const char* test_file_linux = TEST_DIR READ_TEST_NIX;
// data created by user on windows machine
const char* test_file_windows = TEST_DIR READ_TEST_NIX;
static const char* test_file_windows = TEST_DIR READ_TEST_WIN;
// data created by flipper itself
const char* test_file_flipper = TEST_DIR READ_TEST_FLP;
static const char* test_file_flipper = TEST_DIR READ_TEST_FLP;
static bool storage_write_string(const char* path, const char* data) {
Storage* storage = furi_record_open("storage");
@@ -93,43 +95,43 @@ static bool test_read(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
string_t string_value;
string_init(string_value);
uint32_t uint32_value;
void* scratchpad = malloc(512);
do {
if(!flipper_file_open_existing(file, file_name)) break;
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_file_read_header(file, string_value, &uint32_value)) break;
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
if(string_cmp_str(string_value, test_filetype) != 0) break;
if(uint32_value != test_version) break;
if(!flipper_file_read_string(file, test_string_key, string_value)) break;
if(!flipper_format_read_string(file, test_string_key, string_value)) break;
if(string_cmp_str(string_value, test_string_data) != 0) break;
if(!flipper_file_get_value_count(file, test_int_key, &uint32_value)) break;
if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_int_data)) break;
if(!flipper_file_read_int32(file, test_int_key, scratchpad, uint32_value)) break;
if(!flipper_format_read_int32(file, test_int_key, scratchpad, uint32_value)) break;
if(memcmp(scratchpad, test_int_data, sizeof(int32_t) * COUNT_OF(test_int_data)) != 0)
break;
if(!flipper_file_get_value_count(file, test_uint_key, &uint32_value)) break;
if(!flipper_format_get_value_count(file, test_uint_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_uint_data)) break;
if(!flipper_file_read_uint32(file, test_uint_key, scratchpad, uint32_value)) break;
if(!flipper_format_read_uint32(file, test_uint_key, scratchpad, uint32_value)) break;
if(memcmp(scratchpad, test_uint_data, sizeof(uint32_t) * COUNT_OF(test_uint_data)) != 0)
break;
if(!flipper_file_get_value_count(file, test_float_key, &uint32_value)) break;
if(!flipper_format_get_value_count(file, test_float_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_float_data)) break;
if(!flipper_file_read_float(file, test_float_key, scratchpad, uint32_value)) break;
if(!flipper_format_read_float(file, test_float_key, scratchpad, uint32_value)) break;
if(memcmp(scratchpad, test_float_data, sizeof(float) * COUNT_OF(test_float_data)) != 0)
break;
if(!flipper_file_get_value_count(file, test_hex_key, &uint32_value)) break;
if(!flipper_format_get_value_count(file, test_hex_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_hex_data)) break;
if(!flipper_file_read_hex(file, test_hex_key, scratchpad, uint32_value)) break;
if(!flipper_format_read_hex(file, test_hex_key, scratchpad, uint32_value)) break;
if(memcmp(scratchpad, test_hex_data, sizeof(uint8_t) * COUNT_OF(test_hex_data)) != 0)
break;
@@ -138,8 +140,8 @@ static bool test_read(const char* file_name) {
free(scratchpad);
string_clear(string_value);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
@@ -150,52 +152,52 @@ static bool test_read_updated(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
string_t string_value;
string_init(string_value);
uint32_t uint32_value;
void* scratchpad = malloc(512);
do {
if(!flipper_file_open_existing(file, file_name)) break;
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_file_read_header(file, string_value, &uint32_value)) break;
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
if(string_cmp_str(string_value, test_filetype) != 0) break;
if(uint32_value != test_version) break;
if(!flipper_file_read_string(file, test_string_key, string_value)) break;
if(!flipper_format_read_string(file, test_string_key, string_value)) break;
if(string_cmp_str(string_value, test_string_updated_data) != 0) break;
if(!flipper_file_get_value_count(file, test_int_key, &uint32_value)) break;
if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_int_updated_data)) break;
if(!flipper_file_read_int32(file, test_int_key, scratchpad, uint32_value)) break;
if(!flipper_format_read_int32(file, test_int_key, scratchpad, uint32_value)) break;
if(memcmp(
scratchpad,
test_int_updated_data,
sizeof(int32_t) * COUNT_OF(test_int_updated_data)) != 0)
break;
if(!flipper_file_get_value_count(file, test_uint_key, &uint32_value)) break;
if(!flipper_format_get_value_count(file, test_uint_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_uint_updated_data)) break;
if(!flipper_file_read_uint32(file, test_uint_key, scratchpad, uint32_value)) break;
if(!flipper_format_read_uint32(file, test_uint_key, scratchpad, uint32_value)) break;
if(memcmp(
scratchpad,
test_uint_updated_data,
sizeof(uint32_t) * COUNT_OF(test_uint_updated_data)) != 0)
break;
if(!flipper_file_get_value_count(file, test_float_key, &uint32_value)) break;
if(!flipper_format_get_value_count(file, test_float_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_float_updated_data)) break;
if(!flipper_file_read_float(file, test_float_key, scratchpad, uint32_value)) break;
if(!flipper_format_read_float(file, test_float_key, scratchpad, uint32_value)) break;
if(memcmp(
scratchpad,
test_float_updated_data,
sizeof(float) * COUNT_OF(test_float_updated_data)) != 0)
break;
if(!flipper_file_get_value_count(file, test_hex_key, &uint32_value)) break;
if(!flipper_format_get_value_count(file, test_hex_key, &uint32_value)) break;
if(uint32_value != COUNT_OF(test_hex_updated_data)) break;
if(!flipper_file_read_hex(file, test_hex_key, scratchpad, uint32_value)) break;
if(!flipper_format_read_hex(file, test_hex_key, scratchpad, uint32_value)) break;
if(memcmp(
scratchpad,
test_hex_updated_data,
@@ -207,8 +209,8 @@ static bool test_read_updated(const char* file_name) {
free(scratchpad);
string_clear(string_value);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
@@ -218,28 +220,27 @@ static bool test_read_updated(const char* file_name) {
static bool test_write(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
do {
if(!flipper_file_open_always(file, file_name)) break;
if(!flipper_file_write_header_cstr(file, test_filetype, test_version)) break;
if(!flipper_file_write_comment_cstr(file, "This is comment")) break;
if(!flipper_file_write_string_cstr(file, test_string_key, test_string_data)) break;
if(!flipper_file_write_int32(file, test_int_key, test_int_data, COUNT_OF(test_int_data)))
if(!flipper_format_file_open_always(file, file_name)) break;
if(!flipper_format_write_header_cstr(file, test_filetype, test_version)) break;
if(!flipper_format_write_comment_cstr(file, "This is comment")) break;
if(!flipper_format_write_string_cstr(file, test_string_key, test_string_data)) break;
if(!flipper_format_write_int32(file, test_int_key, test_int_data, COUNT_OF(test_int_data)))
break;
if(!flipper_file_write_uint32(
if(!flipper_format_write_uint32(
file, test_uint_key, test_uint_data, COUNT_OF(test_uint_data)))
break;
if(!flipper_file_write_float(
if(!flipper_format_write_float(
file, test_float_key, test_float_data, COUNT_OF(test_float_data)))
break;
if(!flipper_file_write_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
if(!flipper_format_write_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
break;
result = true;
} while(false);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
return result;
@@ -248,16 +249,15 @@ static bool test_write(const char* file_name) {
static bool test_delete_last_key(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
do {
if(!flipper_file_open_existing(file, file_name)) break;
if(!flipper_file_delete_key(file, test_hex_key)) break;
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_format_delete_key(file, test_hex_key)) break;
result = true;
} while(false);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
return result;
@@ -266,17 +266,16 @@ static bool test_delete_last_key(const char* file_name) {
static bool test_append_key(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
do {
if(!flipper_file_open_append(file, file_name)) break;
if(!flipper_file_write_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
if(!flipper_format_file_open_append(file, file_name)) break;
if(!flipper_format_write_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
break;
result = true;
} while(false);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
return result;
@@ -285,30 +284,29 @@ static bool test_append_key(const char* file_name) {
static bool test_update(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
do {
if(!flipper_file_open_existing(file, file_name)) break;
if(!flipper_file_update_string_cstr(file, test_string_key, test_string_updated_data))
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_format_update_string_cstr(file, test_string_key, test_string_updated_data))
break;
if(!flipper_file_update_int32(
if(!flipper_format_update_int32(
file, test_int_key, test_int_updated_data, COUNT_OF(test_int_updated_data)))
break;
if(!flipper_file_update_uint32(
if(!flipper_format_update_uint32(
file, test_uint_key, test_uint_updated_data, COUNT_OF(test_uint_updated_data)))
break;
if(!flipper_file_update_float(
if(!flipper_format_update_float(
file, test_float_key, test_float_updated_data, COUNT_OF(test_float_updated_data)))
break;
if(!flipper_file_update_hex(
if(!flipper_format_update_hex(
file, test_hex_key, test_hex_updated_data, COUNT_OF(test_hex_updated_data)))
break;
result = true;
} while(false);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
return result;
@@ -317,27 +315,26 @@ static bool test_update(const char* file_name) {
static bool test_update_backward(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
do {
if(!flipper_file_open_existing(file, file_name)) break;
if(!flipper_file_update_string_cstr(file, test_string_key, test_string_data)) break;
if(!flipper_file_update_int32(file, test_int_key, test_int_data, COUNT_OF(test_int_data)))
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_format_update_string_cstr(file, test_string_key, test_string_data)) break;
if(!flipper_format_update_int32(file, test_int_key, test_int_data, COUNT_OF(test_int_data)))
break;
if(!flipper_file_update_uint32(
if(!flipper_format_update_uint32(
file, test_uint_key, test_uint_data, COUNT_OF(test_uint_data)))
break;
if(!flipper_file_update_float(
if(!flipper_format_update_float(
file, test_float_key, test_float_data, COUNT_OF(test_float_data)))
break;
if(!flipper_file_update_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
if(!flipper_format_update_hex(file, test_hex_key, test_hex_data, COUNT_OF(test_hex_data)))
break;
result = true;
} while(false);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
return result;
@@ -346,15 +343,15 @@ static bool test_update_backward(const char* file_name) {
static bool test_write_multikey(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
do {
if(!flipper_file_open_always(file, file_name)) break;
if(!flipper_file_write_header_cstr(file, test_filetype, test_version)) break;
if(!flipper_format_file_open_always(file, file_name)) break;
if(!flipper_format_write_header_cstr(file, test_filetype, test_version)) break;
bool error = false;
for(uint8_t index = 0; index < 100; index++) {
if(!flipper_file_write_hex(file, test_hex_key, &index, 1)) {
if(!flipper_format_write_hex(file, test_hex_key, &index, 1)) {
error = true;
break;
}
@@ -364,8 +361,7 @@ static bool test_write_multikey(const char* file_name) {
result = true;
} while(false);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
return result;
@@ -374,22 +370,22 @@ static bool test_write_multikey(const char* file_name) {
static bool test_read_multikey(const char* file_name) {
Storage* storage = furi_record_open("storage");
bool result = false;
FlipperFile* file = flipper_file_alloc(storage);
FlipperFormat* file = flipper_format_file_alloc(storage);
string_t string_value;
string_init(string_value);
uint32_t uint32_value;
do {
if(!flipper_file_open_existing(file, file_name)) break;
if(!flipper_file_read_header(file, string_value, &uint32_value)) break;
if(!flipper_format_file_open_existing(file, file_name)) break;
if(!flipper_format_read_header(file, string_value, &uint32_value)) break;
if(string_cmp_str(string_value, test_filetype) != 0) break;
if(uint32_value != test_version) break;
bool error = false;
uint8_t uint8_value;
for(uint8_t index = 0; index < 100; index++) {
if(!flipper_file_read_hex(file, test_hex_key, &uint8_value, 1)) {
if(!flipper_format_read_hex(file, test_hex_key, &uint8_value, 1)) {
error = true;
break;
}
@@ -405,96 +401,96 @@ static bool test_read_multikey(const char* file_name) {
} while(false);
string_clear(string_value);
flipper_file_close(file);
flipper_file_free(file);
flipper_format_free(file);
furi_record_close("storage");
return result;
}
MU_TEST(flipper_file_write_test) {
MU_TEST(flipper_format_write_test) {
mu_assert(storage_write_string(test_file_linux, test_data_nix), "Write test error [Linux]");
mu_assert(
storage_write_string(test_file_windows, test_data_win), "Write test error [Windows]");
mu_assert(test_write(test_file_flipper), "Write test error [Flipper]");
}
MU_TEST(flipper_file_read_test) {
MU_TEST(flipper_format_read_test) {
mu_assert(test_read(test_file_linux), "Read test error [Linux]");
mu_assert(test_read(test_file_windows), "Read test error [Windows]");
mu_assert(test_read(test_file_flipper), "Read test error [Flipper]");
}
MU_TEST(flipper_file_delete_test) {
MU_TEST(flipper_format_delete_test) {
mu_assert(test_delete_last_key(test_file_linux), "Cannot delete key [Linux]");
mu_assert(test_delete_last_key(test_file_windows), "Cannot delete key [Windows]");
mu_assert(test_delete_last_key(test_file_flipper), "Cannot delete key [Flipper]");
}
MU_TEST(flipper_file_delete_result_test) {
MU_TEST(flipper_format_delete_result_test) {
mu_assert(!test_read(test_file_linux), "Key deleted incorrectly [Linux]");
mu_assert(!test_read(test_file_windows), "Key deleted incorrectly [Windows]");
mu_assert(!test_read(test_file_flipper), "Key deleted incorrectly [Flipper]");
}
MU_TEST(flipper_file_append_test) {
MU_TEST(flipper_format_append_test) {
mu_assert(test_append_key(test_file_linux), "Cannot append data [Linux]");
mu_assert(test_append_key(test_file_windows), "Cannot append data [Windows]");
mu_assert(test_append_key(test_file_flipper), "Cannot append data [Flipper]");
}
MU_TEST(flipper_file_append_result_test) {
MU_TEST(flipper_format_append_result_test) {
mu_assert(test_read(test_file_linux), "Data appended incorrectly [Linux]");
mu_assert(test_read(test_file_windows), "Data appended incorrectly [Windows]");
mu_assert(test_read(test_file_flipper), "Data appended incorrectly [Flipper]");
}
MU_TEST(flipper_file_update_1_test) {
MU_TEST(flipper_format_update_1_test) {
mu_assert(test_update(test_file_linux), "Cannot update data #1 [Linux]");
mu_assert(test_update(test_file_windows), "Cannot update data #1 [Windows]");
mu_assert(test_update(test_file_flipper), "Cannot update data #1 [Flipper]");
}
MU_TEST(flipper_file_update_1_result_test) {
MU_TEST(flipper_format_update_1_result_test) {
mu_assert(test_read_updated(test_file_linux), "Data #1 updated incorrectly [Linux]");
mu_assert(test_read_updated(test_file_windows), "Data #1 updated incorrectly [Windows]");
mu_assert(test_read_updated(test_file_flipper), "Data #1 updated incorrectly [Flipper]");
}
MU_TEST(flipper_file_update_2_test) {
MU_TEST(flipper_format_update_2_test) {
mu_assert(test_update_backward(test_file_linux), "Cannot update data #2 [Linux]");
mu_assert(test_update_backward(test_file_windows), "Cannot update data #2 [Windows]");
mu_assert(test_update_backward(test_file_flipper), "Cannot update data #2 [Flipper]");
}
MU_TEST(flipper_file_update_2_result_test) {
MU_TEST(flipper_format_update_2_result_test) {
mu_assert(test_read(test_file_linux), "Data #2 updated incorrectly [Linux]");
mu_assert(test_read(test_file_windows), "Data #2 updated incorrectly [Windows]");
mu_assert(test_read(test_file_flipper), "Data #2 updated incorrectly [Flipper]");
}
MU_TEST(flipper_file_multikey_test) {
MU_TEST(flipper_format_multikey_test) {
mu_assert(test_write_multikey(TEST_DIR "ff_multiline.test"), "Multikey write test error");
mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error");
}
MU_TEST_SUITE(flipper_file) {
MU_TEST_SUITE(flipper_format) {
tests_setup();
MU_RUN_TEST(flipper_file_write_test);
MU_RUN_TEST(flipper_file_read_test);
MU_RUN_TEST(flipper_file_delete_test);
MU_RUN_TEST(flipper_file_delete_result_test);
MU_RUN_TEST(flipper_file_append_test);
MU_RUN_TEST(flipper_file_append_result_test);
MU_RUN_TEST(flipper_file_update_1_test);
MU_RUN_TEST(flipper_file_update_1_result_test);
MU_RUN_TEST(flipper_file_update_2_test);
MU_RUN_TEST(flipper_file_update_2_result_test);
MU_RUN_TEST(flipper_file_multikey_test);
MU_RUN_TEST(flipper_format_write_test);
MU_RUN_TEST(flipper_format_read_test);
MU_RUN_TEST(flipper_format_delete_test);
MU_RUN_TEST(flipper_format_delete_result_test);
MU_RUN_TEST(flipper_format_append_test);
MU_RUN_TEST(flipper_format_append_result_test);
MU_RUN_TEST(flipper_format_update_1_test);
MU_RUN_TEST(flipper_format_update_1_result_test);
MU_RUN_TEST(flipper_format_update_2_test);
MU_RUN_TEST(flipper_format_update_2_result_test);
MU_RUN_TEST(flipper_format_multikey_test);
tests_teardown();
}
int run_minunit_test_flipper_file() {
MU_RUN_SUITE(flipper_file);
int run_minunit_test_flipper_format() {
MU_RUN_SUITE(flipper_format);
return MU_EXIT_CODE;
}
}

View File

@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// this test is not accurate, but gives a basic understanding
// that memory management is working fine
@@ -96,4 +97,4 @@ void test_furi_memmgr() {
free(original_ptr);
free(ptr);
}
}

View File

@@ -88,7 +88,7 @@ static void run_encoder(
uint32_t* timings = 0;
uint32_t timings_len = 200;
uint32_t j = 0;
timings = furi_alloc(sizeof(uint32_t) * timings_len);
timings = malloc(sizeof(uint32_t) * timings_len);
for(uint32_t message_counter = 0; message_counter < input_messages_len; ++message_counter) {
const IrdaMessage* message = &input_messages[message_counter];
@@ -113,7 +113,7 @@ static void run_encoder_decoder(const IrdaMessage input_messages[], uint32_t inp
uint32_t* timings = 0;
uint32_t timings_len = 200;
bool level = false;
timings = furi_alloc(sizeof(uint32_t) * timings_len);
timings = malloc(sizeof(uint32_t) * timings_len);
for(uint32_t message_counter = 0; message_counter < input_messages_len; ++message_counter) {
const IrdaMessage* message_encoded = &input_messages[message_counter];

View File

@@ -84,6 +84,7 @@ void minunit_print_fail(const char* error);
/* Definitions */
#define MU_TEST(method_name) static void method_name(void)
#define MU_TEST_1(method_name, arg_1) static void method_name(arg_1)
#define MU_TEST_SUITE(suite_name) static void suite_name(void)
#define MU__SAFE_BLOCK(block) \
@@ -107,11 +108,30 @@ void minunit_print_fail(const char* error);
minunit_proc_timer = mu_timer_cpu(); \
} if(minunit_setup) (*minunit_setup)(); \
minunit_status = 0; \
printf(#test "()\r\n"); \
test(); \
minunit_run++; \
if(minunit_status) { \
minunit_fail++; \
minunit_print_fail(minunit_last_message); \
minunit_status = 0; \
} fflush(stdout); \
if(minunit_teardown)(*minunit_teardown)();)
#define MU_RUN_TEST_1(test, arg_1) \
MU__SAFE_BLOCK( \
if(minunit_real_timer == 0 && minunit_proc_timer == 0) { \
minunit_real_timer = mu_timer_real(); \
minunit_proc_timer = mu_timer_cpu(); \
} if(minunit_setup) (*minunit_setup)(); \
minunit_status = 0; \
printf(#test "(" #arg_1 ")\r\n"); \
test(arg_1); \
minunit_run++; \
if(minunit_status) { \
minunit_fail++; \
minunit_print_fail(minunit_last_message); \
minunit_status = 0; \
} fflush(stdout); \
if(minunit_teardown)(*minunit_teardown)();)

View File

@@ -136,9 +136,9 @@ static void clean_directory(Storage* fs_api, const char* clean_dir) {
File* dir = storage_file_alloc(fs_api);
if(storage_dir_open(dir, clean_dir)) {
FileInfo fileinfo;
char* name = furi_alloc(MAX_NAME_LENGTH + 1);
char* name = malloc(MAX_NAME_LENGTH + 1);
while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
char* fullname = furi_alloc(strlen(clean_dir) + strlen(name) + 1 + 1);
char* fullname = malloc(strlen(clean_dir) + strlen(name) + 1 + 1);
sprintf(fullname, "%s/%s", clean_dir, name);
if(fileinfo.flags & FSF_DIRECTORY) {
clean_directory(fs_api, fullname);
@@ -310,7 +310,7 @@ static void test_rpc_add_read_or_write_to_list(
msg_file = &request->content.storage_read_response.file;
}
msg_file->data = furi_alloc(PB_BYTES_ARRAY_T_ALLOCSIZE(pattern_size));
msg_file->data = malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(pattern_size));
msg_file->data->size = pattern_size;
memcpy(msg_file->data->bytes, pattern, pattern_size);
@@ -328,7 +328,7 @@ static void test_rpc_encode_and_feed_one(PB_Main* request) {
bool result = pb_encode_ex(&ostream, &PB_Main_msg, request, PB_ENCODE_DELIMITED);
furi_check(result && ostream.bytes_written);
uint8_t* buffer = furi_alloc(ostream.bytes_written);
uint8_t* buffer = malloc(ostream.bytes_written);
ostream = pb_ostream_from_buffer(buffer, ostream.bytes_written);
pb_encode_ex(&ostream, &PB_Main_msg, request, PB_ENCODE_DELIMITED);
@@ -501,13 +501,13 @@ static void
message->content.storage_list_response.file[1].type = PB_Storage_File_FileType_DIR;
message->content.storage_list_response.file[2].type = PB_Storage_File_FileType_DIR;
char* str = furi_alloc(4);
char* str = malloc(4);
strcpy(str, "any");
message->content.storage_list_response.file[0].name = str;
str = furi_alloc(4);
str = malloc(4);
strcpy(str, "int");
message->content.storage_list_response.file[1].name = str;
str = furi_alloc(4);
str = malloc(4);
strcpy(str, "ext");
message->content.storage_list_response.file[2].name = str;
}
@@ -540,7 +540,7 @@ static void test_rpc_storage_list_create_expected_list(
while(!finish) {
FileInfo fileinfo;
char* name = furi_alloc(MAX_NAME_LENGTH + 1);
char* name = malloc(MAX_NAME_LENGTH + 1);
if(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
if(i == COUNT_OF(list->file)) {
list->file_count = i;
@@ -675,7 +675,7 @@ static void test_rpc_add_read_to_list_by_reading_real_file(
response->content.storage_read_response.has_file = true;
response->content.storage_read_response.file.data =
furi_alloc(PB_BYTES_ARRAY_T_ALLOCSIZE(MIN(size_left, MAX_DATA_SIZE)));
malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(MIN(size_left, MAX_DATA_SIZE)));
uint8_t* buffer = response->content.storage_read_response.file.data->bytes;
uint16_t* read_size_msg = &response->content.storage_read_response.file.data->size;
size_t read_size = MIN(size_left, MAX_DATA_SIZE);
@@ -873,7 +873,7 @@ static void test_storage_write_run(
MsgList_t expected_msg_list;
MsgList_init(expected_msg_list);
uint8_t* buf = furi_alloc(write_size);
uint8_t* buf = malloc(write_size);
for(int i = 0; i < write_size; ++i) {
buf[i] = '0' + (i % 10);
}
@@ -1497,7 +1497,7 @@ MU_TEST_SUITE(test_rpc_app) {
static void
test_send_rubbish(RpcSession* session, const char* pattern, size_t pattern_size, size_t size) {
uint8_t* buf = furi_alloc(size);
uint8_t* buf = malloc(size);
for(int i = 0; i < size; ++i) {
buf[i] = pattern[i % pattern_size];
}

View File

@@ -0,0 +1,381 @@
#include <furi.h>
#include <toolbox/stream/stream.h>
#include <toolbox/stream/string_stream.h>
#include <toolbox/stream/file_stream.h>
#include <storage/storage.h>
#include "../minunit.h"
static const char* stream_test_data = "I write differently from what I speak, "
"I speak differently from what I think, "
"I think differently from the way I ought to think, "
"and so it all proceeds into deepest darkness.";
static const char* stream_test_left_data = "There are two cardinal human sins ";
static const char* stream_test_right_data =
"from which all others derive: impatience and indolence.";
MU_TEST_1(stream_composite_subtest, Stream* stream) {
const size_t data_size = 128;
uint8_t data[data_size];
string_t string_lee;
string_init_set(string_lee, "lee");
// test that stream is empty
// "" -> ""
mu_check(stream_size(stream) == 0);
mu_check(stream_eof(stream));
mu_check(stream_tell(stream) == 0);
mu_check(stream_read(stream, data, data_size) == 0);
mu_check(stream_eof(stream));
mu_check(stream_tell(stream) == 0);
// write char
// "" -> "2"
mu_check(stream_write_char(stream, '2') == 1);
mu_check(stream_size(stream) == 1);
mu_check(stream_tell(stream) == 1);
mu_check(stream_eof(stream));
// test rewind and eof
stream_rewind(stream);
mu_check(stream_size(stream) == 1);
mu_check(stream_tell(stream) == 0);
mu_check(!stream_eof(stream));
// add another char with replacement
// "2" -> "1"
mu_check(stream_write_char(stream, '1') == 1);
mu_check(stream_size(stream) == 1);
mu_check(stream_tell(stream) == 1);
mu_check(stream_eof(stream));
// write string
// "1" -> "1337_69"
mu_check(stream_write_cstring(stream, "337_69") == 6);
mu_check(stream_size(stream) == 7);
mu_check(stream_tell(stream) == 7);
mu_check(stream_eof(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_check(stream_read(stream, data, data_size) == 7);
mu_check(strcmp((char*)data, "1337_69") == 0);
// test misc seeks
mu_check(stream_seek(stream, 2, StreamOffsetFromStart));
mu_check(stream_tell(stream) == 2);
mu_check(!stream_seek(stream, 9000, StreamOffsetFromStart));
mu_check(stream_tell(stream) == 7);
mu_check(stream_eof(stream));
mu_check(stream_seek(stream, -3, StreamOffsetFromEnd));
mu_check(stream_tell(stream) == 4);
// write string with replacemet
// "1337_69" -> "1337lee"
mu_check(stream_write_string(stream, string_lee) == 3);
mu_check(stream_size(stream) == 7);
mu_check(stream_tell(stream) == 7);
mu_check(stream_eof(stream));
// append char
// "1337lee" -> "1337leet"
mu_check(stream_write(stream, (uint8_t*)"t", 1) == 1);
mu_check(stream_size(stream) == 8);
mu_check(stream_tell(stream) == 8);
mu_check(stream_eof(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_check(stream_read(stream, data, data_size) == 8);
mu_check(strcmp((char*)data, "1337leet") == 0);
mu_check(stream_tell(stream) == 8);
mu_check(stream_eof(stream));
// negative seek from current position -> clamp to 0
mu_check(!stream_seek(stream, -9000, StreamOffsetFromCurrent));
mu_check(stream_tell(stream) == 0);
// negative seek from start position -> clamp to 0
stream_rewind(stream);
mu_check(!stream_seek(stream, -3, StreamOffsetFromStart));
mu_check(stream_tell(stream) == 0);
// zero seek from current position -> clamp to stream size
mu_check(stream_seek(stream, 0, StreamOffsetFromEnd));
mu_check(stream_tell(stream) == 8);
// negative seek from end position -> clamp to 0
mu_check(!stream_seek(stream, -9000, StreamOffsetFromEnd));
mu_check(stream_tell(stream) == 0);
// clean stream
stream_clean(stream);
mu_check(stream_size(stream) == 0);
mu_check(stream_eof(stream));
mu_check(stream_tell(stream) == 0);
// write format
// "" -> "dio666"
mu_check(stream_write_format(stream, "%s%d", "dio", 666) == 6);
mu_check(stream_size(stream) == 6);
mu_check(stream_eof(stream));
mu_check(stream_tell(stream) == 6);
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_check(stream_read(stream, data, data_size) == 6);
mu_check(strcmp((char*)data, "dio666") == 0);
// clean and write cstring
// "dio666" -> "" -> "1234567890"
stream_clean(stream);
mu_check(stream_write_cstring(stream, "1234567890") == 10);
// delete 4 bytes from 1 pos
// "1xxxx67890" -> "167890"
mu_check(stream_seek(stream, 1, StreamOffsetFromStart));
mu_check(stream_delete(stream, 4));
mu_assert_int_eq(6, stream_size(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_assert_int_eq(6, stream_read(stream, data, data_size));
mu_check(strcmp((char*)data, "167890") == 0);
// write cstring
// "167890" -> "167890It Was Me, Dio!"
mu_check(stream_write_cstring(stream, "It Was Me, Dio!") == 15);
// delete 1337 bytes from 1 pos
// and check that we can delete only 20 bytes
// "1xxxxxxxxxxxxxxxxxxxx" -> "1"
mu_check(stream_seek(stream, 1, StreamOffsetFromStart));
mu_check(stream_delete(stream, 1337));
mu_assert_int_eq(1, stream_size(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_check(stream_read(stream, data, data_size) == 1);
mu_check(strcmp((char*)data, "1") == 0);
// write cstring from 0 pos, replacing 1 byte
// "1" -> "Oh? You're roaching me?"
mu_check(stream_rewind(stream));
mu_assert_int_eq(23, stream_write_cstring(stream, "Oh? You're roaching me?"));
// insert 11 bytes to 0 pos
// "Oh? You're roaching me?" -> "Za Warudo! Oh? You're roaching me?"
mu_check(stream_rewind(stream));
mu_check(stream_insert(stream, (uint8_t*)"Za Warudo! ", 11));
mu_assert_int_eq(34, stream_size(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_assert_int_eq(34, stream_read(stream, data, data_size));
mu_assert_string_eq("Za Warudo! Oh? You're roaching me?", (char*)data);
// insert cstring to 22 pos
// "Za Warudo! Oh? You're roaching me?" -> "Za Warudo! Oh? You're approaching me?"
mu_check(stream_seek(stream, 22, StreamOffsetFromStart));
mu_check(stream_insert_cstring(stream, "app"));
mu_assert_int_eq(37, stream_size(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_assert_int_eq(37, stream_read(stream, data, data_size));
mu_assert_string_eq("Za Warudo! Oh? You're approaching me?", (char*)data);
// insert cstring to the end of the stream
// "Za Warudo! Oh? You're approaching me?" -> "Za Warudo! Oh? You're approaching me? It was me, Dio!"
mu_check(stream_seek(stream, 0, StreamOffsetFromEnd));
mu_check(stream_insert_cstring(stream, " It was me, Dio!"));
mu_assert_int_eq(53, stream_size(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_assert_int_eq(53, stream_read(stream, data, data_size));
mu_assert_string_eq("Za Warudo! Oh? You're approaching me? It was me, Dio!", (char*)data);
// delete 168430090 bytes from stream
// and test that we can delete only 53
mu_check(stream_rewind(stream));
mu_check(stream_delete(stream, 0x0A0A0A0A));
mu_assert_int_eq(0, stream_size(stream));
mu_check(stream_eof(stream));
mu_assert_int_eq(0, stream_tell(stream));
// clean stream
stream_clean(stream);
mu_assert_int_eq(0, stream_size(stream));
mu_check(stream_eof(stream));
mu_assert_int_eq(0, stream_tell(stream));
// insert formated string at the end of stream
// "" -> "dio666"
mu_check(stream_insert_format(stream, "%s%d", "dio", 666));
mu_assert_int_eq(6, stream_size(stream));
mu_check(stream_eof(stream));
mu_assert_int_eq(6, stream_tell(stream));
// insert formated string at the end of stream
// "dio666" -> "dio666zlo555"
mu_check(stream_insert_format(stream, "%s%d", "zlo", 555));
mu_assert_int_eq(12, stream_size(stream));
mu_check(stream_eof(stream));
mu_assert_int_eq(12, stream_tell(stream));
// insert formated string at the 6 pos
// "dio666" -> "dio666baba13zlo555"
mu_check(stream_seek(stream, 6, StreamOffsetFromStart));
mu_check(stream_insert_format(stream, "%s%d", "baba", 13));
mu_assert_int_eq(18, stream_size(stream));
mu_assert_int_eq(12, stream_tell(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_assert_int_eq(18, stream_read(stream, data, data_size));
mu_assert_string_eq("dio666baba13zlo555", (char*)data);
// delete 6 chars from pos 6 and insert 1 chars
// "dio666baba13zlo555" -> "dio666xzlo555"
mu_check(stream_seek(stream, 6, StreamOffsetFromStart));
mu_check(stream_delete_and_insert_char(stream, 6, 'x'));
mu_assert_int_eq(13, stream_size(stream));
mu_assert_int_eq(7, stream_tell(stream));
// read data
memset(data, 0, data_size);
stream_rewind(stream);
mu_check(stream_read(stream, data, data_size) == 13);
mu_assert_string_eq("dio666xzlo555", (char*)data);
// delete 9000 chars from pos 6 and insert 3 chars from string
// "dio666xzlo555" -> "dio666777"
mu_check(stream_seek(stream, 6, StreamOffsetFromStart));
mu_check(stream_delete_and_insert_cstring(stream, 9000, "777"));
mu_assert_int_eq(9, stream_size(stream));
mu_assert_int_eq(9, stream_tell(stream));
mu_check(stream_eof(stream));
string_clear(string_lee);
}
MU_TEST(stream_composite_test) {
// test string stream
Stream* stream;
stream = string_stream_alloc();
MU_RUN_TEST_1(stream_composite_subtest, stream);
stream_free(stream);
// test file stream
Storage* storage = furi_record_open("storage");
stream = file_stream_alloc(storage);
mu_check(file_stream_open(stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
MU_RUN_TEST_1(stream_composite_subtest, stream);
stream_free(stream);
furi_record_close("storage");
}
MU_TEST_1(stream_write_subtest, Stream* stream) {
mu_assert_int_eq(strlen(stream_test_data), stream_write_cstring(stream, stream_test_data));
}
MU_TEST_1(stream_read_subtest, Stream* stream) {
uint8_t data[256] = {0};
mu_check(stream_rewind(stream));
mu_assert_int_eq(strlen(stream_test_data), stream_read(stream, data, 256));
mu_assert_string_eq(stream_test_data, (const char*)data);
}
MU_TEST(stream_write_read_save_load_test) {
Stream* stream_orig = string_stream_alloc();
Stream* stream_copy = string_stream_alloc();
Storage* storage = furi_record_open("storage");
// write, read
MU_RUN_TEST_1(stream_write_subtest, stream_orig);
MU_RUN_TEST_1(stream_read_subtest, stream_orig);
// copy, read
mu_assert_int_eq(strlen(stream_test_data), stream_copy_full(stream_orig, stream_copy));
MU_RUN_TEST_1(stream_read_subtest, stream_orig);
// save to file
mu_check(stream_seek(stream_orig, 0, StreamOffsetFromStart));
mu_assert_int_eq(
strlen(stream_test_data),
stream_save_to_file(stream_orig, storage, "/ext/filestream.str", FSOM_CREATE_ALWAYS));
stream_free(stream_copy);
stream_free(stream_orig);
// load from file, read
Stream* stream_new = string_stream_alloc();
mu_assert_int_eq(
strlen(stream_test_data),
stream_load_from_file(stream_new, storage, "/ext/filestream.str"));
MU_RUN_TEST_1(stream_read_subtest, stream_new);
stream_free(stream_new);
furi_record_close("storage");
}
MU_TEST_1(stream_split_subtest, Stream* stream) {
stream_clean(stream);
stream_write_cstring(stream, stream_test_left_data);
stream_write_cstring(stream, stream_test_right_data);
Stream* stream_left = string_stream_alloc();
Stream* stream_right = string_stream_alloc();
mu_check(stream_seek(stream, strlen(stream_test_left_data), StreamOffsetFromStart));
mu_check(stream_split(stream, stream_left, stream_right));
uint8_t data[256] = {0};
mu_check(stream_rewind(stream_left));
mu_assert_int_eq(strlen(stream_test_left_data), stream_read(stream_left, data, 256));
mu_assert_string_eq(stream_test_left_data, (const char*)data);
mu_check(stream_rewind(stream_right));
mu_assert_int_eq(strlen(stream_test_right_data), stream_read(stream_right, data, 256));
mu_assert_string_eq(stream_test_right_data, (const char*)data);
stream_free(stream_right);
stream_free(stream_left);
}
MU_TEST(stream_split_test) {
// test string stream
Stream* stream;
stream = string_stream_alloc();
MU_RUN_TEST_1(stream_split_subtest, stream);
stream_free(stream);
// test file stream
Storage* storage = furi_record_open("storage");
stream = file_stream_alloc(storage);
mu_check(file_stream_open(stream, "/ext/filestream.str", FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
MU_RUN_TEST_1(stream_split_subtest, stream);
stream_free(stream);
furi_record_close("storage");
}
MU_TEST_SUITE(stream_suite) {
MU_RUN_TEST(stream_write_read_save_load_test);
MU_RUN_TEST(stream_composite_test);
MU_RUN_TEST(stream_split_test);
}
int run_minunit_test_stream() {
MU_RUN_SUITE(stream_suite);
return MU_EXIT_CODE;
}

View File

@@ -13,7 +13,9 @@
int run_minunit();
int run_minunit_test_irda_decoder_encoder();
int run_minunit_test_rpc();
int run_minunit_test_flipper_file();
int run_minunit_test_flipper_format();
int run_minunit_test_flipper_format_string();
int run_minunit_test_stream();
void minunit_print_progress(void) {
static char progress[] = {'\\', '|', '/', '-'};
@@ -27,7 +29,7 @@ void minunit_print_progress(void) {
}
void minunit_print_fail(const char* str) {
printf("%s\n", str);
printf(FURI_LOG_CLR_E "%s\n" FURI_LOG_CLR_RESET, str);
}
void unit_tests_cli(Cli* cli, string_t args, void* context) {
@@ -53,7 +55,9 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) {
test_result |= run_minunit();
test_result |= run_minunit_test_irda_decoder_encoder();
test_result |= run_minunit_test_rpc();
test_result |= run_minunit_test_flipper_file();
test_result |= run_minunit_test_stream();
test_result |= run_minunit_test_flipper_format();
test_result |= run_minunit_test_flipper_format_string();
cycle_counter = (DWT->CYCCNT - cycle_counter);
FURI_LOG_I(TAG, "Consumed: %0.2fs", (float)cycle_counter / (SystemCoreClock));