mbed-os/TESTS/filesystem/parallel/main.cpp

185 lines
4.6 KiB
C++

#include "mbed.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include <stdlib.h>
#include <errno.h>
using namespace utest::v1;
// test configuration
#ifndef MBED_TEST_FILESYSTEM
#define MBED_TEST_FILESYSTEM FATFileSystem
#endif
#ifndef MBED_TEST_FILESYSTEM_DECL
#define MBED_TEST_FILESYSTEM_DECL MBED_TEST_FILESYSTEM fs("fs")
#endif
#ifndef MBED_TEST_BLOCKDEVICE
#define MBED_TEST_BLOCKDEVICE SDBlockDevice
#define MBED_TEST_BLOCKDEVICE_DECL SDBlockDevice bd(MBED_CONF_SD_SPI_MOSI, MBED_CONF_SD_SPI_MISO, MBED_CONF_SD_SPI_CLK, MBED_CONF_SD_SPI_CS);
#endif
#ifndef MBED_TEST_BLOCKDEVICE_DECL
#define MBED_TEST_BLOCKDEVICE_DECL MBED_TEST_BLOCKDEVICE bd
#endif
#ifndef MBED_TEST_FILES
#define MBED_TEST_FILES 4
#endif
#ifndef MBED_TEST_DIRS
#define MBED_TEST_DIRS 4
#endif
#ifndef MBED_TEST_BUFFER
#define MBED_TEST_BUFFER 512
#endif
#ifndef MBED_TEST_TIMEOUT
#define MBED_TEST_TIMEOUT 120
#endif
#ifndef MBED_THREAD_COUNT
#define MBED_THREAD_COUNT MBED_TEST_FILES
#endif
// declarations
#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#define INCLUDE(x) STRINGIZE(x.h)
#include INCLUDE(MBED_TEST_FILESYSTEM)
#include INCLUDE(MBED_TEST_BLOCKDEVICE)
MBED_TEST_FILESYSTEM_DECL;
MBED_TEST_BLOCKDEVICE_DECL;
Dir dir[MBED_TEST_DIRS];
File file[MBED_TEST_FILES];
DIR *dd[MBED_TEST_DIRS];
FILE *fd[MBED_TEST_FILES];
struct dirent ent;
struct dirent *ed;
volatile bool count_done = 0;
// tests
void test_file_tests() {
int res = bd.init();
TEST_ASSERT_EQUAL(0, res);
{
res = MBED_TEST_FILESYSTEM::format(&bd);
TEST_ASSERT_EQUAL(0, res);
}
res = bd.deinit();
TEST_ASSERT_EQUAL(0, res);
}
void write_file_data (char count) {
char filename[10];
uint8_t wbuffer[MBED_TEST_BUFFER];
int res;
sprintf(filename, "%s%d", "data", count);
res = file[count].open(&fs, filename, O_WRONLY | O_CREAT);
TEST_ASSERT_EQUAL(0, res);
char letter = 'A'+ count;
for (uint32_t i = 0; i < MBED_TEST_BUFFER; i++) {
wbuffer[i] = letter++;
if ('z' == letter) {
letter = 'A' + count;
}
}
for (uint32_t i = 0; i < 5; i++) {
res = file[count].write(wbuffer, MBED_TEST_BUFFER);
TEST_ASSERT_EQUAL(MBED_TEST_BUFFER, res);
}
res = file[count].close();
TEST_ASSERT_EQUAL(0, res);
}
void read_file_data (char count) {
char filename[10];
uint8_t rbuffer[MBED_TEST_BUFFER];
int res;
sprintf(filename, "%s%d", "data", count);
res = file[count].open(&fs, filename, O_RDONLY);
TEST_ASSERT_EQUAL(0, res);
for (uint32_t i = 0; i < 5; i++) {
res = file[count].read(rbuffer, MBED_TEST_BUFFER);
TEST_ASSERT_EQUAL(MBED_TEST_BUFFER, res);
char letter = 'A' + count;
for (uint32_t i = 0; i < MBED_TEST_BUFFER; i++) {
res = rbuffer[i];
TEST_ASSERT_EQUAL(letter++, res);
if ('z' == letter) {
letter = 'A' + count;
}
}
}
res = file[count].close();
TEST_ASSERT_EQUAL(0, res);
}
void test_thread_access_test() {
Thread *data[MBED_THREAD_COUNT];
int res = bd.init();
TEST_ASSERT_EQUAL(0, res);
res = fs.mount(&bd);
TEST_ASSERT_EQUAL(0, res);
// Write threads in parallel
for (char thread_count = 0; thread_count < MBED_THREAD_COUNT; thread_count++) {
data[thread_count] = new Thread(osPriorityNormal);
data[thread_count]->start(callback((void(*)(void*))write_file_data, (void*)thread_count));
}
// Wait for write thread to join before creating read thread
for (char thread_count = 0; thread_count < MBED_THREAD_COUNT; thread_count++) {
data[thread_count]->join();
delete data[thread_count];
data[thread_count] = new Thread(osPriorityNormal);
data[thread_count]->start(callback((void(*)(void*))read_file_data, (void*)thread_count));
}
// Wait for read threads to join
for (char thread_count = 0; thread_count < MBED_THREAD_COUNT; thread_count++) {
data[thread_count]->join();
delete data[thread_count];
}
res = fs.unmount();
TEST_ASSERT_EQUAL(0, res);
res = bd.deinit();
TEST_ASSERT_EQUAL(0, res);
}
// test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(MBED_TEST_TIMEOUT, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("File tests", test_file_tests),
Case("Filesystem access from multiple threads", test_thread_access_test),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}