ppd_metadata_manager_unittest.cc 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include "chromeos/printing/ppd_metadata_manager.h"
  9. #include "base/bind.h"
  10. #include "base/containers/flat_map.h"
  11. #include "base/run_loop.h"
  12. #include "base/test/simple_test_clock.h"
  13. #include "base/test/task_environment.h"
  14. #include "base/threading/sequenced_task_runner_handle.h"
  15. #include "base/time/clock.h"
  16. #include "chromeos/printing/fake_printer_config_cache.h"
  17. #include "chromeos/printing/ppd_metadata_matchers.h"
  18. #include "chromeos/printing/ppd_metadata_parser.h"
  19. #include "chromeos/printing/ppd_provider.h"
  20. #include "chromeos/printing/printer_config_cache.h"
  21. #include "testing/gmock/include/gmock/gmock-matchers.h"
  22. #include "testing/gtest/include/gtest/gtest.h"
  23. namespace chromeos {
  24. namespace {
  25. using ::testing::ElementsAre;
  26. using ::testing::Pair;
  27. using ::testing::StrEq;
  28. using ::testing::UnorderedElementsAre;
  29. // Default browser locale used to construct PpdMetadataManager instances
  30. // in the test fixture. Arbitrarily chosen. Changeable by calling
  31. // PpdMetadataManagerTest::NewManagerWithLocale().
  32. constexpr base::StringPiece kBrowserLocaleForTesting = "en-US";
  33. // Arbitrarily chosen TimeDelta used in test cases that are not
  34. // time-senstive.
  35. constexpr base::TimeDelta kArbitraryTimeDelta = base::Seconds(30LL);
  36. // Arbitrarily malformed JSON used to exercise code paths in which
  37. // parsing fails.
  38. constexpr base::StringPiece kInvalidJson = "blah blah invalid JSON";
  39. // Caller may bind a default-constructed base::RepeatingClosure to
  40. // any Catch*() method, indicating that they don't want anything run.
  41. class PpdMetadataManagerTest : public ::testing::Test {
  42. public:
  43. // Callback method appropriate for passing to
  44. // PpdMetadataManager::GetLocale().
  45. void CatchGetLocale(base::RepeatingClosure quit_closure, bool succeeded) {
  46. results_.get_locale_succeeded = succeeded;
  47. if (quit_closure) {
  48. quit_closure.Run();
  49. }
  50. }
  51. // Callback method appropriate for passing to
  52. // PpdMetadataManager::GetManufacturers().
  53. void CatchGetManufacturers(base::RepeatingClosure quit_closure,
  54. PpdProvider::CallbackResultCode code,
  55. const std::vector<std::string>& manufacturers) {
  56. results_.get_manufacturers_code = code;
  57. results_.manufacturers = manufacturers;
  58. if (quit_closure) {
  59. quit_closure.Run();
  60. }
  61. }
  62. // Callback method appropriate for passing to
  63. // PpdMetadataManager::GetPrinters().
  64. void CatchGetPrinters(base::RepeatingClosure quit_closure,
  65. bool succeeded,
  66. const ParsedPrinters& printers) {
  67. results_.get_printers_succeeded = succeeded;
  68. results_.printers = printers;
  69. if (quit_closure) {
  70. quit_closure.Run();
  71. }
  72. }
  73. // Callback method appropriate for passing to
  74. // PpdMetadataManager::FindAllEmmsAvailableInIndex().
  75. void CatchFindAllEmmsAvailableInIndex(
  76. base::RepeatingClosure quit_closure,
  77. const base::flat_map<std::string, ParsedIndexValues>& values) {
  78. results_.available_effective_make_and_model_strings = values;
  79. if (quit_closure) {
  80. quit_closure.Run();
  81. }
  82. }
  83. // Callback method appropriate for passing to
  84. // PpdMetadataManager::FindDeviceInUsbIndex().
  85. void CatchFindDeviceInUsbIndex(base::RepeatingClosure quit_closure,
  86. const std::string& value) {
  87. results_.effective_make_and_model_string_from_usb_index = value;
  88. if (quit_closure) {
  89. quit_closure.Run();
  90. }
  91. }
  92. // Callback method appropriate for passing to
  93. // PpdMetadataManager::GetUsbManufacturerName().
  94. void CatchGetUsbManufacturerName(base::RepeatingClosure quit_closure,
  95. const std::string& value) {
  96. results_.usb_manufacturer_name = value;
  97. if (quit_closure) {
  98. quit_closure.Run();
  99. }
  100. }
  101. // Callback method appropriate for passing to
  102. // PpdMetadataManager::SplitMakeAndModel().
  103. void CatchSplitMakeAndModel(base::RepeatingClosure quit_closure,
  104. PpdProvider::CallbackResultCode code,
  105. const std::string& make,
  106. const std::string& model) {
  107. results_.split_make_and_model_code = code;
  108. results_.split_make = make;
  109. results_.split_model = model;
  110. if (quit_closure) {
  111. quit_closure.Run();
  112. }
  113. }
  114. protected:
  115. // Convenience container that organizes all callback results.
  116. struct CallbackLandingArea {
  117. CallbackLandingArea()
  118. : get_locale_succeeded(false), get_printers_succeeded(false) {}
  119. ~CallbackLandingArea() = default;
  120. // Landing area for PpdMetadataManager::GetLocale().
  121. bool get_locale_succeeded;
  122. // Landing area for PpdMetadataManager::GetManufacturers().
  123. PpdProvider::CallbackResultCode get_manufacturers_code;
  124. std::vector<std::string> manufacturers;
  125. // Landing area for PpdMetadataManager::GetPrinters().
  126. bool get_printers_succeeded;
  127. ParsedPrinters printers;
  128. // Landing area for
  129. // PpdMetadataManager::FindAllEmmsAvailableInIndex().
  130. base::flat_map<std::string, ParsedIndexValues>
  131. available_effective_make_and_model_strings;
  132. // Landing area for
  133. // PpdMetadataManager::FindDeviceInUsbIndex().
  134. std::string effective_make_and_model_string_from_usb_index;
  135. // Landing area for
  136. // PpdMetadataManager::GetUsbManufacturerName().
  137. std::string usb_manufacturer_name;
  138. // Landing area for PpdMetadataManager::SplitMakeAndModel().
  139. PpdProvider::CallbackResultCode split_make_and_model_code;
  140. std::string split_make;
  141. std::string split_model;
  142. };
  143. PpdMetadataManagerTest()
  144. : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
  145. manager_(PpdMetadataManager::Create(
  146. kBrowserLocaleForTesting,
  147. &clock_,
  148. std::make_unique<FakePrinterConfigCache>())) {}
  149. // Borrows and returns a pointer to the config cache owned by the
  150. // |manager_|.
  151. //
  152. // Useful for adjusting availability of (fake) network resources.
  153. FakePrinterConfigCache* GetFakeCache() {
  154. return reinterpret_cast<FakePrinterConfigCache*>(
  155. manager_->GetPrinterConfigCacheForTesting());
  156. }
  157. // Recreates |manager_| with a new |browser_locale|.
  158. //
  159. // Useful for testing the manager's ability to parse and select a
  160. // proper metadata locale.
  161. void NewManagerWithLocale(base::StringPiece browser_locale) {
  162. manager_.reset();
  163. manager_ = PpdMetadataManager::Create(
  164. browser_locale, &clock_, std::make_unique<FakePrinterConfigCache>());
  165. }
  166. // Holder for all callback results.
  167. CallbackLandingArea results_;
  168. // Environment for task schedulers.
  169. base::test::TaskEnvironment task_environment_;
  170. // Controlled clock that dispenses times of Fetch().
  171. base::SimpleTestClock clock_;
  172. // Class under test.
  173. std::unique_ptr<PpdMetadataManager> manager_;
  174. };
  175. // Verifies that the manager can fetch and parse the best-fit
  176. // locale from the Chrome OS Printing serving root.
  177. //
  178. // This test is done against the default browser locale used
  179. // throughout this suite, "en-US."
  180. TEST_F(PpdMetadataManagerTest, CanGetLocale) {
  181. // Known interaction: the manager will fetch the locales metadata.
  182. GetFakeCache()->SetFetchResponseForTesting(
  183. "metadata_v3/locales.json", R"({ "locales": [ "de", "en", "es" ] })");
  184. base::RunLoop loop;
  185. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
  186. base::Unretained(this), loop.QuitClosure());
  187. auto call =
  188. base::BindOnce(&PpdMetadataManager::GetLocale,
  189. base::Unretained(manager_.get()), std::move(callback));
  190. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  191. loop.Run();
  192. ASSERT_TRUE(results_.get_locale_succeeded);
  193. EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq("en"));
  194. }
  195. // Verifies that the manager defaults to the English ("en") locale
  196. // when it can find no closer fit for the browser locale.
  197. TEST_F(PpdMetadataManagerTest, DefaultsToEnglishLocale) {
  198. // Sets an arbitrarily chosen locale quite distant from what the
  199. // fake serving root will have available.
  200. NewManagerWithLocale("ja-JP");
  201. // Known interaction: the manager will fetch the locales metadata.
  202. GetFakeCache()->SetFetchResponseForTesting(
  203. "metadata_v3/locales.json",
  204. R"({ "locales": [ "de", "en", "es", "wo" ] })");
  205. base::RunLoop loop;
  206. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
  207. base::Unretained(this), loop.QuitClosure());
  208. auto call =
  209. base::BindOnce(&PpdMetadataManager::GetLocale,
  210. base::Unretained(manager_.get()), std::move(callback));
  211. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  212. loop.Run();
  213. ASSERT_TRUE(results_.get_locale_succeeded);
  214. EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq("en"));
  215. }
  216. // Given that the browser locale is not "en-US," verifies that the
  217. // manager can select a best-fit locale when one is available.
  218. TEST_F(PpdMetadataManagerTest, CanSelectNonEnglishCloseFitLocale) {
  219. // It's not "en-US" and is close to advertised metadata locale "es."
  220. NewManagerWithLocale("es-MX");
  221. // Known interaction: the manager will fetch the locales metadata.
  222. GetFakeCache()->SetFetchResponseForTesting(
  223. "metadata_v3/locales.json",
  224. R"({ "locales": [ "de", "en", "es", "wo" ] })");
  225. base::RunLoop loop;
  226. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
  227. base::Unretained(this), loop.QuitClosure());
  228. auto call =
  229. base::BindOnce(&PpdMetadataManager::GetLocale,
  230. base::Unretained(manager_.get()), std::move(callback));
  231. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  232. loop.Run();
  233. ASSERT_TRUE(results_.get_locale_succeeded);
  234. EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq("es"));
  235. }
  236. // Verifies that the manager fails the GetLocaleCallback
  237. // * if it finds no close fit for the browser locale and
  238. // * if the serving root does not advertise availability of
  239. // English-localized metadata.
  240. TEST_F(PpdMetadataManagerTest, FailsToFindAnyCloseFitLocale) {
  241. // Sets an arbitrarily chosen locale quite distant from what the
  242. // fake serving root will have available.
  243. NewManagerWithLocale("ja-JP");
  244. // Known interaction: the manager will fetch the locales metadata.
  245. //
  246. // Note that we are canning well-formed JSON.
  247. GetFakeCache()->SetFetchResponseForTesting(
  248. "metadata_v3/locales.json", R"({ "locales": [ "de", "es", "wo" ] })");
  249. // Jams the result to the opposite of what's expected.
  250. results_.get_locale_succeeded = true;
  251. base::RunLoop loop;
  252. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
  253. base::Unretained(this), loop.QuitClosure());
  254. auto call =
  255. base::BindOnce(&PpdMetadataManager::GetLocale,
  256. base::Unretained(manager_.get()), std::move(callback));
  257. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  258. loop.Run();
  259. ASSERT_FALSE(results_.get_locale_succeeded);
  260. EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq(""));
  261. }
  262. // Verifies that the manager fails the GetLocaleCallback if it fails to
  263. // fetch the locales metadata.
  264. TEST_F(PpdMetadataManagerTest, FailsToGetLocaleOnFetchFailure) {
  265. // This test deliberately doesn't can any response from the
  266. // FakePrinterConfigCache. We want to see what happens when the
  267. // manager fails to fetch the necessary networked resource.
  268. //
  269. // We do need some way to tell that GetLocale() failed, so we start
  270. // by jamming it to the opposite of the expected value.
  271. results_.get_locale_succeeded = true;
  272. base::RunLoop loop;
  273. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
  274. base::Unretained(this), loop.QuitClosure());
  275. auto call =
  276. base::BindOnce(&PpdMetadataManager::GetLocale,
  277. base::Unretained(manager_.get()), std::move(callback));
  278. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  279. loop.Run();
  280. ASSERT_FALSE(results_.get_locale_succeeded);
  281. EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq(""));
  282. }
  283. // Verifies that the manager fails the GetLocaleCallback if it fails to
  284. // parse the locales metadata.
  285. TEST_F(PpdMetadataManagerTest, FailsToGetLocaleOnParseFailure) {
  286. // Known interaction: the manager will fetch the locales metadata.
  287. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/locales.json",
  288. kInvalidJson);
  289. // We've canned an unparsable response for the manager.
  290. // To observe that GetLocale() fails, we jam the result to the
  291. // opposite of the expected value.
  292. results_.get_locale_succeeded = true;
  293. base::RunLoop loop;
  294. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetLocale,
  295. base::Unretained(this), loop.QuitClosure());
  296. auto call =
  297. base::BindOnce(&PpdMetadataManager::GetLocale,
  298. base::Unretained(manager_.get()), std::move(callback));
  299. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  300. loop.Run();
  301. ASSERT_FALSE(results_.get_locale_succeeded);
  302. EXPECT_THAT(manager_->ExposeMetadataLocaleForTesting(), StrEq(""));
  303. }
  304. // Verifies that the manager can fetch, parse, and return a list of
  305. // manufacturers from the Chrome OS Printing serving root.
  306. TEST_F(PpdMetadataManagerTest, CanGetManufacturers) {
  307. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  308. manager_->SetLocaleForTesting("en");
  309. // Known interaction: the manager will fetch manufacturers metadata
  310. // localized in English ("en").
  311. //
  312. // In real life, the values of the filesMap dictionary have a
  313. // hyphenated locale suffix attached; this is not something the
  314. // manager actually cares about and is not something used directly
  315. // in this test case.
  316. GetFakeCache()->SetFetchResponseForTesting(
  317. "metadata_v3/manufacturers-en.json",
  318. R"({ "filesMap": {
  319. "It": "Never_Ends-en.json",
  320. "You Are": "Always-en.json",
  321. "Playing": "Yellow_Car-en.json"
  322. } })");
  323. base::RunLoop loop;
  324. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
  325. base::Unretained(this), loop.QuitClosure());
  326. auto call = base::BindOnce(&PpdMetadataManager::GetManufacturers,
  327. base::Unretained(manager_.get()),
  328. kArbitraryTimeDelta, std::move(callback));
  329. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  330. loop.Run();
  331. ASSERT_EQ(results_.get_manufacturers_code,
  332. PpdProvider::CallbackResultCode::SUCCESS);
  333. // PpdProvider::ResolveManufacturersCallback specifies that the list
  334. // shall be sorted.
  335. EXPECT_THAT(results_.manufacturers,
  336. ElementsAre(StrEq("It"), StrEq("Playing"), StrEq("You Are")));
  337. }
  338. // Verifies that the manager fails the ResolveManufacturersCallback
  339. // when it fails to fetch the manufacturers metadata.
  340. TEST_F(PpdMetadataManagerTest, FailsToGetManufacturersOnFetchFailure) {
  341. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  342. manager_->SetLocaleForTesting("en");
  343. // Known interaction: the manager will fetch manufacturers metadata
  344. // localized in English ("en"). In this test case, we do _not_
  345. // populate the fake config cache with the appropriate metadata,
  346. // causing the fetch to fail.
  347. base::RunLoop loop;
  348. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
  349. base::Unretained(this), loop.QuitClosure());
  350. auto call = base::BindOnce(&PpdMetadataManager::GetManufacturers,
  351. base::Unretained(manager_.get()),
  352. kArbitraryTimeDelta, std::move(callback));
  353. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  354. loop.Run();
  355. ASSERT_EQ(results_.get_manufacturers_code,
  356. PpdProvider::CallbackResultCode::SERVER_ERROR);
  357. }
  358. // Verifies that the manager fails the ResolveManufacturersCallback
  359. // when it fails to parse the manufacturers metadata.
  360. TEST_F(PpdMetadataManagerTest, FailsToGetManufacturersOnParseFailure) {
  361. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  362. manager_->SetLocaleForTesting("en");
  363. // Known interaction: the manager will fetch manufacturers metadata
  364. // localized in English ("en").
  365. GetFakeCache()->SetFetchResponseForTesting(
  366. "metadata_v3/manufacturers-en.json", kInvalidJson);
  367. base::RunLoop loop;
  368. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
  369. base::Unretained(this), loop.QuitClosure());
  370. auto call = base::BindOnce(&PpdMetadataManager::GetManufacturers,
  371. base::Unretained(manager_.get()),
  372. kArbitraryTimeDelta, std::move(callback));
  373. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  374. loop.Run();
  375. ASSERT_EQ(results_.get_manufacturers_code,
  376. PpdProvider::CallbackResultCode::INTERNAL_ERROR);
  377. }
  378. // Verifies that the manager fetches manufacturers metadata anew when
  379. // caller asks it for metadata fresher than what it has cached.
  380. TEST_F(PpdMetadataManagerTest, CanGetManufacturersTimeSensitive) {
  381. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  382. manager_->SetLocaleForTesting("en");
  383. // Known interaction: the manager will fetch manufacturers metadata
  384. // localized in English ("en").
  385. GetFakeCache()->SetFetchResponseForTesting(
  386. "metadata_v3/manufacturers-en.json",
  387. R"({ "filesMap": {
  388. "It": "Never_Ends-en.json",
  389. "You Are": "Always-en.json",
  390. "Playing": "Yellow_Car-en.json"
  391. } })");
  392. base::RunLoop loop;
  393. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
  394. base::Unretained(this), loop.QuitClosure());
  395. // t = 0s: caller requests a list of manufacturers from |manager_|,
  396. // using metadata parsed within the last thirty seconds. |manager_|
  397. // performs a live fetch for the manufacturers metadata.
  398. manager_->GetManufacturers(base::Seconds(30), std::move(callback));
  399. loop.Run();
  400. ASSERT_EQ(results_.get_manufacturers_code,
  401. PpdProvider::CallbackResultCode::SUCCESS);
  402. // PpdProvider::ResolveManufacturersCallback specifies that the list
  403. // shall be sorted.
  404. EXPECT_THAT(results_.manufacturers,
  405. ElementsAre(StrEq("It"), StrEq("Playing"), StrEq("You Are")));
  406. // Mutates the test data, ensuring that if the metadata manager
  407. // attempts a live fetch from the PrinterConfigCache, it will get
  408. // different data in response.
  409. GetFakeCache()->SetFetchResponseForTesting(
  410. "metadata_v3/manufacturers-en.json",
  411. R"({ "filesMap": {
  412. "It": "Never_Ends-en.json",
  413. "You Are": "Always-en.json"
  414. } })");
  415. // Jams the result code to something bad to require that the
  416. // |manager_| positively answer us.
  417. results_.get_manufacturers_code =
  418. PpdProvider::CallbackResultCode::INTERNAL_ERROR;
  419. base::RunLoop second_loop;
  420. auto second_callback =
  421. base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
  422. base::Unretained(this), second_loop.QuitClosure());
  423. // t = 0s: caller requests a list of manufacturers from |manager_|.
  424. // |manager_| responds using the cached metadata without performing
  425. // a live fetch.
  426. manager_->GetManufacturers(base::Seconds(30), std::move(second_callback));
  427. second_loop.Run();
  428. // We assert that the results are unchanged from before.
  429. ASSERT_EQ(results_.get_manufacturers_code,
  430. PpdProvider::CallbackResultCode::SUCCESS);
  431. EXPECT_THAT(results_.manufacturers,
  432. ElementsAre(StrEq("It"), StrEq("Playing"), StrEq("You Are")));
  433. // t = 31s
  434. clock_.Advance(base::Seconds(31));
  435. // Jams the result code to something bad to require that the
  436. // |manager_| positively answer us.
  437. results_.get_manufacturers_code =
  438. PpdProvider::CallbackResultCode::INTERNAL_ERROR;
  439. base::RunLoop third_loop;
  440. auto third_callback =
  441. base::BindOnce(&PpdMetadataManagerTest::CatchGetManufacturers,
  442. base::Unretained(this), third_loop.QuitClosure());
  443. // t = 31s: caller requests a list of manufacturers from |manager_|.
  444. // |manager_| does not have sufficiently fresh metadata, so it
  445. // performs a live fetch.
  446. manager_->GetManufacturers(base::Seconds(30), std::move(third_callback));
  447. third_loop.Run();
  448. // We assert that the results have changed.
  449. ASSERT_EQ(results_.get_manufacturers_code,
  450. PpdProvider::CallbackResultCode::SUCCESS);
  451. EXPECT_THAT(results_.manufacturers,
  452. ElementsAre(StrEq("It"), StrEq("You Are")));
  453. }
  454. // Verifies that the manager can fetch, parse, and return a map of
  455. // printers metadata from the Chrome OS Printing serving root.
  456. TEST_F(PpdMetadataManagerTest, CanGetPrinters) {
  457. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  458. manager_->SetLocaleForTesting("en");
  459. // Bypasses prerequisite call to PpdMetadataManager::GetManufacturers().
  460. ASSERT_TRUE(manager_->SetManufacturersForTesting(R"(
  461. {
  462. "filesMap": {
  463. "Manufacturer A": "Manufacturer_A-en.json",
  464. "Manufacturer B": "Manufacturer_B-en.json"
  465. }
  466. }
  467. )"));
  468. // Known interaction: the manager will fetch printers metadata named
  469. // by the manufacturers map above.
  470. GetFakeCache()->SetFetchResponseForTesting(
  471. "metadata_v3/Manufacturer_A-en.json", R"(
  472. {
  473. "printers": [ {
  474. "emm": "some emm a",
  475. "name": "Some Printer A"
  476. }, {
  477. "emm": "some emm b",
  478. "name": "Some Printer B"
  479. } ]
  480. }
  481. )");
  482. base::RunLoop loop;
  483. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
  484. base::Unretained(this), loop.QuitClosure());
  485. auto call = base::BindOnce(&PpdMetadataManager::GetPrinters,
  486. base::Unretained(manager_.get()), "Manufacturer A",
  487. kArbitraryTimeDelta, std::move(callback));
  488. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  489. loop.Run();
  490. ASSERT_TRUE(results_.get_printers_succeeded);
  491. EXPECT_THAT(
  492. results_.printers,
  493. UnorderedElementsAre(ParsedPrinterLike("Some Printer A", "some emm a"),
  494. ParsedPrinterLike("Some Printer B", "some emm b")));
  495. }
  496. // Verifies that the manager fails the GetPrintersCallback when it fails
  497. // to fetch the printers metadata.
  498. TEST_F(PpdMetadataManagerTest, FailsToGetPrintersOnFetchFailure) {
  499. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  500. manager_->SetLocaleForTesting("en");
  501. // Bypasses prerequisite call to PpdMetadataManager::GetManufacturers().
  502. ASSERT_TRUE(manager_->SetManufacturersForTesting(R"(
  503. {
  504. "filesMap": {
  505. "Manufacturer A": "Manufacturer_A-en.json",
  506. "Manufacturer B": "Manufacturer_B-en.json"
  507. }
  508. }
  509. )"));
  510. // This test is set up like the CanGetPrinters test case above, but we
  511. // elect _not_ to provide a response for any printers metadata,
  512. // causing the fetch to fail.
  513. //
  514. // We set the result value to the opposite of what's expected to
  515. // observe the change.
  516. results_.get_printers_succeeded = true;
  517. base::RunLoop loop;
  518. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
  519. base::Unretained(this), loop.QuitClosure());
  520. auto call = base::BindOnce(&PpdMetadataManager::GetPrinters,
  521. base::Unretained(manager_.get()), "Manufacturer A",
  522. kArbitraryTimeDelta, std::move(callback));
  523. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  524. loop.Run();
  525. EXPECT_FALSE(results_.get_printers_succeeded);
  526. }
  527. // Verifies that the manager fails the GetPrintersCallback when it fails
  528. // to parse the printers metadata.
  529. TEST_F(PpdMetadataManagerTest, FailsToGetPrintersOnParseFailure) {
  530. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  531. manager_->SetLocaleForTesting("en");
  532. // Bypasses prerequisite call to PpdMetadataManager::GetManufacturers().
  533. ASSERT_TRUE(manager_->SetManufacturersForTesting(R"(
  534. {
  535. "filesMap": {
  536. "Manufacturer A": "Manufacturer_A-en.json",
  537. "Manufacturer B": "Manufacturer_B-en.json"
  538. }
  539. }
  540. )"));
  541. // This test is set up like the CanGetPrinters test case above, but we
  542. // elect to provide a malformed JSON response for the printers
  543. // metadata, which will cause the manager to fail parsing.
  544. //
  545. // Known interaction: the manager will fetch the printers metadata
  546. // named by the map above.
  547. GetFakeCache()->SetFetchResponseForTesting(
  548. "metadata_v3/Manufacturer_A-en.json", kInvalidJson);
  549. // We set the result value to the opposite of what's expected to
  550. // observe the change.
  551. results_.get_printers_succeeded = true;
  552. base::RunLoop loop;
  553. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
  554. base::Unretained(this), loop.QuitClosure());
  555. auto call = base::BindOnce(&PpdMetadataManager::GetPrinters,
  556. base::Unretained(manager_.get()), "Manufacturer A",
  557. kArbitraryTimeDelta, std::move(callback));
  558. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  559. loop.Run();
  560. EXPECT_FALSE(results_.get_printers_succeeded);
  561. }
  562. // Verifies that the manager fetches printers metadata anew when caller
  563. // asks it for metadata fresher than what it has cached.
  564. TEST_F(PpdMetadataManagerTest, CanGetPrintersTimeSensitive) {
  565. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  566. manager_->SetLocaleForTesting("en");
  567. // Bypasses prerequisite call to PpdMetadataManager::GetManufacturers().
  568. ASSERT_TRUE(manager_->SetManufacturersForTesting(R"(
  569. {
  570. "filesMap": {
  571. "Manufacturer A": "Manufacturer_A-en.json",
  572. "Manufacturer B": "Manufacturer_B-en.json"
  573. }
  574. }
  575. )"));
  576. // Known interaction: the manager will fetch printers metadata named
  577. // by the manufacturers map above.
  578. GetFakeCache()->SetFetchResponseForTesting(
  579. "metadata_v3/Manufacturer_A-en.json", R"(
  580. {
  581. "printers": [ {
  582. "emm": "some emm a",
  583. "name": "Some Printer A"
  584. }, {
  585. "emm": "some emm b",
  586. "name": "Some Printer B"
  587. } ]
  588. }
  589. )");
  590. // t = 0s: caller requests the printers for "Manufacturer A."
  591. // |manager_| parses and caches the metadata successfully.
  592. base::RunLoop loop;
  593. auto callback = base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
  594. base::Unretained(this), loop.QuitClosure());
  595. manager_->GetPrinters("Manufacturer A", base::Seconds(30),
  596. std::move(callback));
  597. loop.Run();
  598. ASSERT_TRUE(results_.get_printers_succeeded);
  599. EXPECT_THAT(
  600. results_.printers,
  601. UnorderedElementsAre(ParsedPrinterLike("Some Printer A", "some emm a"),
  602. ParsedPrinterLike("Some Printer B", "some emm b")));
  603. // We change the data served by the PrinterConfigCache.
  604. GetFakeCache()->SetFetchResponseForTesting(
  605. "metadata_v3/Manufacturer_A-en.json", R"(
  606. {
  607. "printers": [ {
  608. "emm": "some emm c",
  609. "name": "Some Printer C"
  610. }, {
  611. "emm": "some emm d",
  612. "name": "Some Printer D"
  613. } ]
  614. }
  615. )");
  616. // Jams the results to some bad value, requiring that the manager
  617. // answer us positively.
  618. results_.get_printers_succeeded = false;
  619. base::RunLoop second_loop;
  620. auto second_callback =
  621. base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
  622. base::Unretained(this), second_loop.QuitClosure());
  623. // t = 0s: caller requests the printers for "Manufacturer A."
  624. // |manager_| re-uses the cached metadata.
  625. manager_->GetPrinters("Manufacturer A", base::Seconds(30),
  626. std::move(second_callback));
  627. second_loop.Run();
  628. // We assert that the results are unchanged from before.
  629. ASSERT_TRUE(results_.get_printers_succeeded);
  630. EXPECT_THAT(
  631. results_.printers,
  632. UnorderedElementsAre(ParsedPrinterLike("Some Printer A", "some emm a"),
  633. ParsedPrinterLike("Some Printer B", "some emm b")));
  634. // t = 31s
  635. clock_.Advance(base::Seconds(31));
  636. // Jams the results to some bad value, requiring that the manager
  637. // answer us positively.
  638. results_.get_printers_succeeded = false;
  639. // t = 31s: caller requests the printers for "Manufacturer A."
  640. // |manager_| does not have sufficiently fresh metadata, so it
  641. // performs a live fetch.
  642. base::RunLoop third_loop;
  643. auto third_callback =
  644. base::BindOnce(&PpdMetadataManagerTest::CatchGetPrinters,
  645. base::Unretained(this), third_loop.QuitClosure());
  646. manager_->GetPrinters("Manufacturer A", base::Seconds(30),
  647. std::move(third_callback));
  648. third_loop.Run();
  649. // We assert that the results have changed.
  650. ASSERT_TRUE(results_.get_printers_succeeded);
  651. EXPECT_THAT(
  652. results_.printers,
  653. UnorderedElementsAre(ParsedPrinterLike("Some Printer C", "some emm c"),
  654. ParsedPrinterLike("Some Printer D", "some emm d")));
  655. }
  656. // Verifies that the manager can find all effective-make-and-model
  657. // strings in forward index metadata.
  658. TEST_F(PpdMetadataManagerTest, CanFindAllAvailableEmmsInIndex) {
  659. // Known interaction: the manager will fetch forward index metadata
  660. // numbered 14, 15, and 16.
  661. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json", R"(
  662. {
  663. "ppdIndex": {
  664. "some printer a": {
  665. "ppdMetadata": [ {
  666. "name": "some-ppd-basename-a.ppd.gz"
  667. } ]
  668. }
  669. }
  670. })");
  671. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
  672. {
  673. "ppdIndex": {
  674. "some printer b": {
  675. "ppdMetadata": [ {
  676. "name": "some-ppd-basename-b.ppd.gz"
  677. } ]
  678. }
  679. }
  680. })");
  681. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
  682. {
  683. "ppdIndex": {
  684. "some printer c": {
  685. "ppdMetadata": [ {
  686. "name": "some-ppd-basename-c.ppd.gz"
  687. } ]
  688. }
  689. }
  690. })");
  691. base::RunLoop loop;
  692. auto callback =
  693. base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
  694. base::Unretained(this), loop.QuitClosure());
  695. manager_->FindAllEmmsAvailableInIndex(
  696. {"some printer a", "some printer b", "some printer c"},
  697. kArbitraryTimeDelta, std::move(callback));
  698. loop.Run();
  699. EXPECT_THAT(results_.available_effective_make_and_model_strings,
  700. UnorderedElementsAre(
  701. ParsedIndexEntryLike(
  702. "some printer a",
  703. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  704. "some-ppd-basename-a.ppd.gz"))),
  705. ParsedIndexEntryLike(
  706. "some printer b",
  707. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  708. "some-ppd-basename-b.ppd.gz"))),
  709. ParsedIndexEntryLike(
  710. "some printer c",
  711. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  712. "some-ppd-basename-c.ppd.gz")))));
  713. }
  714. // Verifies that the manager invokes the
  715. // FindAllAvailableEmmsInIndexCallback with a partially filled argument
  716. // if it fails to fetch some of the necessary metadata.
  717. TEST_F(PpdMetadataManagerTest,
  718. CanPartiallyFindAllAvailableEmmsInIndexWithFetchFailure) {
  719. // Known interaction: the manager will fetch forward index metadata
  720. // numbered 14, 15, and 16.
  721. //
  722. // We deliberately omit forward index metadata no. 14 to simulate a
  723. // fetch failure.
  724. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
  725. {
  726. "ppdIndex": {
  727. "some printer b": {
  728. "ppdMetadata": [ {
  729. "name": "some-ppd-basename-b.ppd.gz"
  730. } ]
  731. }
  732. }
  733. })");
  734. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
  735. {
  736. "ppdIndex": {
  737. "some printer c": {
  738. "ppdMetadata": [ {
  739. "name": "some-ppd-basename-c.ppd.gz"
  740. } ]
  741. }
  742. }
  743. })");
  744. base::RunLoop loop;
  745. auto callback =
  746. base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
  747. base::Unretained(this), loop.QuitClosure());
  748. manager_->FindAllEmmsAvailableInIndex(
  749. {"some printer a", "some printer b", "some printer c"},
  750. kArbitraryTimeDelta, std::move(callback));
  751. loop.Run();
  752. // The manager was unable to get the forward index metadata that would
  753. // contain information for effective-make-and-model string
  754. // "some printer a," but the other results should avail themselves.
  755. EXPECT_THAT(results_.available_effective_make_and_model_strings,
  756. UnorderedElementsAre(
  757. ParsedIndexEntryLike(
  758. "some printer b",
  759. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  760. "some-ppd-basename-b.ppd.gz"))),
  761. ParsedIndexEntryLike(
  762. "some printer c",
  763. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  764. "some-ppd-basename-c.ppd.gz")))));
  765. }
  766. // Verifies that the manager invokes the
  767. // FindAllAvailableEmmsInIndexCallback with a partially filled argument
  768. // if it fails to parse some of the necessary metadata.
  769. TEST_F(PpdMetadataManagerTest,
  770. CanPartiallyFindAllAvailableEmmsInIndexWithParseFailure) {
  771. // Known interaction: the manager will fetch forward index metadata
  772. // numbered 14, 15, and 16.
  773. //
  774. // We deliberately serve malformed JSON that will fail to parse for
  775. // indices nos. 14 and 15 to exercise the manager's handling of parse
  776. // failures.
  777. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json",
  778. kInvalidJson);
  779. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json",
  780. kInvalidJson);
  781. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
  782. {
  783. "ppdIndex": {
  784. "some printer c": {
  785. "ppdMetadata": [ {
  786. "name": "some-ppd-basename-c.ppd.gz"
  787. } ]
  788. }
  789. }
  790. })");
  791. base::RunLoop loop;
  792. auto callback =
  793. base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
  794. base::Unretained(this), loop.QuitClosure());
  795. manager_->FindAllEmmsAvailableInIndex(
  796. {"some printer a", "some printer b", "some printer c"},
  797. kArbitraryTimeDelta, std::move(callback));
  798. loop.Run();
  799. // The manager was unable to parse the forward index metadata that would
  800. // contain information for effective-make-and-model strings
  801. // "some printer a" and for "some printer b," but the last string
  802. // "some printer c" should avail itself.
  803. EXPECT_THAT(
  804. results_.available_effective_make_and_model_strings,
  805. UnorderedElementsAre(ParsedIndexEntryLike(
  806. "some printer c", UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  807. "some-ppd-basename-c.ppd.gz")))));
  808. }
  809. // Verifies that the manager fetches forward index metadata anew when
  810. // the caller asks it for metadata fresher than what it has cached.
  811. TEST_F(PpdMetadataManagerTest, CanFindAllAvailableEmmsInIndexTimeSensitive) {
  812. // Known interaction: the manager will fetch forward index metadata
  813. // numbered 14, 15, and 16.
  814. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json", R"(
  815. {
  816. "ppdIndex": {
  817. "some printer a": {
  818. "ppdMetadata": [ {
  819. "name": "some-ppd-basename-a.ppd.gz"
  820. } ]
  821. }
  822. }
  823. })");
  824. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
  825. {
  826. "ppdIndex": {
  827. "some printer b": {
  828. "ppdMetadata": [ {
  829. "name": "some-ppd-basename-b.ppd.gz"
  830. } ]
  831. }
  832. }
  833. })");
  834. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
  835. {
  836. "ppdIndex": {
  837. "some printer c": {
  838. "ppdMetadata": [ {
  839. "name": "some-ppd-basename-c.ppd.gz"
  840. } ]
  841. }
  842. }
  843. })");
  844. base::RunLoop loop;
  845. auto callback =
  846. base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
  847. base::Unretained(this), loop.QuitClosure());
  848. // t = 0s: caller requests the |manager_| to search forward index
  849. // metadata for three effective-make-and-model strings. |manager_|
  850. // fetches the appropriate forward index metadata (nos. 14, 15, and
  851. // 16) and caches the result.
  852. manager_->FindAllEmmsAvailableInIndex(
  853. {"some printer a", "some printer b", "some printer c"}, base::Seconds(30),
  854. std::move(callback));
  855. loop.Run();
  856. EXPECT_THAT(results_.available_effective_make_and_model_strings,
  857. UnorderedElementsAre(
  858. ParsedIndexEntryLike(
  859. "some printer a",
  860. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  861. "some-ppd-basename-a.ppd.gz"))),
  862. ParsedIndexEntryLike(
  863. "some printer b",
  864. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  865. "some-ppd-basename-b.ppd.gz"))),
  866. ParsedIndexEntryLike(
  867. "some printer c",
  868. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  869. "some-ppd-basename-c.ppd.gz")))));
  870. // We drop forward index metadata nos. 14 and 15 now. If the
  871. // |manager_| attempts to fetch these again, it will fail to do so.
  872. GetFakeCache()->Drop("metadata_v3/index-14.json");
  873. GetFakeCache()->Drop("metadata_v3/index-15.json");
  874. // Resets the results to require that the |manager_| answer us
  875. // positively.
  876. results_.available_effective_make_and_model_strings = {};
  877. base::RunLoop second_loop;
  878. auto second_callback =
  879. base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
  880. base::Unretained(this), second_loop.QuitClosure());
  881. // t = 0s: caller requests the |manager_| to search forward index
  882. // metadata for the same three effective-make-and-model strings.
  883. // Caller requests this using metadata fetched within the last thirty
  884. // seconds, so |manager_| does not perform a live fetch of the data.
  885. manager_->FindAllEmmsAvailableInIndex(
  886. {"some printer a", "some printer b", "some printer c"}, base::Seconds(30),
  887. std::move(second_callback));
  888. second_loop.Run();
  889. // We expect the results to be unchanged.
  890. EXPECT_THAT(results_.available_effective_make_and_model_strings,
  891. UnorderedElementsAre(
  892. ParsedIndexEntryLike(
  893. "some printer a",
  894. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  895. "some-ppd-basename-a.ppd.gz"))),
  896. ParsedIndexEntryLike(
  897. "some printer b",
  898. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  899. "some-ppd-basename-b.ppd.gz"))),
  900. ParsedIndexEntryLike(
  901. "some printer c",
  902. UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  903. "some-ppd-basename-c.ppd.gz")))));
  904. // t = 31s
  905. clock_.Advance(base::Seconds(31));
  906. base::RunLoop third_loop;
  907. auto third_callback =
  908. base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
  909. base::Unretained(this), third_loop.QuitClosure());
  910. // t = 31s: caller requests the |manager_| to search forward index
  911. // metadata for the same three effective-make-and-model strings.
  912. // Caller requests this using metadata fetched within the last thirty
  913. // thirds; |manager_| sees that its cached metadata is too old, and
  914. // so performs a live fetch.
  915. //
  916. // Since we previously blocked forward index metadata nos. 14 and 15
  917. // from being served, the |manager_| will fail to fetch these.
  918. manager_->FindAllEmmsAvailableInIndex(
  919. {"some printer a", "some printer b", "some printer c"}, base::Seconds(30),
  920. std::move(third_callback));
  921. third_loop.Run();
  922. // We expect the results to have changed.
  923. EXPECT_THAT(
  924. results_.available_effective_make_and_model_strings,
  925. UnorderedElementsAre(ParsedIndexEntryLike(
  926. "some printer c", UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
  927. "some-ppd-basename-c.ppd.gz")))));
  928. }
  929. // Verifies that the manager can find a USB device by fetching and
  930. // parsing USB index metadata.
  931. TEST_F(PpdMetadataManagerTest, CanFindDeviceInUsbIndex) {
  932. // Known interaction: hex(1138) == 0x472. To fetch USB index metadata
  933. // for a manufacturer with vendor ID 1138, the manager will fetch
  934. // the metadata with the following name.
  935. //
  936. // This USB index describes one product for vendor ID 1138; its
  937. // product ID is 13.
  938. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb-0472.json", R"({
  939. "usbIndex": {
  940. "13": {
  941. "effectiveMakeAndModel": "some printer a"
  942. }
  943. }
  944. })");
  945. base::RunLoop loop;
  946. auto callback =
  947. base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
  948. base::Unretained(this), loop.QuitClosure());
  949. manager_->FindDeviceInUsbIndex(1138, 13, kArbitraryTimeDelta,
  950. std::move(callback));
  951. loop.Run();
  952. EXPECT_THAT(results_.effective_make_and_model_string_from_usb_index,
  953. StrEq("some printer a"));
  954. }
  955. // Verifies that the manager invokes the FindDeviceInUsbIndexCallback
  956. // with an empty argument if it fails to fetch the appropriate USB
  957. // index.
  958. TEST_F(PpdMetadataManagerTest, FailsToFindDeviceInUsbIndexOnFetchFailure) {
  959. // Known interaction: hex(1138) == 0x472. To fetch USB index metadata
  960. // for a manufacturer with vendor ID 1138, the manager will fetch
  961. // the metadata with the following name.
  962. //
  963. // We populate nothing in the fake serving root, so any fetch request
  964. // from the manager will fail.
  965. // Jams the landing area to have a non-empty string. We expect the
  966. // callback to fire with an empty string, which should empty this.
  967. results_.effective_make_and_model_string_from_usb_index =
  968. "non-empty string that will fail this test if it persists";
  969. base::RunLoop loop;
  970. auto callback =
  971. base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
  972. base::Unretained(this), loop.QuitClosure());
  973. manager_->FindDeviceInUsbIndex(1138, 13, kArbitraryTimeDelta,
  974. std::move(callback));
  975. loop.Run();
  976. EXPECT_TRUE(results_.effective_make_and_model_string_from_usb_index.empty());
  977. }
  978. // Verifies that the manager invokes the FindDeviceInUsbIndexCallback
  979. // with an empty argument if it fails to parse the appropriate USB
  980. // index.
  981. TEST_F(PpdMetadataManagerTest, FailsToFindDeviceInUsbIndexOnParseFailure) {
  982. // Known interaction: hex(1138) == 0x472. To fetch USB index metadata
  983. // for a manufacturer with vendor ID 1138, the manager will fetch
  984. // the metadata with the following name.
  985. //
  986. // We populate the fake serving root with invalid JSON for the USB
  987. // index metadata that the manager will fetch and fail to parse.
  988. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb-0472.json",
  989. kInvalidJson);
  990. // Jams the landing area to have a non-empty string. We expect the
  991. // callback to fire with an empty string, which should empty this.
  992. results_.effective_make_and_model_string_from_usb_index =
  993. "non-empty string that will fail this test if it persists";
  994. base::RunLoop loop;
  995. auto callback =
  996. base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
  997. base::Unretained(this), loop.QuitClosure());
  998. manager_->FindDeviceInUsbIndex(1138, 13, kArbitraryTimeDelta,
  999. std::move(callback));
  1000. loop.Run();
  1001. EXPECT_TRUE(results_.effective_make_and_model_string_from_usb_index.empty());
  1002. }
  1003. // Verifies that the manager fetches USB index metadata anew when caller
  1004. // asks it for metadata fresher than what it has cached.
  1005. TEST_F(PpdMetadataManagerTest, CanFindDeviceInUsbIndexTimeSensitive) {
  1006. // Known interaction: hex(1138) == 0x472. To fetch USB index metadata
  1007. // for a manufacturer with vendor ID 1138, the manager will fetch
  1008. // the metadata with the following name.
  1009. //
  1010. // This USB index describes one product for vendor ID 1138; its
  1011. // product ID is 13.
  1012. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb-0472.json", R"({
  1013. "usbIndex": {
  1014. "13": {
  1015. "effectiveMakeAndModel": "some printer a"
  1016. }
  1017. }
  1018. })");
  1019. base::RunLoop loop;
  1020. auto callback =
  1021. base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
  1022. base::Unretained(this), loop.QuitClosure());
  1023. // t = 0s: caller requests |manager_| to name a device with vendor ID
  1024. // 1138 and product ID 13. |manager_| fetches, parses, and caches
  1025. // the appropriate USB index metadata.
  1026. manager_->FindDeviceInUsbIndex(1138, 13, kArbitraryTimeDelta,
  1027. std::move(callback));
  1028. loop.Run();
  1029. EXPECT_THAT(results_.effective_make_and_model_string_from_usb_index,
  1030. StrEq("some printer a"));
  1031. // Sets the serving root to mutate the served USB index metadata; the
  1032. // device with product ID 13 now has the effective-make-and-model
  1033. // string "some printer b." If the |manager_| fetches this metadata
  1034. // anew, then it will observe the changed effective-make-and-model
  1035. // string.
  1036. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb-0472.json", R"({
  1037. "usbIndex": {
  1038. "13": {
  1039. "effectiveMakeAndModel": "some printer b"
  1040. }
  1041. }
  1042. })");
  1043. // Jams the landing area to hold a test-failing string. We expect
  1044. // the successful callback to overwrite this.
  1045. results_.effective_make_and_model_string_from_usb_index =
  1046. "non-empty string that will fail this test if it persists";
  1047. base::RunLoop second_loop;
  1048. auto second_callback =
  1049. base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
  1050. base::Unretained(this), second_loop.QuitClosure());
  1051. // t = 0s: caller requests |manager_| to name a device with vendor ID
  1052. // 1138 and product ID 13. It asks that |manager_| do so with metadata
  1053. // parsed within the last 30 seconds. |manager_| responds with the
  1054. // cached USB index metadata without incurring a live fetch.
  1055. manager_->FindDeviceInUsbIndex(1138, 13, base::Seconds(30),
  1056. std::move(second_callback));
  1057. second_loop.Run();
  1058. // The manager will have responded with the cached
  1059. // effective-make-and-model string "some printer a."
  1060. EXPECT_THAT(results_.effective_make_and_model_string_from_usb_index,
  1061. StrEq("some printer a"));
  1062. // t = 31s
  1063. clock_.Advance(base::Seconds(31));
  1064. // Jams the landing area to hold a test-failing string. We expect
  1065. // the successful callback to overwrite this.
  1066. results_.effective_make_and_model_string_from_usb_index =
  1067. "non-empty string that will fail this test if it persists";
  1068. base::RunLoop third_loop;
  1069. auto third_callback =
  1070. base::BindOnce(&PpdMetadataManagerTest::CatchFindDeviceInUsbIndex,
  1071. base::Unretained(this), third_loop.QuitClosure());
  1072. // t = 31s: caller requests |manager_| to name a device with vendor ID
  1073. // 1138 and product ID 13. It asks that |manager_| do so with metadata
  1074. // parsed within the last 30 seconds. |manager_| sees that the cached
  1075. // USB index metadata is too stale, and so incurs a live fetch. The
  1076. // fetch exposes the changed metadata.
  1077. manager_->FindDeviceInUsbIndex(1138, 13, base::Seconds(30),
  1078. std::move(third_callback));
  1079. third_loop.Run();
  1080. // The manager will have responded with the new and changed
  1081. // effective-make-and-model string "some printer b."
  1082. EXPECT_THAT(results_.effective_make_and_model_string_from_usb_index,
  1083. StrEq("some printer b"));
  1084. }
  1085. // Verifies that the manager can determine a USB manufacturer name
  1086. // by fetching and searching the USB vendor ID map.
  1087. TEST_F(PpdMetadataManagerTest, CanGetUsbManufacturerName) {
  1088. // Known interaction: |manager_| shall fetch the USB vendor ID map.
  1089. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb_vendor_ids.json",
  1090. R"({
  1091. "entries": [ {
  1092. "vendorId": 1138,
  1093. "vendorName": "Some Vendor Name"
  1094. } ]
  1095. })");
  1096. base::RunLoop loop;
  1097. auto callback =
  1098. base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
  1099. base::Unretained(this), loop.QuitClosure());
  1100. manager_->GetUsbManufacturerName(1138, kArbitraryTimeDelta,
  1101. std::move(callback));
  1102. loop.Run();
  1103. EXPECT_THAT(results_.usb_manufacturer_name, StrEq("Some Vendor Name"));
  1104. }
  1105. // Verifies that the manager invokes the GetUsbManufacturerNameCallback
  1106. // with an empty argument if it fails to fetch the USB vendor ID map.
  1107. TEST_F(PpdMetadataManagerTest, FailsToGetUsbManufacturerNameOnFetchFailure) {
  1108. // Known interaction: |manager_| shall fetch the USB vendor ID map.
  1109. //
  1110. // We deliberately don't set any fetch response in the fake serving
  1111. // root; |manager_| will fail to fetch the USB vendor ID map. However,
  1112. // we do jam the landing area with a sentinel value to ensure that the
  1113. // callback does fire with an empty string.
  1114. results_.usb_manufacturer_name =
  1115. "non-empty string that will fail this test if it persists";
  1116. base::RunLoop loop;
  1117. auto callback =
  1118. base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
  1119. base::Unretained(this), loop.QuitClosure());
  1120. manager_->GetUsbManufacturerName(1138, kArbitraryTimeDelta,
  1121. std::move(callback));
  1122. loop.Run();
  1123. EXPECT_TRUE(results_.usb_manufacturer_name.empty());
  1124. }
  1125. // Verifies that the manager invokes the GetUsbManufacturerNameCallback
  1126. // with an empty argument if it fails to parse the USB vendor ID map.
  1127. TEST_F(PpdMetadataManagerTest, FailsToGetUsbManufacturerNameOnParseFailure) {
  1128. // Known interaction: |manager_| shall fetch the USB vendor ID map.
  1129. //
  1130. // We deliberately set a malformed response in the serving root;
  1131. // |manager_| will fetch the USB vendor ID map successfully, but will
  1132. // fail to parse it.
  1133. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb_vendor_ids.json",
  1134. kInvalidJson);
  1135. // We also jam the landing area with a sentinel value to ensure that
  1136. // the callback fires with an empty string.
  1137. results_.usb_manufacturer_name =
  1138. "non-empty string that will fail this test if it persists";
  1139. base::RunLoop loop;
  1140. auto callback =
  1141. base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
  1142. base::Unretained(this), loop.QuitClosure());
  1143. manager_->GetUsbManufacturerName(1138, kArbitraryTimeDelta,
  1144. std::move(callback));
  1145. loop.Run();
  1146. EXPECT_TRUE(results_.usb_manufacturer_name.empty());
  1147. }
  1148. // Verifies that the manager fetches the USB vendor ID map anew if the
  1149. // caller calls GetUsbManufacturerName() asking for metadata fresher
  1150. // than what it has cached.
  1151. TEST_F(PpdMetadataManagerTest, CanGetUsbManufacturerNameTimeSensitive) {
  1152. // Known interaction: |manager_| shall fetch the USB vendor ID map.
  1153. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb_vendor_ids.json",
  1154. R"({
  1155. "entries": [ {
  1156. "vendorId": 1138,
  1157. "vendorName": "Vendor One One Three Eight"
  1158. } ]
  1159. })");
  1160. base::RunLoop loop;
  1161. auto callback =
  1162. base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
  1163. base::Unretained(this), loop.QuitClosure());
  1164. // t = 0s: caller requests the name of a USB manufacturer whose vendor
  1165. // ID is 1138. |manager_| fetches, parses, and caches the USB vendor
  1166. // ID map, responding with the name.
  1167. manager_->GetUsbManufacturerName(1138, base::Seconds(30),
  1168. std::move(callback));
  1169. loop.Run();
  1170. EXPECT_THAT(results_.usb_manufacturer_name,
  1171. StrEq("Vendor One One Three Eight"));
  1172. // Mutates the USB vendor ID map served by the fake serving root.
  1173. // If the |manager_| fetches it now, it will see a changed name for
  1174. // the USB manufacturer with vendor ID 1138.
  1175. GetFakeCache()->SetFetchResponseForTesting("metadata_v3/usb_vendor_ids.json",
  1176. R"({
  1177. "entries": [ {
  1178. "vendorId": 1138,
  1179. "vendorName": "One One Three Eight LLC"
  1180. } ]
  1181. })");
  1182. base::RunLoop second_loop;
  1183. auto second_callback =
  1184. base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
  1185. base::Unretained(this), second_loop.QuitClosure());
  1186. // t = 0s: caller requests the name of a USB manufacturer whose vendor
  1187. // ID is 1138. |manager_| responds with the previously fetched
  1188. // metadata.
  1189. manager_->GetUsbManufacturerName(1138, base::Seconds(30),
  1190. std::move(second_callback));
  1191. second_loop.Run();
  1192. // Since |manager_| has not fetched the mutated USB vendor ID map,
  1193. // the results are unchanged from before.
  1194. EXPECT_THAT(results_.usb_manufacturer_name,
  1195. StrEq("Vendor One One Three Eight"));
  1196. // t = 31s
  1197. clock_.Advance(base::Seconds(31));
  1198. base::RunLoop third_loop;
  1199. auto third_callback =
  1200. base::BindOnce(&PpdMetadataManagerTest::CatchGetUsbManufacturerName,
  1201. base::Unretained(this), third_loop.QuitClosure());
  1202. // t = 31s: caller requests the name of a USB manufacturer whose
  1203. // vendor ID is 1138. |manager_| notices that its cached metadata is
  1204. // too stale and performs a live fetch, receiving the mutated
  1205. // USB vendor ID map.
  1206. manager_->GetUsbManufacturerName(1138, base::Seconds(30),
  1207. std::move(third_callback));
  1208. third_loop.Run();
  1209. // Since |manager_| has not fetched the mutated USB vendor ID map,
  1210. // the results are unchanged from before.
  1211. EXPECT_THAT(results_.usb_manufacturer_name, StrEq("One One Three Eight LLC"));
  1212. }
  1213. // Verifies that the manager can split an effective-make-and-model
  1214. // string into its constituent parts (make and model).
  1215. TEST_F(PpdMetadataManagerTest, CanSplitMakeAndModel) {
  1216. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  1217. manager_->SetLocaleForTesting("en");
  1218. // Known interaction: asking the manager to split the string
  1219. // "Hello there!" will cause it to fetch the reverse index metadata
  1220. // with shard number 2.
  1221. GetFakeCache()->SetFetchResponseForTesting(
  1222. "metadata_v3/reverse_index-en-02.json", R"(
  1223. {
  1224. "reverseIndex": {
  1225. "Hello there!": {
  1226. "manufacturer": "General",
  1227. "model": "Kenobi"
  1228. }
  1229. }
  1230. }
  1231. )");
  1232. base::RunLoop loop;
  1233. auto callback =
  1234. base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
  1235. base::Unretained(this), loop.QuitClosure());
  1236. auto call = base::BindOnce(&PpdMetadataManager::SplitMakeAndModel,
  1237. base::Unretained(manager_.get()), "Hello there!",
  1238. kArbitraryTimeDelta, std::move(callback));
  1239. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  1240. loop.Run();
  1241. ASSERT_EQ(results_.split_make_and_model_code,
  1242. PpdProvider::CallbackResultCode::SUCCESS);
  1243. EXPECT_THAT(results_.split_make, StrEq("General"));
  1244. EXPECT_THAT(results_.split_model, StrEq("Kenobi"));
  1245. }
  1246. // Verifies that the manager fails the ReverseLookupCallback when it
  1247. // fails to fetch the necessary metadata from the Chrome OS Printing
  1248. // serving root.
  1249. TEST_F(PpdMetadataManagerTest, FailsToSplitMakeAndModelOnFetchFailure) {
  1250. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  1251. manager_->SetLocaleForTesting("en");
  1252. // Known interaction: asking the manager to split the string
  1253. // "Hello there!" will cause it to fetch the reverse index metadata
  1254. // with shard number 2.
  1255. //
  1256. // We elect _not_ to fake a value for this s.t. the fetch will fail.
  1257. base::RunLoop loop;
  1258. auto callback =
  1259. base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
  1260. base::Unretained(this), loop.QuitClosure());
  1261. auto call = base::BindOnce(&PpdMetadataManager::SplitMakeAndModel,
  1262. base::Unretained(manager_.get()), "Hello there!",
  1263. kArbitraryTimeDelta, std::move(callback));
  1264. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  1265. loop.Run();
  1266. EXPECT_EQ(results_.split_make_and_model_code,
  1267. PpdProvider::CallbackResultCode::SERVER_ERROR);
  1268. }
  1269. // Verifies that the manager fails the ReverseLookupCallback when it
  1270. // fails to parse the necessary metadata from the Chrome OS Printing
  1271. // serving root.
  1272. TEST_F(PpdMetadataManagerTest, FailsToSplitMakeAndModelOnParseFailure) {
  1273. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  1274. manager_->SetLocaleForTesting("en");
  1275. // Known interaction: asking the manager to split the string
  1276. // "Hello there!" will cause it to fetch the reverse index metadata
  1277. // with shard number 2.
  1278. //
  1279. // We fake a fetch value that is invalid JSON s.t. the manager
  1280. // will fail to parse it.
  1281. GetFakeCache()->SetFetchResponseForTesting(
  1282. "metadata_v3/reverse_index-en-02.json", kInvalidJson);
  1283. base::RunLoop loop;
  1284. auto callback =
  1285. base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
  1286. base::Unretained(this), loop.QuitClosure());
  1287. auto call = base::BindOnce(&PpdMetadataManager::SplitMakeAndModel,
  1288. base::Unretained(manager_.get()), "Hello there!",
  1289. kArbitraryTimeDelta, std::move(callback));
  1290. base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(call));
  1291. loop.Run();
  1292. ASSERT_EQ(results_.split_make_and_model_code,
  1293. PpdProvider::CallbackResultCode::INTERNAL_ERROR);
  1294. }
  1295. // Verifies that the manager fetches reverse index metadata anew when
  1296. // caller asks it for metadata fresher than what it has cached.
  1297. TEST_F(PpdMetadataManagerTest, CanSplitMakeAndModelTimeSensitive) {
  1298. // Bypasses mandatory call to PpdMetadataManager::GetLocale().
  1299. manager_->SetLocaleForTesting("en");
  1300. // Known interaction: asking the manager to split the string
  1301. // "Hello there!" will cause it to fetch the reverse index metadata
  1302. // with shard number 2.
  1303. GetFakeCache()->SetFetchResponseForTesting(
  1304. "metadata_v3/reverse_index-en-02.json", R"(
  1305. {
  1306. "reverseIndex": {
  1307. "Hello there!": {
  1308. "manufacturer": "General",
  1309. "model": "Kenobi"
  1310. }
  1311. }
  1312. }
  1313. )");
  1314. base::RunLoop loop;
  1315. auto callback =
  1316. base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
  1317. base::Unretained(this), loop.QuitClosure());
  1318. // t = 0s: caller requests that |manager_| split the
  1319. // effective-make-and-model string "Hello there!" using metadata
  1320. // parsed within the last thirty seconds. |manager_| fetches the
  1321. // appropriate reverse index metadata.
  1322. manager_->SplitMakeAndModel("Hello there!", base::Seconds(30),
  1323. std::move(callback));
  1324. loop.Run();
  1325. ASSERT_EQ(results_.split_make_and_model_code,
  1326. PpdProvider::CallbackResultCode::SUCCESS);
  1327. EXPECT_THAT(results_.split_make, StrEq("General"));
  1328. EXPECT_THAT(results_.split_model, StrEq("Kenobi"));
  1329. // Mutates the reverse index metadata we serve.
  1330. GetFakeCache()->SetFetchResponseForTesting(
  1331. "metadata_v3/reverse_index-en-02.json", R"(
  1332. {
  1333. "reverseIndex": {
  1334. "Hello there!": {
  1335. "manufacturer": "You are",
  1336. "model": "a bold one!"
  1337. }
  1338. }
  1339. }
  1340. )");
  1341. // Jams the result to a bad value, requiring that the |manager_|
  1342. // answer us positively.
  1343. results_.split_make_and_model_code =
  1344. PpdProvider::CallbackResultCode::INTERNAL_ERROR;
  1345. base::RunLoop second_loop;
  1346. auto second_callback =
  1347. base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
  1348. base::Unretained(this), second_loop.QuitClosure());
  1349. // t = 0s: caller requests that |manager_| split the
  1350. // effective-make-and-model string "Hello there!"
  1351. // |manager_| re-uses the cached reverse index metadata.
  1352. manager_->SplitMakeAndModel("Hello there!", base::Seconds(30),
  1353. std::move(second_callback));
  1354. second_loop.Run();
  1355. // We assert that the results are currently unchanged.
  1356. ASSERT_EQ(results_.split_make_and_model_code,
  1357. PpdProvider::CallbackResultCode::SUCCESS);
  1358. EXPECT_THAT(results_.split_make, StrEq("General"));
  1359. EXPECT_THAT(results_.split_model, StrEq("Kenobi"));
  1360. // t = 31s
  1361. clock_.Advance(base::Seconds(31));
  1362. // Jams the result to a bad value, requiring that the |manager_|
  1363. // answer us positively.
  1364. results_.split_make_and_model_code =
  1365. PpdProvider::CallbackResultCode::INTERNAL_ERROR;
  1366. base::RunLoop third_loop;
  1367. auto third_callback =
  1368. base::BindOnce(&PpdMetadataManagerTest::CatchSplitMakeAndModel,
  1369. base::Unretained(this), third_loop.QuitClosure());
  1370. // t = 31s: caller requests that |manager_| split the
  1371. // effective-make-and-model string "Hello there!"
  1372. // |manager_| doesn't have sufficiently fresh metadata, so it performs
  1373. // a live fetch.
  1374. manager_->SplitMakeAndModel("Hello there!", base::Seconds(30),
  1375. std::move(third_callback));
  1376. third_loop.Run();
  1377. // We assert that the live fetch changed the results.
  1378. ASSERT_EQ(results_.split_make_and_model_code,
  1379. PpdProvider::CallbackResultCode::SUCCESS);
  1380. EXPECT_THAT(results_.split_make, StrEq("You are"));
  1381. EXPECT_THAT(results_.split_model, StrEq("a bold one!"));
  1382. }
  1383. } // namespace
  1384. } // namespace chromeos