justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 1 | // Copyright 2016 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 | |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 5 | #include "chromeos/printing/ppd_provider.h" |
| 6 | |
Justin Carlson | 781f77e21 | 2017-11-15 22:32:31 | [diff] [blame] | 7 | #include <algorithm> |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 8 | #include <map> |
Ben Chan | e6cd028 | 2017-10-18 18:38:41 | [diff] [blame] | 9 | #include <memory> |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 10 | #include <utility> |
| 11 | |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 12 | #include "base/bind.h" |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 13 | #include "base/bind_helpers.h" |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 14 | #include "base/files/file_util.h" |
| 15 | #include "base/files/scoped_temp_dir.h" |
| 16 | #include "base/logging.h" |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 17 | #include "base/run_loop.h" |
| 18 | #include "base/single_thread_task_runner.h" |
| 19 | #include "base/strings/stringprintf.h" |
Gabriel Charette | b69fcd4 | 2019-08-23 02:13:29 | [diff] [blame^] | 20 | #include "base/test/scoped_task_environment.h" |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 21 | #include "base/test/test_message_loop.h" |
| 22 | #include "base/threading/sequenced_task_runner_handle.h" |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 23 | #include "base/threading/thread_task_runner_handle.h" |
Luum Habtemariam | 67e8adb82 | 2018-01-04 16:04:47 | [diff] [blame] | 24 | #include "base/version.h" |
Steven Bennetts | 38e9bde2 | 2019-01-03 17:31:10 | [diff] [blame] | 25 | #include "chromeos/constants/chromeos_paths.h" |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 26 | #include "chromeos/printing/ppd_cache.h" |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 27 | #include "chromeos/printing/printer_configuration.h" |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 28 | #include "net/base/net_errors.h" |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 29 | #include "net/url_request/url_request_test_util.h" |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 30 | #include "services/network/public/cpp/resource_request.h" |
| 31 | #include "services/network/test/test_url_loader_factory.h" |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 32 | #include "testing/gtest/include/gtest/gtest.h" |
| 33 | |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 34 | namespace chromeos { |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 35 | |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 36 | namespace { |
| 37 | |
Luum Habtemariam | 521c687 | 2019-07-11 20:12:46 | [diff] [blame] | 38 | using PrinterDiscoveryType = PrinterSearchData::PrinterDiscoveryType; |
| 39 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 40 | // Name of the fake server we're resolving ppds from. |
| 41 | const char kPpdServer[] = "bogus.google.com"; |
justincarlson | 9c860c8 | 2016-11-01 17:46:36 | [diff] [blame] | 42 | |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 43 | // A pseudo-ppd that should get cupsFilter lines extracted from it. |
| 44 | const char kCupsFilterPpdContents[] = R"( |
| 45 | Other random contents that we don't care about. |
| 46 | *cupsFilter: "application/vnd.cups-raster 0 my_filter" |
| 47 | More random contents that we don't care about |
| 48 | *cupsFilter: "application/vnd.cups-awesome 0 a_different_filter" |
| 49 | *cupsFilter: "application/vnd.cups-awesomesauce 0 filter3" |
| 50 | Yet more randome contents that we don't care about. |
| 51 | More random contents that we don't care about. |
| 52 | )"; |
| 53 | |
| 54 | // A pseudo-ppd that should get cupsFilter2 lines extracted from it. |
| 55 | // We also have cupsFilter lines in here, but since cupsFilter2 lines |
| 56 | // exist, the cupsFilter lines should be ignored. |
| 57 | const char kCupsFilter2PpdContents[] = R"( |
| 58 | Other random contents that we don't care about. |
| 59 | *cupsFilter: "application/vnd.cups-raster 0 my_filter" |
| 60 | More random contents that we don't care about |
| 61 | *cupsFilter2: "foo bar 0 the_real_filter" |
| 62 | *cupsFilter2: "bar baz 381 another_real_filter" |
| 63 | Yet more randome contents that we don't care about. |
| 64 | More random contents that we don't care about. |
| 65 | )"; |
| 66 | |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 67 | class PpdProviderTest : public ::testing::Test { |
| 68 | public: |
| 69 | PpdProviderTest() |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 70 | : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) { |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 71 | TurnOffFakePpdServer(); |
| 72 | } |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 73 | |
| 74 | void SetUp() override { |
| 75 | ASSERT_TRUE(ppd_cache_temp_dir_.CreateUniqueTempDir()); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 76 | } |
| 77 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 78 | void TearDown() override { StopFakePpdServer(); } |
| 79 | |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 80 | // Create and return a provider for a test that uses the given |locale|. If |
| 81 | // run_cache_on_test_thread is true, we'll run the cache using the |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 82 | // task_environment_; otherwise we'll let it spawn it's own background |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 83 | // threads. You should only run the cache on the test thread if you need to |
| 84 | // explicity drain cache actions independently of draining ppd provider |
| 85 | // actions; otherwise letting the cache spawn its own thread should be safe, |
| 86 | // and better exercises the code paths under test. |
| 87 | scoped_refptr<PpdProvider> CreateProvider(const std::string& locale, |
| 88 | bool run_cache_on_test_thread) { |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 89 | auto provider_options = PpdProvider::Options(); |
| 90 | provider_options.ppd_server_root = std::string("https://") + kPpdServer; |
| 91 | |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 92 | if (run_cache_on_test_thread) { |
| 93 | ppd_cache_ = PpdCache::CreateForTesting( |
| 94 | ppd_cache_temp_dir_.GetPath(), |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 95 | task_environment_.GetMainThreadTaskRunner()); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 96 | } else { |
| 97 | ppd_cache_ = PpdCache::Create(ppd_cache_temp_dir_.GetPath()); |
| 98 | } |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 99 | return PpdProvider::Create(locale, &loader_factory_, ppd_cache_, |
| 100 | base::Version("40.8.6753.09"), provider_options); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 101 | } |
| 102 | |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 103 | // Fill loader_factory_ with preset contents for test URLs |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 104 | void StartFakePpdServer() { |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 105 | loader_factory_.ClearResponses(); |
| 106 | for (const auto& entry : server_contents()) { |
| 107 | network::URLLoaderCompletionStatus status; |
| 108 | if (!entry.second.empty()) { |
| 109 | status.decoded_body_length = entry.second.size(); |
| 110 | } else { |
| 111 | status.error_code = net::ERR_ADDRESS_UNREACHABLE; |
| 112 | } |
| 113 | |
| 114 | loader_factory_.AddResponse(FileToURL(entry.first), |
| 115 | network::ResourceResponseHead(), entry.second, |
| 116 | status); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 117 | } |
| 118 | } |
| 119 | |
| 120 | // Interceptor posts a *task* during destruction that actually unregisters |
| 121 | // things. So we have to run the message loop post-interceptor-destruction to |
| 122 | // actually unregister the URLs, otherwise they won't *actually* be |
| 123 | // unregistered until the next time we invoke the message loop. Which may be |
| 124 | // in the middle of the next test. |
| 125 | // |
| 126 | // Note this is harmless to call if we haven't started a fake ppd server. |
| 127 | void StopFakePpdServer() { |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 128 | TurnOffFakePpdServer(); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 129 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 130 | } |
| 131 | |
| 132 | // Capture the result of a ResolveManufacturers() call. |
| 133 | void CaptureResolveManufacturers(PpdProvider::CallbackResultCode code, |
| 134 | const std::vector<std::string>& data) { |
| 135 | captured_resolve_manufacturers_.push_back({code, data}); |
| 136 | } |
| 137 | |
| 138 | // Capture the result of a ResolvePrinters() call. |
| 139 | void CaptureResolvePrinters(PpdProvider::CallbackResultCode code, |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 140 | const PpdProvider::ResolvedPrintersList& data) { |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 141 | captured_resolve_printers_.push_back({code, data}); |
| 142 | } |
| 143 | |
| 144 | // Capture the result of a ResolvePpd() call. |
| 145 | void CaptureResolvePpd(PpdProvider::CallbackResultCode code, |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 146 | const std::string& ppd_contents, |
| 147 | const std::vector<std::string>& ppd_filters) { |
| 148 | CapturedResolvePpdResults results; |
| 149 | results.code = code; |
| 150 | results.ppd_contents = ppd_contents; |
| 151 | results.ppd_filters = ppd_filters; |
| 152 | captured_resolve_ppd_.push_back(results); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 153 | } |
| 154 | |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 155 | // Capture the result of a ResolveUsbIds() call. |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 156 | void CaptureResolvePpdReference(PpdProvider::CallbackResultCode code, |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 157 | const Printer::PpdReference& ref, |
| 158 | const std::string& usb_manufacturer) { |
| 159 | captured_resolve_ppd_references_.push_back({code, ref, usb_manufacturer}); |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 160 | } |
| 161 | |
Sean Kau | 7f57a92 | 2017-08-01 19:00:26 | [diff] [blame] | 162 | void CaptureReverseLookup(PpdProvider::CallbackResultCode code, |
| 163 | const std::string& manufacturer, |
| 164 | const std::string& model) { |
| 165 | captured_reverse_lookup_.push_back({code, manufacturer, model}); |
| 166 | } |
| 167 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 168 | // Discard the result of a ResolvePpd() call. |
| 169 | void DiscardResolvePpd(PpdProvider::CallbackResultCode code, |
| 170 | const std::string& contents) {} |
| 171 | |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 172 | protected: |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 173 | // Run a ResolveManufacturers run from the given locale, expect to get |
| 174 | // results in expected_used_locale. |
| 175 | void RunLocalizationTest(const std::string& browser_locale, |
| 176 | const std::string& expected_used_locale) { |
| 177 | captured_resolve_manufacturers_.clear(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 178 | auto provider = CreateProvider(browser_locale, false); |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 179 | provider->ResolveManufacturers(base::BindOnce( |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 180 | &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 181 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 182 | provider = nullptr; |
| 183 | ASSERT_EQ(captured_resolve_manufacturers_.size(), 1UL); |
| 184 | EXPECT_EQ(captured_resolve_manufacturers_[0].first, PpdProvider::SUCCESS); |
| 185 | |
| 186 | const auto& result_vec = captured_resolve_manufacturers_[0].second; |
| 187 | |
| 188 | // It's sufficient to check for one of the expected locale keys to make sure |
| 189 | // we got the right map. |
Jan Wilken Dörrie | db2c3ef | 2019-06-08 08:45:32 | [diff] [blame] | 190 | EXPECT_TRUE( |
| 191 | base::Contains(result_vec, "manufacturer_a_" + expected_used_locale)); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 192 | } |
| 193 | |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 194 | // Fake server being down, return ERR_ADDRESS_UNREACHABLE for all endpoints |
| 195 | void TurnOffFakePpdServer() { |
| 196 | loader_factory_.ClearResponses(); |
| 197 | network::URLLoaderCompletionStatus status(net::ERR_ADDRESS_UNREACHABLE); |
| 198 | for (const auto& entry : server_contents()) { |
| 199 | loader_factory_.AddResponse(FileToURL(entry.first), |
| 200 | network::ResourceResponseHead(), "", status); |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | GURL FileToURL(std::string filename) { |
| 205 | return GURL( |
| 206 | base::StringPrintf("https://%s/%s", kPpdServer, filename.c_str())); |
| 207 | } |
| 208 | |
| 209 | // List of relevant endpoint for this FakeServer |
| 210 | std::vector<std::pair<std::string, std::string>> server_contents() const { |
| 211 | // Use brace initialization to express the desired server contents as "url", |
| 212 | // "contents" pairs. |
| 213 | return {{"metadata_v2/locales.json", |
| 214 | R"(["en", |
| 215 | "es-mx", |
| 216 | "en-gb"])"}, |
| 217 | {"metadata_v2/index-01.json", |
| 218 | R"([ |
| 219 | ["printer_a_ref", "printer_a.ppd"] |
| 220 | ])"}, |
| 221 | {"metadata_v2/index-02.json", |
| 222 | R"([ |
| 223 | ["printer_b_ref", "printer_b.ppd"] |
| 224 | ])"}, |
| 225 | {"metadata_v2/index-03.json", |
| 226 | R"([ |
| 227 | ["printer_c_ref", "printer_c.ppd"] |
| 228 | ])"}, |
| 229 | {"metadata_v2/index-04.json", |
| 230 | R"([ |
| 231 | ["printer_d_ref", "printer_d.ppd"] |
| 232 | ])"}, |
| 233 | {"metadata_v2/index-05.json", |
| 234 | R"([ |
| 235 | ["printer_e_ref", "printer_e.ppd"] |
| 236 | ])"}, |
| 237 | {"metadata_v2/index-13.json", |
| 238 | R"([ |
| 239 | ])"}, |
| 240 | {"metadata_v2/usb-031f.json", |
| 241 | R"([ |
| 242 | [1592, "Some canonical reference"], |
| 243 | [6535, "Some other canonical reference"] |
| 244 | ])"}, |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 245 | {"metadata_v2/usb-03f0.json", ""}, |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 246 | {"metadata_v2/usb-1234.json", ""}, |
| 247 | {"metadata_v2/manufacturers-en.json", |
| 248 | R"([ |
| 249 | ["manufacturer_a_en", "manufacturer_a.json"], |
| 250 | ["manufacturer_b_en", "manufacturer_b.json"] |
| 251 | ])"}, |
| 252 | {"metadata_v2/manufacturers-en-gb.json", |
| 253 | R"([ |
| 254 | ["manufacturer_a_en-gb", "manufacturer_a.json"], |
| 255 | ["manufacturer_b_en-gb", "manufacturer_b.json"] |
| 256 | ])"}, |
| 257 | {"metadata_v2/manufacturers-es-mx.json", |
| 258 | R"([ |
| 259 | ["manufacturer_a_es-mx", "manufacturer_a.json"], |
| 260 | ["manufacturer_b_es-mx", "manufacturer_b.json"] |
| 261 | ])"}, |
| 262 | {"metadata_v2/manufacturer_a.json", |
| 263 | R"([ |
| 264 | ["printer_a", "printer_a_ref"], |
| 265 | ["printer_b", "printer_b_ref"], |
| 266 | ["printer_d", "printer_d_ref"] |
| 267 | ])"}, |
| 268 | {"metadata_v2/manufacturer_a.json", |
| 269 | R"([ |
| 270 | ["printer_a", "printer_a_ref", |
| 271 | {"min_milestone":25.0000}], |
| 272 | ["printer_b", "printer_b_ref", |
| 273 | {"min_milestone":30.0000, "max_milestone":45.0000}], |
| 274 | ["printer_d", "printer_d_ref", |
| 275 | {"min_milestone":60.0000, "max_milestone":75.0000}] |
| 276 | ])"}, |
| 277 | {"metadata_v2/manufacturer_b.json", |
| 278 | R"([ |
| 279 | ["printer_c", "printer_c_ref"], |
| 280 | ["printer_e", "printer_e_ref"] |
| 281 | ])"}, |
| 282 | {"metadata_v2/reverse_index-en-01.json", |
| 283 | R"([ |
| 284 | ["printer_a_ref", "manufacturer_a_en", "printer_a"] |
| 285 | ])"}, |
| 286 | {"metadata_v2/reverse_index-en-19.json", |
| 287 | R"([ |
| 288 | ])"}, |
| 289 | {"metadata_v2/manufacturer_b.json", |
| 290 | R"([ |
| 291 | ["printer_c", "printer_c_ref", |
| 292 | {"max_milestone":55.0000}], |
| 293 | ["printer_e", "printer_e_ref", |
| 294 | {"min_milestone":17.0000, "max_milestone":33.0000}] |
| 295 | ])"}, |
| 296 | {"ppds/printer_a.ppd", kCupsFilterPpdContents}, |
| 297 | {"ppds/printer_b.ppd", kCupsFilter2PpdContents}, |
| 298 | {"ppds/printer_c.ppd", "c"}, |
| 299 | {"ppds/printer_d.ppd", "d"}, |
| 300 | {"ppds/printer_e.ppd", "e"}, |
| 301 | {"user_supplied_ppd_directory/user_supplied.ppd", "u"}}; |
| 302 | } |
| 303 | |
skau | 4fb6e69 | 2017-06-20 21:27:52 | [diff] [blame] | 304 | // Environment for task schedulers. |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 305 | base::test::TaskEnvironment task_environment_; |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 306 | |
| 307 | std::vector< |
| 308 | std::pair<PpdProvider::CallbackResultCode, std::vector<std::string>>> |
| 309 | captured_resolve_manufacturers_; |
| 310 | |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 311 | std::vector<std::pair<PpdProvider::CallbackResultCode, |
| 312 | PpdProvider::ResolvedPrintersList>> |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 313 | captured_resolve_printers_; |
| 314 | |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 315 | struct CapturedResolvePpdResults { |
| 316 | PpdProvider::CallbackResultCode code; |
| 317 | std::string ppd_contents; |
| 318 | std::vector<std::string> ppd_filters; |
| 319 | }; |
| 320 | std::vector<CapturedResolvePpdResults> captured_resolve_ppd_; |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 321 | |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 322 | struct CapturedResolvePpdReferenceResults { |
| 323 | PpdProvider::CallbackResultCode code; |
| 324 | Printer::PpdReference ref; |
| 325 | std::string usb_manufacturer; |
| 326 | }; |
| 327 | |
| 328 | std::vector<CapturedResolvePpdReferenceResults> |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 329 | captured_resolve_ppd_references_; |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 330 | |
Sean Kau | 7f57a92 | 2017-08-01 19:00:26 | [diff] [blame] | 331 | struct CapturedReverseLookup { |
| 332 | PpdProvider::CallbackResultCode code; |
| 333 | std::string manufacturer; |
| 334 | std::string model; |
| 335 | }; |
| 336 | std::vector<CapturedReverseLookup> captured_reverse_lookup_; |
| 337 | |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 338 | base::ScopedTempDir ppd_cache_temp_dir_; |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 339 | base::ScopedTempDir interceptor_temp_dir_; |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 340 | |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 341 | // Reference to the underlying ppd_cache_ so we can muck with it to test |
| 342 | // cache-dependent behavior of ppd_provider_. |
| 343 | scoped_refptr<PpdCache> ppd_cache_; |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 344 | |
| 345 | // Misc extra stuff needed for the test environment to function. |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 346 | // base::TestMessageLoop loop_; |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 347 | network::TestURLLoaderFactory loader_factory_; |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 348 | }; |
| 349 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 350 | // Test that we get back manufacturer maps as expected. |
| 351 | TEST_F(PpdProviderTest, ManufacturersFetch) { |
| 352 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 353 | auto provider = CreateProvider("en", false); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 354 | // Issue two requests at the same time, both should be resolved properly. |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 355 | provider->ResolveManufacturers(base::BindOnce( |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 356 | &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this))); |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 357 | provider->ResolveManufacturers(base::BindOnce( |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 358 | &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 359 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 360 | ASSERT_EQ(2UL, captured_resolve_manufacturers_.size()); |
| 361 | std::vector<std::string> expected_result( |
| 362 | {"manufacturer_a_en", "manufacturer_b_en"}); |
| 363 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_manufacturers_[0].first); |
| 364 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_manufacturers_[1].first); |
| 365 | EXPECT_TRUE(captured_resolve_manufacturers_[0].second == expected_result); |
| 366 | EXPECT_TRUE(captured_resolve_manufacturers_[1].second == expected_result); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 367 | } |
| 368 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 369 | // Test that we get a reasonable error when we have no server to contact. Tis |
| 370 | // is almost exactly the same as the above test, we just don't bring up the fake |
| 371 | // server first. |
| 372 | TEST_F(PpdProviderTest, ManufacturersFetchNoServer) { |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 373 | auto provider = CreateProvider("en", false); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 374 | // Issue two requests at the same time, both should be resolved properly. |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 375 | provider->ResolveManufacturers(base::BindOnce( |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 376 | &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this))); |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 377 | provider->ResolveManufacturers(base::BindOnce( |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 378 | &PpdProviderTest::CaptureResolveManufacturers, base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 379 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 380 | ASSERT_EQ(2UL, captured_resolve_manufacturers_.size()); |
| 381 | EXPECT_EQ(PpdProvider::SERVER_ERROR, |
| 382 | captured_resolve_manufacturers_[0].first); |
| 383 | EXPECT_EQ(PpdProvider::SERVER_ERROR, |
| 384 | captured_resolve_manufacturers_[1].first); |
| 385 | EXPECT_TRUE(captured_resolve_manufacturers_[0].second.empty()); |
| 386 | EXPECT_TRUE(captured_resolve_manufacturers_[1].second.empty()); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 387 | } |
| 388 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 389 | // Test that we get things in the requested locale, and that fallbacks are sane. |
| 390 | TEST_F(PpdProviderTest, LocalizationAndFallbacks) { |
| 391 | StartFakePpdServer(); |
| 392 | RunLocalizationTest("en-gb", "en-gb"); |
| 393 | RunLocalizationTest("en-blah", "en"); |
| 394 | RunLocalizationTest("en-gb-foo", "en-gb"); |
| 395 | RunLocalizationTest("es", "es-mx"); |
| 396 | RunLocalizationTest("bogus", "en"); |
| 397 | } |
| 398 | |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 399 | // Tests that mutiples requests for make-and-model resolution can be fulfilled |
| 400 | // simultaneously. |
| 401 | TEST_F(PpdProviderTest, RepeatedMakeModel) { |
| 402 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 403 | auto provider = CreateProvider("en", false); |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 404 | |
Luum Habtemariam | 2cbe835 | 2019-01-25 20:57:52 | [diff] [blame] | 405 | PrinterSearchData unrecognized_printer; |
Luum Habtemariam | 521c687 | 2019-07-11 20:12:46 | [diff] [blame] | 406 | unrecognized_printer.discovery_type = PrinterDiscoveryType::kManual; |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 407 | unrecognized_printer.make_and_model = {"Printer Printer"}; |
| 408 | |
Luum Habtemariam | 2cbe835 | 2019-01-25 20:57:52 | [diff] [blame] | 409 | PrinterSearchData recognized_printer; |
Luum Habtemariam | 521c687 | 2019-07-11 20:12:46 | [diff] [blame] | 410 | recognized_printer.discovery_type = PrinterDiscoveryType::kManual; |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 411 | recognized_printer.make_and_model = {"printer_a_ref"}; |
| 412 | |
Luum Habtemariam | 2cbe835 | 2019-01-25 20:57:52 | [diff] [blame] | 413 | PrinterSearchData mixed; |
Luum Habtemariam | 521c687 | 2019-07-11 20:12:46 | [diff] [blame] | 414 | mixed.discovery_type = PrinterDiscoveryType::kManual; |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 415 | mixed.make_and_model = {"printer_a_ref", "Printer Printer"}; |
| 416 | |
| 417 | // Resolve the same thing repeatedly. |
| 418 | provider->ResolvePpdReference( |
| 419 | unrecognized_printer, |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 420 | base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 421 | base::Unretained(this))); |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 422 | provider->ResolvePpdReference( |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 423 | mixed, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 424 | base::Unretained(this))); |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 425 | provider->ResolvePpdReference( |
| 426 | recognized_printer, |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 427 | base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 428 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 429 | task_environment_.RunUntilIdle(); |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 430 | |
| 431 | ASSERT_EQ(static_cast<size_t>(3), captured_resolve_ppd_references_.size()); |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 432 | EXPECT_EQ(PpdProvider::NOT_FOUND, captured_resolve_ppd_references_[0].code); |
| 433 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_references_[1].code); |
| 434 | EXPECT_EQ("printer_a_ref", |
| 435 | captured_resolve_ppd_references_[1].ref.effective_make_and_model); |
| 436 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_references_[2].code); |
| 437 | EXPECT_EQ("printer_a_ref", |
| 438 | captured_resolve_ppd_references_[2].ref.effective_make_and_model); |
Sean Kau | 698756b | 2017-08-24 20:01:18 | [diff] [blame] | 439 | } |
| 440 | |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 441 | // Test successful and unsuccessful usb resolutions. |
| 442 | TEST_F(PpdProviderTest, UsbResolution) { |
| 443 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 444 | auto provider = CreateProvider("en", false); |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 445 | |
Luum Habtemariam | 2cbe835 | 2019-01-25 20:57:52 | [diff] [blame] | 446 | PrinterSearchData search_data; |
Luum Habtemariam | 521c687 | 2019-07-11 20:12:46 | [diff] [blame] | 447 | search_data.discovery_type = PrinterDiscoveryType::kUsb; |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 448 | |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 449 | // Should get back "Some canonical reference" |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 450 | search_data.usb_vendor_id = 0x031f; |
| 451 | search_data.usb_product_id = 1592; |
| 452 | provider->ResolvePpdReference( |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 453 | search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 454 | base::Unretained(this))); |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 455 | // Should get back "Some other canonical reference" |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 456 | search_data.usb_vendor_id = 0x031f; |
| 457 | search_data.usb_product_id = 6535; |
| 458 | provider->ResolvePpdReference( |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 459 | search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 460 | base::Unretained(this))); |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 461 | |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 462 | // Vendor id that exists, nonexistent device id, should get a NOT_FOUND. |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 463 | search_data.usb_vendor_id = 0x031f; |
| 464 | search_data.usb_product_id = 8162; |
| 465 | provider->ResolvePpdReference( |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 466 | search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 467 | base::Unretained(this))); |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 468 | |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 469 | // Nonexistent vendor id, should get a NOT_FOUND in the real world, but |
| 470 | // the URL interceptor we're using considers all nonexistent files to |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 471 | // be effectively CONNECTION REFUSED, so we just check for non-success |
| 472 | // on this one. |
Luum Habtemariam | b30c811 | 2018-06-25 21:51:22 | [diff] [blame] | 473 | search_data.usb_vendor_id = 0x1234; |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 474 | search_data.usb_product_id = 1782; |
| 475 | provider->ResolvePpdReference( |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 476 | search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 477 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 478 | task_environment_.RunUntilIdle(); |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 479 | |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 480 | ASSERT_EQ(captured_resolve_ppd_references_.size(), static_cast<size_t>(4)); |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 481 | EXPECT_EQ(captured_resolve_ppd_references_[0].code, PpdProvider::SUCCESS); |
| 482 | EXPECT_EQ(captured_resolve_ppd_references_[0].ref.effective_make_and_model, |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 483 | "Some canonical reference"); |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 484 | EXPECT_EQ(captured_resolve_ppd_references_[1].code, PpdProvider::SUCCESS); |
| 485 | EXPECT_EQ(captured_resolve_ppd_references_[1].ref.effective_make_and_model, |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 486 | "Some other canonical reference"); |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 487 | EXPECT_EQ(captured_resolve_ppd_references_[2].code, PpdProvider::NOT_FOUND); |
| 488 | EXPECT_FALSE(captured_resolve_ppd_references_[3].code == |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 489 | PpdProvider::SUCCESS); |
justincarlson | 9d5b7af | 2017-02-14 23:04:49 | [diff] [blame] | 490 | } |
| 491 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 492 | // For convenience a null ResolveManufacturers callback target. |
| 493 | void ResolveManufacturersNop(PpdProvider::CallbackResultCode code, |
| 494 | const std::vector<std::string>& v) {} |
| 495 | |
| 496 | // Test basic ResolvePrinters() functionality. At the same time, make |
| 497 | // sure we can get the PpdReference for each of the resolved printers. |
| 498 | TEST_F(PpdProviderTest, ResolvePrinters) { |
| 499 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 500 | auto provider = CreateProvider("en", false); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 501 | |
| 502 | // Grab the manufacturer list, but don't bother to save it, we know what |
| 503 | // should be in it and we check that elsewhere. We just need to run the |
| 504 | // resolve to populate the internal PpdProvider structures. |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 505 | provider->ResolveManufacturers(base::BindOnce(&ResolveManufacturersNop)); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 506 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 507 | |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 508 | provider->ResolvePrinters( |
| 509 | "manufacturer_a_en", |
| 510 | base::BindOnce(&PpdProviderTest::CaptureResolvePrinters, |
| 511 | base::Unretained(this))); |
| 512 | provider->ResolvePrinters( |
| 513 | "manufacturer_b_en", |
| 514 | base::BindOnce(&PpdProviderTest::CaptureResolvePrinters, |
| 515 | base::Unretained(this))); |
Luum Habtemariam | 67e8adb82 | 2018-01-04 16:04:47 | [diff] [blame] | 516 | |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 517 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 518 | ASSERT_EQ(2UL, captured_resolve_printers_.size()); |
| 519 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_printers_[0].first); |
| 520 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_printers_[1].first); |
| 521 | EXPECT_EQ(2UL, captured_resolve_printers_[0].second.size()); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 522 | |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 523 | // First capture should get back printer_a, and printer_b, with ppd |
| 524 | // reference effective make and models of printer_a_ref and printer_b_ref. |
| 525 | const auto& capture0 = captured_resolve_printers_[0].second; |
| 526 | ASSERT_EQ(2UL, capture0.size()); |
Luum Habtemariam | 67e8adb82 | 2018-01-04 16:04:47 | [diff] [blame] | 527 | EXPECT_EQ("printer_a", capture0[0].name); |
| 528 | EXPECT_EQ("printer_a_ref", capture0[0].ppd_ref.effective_make_and_model); |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 529 | |
Luum Habtemariam | 67e8adb82 | 2018-01-04 16:04:47 | [diff] [blame] | 530 | EXPECT_EQ("printer_b", capture0[1].name); |
| 531 | EXPECT_EQ("printer_b_ref", capture0[1].ppd_ref.effective_make_and_model); |
Justin Carlson | 97bf1add | 2017-07-21 18:31:14 | [diff] [blame] | 532 | |
| 533 | // Second capture should get back printer_c with effective make and model of |
| 534 | // printer_c_ref |
| 535 | const auto& capture1 = captured_resolve_printers_[1].second; |
| 536 | ASSERT_EQ(1UL, capture1.size()); |
Luum Habtemariam | 67e8adb82 | 2018-01-04 16:04:47 | [diff] [blame] | 537 | EXPECT_EQ("printer_c", capture1[0].name); |
| 538 | EXPECT_EQ("printer_c_ref", capture1[0].ppd_ref.effective_make_and_model); |
| 539 | // EXPECT_EQ(base::Version("55"), capture1[0].restrictions.max_milestone); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 540 | } |
| 541 | |
| 542 | // Test that if we give a bad reference to ResolvePrinters(), we get an |
| 543 | // INTERNAL_ERROR. |
| 544 | TEST_F(PpdProviderTest, ResolvePrintersBadReference) { |
| 545 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 546 | auto provider = CreateProvider("en", false); |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 547 | provider->ResolveManufacturers(base::BindOnce(&ResolveManufacturersNop)); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 548 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 549 | |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 550 | provider->ResolvePrinters( |
| 551 | "bogus_doesnt_exist", |
| 552 | base::BindOnce(&PpdProviderTest::CaptureResolvePrinters, |
| 553 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 554 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 555 | ASSERT_EQ(1UL, captured_resolve_printers_.size()); |
| 556 | EXPECT_EQ(PpdProvider::INTERNAL_ERROR, captured_resolve_printers_[0].first); |
| 557 | } |
| 558 | |
| 559 | // Test that if the server is unavailable, we get SERVER_ERRORs back out. |
| 560 | TEST_F(PpdProviderTest, ResolvePrintersNoServer) { |
| 561 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 562 | auto provider = CreateProvider("en", false); |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 563 | provider->ResolveManufacturers(base::BindOnce(&ResolveManufacturersNop)); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 564 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 565 | |
| 566 | StopFakePpdServer(); |
| 567 | |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 568 | provider->ResolvePrinters( |
| 569 | "manufacturer_a_en", |
| 570 | base::BindOnce(&PpdProviderTest::CaptureResolvePrinters, |
| 571 | base::Unretained(this))); |
| 572 | provider->ResolvePrinters( |
| 573 | "manufacturer_b_en", |
| 574 | base::BindOnce(&PpdProviderTest::CaptureResolvePrinters, |
| 575 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 576 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 577 | ASSERT_EQ(2UL, captured_resolve_printers_.size()); |
| 578 | EXPECT_EQ(PpdProvider::SERVER_ERROR, captured_resolve_printers_[0].first); |
| 579 | EXPECT_EQ(PpdProvider::SERVER_ERROR, captured_resolve_printers_[1].first); |
| 580 | } |
| 581 | |
| 582 | // Test a successful ppd resolution from an effective_make_and_model reference. |
| 583 | TEST_F(PpdProviderTest, ResolveServerKeyPpd) { |
| 584 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 585 | auto provider = CreateProvider("en", false); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 586 | Printer::PpdReference ref; |
| 587 | ref.effective_make_and_model = "printer_b_ref"; |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 588 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 589 | base::Unretained(this))); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 590 | ref.effective_make_and_model = "printer_c_ref"; |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 591 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 592 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 593 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 594 | |
| 595 | ASSERT_EQ(2UL, captured_resolve_ppd_.size()); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 596 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 597 | EXPECT_EQ(kCupsFilter2PpdContents, captured_resolve_ppd_[0].ppd_contents); |
| 598 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[1].code); |
| 599 | EXPECT_EQ("c", captured_resolve_ppd_[1].ppd_contents); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 600 | } |
| 601 | |
| 602 | // Test that we *don't* resolve a ppd URL over non-file schemes. It's not clear |
| 603 | // whether we'll want to do this in the long term, but for now this is |
| 604 | // disallowed because we're not sure we completely understand the security |
| 605 | // implications. |
| 606 | TEST_F(PpdProviderTest, ResolveUserSuppliedUrlPpdFromNetworkFails) { |
| 607 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 608 | auto provider = CreateProvider("en", false); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 609 | |
| 610 | Printer::PpdReference ref; |
| 611 | ref.user_supplied_ppd_url = base::StringPrintf( |
| 612 | "https://%s/user_supplied_ppd_directory/user_supplied.ppd", kPpdServer); |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 613 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 614 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 615 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 616 | |
| 617 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 618 | EXPECT_EQ(PpdProvider::INTERNAL_ERROR, captured_resolve_ppd_[0].code); |
| 619 | EXPECT_TRUE(captured_resolve_ppd_[0].ppd_contents.empty()); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 620 | } |
| 621 | |
| 622 | // Test a successful ppd resolution from a user_supplied_url field when |
| 623 | // reading from a file. Note we shouldn't need the server to be up |
| 624 | // to do this successfully, as we should be able to do this offline. |
| 625 | TEST_F(PpdProviderTest, ResolveUserSuppliedUrlPpdFromFile) { |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 626 | auto provider = CreateProvider("en", false); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 627 | base::ScopedTempDir temp_dir; |
justincarlson | 9c860c8 | 2016-11-01 17:46:36 | [diff] [blame] | 628 | ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 629 | base::FilePath filename = temp_dir.GetPath().Append("my_spiffy.ppd"); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 630 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 631 | std::string user_ppd_contents = "Woohoo"; |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 632 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 633 | ASSERT_EQ(base::WriteFile(filename, user_ppd_contents.data(), |
| 634 | user_ppd_contents.size()), |
| 635 | static_cast<int>(user_ppd_contents.size())); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 636 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 637 | Printer::PpdReference ref; |
| 638 | ref.user_supplied_ppd_url = |
| 639 | base::StringPrintf("file://%s", filename.MaybeAsASCII().c_str()); |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 640 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 641 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 642 | task_environment_.RunUntilIdle(); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 643 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 644 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 645 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 646 | EXPECT_EQ(user_ppd_contents, captured_resolve_ppd_[0].ppd_contents); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 647 | } |
| 648 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 649 | // Test that we cache ppd resolutions when we fetch them and that we can resolve |
| 650 | // from the cache without the server available. |
| 651 | TEST_F(PpdProviderTest, ResolvedPpdsGetCached) { |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 652 | auto provider = CreateProvider("en", false); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 653 | std::string user_ppd_contents = "Woohoo"; |
| 654 | Printer::PpdReference ref; |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 655 | { |
| 656 | base::ScopedTempDir temp_dir; |
justincarlson | 9c860c8 | 2016-11-01 17:46:36 | [diff] [blame] | 657 | ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 658 | base::FilePath filename = temp_dir.GetPath().Append("my_spiffy.ppd"); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 659 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 660 | ASSERT_EQ(base::WriteFile(filename, user_ppd_contents.data(), |
| 661 | user_ppd_contents.size()), |
| 662 | static_cast<int>(user_ppd_contents.size())); |
| 663 | |
| 664 | ref.user_supplied_ppd_url = |
| 665 | base::StringPrintf("file://%s", filename.MaybeAsASCII().c_str()); |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 666 | provider->ResolvePpd(ref, |
| 667 | base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 668 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 669 | task_environment_.RunUntilIdle(); |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 670 | |
| 671 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 672 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 673 | EXPECT_EQ(user_ppd_contents, captured_resolve_ppd_[0].ppd_contents); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 674 | } |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 675 | // ScopedTempDir goes out of scope, so the source file should now be |
| 676 | // deleted. But if we resolve again, we should hit the cache and |
| 677 | // still be successful. |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 678 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 679 | captured_resolve_ppd_.clear(); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 680 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 681 | // Recreate the provider to make sure we don't have any memory caches which |
| 682 | // would mask problems with disk persistence. |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 683 | provider = CreateProvider("en", false); |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 684 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 685 | // Re-resolve. |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 686 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 687 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 688 | task_environment_.RunUntilIdle(); |
justincarlson | 9c860c8 | 2016-11-01 17:46:36 | [diff] [blame] | 689 | |
justincarlson | 2fc4d82b | 2017-02-03 22:49:47 | [diff] [blame] | 690 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 691 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 692 | EXPECT_EQ(user_ppd_contents, captured_resolve_ppd_[0].ppd_contents); |
| 693 | } |
| 694 | |
| 695 | // Test that the filter extraction code successfully pulls the filters |
| 696 | // from the ppds resolved. |
| 697 | TEST_F(PpdProviderTest, ExtractPpdFilters) { |
| 698 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 699 | auto provider = CreateProvider("en", false); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 700 | Printer::PpdReference ref; |
| 701 | ref.effective_make_and_model = "printer_a_ref"; |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 702 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 703 | base::Unretained(this))); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 704 | ref.effective_make_and_model = "printer_b_ref"; |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 705 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 706 | base::Unretained(this))); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 707 | |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 708 | task_environment_.RunUntilIdle(); |
Justin Carlson | 781f77e21 | 2017-11-15 22:32:31 | [diff] [blame] | 709 | |
| 710 | std::sort(captured_resolve_ppd_[0].ppd_filters.begin(), |
| 711 | captured_resolve_ppd_[0].ppd_filters.end()); |
Luum Habtemariam | 8f4a22c | 2018-04-14 10:09:41 | [diff] [blame] | 712 | ASSERT_EQ(2UL, captured_resolve_ppd_.size()); |
| 713 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 714 | EXPECT_EQ(kCupsFilterPpdContents, captured_resolve_ppd_[0].ppd_contents); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 715 | EXPECT_EQ( |
| 716 | std::vector<std::string>({"a_different_filter", "filter3", "my_filter"}), |
| 717 | captured_resolve_ppd_[0].ppd_filters); |
| 718 | |
Justin Carlson | 781f77e21 | 2017-11-15 22:32:31 | [diff] [blame] | 719 | std::sort(captured_resolve_ppd_[1].ppd_filters.begin(), |
| 720 | captured_resolve_ppd_[1].ppd_filters.end()); |
justincarlson | 96bf4bd8 | 2017-04-12 19:14:46 | [diff] [blame] | 721 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[1].code); |
| 722 | EXPECT_EQ(kCupsFilter2PpdContents, captured_resolve_ppd_[1].ppd_contents); |
| 723 | EXPECT_EQ( |
| 724 | std::vector<std::string>({"another_real_filter", "the_real_filter"}), |
| 725 | captured_resolve_ppd_[1].ppd_filters); |
justincarlson | 9c860c8 | 2016-11-01 17:46:36 | [diff] [blame] | 726 | } |
| 727 | |
Luum Habtemariam | 8f4a22c | 2018-04-14 10:09:41 | [diff] [blame] | 728 | // Test that all entrypoints will correctly work with case-insensitve |
| 729 | // effective-make-and-model strings. |
| 730 | TEST_F(PpdProviderTest, CaseInsensitiveMakeAndModel) { |
| 731 | StartFakePpdServer(); |
| 732 | auto provider = CreateProvider("en", false); |
| 733 | std::string ref = "pRiNteR_A_reF"; |
| 734 | |
| 735 | Printer::PpdReference ppd_ref; |
| 736 | ppd_ref.effective_make_and_model = ref; |
| 737 | provider->ResolvePpd(ppd_ref, |
| 738 | base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 739 | base::Unretained(this))); |
| 740 | provider->ReverseLookup(ref, |
| 741 | base::BindOnce(&PpdProviderTest::CaptureReverseLookup, |
| 742 | base::Unretained(this))); |
Luum Habtemariam | 2cbe835 | 2019-01-25 20:57:52 | [diff] [blame] | 743 | PrinterSearchData printer_info; |
Luum Habtemariam | 8f4a22c | 2018-04-14 10:09:41 | [diff] [blame] | 744 | printer_info.make_and_model = {ref}; |
| 745 | provider->ResolvePpdReference( |
| 746 | printer_info, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 747 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 748 | task_environment_.RunUntilIdle(); |
Luum Habtemariam | 8f4a22c | 2018-04-14 10:09:41 | [diff] [blame] | 749 | |
| 750 | std::sort(captured_resolve_ppd_[0].ppd_filters.begin(), |
| 751 | captured_resolve_ppd_[0].ppd_filters.end()); |
| 752 | |
| 753 | // Check PpdProvider::ResolvePpd |
| 754 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
| 755 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 756 | EXPECT_EQ(kCupsFilterPpdContents, captured_resolve_ppd_[0].ppd_contents); |
| 757 | |
| 758 | // Check PpdProvider::ReverseLookup |
| 759 | ASSERT_EQ(1UL, captured_reverse_lookup_.size()); |
| 760 | EXPECT_EQ(PpdProvider::SUCCESS, captured_reverse_lookup_[0].code); |
| 761 | EXPECT_EQ("manufacturer_a_en", captured_reverse_lookup_[0].manufacturer); |
| 762 | EXPECT_EQ("printer_a", captured_reverse_lookup_[0].model); |
| 763 | |
| 764 | // Check PpdProvider::ResolvePpdReference |
| 765 | ASSERT_EQ(1UL, captured_resolve_ppd_references_.size()); |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 766 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_references_[0].code); |
| 767 | EXPECT_EQ("printer_a_ref", |
| 768 | captured_resolve_ppd_references_[0].ref.effective_make_and_model); |
Luum Habtemariam | 8f4a22c | 2018-04-14 10:09:41 | [diff] [blame] | 769 | } |
| 770 | |
Sean Kau | 7f57a92 | 2017-08-01 19:00:26 | [diff] [blame] | 771 | // Verifies that we can extract the Manufacturer and Model selectison for a |
| 772 | // given effective make and model. |
| 773 | TEST_F(PpdProviderTest, ReverseLookup) { |
| 774 | StartFakePpdServer(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 775 | auto provider = CreateProvider("en", false); |
Sean Kau | 7f57a92 | 2017-08-01 19:00:26 | [diff] [blame] | 776 | std::string ref = "printer_a_ref"; |
| 777 | provider->ReverseLookup(ref, |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 778 | base::BindOnce(&PpdProviderTest::CaptureReverseLookup, |
| 779 | base::Unretained(this))); |
Sean Kau | 7f57a92 | 2017-08-01 19:00:26 | [diff] [blame] | 780 | // TODO(skau): PpdProvider has a race condition that prevents running these |
| 781 | // requests in parallel. |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 782 | task_environment_.RunUntilIdle(); |
Sean Kau | 7f57a92 | 2017-08-01 19:00:26 | [diff] [blame] | 783 | |
| 784 | std::string ref_fail = "printer_does_not_exist"; |
| 785 | provider->ReverseLookup(ref_fail, |
Luum Habtemariam | 0517d81 | 2018-01-26 17:56:05 | [diff] [blame] | 786 | base::BindOnce(&PpdProviderTest::CaptureReverseLookup, |
| 787 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 788 | task_environment_.RunUntilIdle(); |
Sean Kau | 7f57a92 | 2017-08-01 19:00:26 | [diff] [blame] | 789 | |
| 790 | ASSERT_EQ(2U, captured_reverse_lookup_.size()); |
| 791 | CapturedReverseLookup success_capture = captured_reverse_lookup_[0]; |
| 792 | EXPECT_EQ(PpdProvider::SUCCESS, success_capture.code); |
| 793 | EXPECT_EQ("manufacturer_a_en", success_capture.manufacturer); |
| 794 | EXPECT_EQ("printer_a", success_capture.model); |
| 795 | |
| 796 | CapturedReverseLookup failed_capture = captured_reverse_lookup_[1]; |
| 797 | EXPECT_EQ(PpdProvider::NOT_FOUND, failed_capture.code); |
| 798 | } |
| 799 | |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 800 | // If we have a fresh entry in the cache, we shouldn't need to go out to the |
| 801 | // network at all to successfully resolve a ppd. |
| 802 | TEST_F(PpdProviderTest, FreshCacheHitNoNetworkTraffic) { |
| 803 | // Explicitly *not* starting a fake server. |
| 804 | std::string cached_ppd_contents = |
| 805 | "These cached contents are different from what's being served"; |
| 806 | auto provider = CreateProvider("en", true); |
| 807 | Printer::PpdReference ref; |
| 808 | ref.effective_make_and_model = "printer_a_ref"; |
| 809 | std::string cache_key = PpdProvider::PpdReferenceToCacheKey(ref); |
| 810 | // Cache exists, and is just created, so should be fresh. |
| 811 | ppd_cache_->StoreForTesting(PpdProvider::PpdReferenceToCacheKey(ref), |
| 812 | cached_ppd_contents, base::TimeDelta()); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 813 | task_environment_.RunUntilIdle(); |
tzik | c8fdd6c3 | 2018-04-11 04:02:40 | [diff] [blame] | 814 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 815 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 816 | task_environment_.RunUntilIdle(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 817 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
| 818 | |
| 819 | // Should get the cached (not served) results back, and not have hit the |
| 820 | // network. |
| 821 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 822 | EXPECT_EQ(cached_ppd_contents, captured_resolve_ppd_[0].ppd_contents); |
| 823 | } |
| 824 | |
| 825 | // If we have a stale cache entry and a good network connection, does the cache |
| 826 | // get refreshed during a resolution? |
| 827 | TEST_F(PpdProviderTest, StaleCacheGetsRefreshed) { |
| 828 | StartFakePpdServer(); |
| 829 | std::string cached_ppd_contents = |
| 830 | "These cached contents are different from what's being served"; |
| 831 | auto provider = CreateProvider("en", true); |
| 832 | // printer_ref_a resolves to kCupsFilterPpdContents on the server. |
| 833 | std::string expected_ppd = kCupsFilterPpdContents; |
| 834 | Printer::PpdReference ref; |
| 835 | ref.effective_make_and_model = "printer_a_ref"; |
| 836 | std::string cache_key = PpdProvider::PpdReferenceToCacheKey(ref); |
| 837 | // Cache exists, and is 6 months old, so really stale. |
| 838 | ppd_cache_->StoreForTesting(PpdProvider::PpdReferenceToCacheKey(ref), |
| 839 | cached_ppd_contents, |
| 840 | base::TimeDelta::FromDays(180)); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 841 | task_environment_.RunUntilIdle(); |
tzik | c8fdd6c3 | 2018-04-11 04:02:40 | [diff] [blame] | 842 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 843 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 844 | task_environment_.RunUntilIdle(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 845 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
| 846 | |
| 847 | // Should get the served results back, not the stale cached ones. |
| 848 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 849 | EXPECT_EQ(captured_resolve_ppd_[0].ppd_contents, expected_ppd); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 850 | |
| 851 | // Check that the cache was also updated. |
| 852 | PpdCache::FindResult captured_find_result; |
| 853 | // This is just a complicated syntax around the idea "use the Find callback to |
| 854 | // save the result in captured_find_result. |
| 855 | ppd_cache_->Find(PpdProvider::PpdReferenceToCacheKey(ref), |
| 856 | base::BindOnce( |
| 857 | [](PpdCache::FindResult* captured_find_result, |
| 858 | const PpdCache::FindResult& find_result) { |
| 859 | *captured_find_result = find_result; |
| 860 | }, |
| 861 | &captured_find_result)); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 862 | task_environment_.RunUntilIdle(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 863 | EXPECT_EQ(captured_find_result.success, true); |
| 864 | EXPECT_EQ(captured_find_result.contents, expected_ppd); |
| 865 | EXPECT_LT(captured_find_result.age, base::TimeDelta::FromDays(1)); |
| 866 | } |
| 867 | |
| 868 | // Test that, if we have an old entry in the cache that needs to be refreshed, |
| 869 | // and we fail to contact the server, we still use the cached version. |
| 870 | TEST_F(PpdProviderTest, StaleCacheGetsUsedIfNetworkFails) { |
| 871 | // Note that we're explicitly *not* starting the Fake ppd server in this test. |
| 872 | std::string cached_ppd_contents = |
| 873 | "These cached contents are different from what's being served"; |
| 874 | auto provider = CreateProvider("en", true); |
| 875 | Printer::PpdReference ref; |
| 876 | ref.effective_make_and_model = "printer_a_ref"; |
| 877 | std::string cache_key = PpdProvider::PpdReferenceToCacheKey(ref); |
| 878 | // Cache exists, and is 6 months old, so really stale. |
| 879 | ppd_cache_->StoreForTesting(PpdProvider::PpdReferenceToCacheKey(ref), |
| 880 | cached_ppd_contents, |
| 881 | base::TimeDelta::FromDays(180)); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 882 | task_environment_.RunUntilIdle(); |
tzik | c8fdd6c3 | 2018-04-11 04:02:40 | [diff] [blame] | 883 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 884 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 885 | task_environment_.RunUntilIdle(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 886 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
| 887 | |
| 888 | // Should successfully resolve from the cache, even though it's stale. |
| 889 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 890 | EXPECT_EQ(cached_ppd_contents, captured_resolve_ppd_[0].ppd_contents); |
| 891 | |
| 892 | // Check that the cache is *not* updated; it should remain stale. |
| 893 | PpdCache::FindResult captured_find_result; |
| 894 | // This is just a complicated syntax around the idea "use the Find callback to |
| 895 | // save the result in captured_find_result. |
| 896 | ppd_cache_->Find(PpdProvider::PpdReferenceToCacheKey(ref), |
| 897 | base::BindOnce( |
| 898 | [](PpdCache::FindResult* captured_find_result, |
| 899 | const PpdCache::FindResult& find_result) { |
| 900 | *captured_find_result = find_result; |
| 901 | }, |
| 902 | &captured_find_result)); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 903 | task_environment_.RunUntilIdle(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 904 | EXPECT_EQ(captured_find_result.success, true); |
| 905 | EXPECT_EQ(captured_find_result.contents, cached_ppd_contents); |
| 906 | EXPECT_GT(captured_find_result.age, base::TimeDelta::FromDays(179)); |
| 907 | } |
| 908 | |
| 909 | // For user-provided ppds, we should always use the latest version on |
| 910 | // disk if it still exists there. |
| 911 | TEST_F(PpdProviderTest, UserPpdAlwaysRefreshedIfAvailable) { |
| 912 | base::ScopedTempDir temp_dir; |
| 913 | StartFakePpdServer(); |
| 914 | std::string cached_ppd_contents = "Cached Ppd Contents"; |
| 915 | std::string disk_ppd_contents = "Updated Ppd Contents"; |
| 916 | auto provider = CreateProvider("en", true); |
| 917 | ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 918 | base::FilePath filename = temp_dir.GetPath().Append("my_spiffy.ppd"); |
| 919 | |
| 920 | Printer::PpdReference ref; |
| 921 | ref.user_supplied_ppd_url = |
| 922 | base::StringPrintf("file://%s", filename.MaybeAsASCII().c_str()); |
| 923 | |
| 924 | // Put cached_ppd_contents into the cache. |
| 925 | ppd_cache_->StoreForTesting(PpdProvider::PpdReferenceToCacheKey(ref), |
| 926 | cached_ppd_contents, base::TimeDelta()); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 927 | task_environment_.RunUntilIdle(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 928 | |
| 929 | // Write different contents to disk, so that the cached contents are |
| 930 | // now stale. |
| 931 | ASSERT_EQ(base::WriteFile(filename, disk_ppd_contents.data(), |
| 932 | disk_ppd_contents.size()), |
| 933 | static_cast<int>(disk_ppd_contents.size())); |
| 934 | |
tzik | c8fdd6c3 | 2018-04-11 04:02:40 | [diff] [blame] | 935 | provider->ResolvePpd(ref, base::BindOnce(&PpdProviderTest::CaptureResolvePpd, |
| 936 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 937 | task_environment_.RunUntilIdle(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 938 | ASSERT_EQ(1UL, captured_resolve_ppd_.size()); |
| 939 | EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_ppd_[0].code); |
| 940 | EXPECT_EQ(disk_ppd_contents, captured_resolve_ppd_[0].ppd_contents); |
| 941 | |
| 942 | // Check that the cache was also updated with the new contents. |
| 943 | PpdCache::FindResult captured_find_result; |
| 944 | ppd_cache_->Find(PpdProvider::PpdReferenceToCacheKey(ref), |
| 945 | base::BindOnce( |
| 946 | [](PpdCache::FindResult* captured_find_result, |
| 947 | const PpdCache::FindResult& find_result) { |
| 948 | *captured_find_result = find_result; |
| 949 | }, |
| 950 | &captured_find_result)); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 951 | task_environment_.RunUntilIdle(); |
Justin Carlson | d9a04614 | 2018-01-24 17:56:06 | [diff] [blame] | 952 | EXPECT_EQ(captured_find_result.success, true); |
| 953 | EXPECT_EQ(captured_find_result.contents, disk_ppd_contents); |
| 954 | } |
| 955 | |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 956 | // Test resolving usb manufacturer when failed to resolve PpdReference. |
| 957 | TEST_F(PpdProviderTest, ResolveUsbManufacturer) { |
| 958 | StartFakePpdServer(); |
| 959 | auto provider = CreateProvider("en", false); |
| 960 | |
| 961 | PrinterSearchData search_data; |
Luum Habtemariam | 521c687 | 2019-07-11 20:12:46 | [diff] [blame] | 962 | search_data.discovery_type = PrinterDiscoveryType::kUsb; |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 963 | |
| 964 | // Vendor id that exists, nonexistent device id, should get a NOT_FOUND. |
| 965 | // Although this is an unsupported printer model, we can still expect to get |
| 966 | // the manufacturer name. |
| 967 | search_data.usb_vendor_id = 0x03f0; |
| 968 | search_data.usb_product_id = 9999; |
| 969 | provider->ResolvePpdReference( |
| 970 | search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 971 | base::Unretained(this))); |
| 972 | |
| 973 | // Nonexistent vendor id, should get a NOT_FOUND in the real world, but |
| 974 | // the URL interceptor we're using considers all nonexistent files to |
| 975 | // be effectively CONNECTION REFUSED, so we just check for non-success |
| 976 | // on this one. We should also not be able to get a manufacturer name from a |
| 977 | // nonexistent vendor id. |
| 978 | search_data.usb_vendor_id = 0x1234; |
| 979 | search_data.usb_product_id = 1782; |
| 980 | provider->ResolvePpdReference( |
| 981 | search_data, base::BindOnce(&PpdProviderTest::CaptureResolvePpdReference, |
| 982 | base::Unretained(this))); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 983 | task_environment_.RunUntilIdle(); |
Jimmy Gong | 53317773 | 2019-04-26 19:13:19 | [diff] [blame] | 984 | |
| 985 | ASSERT_EQ(static_cast<size_t>(2), captured_resolve_ppd_references_.size()); |
| 986 | // Was able to find the printer manufactuer but unable to find the printer |
| 987 | // model should result in a NOT_FOUND. |
| 988 | EXPECT_EQ(PpdProvider::NOT_FOUND, captured_resolve_ppd_references_[0].code); |
| 989 | // Failed to grab the PPD for a USB printer, but should still be able to grab |
| 990 | // its manufacturer name. |
| 991 | EXPECT_EQ("HP", captured_resolve_ppd_references_[0].usb_manufacturer); |
| 992 | |
| 993 | // Unable to find the PPD file should result in a failure. |
| 994 | EXPECT_FALSE(captured_resolve_ppd_references_[1].code == |
| 995 | PpdProvider::SUCCESS); |
| 996 | // Unknown vendor id should result in an empty manufacturer string. |
| 997 | EXPECT_TRUE(captured_resolve_ppd_references_[1].usb_manufacturer.empty()); |
| 998 | } |
| 999 | |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 1000 | } // namespace |
justincarlson | c7d4aa6c | 2016-10-25 15:12:10 | [diff] [blame] | 1001 | } // namespace chromeos |