blob: bad2d2e3bd8f0f17d63a99043b3bee89f0792fc4 [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_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>
namespace {
constexpr char kDeviceId[] = "device-id";
constexpr char kMainFirmwareFile1[] = "NAND_10.20.30.40.fls";
constexpr char kMainFirmwareVersion1[] = "10.20.30.40";
constexpr char kMainFirmwareFile2[] = "NAND_10.20.30.45.fls";
constexpr char kMainFirmwareVersion2[] = "10.20.30.45";
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";
} // namespace
namespace modemfwd {
class FirmwareDirectoryTest : public ::testing::Test {
public:
FirmwareDirectoryTest() { CHECK(temp_dir_.CreateUniqueTempDir()); }
~FirmwareDirectoryTest() override = default;
protected:
void SetUpDirectory(const base::FilePath& manifest,
bool manifest_is_valid = true) {
base::FilePath manifest_in_dir =
temp_dir_.GetPath().Append("firmware_manifest.prototxt");
CHECK(base::CopyFile(manifest, manifest_in_dir));
firmware_directory_ = CreateFirmwareDirectory(temp_dir_.GetPath());
ASSERT_EQ(!!firmware_directory_, manifest_is_valid);
}
std::unique_ptr<FirmwareDirectory> firmware_directory_;
private:
base::ScopedTempDir temp_dir_;
};
TEST_F(FirmwareDirectoryTest, NoFirmwareForDevice) {
const base::FilePath kManifest("/dev/null");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_FALSE(res.main_firmware.has_value());
EXPECT_FALSE(res.carrier_firmware.has_value());
}
// ----------------------- MANIFEST V1 TESTS ----------------------------------
TEST_F(FirmwareDirectoryTest, FindFirmware) {
const base::FilePath kManifest("test_protos/find_firmware.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.main_firmware.has_value());
const FirmwareFileInfo& main_info = res.main_firmware.value();
EXPECT_EQ(kMainFirmwareFile1, main_info.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion1, main_info.version);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& carrier_info = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1,
carrier_info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, carrier_info.version);
}
TEST_F(FirmwareDirectoryTest, FirmwareForDifferentCarrier) {
const base::FilePath kManifest(
"test_protos/firmware_for_different_carrier.prototxt");
SetUpDirectory(kManifest);
std::string carrier_b(kCarrierB);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_b);
EXPECT_FALSE(res.carrier_firmware.has_value());
}
TEST_F(FirmwareDirectoryTest, FirmwareForDifferentDevice) {
const base::FilePath kManifest(
"test_protos/firmware_for_different_device.prototxt");
SetUpDirectory(kManifest);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, nullptr);
EXPECT_FALSE(res.main_firmware.has_value());
}
TEST_F(FirmwareDirectoryTest, MultipleCarrierFirmware) {
const base::FilePath kManifest(
"test_protos/multiple_carrier_firmware.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_a = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info_a.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_a.version);
std::string carrier_b(kCarrierB);
res = firmware_directory_->FindFirmware(kDeviceId, &carrier_b);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_b = res.carrier_firmware.value();
EXPECT_EQ(kCarrierB, carrier_b);
EXPECT_EQ(kCarrierFirmwareFile2, info_b.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion2, info_b.version);
}
TEST_F(FirmwareDirectoryTest, GenericFirmware) {
const base::FilePath kManifest("test_protos/generic_firmware.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info = res.carrier_firmware.value();
EXPECT_EQ(FirmwareDirectory::kGenericCarrierId, carrier_a);
EXPECT_EQ(kGenericCarrierFirmwareFile, info.firmware_path.BaseName().value());
EXPECT_EQ(kGenericCarrierFirmwareVersion, info.version);
}
TEST_F(FirmwareDirectoryTest, SpecificBeforeGeneric) {
const base::FilePath kManifest(
"test_protos/specific_before_generic.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info.version);
}
TEST_F(FirmwareDirectoryTest, FirmwareSupportsTwoCarriers) {
const base::FilePath kManifest("test_protos/two_carrier_firmware.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_a = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info_a.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_a.version);
std::string carrier_b(kCarrierB);
res = firmware_directory_->FindFirmware(kDeviceId, &carrier_b);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_b = res.carrier_firmware.value();
EXPECT_EQ(kCarrierB, carrier_b);
EXPECT_EQ(kCarrierFirmwareFile1, info_b.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_b.version);
std::string carrier_c(kCarrierC);
res = firmware_directory_->FindFirmware(kDeviceId, &carrier_c);
EXPECT_FALSE(res.carrier_firmware.has_value());
}
TEST_F(FirmwareDirectoryTest, MalformedMainEntry) {
const base::FilePath kManifest(
"test_protos/malformed_main_firmware.prototxt");
SetUpDirectory(kManifest, false);
}
TEST_F(FirmwareDirectoryTest, MalformedCarrierEntry) {
const base::FilePath kManifest(
"test_protos/malformed_carrier_firmware.prototxt");
SetUpDirectory(kManifest, false);
}
// ----------------------- MANIFEST V2 TESTS ----------------------------------
TEST_F(FirmwareDirectoryTest, FindFirmwareV2) {
const base::FilePath kManifest("test_protos/find_firmware_v2.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.main_firmware.has_value());
const FirmwareFileInfo& main_info = res.main_firmware.value();
EXPECT_EQ(kMainFirmwareFile1, main_info.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion1, main_info.version);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& carrier_info = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1,
carrier_info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, carrier_info.version);
}
TEST_F(FirmwareDirectoryTest, FirmwareForDifferentCarrierV2) {
const base::FilePath kManifest("test_protos/find_firmware_v2.prototxt");
SetUpDirectory(kManifest);
std::string carrier_b(kCarrierB);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_b);
EXPECT_FALSE(res.carrier_firmware.has_value());
}
TEST_F(FirmwareDirectoryTest, FirmwareForDifferentDeviceV2) {
const base::FilePath kManifest(
"test_protos/firmware_for_different_device_v2.prototxt");
SetUpDirectory(kManifest);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, nullptr);
EXPECT_FALSE(res.main_firmware.has_value());
}
TEST_F(FirmwareDirectoryTest, MultipleCarrierFirmwareV2) {
const base::FilePath kManifest(
"test_protos/multiple_carrier_firmware_v2.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_a = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info_a.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_a.version);
std::string carrier_b(kCarrierB);
res = firmware_directory_->FindFirmware(kDeviceId, &carrier_b);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_b = res.carrier_firmware.value();
EXPECT_EQ(kCarrierB, carrier_b);
EXPECT_EQ(kCarrierFirmwareFile2, info_b.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion2, info_b.version);
}
TEST_F(FirmwareDirectoryTest, GenericFirmwareV2) {
const base::FilePath kManifest("test_protos/generic_firmware_v2.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info = res.carrier_firmware.value();
EXPECT_EQ(FirmwareDirectory::kGenericCarrierId, carrier_a);
EXPECT_EQ(kGenericCarrierFirmwareFile, info.firmware_path.BaseName().value());
EXPECT_EQ(kGenericCarrierFirmwareVersion, info.version);
}
TEST_F(FirmwareDirectoryTest, FirmwareSupportsTwoCarriersV2) {
const base::FilePath kManifest(
"test_protos/two_carrier_firmware_v2.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_a = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info_a.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_a.version);
std::string carrier_b(kCarrierB);
res = firmware_directory_->FindFirmware(kDeviceId, &carrier_b);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_b = res.carrier_firmware.value();
EXPECT_EQ(kCarrierB, carrier_b);
EXPECT_EQ(kCarrierFirmwareFile1, info_b.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_b.version);
std::string carrier_c(kCarrierC);
res = firmware_directory_->FindFirmware(kDeviceId, &carrier_c);
EXPECT_FALSE(res.carrier_firmware.has_value());
}
TEST_F(FirmwareDirectoryTest, SpecificBeforeGenericV2) {
const base::FilePath kManifest(
"test_protos/specific_before_generic_v2.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info.version);
}
TEST_F(FirmwareDirectoryTest, MainFirmwareDefault) {
const base::FilePath kManifest("test_protos/main_firmware_default.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.main_firmware.has_value());
const FirmwareFileInfo& main_info = res.main_firmware.value();
EXPECT_EQ(kMainFirmwareFile1, main_info.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion1, main_info.version);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_a = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info_a.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_a.version);
}
TEST_F(FirmwareDirectoryTest, MainFirmwareDefaultForGeneric) {
const base::FilePath kManifest("test_protos/main_firmware_default.prototxt");
SetUpDirectory(kManifest);
// The default main firmware should also apply to the generic/no carrier
// case.
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, nullptr);
EXPECT_TRUE(res.main_firmware.has_value());
const FirmwareFileInfo& main_info_2 = res.main_firmware.value();
EXPECT_EQ(kMainFirmwareFile1, main_info_2.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion1, main_info_2.version);
}
TEST_F(FirmwareDirectoryTest, MainFirmwareSwitching) {
const base::FilePath kManifest(
"test_protos/main_firmware_switching.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.main_firmware.has_value());
const FirmwareFileInfo& main_info = res.main_firmware.value();
EXPECT_EQ(kMainFirmwareFile1, main_info.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion1, main_info.version);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_a = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info_a.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_a.version);
// Carrier B calls for different main firmware. This can only be encoded
// in manifest v2.
std::string carrier_b(kCarrierB);
res = firmware_directory_->FindFirmware(kDeviceId, &carrier_b);
EXPECT_TRUE(res.main_firmware.has_value());
const FirmwareFileInfo& main_info_2 = res.main_firmware.value();
EXPECT_EQ(kMainFirmwareFile2, main_info_2.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion2, main_info_2.version);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_b = res.carrier_firmware.value();
EXPECT_EQ(kCarrierB, carrier_b);
EXPECT_EQ(kCarrierFirmwareFile2, info_b.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion2, info_b.version);
}
TEST_F(FirmwareDirectoryTest, MainFirmwareFullySpecified) {
const base::FilePath kManifest(
"test_protos/main_firmware_specified.prototxt");
SetUpDirectory(kManifest);
std::string carrier_a(kCarrierA);
FirmwareDirectory::Files res =
firmware_directory_->FindFirmware(kDeviceId, &carrier_a);
EXPECT_TRUE(res.main_firmware.has_value());
const FirmwareFileInfo& main_info = res.main_firmware.value();
EXPECT_EQ(kMainFirmwareFile1, main_info.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion1, main_info.version);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_a = res.carrier_firmware.value();
EXPECT_EQ(kCarrierA, carrier_a);
EXPECT_EQ(kCarrierFirmwareFile1, info_a.firmware_path.BaseName().value());
EXPECT_EQ(kCarrierFirmwareVersion1, info_a.version);
// Carrier B uses the generic firmware, which specifies its own main firmware.
std::string carrier_b(kCarrierB);
res = firmware_directory_->FindFirmware(kDeviceId, &carrier_b);
EXPECT_TRUE(res.main_firmware.has_value());
const FirmwareFileInfo& main_info_2 = res.main_firmware.value();
EXPECT_EQ(kMainFirmwareFile2, main_info_2.firmware_path.BaseName().value());
EXPECT_EQ(kMainFirmwareVersion2, main_info_2.version);
EXPECT_TRUE(res.carrier_firmware.has_value());
const FirmwareFileInfo& info_b = res.carrier_firmware.value();
EXPECT_EQ(FirmwareDirectory::kGenericCarrierId, carrier_b);
EXPECT_EQ(kGenericCarrierFirmwareFile,
info_b.firmware_path.BaseName().value());
EXPECT_EQ(kGenericCarrierFirmwareVersion, info_b.version);
}
TEST_F(FirmwareDirectoryTest, MainFirmwareFullySpecifiedNoGeneric) {
// If each carrier directly specifies a present main firmware but there's no
// generic firmware, we can't flash anything for unknown carriers.
const base::FilePath kManifest(
"test_protos/main_firmware_specified_no_generic.prototxt");
SetUpDirectory(kManifest, false);
}
TEST_F(FirmwareDirectoryTest, CarrierSpecifiesAbsentMainFirmware) {
const base::FilePath kManifest(
"test_protos/carrier_specifies_absent_main.prototxt");
SetUpDirectory(kManifest, false);
}
TEST_F(FirmwareDirectoryTest, MalformedDeviceEntry) {
const base::FilePath kManifest("test_protos/malformed_device_entry.prototxt");
SetUpDirectory(kManifest, false);
}
TEST_F(FirmwareDirectoryTest, MalformedMainEntryV2) {
const base::FilePath kManifest(
"test_protos/malformed_main_firmware_v2.prototxt");
SetUpDirectory(kManifest, false);
}
TEST_F(FirmwareDirectoryTest, MalformedCarrierEntryV2) {
const base::FilePath kManifest(
"test_protos/malformed_carrier_firmware_v2.prototxt");
SetUpDirectory(kManifest, false);
}
} // namespace modemfwd