test: write_flash_vpnor: Integrate VpnorRoot

Change-Id: I5d49a090482d280317e75c7a7e2dc68d7fa265e2
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/test/vpnor/write_flash_vpnor.cpp b/test/vpnor/write_flash_vpnor.cpp
index 049cb94..384c13a 100644
--- a/test/vpnor/write_flash_vpnor.cpp
+++ b/test/vpnor/write_flash_vpnor.cpp
@@ -37,6 +37,8 @@
 #include <sys/ioctl.h>
 #include <fcntl.h>
 
+#include "test/vpnor/tmpd.hpp"
+
 uint8_t data[8] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7};
 
 #define BLOCK_SIZE 4096
@@ -46,61 +48,29 @@
 #define ERASE_SIZE BLOCK_SIZE
 #define BLOCK_SIZE_SHIFT 12
 
-void init(struct mbox_context* ctx)
-{
+const std::string toc[] = {
+    "partition01=TEST1,00001000,00001400,ECC,READONLY",
+    "partition02=TEST2,00002000,00002008,ECC,READWRITE",
+    "partition03=TEST3,00003000,00003400,ECC,PRESERVED",
+};
 
+std::vector<std::string> partitions = {"TEST1", "TEST2", "TEST3"};
+
+namespace test = openpower::virtual_pnor::test;
+
+void init(struct mbox_context* ctx, test::VpnorRoot& root)
+{
     namespace fs = std::experimental::filesystem;
     using namespace std::string_literals;
 
-    std::string tocData =
-        "partition01=TEST1,00001000,00001400,ECC,READONLY\n"s +
-        "partition02=TEST2,00002000,00002008,ECC,READWRITE\n"s +
-        "partition03=TEST3,00003000,00003400,ECC,PRESERVED"s;
-
-    std::vector<std::string> templatePaths = {
-        "/tmp/ro.XXXXXX", "/tmp/rw.XXXXXX", "/tmp/prsv.XXXXXX",
-        "/tmp/patch.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);
-
-    std::string tmpPATCHdir =
-        mkdtemp(const_cast<char*>(templatePaths[3].c_str()));
-    assert(tmpPATCHdir.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();
+        root.write(partition, data, sizeof(data));
     }
 
     // copy partition2 file from ro to rw
-    std::string roFile = tmpROdir + "/" + "TEST2";
-    std::string rwFile = tmpRWdir + "/" + "TEST2";
-    assert(fs::copy_file(roFile, rwFile) == true);
+    assert(fs::copy_file(root.ro() / "TEST2", root.rw() / "TEST2"));
 
     mbox_vlog = &mbox_log_console;
     verbosity = (verbose)2;
@@ -111,10 +81,10 @@
     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());
-    strcpy(ctx->paths.patch_loc, tmpPATCHdir.c_str());
+    strcpy(ctx->paths.ro_loc, root.ro().c_str());
+    strcpy(ctx->paths.rw_loc, root.rw().c_str());
+    strcpy(ctx->paths.prsv_loc, root.prsv().c_str());
+    strcpy(ctx->paths.patch_loc, root.patch().c_str());
 }
 
 int main(void)
@@ -127,16 +97,13 @@
     struct mbox_context* ctx = &context;
     memset(ctx, 0, sizeof(mbox_context));
 
-    // Initialize the context before running the test case.
-    init(ctx);
+    test::VpnorRoot root(toc, BLOCK_SIZE);
 
-    std::string tmpROdir = ctx->paths.ro_loc;
-    std::string tmpRWdir = ctx->paths.rw_loc;
-    std::string tmpPRSVdir = ctx->paths.prsv_loc;
-    std::string tmpPATCHdir = ctx->paths.patch_loc;
+    // Initialize the context before running the test case.
+    init(ctx, root);
 
     // create the partition table
-    vpnor_create_partition_table_from_path(ctx, tmpROdir.c_str());
+    vpnor_create_partition_table_from_path(ctx, root.ro().c_str());
 
     // Write to psrv partition
 
@@ -148,7 +115,7 @@
     rc = write_flash(ctx, (OFFSET * 3), src, sizeof(src));
     assert(rc == 0);
 
-    auto fd = open((tmpPRSVdir + "/" + "TEST3").c_str(), O_RDONLY);
+    auto fd = open((root.prsv() / "TEST3").c_str(), O_RDONLY);
     auto map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
     assert(map != MAP_FAILED);
 
@@ -160,7 +127,7 @@
 
     // Write to the RO partition
     memset(src, 0x55, sizeof(src));
-    fd = open((tmpROdir + "/" + "TEST1").c_str(), O_RDONLY);
+    fd = open((root.ro() / "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));
@@ -172,7 +139,7 @@
 
     // Write to the RW partition
     memset(src, 0xbb, sizeof(src));
-    fd = open((tmpRWdir + "/" + "TEST2").c_str(), O_RDONLY);
+    fd = open((root.rw() / "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));
@@ -216,11 +183,8 @@
     // Copy partition2 file from ro to patch to simulate a patch file that is
     // different from the one in rw (partition2 in rw was modified with the
     // previous write test)
-    fs::path roFile(tmpROdir);
-    roFile /= "TEST2";
-    fs::path patchFile(tmpPATCHdir);
-    patchFile /= "TEST2";
-    assert(fs::copy_file(roFile, patchFile) == true);
+    fs::path patch = root.patch() / "TEST2";
+    assert(fs::copy_file(root.ro() / "TEST2", patch));
 
     // Write arbitrary data
     char srcPatch[DATA_SIZE]{0};
@@ -229,9 +193,7 @@
     assert(rc == 0);
 
     // Check that partition file in RW location still contains the original data
-    fs::path rwFile(tmpRWdir);
-    rwFile /= "TEST2";
-    fd = open(rwFile.c_str(), O_RDONLY);
+    fd = open((root.rw() / "TEST2").c_str(), O_RDONLY);
     map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
     assert(map != MAP_FAILED);
     rc = memcmp(src, map, sizeof(src));
@@ -240,7 +202,7 @@
     close(fd);
 
     // Check that partition file in PATCH location was written with the new data
-    fd = open(patchFile.c_str(), O_RDONLY);
+    fd = open(patch.c_str(), O_RDONLY);
     map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
     assert(map != MAP_FAILED);
     rc = memcmp(srcPatch, map, sizeof(srcPatch));
@@ -248,15 +210,6 @@
     munmap(map, MEM_SIZE);
     close(fd);
 
-    // Remove patch file so that subsequent tests don't use it
-    fs::remove(patchFile);
-    // END Test patch location
-
-    fs::remove_all(fs::path{tmpROdir});
-    fs::remove_all(fs::path{tmpRWdir});
-    fs::remove_all(fs::path{tmpPRSVdir});
-    fs::remove_all(fs::path{tmpPATCHdir});
-
     destroy_vpnor(ctx);
     free(ctx->flash_bmap);