Various improvements: Toolbox, Updater and Unit Tests. (#2250)
* Toolbox: add seek to character stream method. UpdateUtils: reverse manifest iterator. UnitTests: more unit tests. * Target: bump API version. Updater: delete empty folders from manifest before resource deployment. * UnitTests: use manifest from unit_tests folder instead of global one * Make PVS happy * sector cache: allocate always * Better PVS config for manifest.c * PVS: Move exception outside of condition * PVS: remove confusing condition Co-authored-by: SG <who.just.the.doctor@gmail.com>
This commit is contained in:
75
applications/debug/unit_tests/manifest/manifest.c
Normal file
75
applications/debug/unit_tests/manifest/manifest.c
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <furi.c>
|
||||
#include "../minunit.h"
|
||||
#include <update_util/resources/manifest.h>
|
||||
|
||||
#define TAG "Manifest"
|
||||
|
||||
MU_TEST(manifest_type_test) {
|
||||
mu_assert(ResourceManifestEntryTypeUnknown == 0, "ResourceManifestEntryTypeUnknown != 0\r\n");
|
||||
mu_assert(ResourceManifestEntryTypeVersion == 1, "ResourceManifestEntryTypeVersion != 1\r\n");
|
||||
mu_assert(
|
||||
ResourceManifestEntryTypeTimestamp == 2, "ResourceManifestEntryTypeTimestamp != 2\r\n");
|
||||
mu_assert(
|
||||
ResourceManifestEntryTypeDirectory == 3, "ResourceManifestEntryTypeDirectory != 3\r\n");
|
||||
mu_assert(ResourceManifestEntryTypeFile == 4, "ResourceManifestEntryTypeFile != 4\r\n");
|
||||
}
|
||||
|
||||
MU_TEST(manifest_iteration_test) {
|
||||
bool result = true;
|
||||
size_t counters[5] = {0};
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(storage);
|
||||
do {
|
||||
// Open manifest file
|
||||
if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("unit_tests/Manifest"))) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Iterate forward
|
||||
ResourceManifestEntry* entry_ptr = NULL;
|
||||
while((entry_ptr = resource_manifest_reader_next(manifest_reader))) {
|
||||
FURI_LOG_D(TAG, "F:%u:%s", entry_ptr->type, furi_string_get_cstr(entry_ptr->name));
|
||||
if(entry_ptr->type > 4) {
|
||||
mu_fail("entry_ptr->type > 4\r\n");
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
counters[entry_ptr->type]++;
|
||||
}
|
||||
if(!result) break;
|
||||
|
||||
// Iterate backward
|
||||
while((entry_ptr = resource_manifest_reader_previous(manifest_reader))) {
|
||||
FURI_LOG_D(TAG, "B:%u:%s", entry_ptr->type, furi_string_get_cstr(entry_ptr->name));
|
||||
if(entry_ptr->type > 4) {
|
||||
mu_fail("entry_ptr->type > 4\r\n");
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
counters[entry_ptr->type]--;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
resource_manifest_reader_free(manifest_reader);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
mu_assert(counters[ResourceManifestEntryTypeUnknown] == 0, "Unknown counter != 0\r\n");
|
||||
mu_assert(counters[ResourceManifestEntryTypeVersion] == 0, "Version counter != 0\r\n");
|
||||
mu_assert(counters[ResourceManifestEntryTypeTimestamp] == 0, "Timestamp counter != 0\r\n");
|
||||
mu_assert(counters[ResourceManifestEntryTypeDirectory] == 0, "Directory counter != 0\r\n");
|
||||
mu_assert(counters[ResourceManifestEntryTypeFile] == 0, "File counter != 0\r\n");
|
||||
|
||||
mu_assert(result, "Manifest forward iterate failed\r\n");
|
||||
}
|
||||
|
||||
MU_TEST_SUITE(manifest_suite) {
|
||||
MU_RUN_TEST(manifest_type_test);
|
||||
MU_RUN_TEST(manifest_iteration_test);
|
||||
}
|
||||
|
||||
int run_minunit_test_manifest() {
|
||||
MU_RUN_SUITE(manifest_suite);
|
||||
return MU_EXIT_CODE;
|
||||
}
|
@@ -72,8 +72,32 @@ MU_TEST_1(stream_composite_subtest, Stream* stream) {
|
||||
mu_check(stream_seek(stream, -3, StreamOffsetFromEnd));
|
||||
mu_check(stream_tell(stream) == 4);
|
||||
|
||||
// test seeks to char. content: '1337_69'
|
||||
stream_rewind(stream);
|
||||
mu_check(stream_seek_to_char(stream, '3', StreamDirectionForward));
|
||||
mu_check(stream_tell(stream) == 1);
|
||||
mu_check(stream_seek_to_char(stream, '3', StreamDirectionForward));
|
||||
mu_check(stream_tell(stream) == 2);
|
||||
mu_check(stream_seek_to_char(stream, '_', StreamDirectionForward));
|
||||
mu_check(stream_tell(stream) == 4);
|
||||
mu_check(stream_seek_to_char(stream, '9', StreamDirectionForward));
|
||||
mu_check(stream_tell(stream) == 6);
|
||||
mu_check(!stream_seek_to_char(stream, '9', StreamDirectionForward));
|
||||
mu_check(stream_tell(stream) == 6);
|
||||
mu_check(stream_seek_to_char(stream, '_', StreamDirectionBackward));
|
||||
mu_check(stream_tell(stream) == 4);
|
||||
mu_check(stream_seek_to_char(stream, '3', StreamDirectionBackward));
|
||||
mu_check(stream_tell(stream) == 2);
|
||||
mu_check(stream_seek_to_char(stream, '3', StreamDirectionBackward));
|
||||
mu_check(stream_tell(stream) == 1);
|
||||
mu_check(!stream_seek_to_char(stream, '3', StreamDirectionBackward));
|
||||
mu_check(stream_tell(stream) == 1);
|
||||
mu_check(stream_seek_to_char(stream, '1', StreamDirectionBackward));
|
||||
mu_check(stream_tell(stream) == 0);
|
||||
|
||||
// write string with replacemet
|
||||
// "1337_69" -> "1337lee"
|
||||
mu_check(stream_seek(stream, 4, StreamOffsetFromStart));
|
||||
mu_check(stream_write_string(stream, string_lee) == 3);
|
||||
mu_check(stream_size(stream) == 7);
|
||||
mu_check(stream_tell(stream) == 7);
|
||||
|
@@ -13,6 +13,7 @@ int run_minunit_test_furi_hal();
|
||||
int run_minunit_test_furi_string();
|
||||
int run_minunit_test_infrared();
|
||||
int run_minunit_test_rpc();
|
||||
int run_minunit_test_manifest();
|
||||
int run_minunit_test_flipper_format();
|
||||
int run_minunit_test_flipper_format_string();
|
||||
int run_minunit_test_stream();
|
||||
@@ -41,6 +42,7 @@ const UnitTest unit_tests[] = {
|
||||
{.name = "storage", .entry = run_minunit_test_storage},
|
||||
{.name = "stream", .entry = run_minunit_test_stream},
|
||||
{.name = "dirwalk", .entry = run_minunit_test_dirwalk},
|
||||
{.name = "manifest", .entry = run_minunit_test_manifest},
|
||||
{.name = "flipper_format", .entry = run_minunit_test_flipper_format},
|
||||
{.name = "flipper_format_string", .entry = run_minunit_test_flipper_format_string},
|
||||
{.name = "rpc", .entry = run_minunit_test_rpc},
|
||||
|
@@ -79,8 +79,8 @@ static void
|
||||
update_task_set_progress(
|
||||
update_task,
|
||||
UpdateTaskStageProgress,
|
||||
/* For this stage, first 30% of progress = cleanup */
|
||||
(n_processed_files++ * 30) / (n_approx_file_entries + 1));
|
||||
/* For this stage, first 20% of progress = cleanup files */
|
||||
(n_processed_files++ * 20) / (n_approx_file_entries + 1));
|
||||
|
||||
FuriString* file_path = furi_string_alloc();
|
||||
path_concat(
|
||||
@@ -90,6 +90,46 @@ static void
|
||||
furi_string_free(file_path);
|
||||
}
|
||||
}
|
||||
|
||||
while((entry_ptr = resource_manifest_reader_previous(manifest_reader))) {
|
||||
if(entry_ptr->type == ResourceManifestEntryTypeDirectory) {
|
||||
update_task_set_progress(
|
||||
update_task,
|
||||
UpdateTaskStageProgress,
|
||||
/* For this stage, second 10% of progress = cleanup directories */
|
||||
(n_processed_files++ * 10) / (n_approx_file_entries + 1));
|
||||
|
||||
FuriString* folder_path = furi_string_alloc();
|
||||
File* folder_file = storage_file_alloc(update_task->storage);
|
||||
|
||||
do {
|
||||
path_concat(
|
||||
STORAGE_EXT_PATH_PREFIX,
|
||||
furi_string_get_cstr(entry_ptr->name),
|
||||
folder_path);
|
||||
|
||||
FURI_LOG_D(TAG, "Removing folder %s", furi_string_get_cstr(folder_path));
|
||||
if(!storage_dir_open(folder_file, furi_string_get_cstr(folder_path))) {
|
||||
FURI_LOG_W(
|
||||
TAG,
|
||||
"%s can't be opened, skipping",
|
||||
furi_string_get_cstr(folder_path));
|
||||
break;
|
||||
}
|
||||
|
||||
if(storage_dir_read(folder_file, NULL, NULL, 0)) {
|
||||
FURI_LOG_I(
|
||||
TAG, "%s is not empty, skipping", furi_string_get_cstr(folder_path));
|
||||
break;
|
||||
}
|
||||
|
||||
storage_simply_remove(update_task->storage, furi_string_get_cstr(folder_path));
|
||||
} while(false);
|
||||
|
||||
storage_file_free(folder_file);
|
||||
furi_string_free(folder_path);
|
||||
}
|
||||
}
|
||||
} while(false);
|
||||
resource_manifest_reader_free(manifest_reader);
|
||||
}
|
||||
|
Reference in New Issue
Block a user