blob: e10fe3267c4018a8681f94aa29e54f1139bd6f04 [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "modemfwd/firmware_directory.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <base/files/file.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>
namespace {
constexpr char kDeviceId[] = "device-id";
constexpr char kMainFirmwareFile[] = "NAND_10.20.30.40.fls";
constexpr char kMainFirmwareVersion[] = "10.20.30.40";
constexpr char kCarrierA[] = "CarrierA";
constexpr char kCarrierFirmwareFile1[] = "CarrierA_40.30.20.10.fls";
constexpr char kCarrierFirmwareVersion1[] = "40.30.20.10";
constexpr char kCarrierB[] = "CarrierB";
constexpr char kCarrierFirmwareFile2[] = "Custom_B_50_60.fls";
constexpr char kCarrierFirmwareVersion2[] = "50.60.70.80";
constexpr char kCarrierC[] = "CarrierC";
constexpr char kGenericCarrierFirmwareFile[] = "Generic_V1.59.3.fls";
constexpr char kGenericCarrierFirmwareVersion[] = "V1.59.3";
// To generate a manifest, execute the following:
// protoc --proto_path . --encode modemfwd.FirmwareManifest \
// firmware_manifest.proto < path/to/file.prototxt | xxd -i
// generated from find_firmware.prototxt
std::vector<char> kFindFirmwareManifest{
0x0a, 0x2e, 0x0a, 0x14, 0x4e, 0x41, 0x4e, 0x44, 0x5f, 0x31, 0x30, 0x2e,
0x32, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x34, 0x30, 0x2e, 0x66, 0x6c, 0x73,
0x12, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x1a,
0x0b, 0x31, 0x30, 0x2e, 0x32, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x34, 0x30,
0x12, 0x3c, 0x0a, 0x18, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x41,
0x5f, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32, 0x30, 0x2e, 0x31, 0x30,
0x2e, 0x66, 0x6c, 0x73, 0x12, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
0x2d, 0x69, 0x64, 0x1a, 0x08, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72,
0x41, 0x22, 0x0b, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32, 0x30, 0x2e,
0x31, 0x30
};
// generated from firmware_for_different_carrier.prototxt
std::vector<char> kDifferentCarrierManifest{
0x12, 0x3c, 0x0a, 0x18, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x41,
0x5f, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32, 0x30, 0x2e, 0x31, 0x30,
0x2e, 0x66, 0x6c, 0x73, 0x12, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
0x2d, 0x69, 0x64, 0x1a, 0x08, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72,
0x41, 0x22, 0x0b, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32, 0x30, 0x2e,
0x31, 0x30
};
// generated from firmware_for_different_device.prototxt
std::vector<char> kDifferentDeviceManifest{
0x0a, 0x30, 0x0a, 0x14, 0x4e, 0x41, 0x4e, 0x44, 0x5f, 0x31, 0x30, 0x2e,
0x32, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x34, 0x30, 0x2e, 0x66, 0x6c, 0x73,
0x12, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x2d,
0x32, 0x1a, 0x0b, 0x31, 0x30, 0x2e, 0x32, 0x30, 0x2e, 0x33, 0x30, 0x2e,
0x34, 0x30
};
// generated from multiple_carrier_firmware.prototxt
std::vector<char> kMultipleCarrierFirmwareManifest{
0x12, 0x3c, 0x0a, 0x18, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x41,
0x5f, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32, 0x30, 0x2e, 0x31, 0x30,
0x2e, 0x66, 0x6c, 0x73, 0x12, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
0x2d, 0x69, 0x64, 0x1a, 0x08, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72,
0x41, 0x22, 0x0b, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32, 0x30, 0x2e,
0x31, 0x30, 0x12, 0x36, 0x0a, 0x12, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
0x5f, 0x42, 0x5f, 0x35, 0x30, 0x5f, 0x36, 0x30, 0x2e, 0x66, 0x6c, 0x73,
0x12, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x1a,
0x08, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x42, 0x22, 0x0b, 0x35,
0x30, 0x2e, 0x36, 0x30, 0x2e, 0x37, 0x30, 0x2e, 0x38, 0x30
};
// generated from generic_firmware.prototxt
std::vector<char> kGenericFirmwareManifest{
0x12, 0x32, 0x0a, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f,
0x56, 0x31, 0x2e, 0x35, 0x39, 0x2e, 0x33, 0x2e, 0x66, 0x6c, 0x73, 0x12,
0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x1a, 0x07,
0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x22, 0x07, 0x56, 0x31, 0x2e,
0x35, 0x39, 0x2e, 0x33
};
// generated from specific_before_generic.prototxt
std::vector<char> kSpecificBeforeGenericManifest{
0x12, 0x32, 0x0a, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f,
0x56, 0x31, 0x2e, 0x35, 0x39, 0x2e, 0x33, 0x2e, 0x66, 0x6c, 0x73, 0x12,
0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x1a, 0x07,
0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x22, 0x07, 0x56, 0x31, 0x2e,
0x35, 0x39, 0x2e, 0x33, 0x12, 0x3c, 0x0a, 0x18, 0x43, 0x61, 0x72, 0x72,
0x69, 0x65, 0x72, 0x41, 0x5f, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32,
0x30, 0x2e, 0x31, 0x30, 0x2e, 0x66, 0x6c, 0x73, 0x12, 0x09, 0x64, 0x65,
0x76, 0x69, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x1a, 0x08, 0x43, 0x61, 0x72,
0x72, 0x69, 0x65, 0x72, 0x41, 0x22, 0x0b, 0x34, 0x30, 0x2e, 0x33, 0x30,
0x2e, 0x32, 0x30, 0x2e, 0x31, 0x30
};
// generated from two_carrier_firmware.prototxt
std::vector<char> kTwoCarrierFirmwareManifest{
0x12, 0x46, 0x0a, 0x18, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x41,
0x5f, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32, 0x30, 0x2e, 0x31, 0x30,
0x2e, 0x66, 0x6c, 0x73, 0x12, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
0x2d, 0x69, 0x64, 0x1a, 0x08, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72,
0x41, 0x1a, 0x08, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x42, 0x22,
0x0b, 0x34, 0x30, 0x2e, 0x33, 0x30, 0x2e, 0x32, 0x30, 0x2e, 0x31, 0x30
};
// generated from malformed_main_firmware.prototxt
std::vector<char> kMalformedMainFirmwareManifest{
0x0a, 0x20, 0x0a, 0x13, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x5f, 0x66,
0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x66, 0x6c, 0x73, 0x12,
0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x69, 0x64
};
// generated from malformed_carrier_firmware.prototxt
std::vector<char> kMalformedCarrierFirmwareManifest{
0x12, 0x1b, 0x12, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x69,
0x64, 0x1a, 0x08, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x41, 0x22,
0x04, 0x39, 0x30, 0x30, 0x31
};
} // namespace
namespace modemfwd {
class FirmwareDirectoryTest : public ::testing::Test {
public:
FirmwareDirectoryTest() {
CHECK(temp_dir_.CreateUniqueTempDir());
}
~FirmwareDirectoryTest() override = default;
protected:
void SetUpDirectory(const std::vector<char>& manifest) {
base::File file(temp_dir_.path().Append("manifest.proto"),
base::File::FLAG_CREATE | base::File::FLAG_WRITE);
CHECK(file.IsValid());
file.WriteAtCurrentPos(manifest.data(), manifest.size());
firmware_directory_ = CreateFirmwareDirectory(temp_dir_.path());
}
std::unique_ptr<FirmwareDirectory> firmware_directory_;
private:
base::ScopedTempDir temp_dir_;
};
TEST_F(FirmwareDirectoryTest, FindFirmware) {
SetUpDirectory(kFindFirmwareManifest);
FirmwareFileInfo info;
EXPECT_TRUE(firmware_directory_->FindMainFirmware(kDeviceId, &info));
EXPECT_EQ(kMainFirmwareFile, info.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion, info.version);
std::string carrier_a(kCarrierA);
EXPECT_TRUE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_a, &info));
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info.version);
}
TEST_F(FirmwareDirectoryTest, NoFirmwareForDevice) {
SetUpDirectory({});
FirmwareFileInfo info;
EXPECT_FALSE(firmware_directory_->FindMainFirmware(kDeviceId, &info));
std::string carrier_a(kCarrierA);
EXPECT_FALSE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_a, &info));
}
TEST_F(FirmwareDirectoryTest, FirmwareForDifferentCarrier) {
SetUpDirectory(kDifferentCarrierManifest);
FirmwareFileInfo info;
std::string carrier_b(kCarrierB);
EXPECT_FALSE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_b, &info));
}
TEST_F(FirmwareDirectoryTest, FirmwareForDifferentDevice) {
SetUpDirectory(kDifferentDeviceManifest);
FirmwareFileInfo info;
EXPECT_FALSE(firmware_directory_->FindMainFirmware(kDeviceId, &info));
}
TEST_F(FirmwareDirectoryTest, MultipleCarrierFirmware) {
SetUpDirectory(kMultipleCarrierFirmwareManifest);
FirmwareFileInfo info;
std::string carrier_a(kCarrierA);
EXPECT_TRUE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_a, &info));
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info.version);
std::string carrier_b(kCarrierB);
EXPECT_TRUE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_b, &info));
EXPECT_EQ(kCarrierB, carrier_b);
EXPECT_EQ(kCarrierFirmwareFile2, info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion2, info.version);
}
TEST_F(FirmwareDirectoryTest, GenericFirmware) {
SetUpDirectory(kGenericFirmwareManifest);
FirmwareFileInfo info;
std::string carrier_a(kCarrierA);
EXPECT_TRUE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_a, &info));
EXPECT_EQ(FirmwareDirectory::kGenericCarrierId, carrier_a);
EXPECT_EQ(kGenericCarrierFirmwareFile, info.firmware_path.BaseName().value());
EXPECT_EQ(kGenericCarrierFirmwareVersion, info.version);
}
TEST_F(FirmwareDirectoryTest, SpecificBeforeGeneric) {
SetUpDirectory(kSpecificBeforeGenericManifest);
FirmwareFileInfo info;
std::string carrier_a(kCarrierA);
EXPECT_TRUE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_a, &info));
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info.version);
}
TEST_F(FirmwareDirectoryTest, FirmwareSupportsTwoCarriers) {
SetUpDirectory(kTwoCarrierFirmwareManifest);
FirmwareFileInfo info;
std::string carrier_a(kCarrierA);
EXPECT_TRUE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_a, &info));
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info.version);
std::string carrier_b(kCarrierB);
EXPECT_TRUE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_b, &info));
EXPECT_EQ(kCarrierB, carrier_b);
EXPECT_EQ(kCarrierFirmwareFile1, info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info.version);
std::string carrier_c(kCarrierC);
EXPECT_FALSE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_c, &info));
}
TEST_F(FirmwareDirectoryTest, MalformedMainEntry) {
SetUpDirectory(kMalformedMainFirmwareManifest);
FirmwareFileInfo info;
EXPECT_FALSE(firmware_directory_->FindMainFirmware(kDeviceId, &info));
}
TEST_F(FirmwareDirectoryTest, MalformedCarrierEntry) {
SetUpDirectory(kMalformedCarrierFirmwareManifest);
FirmwareFileInfo info;
std::string carrier_a(kCarrierA);
EXPECT_FALSE(
firmware_directory_->FindCarrierFirmware(kDeviceId, &carrier_a, &info));
}
} // namespace modemfwd