123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596 |
- // Copyright 2020 The Chromium 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 <memory>
- #include <string>
- #include <utility>
- #include <vector>
- #include "chromeos/printing/ppd_metadata_manager.h"
- #include "base/bind.h"
- #include "base/containers/flat_map.h"
- #include "base/run_loop.h"
- #include "base/test/simple_test_clock.h"
- #include "base/test/task_environment.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- #include "base/time/clock.h"
- #include "chromeos/printing/fake_printer_config_cache.h"
- #include "chromeos/printing/ppd_metadata_matchers.h"
- #include "chromeos/printing/ppd_metadata_parser.h"
- #include "chromeos/printing/ppd_provider.h"
- #include "chromeos/printing/printer_config_cache.h"
- #include "testing/gmock/include/gmock/gmock-matchers.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace chromeos {
- namespace {
- using ::testing::ElementsAre;
- using ::testing::Pair;
- using ::testing::StrEq;
- using ::testing::UnorderedElementsAre;
- // Default browser locale used to construct PpdMetadataManager instances
- // in the test fixture. Arbitrarily chosen. Changeable by calling
- // PpdMetadataManagerTest::NewManagerWithLocale().
- constexpr base::StringPiece kBrowserLocaleForTesting = "en-US";
- // Arbitrarily chosen TimeDelta used in test cases that are not
- // time-senstive.
- constexpr base::TimeDelta kArbitraryTimeDelta = base::Seconds(30LL);
- // Arbitrarily malformed JSON used to exercise code paths in which
- // parsing fails.
- constexpr base::StringPiece kInvalidJson = "blah blah invalid JSON";
- // Caller may bind a default-constructed base::RepeatingClosure to
- // any Catch*() method, indicating that they don't want anything run.
- class PpdMetadataManagerTest : public ::testing::Test {
- public:
- // Callback method appropriate for passing to
- // PpdMetadataManager::GetLocale().
- void CatchGetLocale(base::RepeatingClosure quit_closure, bool succeeded) {
- results_.get_locale_succeeded = succeeded;
- if (quit_closure) {
- quit_closure.Run();
- }
- }
- // Callback method appropriate for passing to
- // PpdMetadataManager::GetManufacturers().
- void CatchGetManufacturers(base::RepeatingClosure quit_closure,
- PpdProvider::CallbackResultCode code,
- const std::vector<std::string>& manufacturers) {
- results_.get_manufacturers_code = code;
- results_.manufacturers = manufacturers;
- if (quit_closure) {
- quit_closure.Run();
- }
- }
- // Callback method appropriate for passing to
- // PpdMetadataManager::GetPrinters().
- void CatchGetPrinters(base::RepeatingClosure quit_closure,
- bool succeeded,
- const ParsedPrinters& printers) {
- results_.get_printers_succeeded = succeeded;
- results_.printers = printers;
- if (quit_closure) {
- quit_closure.Run();
- }
- }
- // Callback method appropriate for passing to
- // PpdMetadataManager::FindAllEmmsAvailableInIndex().
- void CatchFindAllEmmsAvailableInIndex(
- base::RepeatingClosure quit_closure,
- const base::flat_map<std::string, ParsedIndexValues>& values) {
- results_.available_effective_make_and_model_strings = values;
- if (quit_closure) {
- quit_closure.Run();
- }
- }
- // Callback method appropriate for passing to
- // PpdMetadataManager::FindDeviceInUsbIndex().
- void CatchFindDeviceInUsbIndex(base::RepeatingClosure quit_closure,
- const std::string& value) {
- results_.effective_make_and_model_string_from_usb_index = value;
- if (quit_closure) {
- quit_closure.Run();
- }
- }
- // Callback method appropriate for passing to
- // PpdMetadataManager::GetUsbManufacturerName().
- void CatchGetUsbManufacturerName(base::RepeatingClosure quit_closure,
- const std::string& value) {
- results_.usb_manufacturer_name = value;
- if (quit_closure) {
- quit_closure.Run();
- }
- }
- // Callback method appropriate for passing to
- // PpdMetadataManager::SplitMakeAndModel().
- void CatchSplitMakeAndModel(base::RepeatingClosure quit_closure,
- PpdProvider::CallbackResultCode code,
- const std::string& make,
- const std::string& model) {
- results_.split_make_and_model_code = code;
- results_.split_make = make;
- results_.split_model = model;
- if (quit_closure) {
- quit_closure.Run();
- }
- }
- protected:
- // Convenience container that organizes all callback results.
- struct CallbackLandingArea {
- CallbackLandingArea()
- : get_locale_succeeded(false), get_printers_succeeded(false) {}
- ~CallbackLandingArea() = default;
- // Landing area for PpdMetadataManager::GetLocale().
- bool get_locale_succeeded;
- // Landing area for PpdMetadataManager::GetManufacturers().
- PpdProvider::CallbackResultCode get_manufacturers_code;
- std::vector<std::string> manufacturers;
- // Landing area for PpdMetadataManager::GetPrinters().
- bool get_printers_succeeded;
- ParsedPrinters printers;
- // Landing area for
- // PpdMetadataManager::FindAllEmmsAvailableInIndex().
- base::flat_map<std::string, ParsedIndexValues>
- available_effective_make_and_model_strings;
- // Landing area for
- // PpdMetadataManager::FindDeviceInUsbIndex().
- std::string effective_make_and_model_string_from_usb_index;
- // Landing area for
- // PpdMetadataManager::GetUsbManufacturerName().
- std::string usb_manufacturer_name;
- // Landing area for PpdMetadataManager::SplitMakeAndModel().
- PpdProvider::CallbackResultCode split_make_and_model_code;
- std::string split_make;
- std::string split_model;
- };
- PpdMetadataManagerTest()
- : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
- manager_(PpdMetadataManager::Create(
- kBrowserLocaleForTesting,
- &clock_,
- std::make_unique<FakePrinterConfigCache>())) {}
- // Borrows and returns a pointer to the config cache owned by the
- // |manager_|.
- //
- // Useful for adjusting availability of (fake) network resources.
- FakePrinterConfigCache* GetFakeCache() {
- return reinterpret_cast<FakePrinterConfigCache*>(
- manager_->GetPrinterConfigCacheForTesting());
- }
- // Recreates |manager_| with a new |browser_locale|.
- //
- // Useful for testing the manager's ability to parse and select a
- // proper metadata locale.
- void NewManagerWithLocale(base::StringPiece browser_locale) {
- manager_.reset();
- manager_ = PpdMetadataManager::Create(
- browser_locale, &clock_, std::make_unique<FakePrinterConfigCache>());
- }
- // Holder for all callback results.
- CallbackLandingArea results_;
- // Environment for task schedulers.
- base::test::TaskEnvironment task_environment_;
- // Controlled clock that dispenses times of Fetch().
- base::SimpleTestClock clock_;
- // Class under test.
- std::unique_ptr<PpdMetadataManager> manager_;
- };
- // Verifies that the manager can fetch and parse the best-fit
- // locale from the Chrome OS Printing serving root.
- //
- // This test is done against the default browser locale used
- // throughout this suite, "en-US."
- TEST_F(PpdMetadataManagerTest, CanGetLocale) {
- // Known interaction: the manager will fetch the locales metadata.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/locales.json", R"({ "locales": [ "de", "en", "es" ] })");
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
- base::Unretained(this), loop.QuitClosure());
- auto call =
- base::BindOnce(&PpdMetadataManager::GetLocale,
- base::Unretained(manager_.get()), std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_TRUE(results_.get_locale_succeeded);
- EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq("en"));
- }
- // Verifies that the manager defaults to the English ("en") locale
- // when it can find no closer fit for the browser locale.
- TEST_F(PpdMetadataManagerTest, DefaultsToEnglishLocale) {
- // Sets an arbitrarily chosen locale quite distant from what the
- // fake serving root will have available.
- NewManagerWithLocale("ja-JP");
- // Known interaction: the manager will fetch the locales metadata.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/locales.json",
- R"({ "locales": [ "de", "en", "es", "wo" ] })");
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
- base::Unretained(this), loop.QuitClosure());
- auto call =
- base::BindOnce(&PpdMetadataManager::GetLocale,
- base::Unretained(manager_.get()), std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_TRUE(results_.get_locale_succeeded);
- EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq("en"));
- }
- // Given that the browser locale is not "en-US," verifies that the
- // manager can select a best-fit locale when one is available.
- TEST_F(PpdMetadataManagerTest, CanSelectNonEnglishCloseFitLocale) {
- // It's not "en-US" and is close to advertised metadata locale "es."
- NewManagerWithLocale("es-MX");
- // Known interaction: the manager will fetch the locales metadata.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/locales.json",
- R"({ "locales": [ "de", "en", "es", "wo" ] })");
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
- base::Unretained(this), loop.QuitClosure());
- auto call =
- base::BindOnce(&PpdMetadataManager::GetLocale,
- base::Unretained(manager_.get()), std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_TRUE(results_.get_locale_succeeded);
- EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq("es"));
- }
- // Verifies that the manager fails the GetLocaleCallback
- // * if it finds no close fit for the browser locale and
- // * if the serving root does not advertise availability of
- // English-localized metadata.
- TEST_F(PpdMetadataManagerTest, FailsToFindAnyCloseFitLocale) {
- // Sets an arbitrarily chosen locale quite distant from what the
- // fake serving root will have available.
- NewManagerWithLocale("ja-JP");
- // Known interaction: the manager will fetch the locales metadata.
- //
- // Note that we are canning well-formed JSON.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/locales.json", R"({ "locales": [ "de", "es", "wo" ] })");
- // Jams the result to the opposite of what's expected.
- results_.get_locale_succeeded = true;
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
- base::Unretained(this), loop.QuitClosure());
- auto call =
- base::BindOnce(&PpdMetadataManager::GetLocale,
- base::Unretained(manager_.get()), std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_FALSE(results_.get_locale_succeeded);
- EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq(""));
- }
- // Verifies that the manager fails the GetLocaleCallback if it fails to
- // fetch the locales metadata.
- TEST_F(PpdMetadataManagerTest, FailsToGetLocaleOnFetchFailure) {
- // This test deliberately doesn't can any response from the
- // FakePrinterConfigCache. We want to see what happens when the
- // manager fails to fetch the necessary networked resource.
- //
- // We do need some way to tell that GetLocale() failed, so we start
- // by jamming it to the opposite of the expected value.
- results_.get_locale_succeeded = true;
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
- base::Unretained(this), loop.QuitClosure());
- auto call =
- base::BindOnce(&PpdMetadataManager::GetLocale,
- base::Unretained(manager_.get()), std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_FALSE(results_.get_locale_succeeded);
- EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq(""));
- }
- // Verifies that the manager fails the GetLocaleCallback if it fails to
- // parse the locales metadata.
- TEST_F(PpdMetadataManagerTest, FailsToGetLocaleOnParseFailure) {
- // Known interaction: the manager will fetch the locales metadata.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/locales.json",
- kInvalidJson);
- // We've canned an unparsable response for the manager.
- // To observe that GetLocale() fails, we jam the result to the
- // opposite of the expected value.
- results_.get_locale_succeeded = true;
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
- base::Unretained(this), loop.QuitClosure());
- auto call =
- base::BindOnce(&PpdMetadataManager::GetLocale,
- base::Unretained(manager_.get()), std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_FALSE(results_.get_locale_succeeded);
- EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq(""));
- }
- // Verifies that the manager can fetch, parse, and return a list of
- // manufacturers from the Chrome OS Printing serving root.
- TEST_F(PpdMetadataManagerTest, CanGetManufacturers) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Known interaction: the manager will fetch manufacturers metadata
- // localized in English ("en").
- //
- // In real life, the values of the filesMap dictionary have a
- // hyphenated locale suffix attached; this is not something the
- // manager actually cares about and is not something used directly
- // in this test case.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/manufacturers-en.json",
- R"({ "filesMap": {
- "It": "Never_Ends-en.json",
- "You Are": "Always-en.json",
- "Playing": "Yellow_Car-en.json"
- } })");
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::GetManufacturers,
- base::Unretained(manager_.get()),
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_EQ(results_.get_manufacturers_code,
- PpdProvider::CallbackResultCode::SUCCESS);
- // PpdProvider::ResolveManufacturersCallback specifies that the list
- // shall be sorted.
- EXPECT_THAT(results_.manufacturers,
- ElementsAre(StrEq("It"), StrEq("Playing"), StrEq("You Are")));
- }
- // Verifies that the manager fails the ResolveManufacturersCallback
- // when it fails to fetch the manufacturers metadata.
- TEST_F(PpdMetadataManagerTest, FailsToGetManufacturersOnFetchFailure) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Known interaction: the manager will fetch manufacturers metadata
- // localized in English ("en"). In this test case, we do _not_
- // populate the fake config cache with the appropriate metadata,
- // causing the fetch to fail.
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::GetManufacturers,
- base::Unretained(manager_.get()),
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_EQ(results_.get_manufacturers_code,
- PpdProvider::CallbackResultCode::SERVER_ERROR);
- }
- // Verifies that the manager fails the ResolveManufacturersCallback
- // when it fails to parse the manufacturers metadata.
- TEST_F(PpdMetadataManagerTest, FailsToGetManufacturersOnParseFailure) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Known interaction: the manager will fetch manufacturers metadata
- // localized in English ("en").
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/manufacturers-en.json", kInvalidJson);
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::GetManufacturers,
- base::Unretained(manager_.get()),
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_EQ(results_.get_manufacturers_code,
- PpdProvider::CallbackResultCode::INTERNAL_ERROR);
- }
- // Verifies that the manager fetches manufacturers metadata anew when
- // caller asks it for metadata fresher than what it has cached.
- TEST_F(PpdMetadataManagerTest, CanGetManufacturersTimeSensitive) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Known interaction: the manager will fetch manufacturers metadata
- // localized in English ("en").
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/manufacturers-en.json",
- R"({ "filesMap": {
- "It": "Never_Ends-en.json",
- "You Are": "Always-en.json",
- "Playing": "Yellow_Car-en.json"
- } })");
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
- base::Unretained(this), loop.QuitClosure());
- // t = 0s: caller requests a list of manufacturers from |manager_|,
- // using metadata parsed within the last thirty seconds. |manager_|
- // performs a live fetch for the manufacturers metadata.
- manager_->GetManufacturers(base::Seconds(30), std::move(callback));
- loop.Run();
- ASSERT_EQ(results_.get_manufacturers_code,
- PpdProvider::CallbackResultCode::SUCCESS);
- // PpdProvider::ResolveManufacturersCallback specifies that the list
- // shall be sorted.
- EXPECT_THAT(results_.manufacturers,
- ElementsAre(StrEq("It"), StrEq("Playing"), StrEq("You Are")));
- // Mutates the test data, ensuring that if the metadata manager
- // attempts a live fetch from the PrinterConfigCache, it will get
- // different data in response.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/manufacturers-en.json",
- R"({ "filesMap": {
- "It": "Never_Ends-en.json",
- "You Are": "Always-en.json"
- } })");
- // Jams the result code to something bad to require that the
- // |manager_| positively answer us.
- results_.get_manufacturers_code =
- PpdProvider::CallbackResultCode::INTERNAL_ERROR;
- base::RunLoop second_loop;
- auto second_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
- base::Unretained(this), second_loop.QuitClosure());
- // t = 0s: caller requests a list of manufacturers from |manager_|.
- // |manager_| responds using the cached metadata without performing
- // a live fetch.
- manager_->GetManufacturers(base::Seconds(30), std::move(second_callback));
- second_loop.Run();
- // We assert that the results are unchanged from before.
- ASSERT_EQ(results_.get_manufacturers_code,
- PpdProvider::CallbackResultCode::SUCCESS);
- EXPECT_THAT(results_.manufacturers,
- ElementsAre(StrEq("It"), StrEq("Playing"), StrEq("You Are")));
- // t = 31s
- clock_.Advance(base::Seconds(31));
- // Jams the result code to something bad to require that the
- // |manager_| positively answer us.
- results_.get_manufacturers_code =
- PpdProvider::CallbackResultCode::INTERNAL_ERROR;
- base::RunLoop third_loop;
- auto third_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
- base::Unretained(this), third_loop.QuitClosure());
- // t = 31s: caller requests a list of manufacturers from |manager_|.
- // |manager_| does not have sufficiently fresh metadata, so it
- // performs a live fetch.
- manager_->GetManufacturers(base::Seconds(30), std::move(third_callback));
- third_loop.Run();
- // We assert that the results have changed.
- ASSERT_EQ(results_.get_manufacturers_code,
- PpdProvider::CallbackResultCode::SUCCESS);
- EXPECT_THAT(results_.manufacturers,
- ElementsAre(StrEq("It"), StrEq("You Are")));
- }
- // Verifies that the manager can fetch, parse, and return a map of
- // printers metadata from the Chrome OS Printing serving root.
- TEST_F(PpdMetadataManagerTest, CanGetPrinters) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Bypasses prerequisite call to PpdMetadataManager::GetManufacturers().
- ASSERT_TRUE(manager_->SetManufacturersForTesting(R"(
- {
- "filesMap": {
- "Manufacturer A": "Manufacturer_A-en.json",
- "Manufacturer B": "Manufacturer_B-en.json"
- }
- }
- )"));
- // Known interaction: the manager will fetch printers metadata named
- // by the manufacturers map above.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/Manufacturer_A-en.json", R"(
- {
- "printers": [ {
- "emm": "some emm a",
- "name": "Some Printer A"
- }, {
- "emm": "some emm b",
- "name": "Some Printer B"
- } ]
- }
- )");
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::GetPrinters,
- base::Unretained(manager_.get()), "Manufacturer A",
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_TRUE(results_.get_printers_succeeded);
- EXPECT_THAT(
- results_.printers,
- UnorderedElementsAre(ParsedPrinterLike("Some Printer A", "some emm a"),
- ParsedPrinterLike("Some Printer B", "some emm b")));
- }
- // Verifies that the manager fails the GetPrintersCallback when it fails
- // to fetch the printers metadata.
- TEST_F(PpdMetadataManagerTest, FailsToGetPrintersOnFetchFailure) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Bypasses prerequisite call to PpdMetadataManager::GetManufacturers().
- ASSERT_TRUE(manager_->SetManufacturersForTesting(R"(
- {
- "filesMap": {
- "Manufacturer A": "Manufacturer_A-en.json",
- "Manufacturer B": "Manufacturer_B-en.json"
- }
- }
- )"));
- // This test is set up like the CanGetPrinters test case above, but we
- // elect _not_ to provide a response for any printers metadata,
- // causing the fetch to fail.
- //
- // We set the result value to the opposite of what's expected to
- // observe the change.
- results_.get_printers_succeeded = true;
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::GetPrinters,
- base::Unretained(manager_.get()), "Manufacturer A",
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- EXPECT_FALSE(results_.get_printers_succeeded);
- }
- // Verifies that the manager fails the GetPrintersCallback when it fails
- // to parse the printers metadata.
- TEST_F(PpdMetadataManagerTest, FailsToGetPrintersOnParseFailure) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Bypasses prerequisite call to PpdMetadataManager::GetManufacturers().
- ASSERT_TRUE(manager_->SetManufacturersForTesting(R"(
- {
- "filesMap": {
- "Manufacturer A": "Manufacturer_A-en.json",
- "Manufacturer B": "Manufacturer_B-en.json"
- }
- }
- )"));
- // This test is set up like the CanGetPrinters test case above, but we
- // elect to provide a malformed JSON response for the printers
- // metadata, which will cause the manager to fail parsing.
- //
- // Known interaction: the manager will fetch the printers metadata
- // named by the map above.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/Manufacturer_A-en.json", kInvalidJson);
- // We set the result value to the opposite of what's expected to
- // observe the change.
- results_.get_printers_succeeded = true;
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::GetPrinters,
- base::Unretained(manager_.get()), "Manufacturer A",
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- EXPECT_FALSE(results_.get_printers_succeeded);
- }
- // Verifies that the manager fetches printers metadata anew when caller
- // asks it for metadata fresher than what it has cached.
- TEST_F(PpdMetadataManagerTest, CanGetPrintersTimeSensitive) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Bypasses prerequisite call to PpdMetadataManager::GetManufacturers().
- ASSERT_TRUE(manager_->SetManufacturersForTesting(R"(
- {
- "filesMap": {
- "Manufacturer A": "Manufacturer_A-en.json",
- "Manufacturer B": "Manufacturer_B-en.json"
- }
- }
- )"));
- // Known interaction: the manager will fetch printers metadata named
- // by the manufacturers map above.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/Manufacturer_A-en.json", R"(
- {
- "printers": [ {
- "emm": "some emm a",
- "name": "Some Printer A"
- }, {
- "emm": "some emm b",
- "name": "Some Printer B"
- } ]
- }
- )");
- // t = 0s: caller requests the printers for "Manufacturer A."
- // |manager_| parses and caches the metadata successfully.
- base::RunLoop loop;
- auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
- base::Unretained(this), loop.QuitClosure());
- manager_->GetPrinters("Manufacturer A", base::Seconds(30),
- std::move(callback));
- loop.Run();
- ASSERT_TRUE(results_.get_printers_succeeded);
- EXPECT_THAT(
- results_.printers,
- UnorderedElementsAre(ParsedPrinterLike("Some Printer A", "some emm a"),
- ParsedPrinterLike("Some Printer B", "some emm b")));
- // We change the data served by the PrinterConfigCache.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/Manufacturer_A-en.json", R"(
- {
- "printers": [ {
- "emm": "some emm c",
- "name": "Some Printer C"
- }, {
- "emm": "some emm d",
- "name": "Some Printer D"
- } ]
- }
- )");
- // Jams the results to some bad value, requiring that the manager
- // answer us positively.
- results_.get_printers_succeeded = false;
- base::RunLoop second_loop;
- auto second_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
- base::Unretained(this), second_loop.QuitClosure());
- // t = 0s: caller requests the printers for "Manufacturer A."
- // |manager_| re-uses the cached metadata.
- manager_->GetPrinters("Manufacturer A", base::Seconds(30),
- std::move(second_callback));
- second_loop.Run();
- // We assert that the results are unchanged from before.
- ASSERT_TRUE(results_.get_printers_succeeded);
- EXPECT_THAT(
- results_.printers,
- UnorderedElementsAre(ParsedPrinterLike("Some Printer A", "some emm a"),
- ParsedPrinterLike("Some Printer B", "some emm b")));
- // t = 31s
- clock_.Advance(base::Seconds(31));
- // Jams the results to some bad value, requiring that the manager
- // answer us positively.
- results_.get_printers_succeeded = false;
- // t = 31s: caller requests the printers for "Manufacturer A."
- // |manager_| does not have sufficiently fresh metadata, so it
- // performs a live fetch.
- base::RunLoop third_loop;
- auto third_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
- base::Unretained(this), third_loop.QuitClosure());
- manager_->GetPrinters("Manufacturer A", base::Seconds(30),
- std::move(third_callback));
- third_loop.Run();
- // We assert that the results have changed.
- ASSERT_TRUE(results_.get_printers_succeeded);
- EXPECT_THAT(
- results_.printers,
- UnorderedElementsAre(ParsedPrinterLike("Some Printer C", "some emm c"),
- ParsedPrinterLike("Some Printer D", "some emm d")));
- }
- // Verifies that the manager can find all effective-make-and-model
- // strings in forward index metadata.
- TEST_F(PpdMetadataManagerTest, CanFindAllAvailableEmmsInIndex) {
- // Known interaction: the manager will fetch forward index metadata
- // numbered 14, 15, and 16.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json", R"(
- {
- "ppdIndex": {
- "some printer a": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-a.ppd.gz"
- } ]
- }
- }
- })");
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
- {
- "ppdIndex": {
- "some printer b": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-b.ppd.gz"
- } ]
- }
- }
- })");
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
- {
- "ppdIndex": {
- "some printer c": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-c.ppd.gz"
- } ]
- }
- }
- })");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
- base::Unretained(this), loop.QuitClosure());
- manager_->FindAllEmmsAvailableInIndex(
- {"some printer a", "some printer b", "some printer c"},
- kArbitraryTimeDelta, std::move(callback));
- loop.Run();
- EXPECT_THAT(results_.available_effective_make_and_model_strings,
- UnorderedElementsAre(
- ParsedIndexEntryLike(
- "some printer a",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-a.ppd.gz"))),
- ParsedIndexEntryLike(
- "some printer b",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-b.ppd.gz"))),
- ParsedIndexEntryLike(
- "some printer c",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-c.ppd.gz")))));
- }
- // Verifies that the manager invokes the
- // FindAllAvailableEmmsInIndexCallback with a partially filled argument
- // if it fails to fetch some of the necessary metadata.
- TEST_F(PpdMetadataManagerTest,
- CanPartiallyFindAllAvailableEmmsInIndexWithFetchFailure) {
- // Known interaction: the manager will fetch forward index metadata
- // numbered 14, 15, and 16.
- //
- // We deliberately omit forward index metadata no. 14 to simulate a
- // fetch failure.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
- {
- "ppdIndex": {
- "some printer b": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-b.ppd.gz"
- } ]
- }
- }
- })");
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
- {
- "ppdIndex": {
- "some printer c": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-c.ppd.gz"
- } ]
- }
- }
- })");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
- base::Unretained(this), loop.QuitClosure());
- manager_->FindAllEmmsAvailableInIndex(
- {"some printer a", "some printer b", "some printer c"},
- kArbitraryTimeDelta, std::move(callback));
- loop.Run();
- // The manager was unable to get the forward index metadata that would
- // contain information for effective-make-and-model string
- // "some printer a," but the other results should avail themselves.
- EXPECT_THAT(results_.available_effective_make_and_model_strings,
- UnorderedElementsAre(
- ParsedIndexEntryLike(
- "some printer b",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-b.ppd.gz"))),
- ParsedIndexEntryLike(
- "some printer c",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-c.ppd.gz")))));
- }
- // Verifies that the manager invokes the
- // FindAllAvailableEmmsInIndexCallback with a partially filled argument
- // if it fails to parse some of the necessary metadata.
- TEST_F(PpdMetadataManagerTest,
- CanPartiallyFindAllAvailableEmmsInIndexWithParseFailure) {
- // Known interaction: the manager will fetch forward index metadata
- // numbered 14, 15, and 16.
- //
- // We deliberately serve malformed JSON that will fail to parse for
- // indices nos. 14 and 15 to exercise the manager's handling of parse
- // failures.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json",
- kInvalidJson);
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json",
- kInvalidJson);
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
- {
- "ppdIndex": {
- "some printer c": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-c.ppd.gz"
- } ]
- }
- }
- })");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
- base::Unretained(this), loop.QuitClosure());
- manager_->FindAllEmmsAvailableInIndex(
- {"some printer a", "some printer b", "some printer c"},
- kArbitraryTimeDelta, std::move(callback));
- loop.Run();
- // The manager was unable to parse the forward index metadata that would
- // contain information for effective-make-and-model strings
- // "some printer a" and for "some printer b," but the last string
- // "some printer c" should avail itself.
- EXPECT_THAT(
- results_.available_effective_make_and_model_strings,
- UnorderedElementsAre(ParsedIndexEntryLike(
- "some printer c", UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-c.ppd.gz")))));
- }
- // Verifies that the manager fetches forward index metadata anew when
- // the caller asks it for metadata fresher than what it has cached.
- TEST_F(PpdMetadataManagerTest, CanFindAllAvailableEmmsInIndexTimeSensitive) {
- // Known interaction: the manager will fetch forward index metadata
- // numbered 14, 15, and 16.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json", R"(
- {
- "ppdIndex": {
- "some printer a": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-a.ppd.gz"
- } ]
- }
- }
- })");
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
- {
- "ppdIndex": {
- "some printer b": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-b.ppd.gz"
- } ]
- }
- }
- })");
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
- {
- "ppdIndex": {
- "some printer c": {
- "ppdMetadata": [ {
- "name": "some-ppd-basename-c.ppd.gz"
- } ]
- }
- }
- })");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
- base::Unretained(this), loop.QuitClosure());
- // t = 0s: caller requests the |manager_| to search forward index
- // metadata for three effective-make-and-model strings. |manager_|
- // fetches the appropriate forward index metadata (nos. 14, 15, and
- // 16) and caches the result.
- manager_->FindAllEmmsAvailableInIndex(
- {"some printer a", "some printer b", "some printer c"}, base::Seconds(30),
- std::move(callback));
- loop.Run();
- EXPECT_THAT(results_.available_effective_make_and_model_strings,
- UnorderedElementsAre(
- ParsedIndexEntryLike(
- "some printer a",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-a.ppd.gz"))),
- ParsedIndexEntryLike(
- "some printer b",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-b.ppd.gz"))),
- ParsedIndexEntryLike(
- "some printer c",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-c.ppd.gz")))));
- // We drop forward index metadata nos. 14 and 15 now. If the
- // |manager_| attempts to fetch these again, it will fail to do so.
- GetFakeCache()->Drop("metadata_v3/index-14.json");
- GetFakeCache()->Drop("metadata_v3/index-15.json");
- // Resets the results to require that the |manager_| answer us
- // positively.
- results_.available_effective_make_and_model_strings = {};
- base::RunLoop second_loop;
- auto second_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
- base::Unretained(this), second_loop.QuitClosure());
- // t = 0s: caller requests the |manager_| to search forward index
- // metadata for the same three effective-make-and-model strings.
- // Caller requests this using metadata fetched within the last thirty
- // seconds, so |manager_| does not perform a live fetch of the data.
- manager_->FindAllEmmsAvailableInIndex(
- {"some printer a", "some printer b", "some printer c"}, base::Seconds(30),
- std::move(second_callback));
- second_loop.Run();
- // We expect the results to be unchanged.
- EXPECT_THAT(results_.available_effective_make_and_model_strings,
- UnorderedElementsAre(
- ParsedIndexEntryLike(
- "some printer a",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-a.ppd.gz"))),
- ParsedIndexEntryLike(
- "some printer b",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-b.ppd.gz"))),
- ParsedIndexEntryLike(
- "some printer c",
- UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-c.ppd.gz")))));
- // t = 31s
- clock_.Advance(base::Seconds(31));
- base::RunLoop third_loop;
- auto third_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
- base::Unretained(this), third_loop.QuitClosure());
- // t = 31s: caller requests the |manager_| to search forward index
- // metadata for the same three effective-make-and-model strings.
- // Caller requests this using metadata fetched within the last thirty
- // thirds; |manager_| sees that its cached metadata is too old, and
- // so performs a live fetch.
- //
- // Since we previously blocked forward index metadata nos. 14 and 15
- // from being served, the |manager_| will fail to fetch these.
- manager_->FindAllEmmsAvailableInIndex(
- {"some printer a", "some printer b", "some printer c"}, base::Seconds(30),
- std::move(third_callback));
- third_loop.Run();
- // We expect the results to have changed.
- EXPECT_THAT(
- results_.available_effective_make_and_model_strings,
- UnorderedElementsAre(ParsedIndexEntryLike(
- "some printer c", UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
- "some-ppd-basename-c.ppd.gz")))));
- }
- // Verifies that the manager can find a USB device by fetching and
- // parsing USB index metadata.
- TEST_F(PpdMetadataManagerTest, CanFindDeviceInUsbIndex) {
- // Known interaction: hex(1138) == 0x472. To fetch USB index metadata
- // for a manufacturer with vendor ID 1138, the manager will fetch
- // the metadata with the following name.
- //
- // This USB index describes one product for vendor ID 1138; its
- // product ID is 13.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb-0472.json", R"({
- "usbIndex": {
- "13": {
- "effectiveMakeAndModel": "some printer a"
- }
- }
- })");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
- base::Unretained(this), loop.QuitClosure());
- manager_->FindDeviceInUsbIndex(1138, 13, kArbitraryTimeDelta,
- std::move(callback));
- loop.Run();
- EXPECT_THAT(results_.effective_make_and_model_string_from_usb_index,
- StrEq("some printer a"));
- }
- // Verifies that the manager invokes the FindDeviceInUsbIndexCallback
- // with an empty argument if it fails to fetch the appropriate USB
- // index.
- TEST_F(PpdMetadataManagerTest, FailsToFindDeviceInUsbIndexOnFetchFailure) {
- // Known interaction: hex(1138) == 0x472. To fetch USB index metadata
- // for a manufacturer with vendor ID 1138, the manager will fetch
- // the metadata with the following name.
- //
- // We populate nothing in the fake serving root, so any fetch request
- // from the manager will fail.
- // Jams the landing area to have a non-empty string. We expect the
- // callback to fire with an empty string, which should empty this.
- results_.effective_make_and_model_string_from_usb_index =
- "non-empty string that will fail this test if it persists";
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
- base::Unretained(this), loop.QuitClosure());
- manager_->FindDeviceInUsbIndex(1138, 13, kArbitraryTimeDelta,
- std::move(callback));
- loop.Run();
- EXPECT_TRUE(results_.effective_make_and_model_string_from_usb_index.empty());
- }
- // Verifies that the manager invokes the FindDeviceInUsbIndexCallback
- // with an empty argument if it fails to parse the appropriate USB
- // index.
- TEST_F(PpdMetadataManagerTest, FailsToFindDeviceInUsbIndexOnParseFailure) {
- // Known interaction: hex(1138) == 0x472. To fetch USB index metadata
- // for a manufacturer with vendor ID 1138, the manager will fetch
- // the metadata with the following name.
- //
- // We populate the fake serving root with invalid JSON for the USB
- // index metadata that the manager will fetch and fail to parse.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb-0472.json",
- kInvalidJson);
- // Jams the landing area to have a non-empty string. We expect the
- // callback to fire with an empty string, which should empty this.
- results_.effective_make_and_model_string_from_usb_index =
- "non-empty string that will fail this test if it persists";
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
- base::Unretained(this), loop.QuitClosure());
- manager_->FindDeviceInUsbIndex(1138, 13, kArbitraryTimeDelta,
- std::move(callback));
- loop.Run();
- EXPECT_TRUE(results_.effective_make_and_model_string_from_usb_index.empty());
- }
- // Verifies that the manager fetches USB index metadata anew when caller
- // asks it for metadata fresher than what it has cached.
- TEST_F(PpdMetadataManagerTest, CanFindDeviceInUsbIndexTimeSensitive) {
- // Known interaction: hex(1138) == 0x472. To fetch USB index metadata
- // for a manufacturer with vendor ID 1138, the manager will fetch
- // the metadata with the following name.
- //
- // This USB index describes one product for vendor ID 1138; its
- // product ID is 13.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb-0472.json", R"({
- "usbIndex": {
- "13": {
- "effectiveMakeAndModel": "some printer a"
- }
- }
- })");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
- base::Unretained(this), loop.QuitClosure());
- // t = 0s: caller requests |manager_| to name a device with vendor ID
- // 1138 and product ID 13. |manager_| fetches, parses, and caches
- // the appropriate USB index metadata.
- manager_->FindDeviceInUsbIndex(1138, 13, kArbitraryTimeDelta,
- std::move(callback));
- loop.Run();
- EXPECT_THAT(results_.effective_make_and_model_string_from_usb_index,
- StrEq("some printer a"));
- // Sets the serving root to mutate the served USB index metadata; the
- // device with product ID 13 now has the effective-make-and-model
- // string "some printer b." If the |manager_| fetches this metadata
- // anew, then it will observe the changed effective-make-and-model
- // string.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb-0472.json", R"({
- "usbIndex": {
- "13": {
- "effectiveMakeAndModel": "some printer b"
- }
- }
- })");
- // Jams the landing area to hold a test-failing string. We expect
- // the successful callback to overwrite this.
- results_.effective_make_and_model_string_from_usb_index =
- "non-empty string that will fail this test if it persists";
- base::RunLoop second_loop;
- auto second_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
- base::Unretained(this), second_loop.QuitClosure());
- // t = 0s: caller requests |manager_| to name a device with vendor ID
- // 1138 and product ID 13. It asks that |manager_| do so with metadata
- // parsed within the last 30 seconds. |manager_| responds with the
- // cached USB index metadata without incurring a live fetch.
- manager_->FindDeviceInUsbIndex(1138, 13, base::Seconds(30),
- std::move(second_callback));
- second_loop.Run();
- // The manager will have responded with the cached
- // effective-make-and-model string "some printer a."
- EXPECT_THAT(results_.effective_make_and_model_string_from_usb_index,
- StrEq("some printer a"));
- // t = 31s
- clock_.Advance(base::Seconds(31));
- // Jams the landing area to hold a test-failing string. We expect
- // the successful callback to overwrite this.
- results_.effective_make_and_model_string_from_usb_index =
- "non-empty string that will fail this test if it persists";
- base::RunLoop third_loop;
- auto third_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
- base::Unretained(this), third_loop.QuitClosure());
- // t = 31s: caller requests |manager_| to name a device with vendor ID
- // 1138 and product ID 13. It asks that |manager_| do so with metadata
- // parsed within the last 30 seconds. |manager_| sees that the cached
- // USB index metadata is too stale, and so incurs a live fetch. The
- // fetch exposes the changed metadata.
- manager_->FindDeviceInUsbIndex(1138, 13, base::Seconds(30),
- std::move(third_callback));
- third_loop.Run();
- // The manager will have responded with the new and changed
- // effective-make-and-model string "some printer b."
- EXPECT_THAT(results_.effective_make_and_model_string_from_usb_index,
- StrEq("some printer b"));
- }
- // Verifies that the manager can determine a USB manufacturer name
- // by fetching and searching the USB vendor ID map.
- TEST_F(PpdMetadataManagerTest, CanGetUsbManufacturerName) {
- // Known interaction: |manager_| shall fetch the USB vendor ID map.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb_vendor_ids.json",
- R"({
- "entries": [ {
- "vendorId": 1138,
- "vendorName": "Some Vendor Name"
- } ]
- })");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
- base::Unretained(this), loop.QuitClosure());
- manager_->GetUsbManufacturerName(1138, kArbitraryTimeDelta,
- std::move(callback));
- loop.Run();
- EXPECT_THAT(results_.usb_manufacturer_name, StrEq("Some Vendor Name"));
- }
- // Verifies that the manager invokes the GetUsbManufacturerNameCallback
- // with an empty argument if it fails to fetch the USB vendor ID map.
- TEST_F(PpdMetadataManagerTest, FailsToGetUsbManufacturerNameOnFetchFailure) {
- // Known interaction: |manager_| shall fetch the USB vendor ID map.
- //
- // We deliberately don't set any fetch response in the fake serving
- // root; |manager_| will fail to fetch the USB vendor ID map. However,
- // we do jam the landing area with a sentinel value to ensure that the
- // callback does fire with an empty string.
- results_.usb_manufacturer_name =
- "non-empty string that will fail this test if it persists";
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
- base::Unretained(this), loop.QuitClosure());
- manager_->GetUsbManufacturerName(1138, kArbitraryTimeDelta,
- std::move(callback));
- loop.Run();
- EXPECT_TRUE(results_.usb_manufacturer_name.empty());
- }
- // Verifies that the manager invokes the GetUsbManufacturerNameCallback
- // with an empty argument if it fails to parse the USB vendor ID map.
- TEST_F(PpdMetadataManagerTest, FailsToGetUsbManufacturerNameOnParseFailure) {
- // Known interaction: |manager_| shall fetch the USB vendor ID map.
- //
- // We deliberately set a malformed response in the serving root;
- // |manager_| will fetch the USB vendor ID map successfully, but will
- // fail to parse it.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb_vendor_ids.json",
- kInvalidJson);
- // We also jam the landing area with a sentinel value to ensure that
- // the callback fires with an empty string.
- results_.usb_manufacturer_name =
- "non-empty string that will fail this test if it persists";
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
- base::Unretained(this), loop.QuitClosure());
- manager_->GetUsbManufacturerName(1138, kArbitraryTimeDelta,
- std::move(callback));
- loop.Run();
- EXPECT_TRUE(results_.usb_manufacturer_name.empty());
- }
- // Verifies that the manager fetches the USB vendor ID map anew if the
- // caller calls GetUsbManufacturerName() asking for metadata fresher
- // than what it has cached.
- TEST_F(PpdMetadataManagerTest, CanGetUsbManufacturerNameTimeSensitive) {
- // Known interaction: |manager_| shall fetch the USB vendor ID map.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb_vendor_ids.json",
- R"({
- "entries": [ {
- "vendorId": 1138,
- "vendorName": "Vendor One One Three Eight"
- } ]
- })");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
- base::Unretained(this), loop.QuitClosure());
- // t = 0s: caller requests the name of a USB manufacturer whose vendor
- // ID is 1138. |manager_| fetches, parses, and caches the USB vendor
- // ID map, responding with the name.
- manager_->GetUsbManufacturerName(1138, base::Seconds(30),
- std::move(callback));
- loop.Run();
- EXPECT_THAT(results_.usb_manufacturer_name,
- StrEq("Vendor One One Three Eight"));
- // Mutates the USB vendor ID map served by the fake serving root.
- // If the |manager_| fetches it now, it will see a changed name for
- // the USB manufacturer with vendor ID 1138.
- GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb_vendor_ids.json",
- R"({
- "entries": [ {
- "vendorId": 1138,
- "vendorName": "One One Three Eight LLC"
- } ]
- })");
- base::RunLoop second_loop;
- auto second_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
- base::Unretained(this), second_loop.QuitClosure());
- // t = 0s: caller requests the name of a USB manufacturer whose vendor
- // ID is 1138. |manager_| responds with the previously fetched
- // metadata.
- manager_->GetUsbManufacturerName(1138, base::Seconds(30),
- std::move(second_callback));
- second_loop.Run();
- // Since |manager_| has not fetched the mutated USB vendor ID map,
- // the results are unchanged from before.
- EXPECT_THAT(results_.usb_manufacturer_name,
- StrEq("Vendor One One Three Eight"));
- // t = 31s
- clock_.Advance(base::Seconds(31));
- base::RunLoop third_loop;
- auto third_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
- base::Unretained(this), third_loop.QuitClosure());
- // t = 31s: caller requests the name of a USB manufacturer whose
- // vendor ID is 1138. |manager_| notices that its cached metadata is
- // too stale and performs a live fetch, receiving the mutated
- // USB vendor ID map.
- manager_->GetUsbManufacturerName(1138, base::Seconds(30),
- std::move(third_callback));
- third_loop.Run();
- // Since |manager_| has not fetched the mutated USB vendor ID map,
- // the results are unchanged from before.
- EXPECT_THAT(results_.usb_manufacturer_name, StrEq("One One Three Eight LLC"));
- }
- // Verifies that the manager can split an effective-make-and-model
- // string into its constituent parts (make and model).
- TEST_F(PpdMetadataManagerTest, CanSplitMakeAndModel) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Known interaction: asking the manager to split the string
- // "Hello there!" will cause it to fetch the reverse index metadata
- // with shard number 2.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/reverse_index-en-02.json", R"(
- {
- "reverseIndex": {
- "Hello there!": {
- "manufacturer": "General",
- "model": "Kenobi"
- }
- }
- }
- )");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::SplitMakeAndModel,
- base::Unretained(manager_.get()), "Hello there!",
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_EQ(results_.split_make_and_model_code,
- PpdProvider::CallbackResultCode::SUCCESS);
- EXPECT_THAT(results_.split_make, StrEq("General"));
- EXPECT_THAT(results_.split_model, StrEq("Kenobi"));
- }
- // Verifies that the manager fails the ReverseLookupCallback when it
- // fails to fetch the necessary metadata from the Chrome OS Printing
- // serving root.
- TEST_F(PpdMetadataManagerTest, FailsToSplitMakeAndModelOnFetchFailure) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Known interaction: asking the manager to split the string
- // "Hello there!" will cause it to fetch the reverse index metadata
- // with shard number 2.
- //
- // We elect _not_ to fake a value for this s.t. the fetch will fail.
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::SplitMakeAndModel,
- base::Unretained(manager_.get()), "Hello there!",
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- EXPECT_EQ(results_.split_make_and_model_code,
- PpdProvider::CallbackResultCode::SERVER_ERROR);
- }
- // Verifies that the manager fails the ReverseLookupCallback when it
- // fails to parse the necessary metadata from the Chrome OS Printing
- // serving root.
- TEST_F(PpdMetadataManagerTest, FailsToSplitMakeAndModelOnParseFailure) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Known interaction: asking the manager to split the string
- // "Hello there!" will cause it to fetch the reverse index metadata
- // with shard number 2.
- //
- // We fake a fetch value that is invalid JSON s.t. the manager
- // will fail to parse it.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/reverse_index-en-02.json", kInvalidJson);
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
- base::Unretained(this), loop.QuitClosure());
- auto call = base::BindOnce(&PpdMetadataManager::SplitMakeAndModel,
- base::Unretained(manager_.get()), "Hello there!",
- kArbitraryTimeDelta, std::move(callback));
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
- loop.Run();
- ASSERT_EQ(results_.split_make_and_model_code,
- PpdProvider::CallbackResultCode::INTERNAL_ERROR);
- }
- // Verifies that the manager fetches reverse index metadata anew when
- // caller asks it for metadata fresher than what it has cached.
- TEST_F(PpdMetadataManagerTest, CanSplitMakeAndModelTimeSensitive) {
- // Bypasses mandatory call to PpdMetadataManager::GetLocale().
- manager_->SetLocaleForTesting("en");
- // Known interaction: asking the manager to split the string
- // "Hello there!" will cause it to fetch the reverse index metadata
- // with shard number 2.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/reverse_index-en-02.json", R"(
- {
- "reverseIndex": {
- "Hello there!": {
- "manufacturer": "General",
- "model": "Kenobi"
- }
- }
- }
- )");
- base::RunLoop loop;
- auto callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
- base::Unretained(this), loop.QuitClosure());
- // t = 0s: caller requests that |manager_| split the
- // effective-make-and-model string "Hello there!" using metadata
- // parsed within the last thirty seconds. |manager_| fetches the
- // appropriate reverse index metadata.
- manager_->SplitMakeAndModel("Hello there!", base::Seconds(30),
- std::move(callback));
- loop.Run();
- ASSERT_EQ(results_.split_make_and_model_code,
- PpdProvider::CallbackResultCode::SUCCESS);
- EXPECT_THAT(results_.split_make, StrEq("General"));
- EXPECT_THAT(results_.split_model, StrEq("Kenobi"));
- // Mutates the reverse index metadata we serve.
- GetFakeCache()->SetFetchResponseForTesting(
- "metadata_v3/reverse_index-en-02.json", R"(
- {
- "reverseIndex": {
- "Hello there!": {
- "manufacturer": "You are",
- "model": "a bold one!"
- }
- }
- }
- )");
- // Jams the result to a bad value, requiring that the |manager_|
- // answer us positively.
- results_.split_make_and_model_code =
- PpdProvider::CallbackResultCode::INTERNAL_ERROR;
- base::RunLoop second_loop;
- auto second_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
- base::Unretained(this), second_loop.QuitClosure());
- // t = 0s: caller requests that |manager_| split the
- // effective-make-and-model string "Hello there!"
- // |manager_| re-uses the cached reverse index metadata.
- manager_->SplitMakeAndModel("Hello there!", base::Seconds(30),
- std::move(second_callback));
- second_loop.Run();
- // We assert that the results are currently unchanged.
- ASSERT_EQ(results_.split_make_and_model_code,
- PpdProvider::CallbackResultCode::SUCCESS);
- EXPECT_THAT(results_.split_make, StrEq("General"));
- EXPECT_THAT(results_.split_model, StrEq("Kenobi"));
- // t = 31s
- clock_.Advance(base::Seconds(31));
- // Jams the result to a bad value, requiring that the |manager_|
- // answer us positively.
- results_.split_make_and_model_code =
- PpdProvider::CallbackResultCode::INTERNAL_ERROR;
- base::RunLoop third_loop;
- auto third_callback =
- base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
- base::Unretained(this), third_loop.QuitClosure());
- // t = 31s: caller requests that |manager_| split the
- // effective-make-and-model string "Hello there!"
- // |manager_| doesn't have sufficiently fresh metadata, so it performs
- // a live fetch.
- manager_->SplitMakeAndModel("Hello there!", base::Seconds(30),
- std::move(third_callback));
- third_loop.Run();
- // We assert that the live fetch changed the results.
- ASSERT_EQ(results_.split_make_and_model_code,
- PpdProvider::CallbackResultCode::SUCCESS);
- EXPECT_THAT(results_.split_make, StrEq("You are"));
- EXPECT_THAT(results_.split_model, StrEq("a bold one!"));
- }
- } // namespace
- } // namespace chromeos
|