1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144 |
- // Copyright 2016 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 "chromeos/printing/ppd_provider.h"
- #include <algorithm>
- #include <map>
- #include <memory>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/files/file_util.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/run_loop.h"
- #include "base/strings/strcat.h"
- #include "base/strings/stringprintf.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/test/bind.h"
- #include "base/test/simple_test_clock.h"
- #include "base/test/task_environment.h"
- #include "base/test/test_message_loop.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/version.h"
- #include "chromeos/printing/fake_printer_config_cache.h"
- #include "chromeos/printing/ppd_cache.h"
- #include "chromeos/printing/ppd_metadata_manager.h"
- #include "chromeos/printing/printer_config_cache.h"
- #include "chromeos/printing/printer_configuration.h"
- #include "testing/gmock/include/gmock/gmock-matchers.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace chromeos {
- namespace {
- using PrinterDiscoveryType = PrinterSearchData::PrinterDiscoveryType;
- using ::testing::AllOf;
- using ::testing::Eq;
- using ::testing::Field;
- using ::testing::StrEq;
- using ::testing::UnorderedElementsAre;
- // A pseudo-ppd that should get cupsFilter lines extracted from it.
- const char kCupsFilterPpdContents[] = R"(
- Other random contents that we don't care about.
- *cupsFilter: "application/vnd.cups-raster 0 my_filter"
- More random contents that we don't care about
- *cupsFilter: "application/vnd.cups-awesome 0 a_different_filter"
- *cupsFilter: "application/vnd.cups-awesomesauce 0 filter3"
- Yet more randome contents that we don't care about.
- More random contents that we don't care about.
- )";
- // A pseudo-ppd that should get cupsFilter2 lines extracted from it.
- // We also have cupsFilter lines in here, but since cupsFilter2 lines
- // exist, the cupsFilter lines should be ignored.
- const char kCupsFilter2PpdContents[] = R"(
- Other random contents that we don't care about.
- *cupsFilter: "application/vnd.cups-raster 0 my_filter"
- More random contents that we don't care about
- *cupsFilter2: "foo bar 0 the_real_filter"
- *cupsFilter2: "bar baz 381 another_real_filter"
- Yet more randome contents that we don't care about.
- More random contents that we don't care about.
- )";
- // Known number of public method calls that the PpdProvider will defer
- // before posting failures directly.
- // * This value is left unspecified in the header.
- // * This value must be kept in sync with the exact value in the
- // implementation of PpdProvider.
- constexpr int kMethodDeferralLimitForTesting = 20;
- // Default manufacturers metadata used for these tests.
- const char kDefaultManufacturersJson[] = R"({
- "filesMap": {
- "Manufacturer A": "manufacturer_a-en.json",
- "Manufacturer B": "manufacturer_b-en.json"
- }
- })";
- // Unowned raw pointers to helper classes composed into the
- // PpdProvider at construct time. Used throughout to activate testing
- // codepaths.
- struct PpdProviderComposedMembers {
- FakePrinterConfigCache* config_cache = nullptr;
- FakePrinterConfigCache* manager_config_cache = nullptr;
- PpdMetadataManager* metadata_manager = nullptr;
- };
- class PpdProviderTest : public ::testing::Test {
- public:
- // * Determines where the PpdCache class runs.
- // * If set to kOnTestThread, the PpdCache class will use the
- // task environment of the test fixture.
- // * If set to kInBackgroundThreads, the PpdCache class will
- // spawn its own background threads.
- // * Prefer only to run cache on the test thread if you need to
- // manipulate its sequencing independently of PpdProvider;
- // otherwise, allowing it spawn its own background threads
- // should be safe and good for exercising its codepaths.
- enum class PpdCacheRunLocation {
- kOnTestThread,
- kInBackgroundThreads,
- };
- // * Determines whether the browser locale given to PpdProvider
- // should be propagated to the composed PpdMetadataManager as its
- // metadata locale as well.
- // * Useful to the caller depending on whether or not one is
- // interested in the codepaths that fetch and parse the locales
- // metadata.
- enum class PropagateLocaleToMetadataManager {
- kDoNotPropagate,
- kDoPropagate,
- };
- // Options passed to CreateProvider().
- struct CreateProviderOptions {
- std::string browser_locale;
- PpdCacheRunLocation where_ppd_cache_runs;
- PropagateLocaleToMetadataManager propagate_locale;
- };
- PpdProviderTest()
- : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
- base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
- void SetUp() override {
- ASSERT_TRUE(ppd_cache_temp_dir_.CreateUniqueTempDir());
- }
- // Creates and return a provider for a test that uses the given |options|.
- scoped_refptr<PpdProvider> CreateProvider(
- const CreateProviderOptions& options) {
- switch (options.where_ppd_cache_runs) {
- case PpdCacheRunLocation::kOnTestThread:
- ppd_cache_ = PpdCache::CreateForTesting(
- ppd_cache_temp_dir_.GetPath(),
- task_environment_.GetMainThreadTaskRunner());
- break;
- case PpdCacheRunLocation::kInBackgroundThreads:
- default:
- ppd_cache_ = PpdCache::Create(ppd_cache_temp_dir_.GetPath());
- break;
- }
- auto manager_config_cache = std::make_unique<FakePrinterConfigCache>();
- provider_backdoor_.manager_config_cache = manager_config_cache.get();
- auto manager = PpdMetadataManager::Create(options.browser_locale, &clock_,
- std::move(manager_config_cache));
- provider_backdoor_.metadata_manager = manager.get();
- switch (options.propagate_locale) {
- case PropagateLocaleToMetadataManager::kDoNotPropagate:
- // Nothing to do; the no-propagate case allows the
- // PpdMetadataManager to acquire the metadata locale (or fail to
- // do so) by natural means.
- break;
- case PropagateLocaleToMetadataManager::kDoPropagate:
- default:
- provider_backdoor_.metadata_manager->SetLocaleForTesting(
- options.browser_locale);
- break;
- }
- auto config_cache = std::make_unique<FakePrinterConfigCache>();
- provider_backdoor_.config_cache = config_cache.get();
- return PpdProvider::Create(base::Version("40.8.6753.09"), ppd_cache_,
- std::move(manager), std::move(config_cache));
- }
- // Fills the fake Chrome OS Printing serving root with content.
- // Must be called after CreateProvider().
- void StartFakePpdServer() {
- for (const auto& entry : server_contents()) {
- provider_backdoor_.config_cache->SetFetchResponseForTesting(entry.first,
- entry.second);
- provider_backdoor_.manager_config_cache->SetFetchResponseForTesting(
- entry.first, entry.second);
- }
- }
- // Interceptor posts a *task* during destruction that actually unregisters
- // things. So we have to run the message loop post-interceptor-destruction to
- // actually unregister the URLs, otherwise they won't *actually* be
- // unregistered until the next time we invoke the message loop. Which may be
- // in the middle of the next test.
- //
- // Note this is harmless to call if we haven't started a fake ppd server.
- void StopFakePpdServer() {
- for (const auto& entry : server_contents()) {
- provider_backdoor_.config_cache->Drop(entry.first);
- provider_backdoor_.manager_config_cache->Drop(entry.first);
- }
- task_environment_.RunUntilIdle();
- }
- // Capture the result of a ResolveManufacturers() call.
- void CaptureResolveManufacturers(PpdProvider::CallbackResultCode code,
- const std::vector<std::string>& data) {
- captured_resolve_manufacturers_.push_back({code, data});
- }
- // Capture the result of a ResolvePrinters() call.
- void CaptureResolvePrinters(PpdProvider::CallbackResultCode code,
- const PpdProvider::ResolvedPrintersList& data) {
- captured_resolve_printers_.push_back({code, data});
- }
- // Capture the result of a ResolvePpd() call.
- void CaptureResolvePpd(PpdProvider::CallbackResultCode code,
- const std::string& ppd_contents) {
- CapturedResolvePpdResults results;
- results.code = code;
- results.ppd_contents = ppd_contents;
- captured_resolve_ppd_.push_back(results);
- }
- // Capture the result of a ResolveUsbIds() call.
- void CaptureResolvePpdReference(PpdProvider::CallbackResultCode code,
- const Printer::PpdReference& ref,
- const std::string& usb_manufacturer) {
- captured_resolve_ppd_references_.push_back({code, ref, usb_manufacturer});
- }
- // Capture the result of a ResolvePpdLicense() call.
- void CaptureResolvePpdLicense(PpdProvider::CallbackResultCode code,
- const std::string& license) {
- captured_resolve_ppd_license_.push_back({code, license});
- }
- void CaptureReverseLookup(PpdProvider::CallbackResultCode code,
- const std::string& manufacturer,
- const std::string& model) {
- captured_reverse_lookup_.push_back({code, manufacturer, model});
- }
- // Discard the result of a ResolvePpd() call.
- void DiscardResolvePpd(PpdProvider::CallbackResultCode code,
- const std::string& contents) {}
- // Calls the ResolveManufacturer() method of the |provider| and
- // waits for its completion. Ignores the returned string values and
- // returns whether the result code was
- // PpdProvider::CallbackResultCode::SUCCESS.
- bool SuccessfullyResolveManufacturers(PpdProvider* provider) {
- base::RunLoop run_loop;
- PpdProvider::CallbackResultCode code;
- provider->ResolveManufacturers(base::BindLambdaForTesting(
- [&run_loop, &code](
- PpdProvider::CallbackResultCode result_code,
- const std::vector<std::string>& unused_manufacturers) {
- code = result_code;
- run_loop.QuitClosure().Run();
- }));
- run_loop.Run();
- return code == PpdProvider::CallbackResultCode::SUCCESS;
- }
- protected:
- // List of relevant endpoint for this FakeServer
- std::vector<std::pair<std::string, std::string>> server_contents() const {
- // Use brace initialization to express the desired server contents as "url",
- // "contents" pairs.
- return {{"metadata_v3/locales.json",
- R"({
- "locales": [ "de", "en", "es" ]
- })"},
- {"metadata_v3/manufacturers-en.json", kDefaultManufacturersJson},
- {"metadata_v3/manufacturer_a-en.json",
- R"({
- "printers": [ {
- "name": "printer_a",
- "emm": "printer_a_ref"
- }, {
- "name": "printer_b",
- "emm": "printer_b_ref"
- } ]
- })"},
- {"metadata_v3/manufacturer_b-en.json",
- R"({
- "printers": [ {
- "name": "printer_c",
- "emm": "printer_c_ref"
- } ]
- })"},
- {"metadata_v3/index-01.json",
- R"({
- "ppdIndex": {
- "printer_a_ref": {
- "ppdMetadata": [ {
- "name": "printer_a.ppd",
- "license": "fake_license"
- } ]
- }
- }
- })"},
- {"metadata_v3/index-02.json",
- R"({
- "ppdIndex": {
- "printer_b_ref": {
- "ppdMetadata": [ {
- "name": "printer_b.ppd"
- } ]
- }
- }
- })"},
- {"metadata_v3/index-03.json",
- R"({
- "ppdIndex": {
- "printer_c_ref": {
- "ppdMetadata": [ {
- "name": "printer_c.ppd"
- } ]
- }
- }
- })"},
- {"metadata_v3/index-04.json",
- R"({
- "ppdIndex": {
- "printer_d_ref": {
- "ppdMetadata": [ {
- "name": "printer_d.ppd"
- } ]
- }
- }
- })"},
- {"metadata_v3/index-05.json",
- R"({
- "ppdIndex": {
- "printer_e_ref": {
- "ppdMetadata": [ {
- "name": "printer_e.ppd"
- } ]
- }
- }
- })"},
- {"metadata_v3/index-08.json",
- R"({
- "ppdIndex": {
- "Some canonical reference": {
- "ppdMetadata": [ {
- "name": "unused.ppd"
- } ]
- }
- }
- })"},
- {"metadata_v3/index-10.json",
- R"({
- "ppdIndex": {
- "Some other canonical reference": {
- "ppdMetadata": [ {
- "name": "unused.ppd"
- } ]
- }
- }
- })"},
- {"metadata_v3/usb-031f.json",
- R"({
- "usbIndex": {
- "1592": {
- "effectiveMakeAndModel": "Some canonical reference"
- },
- "6535": {
- "effectiveMakeAndModel": "Some other canonical reference"
- }
- }
- })"},
- {"metadata_v3/usb-03f0.json", ""},
- {"metadata_v3/usb-1234.json", ""},
- {"metadata_v3/usb_vendor_ids.json", R"({
- "entries": [ {
- "vendorId": 799,
- "vendorName": "Seven Ninety Nine LLC"
- }, {
- "vendorId": 1008,
- "vendorName": "HP"
- } ]
- })"},
- {"metadata_v3/reverse_index-en-01.json",
- R"({
- "reverseIndex": {
- "printer_a_ref": {
- "manufacturer": "manufacturer_a_en",
- "model": "printer_a"
- }
- }
- })"},
- {"metadata_v3/reverse_index-en-19.json",
- R"({
- "reverseIndex": {
- "unused effective make and model": {
- "manufacturer": "unused manufacturer",
- "model": "unused model"
- }
- }
- })"},
- {"ppds_for_metadata_v3/printer_a.ppd", kCupsFilterPpdContents},
- {"ppds_for_metadata_v3/printer_b.ppd", kCupsFilter2PpdContents},
- {"ppds_for_metadata_v3/printer_c.ppd", "c"},
- {"ppds_for_metadata_v3/printer_d.ppd", "d"},
- {"ppds_for_metadata_v3/printer_e.ppd", "e"},
- {"user_supplied_ppd_directory/user_supplied.ppd", "u"}};
- }
- // Environment for task schedulers.
- base::test::TaskEnvironment task_environment_;
- std::vector<
- std::pair<PpdProvider::CallbackResultCode, std::vector<std::string>>>
- captured_resolve_manufacturers_;
- std::vector<std::pair<PpdProvider::CallbackResultCode,
- PpdProvider::ResolvedPrintersList>>
- captured_resolve_printers_;
- struct CapturedResolvePpdResults {
- PpdProvider::CallbackResultCode code;
- std::string ppd_contents;
- };
- std::vector<CapturedResolvePpdResults> captured_resolve_ppd_;
- struct CapturedResolvePpdReferenceResults {
- PpdProvider::CallbackResultCode code;
- Printer::PpdReference ref;
- std::string usb_manufacturer;
- };
- std::vector<CapturedResolvePpdReferenceResults>
- captured_resolve_ppd_references_;
- struct CapturedReverseLookup {
- PpdProvider::CallbackResultCode code;
- std::string manufacturer;
- std::string model;
- };
- std::vector<CapturedReverseLookup> captured_reverse_lookup_;
- struct CapturedResolvePpdLicense {
- PpdProvider::CallbackResultCode code;
- std::string license;
- };
- std::vector<CapturedResolvePpdLicense> captured_resolve_ppd_license_;
- base::ScopedTempDir ppd_cache_temp_dir_;
- base::ScopedTempDir interceptor_temp_dir_;
- // Reference to the underlying ppd_cache_ so we can muck with it to test
- // cache-dependent behavior of ppd_provider_.
- scoped_refptr<PpdCache> ppd_cache_;
- PpdProviderComposedMembers provider_backdoor_;
- // Misc extra stuff needed for the test environment to function.
- base::SimpleTestClock clock_;
- };
- // Tests that PpdProvider enqueues a bounded number of calls to
- // ResolveManufacturers() and fails the oldest call when the queue is
- // deemed full (implementation-specified detail).
- TEST_F(PpdProviderTest, FailsOldestQueuedResolveManufacturers) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoNotPropagate});
- // Prevents the provider from ever getting a metadata locale.
- // We want it to stall out, forcing it to perpetually defer method
- // calls to ResolveManufacturers().
- provider_backdoor_.manager_config_cache->DiscardFetchRequestFor(
- "metadata_v3/locales.json");
- for (int i = kMethodDeferralLimitForTesting; i >= 0; i--) {
- provider->ResolveManufacturers(base::BindOnce(
- &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this)));
- }
- // The for loop above should have overflowed the deferral queue by
- // a factor of one: the oldest call to ResolveManufacturers() should
- // have been forced out and asked to fail, and we expect it to be
- // sitting on the sequence right now.
- ASSERT_EQ(1UL, task_environment_.GetPendingMainThreadTaskCount());
- task_environment_.FastForwardUntilNoTasksRemain();
- ASSERT_EQ(1UL, captured_resolve_manufacturers_.size());
- EXPECT_EQ(PpdProvider::CallbackResultCode::SERVER_ERROR,
- captured_resolve_manufacturers_[0].first);
- }
- // Tests that PpdProvider enqueues a bounded number of calls to
- // ReverseLookup() and fails the oldest call when the queue is deemed
- // full (implementation-specified detail).
- TEST_F(PpdProviderTest, FailsOldestQueuedReverseLookup) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoNotPropagate});
- // Prevents the provider from ever getting a metadata locale.
- // We want it to stall out, forcing it to perpetually defer method
- // calls to ReverseLookup().
- provider_backdoor_.manager_config_cache->DiscardFetchRequestFor(
- "metadata_v3/locales.json");
- for (int i = kMethodDeferralLimitForTesting; i >= 0; i--) {
- provider->ReverseLookup(
- "some effective-make-and-model string",
- base::BindOnce(&PpdProviderTest::CaptureReverseLookup,
- base::Unretained(this)));
- }
- // The for loop above should have overflowed the deferral queue by
- // a factor of one: the oldest call to ReverseLookup() should have
- // been forced out and asked to fail, and we expect it to be sitting
- // on the sequence right now.
- ASSERT_EQ(1UL, task_environment_.GetPendingMainThreadTaskCount());
- task_environment_.FastForwardUntilNoTasksRemain();
- ASSERT_EQ(1UL, captured_reverse_lookup_.size());
- EXPECT_EQ(PpdProvider::CallbackResultCode::SERVER_ERROR,
- captured_reverse_lookup_[0].code);
- }
- // Test that we get back manufacturer maps as expected.
- TEST_F(PpdProviderTest, ManufacturersFetch) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoNotPropagate});
- StartFakePpdServer();
- // Issue two requests at the same time, both should be resolved properly.
- provider->ResolveManufacturers(base::BindOnce(
- &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this)));
- provider->ResolveManufacturers(base::BindOnce(
- &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this)));
- task_environment_.FastForwardUntilNoTasksRemain();
- ASSERT_EQ(2UL, captured_resolve_manufacturers_.size());
- std::vector<std::string> expected_result(
- {"Manufacturer A", "Manufacturer B"});
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_manufacturers_[0].first);
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_manufacturers_[1].first);
- EXPECT_TRUE(captured_resolve_manufacturers_[0].second == expected_result);
- EXPECT_TRUE(captured_resolve_manufacturers_[1].second == expected_result);
- }
- // Test that we get a reasonable error when we have no server to contact. Tis
- // is almost exactly the same as the above test, we just don't bring up the fake
- // server first.
- TEST_F(PpdProviderTest, ManufacturersFetchNoServer) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoNotPropagate});
- // Issue two requests at the same time, both should resolve properly
- // (though they will fail).
- provider->ResolveManufacturers(base::BindOnce(
- &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this)));
- provider->ResolveManufacturers(base::BindOnce(
- &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this)));
- task_environment_.FastForwardUntilNoTasksRemain();
- ASSERT_EQ(2UL, captured_resolve_manufacturers_.size());
- EXPECT_EQ(PpdProvider::SERVER_ERROR,
- captured_resolve_manufacturers_[0].first);
- EXPECT_EQ(PpdProvider::SERVER_ERROR,
- captured_resolve_manufacturers_[1].first);
- EXPECT_TRUE(captured_resolve_manufacturers_[0].second.empty());
- EXPECT_TRUE(captured_resolve_manufacturers_[1].second.empty());
- }
- // Tests that mutiples requests for make-and-model resolution can be fulfilled
- // simultaneously.
- TEST_F(PpdProviderTest, RepeatedMakeModel) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- PrinterSearchData unrecognized_printer;
- unrecognized_printer.discovery_type = PrinterDiscoveryType::kManual;
- unrecognized_printer.make_and_model = {"Printer Printer"};
- PrinterSearchData recognized_printer;
- recognized_printer.discovery_type = PrinterDiscoveryType::kManual;
- recognized_printer.make_and_model = {"printer_a_ref"};
- PrinterSearchData mixed;
- mixed.discovery_type = PrinterDiscoveryType::kManual;
- mixed.make_and_model = {"printer_a_ref", "Printer Printer"};
- // Resolve the same thing repeatedly.
- provider->ResolvePpdReference(
- unrecognized_printer,
- base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- provider->ResolvePpdReference(
- mixed, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- provider->ResolvePpdReference(
- recognized_printer,
- base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(static_cast<size_t>(3), captured_resolve_ppd_references_.size());
- EXPECT_EQ(PpdProvider::NOT_FOUND, captured_resolve_ppd_references_[0].code);
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_references_[1].code);
- EXPECT_EQ("printer_a_ref",
- captured_resolve_ppd_references_[1].ref.effective_make_and_model);
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_references_[2].code);
- EXPECT_EQ("printer_a_ref",
- captured_resolve_ppd_references_[2].ref.effective_make_and_model);
- }
- // Test successful and unsuccessful usb resolutions.
- TEST_F(PpdProviderTest, UsbResolution) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- PrinterSearchData search_data;
- search_data.discovery_type = PrinterDiscoveryType::kUsb;
- // Should get back "Some canonical reference"
- search_data.usb_vendor_id = 0x031f;
- search_data.usb_product_id = 1592;
- provider->ResolvePpdReference(
- search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- // Should get back "Some other canonical reference"
- search_data.usb_vendor_id = 0x031f;
- search_data.usb_product_id = 6535;
- provider->ResolvePpdReference(
- search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- // Vendor id that exists, nonexistent device id, should get a NOT_FOUND.
- // In our fake serving root, the manufacturer with vendor ID 0x031f
- // (== 799) is named "Seven Ninety Nine LLC."
- search_data.usb_vendor_id = 0x031f;
- search_data.usb_product_id = 8162;
- provider->ResolvePpdReference(
- search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- // Nonexistent vendor id, should get a NOT_FOUND in the real world, but
- // the URL interceptor we're using considers all nonexistent files to
- // be effectively CONNECTION REFUSED, so we just check for non-success
- // on this one.
- search_data.usb_vendor_id = 0x1234;
- search_data.usb_product_id = 1782;
- provider->ResolvePpdReference(
- search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(captured_resolve_ppd_references_.size(), static_cast<size_t>(4));
- // ResolvePpdReference() takes place in several asynchronous steps, so
- // order is not guaranteed.
- EXPECT_THAT(
- captured_resolve_ppd_references_,
- UnorderedElementsAre(
- AllOf(Field(&CapturedResolvePpdReferenceResults::code,
- Eq(PpdProvider::SUCCESS)),
- Field(&CapturedResolvePpdReferenceResults::ref,
- Field(&Printer::PpdReference::effective_make_and_model,
- StrEq("Some canonical reference")))),
- AllOf(Field(&CapturedResolvePpdReferenceResults::code,
- Eq(PpdProvider::SUCCESS)),
- Field(&CapturedResolvePpdReferenceResults::ref,
- Field(&Printer::PpdReference::effective_make_and_model,
- StrEq("Some other canonical reference")))),
- AllOf(Field(&CapturedResolvePpdReferenceResults::code,
- Eq(PpdProvider::NOT_FOUND)),
- Field(&CapturedResolvePpdReferenceResults::usb_manufacturer,
- StrEq("Seven Ninety Nine LLC"))),
- Field(&CapturedResolvePpdReferenceResults::code,
- Eq(PpdProvider::NOT_FOUND))));
- }
- // Test basic ResolvePrinters() functionality. At the same time, make
- // sure we can get the PpdReference for each of the resolved printers.
- TEST_F(PpdProviderTest, ResolvePrinters) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- // Required setup calls to advance past PpdProvider's method deferral.
- ASSERT_TRUE(provider_backdoor_.metadata_manager->SetManufacturersForTesting(
- kDefaultManufacturersJson));
- ASSERT_TRUE(SuccessfullyResolveManufacturers(provider.get()));
- provider->ResolvePrinters(
- "Manufacturer A", base::BindOnce(&PpdProviderTest::CaptureResolvePrinters,
- base::Unretained(this)));
- provider->ResolvePrinters(
- "Manufacturer B", base::BindOnce(&PpdProviderTest::CaptureResolvePrinters,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(2UL, captured_resolve_printers_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_printers_[0].first);
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_printers_[1].first);
- EXPECT_EQ(2UL, captured_resolve_printers_[0].second.size());
- // First capture should get back printer_a, and printer_b, with ppd
- // reference effective make and models of printer_a_ref and printer_b_ref.
- const auto& capture0 = captured_resolve_printers_[0].second;
- ASSERT_EQ(2UL, capture0.size());
- EXPECT_EQ("printer_a", capture0[0].name);
- EXPECT_EQ("printer_a_ref", capture0[0].ppd_ref.effective_make_and_model);
- EXPECT_EQ("printer_b", capture0[1].name);
- EXPECT_EQ("printer_b_ref", capture0[1].ppd_ref.effective_make_and_model);
- // Second capture should get back printer_c with effective make and model of
- // printer_c_ref
- const auto& capture1 = captured_resolve_printers_[1].second;
- ASSERT_EQ(1UL, capture1.size());
- EXPECT_EQ("printer_c", capture1[0].name);
- EXPECT_EQ("printer_c_ref", capture1[0].ppd_ref.effective_make_and_model);
- }
- // Test that if we give a bad reference to ResolvePrinters(), we get a
- // SERVER_ERROR. There's currently no feedback that indicates
- // specifically to the caller that they asked for the printers of
- // a manufacturer we didn't previously advertise.
- TEST_F(PpdProviderTest, ResolvePrintersBadReference) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- // Required setup calls to advance past PpdProvider's method deferral.
- ASSERT_TRUE(provider_backdoor_.metadata_manager->SetManufacturersForTesting(
- kDefaultManufacturersJson));
- ASSERT_TRUE(SuccessfullyResolveManufacturers(provider.get()));
- provider->ResolvePrinters(
- "bogus_doesnt_exist",
- base::BindOnce(&PpdProviderTest::CaptureResolvePrinters,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(1UL, captured_resolve_printers_.size());
- EXPECT_EQ(PpdProvider::SERVER_ERROR, captured_resolve_printers_[0].first);
- }
- // Test that if the server is unavailable, we get SERVER_ERRORs back out.
- TEST_F(PpdProviderTest, ResolvePrintersNoServer) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- // Required setup calls to advance past PpdProvider's method deferral.
- ASSERT_TRUE(provider_backdoor_.metadata_manager->SetManufacturersForTesting(
- kDefaultManufacturersJson));
- ASSERT_TRUE(SuccessfullyResolveManufacturers(provider.get()));
- provider->ResolvePrinters(
- "Manufacturer A", base::BindOnce(&PpdProviderTest::CaptureResolvePrinters,
- base::Unretained(this)));
- provider->ResolvePrinters(
- "Manufacturer B", base::BindOnce(&PpdProviderTest::CaptureResolvePrinters,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(2UL, captured_resolve_printers_.size());
- EXPECT_EQ(PpdProvider::SERVER_ERROR, captured_resolve_printers_[0].first);
- EXPECT_EQ(PpdProvider::SERVER_ERROR, captured_resolve_printers_[1].first);
- }
- // Test a successful ppd resolution from an effective_make_and_model reference.
- TEST_F(PpdProviderTest, ResolveServerKeyPpd) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- Printer::PpdReference ref;
- ref.effective_make_and_model = "printer_b_ref";
- provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- ref.effective_make_and_model = "printer_c_ref";
- provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(2UL, captured_resolve_ppd_.size());
- // ResolvePpd() works in several asynchronous steps, so order of
- // return is not guaranteed.
- EXPECT_THAT(
- captured_resolve_ppd_,
- UnorderedElementsAre(
- AllOf(Field(&CapturedResolvePpdResults::code,
- PpdProvider::CallbackResultCode::SUCCESS),
- Field(&CapturedResolvePpdResults::ppd_contents,
- StrEq(kCupsFilter2PpdContents))),
- AllOf(Field(&CapturedResolvePpdResults::code,
- PpdProvider::CallbackResultCode::SUCCESS),
- Field(&CapturedResolvePpdResults::ppd_contents, StrEq("c")))));
- }
- // Test that we *don't* resolve a ppd URL over non-file schemes. It's not clear
- // whether we'll want to do this in the long term, but for now this is
- // disallowed because we're not sure we completely understand the security
- // implications.
- TEST_F(PpdProviderTest, ResolveUserSuppliedUrlPpdFromNetworkFails) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- Printer::PpdReference ref;
- // PpdProvider::ResolvePpd() shall fail if a user-supplied PPD URL
- // does not begin with the "file://" scheme.
- ref.user_supplied_ppd_url = "nonfilescheme://unused";
- provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(1UL, captured_resolve_ppd_.size());
- EXPECT_EQ(PpdProvider::INTERNAL_ERROR, captured_resolve_ppd_[0].code);
- EXPECT_TRUE(captured_resolve_ppd_[0].ppd_contents.empty());
- }
- // Test a successful ppd resolution from a user_supplied_url field when
- // reading from a file. Note we shouldn't need the server to be up
- // to do this successfully, as we should be able to do this offline.
- TEST_F(PpdProviderTest, ResolveUserSuppliedUrlPpdFromFile) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath filename = temp_dir.GetPath().Append("my_spiffy.ppd");
- std::string user_ppd_contents = "Woohoo";
- ASSERT_TRUE(base::WriteFile(filename, user_ppd_contents));
- Printer::PpdReference ref;
- ref.user_supplied_ppd_url =
- base::StringPrintf("file://%s", filename.MaybeAsASCII().c_str());
- provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(1UL, captured_resolve_ppd_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code);
- EXPECT_EQ(user_ppd_contents, captured_resolve_ppd_[0].ppd_contents);
- }
- // Test that we cache ppd resolutions when we fetch them and that we can resolve
- // from the cache without the server available.
- TEST_F(PpdProviderTest, ResolvedPpdsGetCached) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- std::string user_ppd_contents = "Woohoo";
- Printer::PpdReference ref;
- {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath filename = temp_dir.GetPath().Append("my_spiffy.ppd");
- ASSERT_TRUE(base::WriteFile(filename, user_ppd_contents));
- ref.user_supplied_ppd_url =
- base::StringPrintf("file://%s", filename.MaybeAsASCII().c_str());
- provider->ResolvePpd(ref,
- base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(1UL, captured_resolve_ppd_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code);
- EXPECT_EQ(user_ppd_contents, captured_resolve_ppd_[0].ppd_contents);
- }
- // ScopedTempDir goes out of scope, so the source file should now be
- // deleted. But if we resolve again, we should hit the cache and
- // still be successful.
- captured_resolve_ppd_.clear();
- // Recreate the provider to make sure we don't have any memory caches which
- // would mask problems with disk persistence.
- provider = CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- // Re-resolve.
- provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(1UL, captured_resolve_ppd_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code);
- EXPECT_EQ(user_ppd_contents, captured_resolve_ppd_[0].ppd_contents);
- }
- // Test that all entrypoints will correctly work with case-insensitve
- // effective-make-and-model strings.
- TEST_F(PpdProviderTest, CaseInsensitiveMakeAndModel) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- std::string ref = "pRiNteR_A_reF";
- Printer::PpdReference ppd_ref;
- ppd_ref.effective_make_and_model = ref;
- provider->ResolvePpd(ppd_ref,
- base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- provider->ReverseLookup(ref,
- base::BindOnce(&PpdProviderTest::CaptureReverseLookup,
- base::Unretained(this)));
- PrinterSearchData printer_info;
- printer_info.make_and_model = {ref};
- provider->ResolvePpdReference(
- printer_info, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- // Check PpdProvider::ResolvePpd
- ASSERT_EQ(1UL, captured_resolve_ppd_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code);
- EXPECT_EQ(kCupsFilterPpdContents, captured_resolve_ppd_[0].ppd_contents);
- // Check PpdProvider::ReverseLookup
- ASSERT_EQ(1UL, captured_reverse_lookup_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_reverse_lookup_[0].code);
- EXPECT_EQ("manufacturer_a_en", captured_reverse_lookup_[0].manufacturer);
- EXPECT_EQ("printer_a", captured_reverse_lookup_[0].model);
- // Check PpdProvider::ResolvePpdReference
- ASSERT_EQ(1UL, captured_resolve_ppd_references_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_references_[0].code);
- EXPECT_EQ("printer_a_ref",
- captured_resolve_ppd_references_[0].ref.effective_make_and_model);
- }
- // Tests that ResolvePpdLicense is able to correctly source the index and
- // determine the name of the PPD license associated with the given effecive make
- // and model (if any).
- TEST_F(PpdProviderTest, ResolvePpdLicense) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoNotPropagate});
- StartFakePpdServer();
- // For this effective_make_and_model, we expect that there is associated
- // license.
- const char kEmm1[] = "printer_a_ref";
- provider->ResolvePpdLicense(
- kEmm1, base::BindOnce(&PpdProviderTest::CaptureResolvePpdLicense,
- base::Unretained(this)));
- // We do not expect there to be any license associated with this
- // effective_make_and_model, so the response should be empty.
- const char kEmm2[] = "printer_b_ref";
- provider->ResolvePpdLicense(
- kEmm2, base::BindOnce(&PpdProviderTest::CaptureResolvePpdLicense,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(2UL, captured_resolve_ppd_license_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_license_[0].code);
- EXPECT_EQ("fake_license", captured_resolve_ppd_license_[0].license);
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_license_[1].code);
- EXPECT_EQ("", captured_resolve_ppd_license_[1].license);
- }
- // Verifies that we can extract the Manufacturer and Model selection for a
- // given effective make and model.
- TEST_F(PpdProviderTest, ReverseLookup) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- std::string ref = "printer_a_ref";
- provider->ReverseLookup(ref,
- base::BindOnce(&PpdProviderTest::CaptureReverseLookup,
- base::Unretained(this)));
- // TODO(skau): PpdProvider has a race condition that prevents running these
- // requests in parallel.
- task_environment_.RunUntilIdle();
- std::string ref_fail = "printer_does_not_exist";
- provider->ReverseLookup(ref_fail,
- base::BindOnce(&PpdProviderTest::CaptureReverseLookup,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(2U, captured_reverse_lookup_.size());
- CapturedReverseLookup success_capture = captured_reverse_lookup_[0];
- EXPECT_EQ(PpdProvider::SUCCESS, success_capture.code);
- EXPECT_EQ("manufacturer_a_en", success_capture.manufacturer);
- EXPECT_EQ("printer_a", success_capture.model);
- CapturedReverseLookup failed_capture = captured_reverse_lookup_[1];
- EXPECT_EQ(PpdProvider::NOT_FOUND, failed_capture.code);
- }
- // Verifies that we never attempt to re-download a PPD that we
- // previously retrieved from the serving root. The Chrome OS Printing
- // Team plans to keep PPDs immutable inside the serving root, so
- // PpdProvider should always prefer to retrieve a PPD from the PpdCache
- // when it's possible to do so.
- TEST_F(PpdProviderTest, PreferToResolvePpdFromPpdCacheOverServingRoot) {
- // Explicitly *not* starting a fake server.
- std::string cached_ppd_contents =
- "These cached contents are different from what's being served";
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kOnTestThread,
- PropagateLocaleToMetadataManager::kDoPropagate});
- Printer::PpdReference ref;
- ref.effective_make_and_model = "printer_a_ref";
- std::string cache_key = PpdProvider::PpdReferenceToCacheKey(ref);
- // Cache exists, and is just created, so should be fresh.
- //
- // PPD basename is taken from value specified in forward index shard
- // defined in server_contents().
- const std::string ppd_basename = "printer_a.ppd";
- ppd_cache_->StoreForTesting(PpdProvider::PpdBasenameToCacheKey(ppd_basename),
- cached_ppd_contents, base::TimeDelta());
- ppd_cache_->StoreForTesting(PpdProvider::PpdReferenceToCacheKey(ref),
- ppd_basename, base::TimeDelta());
- task_environment_.RunUntilIdle();
- provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(1UL, captured_resolve_ppd_.size());
- // Should get the cached (not served) results back, and not have hit the
- // network.
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code);
- EXPECT_EQ(cached_ppd_contents, captured_resolve_ppd_[0].ppd_contents);
- }
- // For user-provided ppds, we should always use the latest version on
- // disk if it still exists there.
- TEST_F(PpdProviderTest, UserPpdAlwaysRefreshedIfAvailable) {
- base::ScopedTempDir temp_dir;
- std::string cached_ppd_contents = "Cached Ppd Contents";
- std::string disk_ppd_contents = "Updated Ppd Contents";
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kOnTestThread,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath filename = temp_dir.GetPath().Append("my_spiffy.ppd");
- Printer::PpdReference ref;
- ref.user_supplied_ppd_url =
- base::StringPrintf("file://%s", filename.MaybeAsASCII().c_str());
- // Put cached_ppd_contents into the cache.
- ppd_cache_->StoreForTesting(PpdProvider::PpdReferenceToCacheKey(ref),
- cached_ppd_contents, base::TimeDelta());
- task_environment_.RunUntilIdle();
- // Write different contents to disk, so that the cached contents are
- // now stale.
- ASSERT_TRUE(base::WriteFile(filename, disk_ppd_contents));
- provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(1UL, captured_resolve_ppd_.size());
- EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code);
- EXPECT_EQ(disk_ppd_contents, captured_resolve_ppd_[0].ppd_contents);
- // Check that the cache was also updated with the new contents.
- PpdCache::FindResult captured_find_result;
- ppd_cache_->Find(PpdProvider::PpdReferenceToCacheKey(ref),
- base::BindOnce(
- [](PpdCache::FindResult* captured_find_result,
- const PpdCache::FindResult& find_result) {
- *captured_find_result = find_result;
- },
- &captured_find_result));
- task_environment_.RunUntilIdle();
- EXPECT_EQ(captured_find_result.success, true);
- EXPECT_EQ(captured_find_result.contents, disk_ppd_contents);
- }
- // Test resolving usb manufacturer when failed to resolve PpdReference.
- TEST_F(PpdProviderTest, ResolveUsbManufacturer) {
- auto provider =
- CreateProvider({"en", PpdCacheRunLocation::kInBackgroundThreads,
- PropagateLocaleToMetadataManager::kDoPropagate});
- StartFakePpdServer();
- PrinterSearchData search_data;
- search_data.discovery_type = PrinterDiscoveryType::kUsb;
- // Vendor id that exists, nonexistent device id, should get a NOT_FOUND.
- // Although this is an unsupported printer model, we can still expect to get
- // the manufacturer name.
- search_data.usb_vendor_id = 0x03f0;
- search_data.usb_product_id = 9999;
- provider->ResolvePpdReference(
- search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- // Nonexistent vendor id, should get a NOT_FOUND in the real world, but
- // the URL interceptor we're using considers all nonexistent files to
- // be effectively CONNECTION REFUSED, so we just check for non-success
- // on this one. We should also not be able to get a manufacturer name from a
- // nonexistent vendor id.
- search_data.usb_vendor_id = 0x1234;
- search_data.usb_product_id = 1782;
- provider->ResolvePpdReference(
- search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference,
- base::Unretained(this)));
- task_environment_.RunUntilIdle();
- ASSERT_EQ(static_cast<size_t>(2), captured_resolve_ppd_references_.size());
- // Was able to find the printer manufactuer but unable to find the printer
- // model should result in a NOT_FOUND.
- EXPECT_EQ(PpdProvider::NOT_FOUND, captured_resolve_ppd_references_[0].code);
- // Failed to grab the PPD for a USB printer, but should still be able to grab
- // its manufacturer name.
- EXPECT_EQ("HP", captured_resolve_ppd_references_[0].usb_manufacturer);
- // Unable to find the PPD file should result in a failure.
- EXPECT_FALSE(captured_resolve_ppd_references_[1].code ==
- PpdProvider::SUCCESS);
- // Unknown vendor id should result in an empty manufacturer string.
- EXPECT_TRUE(captured_resolve_ppd_references_[1].usb_manufacturer.empty());
- }
- } // namespace
- } // namespace chromeos
|