Commit 2c7db6e6 authored by Kalvin Lee's avatar Kalvin Lee Committed by Commit Bot

PpdProvider v3: implement using forward index

This change implements
PpdMetadataManager::FindAllEmmsAvailableInIndex(), which seeks out PPD
PPD information via the forward index metadata for a given list of
effective-make-and-model strings. This is the first method in a series
needed to implement PpdProvider::ResolvePpdReference().

Bug: chromium:888189
Test: chromeos_unittests --gtest_filter='PpdMetadataManagerTest.*'
Change-Id: I465d7fa6589aa519ed80709a2320d8c1ec4b0e74
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2333582Reviewed-by: default avatarLuum Habtemariam <luum@chromium.org>
Commit-Queue: Kalvin Lee <kdlee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797876}
parent 4a16aeb6
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <vector> #include <vector>
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/containers/queue.h"
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/json/json_reader.h" #include "base/json/json_reader.h"
#include "base/logging.h" #include "base/logging.h"
...@@ -44,6 +45,120 @@ struct ParsedMetadataWithTimestamp { ...@@ -44,6 +45,120 @@ struct ParsedMetadataWithTimestamp {
T value; T value;
}; };
// Tracks the progress of a single call to
// PpdMetadataManager::FindAllEmmsAvailableInIndex().
class ForwardIndexSearchContext {
public:
ForwardIndexSearchContext(
const std::vector<std::string>& emms,
base::Time max_age,
PpdMetadataManager::FindAllEmmsAvailableInIndexCallback cb)
: emms_(emms), current_index_(), max_age_(max_age), cb_(std::move(cb)) {}
~ForwardIndexSearchContext() = default;
ForwardIndexSearchContext(const ForwardIndexSearchContext&) = delete;
ForwardIndexSearchContext& operator=(const ForwardIndexSearchContext&) =
delete;
ForwardIndexSearchContext(ForwardIndexSearchContext&&) = default;
// The effective-make-and-model string currently being sought in the
// forward index search tracked by this struct.
base::StringPiece CurrentEmm() const {
DCHECK_LT(current_index_, emms_.size());
return emms_[current_index_];
}
// Returns whether the CurrentEmm() is the last one in |this|
// that needs searching.
bool CurrentEmmIsLast() const {
DCHECK_LT(current_index_, emms_.size());
return current_index_ + 1 == emms_.size();
}
void AdvanceToNextEmm() {
DCHECK_LT(current_index_, emms_.size());
current_index_++;
}
// Called when the PpdMetadataManager has searched all appropriate
// forward index metadata for all |emms_|.
void PostCallback() {
DCHECK(CurrentEmmIsLast());
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(cb_), cb_arg_));
}
// Called when the PpdMetadataManager successfully maps the
// CurrentEmm() to a ParsedIndexValues struct.
void AddDataFromForwardIndexForCurrentEmm(const ParsedIndexValues& value) {
cb_arg_.insert_or_assign(CurrentEmm(), value);
}
base::Time MaxAge() const { return max_age_; }
private:
// List of all effective-make-and-model strings that caller gave to
// PpdMetadataManager::FindAllEmmsAvailableInIndex().
std::vector<std::string> emms_;
// Index into |emms| that marks the effective-make-and-model string
// currently being searched.
size_t current_index_;
// Freshness requirement for forward indices that this search reads.
base::Time max_age_;
// Callback that caller gave to
// PpdMetadataManager::FindAllEmmsAvailableInIndex().
PpdMetadataManager::FindAllEmmsAvailableInIndexCallback cb_;
// Accrues data to pass to |cb|.
base::flat_map<std::string, ParsedIndexValues> cb_arg_;
};
// Enqueues calls to PpdMetadataManager::FindAllEmmsAvailableInIndex().
class ForwardIndexSearchQueue {
public:
ForwardIndexSearchQueue() = default;
~ForwardIndexSearchQueue() = default;
ForwardIndexSearchQueue(const ForwardIndexSearchQueue&) = delete;
ForwardIndexSearchQueue& operator=(const ForwardIndexSearchQueue&) = delete;
void Enqueue(ForwardIndexSearchContext context) {
contexts_.push(std::move(context));
}
bool IsIdle() const { return contexts_.empty(); }
ForwardIndexSearchContext& CurrentContext() {
DCHECK(!IsIdle());
return contexts_.front();
}
// Progresses the frontmost search context, advancing it to its
// next effective-make-and-model string to find in forward index
// metadata.
//
// If the frontmost search context has no more
// effective-make-and-model strings to search, then
// 1. its callback is posted from here and
// 2. it is popped off the |contexts| queue.
void AdvanceToNextEmm() {
DCHECK(!IsIdle());
if (CurrentContext().CurrentEmmIsLast()) {
CurrentContext().PostCallback();
contexts_.pop();
} else {
CurrentContext().AdvanceToNextEmm();
}
}
private:
base::queue<ForwardIndexSearchContext> contexts_;
};
// Maps parsed metadata by name to parsed contents. // Maps parsed metadata by name to parsed contents.
// //
// Implementation note: the keys (metadata names) used here are // Implementation note: the keys (metadata names) used here are
...@@ -387,6 +502,26 @@ class PpdMetadataManagerImpl : public PpdMetadataManager { ...@@ -387,6 +502,26 @@ class PpdMetadataManagerImpl : public PpdMetadataManager {
config_cache_->Fetch(metadata_name.value(), age, std::move(fetch_cb)); config_cache_->Fetch(metadata_name.value(), age, std::move(fetch_cb));
} }
void FindAllEmmsAvailableInIndex(
const std::vector<std::string>& emms,
base::TimeDelta age,
FindAllEmmsAvailableInIndexCallback cb) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ForwardIndexSearchContext context(emms, clock_->Now() - age, std::move(cb));
bool queue_was_idle = forward_index_search_queue_.IsIdle();
forward_index_search_queue_.Enqueue(std::move(context));
// If we are the prime movers, then we need to set the forward
// index search in motion.
if (queue_was_idle) {
ContinueSearchingForwardIndices();
}
// If we're not the prime movers, then a search is already ongoing
// and we need not provide extra impetus.
}
void SplitMakeAndModel(base::StringPiece effective_make_and_model, void SplitMakeAndModel(base::StringPiece effective_make_and_model,
base::TimeDelta age, base::TimeDelta age,
PpdProvider::ReverseLookupCallback cb) override { PpdProvider::ReverseLookupCallback cb) override {
...@@ -448,6 +583,19 @@ class PpdMetadataManagerImpl : public PpdMetadataManager { ...@@ -448,6 +583,19 @@ class PpdMetadataManagerImpl : public PpdMetadataManager {
} }
private: private:
// Denotes the status of an ongoing forward index search - see
// FindAllEmmsAvailableInIndex().
enum class ForwardIndexSearchStatus {
// We called |config_cache_|::Fetch(). We provided a bound
// callback that will resume the forward index search for us when
// the fetch completes.
kWillResumeOnFetchCompletion,
// We did not call |config_cache_|::Fetch(), so |this| still has
// control of the progression of the forward index search.
kCanContinue,
};
// Called by OnLocalesFetched(). // Called by OnLocalesFetched().
// Continues a prior call to GetLocale(). // Continues a prior call to GetLocale().
// //
...@@ -615,6 +763,111 @@ class PpdMetadataManagerImpl : public PpdMetadataManager { ...@@ -615,6 +763,111 @@ class PpdMetadataManagerImpl : public PpdMetadataManager {
OnPrintersAvailable(result.key, std::move(cb)); OnPrintersAvailable(result.key, std::move(cb));
} }
// Called when one unit of sufficiently fresh forward index metadata
// is available. Seeks out the current effective-make-and-model string
// in said metadata.
void FindEmmInForwardIndex(base::StringPiece metadata_name) {
// Caller must have verified that this index is already present (and
// sufficiently fresh) before entering this method.
DCHECK(cached_forward_indices_.contains(metadata_name));
ForwardIndexSearchContext& context =
forward_index_search_queue_.CurrentContext();
const ParsedIndex& index = cached_forward_indices_.at(metadata_name).value;
const auto& iter = index.find(context.CurrentEmm());
if (iter != index.end()) {
context.AddDataFromForwardIndexForCurrentEmm(iter->second);
}
forward_index_search_queue_.AdvanceToNextEmm();
}
// Called by |config_cache_|.Fetch().
// Continues a prior call to FindAllEmmsAvailableInForwardIndex().
//
// Parses and updates our cached map of forward indices if |result|
// indicates a successful fetch. Continues the action that
// necessitated fetching the present forward index.
void OnForwardIndexFetched(const PrinterConfigCache::FetchResult& result) {
if (!result.succeeded) {
// We failed to fetch the forward index containing the current
// effective-make-and-model string. There's nothing we can do but
// carry on, e.g. by moving to deal with the next emm.
forward_index_search_queue_.AdvanceToNextEmm();
ContinueSearchingForwardIndices();
return;
}
const auto parsed = ParseForwardIndex(result.contents);
if (!parsed.has_value()) {
// Same drill as fetch failure above.
forward_index_search_queue_.AdvanceToNextEmm();
ContinueSearchingForwardIndices();
return;
}
ParsedMetadataWithTimestamp<ParsedIndex> value = {clock_->Now(),
parsed.value()};
cached_forward_indices_.insert_or_assign(result.key, value);
ContinueSearchingForwardIndices();
}
// Works on searching the forward index for the current
// effective-make-and-model string in the frontmost entry in the
// forward index search queue.
//
// One invocation of this method ultimately processes exactly one
// effective-make-and-model string: either we find it in some forward
// index metadata or we don't.
ForwardIndexSearchStatus SearchForwardIndicesForOneEmm() {
const ForwardIndexSearchContext& context =
forward_index_search_queue_.CurrentContext();
const PpdMetadataPathSpecifier options = {PpdMetadataType::INDEX, nullptr,
IndexShard(context.CurrentEmm())};
const std::string forward_index_name =
PpdMetadataPathInServingRoot(options);
if (MapHasValueFresherThan(cached_forward_indices_, forward_index_name,
context.MaxAge())) {
// We have the appropriate forward index metadata and it's fresh
// enough to make a determination: is the current
// effective-make-and-model string present in this metadata?
FindEmmInForwardIndex(forward_index_name);
return ForwardIndexSearchStatus::kCanContinue;
}
// We don't have the appropriate forward index metadata. We need to
// get it before we can determine if the current
// effective-make-and-model string is present in it.
//
// PrinterConfigCache::Fetch() accepts a TimeDelta expressing the
// maximum permissible age of the cached response; to simulate the
// original TimeDelta that caller gave to
// FindAllEmmsAvailableInIndex(), we find the delta between Now()
// and the absolute time ceiling recorded in the
// ForwardIndexSearchContext.
auto callback =
base::BindOnce(&PpdMetadataManagerImpl::OnForwardIndexFetched,
weak_factory_.GetWeakPtr());
config_cache_->Fetch(forward_index_name, clock_->Now() - context.MaxAge(),
std::move(callback));
return ForwardIndexSearchStatus::kWillResumeOnFetchCompletion;
}
// Continues working on the forward index search queue.
void ContinueSearchingForwardIndices() {
while (!forward_index_search_queue_.IsIdle()) {
ForwardIndexSearchStatus status = SearchForwardIndicesForOneEmm();
// If we invoked |config_cache_|::Fetch(), then control has passed
// out of this class for now. It will resume from
// OnForwardIndexFetched().
if (status == ForwardIndexSearchStatus::kWillResumeOnFetchCompletion) {
break;
}
}
}
// Called by one of // Called by one of
// * SplitMakeAndModel() or // * SplitMakeAndModel() or
// * OnReverseIndexFetched(). // * OnReverseIndexFetched().
...@@ -696,8 +949,12 @@ class PpdMetadataManagerImpl : public PpdMetadataManager { ...@@ -696,8 +949,12 @@ class PpdMetadataManagerImpl : public PpdMetadataManager {
CachedParsedMetadataMap<ParsedManufacturers> cached_manufacturers_; CachedParsedMetadataMap<ParsedManufacturers> cached_manufacturers_;
CachedParsedMetadataMap<ParsedPrinters> cached_printers_; CachedParsedMetadataMap<ParsedPrinters> cached_printers_;
CachedParsedMetadataMap<ParsedIndex> cached_forward_indices_;
CachedParsedMetadataMap<ParsedReverseIndex> cached_reverse_indices_; CachedParsedMetadataMap<ParsedReverseIndex> cached_reverse_indices_;
// Processing queue for FindAllEmmsAvailableInIndex().
ForwardIndexSearchQueue forward_index_search_queue_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
// Dispenses weak pointers to the |config_cache_|. This is necessary // Dispenses weak pointers to the |config_cache_|. This is necessary
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/containers/span.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -37,6 +38,15 @@ class CHROMEOS_EXPORT PpdMetadataManager { ...@@ -37,6 +38,15 @@ class CHROMEOS_EXPORT PpdMetadataManager {
using GetPrintersCallback = using GetPrintersCallback =
base::OnceCallback<void(bool, const ParsedPrinters&)>; base::OnceCallback<void(bool, const ParsedPrinters&)>;
// Used by FindAllEmmsAvailableInIndex().
// Contains a map
// * whose keys are effective-make-and-model strings (provided by the
// caller) that are available in forward index metadata and
// * whose values contain the corresponding information read from the
// forward index metadata.
using FindAllEmmsAvailableInIndexCallback = base::OnceCallback<void(
const base::flat_map<std::string, ParsedIndexValues>&)>;
// Assumes ownership of |config_cache|. // Assumes ownership of |config_cache|.
static std::unique_ptr<PpdMetadataManager> Create( static std::unique_ptr<PpdMetadataManager> Create(
base::StringPiece browser_locale, base::StringPiece browser_locale,
...@@ -78,6 +88,17 @@ class CHROMEOS_EXPORT PpdMetadataManager { ...@@ -78,6 +88,17 @@ class CHROMEOS_EXPORT PpdMetadataManager {
base::TimeDelta age, base::TimeDelta age,
GetPrintersCallback cb) = 0; GetPrintersCallback cb) = 0;
// Calls |cb| with the subset of strings from |emms| that are
// available in forward index metadata mapped to the corresponding
// values read from forward index metadata.
// * Does not rely on prior call to GetLocale().
// * During operation, operates with metadata no older than |age|.
// * On failure, calls |cb| with an empty map.
virtual void FindAllEmmsAvailableInIndex(
const std::vector<std::string>& emms,
base::TimeDelta age,
FindAllEmmsAvailableInIndexCallback cb) = 0;
// Calls |cb| with the make and model of // Calls |cb| with the make and model of
// |effective_make_and_model|. // |effective_make_and_model|.
// * On success, the split is performed against metadata no older than // * On success, the split is performed against metadata no older than
......
...@@ -84,6 +84,17 @@ class PpdMetadataManagerTest : public ::testing::Test { ...@@ -84,6 +84,17 @@ class PpdMetadataManagerTest : public ::testing::Test {
} }
} }
// Callback method appropriate for passing to
// PpdMetadataManager::FindAllEmmsAvailableInIndex().
void CatchFindAllEmmsAvailableInIndex(
base::RepeatingClosure quit_closure,
const base::flat_map<std::string, ParsedIndexValues>& values) {
results_.available_effective_make_and_model_strings = values;
if (quit_closure) {
quit_closure.Run();
}
}
// Callback method appropriate for passing to // Callback method appropriate for passing to
// PpdMetadataManager::SplitMakeAndModel(). // PpdMetadataManager::SplitMakeAndModel().
void CatchSplitMakeAndModel(base::RepeatingClosure quit_closure, void CatchSplitMakeAndModel(base::RepeatingClosure quit_closure,
...@@ -116,6 +127,11 @@ class PpdMetadataManagerTest : public ::testing::Test { ...@@ -116,6 +127,11 @@ class PpdMetadataManagerTest : public ::testing::Test {
bool get_printers_succeeded; bool get_printers_succeeded;
ParsedPrinters printers; ParsedPrinters printers;
// Landing area for
// PpdMetadataManager::FindAllEmmsAvailableInIndex().
base::flat_map<std::string, ParsedIndexValues>
available_effective_make_and_model_strings;
// Landing area for PpdMetadataManager::SplitMakeAndModel(). // Landing area for PpdMetadataManager::SplitMakeAndModel().
PpdProvider::CallbackResultCode split_make_and_model_code; PpdProvider::CallbackResultCode split_make_and_model_code;
std::string split_make; std::string split_make;
...@@ -727,6 +743,301 @@ TEST_F(PpdMetadataManagerTest, CanGetPrintersTimeSensitive) { ...@@ -727,6 +743,301 @@ TEST_F(PpdMetadataManagerTest, CanGetPrintersTimeSensitive) {
ParsedPrinterLike("Some Printer D", "some emm d"))); ParsedPrinterLike("Some Printer D", "some emm d")));
} }
// Verifies that the manager can find all effective-make-and-model
// strings in forward index metadata.
TEST_F(PpdMetadataManagerTest, CanFindAllAvailableEmmsInIndex) {
// Known interaction: the manager will fetch forward index metadata
// numbered 14, 15, and 16.
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json", R"(
{
"ppdIndex": {
"some printer a": {
"ppdMetadata": [ {
"name": "some-ppd-basename-a.ppd.gz"
} ]
}
}
})");
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
{
"ppdIndex": {
"some printer b": {
"ppdMetadata": [ {
"name": "some-ppd-basename-b.ppd.gz"
} ]
}
}
})");
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
{
"ppdIndex": {
"some printer c": {
"ppdMetadata": [ {
"name": "some-ppd-basename-c.ppd.gz"
} ]
}
}
})");
base::RunLoop loop;
auto callback =
base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
base::Unretained(this), loop.QuitClosure());
manager_->FindAllEmmsAvailableInIndex(
{"some printer a", "some printer b", "some printer c"},
kArbitraryTimeDelta, std::move(callback));
loop.Run();
EXPECT_THAT(results_.available_effective_make_and_model_strings,
UnorderedElementsAre(
ParsedIndexEntryLike(
"some printer a",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-a.ppd.gz"))),
ParsedIndexEntryLike(
"some printer b",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-b.ppd.gz"))),
ParsedIndexEntryLike(
"some printer c",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-c.ppd.gz")))));
}
// Verifies that the manager invokes the
// FindAllAvailableEmmsInIndexCallback with a partially filled argument
// if it fails to fetch some of the necessary metadata.
TEST_F(PpdMetadataManagerTest,
CanPartiallyFindAllAvailableEmmsInIndexWithFetchFailure) {
// Known interaction: the manager will fetch forward index metadata
// numbered 14, 15, and 16.
//
// We deliberately omit forward index metadata no. 14 to simulate a
// fetch failure.
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
{
"ppdIndex": {
"some printer b": {
"ppdMetadata": [ {
"name": "some-ppd-basename-b.ppd.gz"
} ]
}
}
})");
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
{
"ppdIndex": {
"some printer c": {
"ppdMetadata": [ {
"name": "some-ppd-basename-c.ppd.gz"
} ]
}
}
})");
base::RunLoop loop;
auto callback =
base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
base::Unretained(this), loop.QuitClosure());
manager_->FindAllEmmsAvailableInIndex(
{"some printer a", "some printer b", "some printer c"},
kArbitraryTimeDelta, std::move(callback));
loop.Run();
// The manager was unable to get the forward index metadata that would
// contain information for effective-make-and-model string
// "some printer a," but the other results should avail themselves.
EXPECT_THAT(results_.available_effective_make_and_model_strings,
UnorderedElementsAre(
ParsedIndexEntryLike(
"some printer b",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-b.ppd.gz"))),
ParsedIndexEntryLike(
"some printer c",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-c.ppd.gz")))));
}
// Verifies that the manager invokes the
// FindAllAvailableEmmsInIndexCallback with a partially filled argument
// if it fails to parse some of the necessary metadata.
TEST_F(PpdMetadataManagerTest,
CanPartiallyFindAllAvailableEmmsInIndexWithParseFailure) {
// Known interaction: the manager will fetch forward index metadata
// numbered 14, 15, and 16.
//
// We deliberately serve malformed JSON that will fail to parse for
// indices nos. 14 and 15 to exercise the manager's handling of parse
// failures.
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json",
kInvalidJson);
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json",
kInvalidJson);
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
{
"ppdIndex": {
"some printer c": {
"ppdMetadata": [ {
"name": "some-ppd-basename-c.ppd.gz"
} ]
}
}
})");
base::RunLoop loop;
auto callback =
base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
base::Unretained(this), loop.QuitClosure());
manager_->FindAllEmmsAvailableInIndex(
{"some printer a", "some printer b", "some printer c"},
kArbitraryTimeDelta, std::move(callback));
loop.Run();
// The manager was unable to parse the forward index metadata that would
// contain information for effective-make-and-model strings
// "some printer a" and for "some printer b," but the last string
// "some printer c" should avail itself.
EXPECT_THAT(
results_.available_effective_make_and_model_strings,
UnorderedElementsAre(ParsedIndexEntryLike(
"some printer c", UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-c.ppd.gz")))));
}
// Verifies that the manager fetches forward index metadata anew when
// the caller asks it for metadata fresher than what it has cached.
TEST_F(PpdMetadataManagerTest, CanFindAllAvailableEmmsInIndexTimeSensitive) {
// Known interaction: the manager will fetch forward index metadata
// numbered 14, 15, and 16.
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-14.json", R"(
{
"ppdIndex": {
"some printer a": {
"ppdMetadata": [ {
"name": "some-ppd-basename-a.ppd.gz"
} ]
}
}
})");
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-15.json", R"(
{
"ppdIndex": {
"some printer b": {
"ppdMetadata": [ {
"name": "some-ppd-basename-b.ppd.gz"
} ]
}
}
})");
GetFakeCache()->SetFetchResponseForTesting("metadata_v3/index-16.json", R"(
{
"ppdIndex": {
"some printer c": {
"ppdMetadata": [ {
"name": "some-ppd-basename-c.ppd.gz"
} ]
}
}
})");
base::RunLoop loop;
auto callback =
base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
base::Unretained(this), loop.QuitClosure());
// t = 0s: caller requests the |manager_| to search forward index
// metadata for three effective-make-and-model strings. |manager_|
// fetches the appropriate forward index metadata (nos. 14, 15, and
// 16) and caches the result.
manager_->FindAllEmmsAvailableInIndex(
{"some printer a", "some printer b", "some printer c"},
base::TimeDelta::FromSeconds(30), std::move(callback));
loop.Run();
EXPECT_THAT(results_.available_effective_make_and_model_strings,
UnorderedElementsAre(
ParsedIndexEntryLike(
"some printer a",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-a.ppd.gz"))),
ParsedIndexEntryLike(
"some printer b",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-b.ppd.gz"))),
ParsedIndexEntryLike(
"some printer c",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-c.ppd.gz")))));
// We drop forward index metadata nos. 14 and 15 now. If the
// |manager_| attempts to fetch these again, it will fail to do so.
GetFakeCache()->Drop("metadata_v3/index-14.json");
GetFakeCache()->Drop("metadata_v3/index-15.json");
// Resets the results to require that the |manager_| answer us
// positively.
results_.available_effective_make_and_model_strings = {};
base::RunLoop second_loop;
auto second_callback =
base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
base::Unretained(this), second_loop.QuitClosure());
// t = 0s: caller requests the |manager_| to search forward index
// metadata for the same three effective-make-and-model strings.
// Caller requests this using metadata fetched within the last thirty
// seconds, so |manager_| does not perform a live fetch of the data.
manager_->FindAllEmmsAvailableInIndex(
{"some printer a", "some printer b", "some printer c"},
base::TimeDelta::FromSeconds(30), std::move(second_callback));
second_loop.Run();
// We expect the results to be unchanged.
EXPECT_THAT(results_.available_effective_make_and_model_strings,
UnorderedElementsAre(
ParsedIndexEntryLike(
"some printer a",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-a.ppd.gz"))),
ParsedIndexEntryLike(
"some printer b",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-b.ppd.gz"))),
ParsedIndexEntryLike(
"some printer c",
UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-c.ppd.gz")))));
// t = 31s
clock_.Advance(base::TimeDelta::FromSeconds(31));
base::RunLoop third_loop;
auto third_callback =
base::BindOnce(&PpdMetadataManagerTest::CatchFindAllEmmsAvailableInIndex,
base::Unretained(this), third_loop.QuitClosure());
// t = 31s: caller requests the |manager_| to search forward index
// metadata for the same three effective-make-and-model strings.
// Caller requests this using metadata fetched within the last thirty
// thirds; |manager_| sees that its cached metadata is too old, and
// so performs a live fetch.
//
// Since we previously blocked forward index metadata nos. 14 and 15
// from being served, the |manager_| will fail to fetch these.
manager_->FindAllEmmsAvailableInIndex(
{"some printer a", "some printer b", "some printer c"},
base::TimeDelta::FromSeconds(30), std::move(third_callback));
third_loop.Run();
// We expect the results to have changed.
EXPECT_THAT(
results_.available_effective_make_and_model_strings,
UnorderedElementsAre(ParsedIndexEntryLike(
"some printer c", UnorderedElementsAre(ParsedIndexLeafWithPpdBasename(
"some-ppd-basename-c.ppd.gz")))));
}
// Verifies that the manager can split an effective-make-and-model // Verifies that the manager can split an effective-make-and-model
// string into its constituent parts (make and model). // string into its constituent parts (make and model).
TEST_F(PpdMetadataManagerTest, CanSplitMakeAndModel) { TEST_F(PpdMetadataManagerTest, CanSplitMakeAndModel) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment