133 lines
4.9 KiB
C++
133 lines
4.9 KiB
C++
//
|
|
// Copyright (C) 2019 The Android Open Source Project
|
|
//
|
|
// 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 "update_engine/payload_generator/payload_properties.h"
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <base/files/file_util.h>
|
|
#include <base/files/scoped_file.h>
|
|
#include <base/files/scoped_temp_dir.h>
|
|
#include <base/rand_util.h>
|
|
#include <base/strings/stringprintf.h>
|
|
#include <brillo/data_encoding.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "update_engine/common/hash_calculator.h"
|
|
#include "update_engine/common/test_utils.h"
|
|
#include "update_engine/common/utils.h"
|
|
#include "update_engine/payload_consumer/install_plan.h"
|
|
#include "update_engine/payload_generator/delta_diff_generator.h"
|
|
#include "update_engine/payload_generator/delta_diff_utils.h"
|
|
#include "update_engine/payload_generator/full_update_generator.h"
|
|
#include "update_engine/payload_generator/operations_generator.h"
|
|
#include "update_engine/payload_generator/payload_file.h"
|
|
#include "update_engine/payload_generator/payload_generation_config.h"
|
|
|
|
using std::string;
|
|
using std::unique_ptr;
|
|
using std::vector;
|
|
|
|
namespace chromeos_update_engine {
|
|
|
|
// TODO(kimjae): current implementation is very specific to a static way of
|
|
// producing a deterministic test. It would definitely be beneficial to
|
|
// extend the |PayloadPropertiesTest::SetUp()| into a generic helper or
|
|
// seperate class that can handle creation of different |PayloadFile|s.
|
|
class PayloadPropertiesTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
PayloadGenerationConfig config;
|
|
config.version.major = kBrilloMajorPayloadVersion;
|
|
config.version.minor = kSourceMinorPayloadVersion;
|
|
PayloadFile payload;
|
|
EXPECT_TRUE(payload.Init(config));
|
|
|
|
const auto SetupPartitionConfig =
|
|
[](PartitionConfig* config, const string& path, size_t size) {
|
|
config->path = path;
|
|
config->size = size;
|
|
};
|
|
const auto WriteZerosToFile = [](const char path[], size_t size) {
|
|
string zeros(size, '\0');
|
|
EXPECT_TRUE(utils::WriteFile(path, zeros.c_str(), zeros.size()));
|
|
};
|
|
ScopedTempFile old_part_file("old_part.XXXXXX");
|
|
ScopedTempFile new_part_file("new_part.XXXXXX");
|
|
PartitionConfig old_part(kPartitionNameRoot);
|
|
PartitionConfig new_part(kPartitionNameRoot);
|
|
SetupPartitionConfig(&old_part, old_part_file.path(), 0);
|
|
SetupPartitionConfig(&new_part, new_part_file.path(), 10000);
|
|
WriteZerosToFile(old_part_file.path().c_str(), old_part.size);
|
|
WriteZerosToFile(new_part_file.path().c_str(), new_part.size);
|
|
|
|
// Select payload generation strategy based on the config.
|
|
unique_ptr<OperationsGenerator> strategy(new FullUpdateGenerator());
|
|
|
|
vector<AnnotatedOperation> aops;
|
|
off_t data_file_size = 0;
|
|
ScopedTempFile data_file("temp_data.XXXXXX", true);
|
|
BlobFileWriter blob_file_writer(data_file.fd(), &data_file_size);
|
|
// Generate the operations using the strategy we selected above.
|
|
EXPECT_TRUE(strategy->GenerateOperations(
|
|
config, old_part, new_part, &blob_file_writer, &aops));
|
|
|
|
payload.AddPartition(old_part, new_part, aops, {}, 0);
|
|
|
|
uint64_t metadata_size;
|
|
EXPECT_TRUE(payload.WritePayload(
|
|
payload_file_.path(), data_file.path(), "", &metadata_size));
|
|
}
|
|
|
|
ScopedTempFile payload_file_{"payload_file.XXXXXX"};
|
|
};
|
|
|
|
// Validate the hash of file exists within the output.
|
|
TEST_F(PayloadPropertiesTest, GetPropertiesAsJsonTestHash) {
|
|
constexpr char kJsonProperties[] =
|
|
"{"
|
|
R"("is_delta":true,)"
|
|
R"("metadata_signature":"",)"
|
|
R"("metadata_size":165,)"
|
|
R"("sha256_hex":"cV7kfZBH3K0B6QJHxxykDh6b6x0WgVOmc63whPLOy7U=",)"
|
|
R"("size":211,)"
|
|
R"("version":2)"
|
|
"}";
|
|
string json;
|
|
EXPECT_TRUE(
|
|
PayloadProperties(payload_file_.path()).GetPropertiesAsJson(&json));
|
|
EXPECT_EQ(kJsonProperties, json) << "JSON contents:\n" << json;
|
|
}
|
|
|
|
// Validate the hash of file and metadata are within the output.
|
|
TEST_F(PayloadPropertiesTest, GetPropertiesAsKeyValueTestHash) {
|
|
constexpr char kKeyValueProperties[] =
|
|
"FILE_HASH=cV7kfZBH3K0B6QJHxxykDh6b6x0WgVOmc63whPLOy7U=\n"
|
|
"FILE_SIZE=211\n"
|
|
"METADATA_HASH=aEKYyzJt2E8Gz8fzB+gmekN5mriotZCSq6R+kDfdeV4=\n"
|
|
"METADATA_SIZE=165\n";
|
|
string key_value;
|
|
EXPECT_TRUE(PayloadProperties{payload_file_.path()}.GetPropertiesAsKeyValue(
|
|
&key_value));
|
|
EXPECT_EQ(kKeyValueProperties, key_value) << "Key Value contents:\n"
|
|
<< key_value;
|
|
}
|
|
|
|
} // namespace chromeos_update_engine
|