1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063 |
- <?xml version="1.0" encoding="UTF-8"?>
- <SPC5-Config version="1.0.0">
- <application name="ChibiOS/HAL MFS Test Suite" version="1.0.0" standalone="true" locked="false">
- <description>Test Specification for ChibiOS/HAL MFS Complex Driver.</description>
- <component id="org.chibios.spc5.components.portable.generic_startup">
- <component id="org.chibios.spc5.components.portable.chibios_unitary_tests_engine" />
- </component>
- <instances>
- <instance locked="false" id="org.chibios.spc5.components.portable.generic_startup" />
- <instance locked="false" id="org.chibios.spc5.components.portable.chibios_unitary_tests_engine">
- <description>
- <brief>
- <value>ChibiOS/HAL MFS Test Suite.</value>
- </brief>
- <copyright>
- <value><![CDATA[/*
- ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */]]></value>
- </copyright>
- <introduction>
- <value>Test suite for ChibiOS/HAL MFS. The purpose of this suite is to perform unit tests on the MFS module and to converge to 100% code coverage through successive improvements.</value>
- </introduction>
- </description>
- <global_data_and_code>
- <code_prefix>
- <value>mfs_</value>
- </code_prefix>
- <global_definitions>
- <value><![CDATA[#include "hal_mfs.h"
- #define TEST_SUITE_NAME "ChibiOS/HAL MFS Test Suite"
- #define TEST_REPORT_HOOK_HEADER test_print_mfs_info();
- extern const MFSConfig mfscfg1;
- extern MFSDriver mfs1;
- extern uint8_t mfs_buffer[512];
- flash_error_t bank_erase(mfs_bank_t bank);
- flash_error_t bank_verify_erased(mfs_bank_t bank);
- void test_print_mfs_info(void);]]></value>
- </global_definitions>
- <global_code>
- <value><![CDATA[#include "hal_mfs.h"
- MFSDriver mfs1;
- uint8_t mfs_buffer[512];
- void test_print_mfs_info(void) {
- }
- flash_error_t bank_erase(mfs_bank_t bank) {
- flash_sector_t sector, n;
- if (bank == MFS_BANK_0) {
- sector = mfscfg1.bank0_start;
- n = mfscfg1.bank0_sectors;
- }
- else {
- sector = mfscfg1.bank1_start;
- n = mfscfg1.bank1_sectors;
- }
- while (n--) {
- flash_error_t ferr;
- ferr = flashStartEraseSector(mfscfg1.flashp, sector);
- if (ferr != FLASH_NO_ERROR)
- return ferr;
- ferr = flashWaitErase(mfscfg1.flashp);
- if (ferr != FLASH_NO_ERROR)
- return ferr;
- sector++;
- }
- return FLASH_NO_ERROR;
- }
- flash_error_t bank_verify_erased(mfs_bank_t bank) {
- flash_sector_t sector, n;
- if (bank == MFS_BANK_0) {
- sector = mfscfg1.bank0_start;
- n = mfscfg1.bank0_sectors;
- }
- else {
- sector = mfscfg1.bank1_start;
- n = mfscfg1.bank1_sectors;
- }
- while (n--) {
- flash_error_t ferr;
- ferr = flashVerifyErase(mfscfg1.flashp, sector);
- if (ferr != FLASH_NO_ERROR)
- return ferr;
- sector++;
- }
- return FLASH_NO_ERROR;
- }]]></value>
- </global_code>
- </global_data_and_code>
- <sequences>
- <sequence>
- <type index="0">
- <value>Internal Tests</value>
- </type>
- <brief>
- <value>Functional tests.</value>
- </brief>
- <description>
- <value>The APIs are tested for functionality, correct cases and expected error cases are tested.</value>
- </description>
- <condition>
- <value />
- </condition>
- <shared_code>
- <value><![CDATA[#include <string.h>
- #include "hal_mfs.h"
- static const uint8_t pattern1[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
- };
- static const uint8_t pattern2[] = {
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
- };
- static const uint8_t pattern3[] = {
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57
- };
- static const uint8_t pattern512[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
- };]]></value>
- </shared_code>
- <cases>
- <case>
- <brief>
- <value>Testing mfsStart() behavior.</value>
- </brief>
- <description>
- <value>The initialization function is tested. This function can fail only in case of Flash Array failures or in case of unexpected internal errors.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value><![CDATA[mfsObjectInit(&mfs1);]]></value>
- </setup_code>
- <teardown_code>
- <value><![CDATA[mfsStop(&mfs1);]]></value>
- </teardown_code>
- <local_variables>
- <value />
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>Erasing the flash array using a low level function.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[flash_error_t ferr;
- ferr = bank_erase(MFS_BANK_0);
- test_assert(ferr == FLASH_NO_ERROR, "Bank 0 erase failure");
- ferr = bank_erase(MFS_BANK_1);
- test_assert(ferr == FLASH_NO_ERROR, "Bank 1 erase failure");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Calling mfsStart() on an uninitialized flash array, MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- err = mfsStart(&mfs1, &mfscfg1);
- test_assert(err == MFS_NO_ERROR, "initialization error with erased flash");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Calling mfsStart() on a newly initialized flash array, MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- err = mfsStart(&mfs1, &mfscfg1);
- test_assert(err == MFS_NO_ERROR, "initialization error with initialized flash");]]></value>
- </code>
- </step>
- </steps>
- </case>
- <case>
- <brief>
- <value>Checking for non existing record.</value>
- </brief>
- <description>
- <value>The records space is explored with an initialized but empty managed storage, no record should exist.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value><![CDATA[mfsStart(&mfs1, &mfscfg1);]]></value>
- </setup_code>
- <teardown_code>
- <value><![CDATA[mfsStop(&mfs1);]]></value>
- </teardown_code>
- <local_variables>
- <value />
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>Exploring the records space, MFS_ERR_NOT_FOUND is expected for each index.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- mfs_id_t id;
- size_t size;
- for (id = 1; id <= MFS_CFG_MAX_RECORDS; id++) {
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND,
- "found a record that should not exists");
- }]]></value>
- </code>
- </step>
- </steps>
- </case>
- <case>
- <brief>
- <value>Creating, updating and erasing a record.</value>
- </brief>
- <description>
- <value>A record is created, updated several times with different payloads and finally erased.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value><![CDATA[mfsStart(&mfs1, &mfscfg1);]]></value>
- </setup_code>
- <teardown_code>
- <value><![CDATA[mfsStop(&mfs1);]]></value>
- </teardown_code>
- <local_variables>
- <value><![CDATA[size_t size;]]></value>
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>The record must not already exists, MFS_ERR_NOT_FOUND is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[size = sizeof mfs_buffer;
- mfs_error_t err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND , "record was already present");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Creating the record then retrieving it again, MFS_NO_ERROR is expected, record content and size are compared with the original.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- err = mfsWriteRecord(&mfs1, 1, sizeof pattern1, pattern1);
- test_assert(err == MFS_NO_ERROR, "error creating the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record not found");
- test_assert(size == sizeof pattern1, "unexpected record length");
- test_assert(memcmp(pattern1, mfs_buffer, size) == 0, "wrong record content");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Updating the record then retrieving it again, MFS_NO_ERROR is expected, record content and size are compared with the original.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- err = mfsWriteRecord(&mfs1, 1, sizeof pattern2, pattern2);
- test_assert(err == MFS_NO_ERROR, "error updating the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record not found");
- test_assert(size == sizeof pattern2, "unexpected record length");
- test_assert(memcmp(pattern2, mfs_buffer, size) == 0, "wrong record content");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Erasing the record then trying to retrieve it again, MFS_NO_ERROR is expected on erase, MFS_ERR_NOT_FOUND is expected on retrieve.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- err = mfsEraseRecord(&mfs1, 1);
- test_assert(err == MFS_NO_ERROR, "error erasing the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "record not erased");]]></value>
- </code>
- </step>
- </steps>
- </case>
- <case>
- <brief>
- <value>Erasing the whole storage and re-initialization.</value>
- </brief>
- <description>
- <value>The managed storage is erased, initialized and re-mounted.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value><![CDATA[bank_erase(MFS_BANK_0);
- bank_erase(MFS_BANK_1);
- mfsStart(&mfs1, &mfscfg1);]]></value>
- </setup_code>
- <teardown_code>
- <value><![CDATA[mfsStop(&mfs1);]]></value>
- </teardown_code>
- <local_variables>
- <value />
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>Creating records 1, 2 and 3, MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- err = mfsWriteRecord(&mfs1, 1, sizeof pattern1, pattern1);
- test_assert(err == MFS_NO_ERROR, "error creating record 1");
- err = mfsWriteRecord(&mfs1, 2, sizeof pattern2, pattern2);
- test_assert(err == MFS_NO_ERROR, "error creating record 2");
- err = mfsWriteRecord(&mfs1, 3, sizeof pattern3, pattern3);
- test_assert(err == MFS_NO_ERROR, "error creating record 3");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Records must exist.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record 0 not present");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 2, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record 1 not present");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 3, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record 2 not present");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Re-mounting, records must still exist.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- err = mfsStart(&mfs1, &mfscfg1);
- test_assert(err == MFS_NO_ERROR, "re-mount failed");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record 0 not present");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 2, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record 1 not present");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 3, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record 2 not present");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Erasing storage and verify that the records have been removed, MFS_NO_ERROR is expected on erase, MFS_ERR_NOT_FOUND is expected on retrieve.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- err = mfsErase(&mfs1);
- test_assert(err == MFS_NO_ERROR, "storage erase error");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "record 0 still present");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 2, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "record 1 still present");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 3, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "record 2 still present");]]></value>
- </code>
- </step>
- </steps>
- </case>
- <case>
- <brief>
- <value>Testing storage size limit.</value>
- </brief>
- <description>
- <value>The storage is entirely filled with different records and the final error is tested.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value><![CDATA[mfsStart(&mfs1, &mfscfg1);
- mfsErase(&mfs1);]]></value>
- </setup_code>
- <teardown_code>
- <value><![CDATA[mfsStop(&mfs1);]]></value>
- </teardown_code>
- <local_variables>
- <value />
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>Filling up the storage by writing records with increasing IDs, MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_id_t id;
- mfs_id_t id_max = (mfscfg1.bank_size - sizeof (mfs_bank_header_t)) /
- (sizeof (mfs_data_header_t) + sizeof pattern512);
- for (id = 1; id <= id_max; id++) {
- mfs_error_t err;
- size_t size;
- err = mfsWriteRecord(&mfs1, id, sizeof pattern512, pattern512);
- test_assert(err == MFS_NO_ERROR, "error creating the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR,
- "record not found");
- test_assert(size == sizeof pattern512,
- "unexpected record length");
- test_assert(memcmp(pattern512, mfs_buffer, size) == 0,
- "wrong record content");
- }]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Creating one more record, should fail, MFS_ERR_OUT_OF_MEM is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- mfs_id_t id_max = (mfscfg1.bank_size - sizeof (mfs_bank_header_t)) /
- (sizeof (mfs_data_header_t) + sizeof pattern512);
- err = mfsWriteRecord(&mfs1, id_max, sizeof pattern512 , pattern512);
- test_assert(err == MFS_ERR_OUT_OF_MEM, "creation didn't fail");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Adding a smaller record to fill the final gap. A reinitialization is performed and MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t remaining;
- remaining = (size_t)flashGetSectorOffset(mfscfg1.flashp, mfscfg1.bank0_start) +
- (size_t)mfscfg1.bank_size - (size_t)mfs1.next_offset;
- test_assert(remaining >= sizeof (mfs_data_header_t), "not enough space");
- if (remaining > sizeof (mfs_data_header_t) * 2) {
- err = mfsWriteRecord(&mfs1, MFS_CFG_MAX_RECORDS,
- remaining - (sizeof (mfs_data_header_t) * 2),
- pattern512);
- test_assert(err == MFS_NO_ERROR, "error filling remaining space");
- err = mfsEraseRecord(&mfs1, MFS_CFG_MAX_RECORDS);
- test_assert(err == MFS_NO_ERROR, "error filling remaining space");
- }
- else {
- if (remaining == sizeof (mfs_data_header_t) * 2) {
- err = mfsEraseRecord(&mfs1, 2);
- test_assert(err == MFS_NO_ERROR, "error filling remaining space");
- }
- err = mfsEraseRecord(&mfs1, 1);
- test_assert(err == MFS_NO_ERROR, "error filling remaining space");
- }
- remaining = (size_t)flashGetSectorOffset(mfscfg1.flashp, mfscfg1.bank0_start) +
- (size_t)mfscfg1.bank_size - (size_t)mfs1.next_offset;
- test_assert(remaining == 0U, "remaining space not zero");
- mfsStop(&mfs1);
- err = mfsStart(&mfs1, &mfscfg1);
- test_assert(err == MFS_NO_ERROR, "initialization error");]]></value>
- </code>
- </step>
- </steps>
- </case>
- <case>
- <brief>
- <value>Testing garbage collection by writing.</value>
- </brief>
- <description>
- <value>The garbage collection procedure is triggeredby a write operation and the state of both banks is checked.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value><![CDATA[mfsStart(&mfs1, &mfscfg1);
- mfsErase(&mfs1);]]></value>
- </setup_code>
- <teardown_code>
- <value><![CDATA[mfsStop(&mfs1);]]></value>
- </teardown_code>
- <local_variables>
- <value />
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>Filling up the storage by writing records with increasing IDs, MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_id_t id;
- mfs_id_t id_max = (mfscfg1.bank_size - sizeof (mfs_bank_header_t)) /
- (sizeof (mfs_data_header_t) + sizeof pattern512);
- for (id = 1; id <= id_max; id++) {
- mfs_error_t err;
- size_t size;
- err = mfsWriteRecord(&mfs1, id, sizeof pattern512, pattern512);
- test_assert(err == MFS_NO_ERROR, "error creating the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR,
- "record not found");
- test_assert(size == sizeof pattern512,
- "unexpected record length");
- test_assert(memcmp(pattern512, mfs_buffer, size) == 0,
- "wrong record content");
- }]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Erasing one record, MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- err = mfsEraseRecord(&mfs1, 1);
- test_assert(err == MFS_NO_ERROR, "error erasing the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "record not erased");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Writing one more record triggers garbage collection, MFS_WARN_GC is expected, KS state is checked for correctness after the operation.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- test_assert(mfs1.current_counter == 1, "not first instance");
- err = mfsWriteRecord(&mfs1, 1, sizeof pattern512, pattern512);
- test_assert(err == MFS_WARN_GC, "error creating the record");
- test_assert(mfs1.current_counter == 2, "not second instance");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record not found");
- test_assert(size == sizeof pattern512, "unexpected record length");
- test_assert(memcmp(pattern512, mfs_buffer, size) == 0, "wrong record content");
- test_assert(mfs1.current_bank == MFS_BANK_1, "unexpected bank");
- test_assert(bank_verify_erased(MFS_BANK_0) == FLASH_NO_ERROR, "bank 0 not erased");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Checking for all records in the new bank, MFS_NOERROR is expected for each record.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_id_t id;
- mfs_id_t id_max = (mfscfg1.bank_size - sizeof (mfs_bank_header_t)) /
- (sizeof (mfs_data_header_t) + sizeof pattern512);
- for (id = 1; id <= MFS_CFG_MAX_RECORDS; id++) {
- mfs_error_t err;
- size_t size;
- if (id <= id_max) {
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record not found");
- test_assert(size == sizeof pattern512, "unexpected record length");
- test_assert(memcmp(pattern512, mfs_buffer, size) == 0, "wrong record content");
- }
- else {
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "found unexpected record");
- }
- }]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Erasing one record, MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- err = mfsEraseRecord(&mfs1, 1);
- test_assert(err == MFS_NO_ERROR, "error erasing the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "record not erased");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Writing one more record triggers garbage collection, MFS_WARN_GC is expected, MFS object state is checked for correctness after the operation.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- test_assert(mfs1.current_counter == 2, "not second instance");
- err = mfsWriteRecord(&mfs1, 1, sizeof pattern512, pattern512);
- test_assert(err == MFS_WARN_GC, "error creating the record");
- test_assert(mfs1.current_counter == 3, "not third instance");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record not found");
- test_assert(size == sizeof pattern512, "unexpected record length");
- test_assert(memcmp(pattern512, mfs_buffer, size) == 0, "wrong record content");
- test_assert(mfs1.current_bank == MFS_BANK_0, "unexpected bank");
- test_assert(bank_verify_erased(MFS_BANK_1) == FLASH_NO_ERROR, "bank 1 not erased");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Checking for all records in the new bank, MFS_NO_ERROR is expected for each record.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_id_t id;
- mfs_id_t id_max = (mfscfg1.bank_size - sizeof (mfs_bank_header_t)) /
- (sizeof (mfs_data_header_t) + sizeof pattern512);
- for (id = 1; id <= MFS_CFG_MAX_RECORDS; id++) {
- mfs_error_t err;
- size_t size;
- if (id <= id_max) {
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record not found");
- test_assert(size == sizeof pattern512, "unexpected record length");
- test_assert(memcmp(pattern512, mfs_buffer, size) == 0, "wrong record content");
- }
- else {
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "found unexpected record");
- }
- }]]></value>
- </code>
- </step>
- </steps>
- </case>
- <case>
- <brief>
- <value>Testing garbage collection by erasing</value>
- </brief>
- <description>
- <value>The garbage collection procedure is triggered by an erase operation and the state of both banks is checked.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value><![CDATA[mfsStart(&mfs1, &mfscfg1);
- mfsErase(&mfs1);]]></value>
- </setup_code>
- <teardown_code>
- <value><![CDATA[mfsStop(&mfs1);]]></value>
- </teardown_code>
- <local_variables>
- <value />
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>Filling up the storage by writing records with increasing IDs, MFS_NO_ERROR is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_id_t id;
- mfs_id_t id_max = (mfscfg1.bank_size - sizeof (mfs_bank_header_t)) /
- (sizeof (mfs_data_header_t) + (sizeof pattern512 / 2));
- for (id = 1; id <= id_max; id++) {
- mfs_error_t err;
- size_t size;
- err = mfsWriteRecord(&mfs1, id, (sizeof pattern512 / 2), pattern512);
- test_assert(err == MFS_NO_ERROR, "error creating the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_NO_ERROR, "record not found");
- test_assert(size == (sizeof pattern512 / 2), "unexpected record length");
- test_assert(memcmp(pattern512, mfs_buffer, size) == 0, "wrong record content");
- }]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Erase records until the flash bank is filled entirely.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- mfs_id_t id;
- mfs_id_t id_max = (mfscfg1.bank_size - sizeof (mfs_bank_header_t)) /
- (sizeof (mfs_data_header_t) + (sizeof pattern512 / 2));
- mfs_id_t n = ((mfscfg1.bank_size - sizeof (mfs_bank_header_t)) -
- (id_max * (sizeof (mfs_data_header_t) + (sizeof pattern512 / 2)))) /
- sizeof (mfs_data_header_t);
- for (id = 1; id <= n; id++) {
- err = mfsEraseRecord(&mfs1, id);
- test_assert(err == MFS_NO_ERROR, "error erasing the record");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "record not erased");
- }]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>Erasing one more record triggers garbage collection, MFS_WARN_GC is expected, KS state is checked for correctness after the operation.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- size_t size;
- mfs_id_t id_max = (mfscfg1.bank_size - sizeof (mfs_bank_header_t)) /
- (sizeof (mfs_data_header_t) + (sizeof pattern512 / 2));
- test_assert(mfs1.current_counter == 1, "not first instance");
- err = mfsEraseRecord(&mfs1, id_max);
- test_assert(err == MFS_WARN_GC, "error erasing the record");
- test_assert(mfs1.current_counter == 2, "not second instance");
- size = sizeof mfs_buffer;
- err = mfsReadRecord(&mfs1, id_max, &size, mfs_buffer);
- test_assert(err == MFS_ERR_NOT_FOUND, "record not erased");
- test_assert(mfs1.current_bank == MFS_BANK_1, "unexpected bank");
- test_assert(bank_verify_erased(MFS_BANK_0) == FLASH_NO_ERROR, "bank 0 not erased");]]></value>
- </code>
- </step>
- </steps>
- </case>
- </cases>
- </sequence>
- <sequence>
- <type index="0">
- <value>Internal Tests</value>
- </type>
- <brief>
- <value>API Invalid Cases tests.</value>
- </brief>
- <description>
- <value>This test sequence tests the error coded returned by the various APIs when called when the system is not initialized.</value>
- </description>
- <condition>
- <value />
- </condition>
- <shared_code>
- <value><![CDATA[#include "hal_mfs.h"]]></value>
- </shared_code>
- <cases>
- <case>
- <brief>
- <value>Initialization error from APIs.</value>
- </brief>
- <description>
- <value>The API functions are invoked without prior initialization.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value />
- </setup_code>
- <teardown_code>
- <value />
- </teardown_code>
- <local_variables>
- <value />
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>The function mfsErase() is called, MFS_ERR_INV_STATE is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err = mfsErase(&mfs1);
- test_assert(err == MFS_ERR_INV_STATE, "mfsErase() returned wrong status");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>The function mfsWriteRecord() is called, MFS_ERR_INV_STATE is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err = mfsWriteRecord(&mfs1, 1, 16, mfs_buffer);
- test_assert(err == MFS_ERR_INV_STATE, "mfsWriteRecord() returned wrong status");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>The function mfsEraseRecord() is called, MFS_ERR_INV_STATE is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err = mfsEraseRecord(&mfs1, 1);
- test_assert(err == MFS_ERR_INV_STATE, "mfsEraseRecord() returned wrong status");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>The function mfsReadRecord() is called, MFS_ERR_INV_STATE is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[size_t size = sizeof mfs_buffer;
- mfs_error_t err = mfsReadRecord(&mfs1, 1, &size, mfs_buffer);
- test_assert(err == MFS_ERR_INV_STATE, "mfsReadRecord() returned wrong status");]]></value>
- </code>
- </step>
- <step>
- <description>
- <value>The function mfsPerformGarbageCollection() is called, MFS_ERR_INV_STATE is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err = mfsPerformGarbageCollection(&mfs1);
- test_assert(err == MFS_ERR_INV_STATE, "mfsPerformGarbageCollection() returned wrong status");]]></value>
- </code>
- </step>
- </steps>
- </case>
- <case>
- <brief>
- <value>Erasing non existing record.</value>
- </brief>
- <description>
- <value>An erase operation is attempted on an non-existing record.</value>
- </description>
- <condition>
- <value />
- </condition>
- <various_code>
- <setup_code>
- <value><![CDATA[mfsStart(&mfs1, &mfscfg1);
- mfsErase(&mfs1);]]></value>
- </setup_code>
- <teardown_code>
- <value><![CDATA[mfsStop(&mfs1);]]></value>
- </teardown_code>
- <local_variables>
- <value />
- </local_variables>
- </various_code>
- <steps>
- <step>
- <description>
- <value>Record one is erased, the error MFS_ERR_NOT_FOUND is expected.</value>
- </description>
- <tags>
- <value />
- </tags>
- <code>
- <value><![CDATA[mfs_error_t err;
- err = mfsEraseRecord(&mfs1, 1);
- test_assert(err != MFS_NO_ERROR, "record was present");
- test_assert(err == MFS_ERR_NOT_FOUND, "invalid error code");]]></value>
- </code>
- </step>
- </steps>
- </case>
- </cases>
- </sequence>
- </sequences>
- </instance>
- </instances>
- <exportedFeatures />
- </application>
- </SPC5-Config>
|