2021-08-24 05:45:40 +00:00
|
|
|
// Copyright 2021 The Pigweed Authors
|
|
|
|
//
|
|
|
|
// 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
|
|
|
|
//
|
|
|
|
// https://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 "pw_software_update/update_bundle.h"
|
|
|
|
|
2021-09-22 01:36:59 +00:00
|
|
|
#include <array>
|
|
|
|
|
2021-08-24 05:45:40 +00:00
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "pw_kvs/fake_flash_memory.h"
|
|
|
|
#include "pw_kvs/test_key_value_store.h"
|
2021-09-22 01:36:59 +00:00
|
|
|
#include "pw_software_update/bundled_update_backend.h"
|
2021-09-17 16:55:49 +00:00
|
|
|
#include "test_bundles.h"
|
|
|
|
|
|
|
|
#define ASSERT_OK(status) ASSERT_EQ(OkStatus(), status)
|
2021-08-24 05:45:40 +00:00
|
|
|
|
|
|
|
namespace pw::software_update {
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
constexpr size_t kBufferSize = 256;
|
|
|
|
static constexpr size_t kFlashAlignment = 16;
|
|
|
|
constexpr size_t kSectorSize = 2048;
|
|
|
|
constexpr size_t kSectorCount = 2;
|
2021-09-22 01:36:59 +00:00
|
|
|
constexpr size_t kMetadataBufferSize =
|
|
|
|
blob_store::BlobStore::BlobWriter::RequiredMetadataBufferSize(0);
|
|
|
|
|
|
|
|
class TestBundledUpdateBackend final : public BundledUpdateBackend {
|
|
|
|
public:
|
|
|
|
Status FinalizeApply() override { return OkStatus(); }
|
|
|
|
|
|
|
|
Status ApplyTargetFile(std::string_view, stream::Reader&) override {
|
|
|
|
return OkStatus();
|
|
|
|
}
|
2021-09-22 17:07:09 +00:00
|
|
|
|
|
|
|
Result<uint32_t> EnableBundleTransferHandler() override { return 0; }
|
|
|
|
|
|
|
|
void DisableBundleTransferHandler() override {}
|
2021-09-22 01:36:59 +00:00
|
|
|
};
|
2021-08-24 05:45:40 +00:00
|
|
|
|
|
|
|
class UpdateBundleTest : public testing::Test {
|
|
|
|
public:
|
|
|
|
UpdateBundleTest()
|
|
|
|
: blob_flash_(kFlashAlignment),
|
|
|
|
blob_partition_(&blob_flash_),
|
2021-09-01 21:32:28 +00:00
|
|
|
bundle_blob_("TestBundle",
|
2021-08-24 05:45:40 +00:00
|
|
|
blob_partition_,
|
|
|
|
nullptr,
|
|
|
|
kvs::TestKvs(),
|
|
|
|
kBufferSize) {}
|
|
|
|
|
2021-09-01 21:32:28 +00:00
|
|
|
blob_store::BlobStoreBuffer<kBufferSize>& bundle_blob() {
|
|
|
|
return bundle_blob_;
|
2021-08-24 05:45:40 +00:00
|
|
|
}
|
|
|
|
|
2021-09-01 21:32:28 +00:00
|
|
|
BundledUpdateBackend& backend() { return backend_; }
|
2021-08-24 05:45:40 +00:00
|
|
|
|
2021-09-17 16:55:49 +00:00
|
|
|
void StageTestBundle(ConstByteSpan bundle_data) {
|
|
|
|
ASSERT_OK(bundle_blob_.Init());
|
2021-09-22 01:36:59 +00:00
|
|
|
blob_store::BlobStore::BlobWriter blob_writer(bundle_blob(),
|
|
|
|
metadata_buffer_);
|
2021-09-17 16:55:49 +00:00
|
|
|
ASSERT_OK(blob_writer.Open());
|
|
|
|
ASSERT_OK(blob_writer.Write(bundle_data));
|
|
|
|
ASSERT_OK(blob_writer.Close());
|
|
|
|
}
|
|
|
|
|
2021-08-24 05:45:40 +00:00
|
|
|
private:
|
|
|
|
kvs::FakeFlashMemoryBuffer<kSectorSize, kSectorCount> blob_flash_;
|
|
|
|
kvs::FlashPartition blob_partition_;
|
2021-09-01 21:32:28 +00:00
|
|
|
blob_store::BlobStoreBuffer<kBufferSize> bundle_blob_;
|
2021-09-22 01:36:59 +00:00
|
|
|
std::array<std::byte, kMetadataBufferSize> metadata_buffer_;
|
|
|
|
TestBundledUpdateBackend backend_;
|
2021-08-24 05:45:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2021-09-17 16:55:49 +00:00
|
|
|
TEST_F(UpdateBundleTest, GetTargetPayload) {
|
|
|
|
StageTestBundle(kTestBundle);
|
|
|
|
UpdateBundle update_bundle(bundle_blob(), backend());
|
|
|
|
|
|
|
|
Manifest current_manifest;
|
|
|
|
ASSERT_OK(update_bundle.OpenAndVerify(current_manifest));
|
|
|
|
|
|
|
|
{
|
|
|
|
stream::IntervalReader res = update_bundle.GetTargetPayload("file1");
|
|
|
|
ASSERT_OK(res.status());
|
|
|
|
|
|
|
|
const char kExpectedContent[] = "file 1 content";
|
|
|
|
char read_buffer[sizeof(kExpectedContent) + 1] = {0};
|
|
|
|
ASSERT_TRUE(res.Read(read_buffer, sizeof(kExpectedContent)).ok());
|
|
|
|
ASSERT_STREQ(read_buffer, kExpectedContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
stream::IntervalReader res = update_bundle.GetTargetPayload("file2");
|
|
|
|
ASSERT_OK(res.status());
|
|
|
|
|
|
|
|
const char kExpectedContent[] = "file 2 content";
|
|
|
|
char read_buffer[sizeof(kExpectedContent) + 1] = {0};
|
|
|
|
ASSERT_TRUE(res.Read(read_buffer, sizeof(kExpectedContent)).ok());
|
|
|
|
ASSERT_STREQ(read_buffer, kExpectedContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
stream::IntervalReader res = update_bundle.GetTargetPayload("non-exist");
|
|
|
|
ASSERT_EQ(res.status(), Status::NotFound());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(UpdateBundleTest, IsTargetPayloadIncluded) {
|
|
|
|
StageTestBundle(kTestBundle);
|
|
|
|
UpdateBundle update_bundle(bundle_blob(), backend());
|
|
|
|
|
|
|
|
Manifest current_manifest;
|
|
|
|
ASSERT_OK(update_bundle.OpenAndVerify(current_manifest));
|
|
|
|
|
|
|
|
Result<bool> res = update_bundle.IsTargetPayloadIncluded("file1");
|
|
|
|
ASSERT_OK(res.status());
|
|
|
|
ASSERT_TRUE(res.value());
|
|
|
|
|
|
|
|
res = update_bundle.IsTargetPayloadIncluded("file2");
|
|
|
|
ASSERT_OK(res.status());
|
|
|
|
ASSERT_TRUE(res.value());
|
|
|
|
|
|
|
|
res = update_bundle.IsTargetPayloadIncluded("non-exist");
|
|
|
|
ASSERT_OK(res.status());
|
|
|
|
ASSERT_FALSE(res.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(UpdateBundleTest, WriteManifest) {
|
|
|
|
StageTestBundle(kTestBundle);
|
|
|
|
UpdateBundle update_bundle(bundle_blob(), backend());
|
|
|
|
|
|
|
|
Manifest current_manifest;
|
|
|
|
ASSERT_OK(update_bundle.OpenAndVerify(current_manifest));
|
|
|
|
|
|
|
|
std::byte manifest_buffer[sizeof(kTestBundleManifest)];
|
|
|
|
stream::MemoryWriter manifest_writer(manifest_buffer);
|
|
|
|
ASSERT_OK(update_bundle.WriteManifest(manifest_writer));
|
|
|
|
|
|
|
|
ASSERT_EQ(
|
|
|
|
memcmp(manifest_buffer, kTestBundleManifest, sizeof(kTestBundleManifest)),
|
|
|
|
0);
|
|
|
|
}
|
2021-08-24 05:45:40 +00:00
|
|
|
|
|
|
|
} // namespace pw::software_update
|