diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/write_flash_vpnor.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/test/write_flash_vpnor.cpp b/test/write_flash_vpnor.cpp new file mode 100644 index 0000000..30c9ff7 --- /dev/null +++ b/test/write_flash_vpnor.cpp @@ -0,0 +1,217 @@ +/* + * MBox Daemon Test File + * + * Copyright 2017 IBM + * + * 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. + * + */ + +#include "config.h" +#include "mboxd_pnor_partition_table.h" + +extern "C" { +#include "mbox.h" +#include "test/tmpf.h" +#include "mboxd_flash.h" +} + +#include <assert.h> +#include <unistd.h> + +#include <fstream> +#include <experimental/filesystem> + +#include <sys/mman.h> +#include <sys/syslog.h> +#include <sys/ioctl.h> +#include <fcntl.h> + + +uint8_t data[8] = { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7 }; + +#define BLOCK_SIZE 4096 +#define OFFSET BLOCK_SIZE +#define MEM_SIZE (BLOCK_SIZE *2) +#define DATA_SIZE sizeof(data) +#define ERASE_SIZE BLOCK_SIZE +#define BLOCK_SIZE_SHIFT 12 + + +void init(struct mbox_context* ctx) +{ + + namespace fs = std::experimental::filesystem; + using namespace std::string_literals; + + std::string tocData = "partition01=TEST1,00000000,00000400,ECC,READONLY\n"s + + "partition02=TEST2,00000000,00000008,ECC,READWRITE\n"s + + "partition03=TEST3,00000000,00000400,ECC,PRESERVED"s; + + std::vector<std::string> templatePaths = { "/tmp/ro.XXXXXX", + "/tmp/rw.XXXXXX" , + "/tmp/prsv.XXXXXX" + }; + + std::vector<std::string>partitions = { "TEST1", "TEST2", "TEST3" }; + + + // create various partition directory + + std::string tmpROdir = mkdtemp(const_cast<char*>(templatePaths[0].c_str())); + assert(tmpROdir.length() != 0); + + std::string tmpRWdir = mkdtemp(const_cast<char*>(templatePaths[1].c_str())); + assert(tmpRWdir.length() != 0); + + std::string tmpPRSVdir = mkdtemp(const_cast<char*>(templatePaths[2].c_str())); + assert(tmpPRSVdir.length() != 0); + + // create the toc file + fs::path tocFilePath = tmpROdir; + + tocFilePath /= PARTITION_TOC_FILE; + std::ofstream tocFile(tocFilePath.c_str()); + tocFile.write(tocData.c_str(), static_cast<int>(tocData.length())); + tocFile.close(); + + // create the partition files in the ro directory + for (auto partition : partitions) + { + fs::path partitionFilePath {tmpROdir}; + partitionFilePath /= partition; + std::ofstream partitionFile(partitionFilePath.c_str()); + partitionFile.write(reinterpret_cast<char*>(data), sizeof(data)); + partitionFile.close(); + + } + + // copy partition2 file from ro to rw + std::string roFile = tmpROdir + "/" + "TEST2"; + std::string rwFile = tmpRWdir + "/" + "TEST2"; + assert(fs::copy_file(roFile, rwFile) == true); + + mbox_vlog = &mbox_log_console; + verbosity = (verbose)2; + + // setting context parameters + ctx->erase_size_shift = BLOCK_SIZE_SHIFT; + ctx->block_size_shift = BLOCK_SIZE_SHIFT; + ctx->flash_bmap = reinterpret_cast<uint8_t*>( + calloc(MEM_SIZE >> ctx->erase_size_shift, + sizeof(*ctx->flash_bmap))); + + strcpy(ctx->paths.ro_loc, tmpROdir.c_str()); + strcpy(ctx->paths.rw_loc, tmpRWdir.c_str()); + strcpy(ctx->paths.prsv_loc, tmpPRSVdir.c_str()); + +} + + +int main(void) +{ + namespace fs = std::experimental::filesystem; + + int rc {}; + char src[DATA_SIZE] {0}; + struct mbox_context context; + struct mbox_context* ctx = &context; + memset(ctx, 0, sizeof(mbox_context)); + + //Initialize the context before running the test case. + init(ctx); + + std::string tmpROdir = ctx->paths.ro_loc; + std::string tmpRWdir = ctx->paths.rw_loc; + std::string tmpPRSVdir = ctx->paths.prsv_loc; + + // create the partition table + vpnor_create_partition_table_from_path(ctx, tmpROdir.c_str()); + + // Write to psrv partition + + // As file doesn't exist there, so it copies + // the file from RO to PRSV and write the file in PRSV partition. + + memset(src, 0xaa, sizeof(src)); + + rc = write_flash(ctx, (OFFSET * 3) , src, sizeof(src)); + assert(rc == 0); + + auto fd = open((tmpPRSVdir + "/" + "TEST3").c_str(), O_RDONLY); + auto map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, fd, 0); + assert(map != MAP_FAILED); + + // verify it is written + rc = memcmp(src, map, sizeof(src)); + assert(rc == 0); + munmap(map, MEM_SIZE); + close(fd); + + // Write to the RO partition + memset(src, 0x55, sizeof(src)); + fd = open((tmpROdir + "/" + "TEST1").c_str(), O_RDONLY); + map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, fd, 0); + assert(map != MAP_FAILED); + rc = write_flash(ctx, (OFFSET), src, sizeof(src)); + // Should not be allowed to write on RO + assert(rc != 0); + + munmap(map, MEM_SIZE); + close(fd); + + // Write to the RW partition + memset(src, 0xbb, sizeof(src)); + fd = open((tmpRWdir + "/" + "TEST2").c_str(), O_RDONLY); + map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, fd, 0); + assert(map != MAP_FAILED); + rc = write_flash(ctx, (OFFSET * 2), src, sizeof(src)); + assert(rc == 0); + rc = memcmp(src, map, sizeof(src)); + assert(rc == 0); + + // write beyond the partition length as the partition + // file length is 8 byte(TEST2). + rc = write_flash(ctx, (OFFSET * 2 + 3), src, sizeof(src) + 20); + assert(rc == -1); + + memset(src, 0xcc, sizeof(src)); + rc = write_flash(ctx, (OFFSET * 2), src, sizeof(src)); + assert(rc == 0); + rc = memcmp(src, map, sizeof(src)); + assert(rc == 0); + + src[0] = 0xff; + rc = write_flash(ctx, (OFFSET * 2), src, 1); + assert(rc == 0); + rc = memcmp(src, map, sizeof(src)); + assert(rc == 0); + + src[1] = 0xff; + rc = write_flash(ctx, (OFFSET * 2) + 1, &src[1], 1); + assert(rc == 0); + rc = memcmp(src, map, sizeof(src)); + assert(rc == 0); + + src[2] = 0xff; + rc = write_flash(ctx, (OFFSET * 2) + 2, &src[2], 1); + assert(rc == 0); + rc = memcmp(src, map, sizeof(src)); + assert(rc == 0); + + fs::remove_all(fs::path {tmpROdir}); + fs::remove_all(fs::path {tmpRWdir}); + fs::remove_all(fs::path {tmpPRSVdir}); + + return rc; +} |