summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorRatan Gupta <ratagupt@in.ibm.com>2017-05-31 16:01:01 +0530
committerRatan Gupta <ratagupt@in.ibm.com>2017-06-29 22:08:39 +0530
commit2407f1553bb08d8ba843195ea0bf29327f1301f8 (patch)
treef5faa7f78bdce1525f7a914f38dd6b8239fc6807 /test
parentdc50ce5a787fe4979d084355c485301b84396967 (diff)
downloadphosphor-mboxd-2407f1553bb08d8ba843195ea0bf29327f1301f8.tar.gz
phosphor-mboxd-2407f1553bb08d8ba843195ea0bf29327f1301f8.zip
test: write the vpnor file(flash)
Add the test binary which runs the following test cases 1) Write to the read only partition 2) Write to the RW partition 3) Write to the preserved partition. 4) Write beyond the partition file length. 5) other boundary test cases. Resolves openbmc/openbmc#1479 Change-Id: Ifd4f0e89e434a26e2579415a973fe1bfdbb3e66f Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
Diffstat (limited to 'test')
-rw-r--r--test/write_flash_vpnor.cpp217
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;
+}
OpenPOWER on IntegriCloud