blob: 65b7146cd2cb0812d8205042c13f55a823bfeda7 [file] [log] [blame] [edit]
// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <base/values.h>
#include <gtest/gtest.h>
#include "imageloader/manifest.h"
namespace imageloader {
TEST(ArtifactsMetaTest, Equality) {
EXPECT_EQ((ArtifactsMeta{}), (ArtifactsMeta{.valid = false}));
EXPECT_EQ((ArtifactsMeta{.valid = false, .uri = "foo"}),
(ArtifactsMeta{.uri = "foo"}));
EXPECT_NE((ArtifactsMeta{.uri = "foo"}), (ArtifactsMeta{.uri = "bar"}));
}
TEST(ManifestTest, ParseManifest) {
const std::string fs_type = R"("ext4")";
const std::string is_removable = "true";
const std::string image_sha256_hash =
R"("4CF41BD11362CCB4707FB93939DBB5AC48745EDFC9DC8D7702852FFAA81B3B3F")";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string version = R"("9824.0.4")";
const std::string id = R"("foo")";
const std::string name = R"("bar")";
const std::string image_type = R"("dlc")";
const std::string preallocated_size = R"("600613")";
const std::string size = R"("42")";
const std::string preload_allowed = "true";
const std::string factory_install = "true";
const std::string mount_file_required = "true";
const std::string reserved = "true";
const std::string critical_update = "true";
const std::string description = R"("foo-description")";
const std::string manifest_version = "1";
const std::string use_logical_volume = "true";
const std::string scaled = "true";
const std::string powerwash_safe = "true";
const std::string artifacts_meta = R"({"uri": "gs://some/path"})";
const std::string manifest_raw = std::string() + R"(
{
"critical-update":)" + critical_update +
R"(,
"description":)" + description +
R"(,
"factory-install":)" + factory_install +
R"(,
"fs-type":)" + fs_type + R"(,
"id":)" + id + R"(,
"image-sha256-hash":)" + image_sha256_hash +
R"(,
"image-type":)" + image_type + R"(,
"is-removable":)" + is_removable +
R"(,
"manifest-version":)" + manifest_version +
R"(,
"mount-file-required":)" + mount_file_required +
R"(,
"name":)" + name + R"(,
"pre-allocated-size":)" + preallocated_size +
R"(,
"preload-allowed":)" + preload_allowed +
R"(,
"reserved":)" + reserved + R"(,
"size":)" + size + R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"version":)" + version + R"(,
"use-logical-volume":)" + use_logical_volume +
R"(,
"scaled":)" + scaled +
R"(,
"powerwash-safe":)" + powerwash_safe +
R"(,
"artifacts-meta":)" + artifacts_meta +
R"(
}
)";
Manifest manifest;
// Parse the manifest raw string.
ASSERT_TRUE(manifest.ParseManifest(manifest_raw));
EXPECT_EQ(manifest.fs_type(), FileSystem::kExt4);
EXPECT_EQ(manifest.is_removable(), true);
EXPECT_NE(manifest.image_sha256().size(), 0);
EXPECT_NE(manifest.table_sha256().size(), 0);
EXPECT_NE(manifest.version().size(), 0);
EXPECT_EQ(manifest.manifest_version(), 1);
EXPECT_EQ(manifest.id(), "foo");
EXPECT_EQ(manifest.name(), "bar");
EXPECT_EQ(manifest.image_type(), "dlc");
EXPECT_EQ(manifest.preallocated_size(), 600613);
EXPECT_EQ(manifest.size(), 42);
EXPECT_EQ(manifest.preload_allowed(), true);
EXPECT_EQ(manifest.factory_install(), true);
EXPECT_EQ(manifest.mount_file_required(), true);
EXPECT_EQ(manifest.description(), "foo-description");
EXPECT_EQ(manifest.reserved(), true);
EXPECT_EQ(manifest.critical_update(), true);
EXPECT_TRUE(manifest.use_logical_volume());
EXPECT_TRUE(manifest.scaled());
EXPECT_TRUE(manifest.powerwash_safe());
EXPECT_EQ(manifest.artifacts_meta(),
(ArtifactsMeta{.valid = true, .uri = "gs://some/path"}));
}
TEST(ManifestTest, ParseManifestNoOptional) {
const std::string is_removable = "true";
const std::string image_sha256_hash =
R"("4CF41BD11362CCB4707FB93939DBB5AC48745EDFC9DC8D7702852FFAA81B3B3F")";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string version = R"("9824.0.4")";
const std::string manifest_version = "1";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"image-sha256-hash":)" + image_sha256_hash +
R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"version":)" + version + R"(,
"manifest-version":)" + manifest_version +
R"(
}
)";
Manifest manifest;
// Parse the manifest raw string.
ASSERT_TRUE(manifest.ParseManifest(manifest_raw));
// Should default to squashfs.
EXPECT_EQ(manifest.fs_type(), FileSystem::kSquashFS);
EXPECT_EQ(manifest.is_removable(), true);
EXPECT_NE(manifest.image_sha256().size(), 0);
EXPECT_NE(manifest.table_sha256().size(), 0);
EXPECT_NE(manifest.version().size(), 0);
EXPECT_EQ(manifest.manifest_version(), 1);
EXPECT_EQ(manifest.preload_allowed(), false);
EXPECT_EQ(manifest.factory_install(), false);
EXPECT_EQ(manifest.description(), "");
EXPECT_EQ(manifest.reserved(), false);
EXPECT_EQ(manifest.critical_update(), false);
EXPECT_FALSE(manifest.use_logical_volume());
EXPECT_FALSE(manifest.scaled());
EXPECT_FALSE(manifest.powerwash_safe());
EXPECT_EQ(manifest.artifacts_meta(), (ArtifactsMeta{.valid = false}));
// Sizes should default to 0.
EXPECT_EQ(manifest.preallocated_size(), 0);
EXPECT_EQ(manifest.size(), 0);
}
TEST(ManifestTest, BadArtifactsMeta) {
const std::string is_removable = "true";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string version = R"("9824.0.4")";
const std::string manifest_version = "1";
const std::string bad_artifacts_meta = R"({"uri": 1})";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"version":)" + version + R"(,
"manifest-version":)" + manifest_version +
R"(,
"artifacts-meta":)" + bad_artifacts_meta +
R"(
}
)";
Manifest manifest;
// Parse the manifest raw string.
ASSERT_FALSE(manifest.ParseManifest(manifest_raw));
EXPECT_FALSE(manifest.artifacts_meta().valid);
}
TEST(ManifestTest, ParseManifestNoImageHash) {
const std::string is_removable = "true";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string version = R"("9824.0.4")";
const std::string manifest_version = "1";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"version":)" + version + R"(,
"manifest-version":)" + manifest_version +
R"(
}
)";
Manifest manifest;
// Parse the manifest raw string.
ASSERT_FALSE(manifest.ParseManifest(manifest_raw));
}
TEST(ManifestTest, ParseManifestNoTableHash) {
const std::string is_removable = "true";
const std::string image_sha256_hash =
R"("4CF41BD11362CCB4707FB93939DBB5AC48745EDFC9DC8D7702852FFAA81B3B3F")";
const std::string version = R"("9824.0.4")";
const std::string manifest_version = "1";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"image-sha256-hash":)" + image_sha256_hash +
R"(,
"version":)" + version + R"(,
"manifest-version":)" + manifest_version +
R"(
}
)";
Manifest manifest;
// Parse the manifest raw string.
ASSERT_FALSE(manifest.ParseManifest(manifest_raw));
}
TEST(ManifestTest, ParseManifestNoVersion) {
const std::string is_removable = "true";
const std::string image_sha256_hash =
R"("4CF41BD11362CCB4707FB93939DBB5AC48745EDFC9DC8D7702852FFAA81B3B3F")";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string manifest_version = "1";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"image-sha256-hash":)" + image_sha256_hash +
R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"manifest-version":)" + manifest_version +
R"(
}
)";
Manifest manifest;
// Parse the manifest raw string.
ASSERT_FALSE(manifest.ParseManifest(manifest_raw));
}
TEST(ManifestTest, ParseManifestBadPreallocatedSize) {
const std::string is_removable = "true";
const std::string image_sha256_hash =
R"("4CF41BD11362CCB4707FB93939DBB5AC48745EDFC9DC8D7702852FFAA81B3B3F")";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string version = R"("9824.0.4")";
const std::string manifest_version = "1";
const std::string pre_allocated_size = R"("not a number")";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"image-sha256-hash":)" + image_sha256_hash +
R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"version":)" + version + R"(,
"manifest-version":)" + manifest_version +
R"(,
"pre-allocated-size":)" + pre_allocated_size +
R"(
}
)";
Manifest manifest;
// Parse the manifest raw string.
ASSERT_FALSE(manifest.ParseManifest(manifest_raw));
}
TEST(ManifestTest, ParseManifestBadSize) {
const std::string is_removable = "true";
const std::string image_sha256_hash =
R"("4CF41BD11362CCB4707FB93939DBB5AC48745EDFC9DC8D7702852FFAA81B3B3F")";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string version = R"("9824.0.4")";
const std::string manifest_version = "1";
const std::string size = R"("not a number")";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"image-sha256-hash":)" + image_sha256_hash +
R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"version":)" + version + R"(,
"manifest-version":)" + manifest_version +
R"(,
"size":)" + size + R"(
}
)";
Manifest manifest;
// Parse the manifest raw string.
ASSERT_FALSE(manifest.ParseManifest(manifest_raw));
}
TEST(ManifestTest, ParseManifestValueDict) {
const base::Value::Dict manifest_dict =
base::Value::Dict()
.Set("fs-type", "ext2")
.Set("is-removable", true)
.Set("image-sha256-hash",
"4CF41BD11362CCB4707FB93939DBB5AC"
"48745EDFC9DC8D7702852FFAA81B3B3F")
.Set("table-sha256-hash",
"0E11DA3D7140C6B95496787F50D15152"
"434EBA22B60443BFA7E054FF4C799276")
.Set("version", "9824.0.4")
.Set("id", "foo")
.Set("name", "bar")
.Set("image-type", "dlc")
.Set("pre-allocated-size", "600613")
.Set("size", "42")
.Set("preload-allowed", true)
.Set("factory-install", true)
.Set("mount-file-required", true)
.Set("reserved", true)
.Set("critical-update", true)
.Set("description", "foo-description")
.Set("manifest-version", 1)
.Set("use-logical-volume", true)
.Set("scaled", true)
.Set("powerwash-safe", true)
.Set("artifacts-meta",
base::Value::Dict().Set("uri", "gs://some/path"));
Manifest manifest;
// Parse the manifest dict.
ASSERT_TRUE(manifest.ParseManifest(manifest_dict));
EXPECT_EQ(manifest.fs_type(), FileSystem::kExt2);
EXPECT_EQ(manifest.is_removable(), true);
EXPECT_NE(manifest.image_sha256().size(), 0);
EXPECT_NE(manifest.table_sha256().size(), 0);
EXPECT_NE(manifest.version().size(), 0);
EXPECT_EQ(manifest.manifest_version(), 1);
EXPECT_EQ(manifest.id(), "foo");
EXPECT_EQ(manifest.name(), "bar");
EXPECT_EQ(manifest.image_type(), "dlc");
EXPECT_EQ(manifest.preallocated_size(), 600613);
EXPECT_EQ(manifest.size(), 42);
EXPECT_EQ(manifest.preload_allowed(), true);
EXPECT_EQ(manifest.factory_install(), true);
EXPECT_EQ(manifest.mount_file_required(), true);
EXPECT_EQ(manifest.description(), "foo-description");
EXPECT_EQ(manifest.reserved(), true);
EXPECT_EQ(manifest.critical_update(), true);
EXPECT_TRUE(manifest.use_logical_volume());
EXPECT_TRUE(manifest.scaled());
EXPECT_TRUE(manifest.powerwash_safe());
EXPECT_EQ(manifest.artifacts_meta(),
(ArtifactsMeta{.valid = true, .uri = "gs://some/path"}));
}
TEST(ManifestTest, ManifestComparesEqual) {
const std::string is_removable = "true";
const std::string image_sha256_hash =
R"("4CF41BD11362CCB4707FB93939DBB5AC48745EDFC9DC8D7702852FFAA81B3B3F")";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string version = R"("9824.0.4")";
const std::string manifest_version = "1";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"image-sha256-hash":)" + image_sha256_hash +
R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"version":)" + version + R"(,
"manifest-version":)" + manifest_version +
R"(
}
)";
Manifest manifest_from_str;
// Parse the manifest raw string.
ASSERT_TRUE(manifest_from_str.ParseManifest(manifest_raw));
const base::Value::Dict manifest_dict =
base::Value::Dict()
.Set("is-removable", true)
.Set("image-sha256-hash",
"4CF41BD11362CCB4707FB93939DBB5AC"
"48745EDFC9DC8D7702852FFAA81B3B3F")
.Set("table-sha256-hash",
"0E11DA3D7140C6B95496787F50D15152"
"434EBA22B60443BFA7E054FF4C799276")
.Set("version", "9824.0.4")
.Set("manifest-version", 1);
Manifest manifest_from_val;
// Parse the manifest dict.
ASSERT_TRUE(manifest_from_val.ParseManifest(manifest_dict));
EXPECT_EQ(manifest_from_str, manifest_from_val);
}
TEST(ManifestTest, ManifestComparesNotEqual) {
const std::string is_removable = "true";
const std::string image_sha256_hash =
R"("4CF41BD11362CCB4707FB93939DBB5AC48745EDFC9DC8D7702852FFAA81B3B3F")";
const std::string table_sha256_hash =
R"("0E11DA3D7140C6B95496787F50D15152434EBA22B60443BFA7E054FF4C799276")";
const std::string version = R"("9824.0.4")";
const std::string manifest_version = "1";
const std::string manifest_raw = std::string() + R"(
{
"is-removable":)" + is_removable +
R"(,
"image-sha256-hash":)" + image_sha256_hash +
R"(,
"table-sha256-hash":)" + table_sha256_hash +
R"(,
"version":)" + version + R"(,
"manifest-version":)" + manifest_version +
R"(
}
)";
Manifest manifest_from_str;
// Parse the manifest raw string.
ASSERT_TRUE(manifest_from_str.ParseManifest(manifest_raw));
// Create a `base::Value::Dict` and set a different `is-removable` value.
const base::Value::Dict manifest_dict =
base::Value::Dict()
.Set("is-removable", false)
.Set("image-sha256-hash",
"4CF41BD11362CCB4707FB93939DBB5AC"
"48745EDFC9DC8D7702852FFAA81B3B3F")
.Set("table-sha256-hash",
"0E11DA3D7140C6B95496787F50D15152"
"434EBA22B60443BFA7E054FF4C799276")
.Set("version", "9824.0.4")
.Set("manifest-version", 1);
Manifest manifest_from_val;
// Parse the manifest dict.
ASSERT_TRUE(manifest_from_val.ParseManifest(manifest_dict));
EXPECT_FALSE(manifest_from_str == manifest_from_val);
}
TEST(ManifestTest, ManifestSanitized) {
const base::Value::Dict manifest_dict =
base::Value::Dict()
.Set("id", "foo")
.Set("pre-allocated-size", "600613")
.Set("size", "42")
.Set("user-tied", true)
.Set("image-sha256-hash",
"4CF41BD11362CCB4707FB93939DBB5AC"
"48745EDFC9DC8D7702852FFAA81B3B3F")
.Set("table-sha256-hash",
"0E11DA3D7140C6B95496787F50D15152"
"434EBA22B60443BFA7E054FF4C799276")
.Set("version", "9824.0.4")
.Set("manifest-version", 1);
Manifest manifest_from_val;
// Parse the manifest dict.
ASSERT_TRUE(manifest_from_val.ParseManifest(manifest_dict));
EXPECT_EQ(manifest_from_val.sanitized_id(), kDlcRedactedId);
EXPECT_EQ(manifest_from_val.sanitized_size(), kDlcRedactedSize);
EXPECT_EQ(manifest_from_val.sanitized_preallocated_size(), kDlcRedactedSize);
EXPECT_EQ(manifest_from_val.sanitized_image_sha256(), kDlcRedactedHash);
}
} // namespace imageloader