manifest_test: Build DTs programatically
Manifest unit tests used to come with binary blobs of DTs to test.
This results in having the refresh all the blobs whenever a new required
property is added to the manifest. This patch adds a DTBuilder class
for programatically constructing a DT and compiling it with `dtc`.
Bug: 117551352
Change-Id: Ic6962ad494c200d612988cf25648dd23b9d76c93
diff --git a/build/image/dtc.py b/build/image/dtc.py
old mode 100644
new mode 100755
index 49eeeb7..28a75c3
--- a/build/image/dtc.py
+++ b/build/image/dtc.py
@@ -25,17 +25,22 @@
def main():
parser = argparse.ArgumentParser()
- parser.add_argument("input_file")
- parser.add_argument("output_file")
+ parser.add_argument("-i", "--input-file")
+ parser.add_argument("-o", "--output-file")
args = parser.parse_args()
- return subprocess.call([
- DTC,
- "-I", "dts", "-O", "dtb",
- "-o", args.output_file,
- "--out-version", "17",
- args.input_file
- ])
+ dtc_args = [
+ DTC,
+ "-I", "dts", "-O", "dtb",
+ "--out-version", "17",
+ ]
+
+ if args.output_file:
+ dtc_args += [ "-o", args.output_file ]
+ if args.input_file:
+ dtc_args += [ args.input_file ]
+
+ return subprocess.call(dtc_args)
if __name__ == "__main__":
sys.exit(main())
diff --git a/build/image/image.gni b/build/image/image.gni
index bed73df..6c8ea17 100644
--- a/build/image/image.gni
+++ b/build/image/image.gni
@@ -164,7 +164,9 @@
dtb_file,
]
args = [
+ "-i",
"{{source}}",
+ "-o",
rebase_path(dtb_file),
]
}
diff --git a/src/manifest_test.cc b/src/manifest_test.cc
index 3a86a7a..0a23745 100644
--- a/src/manifest_test.cc
+++ b/src/manifest_test.cc
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+#include <array>
+#include <cstdio>
+#include <sstream>
+
#include <gmock/gmock.h>
extern "C" {
@@ -25,261 +29,276 @@
using ::testing::Eq;
using ::testing::NotNull;
-/*
- * DTB files compiled with:
- * $ dtc -I dts -O dtb --out-version 17 test.dts | xxd -i
- */
+template <typename T>
+void exec(const char *program, char *const args[], const T &stdin,
+ std::vector<char> *stdout)
+{
+ /* Create two pipes, one for stdin and one for stdout. */
+ int pipes[2][2];
+ pipe(pipes[0]);
+ pipe(pipes[1]);
-/*
- * /dts-v1/;
- *
- * / {
- * };
- *
- */
-constexpr uint8_t dtb_empty_root[] = {
- 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09};
+ /* Assign FDs for reading/writing by the parent/child. */
+ int parent_read_fd = pipes[1][0]; /* stdout pipe, read FD */
+ int parent_write_fd = pipes[0][1]; /* stdin pipe, write FD */
+ int child_read_fd = pipes[0][0]; /* stdin pipe, read FD */
+ int child_write_fd = pipes[1][1]; /* stdout pipe, write FD */
-TEST(manifest, empty_root)
+ if (fork()) {
+ /* Parent process. */
+ std::array<char, 128> buf;
+ ssize_t res;
+
+ /* Close child FDs which won't be used. */
+ close(child_read_fd);
+ close(child_write_fd);
+
+ /* Write to stdin. */
+ for (size_t count = 0; count < stdin.size();) {
+ res = write(parent_write_fd, stdin.data() + count,
+ stdin.size() - count);
+ if (res < 0) {
+ std::cerr << "IO error" << std::endl;
+ exit(1);
+ }
+ count += res;
+ }
+ close(parent_write_fd);
+
+ /* Read from stdout. */
+ while (true) {
+ res = read(parent_read_fd, buf.data(), buf.size());
+ if (res == 0) {
+ /* EOF */
+ break;
+ } else if (res < 0) {
+ std::cerr << "IO error" << std::endl;
+ exit(1);
+ }
+ stdout->insert(stdout->end(), buf.begin(),
+ buf.begin() + res);
+ }
+ close(parent_read_fd);
+ } else {
+ /* Child process. */
+
+ /* Redirect stdin/stdout to read/write FDs. */
+ dup2(child_read_fd, STDIN_FILENO);
+ dup2(child_write_fd, STDOUT_FILENO);
+
+ /* Close all FDs which are now unused. */
+ close(child_read_fd);
+ close(child_write_fd);
+ close(parent_read_fd);
+ close(parent_write_fd);
+
+ /* Execute the given program. */
+ execv(program, args);
+ }
+}
+
+/**
+ * Class for programatically building a Device Tree.
+ *
+ * Usage:
+ * std::vector<char> dtb = ManifestDtBuilder()
+ * .Command1()
+ * .Command2()
+ * ...
+ * .CommandN()
+ * .Build();
+ */
+class ManifestDtBuilder
+{
+ public:
+ ManifestDtBuilder()
+ {
+ dts_ << "/dts-v1/;" << std::endl;
+ dts_ << std::endl;
+
+ /* Start root node. */
+ StartChild("/");
+ }
+
+ std::vector<char> Build()
+ {
+ char *const dtc_args[] = {NULL};
+ std::vector<char> dtc_stdout;
+
+ /* Finish root node. */
+ EndChild();
+
+ exec("./build/image/dtc.py", dtc_args, dts_.str(), &dtc_stdout);
+ return dtc_stdout;
+ }
+
+ ManifestDtBuilder &StartChild(const std::string_view &name)
+ {
+ dts_ << name << " {" << std::endl;
+ return *this;
+ }
+
+ ManifestDtBuilder &EndChild()
+ {
+ dts_ << "};" << std::endl;
+ return *this;
+ }
+
+ ManifestDtBuilder &DebugName(const std::string_view &value)
+ {
+ return StringProperty("debug_name", value);
+ }
+
+ ManifestDtBuilder &KernelFilename(const std::string_view &value)
+ {
+ return StringProperty("kernel_filename", value);
+ }
+
+ ManifestDtBuilder &VcpuCount(uint64_t value)
+ {
+ return IntegerProperty("vcpu_count", value);
+ }
+
+ ManifestDtBuilder &MemSize(uint64_t value)
+ {
+ return IntegerProperty("mem_size", value);
+ }
+
+ private:
+ ManifestDtBuilder &StringProperty(const std::string_view &name,
+ const std::string_view &value)
+ {
+ dts_ << name << " = \"" << value << "\";" << std::endl;
+ return *this;
+ }
+
+ ManifestDtBuilder &IntegerProperty(const std::string_view &name,
+ uint64_t value)
+ {
+ dts_ << name << " = <" << value << ">;" << std::endl;
+ return *this;
+ }
+
+ std::stringstream dts_;
+};
+
+TEST(manifest, no_hypervisor_node)
{
struct manifest m;
struct memiter it;
+ std::vector<char> dtb = ManifestDtBuilder().Build();
- memiter_init(&it, dtb_empty_root, sizeof(dtb_empty_root));
+ memiter_init(&it, dtb.data(), dtb.size());
ASSERT_EQ(manifest_init(&m, &it),
MANIFEST_ERROR_NO_HYPERVISOR_FDT_NODE);
}
-/*
- * /dts-v1/;
- *
- * / {
- * hypervisor {
- * };
- * };
- *
- */
-constexpr uint8_t dtb_no_vms[] = {
- 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x79, 0x70, 0x65,
- 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09};
-
TEST(manifest, no_vms)
{
struct manifest m;
struct memiter it;
- memiter_init(&it, dtb_no_vms, sizeof(dtb_no_vms));
+ /* clang-format off */
+ std::vector<char> dtb = ManifestDtBuilder()
+ .StartChild("hypervisor")
+ .EndChild()
+ .Build();
+ /* clang-format on */
+
+ memiter_init(&it, dtb.data(), dtb.size());
ASSERT_EQ(manifest_init(&m, &it), MANIFEST_ERROR_NO_PRIMARY_VM);
}
-/*
- * /dts-v1/;
- *
- * / {
- * hypervisor {
- * vm1 {
- * debug_name = "primary_vm";
- * };
- * vm0 {
- * debug_name = "reserved_vm";
- * vcpu_count = <1>;
- * mem_size = <4096>;
- * kernel_filename = "kernel";
- * };
- * };
- * };
- *
- */
-constexpr uint8_t dtb_reserved_vmid[] = {
- 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f,
- 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x79, 0x70, 0x65,
- 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x76, 0x6d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x00, 0x00, 0x00, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f,
- 0x76, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x76, 0x6d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
- 0x00, 0x00, 0x00, 0x00, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64,
- 0x5f, 0x76, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1f,
- 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
- 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x76,
- 0x63, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x6d, 0x65,
- 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x6b, 0x65, 0x72, 0x6e, 0x65,
- 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x00};
-
TEST(manifest, reserved_vmid)
{
struct manifest m;
struct memiter it;
- memiter_init(&it, dtb_reserved_vmid, sizeof(dtb_reserved_vmid));
+ /* clang-format off */
+ std::vector<char> dtb = ManifestDtBuilder()
+ .StartChild("hypervisor")
+ .StartChild("vm1")
+ .DebugName("primary_vm")
+ .EndChild()
+ .StartChild("vm0")
+ .DebugName("reserved_vm")
+ .VcpuCount(1)
+ .MemSize(0x1000)
+ .KernelFilename("kernel")
+ .EndChild()
+ .EndChild()
+ .Build();
+ /* clang-format on */
+
+ memiter_init(&it, dtb.data(), dtb.size());
ASSERT_EQ(manifest_init(&m, &it), MANIFEST_ERROR_RESERVED_VM_ID);
}
-/*
- * /dts-v1/;
- *
- * / {
- * hypervisor {
- * vm1 {
- * debug_name = "";
- * };
- * vm2 {
- * debug_name = "";
- * vcpu_count = <65535>;
- * mem_size = <0>;
- * kernel_filename = "";
- * };
- * };
- * };
- *
- */
-constexpr uint8_t dtb_last_valid_vcpu_count[] = {
- 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f,
- 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x79, 0x70, 0x65,
- 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x76, 0x6d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x01, 0x76, 0x6d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x09, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x6e, 0x61,
- 0x6d, 0x65, 0x00, 0x76, 0x63, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
- 0x74, 0x00, 0x6d, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x6b,
- 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61,
- 0x6d, 0x65, 0x00};
-
-/* Same as above, set "vcpu_count" to 65536. */
-constexpr uint8_t dtb_first_invalid_vcpu_count[] = {
- 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f,
- 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x79, 0x70, 0x65,
- 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x76, 0x6d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x01, 0x76, 0x6d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x09, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x6e, 0x61,
- 0x6d, 0x65, 0x00, 0x76, 0x63, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
- 0x74, 0x00, 0x6d, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x6b,
- 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61,
- 0x6d, 0x65, 0x00};
+static std::vector<char> gen_vcpu_count_limit_dtb(uint64_t vcpu_count)
+{
+ /* clang-format off */
+ return ManifestDtBuilder()
+ .StartChild("hypervisor")
+ .StartChild("vm1")
+ .DebugName("primary_vm")
+ .EndChild()
+ .StartChild("vm2")
+ .DebugName("secondary_vm")
+ .VcpuCount(vcpu_count)
+ .MemSize(0x1000)
+ .KernelFilename("kernel")
+ .EndChild()
+ .EndChild()
+ .Build();
+ /* clang-format on */
+}
TEST(manifest, vcpu_count_limit)
{
struct manifest m;
struct memiter it;
+ std::vector<char> dtb_last_valid = gen_vcpu_count_limit_dtb(UINT16_MAX);
+ std::vector<char> dtb_first_invalid =
+ gen_vcpu_count_limit_dtb(UINT16_MAX + 1);
- memiter_init(&it, dtb_last_valid_vcpu_count,
- sizeof(dtb_last_valid_vcpu_count));
+ memiter_init(&it, dtb_last_valid.data(), dtb_last_valid.size());
ASSERT_EQ(manifest_init(&m, &it), MANIFEST_SUCCESS);
ASSERT_EQ(m.num_vms, 2);
ASSERT_EQ(m.vm[1].secondary.vcpu_count, UINT16_MAX);
- memiter_init(&it, dtb_first_invalid_vcpu_count,
- sizeof(dtb_first_invalid_vcpu_count));
+ memiter_init(&it, dtb_first_invalid.data(), dtb_first_invalid.size());
ASSERT_EQ(manifest_init(&m, &it), MANIFEST_ERROR_INTEGER_OVERFLOW);
}
-/*
- * /dts-v1/;
- *
- * / {
- * hypervisor {
- * vm1 {
- * debug_name = "primary_vm";
- * };
- * vm3 {
- * debug_name = "second_secondary_vm";
- * vcpu_count = <43>;
- * mem_size = <0x12345>;
- * kernel_filename = "second_kernel";
- * };
- * vm2 {
- * debug_name = "first_secondary_vm";
- * vcpu_count = <42>;
- * mem_size = <12345>;
- * kernel_filename = "first_kernel";
- * };
- * };
- * };
- *
- */
-constexpr uint8_t dtb_valid[] = {
- 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x00, 0x38,
- 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f,
- 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x79, 0x70, 0x65,
- 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x76, 0x6d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x00, 0x00, 0x00, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f,
- 0x76, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
- 0x76, 0x6d, 0x33, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x73,
- 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x76, 0x6d, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0b,
- 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x16, 0x00, 0x01, 0x23, 0x45, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1f, 0x73, 0x65, 0x63, 0x6f,
- 0x6e, 0x64, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x76, 0x6d, 0x32, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00,
- 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64,
- 0x61, 0x72, 0x79, 0x5f, 0x76, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2a,
- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16,
- 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d,
- 0x00, 0x00, 0x00, 0x1f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x6b, 0x65,
- 0x72, 0x6e, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
- 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x76,
- 0x63, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x00, 0x6d, 0x65,
- 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x6b, 0x65, 0x72, 0x6e, 0x65,
- 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x00};
-
TEST(manifest, valid)
{
struct manifest m;
struct manifest_vm *vm;
struct memiter it;
- memiter_init(&it, dtb_valid, sizeof(dtb_valid));
+ /* clang-format off */
+ std::vector<char> dtb = ManifestDtBuilder()
+ .StartChild("hypervisor")
+ .StartChild("vm1")
+ .DebugName("primary_vm")
+ .EndChild()
+ .StartChild("vm3")
+ .DebugName("second_secondary_vm")
+ .VcpuCount(43)
+ .MemSize(0x12345)
+ .KernelFilename("second_kernel")
+ .EndChild()
+ .StartChild("vm2")
+ .DebugName("first_secondary_vm")
+ .VcpuCount(42)
+ .MemSize(12345)
+ .KernelFilename("first_kernel")
+ .EndChild()
+ .EndChild()
+ .Build();
+ /* clang-format on */
+
+ memiter_init(&it, dtb.data(), dtb.size());
ASSERT_EQ(manifest_init(&m, &it), MANIFEST_SUCCESS);
ASSERT_EQ(m.num_vms, 3);