Deprecate obsolete repository
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Change-Id: Ifd2be70c67be5506dc28898d2dc2296b9957cf12
Reviewed-on: https://fuchsia-review.googlesource.com/c/peridot/+/418717
Commit-Queue: Renato Mangini Dias <mangini@google.com>
Reviewed-by: Mahesh Saripalli <maheshsr@google.com>
API-Review: Dale Sather <dalesat@google.com>
diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index 4bdf247..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,10 +0,0 @@
-# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
-BasedOnStyle: Google
-# This defaults to 'Auto'. Explicitly set it for a while, so that
-# 'vector<vector<int> >' in existing files gets formatted to
-# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
-# 'int>>' if the file already contains at least one such instance.)
-Standard: Cpp11
-SortIncludes: true
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
diff --git a/.clang-tidy b/.clang-tidy
deleted file mode 100644
index b7bb616..0000000
--- a/.clang-tidy
+++ /dev/null
@@ -1,32 +0,0 @@
----
-Checks: 'clang-diagnostic-*,-clang-diagnostic-unused-command-line-argument,clang-analyzer-*,-clang-analyzer-core.NullDereference,-clang-analyzer-unix.Malloc,google-*,misc-*,-misc-noexcept*,modernize-*,-modernize-deprecated-headers,-modernize-raw-string-literal,-modernize-return-braced-init-list,-modernize-use-auto,-modernize-use-equals-delete,-modernize-use-equals-default,performance-*,-performance-unnecessary-value-param,readability-*,-readability-implicit-bool-conversion'
-WarningsAsErrors: false
-HeaderFilterRegex: '\.\./peridot/([^t].*|t[^h].*|th[^i].*)'
-AnalyzeTemporaryDtors: false
-FormatStyle: file
-CheckOptions:
- - key: google-readability-braces-around-statements.ShortStatementLines
- value: '2'
- - key: google-readability-function-size.StatementThreshold
- value: '800'
- - key: google-readability-namespace-comments.ShortNamespaceLines
- value: '10'
- - key: google-readability-namespace-comments.SpacesBeforeComments
- value: '2'
- - key: modernize-loop-convert.MaxCopySize
- value: '16'
- - key: modernize-loop-convert.MinConfidence
- value: reasonable
- - key: modernize-loop-convert.NamingStyle
- value: CamelCase
- - key: modernize-pass-by-value.IncludeStyle
- value: llvm
- - key: modernize-replace-auto-ptr.IncludeStyle
- value: llvm
- - key: modernize-use-default-member-init.UseAssignment
- value: '1'
- - key: modernize-use-nullptr.NullMacros
- value: 'NULL'
- - key: readability-braces-around-statements.ShortStatementLines
- value: '2'
-...
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 3bbc38f..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,22 +0,0 @@
-*.iml
-*.pyc
-*~
-.*.sw?
-.DS_Store
-.checkstyle
-.clang_complete
-.classpath
-.cproject
-.gdb_history
-.gdbinit
-.landmines
-.project
-.pub
-.pydevproject
-*.sublime-project
-*.sublime-workspace
-.vscode
-.packages
-**/.atom/
-**/.idea/
-/cloud/third_party
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index c2a4eac..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,8 +0,0 @@
-# This is the list of Fuchsia Authors.
-
-# Names should be added to this file as one of
-# Organization's name
-# Individual's name <submission email address>
-# Individual's name <submission email address> <email2> <emailN>
-
-Google Inc.
diff --git a/BUILD.gn b/BUILD.gn
deleted file mode 100644
index cbac971..0000000
--- a/BUILD.gn
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-import("//peridot/build/tests_package.gni")
-
-config("internal") {
- include_dirs = [
- ".",
- "$root_gen_dir/peridot",
- ]
-}
-
-# All peridot tests that can run as test binaries in a package, and are not
-# associated with the package of a binary already anyway.
-tests_package("peridot_tests") {
- deps = [
- "//peridot/lib:peridot_lib_unittests",
- "//peridot/public/lib:peridot_public_lib_unittests",
- ]
-}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 81e2938..0000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,9 +0,0 @@
-This repository accepts contributions using Gerrit.
-
-Instructions for using Gerrit:
-
- * https://gerrit-review.googlesource.com/Documentation/
-
-Before we can land your change, you need to sign the Google CLA:
-
- * https://cla.developers.google.com/
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index ac6402f..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/PATENTS b/PATENTS
deleted file mode 100644
index 2746e78..0000000
--- a/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Fuchsia project.
-
-Google hereby grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this
-section) patent license to make, have made, use, offer to sell, sell,
-import, transfer, and otherwise run, modify and propagate the contents
-of this implementation of Fuchsia, where such license applies only to
-those patent claims, both currently owned by Google and acquired in
-the future, licensable by Google that are necessarily infringed by
-this implementation. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute
-or order or agree to the institution of patent litigation or any other
-patent enforcement activity against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that this
-implementation of Fuchsia constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of
-Fuchsia shall terminate as of the date such litigation is filed.
diff --git a/README.md b/README.md
index 711a46a..3cc8b3b 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,5 @@
-# Peridot
+# Obsolete
-Peridot is a framework for composed, intelligent and distributed user
-experiences.
-
-Applications not explicitly designed to interoperate (and possibly implemented
-in different programming languages) are ephemerally downloaded and dynamically
-composed to run in a shared context. The framework manages application
-lifecycle, resources and view hierarchy; and well as context and suggestion
-infrastructure.
-
-State of Peridot experiences is transparently synchronized across user devices
-using a distributed offline-first storage system.
-
-
-## Read more
-
- - [bin](bin) - implementation of Peridot components
- - docs
- - [Modular](docs/modular)
- - [Ledger](docs/ledger)
- - developer workflow:
- - [Conventions](docs/conventions.md)
- - [Lint](docs/lint.md)
- - [Repository structure](docs/repository_structure.md)
- - [examples](examples) - examples of applications that use Peridot components
- - [public](public) - public FIDL APIs of Peridot components
+This repository has moved into Fuchsia's main repository:
+https://fuchsia.googlesource.com/fuchsia/
diff --git a/bin/MAINTAINERS b/bin/MAINTAINERS
deleted file mode 100644
index b31f2a9..0000000
--- a/bin/MAINTAINERS
+++ /dev/null
@@ -1,4 +0,0 @@
-mesch@google.com
-ppi@google.com
-qsr@google.com
-thatguy@google.com
diff --git a/bin/acquirers/BUILD.gn b/bin/acquirers/BUILD.gn
deleted file mode 100644
index f849e2c..0000000
--- a/bin/acquirers/BUILD.gn
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("acquirers") {
- public_deps = [
- "story_info",
- ]
-}
diff --git a/bin/acquirers/story_info/BUILD.gn b/bin/acquirers/story_info/BUILD.gn
deleted file mode 100644
index 2b7b203..0000000
--- a/bin/acquirers/story_info/BUILD.gn
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-import("//peridot/build/executable_package.gni")
-
-executable_package("story_info") {
- meta = [
- {
- path = "meta/story_info.cmx"
- dest = "story_info.cmx"
- },
- ]
-
- sources = [
- "link_watcher_impl.cc",
- "link_watcher_impl.h",
- "story_info.cc",
- "story_info.h",
- "story_info_main.cc",
- "story_watcher_impl.cc",
- "story_watcher_impl.h",
- ]
-
- deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/svc/cpp",
-
- # TODO(thatguy): Do not depend on constants_and_utils.
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/lib:maxwell_internal",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/rapidjson",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:agent_driver",
- "//peridot/public/lib/context/cpp:context_metadata_builder",
- "//peridot/public/lib/entity/cpp",
- "//peridot/public/lib/entity/cpp:json",
- "//third_party/rapidjson",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
diff --git a/bin/acquirers/story_info/link_watcher_impl.cc b/bin/acquirers/story_info/link_watcher_impl.cc
deleted file mode 100644
index 62b5f5c..0000000
--- a/bin/acquirers/story_info/link_watcher_impl.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/acquirers/story_info/link_watcher_impl.h"
-
-#include <set>
-#include <sstream>
-
-#include <lib/context/cpp/context_metadata_builder.h>
-#include <lib/entity/cpp/json.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/bin/acquirers/story_info/story_watcher_impl.h"
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h" // MakeLinkKey
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-
-namespace maxwell {
-
-LinkWatcherImpl::LinkWatcherImpl(
- StoryWatcherImpl* const owner,
- fuchsia::modular::StoryController* const story_controller,
- const std::string& story_id,
- fuchsia::modular::ContextValueWriter* const story_value,
- fuchsia::modular::LinkPath link_path)
- : owner_(owner),
- story_controller_(story_controller),
- story_id_(story_id),
- link_path_(std::move(link_path)),
- link_watcher_binding_(this) {
- // We hold onto a LinkPtr for the lifetime of this LinkWatcherImpl so that
- // our watcher handle stays alive. Incidentally, this also means that the
- // observed link remains "active" in the FW forever.
- // TODO(thatguy): Use the new PuppetMaster observation API. MI4-1084
- story_controller_->GetLink(fidl::Clone(link_path_), link_ptr_.NewRequest());
-
- story_value->CreateChildValue(link_node_writer_.NewRequest(),
- fuchsia::modular::ContextValueType::LINK);
- link_node_writer_->Set(
- nullptr, fidl::MakeOptional(ContextMetadataBuilder()
- .SetLinkPath(link_path_.module_path,
- link_path_.link_name)
- .Build()));
-
- link_ptr_->Watch(link_watcher_binding_.NewBinding());
-
- // If the link becomes inactive, we stop watching it. It might still receive
- // updates from other devices, but nothing can tell us as it isn't kept in
- // memory on the current device.
- //
- // The fuchsia::modular::Link itself is not kept here, because otherwise it
- // never becomes inactive (i.e. loses all its fuchsia::modular::Link
- // connections).
- link_watcher_binding_.set_error_handler([this](zx_status_t status) {
- owner_->DropLink(modular::MakeLinkKey(link_path_));
- });
-}
-
-LinkWatcherImpl::~LinkWatcherImpl() = default;
-
-void LinkWatcherImpl::Notify(fuchsia::mem::Buffer json) {
- std::string json_string;
- FXL_CHECK(fsl::StringFromVmo(json, &json_string));
- ProcessNewValue(json_string);
-}
-
-void LinkWatcherImpl::ProcessNewValue(const fidl::StringPtr& value) {
- // We are looking for the following |value| structures:
- //
- // 1) |value| contains a JSON-style entity:
- // { "@type": ..., ... }
- // 2) |value| contains a JSON-encoded fuchsia::modular::Entity reference
- // (EntityReferenceFromJson() will return true).
- // 3) |value| is a JSON dictionary, and any of the members satisfies either
- // (1) or (2).
- //
- // TODO(thatguy): Moving to Bundles allows us to ignore (3), and using
- // Entities everywhere allows us to ignore (1).
- modular::JsonDoc doc;
- doc.Parse(value);
- FXL_CHECK(!doc.HasParseError());
-
- if (!doc.IsObject()) {
- return;
- }
-
- // (1) & (2)
- std::vector<std::string> types;
- std::string ref;
- if (modular::ExtractEntityTypesFromJson(doc, &types) ||
- modular::EntityReferenceFromJson(doc, &ref)) {
- // There is only *one* fuchsia::modular::Entity in this
- // fuchsia::modular::Link.
- entity_node_writers_.clear();
- if (!single_entity_node_writer_.is_bound()) {
- link_node_writer_->CreateChildValue(
- single_entity_node_writer_.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- }
- // TODO(thatguy): The context engine expects an fuchsia::modular::Entity
- // reference to be written directly as the content, versus the way Links
- // wrap the reference in JSON. It'd be good to normalize on one encoded
- // representation for fuchsia::modular::Entity references in the context
- // engine.
- if (ref.empty()) {
- single_entity_node_writer_->Set(value, nullptr);
- } else {
- single_entity_node_writer_->Set(ref, nullptr);
- }
- return;
- } else {
- // There is not simply a *single* fuchsia::modular::Entity in this
- // fuchsia::modular::Link. There may be multiple Entities (see below).
- single_entity_node_writer_.Unbind();
- }
-
- // (3)
- std::set<std::string> keys_that_have_entities;
- for (auto it = doc.MemberBegin(); it != doc.MemberEnd(); ++it) {
- if (modular::ExtractEntityTypesFromJson(it->value, &types) ||
- modular::EntityReferenceFromJson(it->value, &ref)) {
- keys_that_have_entities.insert(it->name.GetString());
-
- auto value_it = entity_node_writers_.find(it->name.GetString());
- if (value_it == entity_node_writers_.end()) {
- fuchsia::modular::ContextValueWriterPtr writer;
- link_node_writer_->CreateChildValue(
- writer.NewRequest(), fuchsia::modular::ContextValueType::ENTITY);
- value_it = entity_node_writers_
- .emplace(it->name.GetString(), std::move(writer))
- .first;
- }
- value_it->second->Set(modular::JsonValueToString(it->value), nullptr);
- }
- }
-
- // Clean up any old entries in |entity_node_writers_|.
- std::set<std::string> to_remove;
- for (const auto& entry : entity_node_writers_) {
- if (keys_that_have_entities.count(entry.first) == 0) {
- to_remove.insert(entry.first);
- }
- }
- for (const auto& key : to_remove) {
- entity_node_writers_.erase(key);
- }
-}
-
-} // namespace maxwell
diff --git a/bin/acquirers/story_info/link_watcher_impl.h b/bin/acquirers/story_info/link_watcher_impl.h
deleted file mode 100644
index 39379d4..0000000
--- a/bin/acquirers/story_info/link_watcher_impl.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_ACQUIRERS_STORY_INFO_LINK_WATCHER_IMPL_H_
-#define PERIDOT_BIN_ACQUIRERS_STORY_INFO_LINK_WATCHER_IMPL_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-
-namespace maxwell {
-
-class StoryWatcherImpl;
-
-class LinkWatcherImpl : fuchsia::modular::LinkWatcher {
- public:
- LinkWatcherImpl(StoryWatcherImpl* const owner,
- fuchsia::modular::StoryController* const story_controller,
- const std::string& story_id,
- fuchsia::modular::ContextValueWriter* story_value,
- fuchsia::modular::LinkPath link_path);
-
- ~LinkWatcherImpl() override;
-
- private:
- // |LinkWatcher|
- void Notify(fuchsia::mem::Buffer json) override;
-
- void ProcessNewValue(const fidl::StringPtr& value);
- void MaybeProcessContextLink(const fidl::StringPtr& value);
-
- StoryWatcherImpl* const owner_;
- fuchsia::modular::StoryController* const story_controller_;
-
- const std::string story_id_;
- const fuchsia::modular::LinkPath link_path_;
-
- // Allows us to write the initial fuchsia::modular::Link node in the Context
- // engine, and then create child nodes for each fuchsia::modular::Entity we
- // see in the fuchsia::modular::Link.
- fuchsia::modular::ContextValueWriterPtr link_node_writer_;
-
- // When applicable: Per top-level JSON member key in the
- // fuchsia::modular::Link value, a value writer that allows us to store the
- // contained fuchsia::modular::Entity.
- //
- // See the documentation in ProcessNewValue() for more details.
- std::map<std::string, fuchsia::modular::ContextValueWriterPtr>
- entity_node_writers_;
- // TODO(thatguy): When Bundles come online, remove |entity_values_| in favor
- // of this. Rename to |entity_value_|.
- fuchsia::modular::ContextValueWriterPtr single_entity_node_writer_;
-
- // Per context link topic, the context value.
- // TODO(thatguy): Deprecate this usage in favor of Links.
- std::map<fidl::StringPtr, fuchsia::modular::ContextValueWriterPtr>
- topic_node_writers_;
-
- fuchsia::modular::LinkPtr link_ptr_;
- fidl::Binding<fuchsia::modular::LinkWatcher> link_watcher_binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LinkWatcherImpl);
-};
-
-} // namespace maxwell
-
-#endif // PERIDOT_BIN_ACQUIRERS_STORY_INFO_LINK_WATCHER_IMPL_H_
diff --git a/bin/acquirers/story_info/meta/story_info.cmx b/bin/acquirers/story_info/meta/story_info.cmx
deleted file mode 100644
index 27ee011..0000000
--- a/bin/acquirers/story_info/meta/story_info.cmx
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.modular.AgentContext",
- "fuchsia.modular.FocusProvider",
- "fuchsia.modular.IntelligenceServices",
- "fuchsia.modular.StoryProvider",
- "fuchsia.modular.VisibleStoriesProvider"
- ]
- }
-}
diff --git a/bin/acquirers/story_info/story_info.cc b/bin/acquirers/story_info/story_info.cc
deleted file mode 100644
index a295905..0000000
--- a/bin/acquirers/story_info/story_info.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/acquirers/story_info/story_info.h"
-
-#include <sstream>
-
-#include "peridot/bin/acquirers/story_info/story_watcher_impl.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "rapidjson/document.h"
-#include "rapidjson/stringbuffer.h"
-#include "rapidjson/writer.h"
-
-namespace maxwell {
-
-StoryInfoAcquirer::StoryInfoAcquirer(modular::AgentHost* const agent_host)
- : visible_stories_watcher_binding_(this),
- story_provider_watcher_binding_(this),
- focus_watcher_binding_(this) {
- // Initialize fuchsia::modular::IntelligenceServices.
- fuchsia::modular::IntelligenceServicesPtr intelligence_services;
- agent_host->startup_context()->ConnectToEnvironmentService(
- intelligence_services.NewRequest());
- intelligence_services->GetContextWriter(context_writer_.NewRequest());
- intelligence_services->GetContextReader(context_reader_.NewRequest());
-
- // Watch for changes to what Stories are visible.
- agent_host->startup_context()->ConnectToEnvironmentService(
- visible_stories_provider_.NewRequest());
- visible_stories_provider_->Watch(
- visible_stories_watcher_binding_.NewBinding());
-
- // Watch for changes in Story state.
- agent_host->startup_context()->ConnectToEnvironmentService(
- story_provider_.NewRequest());
- story_provider_->GetStories(
- story_provider_watcher_binding_.NewBinding(),
- [this](std::vector<fuchsia::modular::StoryInfo> stories) {
- for (const auto& story : stories) {
- stories_.emplace(
- std::make_pair(story.id, std::make_unique<StoryWatcherImpl>(
- this, context_writer_.get(),
- story_provider_.get(), story.id)));
- }
- });
-
- // Watch for changes in the focused Story.
- agent_host->startup_context()->ConnectToEnvironmentService(
- focus_provider_.NewRequest());
- focus_provider_->Watch(focus_watcher_binding_.NewBinding());
-
- // Write initial values for visible stories.
- OnVisibleStoriesChange({});
-}
-
-StoryInfoAcquirer::~StoryInfoAcquirer() = default;
-
-void StoryInfoAcquirer::DropStoryWatcher(const std::string& story_id) {
- stories_.erase(story_id);
-}
-
-void StoryInfoAcquirer::Connect(
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services) {
- agent_services_.AddBinding(std::move(services));
-}
-
-void StoryInfoAcquirer::RunTask(
- const fidl::StringPtr& task_id,
- const fuchsia::modular::Agent::RunTaskCallback& callback) {
- FXL_LOG(FATAL) << "Not implemented.";
-}
-
-void StoryInfoAcquirer::Terminate(const std::function<void()>& done) { done(); }
-
-void StoryInfoAcquirer::OnFocusChange(fuchsia::modular::FocusInfoPtr info) {
- // Set all stories to *not* focused, then set the one that's focused to
- // "focused".
- for (const auto& e : stories_) {
- if (!info->focused_story_id || e.first != info->focused_story_id) {
- e.second->OnFocusChange(false);
- }
- }
- if (info->focused_story_id) {
- auto it = stories_.find(info->focused_story_id);
- if (it == stories_.end()) {
- FXL_LOG(ERROR)
- << "RACE CONDITION: I was notified that story "
- << info->focused_story_id
- << " was focused before being notified it exists in the first place.";
- return;
- }
- it->second->OnFocusChange(true);
- }
-}
-
-void StoryInfoAcquirer::OnVisibleStoriesChange(
- fidl::VectorPtr<std::string> ids) {
- // TODO(thatguy)
-}
-
-void StoryInfoAcquirer::OnChange(fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state,
- fuchsia::modular::StoryVisibilityState) {
- // Here we only check if a story is new, and if so create a StoryWatcherImpl.
- // We proxy all future change events to it.
- auto it = stories_.find(info.id);
- if (it == stories_.end()) {
- auto ret = stories_.emplace(std::make_pair(
- info.id,
- std::make_unique<StoryWatcherImpl>(this, context_writer_.get(),
- story_provider_.get(), info.id)));
- it = ret.first;
- }
- it->second->OnStoryStateChange(std::move(info), state);
-}
-
-void StoryInfoAcquirer::OnDelete(std::string story_id) {
- const std::string id = story_id;
- // TODO(thatguy)
-}
-
-} // namespace maxwell
diff --git a/bin/acquirers/story_info/story_info.h b/bin/acquirers/story_info/story_info.h
deleted file mode 100644
index 6e4589b..0000000
--- a/bin/acquirers/story_info/story_info.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_ACQUIRERS_STORY_INFO_STORY_INFO_H_
-#define PERIDOT_BIN_ACQUIRERS_STORY_INFO_STORY_INFO_H_
-
-#include <map>
-#include <set>
-
-#include <fuchsia/maxwell/internal/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-#include <lib/svc/cpp/service_namespace.h>
-
-namespace maxwell {
-
-class StoryWatcherImpl;
-
-// This class pulls info about Stories from Framework and stores it in
-// the Context service.
-//
-// It maintains a hierarchy of context values to represent:
-// Stories -> Modules
-// -> Link Entities
-//
-// TODO(thatguy): Add Link value types to the Context engine and use them
-// here. Then update the resulting published value to remove its added JSON
-// structure, since it will all be represented in the metadata of the value.
-class StoryInfoAcquirer : public fuchsia::modular::VisibleStoriesWatcher,
- public fuchsia::modular::StoryProviderWatcher,
- public fuchsia::modular::FocusWatcher {
- public:
- StoryInfoAcquirer(modular::AgentHost* agent_host);
- ~StoryInfoAcquirer() override;
-
- // Called by AgentDriver.
- void Connect(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services);
-
- // Called by AgentDriver.
- void RunTask(const fidl::StringPtr& task_id,
- const fuchsia::modular::Agent::RunTaskCallback& callback);
-
- // Called by AgentDriver.
- void Terminate(const std::function<void()>& done);
-
- // Used by StoryWatcherImpl.
- void DropStoryWatcher(const std::string& story_id);
-
- private:
- // |fuchsia::modular::FocusWatcher|
- void OnFocusChange(fuchsia::modular::FocusInfoPtr info) override;
-
- // |fuchsia::modular::VisibleStoriesWatcher|
- void OnVisibleStoriesChange(fidl::VectorPtr<std::string> ids) override;
-
- // |fuchsia::modular::StoryProviderWatcher|
- void OnChange(
- fuchsia::modular::StoryInfo info, fuchsia::modular::StoryState state,
- fuchsia::modular::StoryVisibilityState visibility_state) override;
- void OnDelete(std::string story_id) override;
-
- fuchsia::modular::ContextWriterPtr context_writer_;
- fuchsia::modular::ContextReaderPtr context_reader_;
- fuchsia::modular::StoryProviderPtr story_provider_;
- fuchsia::modular::FocusProviderPtr focus_provider_;
- fuchsia::modular::VisibleStoriesProviderPtr visible_stories_provider_;
-
- fidl::Binding<fuchsia::modular::VisibleStoriesWatcher>
- visible_stories_watcher_binding_;
- fidl::Binding<fuchsia::modular::StoryProviderWatcher>
- story_provider_watcher_binding_;
- fidl::Binding<fuchsia::modular::FocusWatcher> focus_watcher_binding_;
-
- // Local state.
- // story id -> context value id
- std::map<fidl::StringPtr, fidl::StringPtr> story_value_ids_;
- fidl::StringPtr focused_story_id_;
- std::set<fidl::StringPtr> visible_story_ids_;
-
- // A collection of all active stories we watch. Keys are story IDs, Values are
- // the fuchsia::modular::StoryWatcher instances.
- std::map<std::string, std::unique_ptr<StoryWatcherImpl>> stories_;
-
- component::ServiceNamespace agent_services_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryInfoAcquirer);
-};
-
-} // namespace maxwell
-
-#endif // PERIDOT_BIN_ACQUIRERS_STORY_INFO_STORY_INFO_H_
diff --git a/bin/acquirers/story_info/story_info_main.cc b/bin/acquirers/story_info/story_info_main.cc
deleted file mode 100644
index c8eafb5..0000000
--- a/bin/acquirers/story_info/story_info_main.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-
-#include "peridot/bin/acquirers/story_info/story_info.h"
-
-int main(int argc, const char** argv) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<maxwell::StoryInfoAcquirer> driver(
- context.get(), [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/bin/acquirers/story_info/story_watcher_impl.cc b/bin/acquirers/story_info/story_watcher_impl.cc
deleted file mode 100644
index 9a1b6d6..0000000
--- a/bin/acquirers/story_info/story_watcher_impl.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/acquirers/story_info/story_watcher_impl.h"
-
-#include <lib/context/cpp/context_metadata_builder.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/bin/acquirers/story_info/link_watcher_impl.h"
-#include "peridot/bin/acquirers/story_info/story_info.h"
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h" // MakeLinkKey, EncodeModulePath
-
-namespace maxwell {
-
-StoryWatcherImpl::StoryWatcherImpl(
- StoryInfoAcquirer* const owner,
- fuchsia::modular::ContextWriter* const writer,
- fuchsia::modular::StoryProvider* const story_provider,
- const std::string& story_id)
- : owner_(owner),
- writer_(writer),
- story_id_(story_id),
- story_watcher_binding_(this),
- story_links_watcher_binding_(this) {
- story_provider->GetController(story_id, story_controller_.NewRequest());
-
- story_controller_.set_error_handler(
- [this](zx_status_t status) { owner_->DropStoryWatcher(story_id_); });
-
- story_controller_->Watch(story_watcher_binding_.NewBinding());
-
- story_watcher_binding_.set_error_handler(
- [this](zx_status_t status) { owner_->DropStoryWatcher(story_id_); });
-
- context_metadata_ = ContextMetadataBuilder()
- .SetStoryId(story_id)
- .SetStoryFocused(false)
- .Build();
- // TODO(thatguy): Add StoryState.
- // TODO(thatguy): Add visible state.
-
- writer_->CreateValue(context_value_.NewRequest(),
- fuchsia::modular::ContextValueType::STORY);
- fuchsia::modular::ContextMetadata metadata;
- fidl::Clone(context_metadata_, &metadata);
- context_value_->Set(nullptr /* content */,
- fidl::MakeOptional(std::move(metadata)));
-
- story_controller_->GetActiveLinks(
- story_links_watcher_binding_.NewBinding(),
- [this](std::vector<fuchsia::modular::LinkPath> links) mutable {
- for (fuchsia::modular::LinkPath& link_path : links) {
- WatchLink(std::move(link_path));
- }
- });
-}
-
-StoryWatcherImpl::~StoryWatcherImpl() = default;
-
-void StoryWatcherImpl::OnStateChange(fuchsia::modular::StoryState new_state) {
- // TODO(thatguy): Add recording of state to fuchsia::modular::StoryMetadata.
-}
-
-void StoryWatcherImpl::OnModuleAdded(fuchsia::modular::ModuleData module_data) {
- ContextModuleMetadata data;
- context_value_->CreateChildValue(data.value_writer.NewRequest(),
- fuchsia::modular::ContextValueType::MODULE);
- auto metadata = ContextMetadataBuilder()
- .SetModuleUrl(module_data.module_url)
- .SetModulePath(module_data.module_path)
- .Build();
- fidl::Clone(metadata, &data.metadata);
- data.value_writer->Set(nullptr /* content */,
- fidl::MakeOptional(std::move(metadata)));
- auto path = modular::EncodeModulePath(module_data.module_path);
- module_values_.emplace(path, std::move(data));
-}
-
-void StoryWatcherImpl::OnModuleFocused(
- std::vector<std::string> module_path) {
- auto key = modular::EncodeModulePath(module_path);
- auto it = module_values_.find(key);
- if (it == module_values_.end()) {
- return;
- }
- if (!last_module_focus_key_.empty()) {
- auto it_last = module_values_.find(last_module_focus_key_);
- if (it_last != module_values_.end()) {
- UpdateModuleFocus(&it_last->second, false);
- }
- }
- UpdateModuleFocus(&it->second, true);
- last_module_focus_key_ = key;
-}
-
-void StoryWatcherImpl::OnNewLink(fuchsia::modular::LinkPath link_path) {
- WatchLink(std::move(link_path));
-}
-
-void StoryWatcherImpl::WatchLink(fuchsia::modular::LinkPath link_path) {
- links_.emplace(std::make_pair(
- modular::MakeLinkKey(link_path),
- std::make_unique<LinkWatcherImpl>(this, story_controller_.get(),
- story_id_, context_value_.get(),
- std::move(link_path))));
-}
-
-void StoryWatcherImpl::OnFocusChange(bool focused) {
- context_metadata_ = ContextMetadataBuilder(std::move(context_metadata_))
- .SetStoryFocused(focused)
- .Build();
- fuchsia::modular::ContextMetadata metadata;
- fidl::Clone(context_metadata_, &metadata);
- context_value_->Set(nullptr /* content */,
- fidl::MakeOptional(std::move(metadata)));
-}
-
-void StoryWatcherImpl::OnStoryStateChange(fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- // TODO(thatguy): Record this state too.
-}
-
-void StoryWatcherImpl::DropLink(const std::string& link_key) {
- links_.erase(link_key);
-}
-
-void StoryWatcherImpl::UpdateModuleFocus(ContextModuleMetadata* data,
- bool focused) {
- auto metadata = ContextMetadataBuilder(std::move(data->metadata))
- .SetModuleFocused(focused)
- .Build();
- fidl::Clone(metadata, &data->metadata);
- data->value_writer->Set(nullptr /* content */,
- fidl::MakeOptional(std::move(metadata)));
-}
-
-} // namespace maxwell
diff --git a/bin/acquirers/story_info/story_watcher_impl.h b/bin/acquirers/story_info/story_watcher_impl.h
deleted file mode 100644
index 09f4049..0000000
--- a/bin/acquirers/story_info/story_watcher_impl.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_ACQUIRERS_STORY_INFO_STORY_WATCHER_IMPL_H_
-#define PERIDOT_BIN_ACQUIRERS_STORY_INFO_STORY_WATCHER_IMPL_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-
-namespace maxwell {
-
-class StoryInfoAcquirer;
-class LinkWatcherImpl;
-
-class StoryWatcherImpl : fuchsia::modular::StoryWatcher,
- fuchsia::modular::StoryLinksWatcher {
- public:
- StoryWatcherImpl(StoryInfoAcquirer* const owner,
- fuchsia::modular::ContextWriter* const writer,
- fuchsia::modular::StoryProvider* const story_provider,
- const std::string& story_id);
-
- ~StoryWatcherImpl() override;
-
- // Used by LinkWatcherImpl.
- void DropLink(const std::string& link_key);
-
- // Used by |owner_|.
- void OnStoryStateChange(fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state);
- void OnFocusChange(bool focused);
-
- private:
- struct ContextModuleMetadata {
- fuchsia::modular::ContextMetadata metadata;
- fuchsia::modular::ContextValueWriterPtr value_writer;
- };
-
- // |fuchsia::modular::StoryWatcher|
- void OnStateChange(fuchsia::modular::StoryState new_state) override;
-
- // |fuchsia::modular::StoryWatcher|
- void OnModuleAdded(fuchsia::modular::ModuleData module_data) override;
-
- // |fuchsia::modular::StoryWatcher|
- void OnModuleFocused(std::vector<std::string> module_path) override;
-
- // |fuchsia::modular::StoryLinksWatcher|
- void OnNewLink(fuchsia::modular::LinkPath link_path) override;
-
- void WatchLink(fuchsia::modular::LinkPath link_path);
-
- void UpdateModuleFocus(ContextModuleMetadata* data, bool focused);
-
- StoryInfoAcquirer* const owner_;
- fuchsia::modular::ContextWriter* const writer_;
- fuchsia::modular::StoryControllerPtr story_controller_;
- const std::string story_id_;
- fuchsia::modular::ContextValueWriterPtr context_value_;
- fuchsia::modular::ContextMetadata context_metadata_;
-
- fidl::Binding<fuchsia::modular::StoryWatcher> story_watcher_binding_;
- fidl::Binding<fuchsia::modular::StoryLinksWatcher>
- story_links_watcher_binding_;
-
- std::map<std::string, std::unique_ptr<LinkWatcherImpl>> links_;
- // serialized module path -> context value.
- std::map<std::string, ContextModuleMetadata> module_values_;
-
- std::string last_module_focus_key_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryWatcherImpl);
-};
-
-} // namespace maxwell
-
-#endif // PERIDOT_BIN_ACQUIRERS_STORY_INFO_STORY_WATCHER_IMPL_H_
diff --git a/bin/agents/clipboard/BUILD.gn b/bin/agents/clipboard/BUILD.gn
deleted file mode 100644
index 5aa75de..0000000
--- a/bin/agents/clipboard/BUILD.gn
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-import("//peridot/build/tests_package.gni")
-
-executable_package("clipboard_agent") {
-
- meta = [
- {
- path = "meta/clipboard_agent.cmx"
- dest = "clipboard_agent.cmx"
- },
- ]
-
- sources = [
- "clipboard_agent.cc",
- ]
-
- deps = [
- ":clipboard_sources",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/public/lib/app_driver/cpp:agent_driver",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-source_set("clipboard_sources") {
- sources = [
- "clipboard_impl.cc",
- "clipboard_impl.h",
- "clipboard_storage.cc",
- "clipboard_storage.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-executable("clipboard_impl_unittest") {
- testonly = true
-
- sources = [
- "clipboard_impl_unittest.cc",
- ]
-
- deps = [
- ":clipboard_sources",
- "//garnet/public/lib/gtest",
- "//peridot/lib/testing:test_with_ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-tests_package("clipboard_unittests") {
- deps = [
- ":clipboard_impl_unittest",
- ]
-}
diff --git a/bin/agents/clipboard/clipboard_agent.cc b/bin/agents/clipboard/clipboard_agent.cc
deleted file mode 100644
index 168ec57..0000000
--- a/bin/agents/clipboard/clipboard_agent.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-
-#include "peridot/bin/agents/clipboard/clipboard_impl.h"
-#include "peridot/bin/agents/clipboard/clipboard_storage.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-
-namespace modular {
-
-// An agent responsible for providing the fuchsia::modular::Clipboard service.
-class ClipboardAgent {
- public:
- ClipboardAgent(AgentHost* const agent_host) {
- fuchsia::modular::ComponentContextPtr component_context;
- agent_host->agent_context()->GetComponentContext(
- component_context.NewRequest());
-
- fuchsia::ledger::LedgerPtr ledger;
- ledger.set_error_handler([](zx_status_t status) {
- FXL_LOG(ERROR) << "Ledger connection died: " << status;
- });
- component_context->GetLedger(ledger.NewRequest());
-
- ledger_client_ = std::make_unique<LedgerClient>(std::move(ledger));
-
- clipboard_ = std::make_unique<ClipboardImpl>(ledger_client_.get());
-
- services_.AddService<fuchsia::modular::Clipboard>(
- [this](fidl::InterfaceRequest<fuchsia::modular::Clipboard> request) {
- clipboard_->Connect(std::move(request));
- });
- }
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> outgoing_services) {
- services_.AddBinding(std::move(outgoing_services));
- }
-
- void RunTask(const fidl::StringPtr& task_id,
- const std::function<void()>& done) {
- done();
- }
-
- void Terminate(const std::function<void()>& done) { done(); }
-
- private:
- // The ledger client that is provided to the ClipboardImpl.
- std::unique_ptr<LedgerClient> ledger_client_;
-
- std::unique_ptr<ClipboardImpl> clipboard_;
-
- // The service namespace that the fuchsia::modular::Clipboard is added to.
- component::ServiceNamespace services_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ClipboardAgent);
-};
-
-} // namespace modular
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<modular::ClipboardAgent> driver(
- context.get(), [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/bin/agents/clipboard/clipboard_impl.cc b/bin/agents/clipboard/clipboard_impl.cc
deleted file mode 100644
index 33eb1a8..0000000
--- a/bin/agents/clipboard/clipboard_impl.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/agents/clipboard/clipboard_impl.h"
-
-#include <string>
-
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/ledger_client/page_id.h"
-
-namespace modular {
-namespace {
-constexpr char kClipboardImplPageId[] = "ClipboardPage___"; // 16 chars
-} // namespace
-
-ClipboardImpl::ClipboardImpl(LedgerClient* ledger_client)
- : storage_(ledger_client, MakePageId(kClipboardImplPageId)) {}
-
-ClipboardImpl::~ClipboardImpl() = default;
-
-void ClipboardImpl::Push(std::string text) { storage_.Push(text); }
-
-void ClipboardImpl::Peek(PeekCallback callback) { storage_.Peek(callback); }
-
-void ClipboardImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::Clipboard> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-} // namespace modular
diff --git a/bin/agents/clipboard/clipboard_impl.h b/bin/agents/clipboard/clipboard_impl.h
deleted file mode 100644
index 9f3b605..0000000
--- a/bin/agents/clipboard/clipboard_impl.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_AGENTS_CLIPBOARD_CLIPBOARD_IMPL_H_
-#define PERIDOT_BIN_AGENTS_CLIPBOARD_CLIPBOARD_IMPL_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/agents/clipboard/clipboard_storage.h"
-
-namespace modular {
-
-// An agent responsible for providing the fuchsia::modular::Clipboard service.
-class ClipboardImpl : fuchsia::modular::Clipboard {
- public:
- explicit ClipboardImpl(LedgerClient* ledger_client);
- ~ClipboardImpl() override;
-
- void Connect(fidl::InterfaceRequest<fuchsia::modular::Clipboard> request);
-
- private:
- // |fuchsia::modular::Clipboard|
- void Push(std::string text) override;
-
- // |fuchsia::modular::Clipboard|
- void Peek(PeekCallback callback) override;
-
- // The storage instance that manages interactions with the Ledger.
- ClipboardStorage storage_;
-
- // The bindings set containing the outgoing services request from the agent
- // driver.
- fidl::BindingSet<fuchsia::modular::Clipboard> bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ClipboardImpl);
- friend class ClipboardImplTest;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_AGENTS_CLIPBOARD_CLIPBOARD_IMPL_H_
diff --git a/bin/agents/clipboard/clipboard_impl_unittest.cc b/bin/agents/clipboard/clipboard_impl_unittest.cc
deleted file mode 100644
index 65ed49f..0000000
--- a/bin/agents/clipboard/clipboard_impl_unittest.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/agents/clipboard/clipboard_impl.h"
-
-#include <string>
-
-#include "peridot/lib/testing/test_with_ledger.h"
-
-namespace modular {
-
-class ClipboardImplTest : public testing::TestWithLedger {
- public:
- ClipboardImplTest() = default;
-
- void SetUp() override {
- TestWithLedger::SetUp();
-
- clipboard_ = std::make_unique<ClipboardImpl>(ledger_client());
- }
-
- void TearDown() override {
- clipboard_.reset();
-
- TestWithLedger::TearDown();
- }
-
- protected:
- void Push(const std::string& text) { clipboard_->Push(text); }
-
- void Peek(const fuchsia::modular::Clipboard::PeekCallback& callback) {
- clipboard_->Peek(callback);
- }
-
- std::unique_ptr<ClipboardImpl> clipboard_;
-};
-
-namespace {
-
-TEST_F(ClipboardImplTest, FirstPeek) {
- bool callback_called = false;
- Peek([&callback_called](const fidl::StringPtr& text) {
- EXPECT_EQ("", text);
- callback_called = true;
- });
-
- RunLoopWithTimeoutOrUntil([&callback_called] { return callback_called; });
-}
-
-TEST_F(ClipboardImplTest, PushAndPeek) {
- bool callback_called = false;
- std::string expected_value = "a test string";
- Push(expected_value);
- Peek([&callback_called, expected_value](const fidl::StringPtr& text) {
- EXPECT_EQ(expected_value, text);
- callback_called = true;
- });
-
- RunLoopWithTimeoutOrUntil([&callback_called] { return callback_called; });
-}
-
-TEST_F(ClipboardImplTest, PushAndPeekTwice) {
- int callback_called = 0;
- std::string expected_value = "a test string";
- Push(expected_value);
- Peek([&callback_called, expected_value](const fidl::StringPtr& text) {
- EXPECT_EQ(expected_value, text);
- callback_called++;
- });
- Peek([&callback_called, expected_value](const fidl::StringPtr& text) {
- EXPECT_EQ(expected_value, text);
- callback_called++;
- });
-
- RunLoopWithTimeoutOrUntil(
- [&callback_called] { return callback_called == 2; });
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/agents/clipboard/clipboard_storage.cc b/bin/agents/clipboard/clipboard_storage.cc
deleted file mode 100644
index d65a90e..0000000
--- a/bin/agents/clipboard/clipboard_storage.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/agents/clipboard/clipboard_storage.h"
-
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-namespace modular {
-namespace {
-
-fidl::VectorPtr<uint8_t> ToArray(const std::string& str) {
- auto array = fidl::VectorPtr<uint8_t>::New(str.size());
- memcpy(array->data(), str.data(), str.size());
- return array;
-}
-
-std::string ToString(fuchsia::mem::Buffer value) {
- fsl::SizedVmo vmo;
- std::string parsed_string;
- if (!fsl::SizedVmo::FromTransport(std::move(value), &vmo)) {
- FXL_LOG(ERROR) << "Could not decode clipboard value.";
- return "";
- }
- if (!fsl::StringFromVmo(vmo, &parsed_string)) {
- FXL_LOG(ERROR)
- << "fuchsia::modular::Clipboard vmo could not be decoded to string.";
- return "";
- }
- return parsed_string;
-}
-
-// The Ledger key that is used to store the current value.
-constexpr char kCurrentValueKey[] = "current_value";
-
-} // namespace
-
-class ClipboardStorage::PushCall : public Operation<> {
- public:
- PushCall(ClipboardStorage* const impl, const fidl::StringPtr& text)
- : Operation("ClipboardStorage::PushCall", [] {}),
- impl_(impl),
- text_(text) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- impl_->page()->Put(ToArray(kCurrentValueKey), ToArray(text_),
- [this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "Failed to put text: " << text_;
- }
- });
- }
-
- ClipboardStorage* const impl_; // not owned
- const fidl::StringPtr text_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PushCall);
-};
-
-class ClipboardStorage::PeekCall : public Operation<fidl::StringPtr> {
- public:
- PeekCall(ClipboardStorage* const impl,
- std::function<void(fidl::StringPtr)> result)
- : Operation("ClipboardStorage::PeekCall", std::move(result)),
- impl_(impl) {
- // No error checking: Absent ledger value yields "", not
- // null. TODO(mesch): Once we support types, distinction of
- // null may make sense.
- text_.reset("");
- }
-
- private:
- void Run() override {
- FlowToken flow{this, &text_};
- impl_->page()->GetSnapshot(
- snapshot_.NewRequest(), fidl::VectorPtr<uint8_t>::New(0), nullptr,
- [](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "Failed to get page snapshot";
- }
- });
-
- snapshot_->Get(ToArray(kCurrentValueKey),
- [this, flow](fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr value) {
- if (value) {
- text_ = ToString(std::move(*value));
- }
- });
- }
-
- ClipboardStorage* const impl_; // not owned
- fuchsia::ledger::PageSnapshotPtr snapshot_;
- fidl::StringPtr text_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PeekCall);
-};
-
-ClipboardStorage::ClipboardStorage(LedgerClient* ledger_client,
- LedgerPageId page_id)
- : PageClient("ClipboardStorage", ledger_client, std::move(page_id)) {}
-
-ClipboardStorage::~ClipboardStorage() = default;
-
-void ClipboardStorage::Push(const fidl::StringPtr& text) {
- operation_queue_.Add(new PushCall(this, text));
-}
-
-void ClipboardStorage::Peek(
- const std::function<void(fidl::StringPtr)>& callback) {
- operation_queue_.Add(new PeekCall(this, callback));
-}
-
-} // namespace modular
diff --git a/bin/agents/clipboard/clipboard_storage.h b/bin/agents/clipboard/clipboard_storage.h
deleted file mode 100644
index c42e34a..0000000
--- a/bin/agents/clipboard/clipboard_storage.h
+++ /dev/null
@@ -1,47 +0,0 @@
-
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_AGENTS_CLIPBOARD_CLIPBOARD_STORAGE_H_
-#define PERIDOT_BIN_AGENTS_CLIPBOARD_CLIPBOARD_STORAGE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-
-namespace modular {
-
-// |ClipboardStorage| manages serialization of clipboard data to and from the
-// Ledger.
-//
-// A Ledger is scoped to a single user, so each user has their own clipboard.
-// Using the Ledger for the clipboard means that the same clipboard is shared
-// across all of a user's devices. The clipboard will also persist across
-// reboots.
-class ClipboardStorage : public PageClient {
- public:
- ClipboardStorage(LedgerClient* ledger_client, LedgerPageId page_id);
- ~ClipboardStorage() override;
-
- // Stores the provided text.
- void Push(const fidl::StringPtr& text);
-
- // Returns the most recent value that was passed to |Push()|, or "" if nothing
- // has been pushed yet.
- void Peek(const std::function<void(fidl::StringPtr)>& callback);
-
- private:
- OperationQueue operation_queue_;
-
- class PushCall;
- class PeekCall;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ClipboardStorage);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_AGENTS_CLIPBOARD_CLIPBOARD_STORAGE_H_
diff --git a/bin/agents/clipboard/meta/clipboard_agent.cmx b/bin/agents/clipboard/meta/clipboard_agent.cmx
deleted file mode 100644
index fdcd999..0000000
--- a/bin/agents/clipboard/meta/clipboard_agent.cmx
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.AgentContext",
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.netconnector.NetConnector",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/bin/basemgr/BUILD.gn b/bin/basemgr/BUILD.gn
deleted file mode 100644
index 049f6f6..0000000
--- a/bin/basemgr/BUILD.gn
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-import("//peridot/build/executable_package.gni")
-import("//peridot/build/tests_package.gni")
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-declare_args() {
- # Whether basemgr should automatically login as a guest user.
- auto_login_to_guest = false
-}
-
-flatbuffer("users") {
- sources = [
- "users.fbs",
- ]
-}
-
-executable_package("basemgr") {
- meta = [
- {
- path = "meta/basemgr.cmx"
- dest = "basemgr.cmx"
- },
- ]
-
- sources = [
- "basemgr_impl.cc",
- "basemgr_impl.h",
- "basemgr_settings.cc",
- "basemgr_settings.h",
- "main.cc",
- ]
-
- deps = [
- ":lib",
- "//garnet/public/fidl/fuchsia.auth",
- "//garnet/public/fidl/fuchsia.devicesettings",
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/bin/basemgr/cobalt",
- "//peridot/lib/common:async_holder",
- "//peridot/lib/common:names",
- "//peridot/lib/common:teardown",
- "//peridot/lib/fidl:app_client",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/fidl:environment",
- "//peridot/lib/ledger_client:constants",
- "//peridot/lib/session_shell_settings",
- "//peridot/lib/util:filesystem",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/lib/async/cpp:future",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-
- public_deps = [
- "//peridot/bin/basemgr/cobalt:basemgr_metrics_registry",
- ]
-
- resources = [
- {
- path = rebase_path(
- get_label_info(
- "//peridot/bin/basemgr/cobalt:basemgr_metrics_registry",
- "target_gen_dir") + "/basemgr_metrics_registry.pb")
- dest = "basemgr_metrics_registry.pb"
- },
- ]
-}
-
-tests_package("basemgr_unittests") {
- deps = [
- ":user_controller_impl_unittest",
- ]
-}
-
-source_set("lib") {
- sources = [
- "user_controller_impl.cc",
- "user_controller_impl.h",
- "user_provider_impl.cc",
- "user_provider_impl.h",
- ]
-
- deps = [
- ":users",
- "//garnet/public/fidl/fuchsia.auth",
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/common:async_holder",
- "//peridot/lib/common:names",
- "//peridot/lib/common:teardown",
- "//peridot/lib/common:xdr",
- "//peridot/lib/fidl:app_client",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/fidl:environment",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/util:filesystem",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//zircon/public/lib/trace",
- ]
-
- if (auto_login_to_guest) {
- public_configs = [ ":auto_login_to_guest" ]
- }
-}
-
-executable_package("dev_base_shell") {
-
- meta = [
- {
- path = "meta/dev_base_shell.cmx"
- dest = "dev_base_shell.cmx"
- },
- ]
-
- sources = [
- "dev_base_shell.cc",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:single_service_app",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//peridot/public/lib/integration_testing/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable("user_controller_impl_unittest") {
- testonly = true
-
- sources = [
- "user_controller_impl_unittest.cc",
- ]
-
- deps = [
- ":lib",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/component/cpp/testing:fake_launcher",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//peridot/lib/fidl:clone",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-config("auto_login_to_guest") {
- defines = [ "AUTO_LOGIN_TO_GUEST" ]
-}
diff --git a/bin/basemgr/basemgr_impl.cc b/bin/basemgr/basemgr_impl.cc
deleted file mode 100644
index faa5a8e..0000000
--- a/bin/basemgr/basemgr_impl.cc
+++ /dev/null
@@ -1,551 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/basemgr/basemgr_impl.h"
-
-#include <memory>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/basemgr/basemgr_settings.h"
-#include "peridot/bin/basemgr/user_provider_impl.h"
-#include "peridot/lib/common/async_holder.h"
-#include "peridot/lib/common/names.h"
-#include "peridot/lib/common/teardown.h"
-#include "peridot/lib/fidl/app_client.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/session_shell_settings/session_shell_settings.h"
-#include "peridot/lib/util/filesystem.h"
-
-namespace modular {
-
-namespace {
-#ifdef AUTO_LOGIN_TO_GUEST
-constexpr bool kAutoLoginToGuest = true;
-#else
-constexpr bool kAutoLoginToGuest = false;
-#endif
-} // namespace
-
-BasemgrImpl::BasemgrImpl(
- const modular::BasemgrSettings& settings,
- const std::vector<SessionShellSettings>& session_shell_settings,
- fuchsia::sys::Launcher* const launcher,
- fuchsia::ui::policy::PresenterPtr presenter,
- fuchsia::devicesettings::DeviceSettingsManagerPtr device_settings_manager,
- std::function<void()> on_shutdown)
- : settings_(settings),
- session_shell_settings_(session_shell_settings),
- launcher_(launcher),
- presenter_(std::move(presenter)),
- device_settings_manager_(std::move(device_settings_manager)),
- on_shutdown_(std::move(on_shutdown)),
- user_provider_impl_("UserProviderImpl"),
- base_shell_context_binding_(this),
- authentication_context_provider_binding_(this) {
- UpdateSessionShellConfig();
-
- // TODO(SCN-595): Presentation is now discoverable, so we don't need
- // kPresentationService anymore.
- service_namespace_.AddService(presentation_state_.bindings.GetHandler(
- presentation_state_.presentation.get()),
- kPresentationService);
-
- Start();
-}
-
-BasemgrImpl::~BasemgrImpl() = default;
-
-void BasemgrImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::internal::BasemgrDebug> request) {
- basemgr_bindings_.AddBinding(this, std::move(request));
-}
-
-void BasemgrImpl::InitializePresentation(
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner> view_owner) {
- if (settings_.test && !settings_.enable_presenter) {
- return;
- }
-
- auto presentation_request =
- presentation_state_.presentation.is_bound()
- ? presentation_state_.presentation.Unbind().NewRequest()
- : presentation_state_.presentation.NewRequest();
-
- presenter_->Present2(zx::eventpair(view_owner.TakeChannel().release()),
- std::move(presentation_request));
-
- AddGlobalKeyboardShortcuts(presentation_state_.presentation);
-
- SetShadowTechnique(presentation_state_.shadow_technique);
-
- // Set the presentation of the given view to the settings of the active
- // session shell.
- if (active_session_shell_settings_index_ >= session_shell_settings_.size()) {
- FXL_LOG(ERROR) << "Active session shell index is "
- << active_session_shell_settings_index_ << ", but only "
- << session_shell_settings_.size()
- << " session shell settings exist.";
- return;
- }
-
- auto active_session_shell_settings =
- session_shell_settings_[active_session_shell_settings_index_];
- if (active_session_shell_settings.display_usage !=
- fuchsia::ui::policy::DisplayUsage::kUnknown) {
- FXL_DLOG(INFO) << "Setting display usage: "
- << fidl::ToUnderlying(
- active_session_shell_settings.display_usage);
- presentation_state_.presentation->SetDisplayUsage(
- active_session_shell_settings.display_usage);
- }
-
- if (!std::isnan(active_session_shell_settings.screen_width) &&
- !std::isnan(active_session_shell_settings.screen_height)) {
- FXL_DLOG(INFO) << "Setting display size: "
- << active_session_shell_settings.screen_width << " x "
- << active_session_shell_settings.screen_height;
- presentation_state_.presentation->SetDisplaySizeInMm(
- active_session_shell_settings.screen_width,
- active_session_shell_settings.screen_height);
- }
-}
-
-void BasemgrImpl::StartBaseShell() {
- if (base_shell_running_) {
- FXL_DLOG(INFO) << "StartBaseShell() called when already running";
-
- return;
- }
-
- base_shell_app_ = std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- launcher_, CloneStruct(settings_.base_shell));
- base_shell_app_->services().ConnectToService(base_shell_.NewRequest());
-
- fuchsia::ui::viewsv1::ViewProviderPtr base_shell_view_provider;
- base_shell_app_->services().ConnectToService(
- base_shell_view_provider.NewRequest());
-
- // We still need to pass a request for root view to base shell since
- // dev_base_shell (which mimics flutter behavior) blocks until it receives
- // the root view request.
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner> root_view;
- base_shell_view_provider->CreateView(root_view.NewRequest(), nullptr);
-
- InitializePresentation(std::move(root_view));
-
- // Populate parameters and initialize the base shell.
- fuchsia::modular::BaseShellParams params;
- params.presentation = std::move(presentation_state_.presentation);
- base_shell_->Initialize(base_shell_context_binding_.NewBinding(),
- std::move(params));
-
- base_shell_running_ = true;
-}
-
-FuturePtr<> BasemgrImpl::StopBaseShell() {
- if (!base_shell_running_) {
- FXL_DLOG(INFO) << "StopBaseShell() called when already stopped";
-
- return Future<>::CreateCompleted("StopBaseShell::Completed");
- }
-
- auto did_stop = Future<>::Create("StopBaseShell");
-
- base_shell_app_->Teardown(kBasicTimeout, [did_stop, this] {
- FXL_DLOG(INFO) << "- fuchsia::modular::BaseShell down";
-
- base_shell_running_ = false;
- did_stop->Complete();
- });
-
- return did_stop;
-}
-
-FuturePtr<> BasemgrImpl::StopTokenManagerFactoryApp() {
- if (!token_manager_factory_app_) {
- FXL_DLOG(INFO)
- << "StopTokenManagerFactoryApp() called when already stopped";
-
- return Future<>::CreateCompleted("StopTokenManagerFactoryApp::Completed");
- }
-
- auto did_stop = Future<>::Create("StopTokenManagerFactoryApp");
-
- token_manager_factory_app_->Teardown(kBasicTimeout, [did_stop, this] {
- FXL_DLOG(INFO) << "- fuchsia::auth::TokenManagerFactory down";
-
- token_manager_factory_app_.release();
- did_stop->Complete();
- });
-
- return did_stop;
-}
-
-void BasemgrImpl::Start() {
- if (settings_.test) {
- // 0. Print test banner.
- FXL_LOG(INFO)
- << std::endl
- << std::endl
- << "======================== Starting Test [" << settings_.test_name
- << "]" << std::endl
- << "============================================================"
- << std::endl;
- }
-
- // Wait for persistent data to come up.
- if (!settings_.no_minfs) {
- WaitForMinfs();
- }
-
- // Start OAuth Token Manager App.
- token_manager_factory_app_.release();
- fuchsia::modular::AppConfig token_manager_config;
- token_manager_config.url = settings_.account_provider.url;
- token_manager_factory_app_ =
- std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- launcher_, CloneStruct(token_manager_config));
- token_manager_factory_app_->services().ConnectToService(
- token_manager_factory_.NewRequest());
-
- user_provider_impl_.reset(new UserProviderImpl(
- launcher_, settings_.sessionmgr, session_shell_config_,
- settings_.story_shell, token_manager_factory_.get(),
- authentication_context_provider_binding_.NewBinding().Bind(), this));
-
- ShowSetupOrLogin();
-
- ReportEvent(ModularEvent::BOOTED_TO_BASEMGR);
-}
-
-void BasemgrImpl::GetUserProvider(
- fidl::InterfaceRequest<fuchsia::modular::UserProvider> request) {
- user_provider_impl_->Connect(std::move(request));
-}
-
-void BasemgrImpl::Shutdown() {
- // Prevent the shutdown sequence from running twice.
- if (state_ == State::SHUTTING_DOWN) {
- return;
- }
-
- state_ = State::SHUTTING_DOWN;
-
- FXL_DLOG(INFO) << "fuchsia::modular::BaseShellContext::Shutdown()";
-
- if (settings_.test) {
- FXL_LOG(INFO)
- << std::endl
- << "============================================================"
- << std::endl
- << "======================== [" << settings_.test_name << "] Done";
- }
-
- // TODO(mesch): Some of these could be done in parallel too.
- // fuchsia::modular::UserProvider must go first, but the order after user
- // provider is for now rather arbitrary. We terminate base shell last so
- // that in tests testing::Teardown() is invoked at the latest possible time.
- // Right now it just demonstrates that AppTerminate() works as we like it
- // to.
- user_provider_impl_.Teardown(kUserProviderTimeout, [this] {
- FXL_DLOG(INFO) << "- fuchsia::modular::UserProvider down";
- StopTokenManagerFactoryApp()->Then([this] {
- FXL_DLOG(INFO) << "- fuchsia::auth::TokenManagerFactory down";
- StopBaseShell()->Then([this] {
- FXL_LOG(INFO) << "Clean Shutdown";
- on_shutdown_();
- });
- });
- });
-}
-
-void BasemgrImpl::GetAuthenticationUIContext(
- fidl::InterfaceRequest<fuchsia::auth::AuthenticationUIContext> request) {
- // TODO(MI4-1107): Basemgr needs to implement AuthenticationUIContext
- // itself, and proxy calls for StartOverlay & StopOverlay to BaseShell,
- // starting it if it's not running yet.
- FXL_CHECK(base_shell_);
- base_shell_->GetAuthenticationUIContext(std::move(request));
-}
-
-void BasemgrImpl::DidLogin() {
- // Continues if `enable_presenter` is set to true during testing, as
- // ownership of the Presenter should still be moved to the session shell.
- if (settings_.test && !settings_.enable_presenter) {
- // TODO(MI4-1117): Integration tests currently expect base shell to
- // always be running. So, if we're running under a test, do not shut down
- // the base shell after login.
- return;
- }
-
- // TODO(MI4-1117): See above. The base shell shouldn't be shut down.
- if (!settings_.test) {
- FXL_DLOG(INFO) << "Stopping base shell due to login";
- StopBaseShell();
- }
-
- InitializePresentation(session_shell_view_owner_);
-}
-
-void BasemgrImpl::DidLogout() {
- if (settings_.test) {
- // TODO(MI4-1117): Integration tests currently expect base shell to
- // always be running. So, if we're running under a test, DidLogin() will
- // not shut down the base shell after login; thus this method doesn't
- // need to re-start the base shell after a logout.
- return;
- }
-
- FXL_DLOG(INFO) << "Re-starting base shell due to logout";
-
- StartBaseShell();
-}
-
-fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
-BasemgrImpl::GetSessionShellViewOwner(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>) {
- return session_shell_view_owner_.is_bound()
- ? session_shell_view_owner_.Unbind().NewRequest()
- : session_shell_view_owner_.NewRequest();
-}
-
-fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
-BasemgrImpl::GetSessionShellServiceProvider(
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>) {
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> handle;
- service_namespace_.AddBinding(handle.NewRequest());
- return handle;
-}
-
-void BasemgrImpl::OnEvent(fuchsia::ui::input::KeyboardEvent event) {
- switch (event.code_point) {
- case ' ': {
- SwapSessionShell();
- break;
- }
- case 's': {
- SetNextShadowTechnique();
- break;
- }
- case 'l':
- ToggleClipping();
- break;
- default:
- FXL_DLOG(INFO) << "Unknown keyboard event: codepoint=" << event.code_point
- << ", modifiers=" << event.modifiers;
- break;
- }
-}
-
-void BasemgrImpl::AddGlobalKeyboardShortcuts(
- fuchsia::ui::policy::PresentationPtr& presentation) {
- presentation->CaptureKeyboardEventHACK(
- {
- .code_point = ' ', // spacebar
- .modifiers = fuchsia::ui::input::kModifierLeftControl,
- },
- keyboard_capture_listener_bindings_.AddBinding(this));
- presentation->CaptureKeyboardEventHACK(
- {
- .code_point = 's',
- .modifiers = fuchsia::ui::input::kModifierLeftControl,
- },
- keyboard_capture_listener_bindings_.AddBinding(this));
- presentation->CaptureKeyboardEventHACK(
- {
- .code_point = 'l',
- .modifiers = fuchsia::ui::input::kModifierRightAlt,
- },
- keyboard_capture_listener_bindings_.AddBinding(this));
-}
-
-void BasemgrImpl::SwapSessionShell() {
- if (session_shell_settings_.empty()) {
- FXL_DLOG(INFO) << "No session shells has been defined";
- return;
- }
- auto shell_count = session_shell_settings_.size();
- if (shell_count <= 1) {
- FXL_DLOG(INFO)
- << "Only one session shell has been defined so switch is disabled";
- return;
- }
- active_session_shell_settings_index_ =
- (active_session_shell_settings_index_ + 1) % shell_count;
-
- UpdateSessionShellConfig();
-
- user_provider_impl_->SwapSessionShell(CloneStruct(session_shell_config_))
- ->Then([] { FXL_DLOG(INFO) << "Swapped session shell"; });
-}
-
-void BasemgrImpl::SetNextShadowTechnique() {
- using ShadowTechnique = fuchsia::ui::gfx::ShadowTechnique;
-
- auto next_shadow_technique =
- [](ShadowTechnique shadow_technique) -> ShadowTechnique {
- switch (shadow_technique) {
- case ShadowTechnique::UNSHADOWED:
- return ShadowTechnique::SCREEN_SPACE;
- case ShadowTechnique::SCREEN_SPACE:
- return ShadowTechnique::SHADOW_MAP;
- default:
- FXL_LOG(ERROR) << "Unknown shadow technique: "
- << fidl::ToUnderlying(shadow_technique);
- // Fallthrough
- case ShadowTechnique::SHADOW_MAP:
- case ShadowTechnique::MOMENT_SHADOW_MAP:
- return ShadowTechnique::UNSHADOWED;
- }
- };
-
- SetShadowTechnique(
- next_shadow_technique(presentation_state_.shadow_technique));
-}
-
-void BasemgrImpl::SetShadowTechnique(
- fuchsia::ui::gfx::ShadowTechnique shadow_technique) {
- if (!presentation_state_.presentation)
- return;
-
- presentation_state_.shadow_technique = shadow_technique;
-
- FXL_LOG(INFO) << "Setting shadow technique to "
- << fidl::ToUnderlying(presentation_state_.shadow_technique);
-
- fuchsia::ui::gfx::RendererParam param;
- param.set_shadow_technique(presentation_state_.shadow_technique);
-
- std::vector<fuchsia::ui::gfx::RendererParam> renderer_params;
- renderer_params.push_back(std::move(param));
-
- presentation_state_.presentation->SetRendererParams(
- std::move(renderer_params));
-}
-
-void BasemgrImpl::ToggleClipping() {
- if (!presentation_state_.presentation)
- return;
-
- FXL_DLOG(INFO) << "Toggling clipping";
-
- presentation_state_.clipping_enabled = !presentation_state_.clipping_enabled;
- presentation_state_.presentation->EnableClipping(
- presentation_state_.clipping_enabled);
-}
-
-void BasemgrImpl::UpdateSessionShellConfig() {
- // The session shell settings overrides the session_shell flag passed via
- // command line, except in integration tests. TODO(MF-113): Consolidate
- // the session shell settings.
- fuchsia::modular::AppConfig session_shell_config;
- if (settings_.test || session_shell_settings_.empty()) {
- session_shell_config = CloneStruct(settings_.session_shell);
- } else {
- const auto& settings =
- session_shell_settings_[active_session_shell_settings_index_];
- session_shell_config.url = settings.name;
- }
-
- session_shell_config_ = std::move(session_shell_config);
-}
-
-void BasemgrImpl::ShowSetupOrLogin() {
- auto show_setup_or_login = [this] {
- // If there are no session shell settings specified, default to showing
- // setup.
- if (active_session_shell_settings_index_ >=
- session_shell_settings_.size()) {
- StartBaseShell();
- return;
- }
-
- if (kAutoLoginToGuest) {
- user_provider_impl_->Login(fuchsia::modular::UserLoginParams());
- } else {
- user_provider_impl_->PreviousUsers(
- [this](std::vector<fuchsia::modular::auth::Account> accounts) {
- if (accounts.empty()) {
- StartBaseShell();
- } else {
- fuchsia::modular::UserLoginParams params;
- params.account_id = accounts.at(0).id;
- user_provider_impl_->Login(std::move(params));
- }
- });
- }
- };
-
- // TODO(MF-134): Improve the factory reset logic by deleting more than just
- // the user data.
- // If the device needs factory reset, remove all the users before proceeding
- // with setup.
- device_settings_manager_.set_error_handler(
- [show_setup_or_login](zx_status_t status) { show_setup_or_login(); });
- device_settings_manager_->GetInteger(
- kFactoryResetKey,
- [this, show_setup_or_login](int factory_reset_value,
- fuchsia::devicesettings::Status status) {
- if (status == fuchsia::devicesettings::Status::ok &&
- factory_reset_value > 0) {
- // Unset the factory reset flag.
- device_settings_manager_->SetInteger(
- kFactoryResetKey, 0, [](bool result) {
- if (!result) {
- FXL_LOG(WARNING) << "Factory reset flag was not updated.";
- }
- });
-
- user_provider_impl_->PreviousUsers(
- [this](std::vector<fuchsia::modular::auth::Account> accounts) {
- std::vector<FuturePtr<>> did_remove_users;
- did_remove_users.reserve(accounts.size());
-
- for (const auto& account : accounts) {
- auto did_remove_user = Future<>::Create(
- "BasemgrImpl.ShowSetupOrLogin.did_remove_user");
- user_provider_impl_->RemoveUser(
- account.id,
- [did_remove_user](fidl::StringPtr error_code) {
- if (error_code) {
- FXL_LOG(WARNING) << "Account was not removed during "
- "factory reset. Error code: "
- << error_code;
- }
- did_remove_user->Complete();
- });
- did_remove_users.emplace_back(did_remove_user);
- }
-
- Wait("BasemgrImpl.ShowSetupOrLogin.Wait", did_remove_users)
- ->Then([this] { StartBaseShell(); });
- });
- } else {
- show_setup_or_login();
- }
- });
-}
-
-void BasemgrImpl::RestartSession() { user_provider_impl_->RestartSession(); }
-
-void BasemgrImpl::LoginAsGuest() {
- fuchsia::modular::UserLoginParams params;
- user_provider_impl_->Login(std::move(params));
-}
-
-} // namespace modular
diff --git a/bin/basemgr/basemgr_impl.h b/bin/basemgr/basemgr_impl.h
deleted file mode 100644
index 5ed6d84..0000000
--- a/bin/basemgr/basemgr_impl.h
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_BASEMGR_BASEMGR_IMPL_H_
-#define PERIDOT_BIN_BASEMGR_BASEMGR_IMPL_H_
-
-#include <memory>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <fuchsia/devicesettings/cpp/fidl.h>
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/basemgr/basemgr_settings.h"
-#include "peridot/bin/basemgr/cobalt/cobalt.h"
-#include "peridot/bin/basemgr/user_provider_impl.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/session_shell_settings/session_shell_settings.h"
-
-namespace modular {
-
-// Basemgr is the parent process of the modular framework, and it is started by
-// the sysmgr as part of the boot sequence.
-//
-// It has several high-level responsibilites:
-// 1) Initializes and owns the system's root view and presentation.
-// 2) Sets up the interactive flow for user authentication and login.
-// 3) Manages the lifecycle of sessions, represented as |sessionmgr| processes.
-class BasemgrImpl : fuchsia::modular::BaseShellContext,
- fuchsia::auth::AuthenticationContextProvider,
- fuchsia::modular::internal::BasemgrDebug,
- fuchsia::ui::policy::KeyboardCaptureListenerHACK,
- modular::UserProviderImpl::Delegate {
- public:
- // Initializes as BasemgrImpl instance with the given parameters:
- //
- // |settings| Settings that are parsed from command line. Used to configure
- // the modular framework environment.
- // |session_shell_settings| Settings relevant to session shells. Used to
- // configure session shells that are launched.
- // |launcher| Environment service for creating component instances.
- // |presenter| Service to initialize the presentation.
- // |device_settings_manager| Service to look-up whether device needs factory
- // reset.
- // |on_shutdown| Callback invoked when this basemgr instance is shutdown.
- explicit BasemgrImpl(
- const modular::BasemgrSettings& settings,
- const std::vector<modular::SessionShellSettings>& session_shell_settings,
- fuchsia::sys::Launcher* const launcher,
- fuchsia::ui::policy::PresenterPtr presenter,
- fuchsia::devicesettings::DeviceSettingsManagerPtr device_settings_manager,
- std::function<void()> on_shutdown);
-
- ~BasemgrImpl() override;
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::internal::BasemgrDebug> request);
-
- private:
- void InitializePresentation(
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner> view_owner);
-
- void StartBaseShell();
-
- FuturePtr<> StopBaseShell();
-
- FuturePtr<> StopTokenManagerFactoryApp();
-
- void Start();
-
- // |fuchsia::modular::BaseShellContext|
- void GetUserProvider(
- fidl::InterfaceRequest<fuchsia::modular::UserProvider> request) override;
-
- // |fuchsia::modular::BaseShellContext|
- void Shutdown() override;
-
- // |AuthenticationContextProvider|
- void GetAuthenticationUIContext(
- fidl::InterfaceRequest<fuchsia::auth::AuthenticationUIContext> request)
- override;
-
- // |UserProviderImpl::Delegate|
- void DidLogin() override;
-
- // |UserProviderImpl::Delegate|
- void DidLogout() override;
-
- // |UserProviderImpl::Delegate|
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- GetSessionShellViewOwner(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>)
- override;
-
- // |UserProviderImpl::Delegate|
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
- GetSessionShellServiceProvider(
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>) override;
-
- // |KeyboardCaptureListenerHACK|
- void OnEvent(fuchsia::ui::input::KeyboardEvent event) override;
-
- void AddGlobalKeyboardShortcuts(
- fuchsia::ui::policy::PresentationPtr& presentation);
-
- void UpdatePresentation(const SessionShellSettings& settings);
-
- void SwapSessionShell();
-
- void SetNextShadowTechnique();
-
- void SetShadowTechnique(fuchsia::ui::gfx::ShadowTechnique shadow_technique);
-
- void ToggleClipping();
-
- void ShowSetupOrLogin();
-
- // Updates the session shell app config to the active session shell. Done once
- // on initialization and every time the session shells are swapped.
- void UpdateSessionShellConfig();
-
- // |BasemgrDebug|
- void RestartSession() override;
-
- // |BasemgrDebug|
- void LoginAsGuest() override;
-
- const modular::BasemgrSettings& settings_; // Not owned nor copied.
- const std::vector<SessionShellSettings>& session_shell_settings_;
- fuchsia::modular::AppConfig session_shell_config_;
- // Used to indicate which settings in |session_shell_settings_| is currently
- // active.
- std::vector<SessionShellSettings>::size_type
- active_session_shell_settings_index_{};
-
- // Used to launch component instances, such as the base shell.
- fuchsia::sys::Launcher* const launcher_; // Not owned.
- // Used to initialize the presentation.
- fuchsia::ui::policy::PresenterPtr presenter_;
- // Used to look-up whether device needs a factory reset.
- fuchsia::devicesettings::DeviceSettingsManagerPtr device_settings_manager_;
- std::function<void()> on_shutdown_;
-
- AsyncHolder<UserProviderImpl> user_provider_impl_;
-
- fidl::BindingSet<fuchsia::modular::internal::BasemgrDebug> basemgr_bindings_;
- fidl::Binding<fuchsia::modular::BaseShellContext> base_shell_context_binding_;
- fidl::Binding<fuchsia::auth::AuthenticationContextProvider>
- authentication_context_provider_binding_;
-
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>>
- token_manager_factory_app_;
- fuchsia::auth::TokenManagerFactoryPtr token_manager_factory_;
-
- bool base_shell_running_{};
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> base_shell_app_;
- fuchsia::modular::BaseShellPtr base_shell_;
-
- fidl::BindingSet<fuchsia::ui::policy::KeyboardCaptureListenerHACK>
- keyboard_capture_listener_bindings_;
-
- fuchsia::ui::viewsv1token::ViewOwnerPtr session_shell_view_owner_;
-
- struct {
- fuchsia::ui::policy::PresentationPtr presentation;
- fidl::BindingSet<fuchsia::ui::policy::Presentation> bindings;
-
- fuchsia::ui::gfx::ShadowTechnique shadow_technique =
- fuchsia::ui::gfx::ShadowTechnique::UNSHADOWED;
- bool clipping_enabled{};
- } presentation_state_;
-
- component::ServiceNamespace service_namespace_;
-
- enum class State {
- // normal mode of operation
- RUNNING,
- // basemgr is shutting down.
- SHUTTING_DOWN
- };
-
- State state_ = State::RUNNING;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BasemgrImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_BASEMGR_BASEMGR_IMPL_H_
diff --git a/bin/basemgr/basemgr_settings.cc b/bin/basemgr/basemgr_settings.cc
deleted file mode 100644
index 87472e4..0000000
--- a/bin/basemgr/basemgr_settings.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/basemgr/basemgr_settings.h"
-
-#include <string>
-
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-BasemgrSettings::BasemgrSettings(const fxl::CommandLine& command_line) {
- base_shell.url = command_line.GetOptionValueWithDefault(
- "base_shell",
- "fuchsia-pkg://fuchsia.com/userpicker_base_shell#meta/"
- "userpicker_base_shell.cmx");
- story_shell.url = command_line.GetOptionValueWithDefault(
- "story_shell", "fuchsia-pkg://fuchsia.com/mondrian#meta/mondrian.cmx");
- sessionmgr.url = command_line.GetOptionValueWithDefault(
- "sessionmgr", "fuchsia-pkg://fuchsia.com/sessionmgr#meta/sessionmgr.cmx");
- session_shell.url = command_line.GetOptionValueWithDefault(
- "session_shell",
- "fuchsia-pkg://fuchsia.com/ermine_session_shell#meta/"
- "ermine_session_shell.cmx");
- account_provider.url = command_line.GetOptionValueWithDefault(
- "account_provider",
- "fuchsia-pkg://fuchsia.com/token_manager_factory#meta/"
- "token_manager_factory.cmx");
-
- disable_statistics = command_line.HasOption("disable_statistics");
- no_minfs = command_line.HasOption("no_minfs");
- test = command_line.HasOption("test");
- run_base_shell_with_test_runner =
- command_line.GetOptionValueWithDefault("run_base_shell_with_test_runner",
- "true") == "true"
- ? true
- : false;
- enable_presenter = command_line.HasOption("enable_presenter");
-
- ParseShellArgs(command_line.GetOptionValueWithDefault("base_shell_args", ""),
- &base_shell.args);
-
- ParseShellArgs(command_line.GetOptionValueWithDefault("story_shell_args", ""),
- &story_shell.args);
-
- ParseShellArgs(command_line.GetOptionValueWithDefault("sessionmgr_args", ""),
- &sessionmgr.args);
-
- ParseShellArgs(
- command_line.GetOptionValueWithDefault("session_shell_args", ""),
- &session_shell.args);
-
- if (test) {
- if (run_base_shell_with_test_runner) {
- base_shell.args.push_back("--test");
- }
- story_shell.args.push_back("--test");
- sessionmgr.args.push_back("--test");
- session_shell.args.push_back("--test");
- test_name = FindTestName(session_shell.url, session_shell.args);
- disable_statistics = true;
- no_minfs = true;
- }
-}
-
-std::string BasemgrSettings::GetUsage() {
- return R"USAGE(basemgr
- --base_shell=BASE_SHELL
- --base_shell_args=SHELL_ARGS
- --session_shell=SESSION_SHELL
- --session_shell_args=SHELL_ARGS
- --story_shell=STORY_SHELL
- --story_shell_args=SHELL_ARGS
- --account_provider=ACCOUNT_PROVIDER
- --disable_statistics
- --no_minfs
- --test
- --enable_presenter
- DEVICE_NAME: Name which session shell uses to identify this device.
- BASE_SHELL: URL of the base shell to run.
- Defaults to "userpicker_base_shell".
- For integration testing use "dev_base_shell".
- SESSIONMGR: URL of the sessionmgr to run.
- Defaults to "sessionmgr".
- SESSION_SHELL: URL of the session shell to run.
- Defaults to "ermine_session_shell".
- For integration testing use "dev_session_shell".
- STORY_SHELL: URL of the story shell to run.
- Defaults to "mondrian".
- For integration testing use "dev_story_shell".
- SHELL_ARGS: Comma separated list of arguments. Backslash escapes comma.
- ACCOUNT_PROVIDER: URL of the account provider to use.
- Defaults to "oauth_token_manager".
- For integration tests use "dev_token_manager".)USAGE";
-}
-
-void BasemgrSettings::ParseShellArgs(const std::string& value,
- fidl::VectorPtr<std::string>* args) {
- bool escape = false;
- std::string arg;
- for (char i : value) {
- if (escape) {
- arg.push_back(i);
- escape = false;
- continue;
- }
-
- if (i == '\\') {
- escape = true;
- continue;
- }
-
- if (i == ',') {
- args->push_back(arg);
- arg.clear();
- continue;
- }
-
- arg.push_back(i);
- }
-
- if (!arg.empty()) {
- args->push_back(arg);
- }
-}
-
-std::string BasemgrSettings::FindTestName(
- const fidl::StringPtr& session_shell,
- const fidl::VectorPtr<std::string>& session_shell_args) {
- const std::string kRootModule = "--root_module";
- std::string result = session_shell;
-
- for (const auto& arg : *session_shell_args) {
- if (arg.substr(0, kRootModule.size()) == kRootModule) {
- result = arg.substr(kRootModule.size());
- }
- }
-
- const auto index = result.find_last_of('/');
- if (index == std::string::npos) {
- return result;
- }
-
- return result.substr(index + 1);
-}
-
-} // namespace modular
diff --git a/bin/basemgr/basemgr_settings.h b/bin/basemgr/basemgr_settings.h
deleted file mode 100644
index 45333c7..0000000
--- a/bin/basemgr/basemgr_settings.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_BASEMGR_BASEMGR_SETTINGS_H_
-#define PERIDOT_BIN_BASEMGR_BASEMGR_SETTINGS_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-class BasemgrSettings {
- public:
- explicit BasemgrSettings(const fxl::CommandLine& command_line);
-
- static std::string GetUsage();
-
- fuchsia::modular::AppConfig base_shell;
- fuchsia::modular::AppConfig story_shell;
- fuchsia::modular::AppConfig sessionmgr;
- fuchsia::modular::AppConfig session_shell;
- fuchsia::modular::AppConfig account_provider;
-
- std::string test_name;
- bool disable_statistics;
- bool no_minfs;
- bool test;
- bool run_base_shell_with_test_runner;
- bool enable_presenter;
-
- private:
- void ParseShellArgs(const std::string& value,
- fidl::VectorPtr<std::string>* args);
-
- // Extract the test name using knowledge of how Modular structures its
- // command lines for testing.
- static std::string FindTestName(
- const fidl::StringPtr& session_shell,
- const fidl::VectorPtr<std::string>& session_shell_args);
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BasemgrSettings);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_BASEMGR_BASEMGR_SETTINGS_H_
diff --git a/bin/basemgr/cobalt/BUILD.gn b/bin/basemgr/cobalt/BUILD.gn
deleted file mode 100644
index c1fedf6..0000000
--- a/bin/basemgr/cobalt/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/cobalt_config/metrics_registry.gni")
-
-visibility = [
- "//peridot/bin/basemgr/*",
- "//peridot/bin/sessionmgr/*",
-]
-
-metrics_registry("basemgr_metrics_registry") {
- project_id = 101
-}
-
-source_set("cobalt") {
- sources = [
- "cobalt.cc",
- "cobalt.h",
- ]
-
- public_deps = [
- ":basemgr_metrics_registry",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fxl",
- ]
-
- deps = [
- "//garnet/public/lib/backoff",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/cobalt/cpp:cobalt_logger",
- "//zircon/public/fidl/fuchsia-cobalt",
- ]
-}
diff --git a/bin/basemgr/cobalt/cobalt.cc b/bin/basemgr/cobalt/cobalt.cc
deleted file mode 100644
index 08c950a..0000000
--- a/bin/basemgr/cobalt/cobalt.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/basemgr/cobalt/cobalt.h"
-
-#include <fuchsia/cobalt/cpp/fidl.h>
-#include <lib/cobalt/cpp/cobalt_logger.h>
-
-namespace modular {
-namespace {
-constexpr char kConfigBinProtoPath[] = "/pkg/data/basemgr_metrics_registry.pb";
-
-cobalt::CobaltLogger* g_cobalt_logger = nullptr;
-
-} // namespace
-
-fit::deferred_action<fit::closure> InitializeCobalt(
- async_dispatcher_t* dispatcher, component::StartupContext* context) {
- FXL_DCHECK(!g_cobalt_logger) << "Cobalt has already been initialized.";
-
- std::unique_ptr<cobalt::CobaltLogger> cobalt_logger =
- cobalt::NewCobaltLogger(dispatcher, context, kConfigBinProtoPath);
-
- g_cobalt_logger = cobalt_logger.get();
- return fit::defer<fit::closure>([cobalt_logger = std::move(cobalt_logger)] {
- g_cobalt_logger = nullptr;
- });
-}
-
-void ReportEvent(ModularEvent event) {
- if (g_cobalt_logger) {
- g_cobalt_logger->LogEvent(
- static_cast<uint32_t>(CobaltMetric::MODULAR_EVENTS),
- static_cast<uint32_t>(event));
- }
-}
-
-void ReportModuleLaunchTime(std::string module_url, zx::duration time) {
- if (g_cobalt_logger) {
- g_cobalt_logger->LogElapsedTime(
- static_cast<uint32_t>(CobaltMetric::MODULE_LAUNCH_LATENCY), 0,
- module_url, time);
- }
-}
-
-void ReportStoryLaunchTime(zx::duration time) {
- if (g_cobalt_logger) {
- g_cobalt_logger->LogElapsedTime(
- static_cast<uint32_t>(CobaltMetric::STORY_LAUNCH_LATENCY), 0, "", time);
- }
-}
-
-void ReportSessionAgentEvent(const std::string& url, SessionAgentEvent event) {
- if (g_cobalt_logger) {
- g_cobalt_logger->LogEventCount(
- static_cast<uint32_t>(CobaltMetric::SESSION_AGENT_EVENT),
- static_cast<uint32_t>(event), url /* component */,
- zx::duration(0) /* period_duration_micros */, 1 /* count */);
- }
-}
-
-} // namespace modular
diff --git a/bin/basemgr/cobalt/cobalt.h b/bin/basemgr/cobalt/cobalt.h
deleted file mode 100644
index b83e934..0000000
--- a/bin/basemgr/cobalt/cobalt.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_BASEMGR_COBALT_COBALT_H_
-#define PERIDOT_BIN_BASEMGR_COBALT_COBALT_H_
-
-#include <lib/async/dispatcher.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-namespace modular {
-
-// Metric IDs that Cobalt requires to identify the data we are logging.
-// These are not events (events are tracked through ModularEvents index metric).
-// For information on datatypes and structure of each of these metrics, see
-// https://cobalt-analytics.googlesource.com/config/+/master/fuchsia/module_usage_tracking/config.yaml
-// Next enum value: 6
-enum class CobaltMetric : uint32_t {
- MODULE_LAUNCHED = 1,
- MODULE_PAIRS_IN_STORY = 2,
- MODULAR_EVENTS = 3,
- MODULE_LAUNCH_LATENCY = 4,
- STORY_LAUNCH_LATENCY = 5,
- SESSION_AGENT_EVENT = 6,
-};
-
-// The events to report.
-// Next enum value: 2
-enum class ModularEvent : uint32_t {
- BOOTED_TO_BASEMGR = 0,
- BOOTED_TO_SESSIONMGR = 1,
-};
-
-// The sesssion agent events to report.
-// Next enum value: 2
-enum class SessionAgentEvent : uint32_t {
- CRASH = 0,
- CRASH_LIMIT = 1,
-};
-
-// Cobalt initialization. When cobalt is not needed, the returned object must be
-// deleted. This method must not be called again until then.
-fit::deferred_action<fit::closure> InitializeCobalt(
- async_dispatcher_t* dispatcher, component::StartupContext* context);
-
-// Report a modular event to Cobalt.
-void ReportEvent(ModularEvent event);
-
-// Report a module launch time duration to Cobalt.
-void ReportModuleLaunchTime(std::string module_url, zx::duration time);
-
-// Report a story launch time duration to Cobalt.
-void ReportStoryLaunchTime(zx::duration time);
-
-void ReportSessionAgentEvent(const std::string& url, SessionAgentEvent event);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_BASEMGR_COBALT_COBALT_H_
diff --git a/bin/basemgr/dev_base_shell.cc b/bin/basemgr/dev_base_shell.cc
deleted file mode 100644
index 107ae11..0000000
--- a/bin/basemgr/dev_base_shell.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implementation of the fuchsia::modular::BaseShell service that passes a
-// command line configurable user name to its fuchsia::modular::UserProvider,
-// and is able to run a story with a single module through its life cycle.
-
-#include <memory>
-#include <utility>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include "lib/fxl/strings/string_number_conversions.h"
-
-#include "peridot/lib/fidl/single_service_app.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-
-namespace modular {
-
-class Settings {
- public:
- explicit Settings(const fxl::CommandLine& command_line) {
- // device_name will be set to the device's hostname if it is empty or null
- device_name = command_line.GetOptionValueWithDefault("device_name", "");
-
- // default user is incognito
- user = command_line.GetOptionValueWithDefault("user", "");
-
- // If passed, runs as a test harness.
- test = command_line.HasOption("test");
-
- test_timeout_ms = testing::kTestTimeoutMilliseconds;
-
- if (command_line.HasOption("test_timeout_ms")) {
- std::string test_timeout_ms_string;
- command_line.GetOptionValue("test_timeout_ms", &test_timeout_ms_string);
- if (!fxl::StringToNumberWithError<uint64_t>(test_timeout_ms_string,
- &test_timeout_ms)) {
- FXL_LOG(WARNING) << "Unable to parse timeout from '"
- << test_timeout_ms_string << "'. Setting to default.";
- }
- }
- }
-
- std::string device_name;
- std::string user;
- uint64_t test_timeout_ms;
- bool test{};
-};
-
-class DevBaseShellApp : modular::SingleServiceApp<fuchsia::modular::BaseShell>,
- fuchsia::modular::UserWatcher {
- public:
- explicit DevBaseShellApp(component::StartupContext* const startup_context,
- Settings settings)
- : SingleServiceApp(startup_context),
- settings_(std::move(settings)),
- user_watcher_binding_(this),
- weak_ptr_factory_(this) {
- if (settings_.test) {
- testing::Init(this->startup_context(), __FILE__);
- testing::Await(testing::kTestShutdown,
- [this] { base_shell_context_->Shutdown(); });
-
- // Start a timer to quit in case a test component misbehaves and hangs. If
- // we hit the timeout, this is a test failure.
- async::PostDelayedTask(
- async_get_default_dispatcher(),
- callback::MakeScoped(weak_ptr_factory_.GetWeakPtr(),
- [this] {
- FXL_LOG(WARNING) << "DevBaseShell timed out";
- testing::Fail("DevBaseShell timed out");
- base_shell_context_->Shutdown();
- }),
- zx::msec(settings_.test_timeout_ms));
- }
- }
-
- ~DevBaseShellApp() override = default;
-
- // |SingleServiceApp|
- void Terminate(std::function<void()> done) override {
- if (settings_.test) {
- testing::Teardown(done);
- } else {
- done();
- }
- }
-
- private:
- // |SingleServiceApp|
- void CreateView(
- zx::eventpair view_token,
- fidl::InterfaceRequest<
- fuchsia::sys::ServiceProvider> /*incoming_services*/,
- fidl::InterfaceHandle<
- fuchsia::sys::ServiceProvider> /*outgoing_services*/) override {
- view_owner_request_ =
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>(
- zx::channel(view_token.release()));
- Connect();
- }
-
- // |fuchsia::modular::BaseShell|
- void Initialize(
- fidl::InterfaceHandle<fuchsia::modular::BaseShellContext>
- base_shell_context,
- fuchsia::modular::BaseShellParams base_shell_params) override {
- base_shell_context_.Bind(std::move(base_shell_context));
- base_shell_context_->GetUserProvider(user_provider_.NewRequest());
-
- Connect();
- }
-
- // |fuchsia::modular::BaseShell|
- void GetAuthenticationUIContext(
- fidl::InterfaceRequest<
- fuchsia::auth::AuthenticationUIContext> /*request*/) override {
- FXL_LOG(INFO)
- << "fuchsia::modular::BaseShell::GetAuthenticationUIContext() is"
- " unimplemented.";
- }
-
- // |fuchsia::modular::UserWatcher|
- void OnLogout() override {
- FXL_LOG(INFO) << "fuchsia::modular::UserWatcher::OnLogout()";
- base_shell_context_->Shutdown();
- }
-
- void Login(const std::string& account_id) {
- fuchsia::modular::UserLoginParams params;
- params.account_id = account_id;
- params.view_owner = std::move(view_owner_request_);
- params.user_controller = user_controller_.NewRequest();
- user_provider_->Login(std::move(params));
- user_controller_->Watch(user_watcher_binding_.NewBinding());
- }
-
- void Connect() {
- if (user_provider_ && view_owner_request_) {
- if (settings_.user.empty()) {
- // Incognito mode.
- Login("");
- return;
- }
-
- user_provider_->PreviousUsers(
- [this](std::vector<fuchsia::modular::auth::Account> accounts) {
- FXL_LOG(INFO) << "Found " << accounts.size()
- << " users in the user "
- << "database";
-
- // Not running in incognito mode. Add the user if not already
- // added.
- std::string account_id;
- for (const auto& account : accounts) {
- FXL_LOG(INFO) << "Found user " << account.display_name;
- if (account.display_name.size() >= settings_.user.size() &&
- account.display_name.substr(0, settings_.user.size()) ==
- settings_.user) {
- account_id = account.id;
- break;
- }
- }
- if (account_id.empty()) {
- user_provider_->AddUser(
- fuchsia::modular::auth::IdentityProvider::DEV,
- [this](fuchsia::modular::auth::AccountPtr account,
- fidl::StringPtr status) { Login(account->id); });
- } else {
- Login(account_id);
- }
- });
- }
- }
-
- const Settings settings_;
- fidl::Binding<fuchsia::modular::UserWatcher> user_watcher_binding_;
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request_;
- fuchsia::modular::BaseShellContextPtr base_shell_context_;
- fuchsia::modular::UserControllerPtr user_controller_;
- fuchsia::modular::UserProviderPtr user_provider_;
- fxl::WeakPtrFactory<DevBaseShellApp> weak_ptr_factory_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DevBaseShellApp);
-};
-
-} // namespace modular
-
-int main(int argc, const char** argv) {
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- modular::Settings settings(command_line);
-
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
-
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AppDriver<modular::DevBaseShellApp> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<modular::DevBaseShellApp>(context.get(), settings),
- [&loop] { loop.Quit(); });
-
- loop.Run();
- return 0;
-}
diff --git a/bin/basemgr/main.cc b/bin/basemgr/main.cc
deleted file mode 100644
index f90c384..0000000
--- a/bin/basemgr/main.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/macros.h>
-#include <trace-provider/provider.h>
-
-#include "peridot/bin/basemgr/basemgr_impl.h"
-#include "peridot/bin/basemgr/basemgr_settings.h"
-#include "peridot/bin/basemgr/cobalt/cobalt.h"
-#include "peridot/lib/session_shell_settings/session_shell_settings.h"
-
-fit::deferred_action<fit::closure> SetupCobalt(
- modular::BasemgrSettings& settings, async_dispatcher_t* dispatcher,
- component::StartupContext* context) {
- if (settings.disable_statistics) {
- return fit::defer<fit::closure>([] {});
- }
- return modular::InitializeCobalt(dispatcher, context);
-};
-
-constexpr char kBasemgrDir[] = "basemgr";
-
-int main(int argc, const char** argv) {
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- if (command_line.HasOption("help")) {
- std::cout << modular::BasemgrSettings::GetUsage() << std::endl;
- return 0;
- }
-
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- trace::TraceProvider trace_provider(loop.dispatcher());
- auto context = std::shared_ptr<component::StartupContext>(
- component::StartupContext::CreateFromStartupInfo());
- modular::BasemgrSettings settings(command_line);
- auto session_shell_settings =
- modular::SessionShellSettings::GetSystemSettings();
-
- fit::deferred_action<fit::closure> cobalt_cleanup =
- SetupCobalt(settings, std::move(loop.dispatcher()), context.get());
-
- fuchsia::ui::policy::PresenterPtr presenter;
- context->ConnectToEnvironmentService(presenter.NewRequest());
- fuchsia::devicesettings::DeviceSettingsManagerPtr device_settings_manager;
- context->ConnectToEnvironmentService(device_settings_manager.NewRequest());
-
- modular::BasemgrImpl basemgr(
- settings, session_shell_settings, context->launcher().get(),
- std::move(presenter), std::move(device_settings_manager),
- [&loop, &cobalt_cleanup, &context] {
- cobalt_cleanup.call();
- context->outgoing().debug_dir()->RemoveEntry(kBasemgrDir);
- loop.Quit();
- });
- context->outgoing().debug_dir()->AddEntry(
- kBasemgrDir,
- fbl::AdoptRef(new fs::Service([&basemgr](zx::channel channel) {
- fidl::InterfaceRequest<fuchsia::modular::internal::BasemgrDebug>
- request(std::move(channel));
- basemgr.Connect(std::move(request));
- return ZX_OK;
- })));
-
- loop.Run();
-
- return 0;
-}
diff --git a/bin/basemgr/meta/basemgr.cmx b/bin/basemgr/meta/basemgr.cmx
deleted file mode 100644
index 445be71..0000000
--- a/bin/basemgr/meta/basemgr.cmx
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.devicesettings.DeviceSettingsManager",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ],
- "system": [
- "data/sysui"
- ]
- }
-}
diff --git a/bin/basemgr/meta/dev_base_shell.cmx b/bin/basemgr/meta/dev_base_shell.cmx
deleted file mode 100644
index 3861977..0000000
--- a/bin/basemgr/meta/dev_base_shell.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.sys.Launcher",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager"
- ],
- "system": [
- "data/sysui"
- ]
- }
-}
diff --git a/bin/basemgr/user_controller_impl.cc b/bin/basemgr/user_controller_impl.cc
deleted file mode 100644
index 1dc48d9..0000000
--- a/bin/basemgr/user_controller_impl.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/basemgr/user_controller_impl.h"
-
-#include <memory>
-#include <utility>
-
-#include <lib/fidl/cpp/synchronous_interface_ptr.h>
-
-#include "peridot/lib/common/async_holder.h"
-#include "peridot/lib/common/names.h"
-#include "peridot/lib/common/teardown.h"
-#include "peridot/lib/fidl/array_to_string.h"
-
-namespace modular {
-
-UserControllerImpl::UserControllerImpl(
- fuchsia::sys::Launcher* const launcher,
- fuchsia::modular::AppConfig sessionmgr,
- fuchsia::modular::AppConfig session_shell,
- fuchsia::modular::AppConfig story_shell,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> agent_token_manager,
- fuchsia::modular::auth::AccountPtr account,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> base_shell_services,
- fidl::InterfaceRequest<fuchsia::modular::UserController>
- user_controller_request,
- DoneCallback done)
- : user_context_binding_(this),
- user_controller_binding_(this, std::move(user_controller_request)),
- base_shell_services_(base_shell_services ? base_shell_services.Bind()
- : nullptr),
- done_(std::move(done)) {
- // 0. Generate the path to map '/data' for the sessionmgr we are starting.
- std::string data_origin;
- if (!account) {
- // Guest user.
- // Generate a random number to be used in this case.
- uint32_t random_number = 0;
- zx_cprng_draw(&random_number, sizeof random_number);
- data_origin = std::string("/data/modular/USER_GUEST_") +
- std::to_string(random_number);
- } else {
- // Non-guest user.
- data_origin = std::string("/data/modular/USER_") + std::string(account->id);
- }
-
- FXL_LOG(INFO) << "SESSIONMGR DATA ORIGIN IS " << data_origin;
-
- // 1. Launch Sessionmgr in the current environment.
- sessionmgr_app_ = std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- launcher, std::move(sessionmgr), data_origin);
-
- // 2. Initialize the Sessionmgr service.
- sessionmgr_app_->services().ConnectToService(sessionmgr_.NewRequest());
- sessionmgr_->Initialize(
- std::move(account), std::move(session_shell), std::move(story_shell),
- std::move(ledger_token_manager), std::move(agent_token_manager),
- user_context_binding_.NewBinding(), std::move(view_owner_request));
-
- sessionmgr_app_->SetAppErrorHandler([this] {
- FXL_LOG(ERROR) << "Sessionmgr seems to have crashed unexpectedly. "
- << "Calling done_().";
- // This prevents us from receiving any further requests.
- user_controller_binding_.Unbind();
- user_context_binding_.Unbind();
- // Logout(), which expects a graceful shutdown of sessionmgr, does not
- // apply here because sessionmgr crashed. Just run |done_| directly.
- done_(this);
- });
-}
-
-// |fuchsia::modular::UserController|
-void UserControllerImpl::Logout(LogoutCallback done) {
- FXL_LOG(INFO) << "fuchsia::modular::UserController::Logout()";
- logout_response_callbacks_.push_back(done);
- if (logout_response_callbacks_.size() > 1) {
- return;
- }
-
- // This should prevent us from receiving any further requests.
- user_controller_binding_.Unbind();
- user_context_binding_.Unbind();
-
- sessionmgr_app_->Teardown(kSessionmgrTimeout, [this] {
- for (const auto& done : logout_response_callbacks_) {
- done();
- }
- // We announce |OnLogout| only at point just before deleting ourselves,
- // so we can avoid any race conditions that may be triggered by |Shutdown|
- // (which in-turn will call this |Logout| since we have not completed yet).
- for (auto& watcher : user_watchers_.ptrs()) {
- (*watcher)->OnLogout();
- }
- done_(this);
- });
-}
-
-// |UserContext|
-void UserControllerImpl::GetPresentation(
- fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request) {
- if (base_shell_services_) {
- base_shell_services_->ConnectToService(kPresentationService,
- request.TakeChannel());
- }
-}
-
-FuturePtr<> UserControllerImpl::SwapSessionShell(
- fuchsia::modular::AppConfig session_shell_config) {
- auto future = Future<>::Create("SwapSessionShell");
- SwapSessionShell(std::move(session_shell_config), future->Completer());
- return future;
-}
-
-// |fuchsia::modular::UserController|
-void UserControllerImpl::SwapSessionShell(
- fuchsia::modular::AppConfig session_shell_config,
- SwapSessionShellCallback callback) {
- sessionmgr_->SwapSessionShell(std::move(session_shell_config), callback);
-}
-
-// |fuchsia::modular::UserController|
-void UserControllerImpl::Watch(
- fidl::InterfaceHandle<fuchsia::modular::UserWatcher> watcher) {
- user_watchers_.AddInterfacePtr(watcher.Bind());
-}
-
-// |UserContext|
-// TODO(alhaad): Reconcile UserContext.Logout() and UserControllerImpl.Logout().
-void UserControllerImpl::Logout() {
- FXL_LOG(INFO) << "UserContext::Logout()";
- Logout([] {});
-}
-
-} // namespace modular
diff --git a/bin/basemgr/user_controller_impl.h b/bin/basemgr/user_controller_impl.h
deleted file mode 100644
index 1af0f6a..0000000
--- a/bin/basemgr/user_controller_impl.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_BASEMGR_USER_CONTROLLER_IMPL_H_
-#define PERIDOT_BIN_BASEMGR_USER_CONTROLLER_IMPL_H_
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/fidl/app_client.h"
-#include "peridot/lib/fidl/environment.h"
-
-namespace modular {
-
-// |UserControllerImpl| starts and manages a Sessionmgr. The life time of a
-// Sessionmgr is bound to this class. |UserControllerImpl| is not self-owned,
-// but still drives its own deletion: On logout, it signals its
-// owner (BasemgrImpl) to delete it.
-class UserControllerImpl : fuchsia::modular::UserController,
- fuchsia::modular::internal::UserContext {
- public:
- // After perfoming logout, to signal our completion (and deletion of our
- // instance) to our owner, we do it using a callback supplied to us in our
- // constructor. (The alternative is to take in a BasemgrImpl*, which seems
- // a little specific and overscoped).
- using DoneCallback = std::function<void(UserControllerImpl*)>;
-
- UserControllerImpl(
- fuchsia::sys::Launcher* const launcher,
- fuchsia::modular::AppConfig sessionmgr,
- fuchsia::modular::AppConfig session_shell,
- fuchsia::modular::AppConfig story_shell,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> agent_token_manager,
- fuchsia::modular::auth::AccountPtr account,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> base_shell_services,
- fidl::InterfaceRequest<fuchsia::modular::UserController>
- user_controller_request,
- DoneCallback done);
-
- // This will effectively tear down the entire instance by calling |done|.
- // |fuchsia::modular::UserController|
- void Logout(LogoutCallback done) override;
-
- // Stops the active session shell, and starts the session shell specified in
- // |session_shell_config|.
- FuturePtr<> SwapSessionShell(
- fuchsia::modular::AppConfig session_shell_config);
-
- private:
- // |fuchsia::modular::UserController|
- void SwapSessionShell(fuchsia::modular::AppConfig session_shell_config,
- SwapSessionShellCallback callback) override;
-
- // |fuchsia::modular::UserController|
- void Watch(
- fidl::InterfaceHandle<fuchsia::modular::UserWatcher> watcher) override;
-
- // |UserContext|
- void Logout() override;
-
- // |UserContext|
- void GetPresentation(fidl::InterfaceRequest<fuchsia::ui::policy::Presentation>
- request) override;
-
- std::unique_ptr<Environment> sessionmgr_environment_;
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> sessionmgr_app_;
- fuchsia::modular::internal::SessionmgrPtr sessionmgr_;
-
- fidl::Binding<fuchsia::modular::internal::UserContext> user_context_binding_;
- fidl::Binding<fuchsia::modular::UserController> user_controller_binding_;
-
- fidl::InterfacePtrSet<fuchsia::modular::UserWatcher> user_watchers_;
-
- std::vector<LogoutCallback> logout_response_callbacks_;
-
- fuchsia::sys::ServiceProviderPtr base_shell_services_;
-
- DoneCallback done_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(UserControllerImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_BASEMGR_USER_CONTROLLER_IMPL_H_
diff --git a/bin/basemgr/user_controller_impl_unittest.cc b/bin/basemgr/user_controller_impl_unittest.cc
deleted file mode 100644
index ff99304..0000000
--- a/bin/basemgr/user_controller_impl_unittest.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/basemgr/user_controller_impl.h"
-
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/component/cpp/testing/fake_launcher.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/lib/fidl/clone.h"
-
-namespace modular {
-namespace testing {
-namespace {
-
-using ::component::testing::FakeLauncher;
-using UserControllerImplTest = gtest::TestLoopFixture;
-
-TEST_F(UserControllerImplTest, StartSessionmgrWithTokenManagers) {
- FakeLauncher launcher;
- std::string url = "test_url_string";
- fuchsia::modular::AppConfig app_config;
- app_config.url = url;
-
- bool callback_called = false;
- launcher.RegisterComponent(
- url, [&callback_called](
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- callback_called = true;
- });
-
- fuchsia::auth::TokenManagerPtr ledger_token_manager;
- fuchsia::auth::TokenManagerPtr agent_token_manager;
- fuchsia::modular::UserControllerPtr user_controller;
-
- UserControllerImpl impl(
- &launcher, CloneStruct(app_config), CloneStruct(app_config),
- CloneStruct(app_config), std::move(ledger_token_manager),
- std::move(agent_token_manager), nullptr /* account */,
- nullptr /* view_owner_request */, nullptr /* base_shell_services */,
- user_controller.NewRequest(), nullptr /* done_callback */);
-
- EXPECT_TRUE(callback_called);
-}
-
-TEST_F(UserControllerImplTest, SessionmgrCrashInvokesDoneCallback) {
- // Program the fake launcher to drop the CreateComponent request such that
- // the error handler of the sessionmgr_app is invoked. This should invoke the
- // done_callback.
- FakeLauncher launcher;
- std::string url = "test_url_string";
- fuchsia::modular::AppConfig app_config;
- app_config.url = url;
-
- launcher.RegisterComponent(
- url, [](fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- return;
- });
-
- fuchsia::auth::TokenManagerPtr ledger_token_manager;
- fuchsia::auth::TokenManagerPtr agent_token_manager;
- fuchsia::modular::UserControllerPtr user_controller;
-
- bool done_callback_called = false;
- UserControllerImpl impl(
- &launcher, CloneStruct(app_config), CloneStruct(app_config),
- CloneStruct(app_config), std::move(ledger_token_manager),
- std::move(agent_token_manager), nullptr /* account */,
- nullptr /* view_owner_request */, nullptr /* base_shell_services */,
- user_controller.NewRequest(),
- /* done_callback = */ [&done_callback_called](UserControllerImpl*) {
- done_callback_called = true;
- });
-
- RunLoopUntilIdle();
- EXPECT_TRUE(done_callback_called);
-}
-} // namespace
-} // namespace testing
-} // namespace modular
diff --git a/bin/basemgr/user_provider_impl.cc b/bin/basemgr/user_provider_impl.cc
deleted file mode 100644
index af311fd..0000000
--- a/bin/basemgr/user_provider_impl.cc
+++ /dev/null
@@ -1,556 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/basemgr/user_provider_impl.h"
-
-#include <utility>
-
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/path.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "peridot/bin/basemgr/users_generated.h"
-#include "peridot/lib/common/xdr.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace modular {
-
-namespace {
-
-constexpr char kUsersConfigurationFile[] = "/data/modular/users-v5.db";
-
-// Url of the application launching token manager
-constexpr char kUserProviderAppUrl[] = "user_provider_url";
-
-// Dev auth provider configuration
-constexpr char kDevAuthProviderType[] = "dev";
-constexpr char kDevAuthProviderUrl[] =
- "fuchsia-pkg://fuchsia.com/dev_auth_provider#meta/"
- "dev_auth_provider.cmx";
-
-// Google auth provider configuration
-constexpr char kGoogleAuthProviderType[] = "google";
-constexpr char kGoogleAuthProviderUrl[] =
- "fuchsia-pkg://fuchsia.com/google_auth_provider#meta/"
- "google_auth_provider.cmx";
-
-fuchsia::modular::auth::AccountPtr Convert(
- const fuchsia::modular::UserStorage* const user) {
- FXL_DCHECK(user);
- auto account = fuchsia::modular::auth::Account::New();
- account->id = user->id()->str();
- switch (user->identity_provider()) {
- case fuchsia::modular::IdentityProvider_DEV:
- account->identity_provider =
- fuchsia::modular::auth::IdentityProvider::DEV;
- break;
- case fuchsia::modular::IdentityProvider_GOOGLE:
- account->identity_provider =
- fuchsia::modular::auth::IdentityProvider::GOOGLE;
- break;
- default:
- FXL_DCHECK(false) << "Unrecognized IdentityProvider"
- << user->identity_provider();
- }
-
- account->display_name = user->display_name()->str();
- account->url = user->profile_url()->str();
- account->image_url = user->image_url()->str();
-
- if (flatbuffers::IsFieldPresent(
- user, fuchsia::modular::UserStorage::VT_PROFILE_ID)) {
- account->profile_id = user->profile_id()->str();
- } else {
- account->profile_id = "";
- }
- return account;
-}
-
-std::string GetRandomId() {
- uint32_t random_number = 0;
- zx_cprng_draw(&random_number, sizeof random_number);
- return std::to_string(random_number);
-}
-
-// Returns the corresponding |auth_provider_type| string that maps to
-// |fuchsia::modular::auth::IdentityProvider| value.
-// TODO(ukode): Convert enum |fuchsia::modular::auth::IdentityProvider| to
-// fidl::String datatype to make it consistent in the future.
-std::string MapIdentityProviderToAuthProviderType(
- const fuchsia::modular::auth::IdentityProvider idp) {
- switch (idp) {
- case fuchsia::modular::auth::IdentityProvider::DEV:
- return kDevAuthProviderType;
- case fuchsia::modular::auth::IdentityProvider::GOOGLE:
- return kGoogleAuthProviderType;
- }
- FXL_DCHECK(false) << "Unrecognized IDP.";
-}
-
-// Returns a list of supported auth provider configurations that includes the
-// type, startup parameters and the url of the auth provider component.
-// TODO(ukode): This list will be derived from a config package in the future.
-std::vector<fuchsia::auth::AuthProviderConfig> GetAuthProviderConfigs() {
- fuchsia::auth::AuthProviderConfig dev_auth_provider_config;
- dev_auth_provider_config.auth_provider_type = kDevAuthProviderType;
- dev_auth_provider_config.url = kDevAuthProviderUrl;
-
- fuchsia::auth::AuthProviderConfig google_auth_provider_config;
- google_auth_provider_config.auth_provider_type = kGoogleAuthProviderType;
- google_auth_provider_config.url = kGoogleAuthProviderUrl;
-
- std::vector<fuchsia::auth::AuthProviderConfig> auth_provider_configs;
- auth_provider_configs.push_back(std::move(google_auth_provider_config));
- auth_provider_configs.push_back(std::move(dev_auth_provider_config));
-
- return auth_provider_configs;
-}
-
-} // namespace
-
-UserProviderImpl::UserProviderImpl(
- fuchsia::sys::Launcher* const launcher,
- const fuchsia::modular::AppConfig& sessionmgr,
- const fuchsia::modular::AppConfig& session_shell,
- const fuchsia::modular::AppConfig& story_shell,
- fuchsia::auth::TokenManagerFactory* token_manager_factory,
- fuchsia::auth::AuthenticationContextProviderPtr
- authentication_context_provider,
- Delegate* const delegate)
- : launcher_(launcher),
- sessionmgr_(sessionmgr),
- session_shell_(session_shell),
- story_shell_(story_shell),
- token_manager_factory_(token_manager_factory),
- authentication_context_provider_(
- std::move(authentication_context_provider)),
- delegate_(delegate),
- authentication_context_provider_binding_(this) {
- FXL_DCHECK(delegate);
- FXL_DCHECK(authentication_context_provider_);
-
- authentication_context_provider_binding_.set_error_handler(
- [this](zx_status_t status) {
- FXL_LOG(WARNING) << "AuthenticationContextProvider disconnected.";
- authentication_context_provider_binding_.Unbind();
- });
-
- // There might not be a file of users persisted. If config file doesn't
- // exist, move forward with no previous users.
- // TODO(alhaad): Use JSON instead of flatbuffers for better inspectablity.
- if (files::IsFile(kUsersConfigurationFile)) {
- std::string serialized_users;
- if (!files::ReadFileToString(kUsersConfigurationFile, &serialized_users)) {
- // Unable to read file. Bailing out.
- FXL_LOG(ERROR) << "Unable to read user configuration file at: "
- << kUsersConfigurationFile;
- return;
- }
-
- if (!Parse(serialized_users)) {
- return;
- }
- }
-}
-
-void UserProviderImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::UserProvider> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void UserProviderImpl::Teardown(const std::function<void()>& callback) {
- if (user_controllers_.empty()) {
- callback();
- return;
- }
-
- for (auto& it : user_controllers_) {
- auto cont = [this, ptr = it.first, callback] {
- // This is okay because during teardown, |cont| is never invoked
- // asynchronously.
- user_controllers_.erase(ptr);
-
- if (!user_controllers_.empty()) {
- // Not the last callback.
- return;
- }
-
- callback();
- };
-
- it.second->Logout(cont);
- }
-}
-
-void UserProviderImpl::Login(fuchsia::modular::UserLoginParams params) {
- // If requested, run in incognito mode.
- if (params.account_id.is_null() || params.account_id == "") {
- FXL_LOG(INFO) << "fuchsia::modular::UserProvider::Login() Incognito mode";
- LoginInternal(nullptr /* account */, std::move(params));
- return;
- }
-
- // If not running in incognito mode, a corresponding entry must be present
- // in the users database.
- const fuchsia::modular::UserStorage* found_user = nullptr;
- if (users_storage_) {
- for (const auto* user : *users_storage_->users()) {
- if (user->id()->str() == params.account_id) {
- found_user = user;
- break;
- }
- }
- }
-
- // If an entry is not found, we drop the incoming requests on the floor.
- if (!found_user) {
- FXL_LOG(INFO) << "The requested user was not found in the users database"
- << "It needs to be added first via "
- "fuchsia::modular::UserProvider::AddUser().";
- return;
- }
-
- LoginInternal(Convert(found_user), std::move(params));
-}
-
-void UserProviderImpl::PreviousUsers(PreviousUsersCallback callback) {
- fidl::VectorPtr<fuchsia::modular::auth::Account> accounts;
- accounts.resize(0);
- if (users_storage_) {
- for (const auto* user : *users_storage_->users()) {
- accounts.push_back(*Convert(user));
- }
- }
- callback(std::move(accounts));
-}
-
-void UserProviderImpl::AddUser(
- fuchsia::modular::auth::IdentityProvider identity_provider,
- AddUserCallback callback) {
- FXL_DCHECK(token_manager_factory_);
-
- // Creating a new user, the initial bootstrapping will be done by
- // AccountManager in the future. For now, create an account_id that
- // uniquely maps to a token manager instance at runtime.
- const std::string& account_id = GetRandomId();
- fuchsia::auth::TokenManagerPtr token_manager;
- token_manager = CreateTokenManager(account_id);
-
- // TODO(ukode): Fuchsia mod configuration that is requesting OAuth tokens.
- // This includes OAuth client specific details such as client id, secret,
- // list of scopes etc. These could be supplied by a config package in the
- // future.
- fuchsia::auth::AppConfig fuchsia_app_config;
- fuchsia_app_config.auth_provider_type =
- MapIdentityProviderToAuthProviderType(identity_provider);
- std::vector<std::string> scopes;
- token_manager->Authorize(
- std::move(fuchsia_app_config), nullptr, std::move(scopes), "", "",
- [this, identity_provider, account_id,
- token_manager = std::move(token_manager),
- callback](fuchsia::auth::Status status,
- fuchsia::auth::UserProfileInfoPtr user_profile_info) {
- if (status != fuchsia::auth::Status::OK) {
- FXL_LOG(ERROR) << "Authorize() call returned error for user: "
- << account_id;
- callback(nullptr, "Failed to authorize user");
- return;
- }
-
- if (!user_profile_info) {
- FXL_LOG(ERROR) << "Authorize() call returned empty user profile";
- callback(nullptr,
- "Empty user profile info returned by auth_provider");
- return;
- }
-
- auto account = fuchsia::modular::auth::Account::New();
- account->id = account_id;
- account->identity_provider = identity_provider;
- account->profile_id = user_profile_info->id;
- account->display_name = user_profile_info->display_name.is_null()
- ? ""
- : user_profile_info->display_name;
- account->url =
- user_profile_info->url.is_null() ? "" : user_profile_info->url;
- account->image_url = user_profile_info->image_url.is_null()
- ? ""
- : user_profile_info->image_url;
-
- std::string error;
- if (!AddUserToAccountsDB(account.get(), &error)) {
- FXL_LOG(ERROR) << "Failed to add user: " << account_id
- << ", to the accounts database:" << error;
- callback(nullptr, error);
- return;
- }
-
- FXL_DLOG(INFO) << "Successfully added user: " << account_id;
- callback(std::move(account), "");
- });
-}
-
-void UserProviderImpl::RemoveUser(std::string account_id,
- RemoveUserCallback callback) {
- fuchsia::modular::auth::AccountPtr account;
- if (users_storage_) {
- for (const auto* user : *users_storage_->users()) {
- if (user->id()->str() == account_id) {
- account = Convert(user);
- }
- }
- }
-
- if (!account) {
- callback("User not found.");
- return;
- }
-
- RemoveUserInternal(std::move(account), std::move(callback));
-}
-
-bool UserProviderImpl::AddUserToAccountsDB(
- const fuchsia::modular::auth::Account* account, std::string* error) {
- FXL_DCHECK(account);
-
- flatbuffers::FlatBufferBuilder builder;
- std::vector<flatbuffers::Offset<fuchsia::modular::UserStorage>> users;
-
- // Reserialize existing users.
- if (users_storage_) {
- for (const auto* user : *(users_storage_->users())) {
- users.push_back(fuchsia::modular::CreateUserStorage(
- builder, builder.CreateString(user->id()), user->identity_provider(),
- builder.CreateString(user->display_name()),
- builder.CreateString(user->profile_url()),
- builder.CreateString(user->image_url()),
- builder.CreateString(user->profile_id())));
- }
- }
-
- auto account_identity_provider = account->identity_provider;
- auto flatbuffer_identity_provider = [account_identity_provider]() {
- switch (account_identity_provider) {
- case fuchsia::modular::auth::IdentityProvider::DEV:
- return fuchsia::modular::IdentityProvider::IdentityProvider_DEV;
- case fuchsia::modular::auth::IdentityProvider::GOOGLE:
- return fuchsia::modular::IdentityProvider::IdentityProvider_GOOGLE;
- }
- FXL_DCHECK(false) << "Unrecognized IDP.";
- // TODO(ukode): Move |UserStorage::identity_provider| to string
- // datatype. Use DEV identity provider as default in the interim.
- return fuchsia::modular::IdentityProvider::IdentityProvider_DEV;
- }();
-
- // Add new user
- users.push_back(fuchsia::modular::CreateUserStorage(
- builder, builder.CreateString(account->id), flatbuffer_identity_provider,
- builder.CreateString(account->display_name),
- builder.CreateString(account->url),
- builder.CreateString(account->image_url),
- builder.CreateString(account->profile_id)));
-
- // Write user info to disk
- builder.Finish(fuchsia::modular::CreateUsersStorage(
- builder, builder.CreateVector(users)));
- std::string new_serialized_users = std::string(
- reinterpret_cast<const char*>(builder.GetCurrentBufferPointer()),
- builder.GetSize());
-
- return WriteUsersDb(new_serialized_users, error);
-}
-
-void UserProviderImpl::RemoveUserInternal(
- fuchsia::modular::auth::AccountPtr account, RemoveUserCallback callback) {
- FXL_DCHECK(account);
- auto account_id = account->id;
-
- FXL_DLOG(INFO) << "Invoking DeleteAllTokens() for user:" << account_id;
-
- auto token_manager = CreateTokenManager(account_id);
-
- // TODO(ukode): Delete tokens for all the supported auth provider configs just
- // not Google. This will be replaced by AccountManager::RemoveUser api in the
- // future.
- fuchsia::auth::AppConfig fuchsia_app_config;
- fuchsia_app_config.auth_provider_type = kGoogleAuthProviderType;
- token_manager->DeleteAllTokens(
- fuchsia_app_config, account->profile_id,
- [this, account_id, token_manager = std::move(token_manager),
- callback](fuchsia::auth::Status status) {
- if (status != fuchsia::auth::Status::OK) {
- FXL_LOG(ERROR) << "Token Manager Authorize() call returned error";
- callback("Unable to remove user");
- return;
- }
-
- std::string error;
- if (!RemoveUserFromAccountsDB(account_id, &error)) {
- FXL_LOG(ERROR) << "Error in updating user database: " << error;
- callback(error);
- return;
- }
-
- callback(""); // success
- });
-}
-
-// Update user storage after deleting user credentials.
-bool UserProviderImpl::RemoveUserFromAccountsDB(fidl::StringPtr account_id,
- std::string* error) {
- FXL_DCHECK(account_id);
- FXL_DCHECK(error);
-
- flatbuffers::FlatBufferBuilder builder;
- std::vector<flatbuffers::Offset<fuchsia::modular::UserStorage>> users;
- for (const auto* user : *(users_storage_->users())) {
- if (user->id()->str() == account_id) {
- // TODO(alhaad): We need to delete the local ledger data for a user
- // who has been removed. Re-visit this when sandboxing the user
- // runner.
- continue;
- }
-
- users.push_back(fuchsia::modular::CreateUserStorage(
- builder, builder.CreateString(user->id()), user->identity_provider(),
- builder.CreateString(user->display_name()),
- builder.CreateString(user->profile_url()),
- builder.CreateString(user->image_url()),
- builder.CreateString(user->profile_id())));
- }
-
- builder.Finish(fuchsia::modular::CreateUsersStorage(
- builder, builder.CreateVector(users)));
- std::string new_serialized_users = std::string(
- reinterpret_cast<const char*>(builder.GetCurrentBufferPointer()),
- builder.GetSize());
-
- return WriteUsersDb(new_serialized_users, error);
-}
-
-void UserProviderImpl::GetAuthenticationUIContext(
- fidl::InterfaceRequest<fuchsia::auth::AuthenticationUIContext> request) {
- authentication_context_provider_->GetAuthenticationUIContext(
- std::move(request));
-}
-
-fuchsia::auth::TokenManagerPtr UserProviderImpl::CreateTokenManager(
- std::string account_id) {
- FXL_DCHECK(token_manager_factory_);
-
- fuchsia::auth::TokenManagerPtr token_mgr;
- token_manager_factory_->GetTokenManager(
- account_id, kUserProviderAppUrl, GetAuthProviderConfigs(),
- authentication_context_provider_binding_.NewBinding(),
- token_mgr.NewRequest());
-
- token_mgr.set_error_handler([this, account_id](zx_status_t status) {
- FXL_LOG(INFO) << "Token Manager for account:" << account_id
- << " disconnected";
- });
-
- return token_mgr;
-}
-
-bool UserProviderImpl::WriteUsersDb(const std::string& serialized_users,
- std::string* const error) {
- if (!Parse(serialized_users)) {
- *error = "The user database seems corrupted.";
- return false;
- }
-
- // Save users to disk.
- if (!files::CreateDirectory(
- files::GetDirectoryName(kUsersConfigurationFile))) {
- *error = "Unable to create directory.";
- return false;
- }
- if (!files::WriteFile(kUsersConfigurationFile, serialized_users.data(),
- serialized_users.size())) {
- *error = "Unable to write file.";
- return false;
- }
- return true;
-}
-
-bool UserProviderImpl::Parse(const std::string& serialized_users) {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(serialized_users.data()),
- serialized_users.size());
- if (!fuchsia::modular::VerifyUsersStorageBuffer(verifier)) {
- FXL_LOG(ERROR) << "Unable to verify storage buffer.";
- return false;
- }
- serialized_users_ = serialized_users;
- users_storage_ = fuchsia::modular::GetUsersStorage(serialized_users_.data());
- return true;
-}
-
-void UserProviderImpl::LoginInternal(fuchsia::modular::auth::AccountPtr account,
- fuchsia::modular::UserLoginParams params) {
- auto account_id = account ? account->id : GetRandomId();
- FXL_DLOG(INFO) << "Login() User:" << account_id;
-
- // Instead of passing token_manager_factory all the way to agents and
- // runners with all auth provider configurations, send two
- // |fuchsia::auth::TokenManager| handles, one for ledger and one for agents
- // for the given user account |account_id|.
- fuchsia::auth::TokenManagerPtr ledger_token_manager =
- CreateTokenManager(account_id);
- fuchsia::auth::TokenManagerPtr agent_token_manager =
- CreateTokenManager(account_id);
-
- auto view_owner =
- delegate_->GetSessionShellViewOwner(std::move(params.view_owner));
- auto service_provider =
- delegate_->GetSessionShellServiceProvider(std::move(params.services));
-
- auto controller = std::make_unique<UserControllerImpl>(
- launcher_, CloneStruct(sessionmgr_), CloneStruct(session_shell_),
- CloneStruct(story_shell_), std::move(ledger_token_manager),
- std::move(agent_token_manager), std::move(account), std::move(view_owner),
- std::move(service_provider), std::move(params.user_controller),
- [this](UserControllerImpl* c) {
- user_controllers_.erase(c);
- delegate_->DidLogout();
- });
- auto controller_ptr = controller.get();
- user_controllers_[controller_ptr] = std::move(controller);
-
- delegate_->DidLogin();
-}
-
-FuturePtr<> UserProviderImpl::SwapSessionShell(
- fuchsia::modular::AppConfig session_shell_config) {
- if (user_controllers_.size() == 0)
- return Future<>::CreateCompleted("SwapSessionShell(Completed)");
-
- FXL_CHECK(user_controllers_.size() == 1)
- << user_controllers_.size()
- << " user controllers exist, which should be impossible.";
-
- auto user_controller = user_controllers_.begin()->first;
- return user_controller->SwapSessionShell(std::move(session_shell_config));
-}
-
-void UserProviderImpl::RestartSession() {
- // Callback to log the user back in if login is not automatic
- auto login = [this] {
- if (user_controllers_.size() < 1 && users_storage_) {
- auto account = Convert(users_storage_->users()->Get(0));
-
- fuchsia::modular::UserLoginParams params;
- params.account_id = account->id;
- Login(std::move(params));
- }
- };
-
- // Log the user out to shut down sessionmgr
- user_controllers_.begin()->first->Logout(login);
-}
-
-} // namespace modular
diff --git a/bin/basemgr/user_provider_impl.h b/bin/basemgr/user_provider_impl.h
deleted file mode 100644
index 11b31b3..0000000
--- a/bin/basemgr/user_provider_impl.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_BASEMGR_USER_PROVIDER_IMPL_H_
-#define PERIDOT_BIN_BASEMGR_USER_PROVIDER_IMPL_H_
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-
-#include "peridot/bin/basemgr/user_controller_impl.h"
-
-namespace fuchsia {
-namespace modular {
-struct UsersStorage;
-}
-} // namespace fuchsia
-
-namespace modular {
-
-class UserProviderImpl : fuchsia::auth::AuthenticationContextProvider,
- fuchsia::modular::UserProvider {
- public:
- // Users of UserProviderImpl must register a Delegate object.
- class Delegate {
- public:
- // Called after UserProviderImpl successfully logs in a user.
- virtual void DidLogin() = 0;
-
- // Called after UserProviderImpl successfully logs out a user.
- virtual void DidLogout() = 0;
-
- // Enables the delegate to intercept the session shell's view owner, so that
- // e.g. the delegate can embed it in a parent view or present it.
- // |default_view_owner| is the view owner request that's passed to
- // UserProviderImpl from base shell. If you don't need to intercept the
- // view owner, return it without modifying it.
- virtual fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- GetSessionShellViewOwner(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- default_view_owner) = 0;
-
- // Enables the delegate to supply a different service provider to the user
- // shell. |default_service_provider| is the service provider passed to the
- // session shell by the base shell. If you don't need to replace it, return
- // it without modifying it.
- virtual fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
- GetSessionShellServiceProvider(
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
- default_service_provider) = 0;
- };
-
- // |account_provider| and |delegate| must outlive UserProviderImpl.
- UserProviderImpl(
- fuchsia::sys::Launcher* const launcher,
- const fuchsia::modular::AppConfig& sessionmgr,
- const fuchsia::modular::AppConfig& session_shell,
- const fuchsia::modular::AppConfig& story_shell,
- fuchsia::auth::TokenManagerFactory* token_manager_factory,
- fuchsia::auth::AuthenticationContextProviderPtr auth_context_provider,
- Delegate* const delegate);
-
- void Connect(fidl::InterfaceRequest<fuchsia::modular::UserProvider> request);
-
- void Teardown(const std::function<void()>& callback);
-
- // Stops the active session shell, and starts the session shell specified in
- // |session_shell_config|. This has no effect, and will return an
- // immediately-completed future, if no session shells are running.
- FuturePtr<> SwapSessionShell(
- fuchsia::modular::AppConfig session_shell_config);
-
- // Restarts the current session by logging out the current user and logging
- // that user back in.
- void RestartSession();
-
- // |fuchsia::modular::UserProvider|, also called by |basemgr_impl|.
- void Login(fuchsia::modular::UserLoginParams params) override;
-
- // |fuchsia::modular::UserProvider|, also called by |basemgr_impl|.
- void PreviousUsers(PreviousUsersCallback callback) override;
-
- // |fuchsia::modular::UserProvider|, also called by |basemgr_impl|.
- void RemoveUser(std::string account_id,
- RemoveUserCallback callback) override;
-
- private:
- // |fuchsia::modular::UserProvider|
- void AddUser(fuchsia::modular::auth::IdentityProvider identity_provider,
- AddUserCallback callback) override;
-
- // |fuchsia::auth::AuthenticationContextProvider|
- void GetAuthenticationUIContext(
- fidl::InterfaceRequest<fuchsia::auth::AuthenticationUIContext> request)
- override;
-
- // Returns a new |fuchsia::auth::TokenManager| handle for the given user
- // account |account_id|.
- fuchsia::auth::TokenManagerPtr CreateTokenManager(std::string account_id);
-
- bool AddUserToAccountsDB(const fuchsia::modular::auth::Account* account,
- std::string* error);
- bool RemoveUserFromAccountsDB(fidl::StringPtr account_id, std::string* error);
- bool WriteUsersDb(const std::string& serialized_users, std::string* error);
- bool Parse(const std::string& serialized_users);
- void RemoveUserInternal(fuchsia::modular::auth::AccountPtr account,
- RemoveUserCallback callback);
- void LoginInternal(fuchsia::modular::auth::AccountPtr account,
- fuchsia::modular::UserLoginParams params);
-
- fidl::BindingSet<fuchsia::modular::UserProvider> bindings_;
-
- fuchsia::sys::Launcher* const launcher_; // Not owned.
- const fuchsia::modular::AppConfig& sessionmgr_; // Neither owned nor copied.
- const fuchsia::modular::AppConfig&
- session_shell_; // Neither owned nor copied.
- const fuchsia::modular::AppConfig& story_shell_; // Neither owned nor copied.
- fuchsia::auth::TokenManagerFactory* const
- token_manager_factory_; // Neither owned nor copied.
- fuchsia::auth::AuthenticationContextProviderPtr
- authentication_context_provider_;
- Delegate* const delegate_; // Neither owned nor copied.
-
- fidl::Binding<fuchsia::auth::AuthenticationContextProvider>
- authentication_context_provider_binding_;
- std::string serialized_users_;
- const fuchsia::modular::UsersStorage* users_storage_ = nullptr;
-
- std::map<UserControllerImpl*, std::unique_ptr<UserControllerImpl>>
- user_controllers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(UserProviderImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_BASEMGR_USER_PROVIDER_IMPL_H_
diff --git a/bin/basemgr/users.fbs b/bin/basemgr/users.fbs
deleted file mode 100644
index f1017f4..0000000
--- a/bin/basemgr/users.fbs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-namespace fuchsia.modular;
-
-// See public/fidl/fuchsia.modular.auth/account/account.fidl for detailed
-// documentation about these fields.
-
-enum IdentityProvider : byte { DEV, GOOGLE }
-
-table UserStorage {
- id: string;
- identity_provider: IdentityProvider;
- display_name: string;
- profile_url: string;
- image_url: string;
- profile_id: string;
-}
-
-table UsersStorage {
- users: [UserStorage];
-}
-
-root_type UsersStorage;
diff --git a/bin/cloud_provider_firestore/BUILD.gn b/bin/cloud_provider_firestore/BUILD.gn
deleted file mode 100644
index 4438f6a..0000000
--- a/bin/cloud_provider_firestore/BUILD.gn
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-
-package("cloud_provider_firestore") {
- deps = [
- "app",
- "//peridot/bin/ledger/cobalt:ledger_metrics_registry",
- ]
-
- resources = [
- {
- path =
- rebase_path(get_label_info(
- "//peridot/bin/ledger/cobalt:ledger_metrics_registry",
- "target_gen_dir") + "/ledger_metrics_registry.pb")
- dest = "firebase_auth_ledger_metrics_config.pb"
- },
- ]
-
- binary = "cloud_provider_firestore"
-
- meta = [
- {
- path = rebase_path("app/meta/cloud_provider_firestore.cmx")
- dest = "cloud_provider_firestore.cmx"
- },
- ]
-}
-
-executable("unittests") {
- testonly = true
-
- output_name = "cloud_provider_firestore_unittests"
-
- deps = [
- "//peridot/bin/cloud_provider_firestore/app:unittests",
- "//peridot/bin/cloud_provider_firestore/firestore:unittests",
- "//peridot/bin/cloud_provider_firestore/grpc:unittests",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-group("tests") {
- testonly = true
-
- public_deps = [
- ":unittests",
- "//peridot/bin/cloud_provider_firestore/validation",
- ]
-}
diff --git a/bin/cloud_provider_firestore/README.md b/bin/cloud_provider_firestore/README.md
deleted file mode 100644
index eed929c..0000000
--- a/bin/cloud_provider_firestore/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Firestore-based cloud provider
-
-This directory contains a Firestore-based implementation of the [cloud provider]
-interface.
-
-[TOC]
-
-## Testing
-
-The tests are packaged with Ledger tests.
-
-In order to run the unit tests:
-
-```sh
-fx run-test -t cloud_provider_firestore_unittests ledger_tests
-```
-
-In order to run the [validation tests], follow the [cloud sync set-up
-instructions] to set up a Firestore instance, configure the build environment
-and obtain the sync parameters.
-
-Then, run the validation tests as follows:
-
-```sh
-fx run-test -t validation_firestore ledger_tests
-```
-
-Note that `validation_firestore` is only a launcher for the actual tests,
-`cloud_provider_validation_tests`. As a result, you will need to look at `fx
-log` output to see if the tests passed.
-
-## Documentation
-
- - [configuration](docs/configuration.md) of server instances
-
-[cloud provider]: /public/fidl/fuchsia.ledger.cloud/cloud_provider.fidl
-[cloud sync set-up instructions]: /docs/ledger/testing.md#cloud-sync
-[validation tests]: /public/lib/cloud_provider/validation/README.md
diff --git a/bin/cloud_provider_firestore/app/BUILD.gn b/bin/cloud_provider_firestore/app/BUILD.gn
deleted file mode 100644
index 2203654..0000000
--- a/bin/cloud_provider_firestore/app/BUILD.gn
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/cloud_provider_firestore/*" ]
-
-executable("app") {
- output_name = "cloud_provider_firestore"
-
- sources = [
- "app.cc",
- ]
-
- deps = [
- ":lib",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/rng:system",
- "//peridot/public/fidl/fuchsia.modular",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-}
-
-source_set("lib") {
- sources = [
- "cloud_provider_impl.cc",
- "cloud_provider_impl.h",
- "credentials_provider.h",
- "credentials_provider_impl.cc",
- "credentials_provider_impl.h",
- "device_set_impl.cc",
- "device_set_impl.h",
- "factory_impl.cc",
- "factory_impl.h",
- "grpc_status.cc",
- "grpc_status.h",
- "page_cloud_impl.cc",
- "page_cloud_impl.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/bin/cloud_provider_firestore/fidl",
- "//peridot/bin/cloud_provider_firestore/firestore",
- "//peridot/bin/cloud_provider_firestore/include",
- "//peridot/lib/firebase_auth",
- "//peridot/lib/rng",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//third_party/grpc:grpc++",
- ]
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fsl",
- "//peridot/bin/ledger/app:serialization_version",
- "//peridot/lib/commit_pack",
- "//peridot/lib/convert",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "cloud_provider_impl_unittest.cc",
- "credentials_provider_impl_unittest.cc",
- "device_set_impl_unittest.cc",
- "factory_impl_unittest.cc",
- "page_cloud_impl_unittest.cc",
- ]
-
- deps = [
- ":lib",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl:fxl_printers",
- "//garnet/public/lib/gtest",
- "//peridot/bin/cloud_provider_firestore/app/testing",
- "//peridot/bin/cloud_provider_firestore/firestore/testing",
- "//peridot/lib/convert",
- "//peridot/lib/firebase_auth/testing",
- "//peridot/lib/rng:testing",
- "//third_party/protobuf:protobuf_full",
- ]
-}
diff --git a/bin/cloud_provider_firestore/app/app.cc b/bin/cloud_provider_firestore/app/app.cc
deleted file mode 100644
index 5550748..0000000
--- a/bin/cloud_provider_firestore/app/app.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/log_settings_command_line.h>
-#include <trace-provider/provider.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/factory_impl.h"
-#include "peridot/lib/rng/system_random.h"
-
-namespace cloud_provider_firestore {
-namespace {
-
-constexpr fxl::StringView kCobaltClientName = "cloud_provider_firestore";
-constexpr fxl::StringView kNoStatisticsReporting = "disable_reporting";
-
-struct AppParams {
- bool disable_statistics = false;
-};
-
-class App : public fuchsia::modular::Lifecycle {
- public:
- explicit App(AppParams app_params)
- : loop_(&kAsyncLoopConfigAttachToThread),
- startup_context_(component::StartupContext::CreateFromStartupInfo()),
- trace_provider_(loop_.dispatcher()),
- factory_impl_(
- loop_.dispatcher(), &random_, startup_context_.get(),
- app_params.disable_statistics ? "" : kCobaltClientName.ToString()) {
- FXL_DCHECK(startup_context_);
- }
-
- void Run() {
- startup_context_->outgoing().AddPublicService<fuchsia::modular::Lifecycle>(
- [this](fidl::InterfaceRequest<fuchsia::modular::Lifecycle> request) {
- lifecycle_bindings_.AddBinding(this, std::move(request));
- });
- startup_context_->outgoing().AddPublicService<Factory>(
- [this](fidl::InterfaceRequest<Factory> request) {
- factory_bindings_.AddBinding(&factory_impl_, std::move(request));
- });
- loop_.Run();
- }
-
- void Terminate() override {
- factory_impl_.ShutDown([this] { loop_.Quit(); });
- }
-
- private:
- async::Loop loop_;
- rng::SystemRandom random_;
- std::unique_ptr<component::StartupContext> startup_context_;
- trace::TraceProvider trace_provider_;
-
- FactoryImpl factory_impl_;
- fidl::BindingSet<fuchsia::modular::Lifecycle> lifecycle_bindings_;
- fidl::BindingSet<Factory> factory_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(App);
-};
-} // namespace
-
-} // namespace cloud_provider_firestore
-
-int main(int argc, const char** argv) {
- // The trust root file is made available by the sandbox feature
- // "root-ssl-certificates"
- setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", "/config/ssl/cert.pem", 1);
-
- const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- fxl::SetLogSettingsFromCommandLine(command_line);
-
- cloud_provider_firestore::AppParams app_params;
- app_params.disable_statistics =
- command_line.HasOption(cloud_provider_firestore::kNoStatisticsReporting);
-
- cloud_provider_firestore::App app(app_params);
- app.Run();
-
- return 0;
-}
diff --git a/bin/cloud_provider_firestore/app/cloud_provider_impl.cc b/bin/cloud_provider_firestore/app/cloud_provider_impl.cc
deleted file mode 100644
index 2aa6297..0000000
--- a/bin/cloud_provider_firestore/app/cloud_provider_impl.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/cloud_provider_impl.h"
-
-#include <utility>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/concatenate.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/credentials_provider_impl.h"
-#include "peridot/bin/cloud_provider_firestore/app/grpc_status.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/encoding.h"
-#include "peridot/bin/ledger/app/serialization_version.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_provider_firestore {
-
-constexpr char kSeparator[] = "/";
-constexpr char kUsersCollection[] = "users";
-constexpr char kVersionsCollection[] = "versions";
-constexpr char kPageCollection[] = "pages";
-constexpr char kNamespaceCollection[] = "namespaces";
-constexpr char kExistsKey[] = "exists";
-
-std::string GetUserPath(fxl::StringView root_path, fxl::StringView user_id) {
- return fxl::Concatenate({
- root_path,
- kSeparator,
- kUsersCollection,
- kSeparator,
- user_id,
- });
-}
-
-std::string GetVersionPath(fxl::StringView user_path) {
- return fxl::Concatenate({
- user_path,
- kSeparator,
- kVersionsCollection,
- kSeparator,
- ledger::kSerializationVersion,
- });
-}
-
-std::string GetNamespacePath(fxl::StringView version_path,
- fxl::StringView namespace_id) {
- std::string encoded_namespace_id = EncodeKey(namespace_id);
- return fxl::Concatenate({version_path, kSeparator, kNamespaceCollection,
- kSeparator, encoded_namespace_id});
-}
-
-std::string GetPagePath(fxl::StringView namespace_path,
- fxl::StringView page_id) {
- std::string encoded_page_id = EncodeKey(page_id);
- return fxl::Concatenate({namespace_path, kSeparator, kPageCollection,
- kSeparator, encoded_page_id});
-}
-
-CloudProviderImpl::CloudProviderImpl(
- rng::Random* random, std::string user_id,
- std::unique_ptr<firebase_auth::FirebaseAuth> firebase_auth,
- std::unique_ptr<FirestoreService> firestore_service,
- fidl::InterfaceRequest<cloud_provider::CloudProvider> request)
- : random_(random),
- user_id_(std::move(user_id)),
- firestore_service_(std::move(firestore_service)),
- binding_(this, std::move(request)),
- weak_ptr_factory_(this) {
- // The class shuts down when the client connection is disconnected.
- binding_.set_error_handler(
- [this](zx_status_t status) { ShutDownAndReportEmpty(); });
- // The class also shuts down when the auth provider is disconnected.
- firebase_auth->set_error_handler([this] {
- FXL_LOG(ERROR) << "Lost connection to the token provider, "
- << "shutting down the cloud provider.";
- ShutDownAndReportEmpty();
- });
-
- credentials_provider_ =
- std::make_unique<CredentialsProviderImpl>(std::move(firebase_auth));
-}
-
-CloudProviderImpl::~CloudProviderImpl() {}
-
-void CloudProviderImpl::ShutDownAndReportEmpty() {
- if (binding_.is_bound()) {
- binding_.Unbind();
- }
-
- fit::closure shut_down = [this] {
- firestore_service_->ShutDown([this] {
- if (on_empty_) {
- on_empty_();
- }
- });
- };
-
- if (pending_placeholder_requests_.empty()) {
- shut_down();
- return;
- }
-
- pending_placeholder_requests_.set_on_empty(std::move(shut_down));
-}
-
-void CloudProviderImpl::ScopedGetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback) {
- credentials_provider_->GetCredentials(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void CloudProviderImpl::GetDeviceSet(
- fidl::InterfaceRequest<cloud_provider::DeviceSet> device_set,
- GetDeviceSetCallback callback) {
- const std::string user_path =
- GetUserPath(firestore_service_->GetRootPath(), user_id_);
- const std::string version_path = GetVersionPath(user_path);
- device_sets_.emplace(version_path, credentials_provider_.get(),
- firestore_service_.get(), std::move(device_set));
- callback(cloud_provider::Status::OK);
-
- // Create a placeholder document for the root of the serialization version.
- CreatePlaceholderDocument(user_path, kVersionsCollection,
- ledger::kSerializationVersion.ToString());
-}
-
-void CloudProviderImpl::GetPageCloud(
- std::vector<uint8_t> app_id, std::vector<uint8_t> page_id,
- fidl::InterfaceRequest<cloud_provider::PageCloud> page_cloud,
- GetPageCloudCallback callback) {
- const std::string user_path =
- GetUserPath(firestore_service_->GetRootPath(), user_id_);
- const std::string version_path = GetVersionPath(user_path);
- const std::string app_id_str = convert::ToString(app_id);
- const std::string namespace_path = GetNamespacePath(version_path, app_id_str);
- const std::string page_id_str = convert::ToString(page_id);
- const std::string page_path = GetPagePath(namespace_path, page_id_str);
- page_clouds_.emplace(page_path, random_, credentials_provider_.get(),
- firestore_service_.get(), std::move(page_cloud));
- callback(cloud_provider::Status::OK);
-
- // Create a placeholder document for the root of the serialization version.
- CreatePlaceholderDocument(user_path, kVersionsCollection,
- ledger::kSerializationVersion.ToString());
- // Create a placeholder document for the root of the app namespace.
- CreatePlaceholderDocument(version_path, kNamespaceCollection,
- EncodeKey(app_id_str));
- // Create a placeholder document for the root of the page.
- CreatePlaceholderDocument(namespace_path, kPageCollection,
- EncodeKey(page_id_str));
-}
-
-void CloudProviderImpl::CreatePlaceholderDocument(
- std::string parent_document_path, std::string collection_id,
- std::string document_id) {
- auto request = google::firestore::v1beta1::CreateDocumentRequest();
- request.set_parent(std::move(parent_document_path));
- request.set_collection_id(std::move(collection_id));
- request.set_document_id(std::move(document_id));
- google::firestore::v1beta1::Value exists;
- exists.set_boolean_value(true);
- (*(request.mutable_document()->mutable_fields()))[kExistsKey] = exists;
-
- // Create an object that tracks the request in progress, so that we don't shut
- // down between requesting and receiving the credentials (see
- // ShutDownAndReportEmoty()). The value |true| is not meaningful.
- auto pending_request_marker = pending_placeholder_requests_.Manage(true);
- ScopedGetCredentials(
- [this, request = std::move(request),
- pending_request_marker =
- std::move(pending_request_marker)](auto call_credentials) mutable {
- firestore_service_->CreateDocument(
- std::move(request), std::move(call_credentials),
- [](auto status, auto result) {
- if (status.error_code() != grpc::OK &&
- status.error_code() != grpc::ALREADY_EXISTS) {
- LogGrpcRequestError(status);
- }
- });
- });
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/cloud_provider_impl.h b/bin/cloud_provider_firestore/app/cloud_provider_impl.h
deleted file mode 100644
index a056be3..0000000
--- a/bin/cloud_provider_firestore/app/cloud_provider_impl.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CLOUD_PROVIDER_IMPL_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CLOUD_PROVIDER_IMPL_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/ledger/cloud/firestore/cpp/fidl.h>
-#include <lib/callback/managed_container.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/device_set_impl.h"
-#include "peridot/bin/cloud_provider_firestore/app/page_cloud_impl.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/firestore_service.h"
-#include "peridot/lib/firebase_auth/firebase_auth_impl.h"
-#include "peridot/lib/rng/random.h"
-
-namespace cloud_provider_firestore {
-
-// Implementation of cloud_provider::CloudProvider.
-//
-// If the |on_empty| callback is set, it is called when the client connection is
-// closed.
-class CloudProviderImpl : public cloud_provider::CloudProvider {
- public:
- CloudProviderImpl(
- rng::Random* random, std::string user_id,
- std::unique_ptr<firebase_auth::FirebaseAuth> firebase_auth,
- std::unique_ptr<FirestoreService> firestore_service,
- fidl::InterfaceRequest<cloud_provider::CloudProvider> request);
- ~CloudProviderImpl() override;
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
-
- // Shuts the class down and calls the on_empty callback, if set.
- //
- // It is only valid to delete the class after the on_empty callback is called.
- void ShutDownAndReportEmpty();
-
- private:
- void GetDeviceSet(
- fidl::InterfaceRequest<cloud_provider::DeviceSet> device_set,
- GetDeviceSetCallback callback) override;
-
- void GetPageCloud(
- std::vector<uint8_t> app_id, std::vector<uint8_t> page_id,
- fidl::InterfaceRequest<cloud_provider::PageCloud> page_cloud,
- GetPageCloudCallback callback) override;
-
- // Makes a best-effort attempt to create a placeholder document at the given
- // location.
- //
- // Placeholder documents have a single field "exists: true" and ensure that
- // data under this path is visible when querying the parent collection. This
- // works around limitations of the web client API for purposes of the
- // development cloud dashboard, see LE-522.
- void CreatePlaceholderDocument(std::string parent_document_path,
- std::string collection_id,
- std::string document_id);
-
- void ScopedGetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback);
-
- rng::Random* const random_;
- const std::string user_id_;
-
- std::unique_ptr<CredentialsProvider> credentials_provider_;
- std::unique_ptr<FirestoreService> firestore_service_;
- fidl::Binding<cloud_provider::CloudProvider> binding_;
- fit::closure on_empty_;
-
- callback::AutoCleanableSet<DeviceSetImpl> device_sets_;
- callback::AutoCleanableSet<PageCloudImpl> page_clouds_;
-
- // Tracks pending requests to create placeholder documents.
- callback::ManagedContainer pending_placeholder_requests_;
-
- // Must be the last member.
- fxl::WeakPtrFactory<CloudProviderImpl> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(CloudProviderImpl);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CLOUD_PROVIDER_IMPL_H_
diff --git a/bin/cloud_provider_firestore/app/cloud_provider_impl_unittest.cc b/bin/cloud_provider_firestore/app/cloud_provider_impl_unittest.cc
deleted file mode 100644
index 1ebe583..0000000
--- a/bin/cloud_provider_firestore/app/cloud_provider_impl_unittest.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/cloud_provider_impl.h"
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/firebase_auth/testing/test_firebase_auth.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace cloud_provider_firestore {
-
-class CloudProviderImplTest : public gtest::TestLoopFixture {
- public:
- CloudProviderImplTest() : random_(test_loop().initial_state()) {
- auto firebase_auth =
- std::make_unique<firebase_auth::TestFirebaseAuth>(dispatcher());
- firebase_auth_ = firebase_auth.get();
- auto firestore_service = std::make_unique<TestFirestoreService>();
- firestore_service_ = firestore_service.get();
- cloud_provider_impl_ = std::make_unique<CloudProviderImpl>(
- &random_, "some user id", std::move(firebase_auth),
- std::move(firestore_service), cloud_provider_.NewRequest());
- }
- ~CloudProviderImplTest() override {}
-
- protected:
- rng::TestRandom random_;
- firebase_auth::TestFirebaseAuth* firebase_auth_ = nullptr;
-
- TestFirestoreService* firestore_service_;
- cloud_provider::CloudProviderPtr cloud_provider_;
- std::unique_ptr<CloudProviderImpl> cloud_provider_impl_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(CloudProviderImplTest);
-};
-
-TEST_F(CloudProviderImplTest, EmptyWhenClientDisconnected) {
- bool on_empty_called = false;
- cloud_provider_impl_->set_on_empty(
- [this, &on_empty_called] { on_empty_called = true; });
- EXPECT_FALSE(firestore_service_->shutdown_callback);
- cloud_provider_.Unbind();
- RunLoopUntilIdle();
-
- // Verify that shutdown was started, but on_empty wasn't called yet.
- EXPECT_TRUE(firestore_service_->shutdown_callback);
- EXPECT_FALSE(on_empty_called);
-
- // Verify that on_empty is called when the shutdown callback is executed.
- firestore_service_->shutdown_callback();
- EXPECT_TRUE(on_empty_called);
-}
-
-TEST_F(CloudProviderImplTest, EmptyWhenFirebaseAuthDisconnected) {
- bool on_empty_called = false;
- cloud_provider_impl_->set_on_empty(
- [this, &on_empty_called] { on_empty_called = true; });
- firebase_auth_->TriggerConnectionErrorHandler();
- RunLoopUntilIdle();
-
- // Verify that shutdown was started, but on_empty wasn't called yet.
- EXPECT_TRUE(firestore_service_->shutdown_callback);
- EXPECT_FALSE(on_empty_called);
-
- // Verify that on_empty is called when the shutdown callback is executed.
- firestore_service_->shutdown_callback();
- EXPECT_TRUE(on_empty_called);
-}
-
-TEST_F(CloudProviderImplTest, GetDeviceSet) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- cloud_provider::DeviceSetPtr device_set;
- cloud_provider_->GetDeviceSet(
- device_set.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-
- // Expect one placeholder document creation request: root document of the
- // serialization version.
- EXPECT_EQ(1u, firestore_service_->create_document_records.size());
-}
-
-TEST_F(CloudProviderImplTest, GetPageCloud) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- cloud_provider::PageCloudPtr page_cloud;
- cloud_provider_->GetPageCloud(
- convert::ToArray("app_id"), convert::ToArray("page_id"),
- page_cloud.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-
- // Expect three placeholder document creation request: root document of the
- // serialization version, root document of the app namespace, root document of
- // the page.
- EXPECT_EQ(3u, firestore_service_->create_document_records.size());
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/credentials_provider.h b/bin/cloud_provider_firestore/app/credentials_provider.h
deleted file mode 100644
index d954193..0000000
--- a/bin/cloud_provider_firestore/app/credentials_provider.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CREDENTIALS_PROVIDER_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CREDENTIALS_PROVIDER_H_
-
-#include <functional>
-#include <memory>
-
-#include <grpc++/grpc++.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-namespace cloud_provider_firestore {
-
-// Interface for a provider of gRPC call credentials that can be used to make
-// Firestore requests.
-class CredentialsProvider {
- public:
- CredentialsProvider() {}
- virtual ~CredentialsProvider() {}
-
- // Retrieves call credentials.
- virtual void GetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(CredentialsProvider);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CREDENTIALS_PROVIDER_H_
diff --git a/bin/cloud_provider_firestore/app/credentials_provider_impl.cc b/bin/cloud_provider_firestore/app/credentials_provider_impl.cc
deleted file mode 100644
index 73217b2..0000000
--- a/bin/cloud_provider_firestore/app/credentials_provider_impl.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/credentials_provider_impl.h"
-
-#include <lib/fit/function.h>
-
-namespace cloud_provider_firestore {
-
-namespace {
-
-class FirebaseAuthPlugin : public grpc::MetadataCredentialsPlugin {
- public:
- explicit FirebaseAuthPlugin(std::string token)
- : header_value_("Bearer " + token) {}
-
- grpc::Status GetMetadata(
- grpc::string_ref /*service_url*/, grpc::string_ref /*method_name*/,
- const grpc::AuthContext& /*channel_auth_context*/,
- std::multimap<grpc::string, grpc::string>* metadata) override {
- // note: grpc seems to insist on lowercase "authorization", otherwise we get
- // "Illegal header key" from "src/core/lib/surface/validate_metadata.c".
- metadata->insert(std::make_pair("authorization", header_value_));
- return grpc::Status::OK;
- }
-
- private:
- const std::string header_value_;
-};
-
-std::shared_ptr<grpc::CallCredentials> MakeCredentials(std::string token) {
- return grpc::MetadataCredentialsFromPlugin(
- std::make_unique<FirebaseAuthPlugin>(std::move(token)));
-}
-
-} // namespace
-
-CredentialsProviderImpl::CredentialsProviderImpl(
- std::unique_ptr<firebase_auth::FirebaseAuth> firebase_auth)
- : firebase_auth_(std::move(firebase_auth)) {}
-
-CredentialsProviderImpl::~CredentialsProviderImpl() {}
-
-void CredentialsProviderImpl::GetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback) {
- auto request = firebase_auth_->GetFirebaseToken(
- [this, callback = std::move(callback)](
- firebase_auth::AuthStatus auth_status, std::string auth_token) {
- switch (auth_status) {
- case firebase_auth::AuthStatus::OK:
- callback(MakeCredentials(auth_token));
- return;
- case firebase_auth::AuthStatus::ERROR:
- callback(nullptr);
- return;
- }
- });
- auth_token_requests_.emplace(request);
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/credentials_provider_impl.h b/bin/cloud_provider_firestore/app/credentials_provider_impl.h
deleted file mode 100644
index a78225f..0000000
--- a/bin/cloud_provider_firestore/app/credentials_provider_impl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CREDENTIALS_PROVIDER_IMPL_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CREDENTIALS_PROVIDER_IMPL_H_
-
-#include <functional>
-#include <memory>
-
-#include <grpc++/grpc++.h>
-#include <lib/callback/cancellable.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/credentials_provider.h"
-#include "peridot/lib/firebase_auth/firebase_auth.h"
-
-namespace cloud_provider_firestore {
-
-class CredentialsProviderImpl : public CredentialsProvider {
- public:
- explicit CredentialsProviderImpl(
- std::unique_ptr<firebase_auth::FirebaseAuth> firebase_auth);
- ~CredentialsProviderImpl() override;
-
- void GetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback)
- override;
-
- private:
- std::unique_ptr<firebase_auth::FirebaseAuth> firebase_auth_;
-
- // Pending auth token requests to be cancelled when this class goes away.
- callback::CancellableContainer auth_token_requests_;
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_CREDENTIALS_PROVIDER_IMPL_H_
diff --git a/bin/cloud_provider_firestore/app/credentials_provider_impl_unittest.cc b/bin/cloud_provider_firestore/app/credentials_provider_impl_unittest.cc
deleted file mode 100644
index 53e8402..0000000
--- a/bin/cloud_provider_firestore/app/credentials_provider_impl_unittest.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/credentials_provider_impl.h"
-
-#include <gtest/gtest.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/lib/firebase_auth/testing/test_firebase_auth.h"
-
-namespace cloud_provider_firestore {
-
-namespace {
-
-class CredentialsProviderImplTest : public gtest::TestLoopFixture {
- public:
- CredentialsProviderImplTest() {
- auto firebase_auth =
- std::make_unique<firebase_auth::TestFirebaseAuth>(dispatcher());
- firebase_auth_ = firebase_auth.get();
- credentials_provider_ =
- std::make_unique<CredentialsProviderImpl>(std::move(firebase_auth));
- }
-
- protected:
- firebase_auth::TestFirebaseAuth* firebase_auth_ = nullptr;
- std::unique_ptr<CredentialsProviderImpl> credentials_provider_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(CredentialsProviderImplTest);
-};
-
-TEST_F(CredentialsProviderImplTest, Ok) {
- std::shared_ptr<grpc::CallCredentials> call_credentials;
- bool called;
- credentials_provider_->GetCredentials(
- callback::Capture(callback::SetWhenCalled(&called), &call_credentials));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_TRUE(call_credentials);
-}
-
-TEST_F(CredentialsProviderImplTest, Error) {
- firebase_auth_->status_to_return = firebase_auth::AuthStatus::ERROR;
- bool called;
- std::shared_ptr<grpc::CallCredentials> call_credentials;
- credentials_provider_->GetCredentials(
- callback::Capture(callback::SetWhenCalled(&called), &call_credentials));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_FALSE(call_credentials);
-}
-
-} // namespace
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/device_set_impl.cc b/bin/cloud_provider_firestore/app/device_set_impl.cc
deleted file mode 100644
index ddcc4bf..0000000
--- a/bin/cloud_provider_firestore/app/device_set_impl.cc
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/device_set_impl.h"
-
-#include <google/firestore/v1beta1/firestore.pb.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/concatenate.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/grpc_status.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/encoding.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_provider_firestore {
-
-namespace {
-constexpr char kSeparator[] = "/";
-constexpr char kDeviceCollection[] = "devices";
-constexpr char kExistsKey[] = "exists";
-
-std::string GetDevicePath(fxl::StringView user_path,
- fxl::StringView fingerprint) {
- std::string encoded_fingerprint = EncodeKey(fingerprint);
- return fxl::Concatenate({user_path, kSeparator, kDeviceCollection, kSeparator,
- encoded_fingerprint});
-}
-
-class GrpcStatusAccumulator {
- public:
- bool PrepareCall() { return true; }
-
- bool Update(bool /*token*/, grpc::Status status) {
- result_status_ = status;
- return result_status_.ok();
- }
-
- grpc::Status Result() { return result_status_; }
-
- private:
- grpc::Status result_status_ = grpc::Status::OK;
-};
-
-class GrpcStatusWaiter
- : public callback::BaseWaiter<GrpcStatusAccumulator, grpc::Status,
- grpc::Status> {
- private:
- GrpcStatusWaiter()
- : callback::BaseWaiter<GrpcStatusAccumulator, grpc::Status, grpc::Status>(
- GrpcStatusAccumulator()) {}
- FRIEND_REF_COUNTED_THREAD_SAFE(GrpcStatusWaiter);
- FRIEND_MAKE_REF_COUNTED(GrpcStatusWaiter);
-};
-} // namespace
-
-DeviceSetImpl::DeviceSetImpl(
- std::string user_path, CredentialsProvider* credentials_provider,
- FirestoreService* firestore_service,
- fidl::InterfaceRequest<cloud_provider::DeviceSet> request)
- : user_path_(std::move(user_path)),
- credentials_provider_(credentials_provider),
- firestore_service_(firestore_service),
- binding_(this, std::move(request)),
- weak_ptr_factory_(this) {
- FXL_DCHECK(!user_path_.empty());
- FXL_DCHECK(credentials_provider_);
- FXL_DCHECK(firestore_service_);
-
- // The class shuts down when the client connection is disconnected.
- binding_.set_error_handler([this](zx_status_t status) {
- if (on_empty_) {
- on_empty_();
- }
- });
-}
-
-DeviceSetImpl::~DeviceSetImpl() {}
-
-void DeviceSetImpl::ScopedGetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback) {
- credentials_provider_->GetCredentials(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void DeviceSetImpl::CheckFingerprint(std::vector<uint8_t> fingerprint,
- CheckFingerprintCallback callback) {
- auto request = google::firestore::v1beta1::GetDocumentRequest();
- request.set_name(
- GetDevicePath(user_path_, convert::ToStringView(fingerprint)));
-
- ScopedGetCredentials(
- [this, request = std::move(request),
- callback = std::move(callback)](auto call_credentials) mutable {
- firestore_service_->GetDocument(
- std::move(request), std::move(call_credentials),
- [callback = std::move(callback)](auto status, auto result) {
- if (LogGrpcRequestError(status)) {
- callback(ConvertGrpcStatus(status.error_code()));
- return;
- }
-
- callback(cloud_provider::Status::OK);
- });
- });
-}
-
-void DeviceSetImpl::SetFingerprint(std::vector<uint8_t> fingerprint,
- SetFingerprintCallback callback) {
- auto request = google::firestore::v1beta1::CreateDocumentRequest();
- request.set_parent(user_path_);
- request.set_collection_id(kDeviceCollection);
- request.set_document_id(EncodeKey(convert::ToString(fingerprint)));
- google::firestore::v1beta1::Value exists;
- // TODO(ppi): store a timestamp of the last connection rather than a boolean
- // flag.
- exists.set_boolean_value(true);
- (*(request.mutable_document()->mutable_fields()))[kExistsKey] = exists;
-
- ScopedGetCredentials(
- [this, request = std::move(request),
- callback = std::move(callback)](auto call_credentials) mutable {
- firestore_service_->CreateDocument(
- std::move(request), std::move(call_credentials),
- [callback = std::move(callback)](auto status, auto result) {
- if (LogGrpcRequestError(status)) {
- callback(ConvertGrpcStatus(status.error_code()));
- return;
- }
- callback(cloud_provider::Status::OK);
- });
- });
-}
-
-void DeviceSetImpl::SetWatcher(
- std::vector<uint8_t> fingerprint,
- fidl::InterfaceHandle<cloud_provider::DeviceSetWatcher> watcher,
- SetWatcherCallback callback) {
- watcher_ = watcher.Bind();
- watched_fingerprint_ = convert::ToString(fingerprint);
- set_watcher_callback_ = std::move(callback);
-
- ScopedGetCredentials([this](auto call_credentials) mutable {
- // Initiate the listen RPC. We will receive a call on OnConnected() when the
- // watcher is ready.
- listen_call_handler_ =
- firestore_service_->Listen(std::move(call_credentials), this);
- });
-}
-
-void DeviceSetImpl::Erase(EraseCallback callback) {
- auto request = google::firestore::v1beta1::ListDocumentsRequest();
- request.set_parent(user_path_);
- request.set_collection_id(kDeviceCollection);
-
- ScopedGetCredentials(
- [this, request = std::move(request),
- callback = std::move(callback)](auto call_credentials) mutable {
- firestore_service_->ListDocuments(
- std::move(request), call_credentials,
- [this, call_credentials, callback = std::move(callback)](
- auto status, auto result) mutable {
- if (LogGrpcRequestError(status)) {
- callback(ConvertGrpcStatus(status.error_code()));
- return;
- }
- OnGotDocumentsToErase(std::move(call_credentials),
- std::move(result), std::move(callback));
- });
- });
-}
-
-void DeviceSetImpl::OnGotDocumentsToErase(
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- google::firestore::v1beta1::ListDocumentsResponse documents_response,
- EraseCallback callback) {
- if (!documents_response.next_page_token().empty()) {
- // TODO(ppi): handle paginated response.
- FXL_LOG(ERROR)
- << "Failed to erase the device map - too many devices in the map.";
- callback(cloud_provider::Status::INTERNAL_ERROR);
- return;
- }
-
- auto waiter = fxl::MakeRefCounted<GrpcStatusWaiter>();
- for (const auto& document : documents_response.documents()) {
- auto request = google::firestore::v1beta1::DeleteDocumentRequest();
- request.set_name(document.name());
- firestore_service_->DeleteDocument(std::move(request), call_credentials,
- waiter->NewCallback());
- }
- waiter->Finalize(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [callback = std::move(callback)](grpc::Status status) {
- if (LogGrpcRequestError(status)) {
- callback(ConvertGrpcStatus(status.error_code()));
- return;
- }
- callback(cloud_provider::Status::OK);
- }));
-}
-
-void DeviceSetImpl::OnConnected() {
- auto request = google::firestore::v1beta1::ListenRequest();
- request.set_database(firestore_service_->GetDatabasePath());
- request.mutable_add_target()->mutable_documents()->add_documents(
- GetDevicePath(user_path_, watched_fingerprint_));
- listen_call_handler_->Write(std::move(request));
-}
-
-void DeviceSetImpl::OnResponse(
- google::firestore::v1beta1::ListenResponse response) {
- if (response.has_target_change()) {
- if (response.target_change().target_change_type() ==
- google::firestore::v1beta1::TargetChange_TargetChangeType_CURRENT) {
- if (set_watcher_callback_) {
- set_watcher_callback_(cloud_provider::Status::OK);
- set_watcher_callback_ = nullptr;
- }
- }
- return;
- }
- if (response.has_document_delete()) {
- if (set_watcher_callback_) {
- set_watcher_callback_(cloud_provider::Status::NOT_FOUND);
- set_watcher_callback_ = nullptr;
- }
- watcher_->OnCloudErased();
- return;
- }
-}
-
-void DeviceSetImpl::OnFinished(grpc::Status status) {
- if (status.error_code() == grpc::UNAVAILABLE ||
- status.error_code() == grpc::UNAUTHENTICATED) {
- if (watcher_) {
- watcher_->OnNetworkError();
- }
- return;
- }
- LogGrpcConnectionError(status);
- watcher_.Unbind();
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/device_set_impl.h b/bin/cloud_provider_firestore/app/device_set_impl.h
deleted file mode 100644
index b41d64c..0000000
--- a/bin/cloud_provider_firestore/app/device_set_impl.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_DEVICE_SET_IMPL_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_DEVICE_SET_IMPL_H_
-
-#include <memory>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/vector.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/credentials_provider.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/firestore_service.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/listen_call_client.h"
-#include "peridot/bin/cloud_provider_firestore/include/types.h"
-
-namespace cloud_provider_firestore {
-
-// Implementation of cloud_provider::DeviceSet.
-//
-// If the |on_empty| callback is set, it is called when the client connection is
-// closed.
-class DeviceSetImpl : public cloud_provider::DeviceSet, ListenCallClient {
- public:
- DeviceSetImpl(std::string user_path,
- CredentialsProvider* credentials_provider,
- FirestoreService* firestore_service,
- fidl::InterfaceRequest<cloud_provider::DeviceSet> request);
- ~DeviceSetImpl() override;
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
-
- private:
- void ScopedGetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback);
-
- // cloud_provider::DeviceSet:
- void CheckFingerprint(std::vector<uint8_t> fingerprint,
- CheckFingerprintCallback callback) override;
-
- void SetFingerprint(std::vector<uint8_t> fingerprint,
- SetFingerprintCallback callback) override;
-
- void SetWatcher(
- std::vector<uint8_t> fingerprint,
- fidl::InterfaceHandle<cloud_provider::DeviceSetWatcher> watcher,
- SetWatcherCallback callback) override;
-
- void Erase(EraseCallback callback) override;
-
- void OnGotDocumentsToErase(
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- google::firestore::v1beta1::ListDocumentsResponse documents_response,
- EraseCallback callback);
-
- // ListenCallClient:
- void OnConnected() override;
-
- void OnResponse(google::firestore::v1beta1::ListenResponse response) override;
-
- void OnFinished(grpc::Status status) override;
-
- const std::string user_path_;
- CredentialsProvider* const credentials_provider_;
- FirestoreService* const firestore_service_;
-
- fidl::Binding<cloud_provider::DeviceSet> binding_;
- fit::closure on_empty_;
-
- // Watcher set by the client.
- cloud_provider::DeviceSetWatcherPtr watcher_;
- std::string watched_fingerprint_;
- SetWatcherCallback set_watcher_callback_;
- std::unique_ptr<ListenCallHandler> listen_call_handler_;
-
- // Must be the last member.
- fxl::WeakPtrFactory<DeviceSetImpl> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DeviceSetImpl);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_DEVICE_SET_IMPL_H_
diff --git a/bin/cloud_provider_firestore/app/device_set_impl_unittest.cc b/bin/cloud_provider_firestore/app/device_set_impl_unittest.cc
deleted file mode 100644
index 67289d4..0000000
--- a/bin/cloud_provider_firestore/app/device_set_impl_unittest.cc
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/device_set_impl.h"
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/testing/test_credentials_provider.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_provider_firestore {
-namespace {
-
-class DeviceSetImplTest : public gtest::TestLoopFixture,
- public cloud_provider::DeviceSetWatcher {
- public:
- DeviceSetImplTest()
- : test_credentials_provider_(dispatcher()),
- device_set_impl_("user_path", &test_credentials_provider_,
- &firestore_service_, device_set_.NewRequest()),
- watcher_binding_(this) {}
-
- // cloud_provider::DeviceSetWatcher:
- void OnCloudErased() override { on_cloud_erased_calls_++; }
-
- void OnNetworkError() override { on_network_error_calls_++; }
-
- protected:
- cloud_provider::DeviceSetPtr device_set_;
- TestCredentialsProvider test_credentials_provider_;
- TestFirestoreService firestore_service_;
- DeviceSetImpl device_set_impl_;
-
- fidl::Binding<cloud_provider::DeviceSetWatcher> watcher_binding_;
- int on_cloud_erased_calls_ = 0;
- int on_network_error_calls_ = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(DeviceSetImplTest);
-};
-
-TEST_F(DeviceSetImplTest, EmptyWhenDisconnected) {
- bool on_empty_called = false;
- device_set_impl_.set_on_empty(callback::SetWhenCalled(&on_empty_called));
- device_set_.Unbind();
- RunLoopUntilIdle();
- EXPECT_TRUE(on_empty_called);
-}
-
-TEST_F(DeviceSetImplTest, CheckFingerprintOk) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- device_set_->CheckFingerprint(
- convert::ToArray("abc"),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.get_document_records.size());
-
- firestore_service_.get_document_records.front().callback(
- grpc::Status(), google::firestore::v1beta1::Document());
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-}
-
-TEST_F(DeviceSetImplTest, CheckFingerprintNotFound) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- device_set_->CheckFingerprint(
- convert::ToArray("abc"),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.get_document_records.size());
-
- firestore_service_.get_document_records.front().callback(
- grpc::Status(grpc::NOT_FOUND, ""),
- google::firestore::v1beta1::Document());
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::NOT_FOUND, status);
-}
-
-TEST_F(DeviceSetImplTest, SetFingerprint) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- device_set_->SetFingerprint(
- convert::ToArray("abc"),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.create_document_records.size());
-
- firestore_service_.create_document_records.front().callback(
- grpc::Status(), google::firestore::v1beta1::Document());
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-}
-
-TEST_F(DeviceSetImplTest, SetWatcherResultOk) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- cloud_provider::DeviceSetWatcherPtr watcher;
- watcher_binding_.Bind(watcher.NewRequest());
- device_set_->SetWatcher(
- convert::ToArray("abc"), std::move(watcher),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_EQ(1u, firestore_service_.listen_clients.size());
- EXPECT_FALSE(callback_called);
-
- auto response = google::firestore::v1beta1::ListenResponse();
- response.mutable_target_change()->set_target_change_type(
- google::firestore::v1beta1::TargetChange_TargetChangeType_CURRENT);
- firestore_service_.listen_clients[0]->OnResponse(std::move(response));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
- EXPECT_EQ(0, on_cloud_erased_calls_);
-}
-
-TEST_F(DeviceSetImplTest, SetWatcherResultCloudErased) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- cloud_provider::DeviceSetWatcherPtr watcher;
- watcher_binding_.Bind(watcher.NewRequest());
- device_set_->SetWatcher(
- convert::ToArray("abc"), std::move(watcher),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_EQ(1u, firestore_service_.listen_clients.size());
- EXPECT_FALSE(callback_called);
-
- auto response = google::firestore::v1beta1::ListenResponse();
- response.mutable_document_delete();
- firestore_service_.listen_clients[0]->OnResponse(std::move(response));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::NOT_FOUND, status);
- EXPECT_EQ(1, on_cloud_erased_calls_);
-}
-
-TEST_F(DeviceSetImplTest, Erase) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- device_set_->Erase(
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.list_documents_records.size());
-
- auto response = google::firestore::v1beta1::ListDocumentsResponse();
- response.add_documents()->set_name("some/document/name");
- response.add_documents()->set_name("some/other/name");
- firestore_service_.list_documents_records[0].callback(grpc::Status::OK,
- std::move(response));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(2u, firestore_service_.delete_document_records.size());
- EXPECT_EQ("some/document/name",
- firestore_service_.delete_document_records[0].request.name());
- EXPECT_EQ("some/other/name",
- firestore_service_.delete_document_records[1].request.name());
-
- firestore_service_.delete_document_records[0].callback(grpc::Status::OK);
- firestore_service_.delete_document_records[1].callback(grpc::Status::OK);
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-}
-
-// Paginated response from the device map list is not currently handled - we
-// give up and return INTERNAL_ERROR. When we add support for pagination, this
-// test should be edited to verify the correct behavior.
-TEST_F(DeviceSetImplTest, EraseWithPaginatedDeviceListResponse) {
- bool callback_called = false;
- auto status = cloud_provider::Status::OK;
- device_set_->Erase(
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.list_documents_records.size());
-
- auto response = google::firestore::v1beta1::ListDocumentsResponse();
- response.add_documents()->set_name("some/document/name");
- response.add_documents()->set_name("some/other/name");
- response.set_next_page_token("token");
- firestore_service_.list_documents_records[0].callback(grpc::Status::OK,
- std::move(response));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::INTERNAL_ERROR, status);
-}
-
-} // namespace
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/factory_impl.cc b/bin/cloud_provider_firestore/app/factory_impl.cc
deleted file mode 100644
index 46fb4e4..0000000
--- a/bin/cloud_provider_firestore/app/factory_impl.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/factory_impl.h"
-
-#include <grpc++/grpc++.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/cloud_provider_firestore/firestore/firestore_service_impl.h"
-
-namespace cloud_provider_firestore {
-
-namespace {
-std::shared_ptr<grpc::Channel> MakeChannel() {
- auto opts = grpc::SslCredentialsOptions();
- auto credentials = grpc::SslCredentials(opts);
- return grpc::CreateChannel("firestore.googleapis.com:443", credentials);
-}
-
-firebase_auth::FirebaseAuthImpl::Config GetFirebaseAuthConfig(
- const std::string& api_key, const std::string& cobalt_client_name) {
- firebase_auth::FirebaseAuthImpl::Config config;
- config.api_key = api_key;
- config.cobalt_client_name = cobalt_client_name;
-
- return config;
-}
-
-} // namespace
-
-FactoryImpl::FactoryImpl(async_dispatcher_t* dispatcher, rng::Random* random,
- component::StartupContext* startup_context,
- std::string cobalt_client_name)
- : dispatcher_(dispatcher),
- random_(random),
- startup_context_(startup_context),
- cobalt_client_name_(std::move(cobalt_client_name)) {}
-
-FactoryImpl::~FactoryImpl() {}
-
-void FactoryImpl::ShutDown(fit::closure callback) {
- if (providers_.empty()) {
- callback();
- return;
- }
-
- providers_.set_on_empty(std::move(callback));
- for (auto& cloud_provider : providers_) {
- cloud_provider.ShutDownAndReportEmpty();
- }
-}
-
-void FactoryImpl::GetCloudProvider(
- Config config,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> token_manager,
- fidl::InterfaceRequest<cloud_provider::CloudProvider>
- cloud_provider_request,
- GetCloudProviderCallback callback) {
- auto firebase_auth = std::make_unique<firebase_auth::FirebaseAuthImpl>(
- GetFirebaseAuthConfig(config.api_key, cobalt_client_name_), dispatcher_,
- random_, token_manager.Bind(), startup_context_);
-
- GetFirebaseCloudProvider(std::move(config), std::move(firebase_auth),
- std::move(cloud_provider_request),
- std::move(callback));
-}
-
-void FactoryImpl::GetFirebaseCloudProvider(
- Config config,
- std::unique_ptr<firebase_auth::FirebaseAuthImpl> firebase_auth,
- fidl::InterfaceRequest<cloud_provider::CloudProvider>
- cloud_provider_request,
- fit::function<void(cloud_provider::Status)> callback) {
- FXL_DCHECK(firebase_auth);
-
- auto token_request =
- firebase_auth->GetFirebaseUserId(fxl::MakeCopyable(
- [this, config = std::move(config),
- firebase_auth = std::move(firebase_auth),
- cloud_provider_request = std::move(cloud_provider_request),
- callback = std::move(callback)](firebase_auth::AuthStatus status,
- std::string user_id) mutable {
- if (status != firebase_auth::AuthStatus::OK) {
- FXL_LOG(ERROR)
- << "Failed to retrieve the user ID from auth token provider";
- callback(cloud_provider::Status::AUTH_ERROR);
- return;
- }
-
- auto firestore_service = std::make_unique<FirestoreServiceImpl>(
- config.server_id, dispatcher_, MakeChannel());
-
- providers_.emplace(random_, user_id, std::move(firebase_auth),
- std::move(firestore_service),
- std::move(cloud_provider_request));
- callback(cloud_provider::Status::OK);
- }));
- token_requests_.emplace(token_request);
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/factory_impl.h b/bin/cloud_provider_firestore/app/factory_impl.h
deleted file mode 100644
index df8ffb4..0000000
--- a/bin/cloud_provider_firestore/app/factory_impl.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_FACTORY_IMPL_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_FACTORY_IMPL_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/ledger/cloud/firestore/cpp/fidl.h>
-#include <lib/async/dispatcher.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/callback/cancellable.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/cloud_provider_impl.h"
-#include "peridot/lib/rng/random.h"
-
-namespace cloud_provider_firestore {
-
-class FactoryImpl : public Factory {
- public:
- explicit FactoryImpl(async_dispatcher_t* dispatcher, rng::Random* random,
- component::StartupContext* startup_context,
- std::string cobalt_client_name);
-
- ~FactoryImpl() override;
-
- // Shuts down all cloud providers owned by the class.
- //
- // It is only valid to delete the factory after the completion callback is
- // called.
- void ShutDown(fit::closure callback);
-
- private:
- // Factory:
- void GetCloudProvider(
- Config config,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> token_manager,
- fidl::InterfaceRequest<cloud_provider::CloudProvider>
- cloud_provider_request,
- GetCloudProviderCallback callback) override;
-
- void GetFirebaseCloudProvider(
- Config config,
- std::unique_ptr<firebase_auth::FirebaseAuthImpl> firebase_auth,
- fidl::InterfaceRequest<cloud_provider::CloudProvider>
- cloud_provider_request,
- fit::function<void(cloud_provider::Status)> callback);
-
- async_dispatcher_t* const dispatcher_;
- rng::Random* random_;
- component::StartupContext* const startup_context_;
- const std::string cobalt_client_name_;
- callback::CancellableContainer token_requests_;
- callback::AutoCleanableSet<CloudProviderImpl> providers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FactoryImpl);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_FACTORY_IMPL_H_
diff --git a/bin/cloud_provider_firestore/app/factory_impl_unittest.cc b/bin/cloud_provider_firestore/app/factory_impl_unittest.cc
deleted file mode 100644
index 42c88a8..0000000
--- a/bin/cloud_provider_firestore/app/factory_impl_unittest.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/factory_impl.h"
-
-#include <fuchsia/ledger/cloud/firestore/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/lib/firebase_auth/testing/test_token_manager.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace cloud_provider_firestore {
-
-class FactoryImplTest : public gtest::TestLoopFixture {
- public:
- FactoryImplTest()
- : random_(test_loop().initial_state()),
- factory_impl_(dispatcher(), &random_, /*startup_context=*/nullptr,
- /*cobalt_client_name=*/""),
- factory_binding_(&factory_impl_, factory_.NewRequest()),
- token_manager_(dispatcher()),
- token_manager_binding_(&token_manager_) {}
- ~FactoryImplTest() override {}
-
- protected:
- rng::TestRandom random_;
- FactoryImpl factory_impl_;
- FactoryPtr factory_;
- fidl::Binding<Factory> factory_binding_;
-
- firebase_auth::TestTokenManager token_manager_;
- fidl::Binding<fuchsia::auth::TokenManager> token_manager_binding_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(FactoryImplTest);
-};
-
-TEST_F(FactoryImplTest, GetCloudProvider) {
- bool callback_called = false;
- token_manager_.Set("this is a token", "some id", "me@example.com");
-
- cloud_provider::Status status = cloud_provider::Status::INTERNAL_ERROR;
- cloud_provider::CloudProviderPtr cloud_provider;
- Config config;
- config.server_id = "some server id";
- config.api_key = "some api key";
- factory_->GetCloudProvider(
- std::move(config), token_manager_binding_.NewBinding(),
- cloud_provider.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-
- callback_called = false;
- factory_impl_.ShutDown(callback::SetWhenCalled(&callback_called));
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/grpc_status.cc b/bin/cloud_provider_firestore/app/grpc_status.cc
deleted file mode 100644
index ac54e5f..0000000
--- a/bin/cloud_provider_firestore/app/grpc_status.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/grpc_status.h"
-
-#include <lib/fxl/logging.h>
-
-namespace cloud_provider_firestore {
-
-cloud_provider::Status ConvertGrpcStatus(grpc::StatusCode status) {
- switch (status) {
- case grpc::OK:
- return cloud_provider::Status::OK;
- case grpc::UNAUTHENTICATED:
- return cloud_provider::Status::AUTH_ERROR;
- case grpc::NOT_FOUND:
- return cloud_provider::Status::NOT_FOUND;
- case grpc::UNAVAILABLE:
- return cloud_provider::Status::NETWORK_ERROR;
- default:
- return cloud_provider::Status::SERVER_ERROR;
- }
-}
-
-bool LogGrpcRequestError(const grpc::Status& status) {
- if (!status.ok()) {
- FXL_LOG(ERROR) << "Server request failed, "
- << "error message: " << status.error_message()
- << ", error details: " << status.error_details()
- << ", error code: " << status.error_code();
- return true;
- }
-
- return false;
-}
-
-bool LogGrpcConnectionError(const grpc::Status& status) {
- if (!status.ok()) {
- FXL_LOG(ERROR) << "Server unexpectedly closed the connection "
- << "with status: " << status.error_message()
- << ", error details: " << status.error_details()
- << ", error code: " << status.error_code();
- return true;
- return true;
- }
-
- return false;
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/grpc_status.h b/bin/cloud_provider_firestore/app/grpc_status.h
deleted file mode 100644
index 6e78ab6..0000000
--- a/bin/cloud_provider_firestore/app/grpc_status.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_GRPC_STATUS_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_GRPC_STATUS_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <grpc++/grpc++.h>
-
-#include "peridot/bin/cloud_provider_firestore/include/types.h"
-
-namespace cloud_provider_firestore {
-
-cloud_provider::Status ConvertGrpcStatus(grpc::StatusCode status);
-
-// If |status| is not OK, logs an error and returns true. Otherwise, returns
-// false.
-bool LogGrpcRequestError(const grpc::Status& status);
-
-// If |status| is not OK, logs an error and returns true. Otherwise, returns
-// false.
-bool LogGrpcConnectionError(const grpc::Status& status);
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_GRPC_STATUS_H_
diff --git a/bin/cloud_provider_firestore/app/meta/cloud_provider_firestore.cmx b/bin/cloud_provider_firestore/app/meta/cloud_provider_firestore.cmx
deleted file mode 100644
index c4027f6..0000000
--- a/bin/cloud_provider_firestore/app/meta/cloud_provider_firestore.cmx
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [
- "root-ssl-certificates"
- ],
- "services": [
- "fuchsia.tracelink.Registry",
- "fuchsia.net.LegacySocketProvider",
- "fuchsia.net.SocketProvider",
- "fuchsia.cobalt.LoggerFactory"
- ]
- }
-}
diff --git a/bin/cloud_provider_firestore/app/page_cloud_impl.cc b/bin/cloud_provider_firestore/app/page_cloud_impl.cc
deleted file mode 100644
index 4265eef..0000000
--- a/bin/cloud_provider_firestore/app/page_cloud_impl.cc
+++ /dev/null
@@ -1,423 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/page_cloud_impl.h"
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/grpc_status.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/encoding.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_provider_firestore {
-namespace {
-
-constexpr char kSeparator[] = "/";
-constexpr char kObjectCollection[] = "objects";
-constexpr char kCommitLogCollection[] = "commit-log";
-constexpr char kDataKey[] = "data";
-constexpr char kTimestampField[] = "timestamp";
-constexpr size_t kFirestoreMaxDocumentSize = 1'000'000;
-// Ledger stores objects chunked to ~64k, so even 500kB is more than should ever
-// be needed.
-constexpr size_t kMaxObjectSize = kFirestoreMaxDocumentSize / 2;
-
-std::string GetObjectPath(fxl::StringView page_path,
- fxl::StringView object_id) {
- std::string encoded_object_id = EncodeKey(object_id);
- return fxl::Concatenate({page_path, kSeparator, kObjectCollection, kSeparator,
- encoded_object_id});
-}
-
-std::string GetCommitBatchPath(fxl::StringView page_path,
- fxl::StringView batch_id) {
- std::string encoded_batch_id = EncodeKey(batch_id);
- return fxl::Concatenate({page_path, kSeparator, kCommitLogCollection,
- kSeparator, encoded_batch_id});
-}
-
-google::firestore::v1beta1::StructuredQuery MakeCommitQuery(
- std::unique_ptr<google::protobuf::Timestamp> timestamp_or_null) {
- google::firestore::v1beta1::StructuredQuery query;
-
- // Sub-collections to be queried.
- google::firestore::v1beta1::StructuredQuery::CollectionSelector& selector =
- *query.add_from();
- selector.set_collection_id(kCommitLogCollection);
- selector.set_all_descendants(false);
-
- // Ordering.
- google::firestore::v1beta1::StructuredQuery::Order& order_by =
- *query.add_order_by();
- order_by.mutable_field()->set_field_path(kTimestampField);
-
- // Filtering.
- if (timestamp_or_null) {
- google::firestore::v1beta1::StructuredQuery::Filter& filter =
- *query.mutable_where();
- google::firestore::v1beta1::StructuredQuery::FieldFilter& field_filter =
- *filter.mutable_field_filter();
-
- field_filter.mutable_field()->set_field_path(kTimestampField);
- field_filter.set_op(
- google::firestore::v1beta1::
- StructuredQuery_FieldFilter_Operator_GREATER_THAN_OR_EQUAL);
- field_filter.mutable_value()->mutable_timestamp_value()->Swap(
- timestamp_or_null.get());
- }
- return query;
-}
-
-} // namespace
-
-PageCloudImpl::PageCloudImpl(
- std::string page_path, rng::Random* random,
- CredentialsProvider* credentials_provider,
- FirestoreService* firestore_service,
- fidl::InterfaceRequest<cloud_provider::PageCloud> request)
- : page_path_(std::move(page_path)),
- random_(random),
- credentials_provider_(credentials_provider),
- firestore_service_(firestore_service),
- binding_(this, std::move(request)),
- weak_ptr_factory_(this) {
- // The class shuts down when the client connection is disconnected.
- binding_.set_error_handler([this](zx_status_t status) {
- if (on_empty_) {
- on_empty_();
- }
- });
-}
-
-PageCloudImpl::~PageCloudImpl() {}
-
-void PageCloudImpl::ScopedGetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback) {
- credentials_provider_->GetCredentials(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void PageCloudImpl::AddCommits(cloud_provider::CommitPack commits,
- AddCommitsCallback callback) {
- std::vector<cloud_provider::CommitPackEntry> commit_pack_entries;
- if (!cloud_provider::DecodeCommitPack(commits, &commit_pack_entries)) {
- callback(cloud_provider::Status::ARGUMENT_ERROR);
- return;
- }
-
- auto request = google::firestore::v1beta1::CommitRequest();
- request.set_database(firestore_service_->GetDatabasePath());
-
- // Set the document name to a new UUID. Firestore Commit() API doesn't allow
- // to request the ID to be assigned by the server.
- const std::string document_name = GetCommitBatchPath(
- page_path_, convert::ToHex(random_->RandomUniqueBytes()));
-
- // The commit batch is added in a single commit containing multiple writes.
- //
- // First write adds the document containing the encoded commit batch.
- google::firestore::v1beta1::Write& add_batch_write = *(request.add_writes());
- EncodeCommitBatch(commits, add_batch_write.mutable_update());
- (*add_batch_write.mutable_update()->mutable_name()) = document_name;
- // Ensure that the write doesn't overwrite an existing document.
- add_batch_write.mutable_current_document()->set_exists(false);
-
- // The second write sets the timestamp field to the server-side request
- // timestamp.
- google::firestore::v1beta1::Write& set_timestamp_write =
- *(request.add_writes());
- (*set_timestamp_write.mutable_transform()->mutable_document()) =
- document_name;
-
- google::firestore::v1beta1::DocumentTransform_FieldTransform& transform =
- *(set_timestamp_write.mutable_transform()->add_field_transforms());
- *(transform.mutable_field_path()) = kTimestampField;
- transform.set_set_to_server_value(
- google::firestore::v1beta1::
- DocumentTransform_FieldTransform_ServerValue_REQUEST_TIME);
-
- ScopedGetCredentials(
- [this, request = std::move(request),
- callback = std::move(callback)](auto call_credentials) mutable {
- firestore_service_->Commit(
- std::move(request), std::move(call_credentials),
- [callback = std::move(callback)](auto status, auto result) {
- if (LogGrpcRequestError(status)) {
- callback(ConvertGrpcStatus(status.error_code()));
- return;
- }
- callback(cloud_provider::Status::OK);
- });
- });
-}
-
-void PageCloudImpl::GetCommits(
- std::unique_ptr<cloud_provider::Token> min_position_token,
- GetCommitsCallback callback) {
- std::unique_ptr<google::protobuf::Timestamp> timestamp_or_null;
- if (min_position_token) {
- timestamp_or_null = std::make_unique<google::protobuf::Timestamp>();
- if (!timestamp_or_null->ParseFromString(
- convert::ToString(min_position_token->opaque_id))) {
- callback(cloud_provider::Status::ARGUMENT_ERROR, nullptr, nullptr);
- return;
- }
- }
-
- auto request = google::firestore::v1beta1::RunQueryRequest();
- request.set_parent(page_path_);
- auto query = MakeCommitQuery(std::move(timestamp_or_null));
- request.mutable_structured_query()->Swap(&query);
-
- ScopedGetCredentials([this, request = std::move(request),
- callback = std::move(callback)](
- auto call_credentials) mutable {
- firestore_service_->RunQuery(
- std::move(request), std::move(call_credentials),
- [callback = std::move(callback)](auto status, auto result) {
- if (LogGrpcRequestError(status)) {
- callback(ConvertGrpcStatus(status.error_code()), nullptr, nullptr);
- return;
- }
-
- std::vector<cloud_provider::CommitPackEntry> commit_entries;
- std::string timestamp;
-
- for (const auto& response : result) {
- if (!response.has_document()) {
- continue;
- }
-
- std::vector<cloud_provider::CommitPackEntry> batch_entries;
- if (!DecodeCommitBatch(response.document(), &batch_entries,
- ×tamp)) {
- callback(cloud_provider::Status::PARSE_ERROR, nullptr, nullptr);
- return;
- }
-
- std::move(batch_entries.begin(), batch_entries.end(),
- std::back_inserter(commit_entries));
- }
-
- cloud_provider::CommitPack commit_pack;
- if (!cloud_provider::EncodeCommitPack(commit_entries, &commit_pack)) {
- callback(cloud_provider::Status::INTERNAL_ERROR, nullptr, nullptr);
- return;
- }
-
- std::unique_ptr<cloud_provider::Token> token;
- if (!commit_entries.empty()) {
- token = std::make_unique<cloud_provider::Token>();
- token->opaque_id = convert::ToArray(timestamp);
- }
- callback(cloud_provider::Status::OK,
- fidl::MakeOptional(std::move(commit_pack)),
- std::move(token));
- });
- });
-}
-
-void PageCloudImpl::AddObject(std::vector<uint8_t> id,
- fuchsia::mem::Buffer data,
- AddObjectCallback callback) {
- std::string data_str;
- fsl::SizedVmo vmo;
- if (!fsl::StringFromVmo(data, &data_str) ||
- data_str.size() > kMaxObjectSize) {
- callback(cloud_provider::Status::ARGUMENT_ERROR);
- return;
- }
-
- auto request = google::firestore::v1beta1::CreateDocumentRequest();
- request.set_parent(page_path_);
- request.set_collection_id(kObjectCollection);
- google::firestore::v1beta1::Document* document = request.mutable_document();
- request.set_document_id(EncodeKey(convert::ToString(id)));
- *((*document->mutable_fields())[kDataKey].mutable_bytes_value()) =
- std::move(data_str);
-
- ScopedGetCredentials(
- [this, request = std::move(request),
- callback = std::move(callback)](auto call_credentials) mutable {
- firestore_service_->CreateDocument(
- std::move(request), std::move(call_credentials),
- [callback = std::move(callback)](auto status, auto result) {
- if (status.error_code() == grpc::ALREADY_EXISTS) {
- callback(cloud_provider::Status::OK);
- return;
- }
- if (LogGrpcRequestError(status)) {
- callback(ConvertGrpcStatus(status.error_code()));
- return;
- }
- callback(cloud_provider::Status::OK);
- });
- });
-}
-
-void PageCloudImpl::GetObject(std::vector<uint8_t> id,
- GetObjectCallback callback) {
- auto request = google::firestore::v1beta1::GetDocumentRequest();
- request.set_name(GetObjectPath(page_path_, convert::ToString(id)));
-
- ScopedGetCredentials(
- [this, request = std::move(request),
- callback = std::move(callback)](auto call_credentials) mutable {
- firestore_service_->GetDocument(
- std::move(request), std::move(call_credentials),
- [callback = std::move(callback)](auto status, auto result) {
- if (LogGrpcRequestError(status)) {
- callback(ConvertGrpcStatus(status.error_code()), nullptr);
- return;
- }
-
- if (result.fields().count(kDataKey) != 1) {
- FXL_LOG(ERROR)
- << "Incorrect format of the retrieved object document";
- callback(cloud_provider::Status::PARSE_ERROR, nullptr);
- return;
- }
-
- const std::string& bytes =
- result.fields().at(kDataKey).bytes_value();
- ::fuchsia::mem::Buffer buffer;
- if (!fsl::VmoFromString(bytes, &buffer)) {
- callback(cloud_provider::Status::INTERNAL_ERROR, nullptr);
- return;
- }
- callback(cloud_provider::Status::OK,
- fidl::MakeOptional(std::move(buffer)));
- });
- });
-}
-
-void PageCloudImpl::SetWatcher(
- std::unique_ptr<cloud_provider::Token> min_position_token,
- fidl::InterfaceHandle<cloud_provider::PageCloudWatcher> watcher,
- SetWatcherCallback callback) {
- std::unique_ptr<google::protobuf::Timestamp> timestamp_or_null;
- if (min_position_token) {
- timestamp_or_null = std::make_unique<google::protobuf::Timestamp>();
- if (!timestamp_or_null->ParseFromString(
- convert::ToString(min_position_token->opaque_id))) {
- callback(cloud_provider::Status::ARGUMENT_ERROR);
- return;
- }
- }
-
- watcher_ = watcher.Bind();
- watcher_.set_error_handler([this](zx_status_t status) { ShutDownWatcher(); });
- watcher_timestamp_or_null_ = std::move(timestamp_or_null);
- set_watcher_callback_ = std::move(callback);
-
- ScopedGetCredentials([this](auto call_credentials) mutable {
- // Initiate the listen RPC. We will receive a call on OnConnected() when the
- // listen stream is ready.
- listen_call_handler_ =
- firestore_service_->Listen(std::move(call_credentials), this);
- });
-}
-
-void PageCloudImpl::OnConnected() {
- auto request = google::firestore::v1beta1::ListenRequest();
- request.set_database(firestore_service_->GetDatabasePath());
- google::firestore::v1beta1::Target::QueryTarget& query_target =
- *request.mutable_add_target()->mutable_query();
- query_target.set_parent(page_path_);
- auto query = MakeCommitQuery(std::move(watcher_timestamp_or_null_));
- query_target.mutable_structured_query()->Swap(&query);
- listen_call_handler_->Write(std::move(request));
-}
-
-void PageCloudImpl::OnResponse(
- google::firestore::v1beta1::ListenResponse response) {
- if (response.has_target_change()) {
- if (response.target_change().target_change_type() ==
- google::firestore::v1beta1::TargetChange_TargetChangeType_CURRENT) {
- if (set_watcher_callback_) {
- set_watcher_callback_(cloud_provider::Status::OK);
- set_watcher_callback_ = nullptr;
- }
- }
- return;
- }
-
- if (response.has_document_change()) {
- std::string timestamp;
-
- std::vector<cloud_provider::CommitPackEntry> commit_entries;
- if (!DecodeCommitBatch(response.document_change().document(),
- &commit_entries, ×tamp)) {
- watcher_->OnError(cloud_provider::Status::PARSE_ERROR);
- ShutDownWatcher();
- }
-
- cloud_provider::Token token;
- token.opaque_id = convert::ToArray(timestamp);
- HandleCommits(std::move(commit_entries), std::move(token));
- }
-}
-
-void PageCloudImpl::OnFinished(grpc::Status status) {
- if (status.error_code() == grpc::UNAVAILABLE ||
- status.error_code() == grpc::UNAUTHENTICATED) {
- if (watcher_) {
- watcher_->OnError(cloud_provider::Status::NETWORK_ERROR);
- }
- return;
- }
- LogGrpcConnectionError(status);
- watcher_.Unbind();
-}
-
-void PageCloudImpl::HandleCommits(
- std::vector<cloud_provider::CommitPackEntry> commit_entries,
- cloud_provider::Token token) {
- std::move(commit_entries.begin(), commit_entries.end(),
- std::back_inserter(commits_waiting_for_ack_));
- token_for_waiting_commits_ = std::move(token);
-
- if (!waiting_for_watcher_to_ack_commits_) {
- SendWaitingCommits();
- }
-}
-
-void PageCloudImpl::SendWaitingCommits() {
- FXL_DCHECK(watcher_);
- FXL_DCHECK(!commits_waiting_for_ack_.empty());
- cloud_provider::Token token = std::move(token_for_waiting_commits_);
- cloud_provider::CommitPack commit_pack;
- if (!cloud_provider::EncodeCommitPack(commits_waiting_for_ack_,
- &commit_pack)) {
- watcher_->OnError(cloud_provider::Status::INTERNAL_ERROR);
- ShutDownWatcher();
- return;
- }
- watcher_->OnNewCommits(std::move(commit_pack), std::move(token), [this] {
- waiting_for_watcher_to_ack_commits_ = false;
- if (!commits_waiting_for_ack_.empty()) {
- SendWaitingCommits();
- }
- });
- waiting_for_watcher_to_ack_commits_ = true;
- commits_waiting_for_ack_.clear();
-}
-
-void PageCloudImpl::ShutDownWatcher() {
- if (watcher_) {
- watcher_.Unbind();
- }
- if (listen_call_handler_) {
- listen_call_handler_.reset();
- }
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/page_cloud_impl.h b/bin/cloud_provider_firestore/app/page_cloud_impl.h
deleted file mode 100644
index 4eb5ad1..0000000
--- a/bin/cloud_provider_firestore/app/page_cloud_impl.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_PAGE_CLOUD_IMPL_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_PAGE_CLOUD_IMPL_H_
-
-#include <memory>
-#include <utility>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/vector.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/credentials_provider.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/firestore_service.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/listen_call_client.h"
-#include "peridot/bin/cloud_provider_firestore/include/types.h"
-#include "peridot/lib/commit_pack/commit_pack.h"
-#include "peridot/lib/rng/random.h"
-
-namespace cloud_provider_firestore {
-
-class PageCloudImpl : public cloud_provider::PageCloud,
- public ListenCallClient {
- public:
- explicit PageCloudImpl(
- std::string page_path, rng::Random* random,
- CredentialsProvider* credentials_provider,
- FirestoreService* firestore_service,
- fidl::InterfaceRequest<cloud_provider::PageCloud> request);
- ~PageCloudImpl() override;
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
-
- private:
- void ScopedGetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback);
-
- // cloud_provider::PageCloud:
- void AddCommits(cloud_provider::CommitPack commits,
- AddCommitsCallback callback) override;
- void GetCommits(std::unique_ptr<cloud_provider::Token> min_position_token,
- GetCommitsCallback callback) override;
- void AddObject(std::vector<uint8_t> id, fuchsia::mem::Buffer data,
- AddObjectCallback callback) override;
- void GetObject(std::vector<uint8_t> id,
- GetObjectCallback callback) override;
- void SetWatcher(
- std::unique_ptr<cloud_provider::Token> min_position_token,
- fidl::InterfaceHandle<cloud_provider::PageCloudWatcher> watcher,
- SetWatcherCallback callback) override;
-
- // ListenCallClient:
- void OnConnected() override;
-
- void OnResponse(google::firestore::v1beta1::ListenResponse response) override;
-
- void OnFinished(grpc::Status status) override;
-
- // Handles new commits delivered from the cloud watcher.
- //
- // This will either send over the commits immediately or queue them if we're
- // waiting the the watcher to ack the previous call.
- void HandleCommits(
- std::vector<cloud_provider::CommitPackEntry> commit_entries,
- cloud_provider::Token token);
-
- void SendWaitingCommits();
-
- // Brings down the cloud watcher.
- //
- // This can be called either because of an error, or because the client is
- // gone.
- void ShutDownWatcher();
-
- const std::string page_path_;
- rng::Random* const random_;
- CredentialsProvider* const credentials_provider_;
- FirestoreService* const firestore_service_;
-
- fidl::Binding<cloud_provider::PageCloud> binding_;
- fit::closure on_empty_;
-
- // Watcher set by the client.
- cloud_provider::PageCloudWatcherPtr watcher_;
- std::unique_ptr<google::protobuf::Timestamp> watcher_timestamp_or_null_;
- SetWatcherCallback set_watcher_callback_;
- std::unique_ptr<ListenCallHandler> listen_call_handler_;
-
- // We will only call OnNewCommits() on the watcher when the callback of the
- // previous OnNewCommits() call is already called. Any commits delivered
- // between an OnNewCommits() call and its callback executing are queued in
- // |commits_waiting_for_ack_|.
- bool waiting_for_watcher_to_ack_commits_ = false;
- std::vector<cloud_provider::CommitPackEntry> commits_waiting_for_ack_;
- cloud_provider::Token token_for_waiting_commits_;
-
- // Must be the last member.
- fxl::WeakPtrFactory<PageCloudImpl> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageCloudImpl);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_PAGE_CLOUD_IMPL_H_
diff --git a/bin/cloud_provider_firestore/app/page_cloud_impl_unittest.cc b/bin/cloud_provider_firestore/app/page_cloud_impl_unittest.cc
deleted file mode 100644
index f22eae4..0000000
--- a/bin/cloud_provider_firestore/app/page_cloud_impl_unittest.cc
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/page_cloud_impl.h"
-
-#include <iterator>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <google/protobuf/util/time_util.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/vector.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/testing/test_credentials_provider.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/encoding.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/testing/encoding.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.h"
-#include "peridot/lib/commit_pack/commit_pack.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace cloud_provider_firestore {
-namespace {
-
-void SetTimestamp(google::firestore::v1beta1::Document* document,
- int64_t seconds, int32_t nanos) {
- google::protobuf::Timestamp& timestamp =
- *((*document->mutable_fields())["timestamp"].mutable_timestamp_value());
- timestamp.set_seconds(seconds);
- timestamp.set_nanos(nanos);
-}
-
-class TestPageCloudWatcher : public cloud_provider::PageCloudWatcher {
- public:
- TestPageCloudWatcher() {}
- ~TestPageCloudWatcher() override {}
-
- std::vector<cloud_provider::CommitPackEntry> received_commits;
- std::vector<cloud_provider::Token> received_tokens;
- OnNewCommitsCallback pending_on_new_commit_callback = nullptr;
-
- private:
- // cloud_provider::PageCloudWatcher:
- void OnNewCommits(cloud_provider::CommitPack commit_pack,
- cloud_provider::Token position_token,
- OnNewCommitsCallback callback) override {
- std::vector<cloud_provider::CommitPackEntry> entries;
- EXPECT_TRUE(cloud_provider::DecodeCommitPack(commit_pack, &entries));
- std::move(entries.begin(), entries.end(),
- std::back_inserter(received_commits));
- received_tokens.push_back(std::move(position_token));
-
- EXPECT_FALSE(pending_on_new_commit_callback);
- pending_on_new_commit_callback = std::move(callback);
- }
-
- void OnNewObject(std::vector<uint8_t> /*id*/,
- fuchsia::mem::Buffer /*buffer*/,
- OnNewObjectCallback /*callback*/) override {
- FXL_NOTIMPLEMENTED();
- }
-
- void OnError(cloud_provider::Status /*status*/) override {
- FXL_NOTIMPLEMENTED();
- }
-};
-
-class PageCloudImplTest : public gtest::TestLoopFixture {
- public:
- PageCloudImplTest()
- : random_(test_loop().initial_state()),
- test_credentials_provider_(dispatcher()),
- page_cloud_impl_("page_path", &random_, &test_credentials_provider_,
- &firestore_service_, page_cloud_.NewRequest()) {}
- ~PageCloudImplTest() override {}
-
- protected:
- rng::TestRandom random_;
- cloud_provider::PageCloudPtr page_cloud_;
- TestCredentialsProvider test_credentials_provider_;
- TestFirestoreService firestore_service_;
- PageCloudImpl page_cloud_impl_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageCloudImplTest);
-};
-
-TEST_F(PageCloudImplTest, EmptyWhenDisconnected) {
- bool on_empty_called = false;
- page_cloud_impl_.set_on_empty(callback::SetWhenCalled(&on_empty_called));
- page_cloud_.Unbind();
- RunLoopUntilIdle();
- EXPECT_TRUE(on_empty_called);
-}
-
-TEST_F(PageCloudImplTest, AddCommits) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- std::vector<cloud_provider::CommitPackEntry> entries{{"id0", "data0"}};
- cloud_provider::CommitPack commit_pack;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack(entries, &commit_pack));
- page_cloud_->AddCommits(
- std::move(commit_pack),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.commit_records.size());
- const google::firestore::v1beta1::CommitRequest& request =
- firestore_service_.commit_records.front().request;
- EXPECT_EQ(2, request.writes_size());
- EXPECT_TRUE(request.writes(0).has_update());
- EXPECT_TRUE(request.writes(1).has_transform());
- EXPECT_EQ(request.writes(0).update().name(),
- request.writes(1).transform().document());
-
- auto response = google::firestore::v1beta1::CommitResponse();
- firestore_service_.commit_records.front().callback(grpc::Status::OK,
- std::move(response));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-}
-
-TEST_F(PageCloudImplTest, GetCommits) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- std::unique_ptr<cloud_provider::CommitPack> commit_pack;
- std::unique_ptr<cloud_provider::Token> position_token;
- page_cloud_->GetCommits(
- nullptr, callback::Capture(callback::SetWhenCalled(&callback_called),
- &status, &commit_pack, &position_token));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.run_query_records.size());
-
- std::vector<google::firestore::v1beta1::RunQueryResponse> responses;
- {
- // First batch contains one commit.
- std::vector<cloud_provider::CommitPackEntry> entries{{"id0", "data0"}};
- cloud_provider::CommitPack commit_pack;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack(entries, &commit_pack));
- google::firestore::v1beta1::RunQueryResponse response;
- ASSERT_TRUE(EncodeCommitBatch(commit_pack, response.mutable_document()));
- SetTimestamp(response.mutable_document(), 100, 1);
- responses.push_back(std::move(response));
- }
- {
- // The second batch contains two commits.
- std::vector<cloud_provider::CommitPackEntry> entries{{"id1", "data1"},
- {"id2", "data2"}};
- cloud_provider::CommitPack commit_pack;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack(entries, &commit_pack));
- google::firestore::v1beta1::RunQueryResponse response;
- ASSERT_TRUE(EncodeCommitBatch(commit_pack, response.mutable_document()));
- SetTimestamp(response.mutable_document(), 100, 2);
- responses.push_back(std::move(response));
- }
-
- firestore_service_.run_query_records.front().callback(grpc::Status::OK,
- std::move(responses));
- RunLoopUntilIdle();
-
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
- ASSERT_TRUE(commit_pack);
- std::vector<cloud_provider::CommitPackEntry> entries;
- ASSERT_TRUE(cloud_provider::DecodeCommitPack(*commit_pack, &entries));
- // The result should be a flat vector of all three commits.
- EXPECT_EQ(3u, entries.size());
-
- EXPECT_TRUE(position_token);
- google::protobuf::Timestamp decoded_timestamp;
- ASSERT_TRUE(decoded_timestamp.ParseFromString(
- convert::ToString(position_token->opaque_id)));
- EXPECT_EQ(100, decoded_timestamp.seconds());
- EXPECT_EQ(2, decoded_timestamp.nanos());
-}
-
-TEST_F(PageCloudImplTest, GetCommitsQueryPositionToken) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- std::unique_ptr<cloud_provider::CommitPack> commit_pack;
- google::protobuf::Timestamp timestamp;
- timestamp.set_seconds(42);
- timestamp.set_nanos(1);
- std::string position_token_str;
- ASSERT_TRUE(timestamp.SerializeToString(&position_token_str));
- auto position_token = std::make_unique<cloud_provider::Token>();
- position_token->opaque_id = convert::ToArray(position_token_str);
- page_cloud_->GetCommits(
- std::move(position_token),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status,
- &commit_pack, &position_token));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.run_query_records.size());
-
- const google::firestore::v1beta1::RunQueryRequest& request =
- firestore_service_.run_query_records.front().request;
- EXPECT_TRUE(request.has_structured_query());
- EXPECT_TRUE(request.structured_query().has_where());
-
- const google::firestore::v1beta1::StructuredQuery::Filter& filter =
- request.structured_query().where();
- EXPECT_TRUE(filter.has_field_filter());
- EXPECT_EQ("timestamp", filter.field_filter().field().field_path());
- EXPECT_EQ(google::firestore::v1beta1::
- StructuredQuery_FieldFilter_Operator_GREATER_THAN_OR_EQUAL,
- filter.field_filter().op());
- EXPECT_EQ(42, filter.field_filter().value().timestamp_value().seconds());
- EXPECT_EQ(1, filter.field_filter().value().timestamp_value().nanos());
-}
-
-TEST_F(PageCloudImplTest, AddObject) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- fsl::SizedVmo data;
- ASSERT_TRUE(fsl::VmoFromString("some_data", &data));
- page_cloud_->AddObject(
- convert::ToArray("some_id"), std::move(data).ToTransport(),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.create_document_records.size());
-
- firestore_service_.create_document_records.front().callback(
- grpc::Status::OK, google::firestore::v1beta1::Document());
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-}
-
-TEST_F(PageCloudImplTest, GetObject) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- ::fuchsia::mem::BufferPtr data;
- page_cloud_->GetObject(
- convert::ToArray("some_id"),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status,
- &data));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.get_document_records.size());
-
- const std::string response_data = "some_data";
- google::firestore::v1beta1::Document response;
- *((*response.mutable_fields())["data"].mutable_bytes_value()) = response_data;
- firestore_service_.get_document_records.front().callback(grpc::Status(),
- response);
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-
- std::string read_data;
- ASSERT_TRUE(fsl::StringFromVmo(*data, &read_data));
- EXPECT_EQ("some_data", read_data);
-}
-
-TEST_F(PageCloudImplTest, GetObjectParseError) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- ::fuchsia::mem::BufferPtr data;
- page_cloud_->GetObject(
- convert::ToArray("some_id"),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status,
- &data));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1u, firestore_service_.get_document_records.size());
-
- // Create empty response with no data field.
- google::firestore::v1beta1::Document response;
- firestore_service_.get_document_records.front().callback(grpc::Status(),
- response);
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::PARSE_ERROR, status);
-}
-
-TEST_F(PageCloudImplTest, SetWatcherResultOk) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- TestPageCloudWatcher watcher_impl;
- cloud_provider::PageCloudWatcherPtr watcher;
- fidl::Binding<cloud_provider::PageCloudWatcher> watcher_binding(
- &watcher_impl, watcher.NewRequest());
- page_cloud_->SetWatcher(
- nullptr, std::move(watcher),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_EQ(1u, firestore_service_.listen_clients.size());
- EXPECT_FALSE(callback_called);
-
- auto response = google::firestore::v1beta1::ListenResponse();
- response.mutable_target_change()->set_target_change_type(
- google::firestore::v1beta1::TargetChange_TargetChangeType_CURRENT);
- firestore_service_.listen_clients[0]->OnResponse(std::move(response));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-}
-
-TEST_F(PageCloudImplTest, SetWatcherGetCommits) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- TestPageCloudWatcher watcher_impl;
- cloud_provider::PageCloudWatcherPtr watcher;
- fidl::Binding<cloud_provider::PageCloudWatcher> watcher_binding(
- &watcher_impl, watcher.NewRequest());
- page_cloud_->SetWatcher(
- nullptr, std::move(watcher),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
- EXPECT_EQ(1u, firestore_service_.listen_clients.size());
- EXPECT_FALSE(callback_called);
-
- {
- auto response = google::firestore::v1beta1::ListenResponse();
- response.mutable_target_change()->set_target_change_type(
- google::firestore::v1beta1::TargetChange_TargetChangeType_CURRENT);
- firestore_service_.listen_clients[0]->OnResponse(std::move(response));
- }
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-
- std::vector<cloud_provider::CommitPackEntry> entries{{"id0", "data0"}};
- google::protobuf::Timestamp protobuf_timestamp;
- ASSERT_TRUE(google::protobuf::util::TimeUtil::FromString(
- "2018-06-26T14:39:22+00:00", &protobuf_timestamp));
- std::string original_timestamp;
- ASSERT_TRUE(protobuf_timestamp.SerializeToString(&original_timestamp));
-
- cloud_provider::CommitPack commit_pack;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack(entries, &commit_pack));
- auto response = google::firestore::v1beta1::ListenResponse();
- ASSERT_TRUE(EncodeCommitBatchWithTimestamp(
- commit_pack, original_timestamp,
- response.mutable_document_change()->mutable_document()));
- firestore_service_.listen_clients[0]->OnResponse(std::move(response));
-
- RunLoopUntilIdle();
- EXPECT_EQ(1u, watcher_impl.received_commits.size());
- EXPECT_EQ("id0", convert::ToString(watcher_impl.received_commits.front().id));
- EXPECT_EQ("data0",
- convert::ToString(watcher_impl.received_commits.front().data));
- EXPECT_EQ(1u, watcher_impl.received_tokens.size());
- EXPECT_EQ(original_timestamp,
- convert::ToString(watcher_impl.received_tokens.front().opaque_id));
- EXPECT_TRUE(watcher_impl.pending_on_new_commit_callback);
-}
-
-TEST_F(PageCloudImplTest, SetWatcherNotificationOneAtATime) {
- bool callback_called = false;
- auto status = cloud_provider::Status::INTERNAL_ERROR;
- TestPageCloudWatcher watcher_impl;
- cloud_provider::PageCloudWatcherPtr watcher;
- fidl::Binding<cloud_provider::PageCloudWatcher> watcher_binding(
- &watcher_impl, watcher.NewRequest());
- page_cloud_->SetWatcher(
- nullptr, std::move(watcher),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- RunLoopUntilIdle();
-
- {
- auto response = google::firestore::v1beta1::ListenResponse();
- response.mutable_target_change()->set_target_change_type(
- google::firestore::v1beta1::TargetChange_TargetChangeType_CURRENT);
- firestore_service_.listen_clients[0]->OnResponse(std::move(response));
- }
-
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(cloud_provider::Status::OK, status);
-
- // Deliver a commit notificiation from the cloud.
- {
- std::vector<cloud_provider::CommitPackEntry> entries{{"id0", "data0"}};
- google::protobuf::Timestamp protobuf_timestamp;
- ASSERT_TRUE(google::protobuf::util::TimeUtil::FromString(
- "2018-06-26T14:39:22+00:00", &protobuf_timestamp));
- std::string timestamp;
- ASSERT_TRUE(protobuf_timestamp.SerializeToString(×tamp));
-
- cloud_provider::CommitPack commit_pack;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack(entries, &commit_pack));
- auto response = google::firestore::v1beta1::ListenResponse();
- ASSERT_TRUE(EncodeCommitBatchWithTimestamp(
- commit_pack, timestamp,
- response.mutable_document_change()->mutable_document()));
- firestore_service_.listen_clients[0]->OnResponse(std::move(response));
- }
-
- // Verify that the notification was delivered to the watcher.
- RunLoopUntilIdle();
- EXPECT_EQ(1u, watcher_impl.received_commits.size());
- EXPECT_TRUE(watcher_impl.pending_on_new_commit_callback);
-
- // Deliver another commit notificiation from the cloud without calling the
- // watcher pending callback.
- {
- std::vector<cloud_provider::CommitPackEntry> entries{{"id1", "data1"}};
- google::protobuf::Timestamp protobuf_timestamp;
- ASSERT_TRUE(google::protobuf::util::TimeUtil::FromString(
- "2018-06-26T14:39:24+00:00", &protobuf_timestamp));
- std::string timestamp;
- ASSERT_TRUE(protobuf_timestamp.SerializeToString(×tamp));
-
- cloud_provider::CommitPack commit_pack;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack(entries, &commit_pack));
- auto response = google::firestore::v1beta1::ListenResponse();
- ASSERT_TRUE(EncodeCommitBatchWithTimestamp(
- commit_pack, timestamp,
- response.mutable_document_change()->mutable_document()));
- firestore_service_.listen_clients[0]->OnResponse(std::move(response));
- }
-
- // Verify that another commit notification was not delivered.
- RunLoopUntilIdle();
- EXPECT_EQ(1u, watcher_impl.received_commits.size());
- EXPECT_TRUE(watcher_impl.pending_on_new_commit_callback);
-
- // Call the pending callback and verify that the new commit notification was
- // delivered.
- watcher_impl.pending_on_new_commit_callback();
- watcher_impl.pending_on_new_commit_callback = nullptr;
- RunLoopUntilIdle();
- EXPECT_EQ(2u, watcher_impl.received_commits.size());
- EXPECT_EQ("id0", convert::ToString(watcher_impl.received_commits[0].id));
- EXPECT_EQ("id1", convert::ToString(watcher_impl.received_commits[1].id));
- EXPECT_TRUE(watcher_impl.pending_on_new_commit_callback);
-}
-
-} // namespace
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/testing/BUILD.gn b/bin/cloud_provider_firestore/app/testing/BUILD.gn
deleted file mode 100644
index 7e16ac0..0000000
--- a/bin/cloud_provider_firestore/app/testing/BUILD.gn
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/cloud_provider_firestore/*" ]
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "test_credentials_provider.cc",
- "test_credentials_provider.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/callback",
- "//peridot/bin/cloud_provider_firestore/app:lib",
- "//third_party/grpc:grpc++",
- ]
-}
diff --git a/bin/cloud_provider_firestore/app/testing/test_credentials_provider.cc b/bin/cloud_provider_firestore/app/testing/test_credentials_provider.cc
deleted file mode 100644
index 6a6a334..0000000
--- a/bin/cloud_provider_firestore/app/testing/test_credentials_provider.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/app/testing/test_credentials_provider.h"
-
-#include <lib/fit/function.h>
-
-namespace cloud_provider_firestore {
-
-TestCredentialsProvider::TestCredentialsProvider(async_dispatcher_t* dispatcher)
- : task_runner_(dispatcher) {}
-
-TestCredentialsProvider::~TestCredentialsProvider() {}
-
-void TestCredentialsProvider::GetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback) {
- task_runner_.PostTask(
- [callback = std::move(callback)] { callback(nullptr); });
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/app/testing/test_credentials_provider.h b/bin/cloud_provider_firestore/app/testing/test_credentials_provider.h
deleted file mode 100644
index fa52603..0000000
--- a/bin/cloud_provider_firestore/app/testing/test_credentials_provider.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_TESTING_TEST_CREDENTIALS_PROVIDER_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_TESTING_TEST_CREDENTIALS_PROVIDER_H_
-
-#include <functional>
-#include <memory>
-
-#include <grpc++/grpc++.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/cloud_provider_firestore/app/credentials_provider.h"
-
-namespace cloud_provider_firestore {
-
-class TestCredentialsProvider : public CredentialsProvider {
- public:
- explicit TestCredentialsProvider(async_dispatcher_t* dispatcher);
- ~TestCredentialsProvider() override;
-
- void GetCredentials(
- fit::function<void(std::shared_ptr<grpc::CallCredentials>)> callback)
- override;
-
- private:
- // Must be the last member.
- callback::ScopedTaskRunner task_runner_;
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_APP_TESTING_TEST_CREDENTIALS_PROVIDER_H_
diff --git a/bin/cloud_provider_firestore/cloud_provider_firestore_unittests.cmx b/bin/cloud_provider_firestore/cloud_provider_firestore_unittests.cmx
deleted file mode 100644
index 6b4cc0f..0000000
--- a/bin/cloud_provider_firestore/cloud_provider_firestore_unittests.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/cloud_provider_firestore_unittests"
- },
- "sandbox": {
- "features": [],
- "services": [
- ]
- }
-}
diff --git a/bin/cloud_provider_firestore/docs/configuration.md b/bin/cloud_provider_firestore/docs/configuration.md
deleted file mode 100644
index 8318f72..0000000
--- a/bin/cloud_provider_firestore/docs/configuration.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Configuration
-
-This document describes the configuration required for a Firestore Database
-project to be used with `cloud_provider_firestore`.
-
-*** note
-These instructions are relevant only when setting up one's own server instance,
-and not needed to use an existing server instance.
-***
-
-## Rules
-
-In the [Firebase Console], under `Database > Cloud Firestore > Rules`, set the
-rules to:
-
-```
-service cloud.firestore {
- match /databases/{database}/documents {
- match /users/{uid}/{everything=**} {
- allow read, write: if request.auth.uid == uid;
- }
- }
-}
-```
-
-[Firebase Console]: https://console.firebase.google.com/
-
-## Credentials
-
-In order to run tests (end-to-end sync tests, sync benchmarks, validation tests)
-against a Firestore instance, you need the following:
-
- - **API key** - available in `Project Settings / General`
- - **credentials file** for a service account - available in `Project Settings /
- Service accounts`. Click on "Generate new private key".
-
-See [cloud sync set-up instructions] for instructions on how to use this
-information to run these tests.
-
-[cloud sync set-up instructions]: /docs/ledger/testing.md#cloud-sync
diff --git a/bin/cloud_provider_firestore/fidl/BUILD.gn b/bin/cloud_provider_firestore/fidl/BUILD.gn
deleted file mode 100644
index 0808e1b..0000000
--- a/bin/cloud_provider_firestore/fidl/BUILD.gn
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-fidl("fidl") {
- name = "fuchsia.ledger.cloud.firestore"
-
- sources = [
- "factory.fidl",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.auth",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//peridot/public/fidl/fuchsia.modular.auth",
- ]
-}
diff --git a/bin/cloud_provider_firestore/fidl/factory.fidl b/bin/cloud_provider_firestore/fidl/factory.fidl
deleted file mode 100644
index fc0f740..0000000
--- a/bin/cloud_provider_firestore/fidl/factory.fidl
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.ledger.cloud.firestore;
-
-using fuchsia.auth;
-using fuchsia.ledger.cloud;
-
-// Configuration to use when connecting to the Firestore server.
-struct Config {
- // ID of the Firestore instance.
- string server_id;
-
- // API key to use when authenticating with Firebase Auth.
- string api_key;
-};
-
-[Discoverable]
-interface Factory {
- // Creates a cloud provider instance using the given |config|.
- //
- // Parameters:
- // |config| configuration
- // |token_manager| is used to get the appropriate auth tokens
- // associated with user for whom the cloud provider is running.
- 1: GetCloudProvider(
- Config config,
- fuchsia.auth.TokenManager? token_manager,
- request<fuchsia.ledger.cloud.CloudProvider> cloud_provider)
- -> (fuchsia.ledger.cloud.Status status);
-};
diff --git a/bin/cloud_provider_firestore/firestore/BUILD.gn b/bin/cloud_provider_firestore/firestore/BUILD.gn
deleted file mode 100644
index b5cde06..0000000
--- a/bin/cloud_provider_firestore/firestore/BUILD.gn
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/cloud_provider_firestore/*" ]
-
-source_set("firestore") {
- sources = [
- "encoding.cc",
- "encoding.h",
- "firestore_service.h",
- "firestore_service_impl.cc",
- "firestore_service_impl.h",
- "listen_call.cc",
- "listen_call.h",
- "listen_call_client.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- "//peridot/bin/cloud_provider_firestore/grpc",
- "//peridot/bin/cloud_provider_firestore/include",
- "//peridot/lib/commit_pack",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//third_party/googleapis/google/firestore/v1beta1",
- "//third_party/googleapis/google/firestore/v1beta1:service",
- "//third_party/grpc:grpc++",
- ]
-
- deps = [
- "//peridot/lib/base64url",
- "//peridot/lib/convert",
- ]
-
- public_configs = [ "//third_party/googleapis:googleapis_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "encoding_unittest.cc",
- "listen_call_unittest.cc",
- ]
-
- deps = [
- ":firestore",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl:fxl_printers",
- "//garnet/public/lib/gtest",
- "//peridot/bin/cloud_provider_firestore/firestore/testing",
- "//peridot/lib/convert",
- "//third_party/protobuf:protobuf_full",
- ]
-}
diff --git a/bin/cloud_provider_firestore/firestore/encoding.cc b/bin/cloud_provider_firestore/firestore/encoding.cc
deleted file mode 100644
index cb278ea..0000000
--- a/bin/cloud_provider_firestore/firestore/encoding.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/firestore/encoding.h"
-
-#include "peridot/lib/base64url/base64url.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_provider_firestore {
-namespace {
-constexpr char kCommitsKey[] = "commits";
-constexpr char kTimestampKey[] = "timestamp";
-constexpr char kIdKey[] = "id";
-constexpr char kDataKey[] = "data";
-} // namespace
-
-std::string EncodeKey(fxl::StringView input) {
- std::string encoded = base64url::Base64UrlEncode(input);
- encoded.append(1u, '+');
- return encoded;
-}
-
-bool DecodeKey(fxl::StringView input, std::string* output) {
- if (input.empty() || input.back() != '+') {
- return false;
- }
-
- input.remove_suffix(1u);
- return base64url::Base64UrlDecode(input, output);
-}
-
-bool EncodeCommitBatch(const cloud_provider::CommitPack& commits,
- google::firestore::v1beta1::Document* document) {
- FXL_DCHECK(document);
-
- std::vector<cloud_provider::CommitPackEntry> entries;
- if (!cloud_provider::DecodeCommitPack(commits, &entries)) {
- return false;
- }
-
- // TODO(ppi): fail and return false if the resulting batch exceeds max
- // Firestore document size.
- google::firestore::v1beta1::Document result;
- google::firestore::v1beta1::ArrayValue* commit_array =
- (*result.mutable_fields())[kCommitsKey].mutable_array_value();
- for (const auto& entry : entries) {
- google::firestore::v1beta1::MapValue* commit_value =
- commit_array->add_values()->mutable_map_value();
- *((*commit_value->mutable_fields())[kIdKey].mutable_bytes_value()) =
- convert::ToString(entry.id);
- *((*commit_value->mutable_fields())[kDataKey].mutable_bytes_value()) =
- convert::ToString(entry.data);
- }
-
- document->Swap(&result);
- return true;
-}
-
-bool DecodeCommitBatch(
- const google::firestore::v1beta1::Document& document,
- std::vector<cloud_provider::CommitPackEntry>* commit_entries,
- std::string* timestamp) {
- FXL_DCHECK(commit_entries);
- FXL_DCHECK(timestamp);
-
- std::vector<cloud_provider::CommitPackEntry> result;
- if (document.fields().count(kCommitsKey) != 1) {
- return false;
- }
-
- const google::firestore::v1beta1::Value& commits_value =
- document.fields().at(kCommitsKey);
- if (!commits_value.has_array_value()) {
- return false;
- }
-
- const google::firestore::v1beta1::ArrayValue& commits_array_value =
- commits_value.array_value();
- for (const auto& commit_value : commits_array_value.values()) {
- if (!commit_value.has_map_value()) {
- return false;
- }
-
- const google::firestore::v1beta1::MapValue& commit_map_value =
- commit_value.map_value();
- cloud_provider::CommitPackEntry entry;
- if (commit_map_value.fields().count(kIdKey) != 1) {
- return false;
- }
- entry.id =
- convert::ToString(commit_map_value.fields().at(kIdKey).bytes_value());
- if (commit_map_value.fields().count(kDataKey) != 1) {
- return false;
- }
- entry.data =
- convert::ToString(commit_map_value.fields().at(kDataKey).bytes_value());
- result.push_back(std::move(entry));
- }
-
- // Read the timestamp field.
- if (document.fields().count(kTimestampKey) == 1) {
- const google::firestore::v1beta1::Value& timestamp_value =
- document.fields().at(kTimestampKey);
- if (!timestamp_value.has_timestamp_value()) {
- return false;
- }
-
- if (!timestamp_value.timestamp_value().SerializeToString(timestamp)) {
- return false;
- }
- } else if (document.fields().count(kTimestampKey) != 0) {
- // The timestamp field should appear only 0 or 1 time.
- return false;
- }
-
- commit_entries->swap(result);
- return true;
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/firestore/encoding.h b/bin/cloud_provider_firestore/firestore/encoding.h
deleted file mode 100644
index 3efbfcd..0000000
--- a/bin/cloud_provider_firestore/firestore/encoding.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_ENCODING_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_ENCODING_H_
-
-#include <string>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <google/firestore/v1beta1/document.pb.h>
-#include <lib/fidl/cpp/vector.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/cloud_provider_firestore/include/types.h"
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-namespace cloud_provider_firestore {
-
-// Encodes the data so that it can be used as a Firestore key.
-//
-// The resulting encoding is base64url with a single '+' character appended at
-// the end. This is because Firestore disallows keys matching the regular
-// expression `__.*__` which would otherwise be possible to produce.
-//
-// See https://cloud.google.com/firestore/quotas#limits.
-std::string EncodeKey(fxl::StringView input);
-
-// Decodes a Firestore key encoded using |EncodeKey|.
-bool DecodeKey(fxl::StringView input, std::string* output);
-
-// Encodes a batch of commits in the cloud provider FIDL format as a Firestore
-// document.
-bool EncodeCommitBatch(const cloud_provider::CommitPack& commits,
- google::firestore::v1beta1::Document* document);
-
-// Decodes a Firestore document representing a commit batch.
-bool DecodeCommitBatch(
- const google::firestore::v1beta1::Document& document,
- std::vector<cloud_provider::CommitPackEntry>* commit_entries,
- std::string* timestamp);
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_ENCODING_H_
diff --git a/bin/cloud_provider_firestore/firestore/encoding_unittest.cc b/bin/cloud_provider_firestore/firestore/encoding_unittest.cc
deleted file mode 100644
index 7426894..0000000
--- a/bin/cloud_provider_firestore/firestore/encoding_unittest.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/firestore/encoding.h"
-
-#include <string>
-
-#include <google/protobuf/util/time_util.h>
-#include <gtest/gtest.h>
-
-#include "peridot/bin/cloud_provider_firestore/firestore/testing/encoding.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_provider_firestore {
-
-namespace {
-
-// Creates correct std::strings with \0 bytes inside from C-style string
-// constants.
-std::string operator"" _s(const char* str, size_t size) {
- return std::string(str, size);
-}
-
-using StringEncodingTest = ::testing::TestWithParam<std::string>;
-
-TEST_P(StringEncodingTest, BackAndForth) {
- std::string data = GetParam();
- std::string encoded;
- std::string decoded;
-
- encoded = EncodeKey(data);
- EXPECT_EQ('+', encoded.back());
- EXPECT_TRUE(DecodeKey(encoded, &decoded));
- EXPECT_EQ(data, decoded);
-}
-
-INSTANTIATE_TEST_CASE_P(ExampleData, StringEncodingTest,
- ::testing::Values(""_s, "abcdef"_s, "\x02\x7F"_s,
- "~!@#$%^&*()_+-="_s, "\0"_s,
- "bazinga\0\0\0"_s));
-
-TEST(BatchEncodingTest, Empty) {
- cloud_provider::CommitPack commits;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack({}, &commits));
- google::firestore::v1beta1::Document document;
- ASSERT_TRUE(EncodeCommitBatch(commits, &document));
-
- std::vector<cloud_provider::CommitPackEntry> entries;
- std::string timestamp;
- ASSERT_TRUE(DecodeCommitBatch(document, &entries, ×tamp));
- EXPECT_EQ(0u, entries.size());
-}
-
-TEST(BatchEncodingTest, TwoCommits) {
- cloud_provider::CommitPack commits;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack(
- {{"id0", "data0"}, {"id1", "data1"}}, &commits));
- google::firestore::v1beta1::Document document;
- ASSERT_TRUE(EncodeCommitBatch(commits, &document));
-
- std::vector<cloud_provider::CommitPackEntry> entries;
- std::string timestamp;
- ASSERT_TRUE(DecodeCommitBatch(document, &entries, ×tamp));
- EXPECT_EQ(2u, entries.size());
- EXPECT_EQ("id0", entries[0].id);
- EXPECT_EQ("data0", entries[0].data);
- EXPECT_EQ("id1", entries[1].id);
- EXPECT_EQ("data1", entries[1].data);
-}
-
-TEST(BatchEncodingTest, Timestamp) {
- cloud_provider::CommitPack commits;
- ASSERT_TRUE(cloud_provider::EncodeCommitPack({{"id0", "data0"}}, &commits));
- google::firestore::v1beta1::Document document;
- google::protobuf::Timestamp protobuf_timestamp;
- ASSERT_TRUE(google::protobuf::util::TimeUtil::FromString(
- "2018-06-26T14:39:22+00:00", &protobuf_timestamp));
- std::string original_timestamp;
- ASSERT_TRUE(protobuf_timestamp.SerializeToString(&original_timestamp));
- EncodeCommitBatchWithTimestamp(commits, original_timestamp, &document);
-
- std::vector<cloud_provider::CommitPackEntry> entries;
- std::string decoded_timestamp;
- EXPECT_TRUE(DecodeCommitBatch(document, &entries, &decoded_timestamp));
- EXPECT_EQ(original_timestamp, decoded_timestamp);
-}
-
-TEST(BatchEncodingTest, DecodingErrors) {
- std::vector<cloud_provider::CommitPackEntry> entries;
- std::string timestamp;
-
- {
- // Empty document.
- google::firestore::v1beta1::Document document;
- EXPECT_FALSE(DecodeCommitBatch(document, &entries, ×tamp));
- }
-
- {
- // Non-empty but the commit key is missing.
- google::firestore::v1beta1::Document document;
- (*document.mutable_fields())["some_field"].set_integer_value(3);
- EXPECT_FALSE(DecodeCommitBatch(document, &entries, ×tamp));
- }
-
- {
- // Commits field is not an array.
- google::firestore::v1beta1::Document document;
- (*document.mutable_fields())["commits"].set_integer_value(3);
- EXPECT_FALSE(DecodeCommitBatch(document, &entries, ×tamp));
- }
-
- {
- // Commits contains a commit that is not a map.
- google::firestore::v1beta1::Document document;
- google::firestore::v1beta1::ArrayValue* commit_array =
- (*document.mutable_fields())["commits"].mutable_array_value();
- commit_array->add_values()->set_integer_value(3);
- EXPECT_FALSE(DecodeCommitBatch(document, &entries, ×tamp));
- }
-
- {
- // Commits contains a commit that misses the "data" field.
- google::firestore::v1beta1::Document document;
- google::firestore::v1beta1::ArrayValue* commit_array =
- (*document.mutable_fields())["commits"].mutable_array_value();
- google::firestore::v1beta1::MapValue* commit_value =
- commit_array->add_values()->mutable_map_value();
- *((*commit_value->mutable_fields())["id"].mutable_bytes_value()) =
- "some_id";
- EXPECT_FALSE(DecodeCommitBatch(document, &entries, ×tamp));
- }
-
- {
- // Commits contains a commit that misses the "id" field.
- google::firestore::v1beta1::Document document;
- google::firestore::v1beta1::ArrayValue* commit_array =
- (*document.mutable_fields())["commits"].mutable_array_value();
- google::firestore::v1beta1::MapValue* commit_value =
- commit_array->add_values()->mutable_map_value();
- *((*commit_value->mutable_fields())["data"].mutable_bytes_value()) =
- "some_data";
- EXPECT_FALSE(DecodeCommitBatch(document, &entries, ×tamp));
- }
-
- {
- // Correct batch (sanity check).
- google::firestore::v1beta1::Document document;
- google::firestore::v1beta1::ArrayValue* commit_array =
- (*document.mutable_fields())["commits"].mutable_array_value();
- google::firestore::v1beta1::MapValue* commit_value =
- commit_array->add_values()->mutable_map_value();
- *((*commit_value->mutable_fields())["id"].mutable_bytes_value()) =
- "some_id";
- *((*commit_value->mutable_fields())["data"].mutable_bytes_value()) =
- "some_data";
- EXPECT_TRUE(DecodeCommitBatch(document, &entries, ×tamp));
- }
-}
-
-} // namespace
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/firestore/firestore_service.h b/bin/cloud_provider_firestore/firestore/firestore_service.h
deleted file mode 100644
index 4f4fa3c..0000000
--- a/bin/cloud_provider_firestore/firestore/firestore_service.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_H_
-
-#include <functional>
-
-#include <google/firestore/v1beta1/document.pb.h>
-#include <google/firestore/v1beta1/firestore.grpc.pb.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/cloud_provider_firestore/firestore/listen_call_client.h"
-
-namespace cloud_provider_firestore {
-
-// Client library for Firestore.
-//
-// Manages access to a particular Firestore database.
-//
-// Requests methods are assumed to be called on the |main_runner| thread. All
-// client callbacks are called on the |main_runner|.
-class FirestoreService {
- public:
- FirestoreService() {}
- virtual ~FirestoreService() {}
-
- // Returns the Firestore path to the managed database.
- //
- // The returned value is in the format:
- // `projects/{project_id}/databases/{database_id}`.
- virtual const std::string& GetDatabasePath() = 0;
-
- // Returns the Firestore path to the root of the resource tree of the managed
- // database.
- //
- // The returned value is in the format:
- // `projects/{project_id}/databases/{database_id}/documents`.
- virtual const std::string& GetRootPath() = 0;
-
- // Gets a single document.
- virtual void GetDocument(
- google::firestore::v1beta1::GetDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) = 0;
-
- // Lists documents.
- virtual void ListDocuments(
- google::firestore::v1beta1::ListDocumentsRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::ListDocumentsResponse)>
- callback) = 0;
-
- // Creates a new document.
- virtual void CreateDocument(
- google::firestore::v1beta1::CreateDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) = 0;
-
- // Deletes a document.
- virtual void DeleteDocument(
- google::firestore::v1beta1::DeleteDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status)> callback) = 0;
-
- // Commits a transaction, while optionally updating documents.
- virtual void Commit(
- google::firestore::v1beta1::CommitRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::CommitResponse)>
- callback) = 0;
-
- // Runs a query.
- virtual void RunQuery(
- google::firestore::v1beta1::RunQueryRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<
- void(grpc::Status,
- std::vector<google::firestore::v1beta1::RunQueryResponse>)>
- callback) = 0;
-
- // Initiates a stream to watch for change notifications.
- virtual std::unique_ptr<ListenCallHandler> Listen(
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- ListenCallClient* client) = 0;
-
- // Shuts the client down.
- //
- // It is not allowed to make any calls on FirestoreService after ShutDown()
- // was called.
- //
- // It is only safe to delete the class after the callback is called.
- virtual void ShutDown(fit::closure callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(FirestoreService);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_H_
diff --git a/bin/cloud_provider_firestore/firestore/firestore_service_impl.cc b/bin/cloud_provider_firestore/firestore/firestore_service_impl.cc
deleted file mode 100644
index 1d6eb6b..0000000
--- a/bin/cloud_provider_firestore/firestore/firestore_service_impl.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/firestore/firestore_service_impl.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/strings/string_view.h>
-
-namespace cloud_provider_firestore {
-
-namespace {
-
-constexpr fxl::StringView kGoogleCloudResourcePrefixHeader =
- "google-cloud-resource-prefix";
-
-// Handles the general case of call response that returns a status and a
-// response value.
-template <typename ResponseType>
-struct ResponseVariant {
- using CallbackType = fit::function<void(grpc::Status, ResponseType)>;
-
- static void Call(const CallbackType& callback, grpc::Status status,
- ResponseType response) {
- callback(std::move(status), std::move(response));
- }
-};
-
-// Handles a special case of response type being empty, in which case we skip
-// the google::protobuf::Empty value and only pass the status to the caller.
-template <>
-struct ResponseVariant<google::protobuf::Empty> {
- using CallbackType = fit::function<void(grpc::Status)>;
-
- static void Call(const CallbackType& callback, grpc::Status status,
- google::protobuf::Empty /*response*/) {
- callback(std::move(status));
- }
-};
-
-template <typename ResponseType>
-void MakeCall(
- SingleResponseCall<ResponseType>* call,
- std::unique_ptr<SingleResponseReader<ResponseType>> response_reader,
- typename ResponseVariant<ResponseType>::CallbackType callback) {
- call->response_reader = std::move(response_reader);
-
- call->on_complete = [call, callback = std::move(callback)](bool ok) {
- ResponseVariant<ResponseType>::Call(callback, std::move(call->status),
- std::move(call->response));
- if (call->on_empty) {
- call->on_empty();
- }
- };
- call->response_reader->Finish(&call->response, &call->status,
- &call->on_complete);
-}
-
-} // namespace
-
-FirestoreServiceImpl::FirestoreServiceImpl(
- std::string server_id, async_dispatcher_t* dispatcher,
- std::shared_ptr<grpc::Channel> channel)
- : server_id_(std::move(server_id)),
- database_path_("projects/" + server_id_ + "/databases/(default)"),
- root_path_(database_path_ + "/documents"),
- dispatcher_(dispatcher),
- firestore_(google::firestore::v1beta1::Firestore::NewStub(channel)) {
- polling_thread_ = std::thread(&FirestoreServiceImpl::Poll, this);
-}
-
-FirestoreServiceImpl::~FirestoreServiceImpl() {}
-
-void FirestoreServiceImpl::GetDocument(
- google::firestore::v1beta1::GetDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) {
- FXL_DCHECK(dispatcher_ == async_get_default_dispatcher());
- DocumentResponseCall& call = document_response_calls_.emplace();
- SetUpContext(&call.context, call_credentials);
- auto response_reader =
- firestore_->AsyncGetDocument(&call.context, request, &cq_);
- MakeCall<google::firestore::v1beta1::Document>(
- &call, std::move(response_reader), std::move(callback));
-}
-
-void FirestoreServiceImpl::ListDocuments(
- google::firestore::v1beta1::ListDocumentsRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::ListDocumentsResponse)>
- callback) {
- FXL_DCHECK(dispatcher_ == async_get_default_dispatcher());
- ListDocumentsResponseCall& call = list_documents_response_calls_.emplace();
- SetUpContext(&call.context, call_credentials);
- auto response_reader =
- firestore_->AsyncListDocuments(&call.context, request, &cq_);
- MakeCall<google::firestore::v1beta1::ListDocumentsResponse>(
- &call, std::move(response_reader), std::move(callback));
-}
-
-void FirestoreServiceImpl::CreateDocument(
- google::firestore::v1beta1::CreateDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) {
- FXL_DCHECK(dispatcher_ == async_get_default_dispatcher());
- DocumentResponseCall& call = document_response_calls_.emplace();
- SetUpContext(&call.context, call_credentials);
- auto response_reader =
- firestore_->AsyncCreateDocument(&call.context, request, &cq_);
-
- MakeCall<google::firestore::v1beta1::Document>(
- &call, std::move(response_reader), std::move(callback));
-}
-
-void FirestoreServiceImpl::DeleteDocument(
- google::firestore::v1beta1::DeleteDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status)> callback) {
- FXL_DCHECK(dispatcher_ == async_get_default_dispatcher());
- EmptyResponseCall& call = empty_response_calls_.emplace();
- SetUpContext(&call.context, call_credentials);
- auto response_reader =
- firestore_->AsyncDeleteDocument(&call.context, request, &cq_);
-
- MakeCall<google::protobuf::Empty>(&call, std::move(response_reader),
- std::move(callback));
-}
-
-void FirestoreServiceImpl::Commit(
- google::firestore::v1beta1::CommitRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::CommitResponse)>
- callback) {
- FXL_DCHECK(dispatcher_ == async_get_default_dispatcher());
- CommitResponseCall& call = commit_response_calls_.emplace();
- SetUpContext(&call.context, call_credentials);
- auto response_reader = firestore_->AsyncCommit(&call.context, request, &cq_);
-
- MakeCall<google::firestore::v1beta1::CommitResponse>(
- &call, std::move(response_reader), std::move(callback));
-}
-
-void FirestoreServiceImpl::RunQuery(
- google::firestore::v1beta1::RunQueryRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<
- void(grpc::Status,
- std::vector<google::firestore::v1beta1::RunQueryResponse>)>
- callback) {
- FXL_DCHECK(dispatcher_ == async_get_default_dispatcher());
- auto context = std::make_unique<grpc::ClientContext>();
- SetUpContext(context.get(), call_credentials);
-
- auto stream = firestore_->PrepareAsyncRunQuery(context.get(), request, &cq_);
- auto& call = run_query_calls_.emplace(std::move(context), std::move(stream));
- call.Drain(std::move(callback));
-}
-
-std::unique_ptr<ListenCallHandler> FirestoreServiceImpl::Listen(
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- ListenCallClient* client) {
- FXL_DCHECK(dispatcher_ == async_get_default_dispatcher());
- auto context = std::make_unique<grpc::ClientContext>();
- SetUpContext(context.get(), call_credentials);
-
- auto stream = firestore_->PrepareAsyncListen(context.get(), &cq_);
- auto& call =
- listen_calls_.emplace(client, std::move(context), std::move(stream));
- return call.MakeHandler();
-}
-
-void FirestoreServiceImpl::ShutDown(fit::closure callback) {
- // Ask the CompletionQueue to shut down. This makes cq_.Next() to start
- // returning false once the pending operations are drained.
- cq_.Shutdown();
-
- // Wait for the polling thread to exit.
- polling_thread_.join();
-
- // The CQ polling thread might have posted new tasks on the main thread before
- // exiting, completing the calls that were active when we initated the
- // CompletionQueue shut down. These must be processed before we call the
- // client callback, so post the client callback on the main thread too.
- async::PostTask(dispatcher_, std::move(callback));
-}
-
-void FirestoreServiceImpl::SetUpContext(
- grpc::ClientContext* context,
- std::shared_ptr<grpc::CallCredentials> call_credentials) {
- context->AddMetadata(kGoogleCloudResourcePrefixHeader.ToString(),
- database_path_);
- context->set_credentials(call_credentials);
-}
-
-void FirestoreServiceImpl::Poll() {
- void* tag;
- bool ok = false;
- while (cq_.Next(&tag, &ok)) {
- FXL_DCHECK(tag);
- auto callable = reinterpret_cast<fit::function<void(bool)>*>(tag);
- async::PostTask(dispatcher_, [callable, ok] { (*callable)(ok); });
- }
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/firestore/firestore_service_impl.h b/bin/cloud_provider_firestore/firestore/firestore_service_impl.h
deleted file mode 100644
index 2ac2641..0000000
--- a/bin/cloud_provider_firestore/firestore/firestore_service_impl.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_IMPL_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_IMPL_H_
-
-#include <memory>
-#include <thread>
-
-#include <lib/async/dispatcher.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/cloud_provider_firestore/firestore/firestore_service.h"
-#include "peridot/bin/cloud_provider_firestore/firestore/listen_call.h"
-#include "peridot/bin/cloud_provider_firestore/grpc/read_stream_drainer.h"
-
-namespace cloud_provider_firestore {
-
-template <typename ResponseType>
-using SingleResponseReader = grpc::ClientAsyncResponseReader<ResponseType>;
-
-template <typename ResponseType>
-struct SingleResponseCall {
- void set_on_empty(fit::closure on_empty) {
- this->on_empty = std::move(on_empty);
- }
-
- // Context used to make the remote call.
- grpc::ClientContext context;
-
- // Reader used to retrieve the result of the remote call.
- std::unique_ptr<SingleResponseReader<ResponseType>> response_reader;
-
- // Response of the remote call.
- ResponseType response;
-
- // Response status of the remote call.
- grpc::Status status;
-
- // Callback to be called upon completing the remote call.
- fit::function<void(bool)> on_complete;
-
- // Callback to be called when the call object can be deleted.
- fit::closure on_empty;
-};
-
-using DocumentResponseCall =
- SingleResponseCall<google::firestore::v1beta1::Document>;
-
-using CommitResponseCall =
- SingleResponseCall<google::firestore::v1beta1::CommitResponse>;
-
-using ListDocumentsResponseCall =
- SingleResponseCall<google::firestore::v1beta1::ListDocumentsResponse>;
-
-using EmptyResponseCall = SingleResponseCall<google::protobuf::Empty>;
-
-using RunQueryCall =
- ReadStreamDrainer<grpc::ClientAsyncReaderInterface<
- google::firestore::v1beta1::RunQueryResponse>,
- google::firestore::v1beta1::RunQueryResponse>;
-
-// Implementation of the FirestoreService interface.
-//
-// This class is implemented as a wrapper over the Firestore connection. We use
-// a polling thread to wait for request completion on the completion queue and
-// expose a callback-based API to the client.
-class FirestoreServiceImpl : public FirestoreService {
- public:
- FirestoreServiceImpl(std::string server_id, async_dispatcher_t* dispatcher,
- std::shared_ptr<grpc::Channel> channel);
-
- ~FirestoreServiceImpl() override;
-
- // FirestoreService:
- const std::string& GetDatabasePath() override { return database_path_; }
-
- const std::string& GetRootPath() override { return root_path_; }
-
- void GetDocument(
- google::firestore::v1beta1::GetDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) override;
-
- void ListDocuments(
- google::firestore::v1beta1::ListDocumentsRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::ListDocumentsResponse)>
- callback) override;
-
- void CreateDocument(
- google::firestore::v1beta1::CreateDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) override;
-
- void DeleteDocument(google::firestore::v1beta1::DeleteDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status)> callback) override;
-
- void Commit(google::firestore::v1beta1::CommitRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::CommitResponse)>
- callback) override;
-
- void RunQuery(google::firestore::v1beta1::RunQueryRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(
- grpc::Status,
- std::vector<google::firestore::v1beta1::RunQueryResponse>)>
- callback) override;
-
- std::unique_ptr<ListenCallHandler> Listen(
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- ListenCallClient* client) override;
-
- void ShutDown(fit::closure callback) override;
-
- private:
- void SetUpContext(grpc::ClientContext* context,
- std::shared_ptr<grpc::CallCredentials> call_credentials);
-
- void Poll();
-
- const std::string server_id_;
- const std::string database_path_;
- const std::string root_path_;
-
- async_dispatcher_t* const dispatcher_;
- std::thread polling_thread_;
-
- std::unique_ptr<google::firestore::v1beta1::Firestore::Stub> firestore_;
- grpc::CompletionQueue cq_;
-
- // Single-request single-response calls.
- callback::AutoCleanableSet<DocumentResponseCall> document_response_calls_;
- callback::AutoCleanableSet<CommitResponseCall> commit_response_calls_;
- callback::AutoCleanableSet<ListDocumentsResponseCall>
- list_documents_response_calls_;
- callback::AutoCleanableSet<EmptyResponseCall> empty_response_calls_;
-
- // Single-request stream-response calls.
- callback::AutoCleanableSet<RunQueryCall> run_query_calls_;
-
- // Stream-request stream-response calls.
- callback::AutoCleanableSet<ListenCall> listen_calls_;
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_IMPL_H_
diff --git a/bin/cloud_provider_firestore/firestore/listen_call.cc b/bin/cloud_provider_firestore/firestore/listen_call.cc
deleted file mode 100644
index 1899617..0000000
--- a/bin/cloud_provider_firestore/firestore/listen_call.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/firestore/listen_call.h"
-
-namespace cloud_provider_firestore {
-
-namespace {
-
-class ListenCallHandlerImpl : public ListenCallHandler {
- public:
- explicit ListenCallHandlerImpl(fxl::WeakPtr<ListenCall> call) : call_(call) {}
-
- ~ListenCallHandlerImpl() override {
- if (!call_) {
- return;
- }
- call_->OnHandlerGone();
- }
-
- void Write(google::firestore::v1beta1::ListenRequest request) override {
- // It's an arror to call Write() after OnFinished() is delivered to the
- // client (which happens before |call_| is deleted).
- FXL_DCHECK(call_);
- call_->Write(std::move(request));
- }
-
- private:
- fxl::WeakPtr<ListenCall> const call_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ListenCallHandlerImpl);
-};
-
-} // namespace
-
-ListenCall::ListenCall(ListenCallClient* client,
- std::unique_ptr<grpc::ClientContext> context,
- std::unique_ptr<ListenStream> stream)
- : client_(client),
- context_(std::move(context)),
- stream_(std::move(stream)),
- stream_controller_(stream_.get()),
- stream_reader_(stream_.get()),
- stream_writer_(stream_.get()),
- weak_ptr_factory_(this) {
- // Configure reading from the stream.
- stream_reader_.SetOnError([this] { FinishIfNeeded(); });
- stream_reader_.SetOnMessage(
- [this](google::firestore::v1beta1::ListenResponse response) {
- if (CheckEmpty()) {
- return;
- }
-
- client_->OnResponse(std::move(response));
- if (finish_requested_) {
- return;
- }
- stream_reader_.Read();
- });
-
- // Configure writing to the stream.
- stream_writer_.SetOnError([this] { FinishIfNeeded(); });
- stream_writer_.SetOnSuccess([this] { CheckEmpty(); });
-
- // Finally, start the stream.
- stream_controller_.StartCall([this](bool ok) {
- if (!ok) {
- FXL_LOG(ERROR) << "Failed to establish the stream.";
- HandleFinished(grpc::Status(grpc::StatusCode::UNKNOWN, "unknown"));
- return;
- }
-
- if (CheckEmpty()) {
- return;
- }
-
- // Notify the client that the connection is now established and start
- // reading the server stream.
- connected_ = true;
- client_->OnConnected();
- stream_reader_.Read();
- });
-}
-
-ListenCall::~ListenCall() { FXL_DCHECK(IsEmpty()); }
-
-void ListenCall::Write(google::firestore::v1beta1::ListenRequest request) {
- // It's only valid to perform a write after the connection was established,
- // and before the Finish() call was made.
- FXL_DCHECK(connected_);
- FXL_DCHECK(!finish_requested_);
- stream_writer_.Write(std::move(request));
-}
-
-void ListenCall::OnHandlerGone() {
- // Unset the |client_| pointer, so that no client notifications are made
- // after the handler is deleted.
- client_ = nullptr;
-
- context_->TryCancel();
- CheckEmpty();
-}
-
-std::unique_ptr<ListenCallHandler> ListenCall::MakeHandler() {
- return std::make_unique<ListenCallHandlerImpl>(
- weak_ptr_factory_.GetWeakPtr());
-}
-
-void ListenCall::FinishIfNeeded() {
- if (!finish_requested_ && client_) {
- Finish();
- return;
- }
-
- CheckEmpty();
-}
-
-void ListenCall::Finish() {
- FXL_DCHECK(!finish_requested_);
- finish_requested_ = true;
-
- stream_controller_.Finish([this](bool ok, grpc::Status status) {
- if (!client_) {
- CheckEmpty();
- return;
- }
-
- if (!ok) {
- FXL_LOG(ERROR) << "Failed to retrieve the final status of the stream";
- HandleFinished(grpc::Status(grpc::StatusCode::UNKNOWN, "unknown"));
- return;
- }
-
- HandleFinished(status);
- });
-}
-
-void ListenCall::HandleFinished(grpc::Status status) {
- if (client_) {
- client_->OnFinished(status);
- // No client notifications can be delivered after |OnFinished|.
- client_ = nullptr;
- }
- CheckEmpty();
-}
-
-bool ListenCall::IsEmpty() {
- return client_ == nullptr && stream_controller_.IsEmpty() &&
- stream_reader_.IsEmpty() && stream_writer_.IsEmpty();
-}
-
-bool ListenCall::CheckEmpty() {
- if (!IsEmpty()) {
- return false;
- }
-
- if (on_empty_) {
- on_empty_();
- }
- return true;
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/firestore/listen_call.h b/bin/cloud_provider_firestore/firestore/listen_call.h
deleted file mode 100644
index c8e4e6e..0000000
--- a/bin/cloud_provider_firestore/firestore/listen_call.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_LISTEN_CALL_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_LISTEN_CALL_H_
-
-#include <memory>
-
-#include <google/firestore/v1beta1/firestore.grpc.pb.h>
-#include <grpc++/grpc++.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/cloud_provider_firestore/firestore/listen_call_client.h"
-#include "peridot/bin/cloud_provider_firestore/grpc/stream_controller.h"
-#include "peridot/bin/cloud_provider_firestore/grpc/stream_reader.h"
-#include "peridot/bin/cloud_provider_firestore/grpc/stream_writer.h"
-
-namespace cloud_provider_firestore {
-
-using ListenStream = grpc::ClientAsyncReaderWriterInterface<
- google::firestore::v1beta1::ListenRequest,
- google::firestore::v1beta1::ListenResponse>;
-
-class ListenCall {
- public:
- // Creates a new instance.
- ListenCall(ListenCallClient* client,
- std::unique_ptr<grpc::ClientContext> context,
- std::unique_ptr<ListenStream> stream);
- ~ListenCall();
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
-
- void Write(google::firestore::v1beta1::ListenRequest request);
-
- void OnHandlerGone();
-
- std::unique_ptr<ListenCallHandler> MakeHandler();
-
- private:
- void FinishIfNeeded();
-
- void Finish();
-
- void HandleFinished(grpc::Status status);
-
- bool IsEmpty();
-
- bool CheckEmpty();
-
- // Pointer to the client of the call. It is unset when the call handler is
- // deleted.
- ListenCallClient* client_;
-
- // Context used to make the remote call.
- std::unique_ptr<grpc::ClientContext> context_;
-
- // gRPC stream handler.
- std::unique_ptr<ListenStream> stream_;
-
- StreamController<ListenStream> stream_controller_;
- StreamReader<ListenStream, google::firestore::v1beta1::ListenResponse>
- stream_reader_;
- StreamWriter<ListenStream, google::firestore::v1beta1::ListenRequest>
- stream_writer_;
-
- fit::closure on_empty_;
-
- bool connected_ = false;
- bool finish_requested_ = false;
-
- // Must be the last member.
- fxl::WeakPtrFactory<ListenCall> weak_ptr_factory_;
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_LISTEN_CALL_H_
diff --git a/bin/cloud_provider_firestore/firestore/listen_call_client.h b/bin/cloud_provider_firestore/firestore/listen_call_client.h
deleted file mode 100644
index 7ddf917..0000000
--- a/bin/cloud_provider_firestore/firestore/listen_call_client.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_LISTEN_CALL_CLIENT_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_LISTEN_CALL_CLIENT_H_
-
-#include <functional>
-#include <memory>
-
-#include <google/firestore/v1beta1/firestore.grpc.pb.h>
-#include <grpc++/grpc++.h>
-#include <lib/fxl/functional/closure.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-namespace cloud_provider_firestore {
-
-// Client interface for the Listen call.
-//
-// No methods will be called after the associated ListenCallHandler is deleted.
-class ListenCallClient {
- public:
- ListenCallClient() {}
- virtual ~ListenCallClient() {}
-
- // Called when the connection is established.
- //
- // It is only after receiving this call that any methods on the associated
- // ListenCallHandler can be called.
- virtual void OnConnected() = 0;
-
- // Called when a response is received.
- //
- // Can be called multiple times.
- virtual void OnResponse(
- google::firestore::v1beta1::ListenResponse response) = 0;
-
- // Called when the stream is closed.
- //
- // Might be called at any time before or after the OnConnected() call, when
- // an error shuts down the stream.
- //
- // This method will be called exactly once. No other methods will be called
- // after this one. No methods on the associated ListenCallHandler can be
- // called after this call is received.
- virtual void OnFinished(grpc::Status status) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(ListenCallClient);
-};
-
-// Handler for the listen call.
-//
-// The client can delete this at any point, causing the underlying RPC to
-// correctly terminate if needed.
-class ListenCallHandler {
- public:
- ListenCallHandler() {}
-
- virtual ~ListenCallHandler() {}
-
- // Writes the given |request| into the outgoing stream.
- //
- // Can be only called after the |OnConnected()| notification on the associated
- // ListenCallClient.
- virtual void Write(google::firestore::v1beta1::ListenRequest request) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(ListenCallHandler);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_LISTEN_CALL_CLIENT_H_
diff --git a/bin/cloud_provider_firestore/firestore/listen_call_unittest.cc b/bin/cloud_provider_firestore/firestore/listen_call_unittest.cc
deleted file mode 100644
index 61e9f45..0000000
--- a/bin/cloud_provider_firestore/firestore/listen_call_unittest.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/firestore/listen_call.h"
-
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-
-namespace cloud_provider_firestore {
-
-class TestListenStream : public ListenStream {
- public:
- TestListenStream() {}
- ~TestListenStream() override {}
-
- // ListenStream:
- void StartCall(void* tag) override {
- connect_tag = static_cast<fit::function<void(bool)>*>(tag);
- }
- void ReadInitialMetadata(void* /*tag*/) override {}
- void Read(google::firestore::v1beta1::ListenResponse* /*response*/,
- void* tag) override {
- read_tag = static_cast<fit::function<void(bool)>*>(tag);
- }
- void Write(const google::firestore::v1beta1::ListenRequest& /*request*/,
- void* tag) override {
- write_tag = static_cast<fit::function<void(bool)>*>(tag);
- }
- void Write(const google::firestore::v1beta1::ListenRequest& /*request*/,
- grpc::WriteOptions /*options*/, void* /*tag*/) override {}
- void WritesDone(void* /*tag*/) override {}
- void Finish(grpc::Status* /*status*/, void* tag) override {
- finish_tag = static_cast<fit::function<void(bool)>*>(tag);
- }
-
- fit::function<void(bool)>* connect_tag = nullptr;
- fit::function<void(bool)>* read_tag = nullptr;
- fit::function<void(bool)>* write_tag = nullptr;
- fit::function<void(bool)>* finish_tag = nullptr;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(TestListenStream);
-};
-
-class ListenCallTest : public ::testing::Test, public ListenCallClient {
- public:
- ListenCallTest() {
- auto stream = std::make_unique<TestListenStream>();
- auto context = std::make_unique<grpc::ClientContext>();
- stream_ = stream.get();
- call_ = std::make_unique<ListenCall>(this, std::move(context),
- std::move(stream));
- call_->set_on_empty([this] { on_empty_calls_++; });
- }
- ~ListenCallTest() override {}
-
- // ListenCallClient:
- void OnConnected() override { on_connected_calls_++; }
-
- void OnResponse(
- google::firestore::v1beta1::ListenResponse /*response*/) override {
- on_response_calls_++;
- }
-
- void OnFinished(grpc::Status status) override {
- on_finished_calls_++;
- status_ = status;
- }
-
- protected:
- TestListenStream* stream_;
- std::unique_ptr<ListenCall> call_;
-
- int on_connected_calls_ = 0;
- int on_response_calls_ = 0;
- int on_finished_calls_ = 0;
- grpc::Status status_;
-
- int on_empty_calls_ = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(ListenCallTest);
-};
-
-TEST_F(ListenCallTest, DeleteHandlerBeforeConnect) {
- auto handler = call_->MakeHandler();
- handler.reset();
-
- // Simulate the connection response arriving.
- (*stream_->connect_tag)(true);
-
- // Verify that on_empty was called.
- EXPECT_EQ(1, on_empty_calls_);
-
- // Verify that no client calls were made (because the handler was deleted at
- // the very beginning and no client calls should be made after it goes away).
- EXPECT_EQ(0, on_connected_calls_);
- EXPECT_EQ(0, on_response_calls_);
- EXPECT_EQ(0, on_finished_calls_);
-}
-
-TEST_F(ListenCallTest, ConnectionError) {
- auto handler = call_->MakeHandler();
- (*stream_->connect_tag)(false);
- EXPECT_EQ(0, on_connected_calls_);
- EXPECT_EQ(0, on_response_calls_);
- EXPECT_EQ(1, on_finished_calls_);
- EXPECT_FALSE(status_.ok());
-}
-
-TEST_F(ListenCallTest, DeleteHandlerAfterConnect) {
- auto handler = call_->MakeHandler();
- (*stream_->connect_tag)(true);
- EXPECT_EQ(1, on_connected_calls_);
-
- // Delete the handler and simulate the pending read call failing due to being
- // interrupted.
- handler.reset();
- (*stream_->read_tag)(false);
-
- // Verify that on_empty was called.
- EXPECT_EQ(1, on_empty_calls_);
-
- // Verify that no further client calls were made after the handler is deleted.
- EXPECT_EQ(1, on_connected_calls_);
- EXPECT_EQ(0, on_response_calls_);
- EXPECT_EQ(0, on_finished_calls_);
-}
-
-TEST_F(ListenCallTest, WriteAndDeleteHandler) {
- auto handler = call_->MakeHandler();
- (*stream_->connect_tag)(true);
- EXPECT_EQ(1, on_connected_calls_);
-
- handler->Write(google::firestore::v1beta1::ListenRequest());
- (*stream_->write_tag)(true);
-
- handler.reset();
- (*stream_->read_tag)(false);
- EXPECT_EQ(1, on_empty_calls_);
- EXPECT_EQ(1, on_connected_calls_);
- EXPECT_EQ(0, on_response_calls_);
- EXPECT_EQ(0, on_finished_calls_);
-}
-
-TEST_F(ListenCallTest, ReadAndDeleteHandler) {
- auto handler = call_->MakeHandler();
- (*stream_->connect_tag)(true);
- EXPECT_EQ(1, on_connected_calls_);
-
- (*stream_->read_tag)(true);
- (*stream_->read_tag)(true);
- (*stream_->read_tag)(true);
-
- handler.reset();
- (*stream_->read_tag)(false);
- EXPECT_EQ(1, on_empty_calls_);
- EXPECT_EQ(1, on_connected_calls_);
- EXPECT_EQ(3, on_response_calls_);
- EXPECT_EQ(0, on_finished_calls_);
-}
-
-TEST_F(ListenCallTest, ReadError) {
- auto handler = call_->MakeHandler();
- (*stream_->connect_tag)(true);
- EXPECT_EQ(1, on_connected_calls_);
-
- (*stream_->read_tag)(true);
- EXPECT_EQ(1, on_response_calls_);
- EXPECT_FALSE(stream_->finish_tag);
-
- // Simulate read error, verify that we attempt to finish the stream to
- // retrieve the error status.
- (*stream_->read_tag)(false);
- EXPECT_TRUE(stream_->finish_tag);
-
- (*stream_->finish_tag)(true);
- EXPECT_EQ(1, on_finished_calls_);
-}
-
-// Verifies that we don't crash when the handler outlives the call object, see
-// LE-584.
-TEST_F(ListenCallTest, DeleteCallObjectBeforeHandler) {
- auto handler = call_->MakeHandler();
- (*stream_->connect_tag)(true);
- EXPECT_EQ(1, on_connected_calls_);
-
- (*stream_->read_tag)(true);
- EXPECT_EQ(1, on_response_calls_);
- EXPECT_FALSE(stream_->finish_tag);
-
- // Simulate read error which will close the stream.
- (*stream_->read_tag)(false);
- EXPECT_TRUE(stream_->finish_tag);
- (*stream_->finish_tag)(true);
- EXPECT_EQ(1, on_finished_calls_);
-
- // Verify that on_empty was called.
- EXPECT_EQ(1, on_empty_calls_);
-
- // Delete the call object.
- call_.reset();
-
- // Delete the handler.
- handler.reset();
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/firestore/testing/BUILD.gn b/bin/cloud_provider_firestore/firestore/testing/BUILD.gn
deleted file mode 100644
index a3b3220..0000000
--- a/bin/cloud_provider_firestore/firestore/testing/BUILD.gn
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/cloud_provider_firestore/*" ]
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "encoding.cc",
- "encoding.h",
- "test_firestore_service.cc",
- "test_firestore_service.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fidl/cpp",
- "//peridot/bin/cloud_provider_firestore/firestore",
- "//peridot/bin/cloud_provider_firestore/include",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-
- deps = [
- "//third_party/googleapis/google/firestore/v1beta1",
- "//third_party/googleapis/google/firestore/v1beta1:service",
- "//third_party/grpc:grpc++",
- ]
-}
diff --git a/bin/cloud_provider_firestore/firestore/testing/encoding.cc b/bin/cloud_provider_firestore/firestore/testing/encoding.cc
deleted file mode 100644
index 5962257..0000000
--- a/bin/cloud_provider_firestore/firestore/testing/encoding.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/firestore/testing/encoding.h"
-
-#include "peridot/bin/cloud_provider_firestore/firestore/encoding.h"
-
-namespace cloud_provider_firestore {
-
-namespace {
-// Must match |kTimestampKey| in
-// peridot/bin/cloud_provider_firestore/firestore/encoding.cc.
-constexpr char kTimestampKey[] = "timestamp";
-} // namespace
-
-bool EncodeCommitBatchWithTimestamp(
- const cloud_provider::CommitPack& commits, std::string timestamp,
- google::firestore::v1beta1::Document* document) {
- google::firestore::v1beta1::Document result;
- if (!EncodeCommitBatch(commits, &result)) {
- return false;
- }
-
- google::protobuf::Timestamp protobuf_timestamp;
- if (!protobuf_timestamp.ParseFromString(timestamp)) {
- return false;
- }
- google::firestore::v1beta1::Value& timestamp_value =
- (*result.mutable_fields())[kTimestampKey];
- *(timestamp_value.mutable_timestamp_value()) = std::move(protobuf_timestamp);
-
- document->Swap(&result);
- return true;
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/firestore/testing/encoding.h b/bin/cloud_provider_firestore/firestore/testing/encoding.h
deleted file mode 100644
index e33b265..0000000
--- a/bin/cloud_provider_firestore/firestore/testing/encoding.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_TESTING_ENCODING_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_TESTING_ENCODING_H_
-
-#include <string>
-
-#include <google/firestore/v1beta1/document.pb.h>
-#include <lib/fidl/cpp/vector.h>
-
-#include "peridot/bin/cloud_provider_firestore/include/types.h"
-
-namespace cloud_provider_firestore {
-
-// Encodes a batch of commits along with the givem timestamp.
-//
-// The resulting Document matches what the server returns from queries: the
-// given timestamp appears as the server-set timestamp.
-//
-// |timestamp| must be a valid serialized protobuf::Timestamp.
-bool EncodeCommitBatchWithTimestamp(
- const cloud_provider::CommitPack& commits, std::string timestamp,
- google::firestore::v1beta1::Document* document);
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_TESTING_ENCODING_H_
diff --git a/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.cc b/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.cc
deleted file mode 100644
index 982e9bc..0000000
--- a/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.h"
-
-#include <lib/fit/function.h>
-
-namespace cloud_provider_firestore {
-
-namespace {
-class TestListenCallHandler : public ListenCallHandler {
- public:
- TestListenCallHandler() {}
-
- ~TestListenCallHandler() override {}
-
- void Write(google::firestore::v1beta1::ListenRequest /*request*/) override {
- // do nothing
- }
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(TestListenCallHandler);
-};
-
-} // namespace
-
-TestFirestoreService::TestFirestoreService() : db_path_(), root_path_() {}
-TestFirestoreService::~TestFirestoreService() {}
-
-const std::string& TestFirestoreService::GetDatabasePath() { return db_path_; }
-
-const std::string& TestFirestoreService::GetRootPath() { return root_path_; }
-
-void TestFirestoreService::GetDocument(
- google::firestore::v1beta1::GetDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> /*call_credentials*/,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) {
- FXL_DCHECK(!shutdown_callback);
- get_document_records.push_back({std::move(request), std::move(callback)});
-}
-
-void TestFirestoreService::ListDocuments(
- google::firestore::v1beta1::ListDocumentsRequest request,
- std::shared_ptr<grpc::CallCredentials> /*call_credentials*/,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::ListDocumentsResponse)>
- callback) {
- FXL_DCHECK(!shutdown_callback);
- list_documents_records.push_back({std::move(request), std::move(callback)});
-}
-
-void TestFirestoreService::CreateDocument(
- google::firestore::v1beta1::CreateDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> /*call_credentials*/,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) {
- FXL_DCHECK(!shutdown_callback);
- create_document_records.push_back({std::move(request), std::move(callback)});
-}
-
-void TestFirestoreService::DeleteDocument(
- google::firestore::v1beta1::DeleteDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> /*call_credentials*/,
- fit::function<void(grpc::Status)> callback) {
- FXL_DCHECK(!shutdown_callback);
- delete_document_records.push_back({std::move(request), std::move(callback)});
-}
-
-void TestFirestoreService::RunQuery(
- google::firestore::v1beta1::RunQueryRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<
- void(grpc::Status,
- std::vector<google::firestore::v1beta1::RunQueryResponse>)>
- callback) {
- FXL_DCHECK(!shutdown_callback);
- run_query_records.push_back({std::move(request), std::move(callback)});
-}
-
-void TestFirestoreService::Commit(
- google::firestore::v1beta1::CommitRequest request,
- std::shared_ptr<grpc::CallCredentials> /*call_credentials*/,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::CommitResponse)>
- callback) {
- FXL_DCHECK(!shutdown_callback);
- commit_records.push_back({std::move(request), std::move(callback)});
-}
-
-std::unique_ptr<ListenCallHandler> TestFirestoreService::Listen(
- std::shared_ptr<grpc::CallCredentials> /*call_credentials*/,
- ListenCallClient* client) {
- FXL_DCHECK(!shutdown_callback);
- listen_clients.push_back(client);
- return std::make_unique<TestListenCallHandler>();
-}
-
-void TestFirestoreService::ShutDown(fit::closure callback) {
- FXL_DCHECK(!shutdown_callback);
- shutdown_callback = std::move(callback);
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.h b/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.h
deleted file mode 100644
index 977d32d..0000000
--- a/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_TESTING_TEST_FIRESTORE_SERVICE_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_TESTING_TEST_FIRESTORE_SERVICE_H_
-
-#include <string>
-
-#include <google/firestore/v1beta1/document.pb.h>
-#include <google/firestore/v1beta1/firestore.grpc.pb.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/cloud_provider_firestore/firestore/firestore_service.h"
-
-namespace cloud_provider_firestore {
-
-struct GetDocumentRecord {
- google::firestore::v1beta1::GetDocumentRequest request;
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback;
-};
-
-struct ListDocumentsRecord {
- google::firestore::v1beta1::ListDocumentsRequest request;
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::ListDocumentsResponse)>
- callback;
-};
-
-struct CreateDocumentRecord {
- google::firestore::v1beta1::CreateDocumentRequest request;
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback;
-};
-
-struct DeleteDocumentRecord {
- google::firestore::v1beta1::DeleteDocumentRequest request;
- fit::function<void(grpc::Status)> callback;
-};
-
-struct CommitRecord {
- google::firestore::v1beta1::CommitRequest request;
- fit::function<void(grpc::Status, google::firestore::v1beta1::CommitResponse)>
- callback;
-};
-
-struct RunQueryRecord {
- google::firestore::v1beta1::RunQueryRequest request;
- fit::function<void(grpc::Status,
- std::vector<google::firestore::v1beta1::RunQueryResponse>)>
- callback;
-};
-
-class TestFirestoreService : public FirestoreService {
- public:
- TestFirestoreService();
- ~TestFirestoreService() override;
-
- // FirestoreService:
- const std::string& GetDatabasePath() override;
-
- const std::string& GetRootPath() override;
-
- void GetDocument(
- google::firestore::v1beta1::GetDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) override;
-
- void ListDocuments(
- google::firestore::v1beta1::ListDocumentsRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::ListDocumentsResponse)>
- callback) override;
-
- void CreateDocument(
- google::firestore::v1beta1::CreateDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status, google::firestore::v1beta1::Document)>
- callback) override;
-
- void DeleteDocument(google::firestore::v1beta1::DeleteDocumentRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status)> callback) override;
-
- void RunQuery(google::firestore::v1beta1::RunQueryRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(
- grpc::Status,
- std::vector<google::firestore::v1beta1::RunQueryResponse>)>
- callback) override;
-
- void Commit(google::firestore::v1beta1::CommitRequest request,
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- fit::function<void(grpc::Status,
- google::firestore::v1beta1::CommitResponse)>
- callback) override;
-
- std::unique_ptr<ListenCallHandler> Listen(
- std::shared_ptr<grpc::CallCredentials> call_credentials,
- ListenCallClient* client) override;
-
- void ShutDown(fit::closure callback) override;
-
- std::vector<GetDocumentRecord> get_document_records;
- std::vector<ListDocumentsRecord> list_documents_records;
- std::vector<CreateDocumentRecord> create_document_records;
- std::vector<DeleteDocumentRecord> delete_document_records;
- std::vector<CommitRecord> commit_records;
- std::vector<RunQueryRecord> run_query_records;
- std::vector<ListenCallClient*> listen_clients;
-
- fit::closure shutdown_callback;
-
- private:
- const std::string db_path_;
- const std::string root_path_;
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_TESTING_TEST_FIRESTORE_SERVICE_H_
diff --git a/bin/cloud_provider_firestore/grpc/BUILD.gn b/bin/cloud_provider_firestore/grpc/BUILD.gn
deleted file mode 100644
index 2e5c5cd..0000000
--- a/bin/cloud_provider_firestore/grpc/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/cloud_provider_firestore/*" ]
-
-source_set("grpc") {
- sources = [
- "read_stream_drainer.h",
- "stream_controller.h",
- "stream_reader.h",
- "stream_writer.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//third_party/grpc:grpc++",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "read_stream_drainer_unittest.cc",
- ]
-
- deps = [
- ":grpc",
- "//garnet/public/lib/callback",
- "//third_party/googletest:gtest",
- "//third_party/grpc:grpc++",
- ]
-}
diff --git a/bin/cloud_provider_firestore/grpc/read_stream_drainer.h b/bin/cloud_provider_firestore/grpc/read_stream_drainer.h
deleted file mode 100644
index 190a6df..0000000
--- a/bin/cloud_provider_firestore/grpc/read_stream_drainer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_READ_STREAM_DRAINER_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_READ_STREAM_DRAINER_H_
-
-#include <functional>
-#include <memory>
-#include <vector>
-
-#include <grpc++/grpc++.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/cloud_provider_firestore/grpc/stream_controller.h"
-#include "peridot/bin/cloud_provider_firestore/grpc/stream_reader.h"
-
-namespace cloud_provider_firestore {
-
-// Utility which can drain a read-only grpc::Stream and return the messages.
-//
-// |GrpcStream| template type can be any class inheriting from
-// grpc::internal::AsyncReaderInterface.
-template <typename GrpcStream, typename Message>
-class ReadStreamDrainer {
- public:
- // Creates a new instance.
- ReadStreamDrainer(std::unique_ptr<grpc::ClientContext> context,
- std::unique_ptr<GrpcStream> stream)
- : context_(std::move(context)),
- stream_(std::move(stream)),
- stream_controller_(stream_.get()),
- stream_reader_(stream_.get()) {}
- ~ReadStreamDrainer() {}
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
-
- // Reads messages from the stream until there is no more messages to read and
- // returns all the messages to the caller.
- //
- // Can be called at most once.
- void Drain(fit::function<void(grpc::Status, std::vector<Message>)> callback) {
- FXL_DCHECK(!callback_);
- callback_ = std::move(callback);
- stream_controller_.StartCall([this](bool ok) {
- if (!ok) {
- Finish();
- return;
- }
-
- OnConnected();
- });
- }
-
- private:
- void OnConnected() {
- // Configure the stream reader.
- stream_reader_.SetOnError([this] { Finish(); });
- stream_reader_.SetOnMessage([this](Message message) {
- messages_.push_back(std::move(message));
- stream_reader_.Read();
- });
-
- // Start reading.
- stream_reader_.Read();
- }
-
- void Finish() {
- stream_controller_.Finish([this](bool ok, grpc::Status status) {
- if (status.ok()) {
- callback_(status, std::move(messages_));
- } else {
- callback_(status, std::vector<Message>{});
- }
-
- if (on_empty_) {
- on_empty_();
- }
- });
- }
-
- // Context used to make the remote call.
- std::unique_ptr<grpc::ClientContext> context_;
-
- // gRPC stream handler.
- std::unique_ptr<GrpcStream> stream_;
-
- StreamController<GrpcStream> stream_controller_;
- StreamReader<GrpcStream, Message> stream_reader_;
-
- fit::closure on_empty_;
- std::vector<Message> messages_;
- fit::function<void(grpc::Status, std::vector<Message>)> callback_;
- FXL_DISALLOW_COPY_AND_ASSIGN(ReadStreamDrainer);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_READ_STREAM_DRAINER_H_
diff --git a/bin/cloud_provider_firestore/grpc/read_stream_drainer_unittest.cc b/bin/cloud_provider_firestore/grpc/read_stream_drainer_unittest.cc
deleted file mode 100644
index 2543904..0000000
--- a/bin/cloud_provider_firestore/grpc/read_stream_drainer_unittest.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/grpc/read_stream_drainer.h"
-
-#include <functional>
-#include <vector>
-
-#include <grpc++/grpc++.h>
-#include <grpc++/support/async_stream.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-
-namespace cloud_provider_firestore {
-namespace {
-
-using IntegerStream = grpc::ClientAsyncReaderInterface<int>;
-
-class TestIntegerStream : public IntegerStream {
- public:
- TestIntegerStream() {}
- ~TestIntegerStream() override {}
-
- // IntegerStream:
- void StartCall(void* tag) override {
- connect_tag = static_cast<fit::function<void(bool)>*>(tag);
- }
- void ReadInitialMetadata(void* /*tag*/) override {}
- void Read(int* message, void* tag) override {
- message_ptr = message;
- read_tag = static_cast<fit::function<void(bool)>*>(tag);
- }
- void Finish(grpc::Status* status, void* tag) override {
- status_ptr = status;
- finish_tag = static_cast<fit::function<void(bool)>*>(tag);
- }
-
- fit::function<void(bool)>* connect_tag = nullptr;
- fit::function<void(bool)>* read_tag = nullptr;
- fit::function<void(bool)>* finish_tag = nullptr;
-
- int* message_ptr = nullptr;
- grpc::Status* status_ptr = nullptr;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(TestIntegerStream);
-};
-
-class ReadStreamDrainerTest : public ::testing::Test {
- public:
- ReadStreamDrainerTest() {
- auto stream = std::make_unique<TestIntegerStream>();
- auto context = std::make_unique<grpc::ClientContext>();
- stream_ = stream.get();
- drainer_ = std::make_unique<ReadStreamDrainer<IntegerStream, int>>(
- std::move(context), std::move(stream));
- drainer_->set_on_empty([this] { on_empty_calls_++; });
- }
- ~ReadStreamDrainerTest() override {}
-
- protected:
- TestIntegerStream* stream_;
- std::unique_ptr<ReadStreamDrainer<IntegerStream, int>> drainer_;
-
- int on_empty_calls_ = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(ReadStreamDrainerTest);
-};
-
-TEST_F(ReadStreamDrainerTest, ConnectionError) {
- bool called = false;
- grpc::Status status;
- std::vector<int> result;
- drainer_->Drain(
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- (*stream_->connect_tag)(false);
- (*stream_->status_ptr) = grpc::Status(grpc::StatusCode::INTERNAL, "");
- EXPECT_FALSE(called);
- (*stream_->finish_tag)(true);
-
- EXPECT_TRUE(called);
- EXPECT_FALSE(status.ok());
- EXPECT_EQ(grpc::StatusCode::INTERNAL, status.error_code());
- EXPECT_TRUE(result.empty());
-}
-
-TEST_F(ReadStreamDrainerTest, Ok) {
- bool called = false;
- grpc::Status status;
- std::vector<int> result;
- drainer_->Drain(
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- (*stream_->connect_tag)(true);
- (*stream_->message_ptr) = 1;
- (*stream_->read_tag)(true);
- (*stream_->message_ptr) = 2;
- (*stream_->read_tag)(true);
- // Signal that there is no more messages to read.
- (*stream_->read_tag)(false);
- (*stream_->status_ptr) = grpc::Status::OK;
- EXPECT_FALSE(called);
- (*stream_->finish_tag)(true);
-
- EXPECT_TRUE(called);
- EXPECT_TRUE(status.ok());
- EXPECT_EQ((std::vector<int>{1, 2}), result);
-}
-
-} // namespace
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/grpc/stream_controller.h b/bin/cloud_provider_firestore/grpc/stream_controller.h
deleted file mode 100644
index eaab227..0000000
--- a/bin/cloud_provider_firestore/grpc/stream_controller.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_CONTROLLER_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_CONTROLLER_H_
-
-#include <functional>
-
-#include <grpc++/grpc++.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-namespace cloud_provider_firestore {
-
-// Handler common for all gRPC streams.
-//
-// |GrpcStream| template type can be any class inheriting from
-// grpc::internal::ClientAsyncStreamingInterface.
-template <typename GrpcStream>
-class StreamController {
- public:
- StreamController(GrpcStream* grpc_stream) : grpc_stream_(grpc_stream) {
- FXL_DCHECK(grpc_stream_);
- }
-
- ~StreamController() {
- // The class cannot go away while completion queue operations are pending,
- // as they reference member function objects as operation tags.
- FXL_DCHECK(pending_cq_operations_ == 0);
- }
-
- bool IsEmpty() const { return pending_cq_operations_ == 0; }
-
- // Attempts to start the stream.
- void StartCall(fit::function<void(bool)> callback) {
- on_connected_ = [this, callback = std::move(callback)](bool ok) {
- pending_cq_operations_--;
- callback(ok);
- };
-
- pending_cq_operations_++;
- grpc_stream_->StartCall(&on_connected_);
- }
-
- // Attempts to finish the stream and read the final status.
- //
- // Note that calling Finish() by itself does *not* make any pending read/write
- // operations fail early. For that, call TryCancel() on the associated client
- // context.
- void Finish(fit::function<void(bool, grpc::Status)> callback) {
- on_finish_ = [this, callback = std::move(callback)](bool ok) {
- pending_cq_operations_--;
- callback(ok, status_);
- };
-
- pending_cq_operations_++;
- grpc_stream_->Finish(&status_, &on_finish_);
- }
-
- private:
- // gRPC stream handler.
- GrpcStream* const grpc_stream_;
-
- // Count of pending async tasks posted on the completion queue.
- int pending_cq_operations_ = 0;
-
- // Callables posted as CompletionQueue tags:
- fit::function<void(bool)> on_connected_;
- fit::function<void(bool)> on_finish_;
-
- // Final status of the stream set by the server.
- grpc::Status status_;
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_CONTROLLER_H_
diff --git a/bin/cloud_provider_firestore/grpc/stream_reader.h b/bin/cloud_provider_firestore/grpc/stream_reader.h
deleted file mode 100644
index 83a620f..0000000
--- a/bin/cloud_provider_firestore/grpc/stream_reader.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_READER_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_READER_H_
-
-#include <functional>
-
-#include <grpc++/grpc++.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-namespace cloud_provider_firestore {
-
-// Handler for gRPC read streams.
-//
-// |GrpcStream| template type can be any class inheriting from
-// grpc::internal::AsyncReaderInterface.
-template <typename GrpcStream, typename Message>
-class StreamReader {
- public:
- StreamReader(GrpcStream* grpc_stream) : grpc_stream_(grpc_stream) {
- FXL_DCHECK(grpc_stream_);
-
- on_read_ = [this](bool ok) {
- read_is_pending_ = false;
- OnRead(ok);
- };
- }
-
- ~StreamReader() {
- // The class cannot go away while completion queue operations are pending,
- // as they reference member function objects as operation tags.
- FXL_DCHECK(!read_is_pending_);
- }
-
- bool IsEmpty() const { return !read_is_pending_; }
-
- // Sets a callback which is called when a read operation fails.
- //
- // This error is unrecoverable and means that there is no more messages to
- // read or that the connection is broken.
- void SetOnError(fit::function<void()> on_error) {
- FXL_DCHECK(on_error);
- on_error_ = std::move(on_error);
- }
-
- // Sets a callback which is called each time a message is read.
- void SetOnMessage(fit::function<void(Message)> on_message) {
- FXL_DCHECK(on_message);
- on_message_ = std::move(on_message);
- }
-
- // Attempts to read a message from the stream.
- //
- // SetOnError() and SetOnMessage() must be called before calling Read() for
- // the first time.
- //
- // Cannot be called while another read is already pending.
- void Read() {
- FXL_DCHECK(on_error_);
- FXL_DCHECK(on_message_);
-
- FXL_DCHECK(!read_is_pending_);
- read_is_pending_ = true;
- grpc_stream_->Read(&message_, &on_read_);
- }
-
- private:
- void OnRead(bool ok) {
- if (!ok) {
- // This can mean an unrecoverable connection error or be part of a regular
- // shutdown sequence: OnRead with ok = false is called after the client
- // calls TryCancel() to abort the RPC.
- on_error_();
- return;
- }
-
- on_message_(std::move(message_));
- }
-
- // gRPC stream handler.
- GrpcStream* const grpc_stream_;
-
- // Whether a read operation is currently in progress.
- bool read_is_pending_ = false;
-
- // Callables posted as CompletionQueue tags:
- fit::function<void(bool)> on_read_;
-
- // Internal callables not posted on CompletionQueue:
- fit::function<void()> on_error_;
- fit::function<void(Message)> on_message_;
-
- Message message_;
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_READER_H_
diff --git a/bin/cloud_provider_firestore/grpc/stream_writer.h b/bin/cloud_provider_firestore/grpc/stream_writer.h
deleted file mode 100644
index 087791a..0000000
--- a/bin/cloud_provider_firestore/grpc/stream_writer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_WRITER_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_WRITER_H_
-
-#include <functional>
-
-#include <grpc++/grpc++.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-namespace cloud_provider_firestore {
-
-// Handler for gRPC write streams.
-//
-// |GrpcStream| template type can be any class inheriting from
-// grpc::internal::AsyncWriterInterface<Message>.
-template <typename GrpcStream, typename Message>
-class StreamWriter {
- public:
- StreamWriter(GrpcStream* grpc_stream) : grpc_stream_(grpc_stream) {
- FXL_DCHECK(grpc_stream_);
-
- on_write_ = [this](bool ok) {
- write_is_pending_ = false;
- OnWrite(ok);
- };
- }
-
- ~StreamWriter() {
- // The class cannot go away while completion queue operations are pending,
- // as they reference member function objects as operation tags.
- FXL_DCHECK(!write_is_pending_);
- }
-
- bool IsEmpty() const { return !write_is_pending_; }
-
- // Sets a callback which is called when a write operation fails.
- //
- // This error is unrecoverable and means that the write call cannot be made
- // because the connection is broken.
- void SetOnError(fit::function<void()> on_error) {
- on_error_ = std::move(on_error);
- }
-
- // Sets a callback which is called when a write operation succeeds.
- void SetOnSuccess(fit::function<void()> on_success) {
- on_success_ = std::move(on_success);
- }
-
- // Attempts to write a message to the stream.
- //
- // SetOnError() and SetOnSuccess() must be called before calling Read() for
- // the first time.
- //
- // Cannot be called while another write is already pending.
- void Write(Message message) {
- FXL_DCHECK(on_error_);
- FXL_DCHECK(on_success_);
-
- FXL_DCHECK(!write_is_pending_);
- write_is_pending_ = true;
- grpc_stream_->Write(message, &on_write_);
- }
-
- private:
- void OnWrite(bool ok) {
- if (!ok) {
- // This can mean an unrecoverable connection error or be part of a regular
- // shutdown sequence: OnWrite with ok = false is called if the client
- // calls TryCancel() to abort the RPC after a Write request was made.
- on_error_();
- return;
- }
-
- on_success_();
- }
-
- // gRPC stream handler.
- GrpcStream* const grpc_stream_;
-
- // Whether a write operation is currently in progress.
- bool write_is_pending_ = false;
-
- // Callables posted as CompletionQueue tags:
- fit::function<void(bool)> on_write_;
-
- // Internal callables not posted on CompletionQueue:
- fit::function<void()> on_error_;
- fit::function<void()> on_success_;
-
- // Final status of the stream set by the server.
- grpc::Status status_;
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_GRPC_STREAM_WRITER_H_
diff --git a/bin/cloud_provider_firestore/include/BUILD.gn b/bin/cloud_provider_firestore/include/BUILD.gn
deleted file mode 100644
index 313ce1a..0000000
--- a/bin/cloud_provider_firestore/include/BUILD.gn
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/cloud_provider_firestore/*" ]
-
-source_set("include") {
- sources = [
- "types.h",
- ]
-
- public_deps = [
- "//peridot/bin/cloud_provider_firestore/fidl",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-}
diff --git a/bin/cloud_provider_firestore/include/types.h b/bin/cloud_provider_firestore/include/types.h
deleted file mode 100644
index 2d4f23b..0000000
--- a/bin/cloud_provider_firestore/include/types.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_INCLUDE_TYPES_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_INCLUDE_TYPES_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/ledger/cloud/firestore/cpp/fidl.h>
-
-// More convenient aliases for FIDL types.
-
-namespace cloud_provider {
-using CloudProvider = fuchsia::ledger::cloud::CloudProvider;
-using CloudProviderPtr = fuchsia::ledger::cloud::CloudProviderPtr;
-using CommitPack = fuchsia::ledger::cloud::CommitPack;
-using DeviceSet = fuchsia::ledger::cloud::DeviceSet;
-using DeviceSetPtr = fuchsia::ledger::cloud::DeviceSetPtr;
-using DeviceSetWatcher = fuchsia::ledger::cloud::DeviceSetWatcher;
-using DeviceSetWatcherPtr = fuchsia::ledger::cloud::DeviceSetWatcherPtr;
-using PageCloud = fuchsia::ledger::cloud::PageCloud;
-using PageCloudPtr = fuchsia::ledger::cloud::PageCloudPtr;
-using PageCloudWatcher = fuchsia::ledger::cloud::PageCloudWatcher;
-using PageCloudWatcherPtr = fuchsia::ledger::cloud::PageCloudWatcherPtr;
-using Status = fuchsia::ledger::cloud::Status;
-using Token = fuchsia::ledger::cloud::Token;
-} // namespace cloud_provider
-
-namespace cloud_provider_firestore {
-using Config = fuchsia::ledger::cloud::firestore::Config;
-using Factory = fuchsia::ledger::cloud::firestore::Factory;
-using FactoryPtr = fuchsia::ledger::cloud::firestore::FactoryPtr;
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_INCLUDE_TYPES_H_
diff --git a/bin/cloud_provider_firestore/testing/BUILD.gn b/bin/cloud_provider_firestore/testing/BUILD.gn
deleted file mode 100644
index d97f2a4..0000000
--- a/bin/cloud_provider_firestore/testing/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- "//peridot/bin/*",
- "//peridot/lib/*",
-]
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "cloud_provider_factory.cc",
- "cloud_provider_factory.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//peridot/bin/cloud_provider_firestore/fidl",
- "//peridot/bin/cloud_provider_firestore/include",
- "//peridot/lib/convert",
- "//peridot/lib/firebase_auth/testing:service_account_provider",
- "//peridot/lib/rng",
- "//peridot/lib/rng:system",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//zircon/public/lib/async-loop-cpp",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- ]
-}
diff --git a/bin/cloud_provider_firestore/testing/cloud_provider_factory.cc b/bin/cloud_provider_firestore/testing/cloud_provider_factory.cc
deleted file mode 100644
index 0fc71fa..0000000
--- a/bin/cloud_provider_firestore/testing/cloud_provider_factory.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/cloud_provider_firestore/testing/cloud_provider_factory.h"
-
-#include <utility>
-
-#include <fuchsia/net/oldhttp/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/svc/cpp/services.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_provider_firestore {
-namespace {
-namespace http = ::fuchsia::net::oldhttp;
-
-constexpr char kAppUrl[] =
- "fuchsia-pkg://fuchsia.com/cloud_provider_firestore"
- "#meta/cloud_provider_firestore.cmx";
-
-std::string GenerateUserId() {
- // Always use a real random generator for user ids.
- rng::SystemRandom system_random;
- return convert::ToHex(system_random.RandomUniqueBytes());
-}
-
-} // namespace
-
-CloudProviderFactory::UserId::UserId(const UserId& user_id) = default;
-
-CloudProviderFactory::UserId::UserId(UserId&& user_id) = default;
-
-CloudProviderFactory::UserId& CloudProviderFactory::UserId::operator=(
- const UserId& user_id) = default;
-
-CloudProviderFactory::UserId& CloudProviderFactory::UserId::operator=(
- UserId&& user_id) = default;
-
-CloudProviderFactory::UserId CloudProviderFactory::UserId::New() {
- return UserId();
-}
-
-CloudProviderFactory::UserId::UserId() : user_id_(GenerateUserId()) {}
-
-class CloudProviderFactory::TokenManagerContainer {
- public:
- TokenManagerContainer(
- component::StartupContext* startup_context,
- async_dispatcher_t* dispatcher, rng::Random* random,
- std::unique_ptr<service_account::Credentials> credentials,
- std::string user_id,
- fidl::InterfaceRequest<fuchsia::auth::TokenManager> request)
- : startup_context_(startup_context),
- network_wrapper_(
- dispatcher,
- std::make_unique<backoff::ExponentialBackoff>(
- random->NewBitGenerator<uint64_t>()),
- [this] {
- return startup_context_
- ->ConnectToEnvironmentService<http::HttpService>();
- }),
- token_manager_(&network_wrapper_, std::move(credentials),
- std::move(user_id)),
- binding_(&token_manager_, std::move(request)) {}
-
- void set_on_empty(fit::closure on_empty) {
- binding_.set_error_handler(
- [on_empty = std::move(on_empty)](zx_status_t status) { on_empty(); });
- }
-
- private:
- component::StartupContext* const startup_context_;
- network_wrapper::NetworkWrapperImpl network_wrapper_;
- service_account::ServiceAccountTokenManager token_manager_;
- fidl::Binding<fuchsia::auth::TokenManager> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TokenManagerContainer);
-};
-
-CloudProviderFactory::CloudProviderFactory(
- component::StartupContext* startup_context, rng::Random* random,
- std::string api_key,
- std::unique_ptr<service_account::Credentials> credentials)
- : startup_context_(startup_context),
- random_(random),
- api_key_(std::move(api_key)),
- credentials_(std::move(credentials)),
- services_loop_(&kAsyncLoopConfigNoAttachToThread) {
- FXL_DCHECK(startup_context);
- FXL_DCHECK(!api_key_.empty());
-}
-
-CloudProviderFactory::~CloudProviderFactory() { services_loop_.Shutdown(); }
-
-void CloudProviderFactory::Init() {
- services_loop_.StartThread();
- component::Services child_services;
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = kAppUrl;
- launch_info.directory_request = child_services.NewRequest();
- startup_context_->launcher()->CreateComponent(
- std::move(launch_info), cloud_provider_controller_.NewRequest());
- child_services.ConnectToService(cloud_provider_factory_.NewRequest());
-}
-
-void CloudProviderFactory::MakeCloudProvider(
- UserId user_id,
- fidl::InterfaceRequest<cloud_provider::CloudProvider> request) {
- fuchsia::auth::TokenManagerPtr token_manager;
- MakeTokenManager(std::move(user_id), token_manager.NewRequest());
-
- cloud_provider_firestore::Config firebase_config;
- firebase_config.server_id = credentials_->project_id();
- firebase_config.api_key = api_key_;
-
- cloud_provider_factory_->GetCloudProvider(
- std::move(firebase_config), std::move(token_manager), std::move(request),
- [](cloud_provider::Status status) {
- if (status != cloud_provider::Status::OK) {
- FXL_LOG(ERROR) << "Failed to create a cloud provider: "
- << fidl::ToUnderlying(status);
- }
- });
-}
-
-void CloudProviderFactory::MakeTokenManager(
- UserId user_id,
- fidl::InterfaceRequest<fuchsia::auth::TokenManager> request) {
- async::PostTask(services_loop_.dispatcher(),
- fxl::MakeCopyable([this, user_id = std::move(user_id),
- request = std::move(request)]() mutable {
- token_managers_.emplace(
- startup_context_, services_loop_.dispatcher(), random_,
- credentials_->Clone(), std::move(user_id.user_id()),
- std::move(request));
- }));
-}
-
-} // namespace cloud_provider_firestore
diff --git a/bin/cloud_provider_firestore/testing/cloud_provider_factory.h b/bin/cloud_provider_firestore/testing/cloud_provider_factory.h
deleted file mode 100644
index eab1814..0000000
--- a/bin/cloud_provider_firestore/testing/cloud_provider_factory.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_TESTING_CLOUD_PROVIDER_FACTORY_H_
-#define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_TESTING_CLOUD_PROVIDER_FACTORY_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/ledger/cloud/firestore/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/network_wrapper/network_wrapper_impl.h>
-
-#include "peridot/bin/cloud_provider_firestore/include/types.h"
-#include "peridot/lib/firebase_auth/testing/credentials.h"
-#include "peridot/lib/firebase_auth/testing/service_account_token_manager.h"
-#include "peridot/lib/rng/random.h"
-#include "peridot/lib/rng/system_random.h"
-
-namespace cloud_provider_firestore {
-
-// Factory for real Firestore cloud provider binaries backed by fake token
-// provider.
-//
-// This is used for end-to-end testing, including the validation test suite for
-// the cloud provider.
-class CloudProviderFactory {
- public:
- // Opaque container for user id.
- class UserId {
- public:
- UserId(const UserId& user_id);
- UserId(UserId&& user_id);
- UserId& operator=(const UserId& user_id);
- UserId& operator=(UserId&& user_id);
-
- static UserId New();
-
- const std::string& user_id() const { return user_id_; }
-
- private:
- UserId();
-
- std::string user_id_;
- };
-
- CloudProviderFactory(
- component::StartupContext* startup_context, rng::Random* random,
- std::string api_key,
- std::unique_ptr<service_account::Credentials> credentials);
- ~CloudProviderFactory();
-
- void Init();
-
- void MakeCloudProvider(
- UserId user_id,
- fidl::InterfaceRequest<cloud_provider::CloudProvider> request);
-
- void MakeTokenManager(
- UserId user_id,
- fidl::InterfaceRequest<fuchsia::auth::TokenManager> request);
-
- private:
- class TokenManagerContainer;
- component::StartupContext* const startup_context_;
- rng::Random* const random_;
- const std::string api_key_;
- std::unique_ptr<service_account::Credentials> credentials_;
-
- // Loop on which the token manager runs.
- async::Loop services_loop_;
-
- callback::AutoCleanableSet<TokenManagerContainer> token_managers_;
-
- fuchsia::sys::ComponentControllerPtr cloud_provider_controller_;
- FactoryPtr cloud_provider_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(CloudProviderFactory);
-};
-
-} // namespace cloud_provider_firestore
-
-#endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_TESTING_CLOUD_PROVIDER_FACTORY_H_
diff --git a/bin/cloud_provider_firestore/validation/BUILD.gn b/bin/cloud_provider_firestore/validation/BUILD.gn
deleted file mode 100644
index 3f7b059..0000000
--- a/bin/cloud_provider_firestore/validation/BUILD.gn
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/cloud_provider_firestore/*" ]
-
-executable("validation") {
- output_name = "launch_validation_tests_firestore"
- testonly = true
-
- sources = [
- "app.cc",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/cloud_provider_firestore/include",
- "//peridot/bin/cloud_provider_firestore/testing",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/bin/ledger/tests/cloud_provider/launcher",
- "//peridot/lib/rng:system",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
diff --git a/bin/cloud_provider_firestore/validation/app.cc b/bin/cloud_provider_firestore/validation/app.cc
deleted file mode 100644
index 82c90d0..0000000
--- a/bin/cloud_provider_firestore/validation/app.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/concatenate.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/cloud_provider_firestore/include/types.h"
-#include "peridot/bin/cloud_provider_firestore/testing/cloud_provider_factory.h"
-#include "peridot/bin/ledger/testing/sync_params.h"
-#include "peridot/bin/ledger/tests/cloud_provider/launcher/validation_tests_launcher.h"
-#include "peridot/lib/rng/system_random.h"
-
-namespace cloud_provider_firestore {
-void PrintUsage(const char* executable_name) {
- std::cerr << "Usage: "
- << executable_name
- // Comment to make clang format not break formatting.
- << ledger::GetSyncParamsUsage();
-}
-
-} // namespace cloud_provider_firestore
-
-int main(int argc, char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- std::unique_ptr<component::StartupContext> startup_context =
- component::StartupContext::CreateFromStartupInfo();
-
- ledger::SyncParams sync_params;
- if (!ledger::ParseSyncParamsFromCommandLine(
- command_line, startup_context.get(), &sync_params)) {
- cloud_provider_firestore::PrintUsage(argv[0]);
- return -1;
- }
-
- const std::set<std::string> known_options = ledger::GetSyncParamFlags();
- std::vector<std::string> arguments;
- for (auto& option : command_line.options()) {
- if (known_options.count(option.name) == 0u) {
- arguments.push_back(
- fxl::Concatenate({"--", option.name, "=", option.value}));
- }
- }
-
- rng::SystemRandom random;
-
- cloud_provider_firestore::CloudProviderFactory factory(
- startup_context.get(), &random, sync_params.api_key,
- sync_params.credentials->Clone());
-
- cloud_provider::ValidationTestsLauncher launcher(
- startup_context.get(), [&factory](auto request) {
- factory.MakeCloudProvider(
- cloud_provider_firestore::CloudProviderFactory::UserId::New(),
- std::move(request));
- });
-
- int32_t return_code = -1;
- async::PostTask(loop.dispatcher(), [&factory, &launcher, &return_code, &loop,
- arguments = std::move(arguments)] {
- factory.Init();
-
- launcher.Run(arguments, [&return_code, &loop](int32_t result) {
- return_code = result;
- loop.Quit();
- });
- });
- loop.Run();
- return return_code;
-}
diff --git a/bin/cloud_provider_firestore/validation/validation_firestore.cmx b/bin/cloud_provider_firestore/validation/validation_firestore.cmx
deleted file mode 100644
index 845e193..0000000
--- a/bin/cloud_provider_firestore/validation/validation_firestore.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "facets": {
- "fuchsia.test": {
- "injected-services": {
- "fuchsia.net.oldhttp.HttpService": "http"
- },
- "system-services": [
- "fuchsia.net.LegacySocketProvider",
- "fuchsia.netstack.Netstack",
- "fuchsia.net.stack.Stack"
- ]
- }
- },
- "program": {
- "binary": "test/disabled/launch_validation_tests_firestore"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/context_engine/BUILD.gn b/bin/context_engine/BUILD.gn
deleted file mode 100644
index 93cc674..0000000
--- a/bin/context_engine/BUILD.gn
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-import("//peridot/build/tests_package.gni")
-
-executable_package("context_engine") {
- meta = [
- {
- path = "meta/context_engine.cmx"
- dest = "context_engine.cmx"
- },
- ]
-
- sources = [
- "context_engine_main.cc",
- ]
-
- deps = [
- ":context_engine_impl",
- "//garnet/public/lib/component/cpp",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-hermetic_tests_package("context_engine_unittests") {
- deps = [
- ":context_index_unittest",
- ":context_repository_unittest",
- ]
-}
-
-source_set("context_index") {
- sources = [
- "index.cc",
- "index.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("context_index_unittest") {
- testonly = true
-
- sources = [
- "index_unittest.cc",
- ]
-
- deps = [
- ":context_index",
- "//garnet/public/lib/fsl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/context/cpp:context_helper",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("context_reader_impl") {
- sources = [
- "context_reader_impl.cc",
- "context_reader_impl.h",
- ]
-
- deps = [
- ":context_repository",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("context_repository") {
- sources = [
- "context_repository.cc",
- "context_repository.h",
- "debug.cc",
- "debug.h",
- ]
-
- public_deps = [
- "//peridot/lib/util:idle_waiter",
- ]
-
- deps = [
- ":context_index",
- "//garnet/public/lib/fsl",
- "//peridot/lib/bound_set",
- "//peridot/lib/rapidjson",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular",
- "//third_party/rapidjson",
- ]
-}
-
-executable("context_repository_unittest") {
- testonly = true
-
- sources = [
- "context_repository_unittest.cc",
- ]
-
- deps = [
- ":context_repository",
- "//garnet/public/lib/fsl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/context/cpp:context_helper",
- "//peridot/public/lib/context/cpp:context_metadata_builder",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("context_writer_impl") {
- sources = [
- "context_writer_impl.cc",
- "context_writer_impl.h",
- ]
-
- deps = [
- ":context_repository",
- "//garnet/public/lib/fxl",
- "//peridot/lib/bound_set",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:future",
- "//peridot/public/lib/entity/cpp",
- "//peridot/public/lib/entity/cpp:json",
- "//third_party/rapidjson",
- ]
-}
-
-source_set("context_engine_impl") {
- sources = [
- "context_engine_impl.cc",
- "context_engine_impl.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- ]
-
- deps = [
- ":context_reader_impl",
- ":context_repository",
- ":context_writer_impl",
- "//garnet/public/lib/fidl/cpp",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("scope_utils") {
- sources = [
- "scope_utils.cc",
- "scope_utils.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/boringssl", # for sha256
- ]
-}
diff --git a/bin/context_engine/context_engine_impl.cc b/bin/context_engine/context_engine_impl.cc
deleted file mode 100644
index 21a6b5b..0000000
--- a/bin/context_engine/context_engine_impl.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/context_engine_impl.h"
-
-#include <lib/component/cpp/startup_context.h>
-
-#include "peridot/bin/context_engine/context_reader_impl.h"
-#include "peridot/bin/context_engine/context_repository.h"
-#include "peridot/bin/context_engine/context_writer_impl.h"
-
-namespace modular {
-
-ContextEngineImpl::ContextEngineImpl(
- fuchsia::modular::EntityResolver* const entity_resolver)
- : entity_resolver_(entity_resolver) {}
-ContextEngineImpl::~ContextEngineImpl() = default;
-
-fxl::WeakPtr<ContextDebugImpl> ContextEngineImpl::debug() {
- return repository_.debug()->GetWeakPtr();
-}
-
-void ContextEngineImpl::AddBinding(
- fidl::InterfaceRequest<fuchsia::modular::ContextEngine> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void ContextEngineImpl::GetWriter(
- fuchsia::modular::ComponentScope client_info,
- fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request) {
- writers_.emplace_back(std::make_unique<ContextWriterImpl>(
- std::move(client_info), &repository_, entity_resolver_,
- std::move(request)));
-}
-
-void ContextEngineImpl::GetReader(
- fuchsia::modular::ComponentScope client_info,
- fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) {
- readers_.emplace_back(std::make_unique<ContextReaderImpl>(
- std::move(client_info), &repository_, std::move(request)));
-}
-
-void ContextEngineImpl::GetContextDebug(
- fidl::InterfaceRequest<fuchsia::modular::ContextDebug> request) {
- repository_.AddDebugBinding(std::move(request));
-}
-
-} // namespace modular
diff --git a/bin/context_engine/context_engine_impl.h b/bin/context_engine/context_engine_impl.h
deleted file mode 100644
index f07d99a..0000000
--- a/bin/context_engine/context_engine_impl.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_ENGINE_IMPL_H_
-#define PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_ENGINE_IMPL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-
-#include "peridot/bin/context_engine/context_repository.h"
-#include "peridot/bin/context_engine/debug.h"
-
-namespace modular {
-
-class EntityResolver;
-
-class ContextReaderImpl;
-class ContextWriterImpl;
-
-class ContextEngineImpl : fuchsia::modular::ContextEngine {
- public:
- // Does not take ownership of |entity_resolver|.
- ContextEngineImpl(fuchsia::modular::EntityResolver* entity_resolver);
- ~ContextEngineImpl() override;
-
- void AddBinding(
- fidl::InterfaceRequest<fuchsia::modular::ContextEngine> request);
-
- fxl::WeakPtr<ContextDebugImpl> debug();
-
- private:
- // |fuchsia::modular::ContextEngine|
- void GetWriter(
- fuchsia::modular::ComponentScope client_info,
- fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request) override;
-
- // |fuchsia::modular::ContextEngine|
- void GetReader(
- fuchsia::modular::ComponentScope client_info,
- fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) override;
-
- // |fuchsia::modular::ContextEngine|
- void GetContextDebug(
- fidl::InterfaceRequest<fuchsia::modular::ContextDebug> request) override;
-
- fuchsia::modular::EntityResolver* const entity_resolver_;
-
- ContextRepository repository_;
-
- fidl::BindingSet<fuchsia::modular::ContextEngine> bindings_;
-
- std::vector<std::unique_ptr<ContextReaderImpl>> readers_;
- std::vector<std::unique_ptr<ContextWriterImpl>> writers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ContextEngineImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_ENGINE_IMPL_H_
diff --git a/bin/context_engine/context_engine_main.cc b/bin/context_engine/context_engine_main.cc
deleted file mode 100644
index 279aaef..0000000
--- a/bin/context_engine/context_engine_main.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding_set.h>
-
-#include "peridot/bin/context_engine/context_engine_impl.h"
-
-namespace modular {
-
-class ContextEngineApp {
- public:
- ContextEngineApp(component::StartupContext* const context) {
- auto component_context =
- context
- ->ConnectToEnvironmentService<fuchsia::modular::ComponentContext>();
- component_context->GetEntityResolver(entity_resolver_.NewRequest());
- context_engine_impl_ =
- std::make_unique<ContextEngineImpl>(entity_resolver_.get());
-
- context->outgoing().AddPublicService<fuchsia::modular::ContextEngine>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::ContextEngine> request) {
- context_engine_impl_->AddBinding(std::move(request));
- });
- }
-
- void Terminate(std::function<void()> done) { done(); }
-
- fxl::WeakPtr<ContextDebugImpl> debug() {
- return context_engine_impl_->debug();
- }
-
- private:
- fuchsia::modular::EntityResolverPtr entity_resolver_;
- std::unique_ptr<ContextEngineImpl> context_engine_impl_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ContextEngineApp);
-};
-
-} // namespace modular
-
-int main(int argc, const char** argv) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- auto context_engine_app =
- std::make_unique<modular::ContextEngineApp>(context.get());
- fxl::WeakPtr<modular::ContextDebugImpl> debug = context_engine_app->debug();
- debug->GetIdleWaiter()->SetLoop(&loop);
-
- modular::AppDriver<modular::ContextEngineApp> driver(
- context->outgoing().deprecated_services(), std::move(context_engine_app),
- [&loop] { loop.Quit(); });
-
- // The |WaitUntilIdle| debug functionality escapes the main message loop to
- // perform its test.
- do {
- loop.Run();
- loop.ResetQuit();
- } while (debug && debug->GetIdleWaiter()->FinishIdleCheck());
-
- return 0;
-}
diff --git a/bin/context_engine/context_reader_impl.cc b/bin/context_engine/context_reader_impl.cc
deleted file mode 100644
index 6056fe1..0000000
--- a/bin/context_engine/context_reader_impl.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/context_reader_impl.h"
-
-#include <lib/fidl/cpp/clone.h>
-
-#include "peridot/bin/context_engine/context_repository.h"
-
-namespace modular {
-
-ContextReaderImpl::ContextReaderImpl(
- fuchsia::modular::ComponentScope client_info, ContextRepository* repository,
- fidl::InterfaceRequest<fuchsia::modular::ContextReader> request)
- : binding_(this, std::move(request)), repository_(repository) {
- debug_.client_info = std::move(client_info);
-}
-
-ContextReaderImpl::~ContextReaderImpl() = default;
-
-void ContextReaderImpl::Subscribe(
- fuchsia::modular::ContextQuery query,
- fidl::InterfaceHandle<fuchsia::modular::ContextListener> listener) {
- auto listener_ptr = listener.Bind();
- fuchsia::modular::SubscriptionDebugInfo debug_info;
- fidl::Clone(debug_, &debug_info);
- repository_->AddSubscription(std::move(query), std::move(listener_ptr),
- std::move(debug_info));
-}
-
-void ContextReaderImpl::Get(fuchsia::modular::ContextQuery query,
- GetCallback callback) {
- callback(repository_->Query(query));
-}
-
-} // namespace modular
diff --git a/bin/context_engine/context_reader_impl.h b/bin/context_engine/context_reader_impl.h
deleted file mode 100644
index ba29626..0000000
--- a/bin/context_engine/context_reader_impl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be //
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_READER_IMPL_H_
-#define PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_READER_IMPL_H_
-
-#include <list>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-
-#include "peridot/bin/context_engine/context_repository.h"
-
-namespace modular {
-
-class ContextReaderImpl : fuchsia::modular::ContextReader {
- public:
- ContextReaderImpl(
- fuchsia::modular::ComponentScope client_info,
- ContextRepository* repository,
- fidl::InterfaceRequest<fuchsia::modular::ContextReader> request);
- ~ContextReaderImpl() override;
-
- private:
- // |fuchsia::modular::ContextReader|
- void Subscribe(fuchsia::modular::ContextQuery query,
- fidl::InterfaceHandle<fuchsia::modular::ContextListener>
- listener) override;
-
- // |fuchsia::modular::ContextReader|
- void Get(fuchsia::modular::ContextQuery query,
- fuchsia::modular::ContextReader::GetCallback callback) override;
-
- fidl::Binding<fuchsia::modular::ContextReader> binding_;
-
- fuchsia::modular::SubscriptionDebugInfo debug_;
- ContextRepository* const repository_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ContextReaderImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_READER_IMPL_H_
diff --git a/bin/context_engine/context_repository.cc b/bin/context_engine/context_repository.cc
deleted file mode 100644
index fb524f1..0000000
--- a/bin/context_engine/context_repository.cc
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/context_repository.h"
-
-#include <list>
-#include <memory>
-#include <set>
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fostr/fidl/fuchsia/modular/formatting.h>
-
-#include "peridot/bin/context_engine/debug.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "rapidjson/document.h"
-
-namespace modular {
-
-ContextGraph::ContextGraph() = default;
-
-ContextGraph::~ContextGraph() = default;
-
-void ContextGraph::AddEdge(const Id& from, const Id& to) {
- parents_[to].insert(from);
- children_[from].insert(to);
-}
-void ContextGraph::Remove(const Id& id) {
- auto parents = GetParents(id);
- for (const auto& parent : parents) {
- children_[parent].erase(id);
- }
- for (const auto& child : children_[id]) {
- parents_[child].erase(id);
- }
- // TODO(thatguy): Decide what to do about orphaned children.
- children_.erase(id);
- parents_.erase(id);
-}
-
-std::set<ContextGraph::Id> ContextGraph::GetParents(const Id& id) const {
- auto it = parents_.find(id);
- if (it == parents_.end())
- return {};
- return it->second;
-}
-
-std::set<ContextGraph::Id> ContextGraph::GetChildrenRecursive(
- const Id& id) const {
- std::set<Id> children;
- std::list<Id> to_visit{id};
-
- while (!to_visit.empty()) {
- auto cur = to_visit.front();
- to_visit.pop_front();
-
- auto it = children_.find(cur);
- if (it != children_.end()) {
- children.insert(it->second.begin(), it->second.end());
- to_visit.insert(to_visit.begin(), it->second.begin(), it->second.end());
- }
- }
-
- return children;
-}
-
-std::vector<ContextGraph::Id> ContextGraph::GetAncestors(const Id& id) const {
- std::vector<Id> ancestors;
- std::set<Id> visited;
- std::list<Id> to_visit;
-
- auto it = parents_.find(id);
- if (it == parents_.end())
- return ancestors;
- to_visit.insert(to_visit.begin(), it->second.begin(), it->second.end());
- while (!to_visit.empty()) {
- auto cur = to_visit.front();
- to_visit.pop_front();
- if (!visited.insert(cur).second)
- continue;
- ancestors.insert(ancestors.begin(), cur);
- it = parents_.find(cur);
- if (it != parents_.end()) {
- to_visit.insert(to_visit.end(), it->second.begin(), it->second.end());
- }
- }
- return ancestors;
-}
-
-namespace {
-
-ContextRepository::Id CreateValueId() {
- // TODO(thatguy): Prefer to use a string UUID.
- static uint32_t next_id = 0;
- return std::to_string(next_id++);
-}
-
-ContextRepository::Id CreateSubscriptionId() {
- static uint32_t next_id = 0;
- return std::to_string(next_id++);
-}
-
-void LogInvalidAncestorMetadata(const fuchsia::modular::ContextMetadata& from,
- fuchsia::modular::ContextMetadata* to,
- const char* type) {
- FXL_LOG(WARNING) << "Context value and ancestor both have metadata type ("
- << type
- << "), which is not allowed. Ignoring value metadata.";
- FXL_LOG(WARNING) << "Value metadata: " << *to;
- FXL_LOG(WARNING) << "Ancestor metadata: " << from;
-}
-
-void MergeMetadata(const fuchsia::modular::ContextMetadata& from,
- fuchsia::modular::ContextMetadata* to) {
-#define MERGE(type) \
- if (from.type) { \
- if (to->type) { \
- LogInvalidAncestorMetadata(from, to, #type); \
- } else { \
- fidl::Clone(from.type, &(*to).type); \
- } \
- }
- // Go through each type of metadata on |from|, and copy it to
- // |*to|. However, if anything in |from| already exists in |*to|,
- // that's an error, since a value's ancestors can only have one
- // node of each type (story, module, entity, etc).
- MERGE(story);
- MERGE(mod);
- MERGE(link);
- MERGE(entity);
-#undef MERGE
-}
-
-} // namespace
-
-ContextRepository::ContextRepository() : debug_(new ContextDebugImpl(this)) {}
-ContextRepository::~ContextRepository() = default;
-
-bool ContextRepository::Contains(const Id& id) const {
- return values_.find(id) != values_.end();
-}
-
-ContextRepository::Id ContextRepository::Add(
- const Id& parent_id, fuchsia::modular::ContextValue value) {
- FXL_DCHECK(values_.find(parent_id) != values_.end()) << parent_id;
- return AddInternal(parent_id, std::move(value));
-}
-
-ContextRepository::Id ContextRepository::Add(
- fuchsia::modular::ContextValue value) {
- return AddInternal("", std::move(value));
-}
-
-void ContextRepository::Update(const Id& id,
- fuchsia::modular::ContextValue value) {
- // TODO(thatguy): Short-circuit if |value| isn't changing anything to avoid
- // spurious update computation.
-
- auto it = values_.find(id);
- FXL_DCHECK(it != values_.end()) << id;
- it->second.value = std::move(value);
- it->second.version++;
-
- InProgressUpdate update;
- update.updated_values.push_back(&it->second);
- // Updating a value can affect all of its children, so we need to re-process
- // and reindex them.
- auto children = graph_.GetChildrenRecursive(id);
- for (const auto& child : children) {
- auto child_it = values_.find(child);
- FXL_DCHECK(child_it != values_.end()) << child;
- update.updated_values.push_back(&child_it->second);
- }
- ReindexAndNotify(std::move(update));
- debug_->OnValueChanged(graph_.GetParents(id), id, it->second.value);
-}
-
-ContextRepository::Id ContextRepository::AddInternal(
- const Id& parent_id, fuchsia::modular::ContextValue value) {
- const auto new_id = CreateValueId();
-
- // Add the new value to |values_|.
- ValueInternal value_internal;
- value_internal.id = new_id;
- value_internal.version = 0;
-
- value_internal.value = std::move(value);
- auto it = values_.emplace(new_id, std::move(value_internal));
-
- if (!parent_id.empty()) {
- // Update the graph.
- graph_.AddEdge(parent_id, new_id);
- }
-
- InProgressUpdate update;
- update.updated_values.push_back(&it.first->second);
- ReindexAndNotify(std::move(update));
-
- if (parent_id.empty()) {
- debug_->OnValueChanged({}, new_id, it.first->second.value);
- } else {
- debug_->OnValueChanged({parent_id}, new_id, it.first->second.value);
- }
- return new_id;
-}
-
-void ContextRepository::Remove(const Id& id) {
- auto it = values_.find(id);
- if (it == values_.end()) {
- FXL_LOG(WARNING) << "Attempting to remove non-existent value: " << id;
- return;
- }
- InProgressUpdate update;
- update.removed_values.push_back(std::move(it->second));
- // Removing a value can affect all of its children, so we need to re-process
- // and reindex them.
- auto children = graph_.GetChildrenRecursive(id);
- for (const auto& child : children) {
- auto child_it = values_.find(child);
- FXL_DCHECK(child_it != values_.end()) << child;
- update.updated_values.push_back(&child_it->second);
- }
- values_.erase(it);
- graph_.Remove(id);
-
- debug_->OnValueRemoved(id);
- ReindexAndNotify(std::move(update));
-}
-
-fuchsia::modular::ContextValuePtr ContextRepository::Get(const Id& id) const {
- auto it = values_.find(id);
- if (it == values_.end())
- return fuchsia::modular::ContextValuePtr();
-
- fuchsia::modular::ContextValue value;
- fidl::Clone(it->second.value, &value);
- return fidl::MakeOptional(std::move(value));
-}
-
-fuchsia::modular::ContextValuePtr ContextRepository::GetMerged(
- const Id& id) const {
- auto it = values_.find(id);
- if (it == values_.end())
- return fuchsia::modular::ContextValuePtr();
-
- fuchsia::modular::ContextValue merged_value;
- fidl::Clone(it->second.value, &merged_value);
- // Copy the merged metadata (includes ancestor metadata).
- fidl::Clone(it->second.merged_metadata, &merged_value.meta);
- return fidl::MakeOptional(std::move(merged_value));
-}
-
-fuchsia::modular::ContextUpdate ContextRepository::Query(
- const fuchsia::modular::ContextQuery& query) {
- return QueryInternal(query).first;
-}
-
-ContextRepository::Id ContextRepository::AddSubscription(
- fuchsia::modular::ContextQuery query,
- fuchsia::modular::ContextListener* const listener,
- fuchsia::modular::SubscriptionDebugInfo debug_info) {
- // Add the subscription to our list.
- Subscription subscription;
- subscription.query = std::move(query);
- subscription.listener = listener;
- subscription.debug_info = std::move(debug_info);
- const auto id = CreateSubscriptionId();
- auto it = subscriptions_.emplace(id, std::move(subscription));
- FXL_DCHECK(it.second);
-
- // Notify the listener immediately of our current state.
- QueryAndMaybeNotify(&it.first->second, true /* force */);
-
- // TODO(thatguy): Add a client identifier parameter to AddSubscription().
- debug_->OnSubscriptionAdded(id, it.first->second.query,
- it.first->second.debug_info);
- return id;
-}
-
-void ContextRepository::AddSubscription(
- fuchsia::modular::ContextQuery query,
- fuchsia::modular::ContextListenerPtr listener,
- fuchsia::modular::SubscriptionDebugInfo debug_info) {
- auto id =
- AddSubscription(std::move(query), listener.get(), std::move(debug_info));
- listener.set_error_handler(
- [this, id](zx_status_t status) { RemoveSubscription(id); });
- // RemoveSubscription() above is responsible for freeing this memory.
- subscriptions_[id].listener_storage = std::move(listener);
-}
-
-ContextDebugImpl* ContextRepository::debug() { return debug_.get(); }
-
-void ContextRepository::AddDebugBinding(
- fidl::InterfaceRequest<fuchsia::modular::ContextDebug> request) {
- debug_bindings_.AddBinding(debug_.get(), std::move(request));
-}
-
-void ContextRepository::RemoveSubscription(Id id) {
- auto it = subscriptions_.find(id);
- FXL_DCHECK(it != subscriptions_.end());
- subscriptions_.erase(it);
-
- debug_->OnSubscriptionRemoved(id);
-}
-
-std::pair<fuchsia::modular::ContextUpdate, ContextRepository::IdAndVersionSet>
-ContextRepository::QueryInternal(const fuchsia::modular::ContextQuery& query) {
- // For each entry in |query->selector|, query the index for matching values.
- IdAndVersionSet matching_id_version;
- fuchsia::modular::ContextUpdate update;
- for (const auto& entry : query.selector) {
- const auto& key = entry.key;
- const auto& selector = entry.value;
-
- std::set<ContextIndex::Id> values = Select(selector);
-
- fuchsia::modular::ContextUpdateEntry update_entry;
- update_entry.key = key;
- update.values.push_back(std::move(update_entry));
- for (const auto& id : values) {
- auto it = values_.find(id);
- FXL_DCHECK(it != values_.end()) << id;
- matching_id_version.insert(std::make_pair(id, it->second.version));
- for (auto& it : update.values) {
- if (it.key == key) {
- it.value.push_back(std::move(*GetMerged(id)));
- }
- }
- }
- }
- return std::make_pair(std::move(update), std::move(matching_id_version));
-}
-
-void ContextRepository::QueryAndMaybeNotify(Subscription* const subscription,
- bool force) {
- std::pair<fuchsia::modular::ContextUpdate, IdAndVersionSet> result =
- QueryInternal(subscription->query);
- if (!force) {
- // Check if this update contains any new values.
- IdAndVersionSet diff;
- std::set_symmetric_difference(result.second.begin(), result.second.end(),
- subscription->last_update.begin(),
- subscription->last_update.end(),
- std::inserter(diff, diff.begin()));
- if (diff.empty()) {
- return;
- }
- }
- subscription->last_update = result.second;
-
- subscription->listener->OnContextUpdate(std::move(result.first));
-}
-
-void ContextRepository::ReindexAndNotify(
- ContextRepository::InProgressUpdate update) {
- for (auto& value : update.removed_values) {
- index_.Remove(value.id, value.value.type, value.merged_metadata);
- }
- for (auto* value : update.updated_values) {
- // Step 1: reindex the value.
-
- // Before we add the newest metadata values to the index, we need to remove
- // the old values from the index. |value.merged_metadata| contains whatever
- // we added to the index last time.
- index_.Remove(value->id, value->value.type, value->merged_metadata);
- RecomputeMergedMetadata(value);
- index_.Add(value->id, value->value.type, value->merged_metadata);
- }
-
- // Step 2: recompute the output for each subscription and notify its
- // listeners.
- for (auto& it : subscriptions_) {
- QueryAndMaybeNotify(&it.second, false /* force */);
- }
-}
-
-void ContextRepository::RecomputeMergedMetadata(ValueInternal* const value) {
- value->merged_metadata = fuchsia::modular::ContextMetadata();
- // It doesn't matter what order we merge the ancestor values, because there
- // should always only be one of each type, and thus no collisions.
- std::vector<Id> ancestors = graph_.GetAncestors(value->id);
- for (const auto& ancestor_id : ancestors) {
- const auto& it = values_.find(ancestor_id);
- FXL_DCHECK(it != values_.end());
- const auto& ancestor_value = it->second;
- MergeMetadata(ancestor_value.value.meta, &value->merged_metadata);
- }
- MergeMetadata(value->value.meta, &value->merged_metadata);
-}
-
-std::set<ContextRepository::Id> ContextRepository::Select(
- const fuchsia::modular::ContextSelector& selector) {
- std::set<ContextIndex::Id> values;
- index_.Query(selector.type, selector.meta, &values);
- return values;
-}
-
-} // namespace modular
diff --git a/bin/context_engine/context_repository.h b/bin/context_engine/context_repository.h
deleted file mode 100644
index 74aaacf..0000000
--- a/bin/context_engine/context_repository.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_REPOSITORY_H_
-#define PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_REPOSITORY_H_
-
-#include <map>
-#include <set>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/context_engine/index.h"
-
-namespace modular {
-
-class ContextDebug;
-class ContextDebugImpl;
-
-// This class represents a "multiparent hierarchy", which is another way
-// of saying a directed graph that cannot have any cycles.
-// TODO(thatguy): Actually enforce the no cycles constraint :).
-class ContextGraph {
- public:
- using Id = std::string;
-
- ContextGraph();
- virtual ~ContextGraph();
-
- // Adds a graph edge from |from| to |to|.
- void AddEdge(const Id& from, const Id& to);
-
- // Removes the node |id| and removes any incoming or outgoing edges.
- // TODO(thatguy): Decide what to do about orphaned children.
- void Remove(const Id& id);
-
- std::set<Id> GetParents(const Id& id) const;
-
- // Returns all |id|'s children and their children, recursively.
- std::set<Id> GetChildrenRecursive(const Id& id) const;
-
- // Returns all ancestors for |id|, guaranteeing that all node ids appear in
- // the return value before their children (ie, in order of seniority).
- std::vector<Id> GetAncestors(const Id& id) const;
-
- private:
- // From node to its parents.
- std::map<Id, std::set<Id>> parents_;
- // From parent to its immediate children.
- std::map<Id, std::set<Id>> children_;
-};
-
-// Stores a graph of fuchsia::modular::ContextValue structs (values). Supports
-// fetching lists of values based on a) the value's type and b)
-// fuchsia::modular::ContextMetadata fields.
-//
-// The graph structure is used to represent value namespaces or scope, although
-// the exact meaning or what concepts are represented is up to the client. When
-// a value is queried against and returned, its metadata is "flattened" with
-// its ancestors' metadata. For example, if an ENTITY value is a child of a
-// MODULE value, the ENTITY value will inherit the MODULE value's metadata (ie,
-// the |mod| field of the fuchsia::modular::ContextMetadata struct).
-class ContextRepository {
- struct ValueInternal;
- struct Subscription;
- struct InProgressUpdate;
-
- public:
- using Id = ContextIndex::Id;
- using IdAndVersionSet = std::set<std::pair<Id, uint32_t>>;
-
- ContextRepository();
- ~ContextRepository();
-
- bool Contains(const Id& id) const;
- Id Add(fuchsia::modular::ContextValue value);
- Id Add(const Id& parent_id, fuchsia::modular::ContextValue value);
- void Update(const Id& id, fuchsia::modular::ContextValue value);
- void Remove(const Id& id);
-
- // Returns a copy of the fuchsia::modular::ContextValue for |id|. Returns a
- // null |fuchsia::modular::ContextValuePtr| if |id| is not valid.
- fuchsia::modular::ContextValuePtr Get(const Id& id) const;
-
- // Returns a copy of the fuchsia::modular::ContextValue for |id|, with
- // metadata merged from ancestors. Returns a null
- // |fuchsia::modular::ContextValuePtr| if |id| is not valid.
- fuchsia::modular::ContextValuePtr GetMerged(const Id& id) const;
-
- std::set<Id> Select(const fuchsia::modular::ContextSelector& selector);
-
- // Returns the current requested values for the given query as a context
- // update.
- fuchsia::modular::ContextUpdate Query(
- const fuchsia::modular::ContextQuery& query);
-
- // Does not take ownership of |listener|. |listener| must remain valid until
- // RemoveSubscription() is called with the returned Id.
- Id AddSubscription(fuchsia::modular::ContextQuery query,
- fuchsia::modular::ContextListener* listener,
- fuchsia::modular::SubscriptionDebugInfo debug_info);
- void RemoveSubscription(Id id);
-
- // Like AddSubscription above, but takes ownership of the FIDL service proxy
- // object, |listener|. The subscription is automatically removed when
- // |listener| experiences a connection error.
- void AddSubscription(fuchsia::modular::ContextQuery query,
- fuchsia::modular::ContextListenerPtr listener,
- fuchsia::modular::SubscriptionDebugInfo debug_info);
-
- ContextDebugImpl* debug();
- void AddDebugBinding(
- fidl::InterfaceRequest<fuchsia::modular::ContextDebug> request);
-
- private:
- Id AddInternal(const Id& parent_id, fuchsia::modular::ContextValue value);
- void RecomputeMergedMetadata(ValueInternal* value);
- void ReindexAndNotify(InProgressUpdate update);
- void QueryAndMaybeNotify(Subscription* subscription, bool force);
- std::pair<fuchsia::modular::ContextUpdate, IdAndVersionSet> QueryInternal(
- const fuchsia::modular::ContextQuery& query);
-
- // Keyed by internal id.
- std::map<Id, ValueInternal> values_;
- ContextGraph graph_;
-
- // A map of Id (int) to Subscription.
- std::map<Id, Subscription> subscriptions_;
-
- ContextIndex index_;
-
- friend class ContextDebugImpl;
- std::unique_ptr<ContextDebugImpl> debug_;
- fidl::BindingSet<fuchsia::modular::ContextDebug> debug_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ContextRepository);
-};
-
-struct ContextRepository::ValueInternal {
- // The contents of |value.meta| merged with metadata from all
- // of this value's ancestors.
- Id id;
- fuchsia::modular::ContextMetadata merged_metadata;
- fuchsia::modular::ContextValue value;
- uint32_t version; // Incremented on change.
-};
-
-struct ContextRepository::Subscription {
- fuchsia::modular::ContextQuery query;
- fuchsia::modular::ContextListener*
- listener; // Optionally owned by |listener_storage|.
- fuchsia::modular::ContextListenerPtr listener_storage;
- fuchsia::modular::SubscriptionDebugInfo debug_info;
- // The set of value id and version we sent the last time we notified
- // |listener|. Used to calculate if a new update is different.
- IdAndVersionSet last_update;
-};
-
-// Holds interim values necessary for processing an update to at least one
-// context value.
-struct ContextRepository::InProgressUpdate {
- // These values are having their values added or updated.
- std::vector<ValueInternal*> updated_values;
- // These values are being removed.
- std::vector<ValueInternal> removed_values;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_REPOSITORY_H_
diff --git a/bin/context_engine/context_repository_unittest.cc b/bin/context_engine/context_repository_unittest.cc
deleted file mode 100644
index df3b463..0000000
--- a/bin/context_engine/context_repository_unittest.cc
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/context_repository.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/context/cpp/context_helper.h>
-#include <lib/context/cpp/context_metadata_builder.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-
-#include "gtest/gtest.h"
-
-using maxwell::ContextMetadataBuilder;
-
-namespace modular {
-namespace {
-
-TEST(ContextGraph, GetChildrenRecursive_GetAncestors) {
- ContextGraph graph;
-
- graph.AddEdge("a", "b");
- graph.AddEdge("b", "c");
- graph.AddEdge("b", "d");
-
- auto children = graph.GetChildrenRecursive("b");
- EXPECT_EQ(2lu, children.size());
- EXPECT_TRUE(children.find("c") != children.end());
- EXPECT_TRUE(children.find("d") != children.end());
-
- children = graph.GetChildrenRecursive("a");
- EXPECT_EQ(3lu, children.size());
- EXPECT_TRUE(children.find("b") != children.end());
- EXPECT_TRUE(children.find("c") != children.end());
- EXPECT_TRUE(children.find("d") != children.end());
-
- auto ancestors = graph.GetAncestors("c");
- EXPECT_EQ(2lu, ancestors.size());
- EXPECT_EQ("a", ancestors[0]);
- EXPECT_EQ("b", ancestors[1]);
-}
-
-class ContextRepositoryTest : public ::testing::Test {
- public:
- ContextRepositoryTest() {}
-
- protected:
- ContextRepository repository_;
-};
-
-class TestListener : public fuchsia::modular::ContextListener {
- public:
- fuchsia::modular::ContextUpdatePtr last_update;
-
- void OnContextUpdate(fuchsia::modular::ContextUpdate update) override {
- last_update = fidl::MakeOptional(std::move(update));
- }
-
- void reset() { last_update.reset(); }
-};
-
-fuchsia::modular::ContextValue CreateValue(
- fuchsia::modular::ContextValueType type, const std::string& content) {
- fuchsia::modular::ContextValue value;
- value.type = type;
- value.content = content;
- return value;
-}
-
-fuchsia::modular::ContextValue CreateValue(
- fuchsia::modular::ContextValueType type, const std::string& content,
- fuchsia::modular::ContextMetadata meta) {
- fuchsia::modular::ContextValue value;
- value.type = type;
- value.content = content;
- value.meta = std::move(meta);
- return value;
-}
-
-} // namespace
-
-TEST_F(ContextRepositoryTest, GetAddUpdateRemove) {
- // This test ensures that we can do basic, synchronous add/update/remove/get
- // operations.
-
- // Show that when we set values, we can get them back.
- auto id1 = repository_.Add(
- CreateValue(fuchsia::modular::ContextValueType::ENTITY, "content"));
- auto value1 = repository_.Get(id1);
- ASSERT_TRUE(value1);
- EXPECT_EQ(fuchsia::modular::ContextValueType::ENTITY, value1->type);
- EXPECT_EQ("content", value1->content);
-
- // Setting another value doesn't affect the original value.
- auto id2 = repository_.Add(
- CreateValue(fuchsia::modular::ContextValueType::ENTITY, "content2"));
- auto value2 = repository_.Get(id2);
- ASSERT_TRUE(value2);
- EXPECT_EQ("content2", value2->content);
- value1 = repository_.Get(id1);
- ASSERT_TRUE(value1);
- EXPECT_EQ(fuchsia::modular::ContextValueType::ENTITY, value1->type);
- EXPECT_EQ("content", value1->content);
-
- // Let's create metadata.
- auto id3 = repository_.Add(
- CreateValue(fuchsia::modular::ContextValueType::ENTITY, "content3",
- ContextMetadataBuilder().SetStoryId("id3story").Build()));
- auto value3 = repository_.Get(id3);
- ASSERT_TRUE(value3);
- EXPECT_EQ("content3", value3->content);
- ASSERT_TRUE(value3->meta.story);
- EXPECT_EQ("id3story", value3->meta.story->id);
-
- // Update one of the previous values.
- repository_.Update(
- id2,
- CreateValue(fuchsia::modular::ContextValueType::ENTITY, "new content2",
- ContextMetadataBuilder().SetStoryId("id2story").Build()));
- value2 = repository_.Get(id2);
- ASSERT_TRUE(value2);
- ASSERT_TRUE(value2->meta.story);
- EXPECT_EQ("id2story", value2->meta.story->id);
- EXPECT_EQ("new content2", value2->content);
-
- // Now remove id3.
- repository_.Remove(id3);
- EXPECT_FALSE(repository_.Get(id3));
- EXPECT_TRUE(repository_.Get(id1));
- EXPECT_TRUE(repository_.Get(id2));
-
- // And the others.
- repository_.Remove(id1);
- repository_.Remove(id2);
- EXPECT_FALSE(repository_.Get(id1));
- EXPECT_FALSE(repository_.Get(id2));
-}
-
-TEST_F(ContextRepositoryTest, ValuesInheritMetadata) {
- // When a value is added as a child of another value, the child inherits the
- // metadata of its parent.
- auto meta1 = ContextMetadataBuilder().SetStoryId("id").Build();
- auto id1 = repository_.Add(CreateValue(
- fuchsia::modular::ContextValueType::STORY, "s", std::move(meta1)));
-
- auto meta2 = ContextMetadataBuilder().SetModuleUrl("url").Build();
- auto id2 = repository_.Add(
- id1, CreateValue(fuchsia::modular::ContextValueType::MODULE, "m",
- std::move(meta2)));
-
- auto value1 = repository_.GetMerged(id1);
- ASSERT_TRUE(value1);
- // value1's metadata shouldn't have changed.
- ASSERT_TRUE(value1->meta.story);
- EXPECT_EQ("id", value1->meta.story->id);
- ASSERT_FALSE(value1->meta.mod);
-
- auto value2 = repository_.GetMerged(id2);
- ASSERT_TRUE(value2);
- // value2's metadata should combine both value1's and value2's.
- ASSERT_TRUE(value2->meta.story);
- EXPECT_EQ("id", value2->meta.story->id);
- ASSERT_TRUE(value2->meta.mod);
- ASSERT_TRUE(value2->meta.mod->url);
- EXPECT_EQ("url", value2->meta.mod->url);
-
- // Changing the parent's metadata value should update the child's also.
- meta1 = fuchsia::modular::ContextMetadata();
- meta1.story = fuchsia::modular::StoryMetadata::New();
- meta1.story->id = "newid";
- repository_.Update(id1, CreateValue(fuchsia::modular::ContextValueType::STORY,
- "s", std::move(meta1)));
- value2 = repository_.GetMerged(id2);
- ASSERT_TRUE(value2);
- ASSERT_TRUE(value2->meta.story);
- EXPECT_EQ("newid", value2->meta.story->id);
- ASSERT_TRUE(value2->meta.mod);
- ASSERT_TRUE(value2->meta.mod->url);
- EXPECT_EQ("url", value2->meta.mod->url);
-
- // If a parent contains metadata that the child also contains (they both have
- // 'mod' metadata), the parent's takes precendence.
- meta1 =
- ContextMetadataBuilder(std::move(meta1)).SetModuleUrl("override").Build();
- repository_.Update(id1, CreateValue(fuchsia::modular::ContextValueType::STORY,
- "s", std::move(meta1)));
- value2 = repository_.GetMerged(id2);
- ASSERT_TRUE(value2);
- ASSERT_FALSE(value2->meta.story);
- ASSERT_TRUE(value2->meta.mod);
- ASSERT_EQ("override", value2->meta.mod->url);
-}
-
-TEST_F(ContextRepositoryTest, ListenersGetUpdates) {
- // We want to test these subscription behaviors.
- // 1) A value is added but doesn't match our subscription.
- // a) It's the wrong type (ie, STORY vs ENTITY)
- // b) Its metadata doesn't match.
- // 2) A value is added that matches our existing subscription.
- // 3) A value is updated that newly matches our subscription.
- // 4) When a value is removed, it is no longer returned.
-
- // (1)
- fuchsia::modular::ContextQuery query;
- fuchsia::modular::ContextSelector selector;
- selector.type = fuchsia::modular::ContextValueType::ENTITY;
- selector.meta = ContextMetadataBuilder().SetEntityTopic("topic").BuildPtr();
- AddToContextQuery(&query, "a", std::move(selector));
-
- TestListener listener;
- repository_.AddSubscription(std::move(query), &listener,
- fuchsia::modular::SubscriptionDebugInfo());
- auto maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- EXPECT_TRUE(maybe_result.value().empty());
- listener.reset();
-
- // (a)
- fuchsia::modular::ContextValue value;
- value.type = fuchsia::modular::ContextValueType::STORY;
- value.content = "no match";
- value.meta = ContextMetadataBuilder().SetEntityTopic("topic").Build();
- repository_.Add(std::move(value));
- // No new update because nothing changed for our subscription.
- EXPECT_FALSE(listener.last_update);
- listener.reset();
-
- // (b)
- value = fuchsia::modular::ContextValue();
- value.type = fuchsia::modular::ContextValueType::ENTITY;
- value.content = "no match yet";
- value.meta = ContextMetadataBuilder().SetEntityTopic("not the topic").Build();
- auto id = repository_.Add(std::move(value)); // Save id for later.
- // No new update because nothing changed for our subscription.
- EXPECT_FALSE(listener.last_update);
- listener.reset();
-
- // (2)
- value = fuchsia::modular::ContextValue();
- value.type = fuchsia::modular::ContextValueType::ENTITY;
- value.content = "match";
- value.meta = ContextMetadataBuilder().SetEntityTopic("topic").Build();
- repository_.Add(std::move(value));
- maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- {
- auto& result = maybe_result.value();
- EXPECT_EQ(1lu, result.size());
- EXPECT_EQ("match", result.at(0).content);
- }
- listener.reset();
-
- // (3)
- value = fuchsia::modular::ContextValue();
- value.type = fuchsia::modular::ContextValueType::ENTITY;
- value.content = "now it matches";
- // Add more metadata than the query is looking for. It shouldn't affect
- // the query, because it doesn't express any constraint on 'type'.
- value.meta = ContextMetadataBuilder()
- .SetEntityTopic("topic")
- .AddEntityType("type1")
- .AddEntityType("type2")
- .Build();
- repository_.Update(id, std::move(value));
- ASSERT_TRUE(listener.last_update);
- maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- {
- auto& result = maybe_result.value();
- EXPECT_EQ(2lu, result.size());
- EXPECT_EQ("now it matches", result.at(0).content);
- EXPECT_EQ("match", result.at(1).content);
- }
- listener.reset();
-
- // (4)
- repository_.Remove(id);
- ASSERT_TRUE(listener.last_update);
- maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- {
- auto& result = maybe_result.value();
- EXPECT_EQ(1lu, result.size());
- EXPECT_EQ("match", result.at(0).content);
- }
- listener.reset();
-}
-
-TEST_F(ContextRepositoryTest, ListenersGetUpdates_WhenParentsUpdated) {
- // We should see updates to listeners when an update to a node's
- // parent causes that node to be matched by a query.
- fuchsia::modular::ContextQuery query;
- fuchsia::modular::ContextSelector selector;
- selector.type = fuchsia::modular::ContextValueType::ENTITY;
- selector.meta = ContextMetadataBuilder().SetStoryId("match").BuildPtr();
- AddToContextQuery(&query, "a", std::move(selector));
-
- TestListener listener;
- repository_.AddSubscription(std::move(query), &listener,
- fuchsia::modular::SubscriptionDebugInfo());
- ASSERT_TRUE(listener.last_update);
- auto maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- {
- auto& result = maybe_result.value();
- EXPECT_EQ(0lu, result.size());
- listener.reset();
- }
-
- // Add a Story value.
- fuchsia::modular::ContextValue story_value;
- story_value.type = fuchsia::modular::ContextValueType::STORY;
- story_value.meta = ContextMetadataBuilder().SetStoryId("no match").Build();
- fuchsia::modular::ContextValue first_story_value;
- fidl::Clone(story_value, &first_story_value); // Save for later.
- auto story_value_id = repository_.Add(std::move(story_value));
-
- // Expect no update.
- EXPECT_FALSE(listener.last_update);
-
- // Add an fuchsia::modular::Entity node, but it still shouldn't match.
- fuchsia::modular::ContextValue entity_value;
- entity_value.type = fuchsia::modular::ContextValueType::ENTITY;
- entity_value.content = "content";
- repository_.Add(story_value_id, std::move(entity_value));
-
- // Still expect no update.
- EXPECT_FALSE(listener.last_update);
-
- // Update the story value so its metadata matches the query, and we should
- // see the entity value returned in our update.
- story_value = fuchsia::modular::ContextValue();
- story_value.type = fuchsia::modular::ContextValueType::STORY;
- story_value.meta = ContextMetadataBuilder().SetStoryId("match").Build();
- fuchsia::modular::ContextValue matching_story_value;
- fidl::Clone(story_value, &matching_story_value); // Save for later.
- repository_.Update(story_value_id, std::move(story_value));
-
- ASSERT_TRUE(listener.last_update);
- maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- {
- auto& result = maybe_result.value();
- EXPECT_EQ(1lu, result.size());
- EXPECT_EQ("content", result.at(0).content);
- // Make sure we adopted the parent metadata from the story node.
- ASSERT_TRUE(result.at(0).meta.story);
- EXPECT_EQ("match", result.at(0).meta.story->id);
- }
- listener.reset();
-
- // Set the value back to something that doesn't match, and we should get an
- // empty update.
- repository_.Update(story_value_id, std::move(first_story_value));
- ASSERT_TRUE(listener.last_update);
- maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- EXPECT_EQ(0lu, maybe_result.value().size());
- listener.reset();
-
- // Set it back to something that matched, and this time remove the value
- // entirely. We should observe it go away.
- repository_.Update(story_value_id, std::move(matching_story_value));
- ASSERT_TRUE(listener.last_update);
- maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- EXPECT_EQ(1lu, maybe_result.value().size());
- listener.reset();
-
- repository_.Remove(story_value_id);
- ASSERT_TRUE(listener.last_update);
- maybe_result = TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- EXPECT_TRUE(maybe_result.value().empty());
- listener.reset();
-}
-
-} // namespace modular
diff --git a/bin/context_engine/context_writer_impl.cc b/bin/context_engine/context_writer_impl.cc
deleted file mode 100644
index e8d3044..0000000
--- a/bin/context_engine/context_writer_impl.cc
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/context_writer_impl.h"
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/entity/cpp/json.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fit/defer.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/bin/context_engine/debug.h"
-#include "rapidjson/document.h"
-
-namespace modular {
-
-ContextWriterImpl::ContextWriterImpl(
- const fuchsia::modular::ComponentScope& client_info,
- ContextRepository* const repository,
- fuchsia::modular::EntityResolver* const entity_resolver,
- fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request)
- : binding_(this, std::move(request)),
- repository_(repository),
- entity_resolver_(entity_resolver),
- weak_factory_(this) {
- FXL_DCHECK(repository != nullptr);
-
- // Set up a query to the repository to get our parent id.
- if (client_info.is_module_scope()) {
- parent_value_selector_.type = fuchsia::modular::ContextValueType::MODULE;
- parent_value_selector_.meta = fuchsia::modular::ContextMetadata::New();
- parent_value_selector_.meta->story = fuchsia::modular::StoryMetadata::New();
- parent_value_selector_.meta->story->id =
- client_info.module_scope().story_id;
- parent_value_selector_.meta->mod = fuchsia::modular::ModuleMetadata::New();
- std::vector<std::string> module_path;
- fidl::Clone(client_info.module_scope().module_path, &module_path);
- parent_value_selector_.meta->mod->path = fidl::VectorPtr(std::move(module_path));
- }
-}
-
-ContextWriterImpl::~ContextWriterImpl() {}
-
-namespace {
-
-fidl::VectorPtr<std::string> Deprecated_GetTypesFromJsonEntity(
- const fidl::StringPtr& content) {
- // If the content has the @type attribute, take its contents and populate the
- // fuchsia::modular::EntityMetadata appropriately, overriding whatever is
- // there.
- std::vector<std::string> types;
- if (!ExtractEntityTypesFromJson(content, &types)) {
- FXL_LOG(WARNING) << "Invalid entity metadata in JSON value: " << content;
- return {};
- }
-
- return fidl::VectorPtr(types);
-}
-
-void MaybeFillEntityTypeMetadata(const std::vector<std::string>& types,
- fuchsia::modular::ContextValue& value) {
- if (value.type != fuchsia::modular::ContextValueType::ENTITY)
- return;
-
- if (!value.meta.entity) {
- value.meta.entity = fuchsia::modular::EntityMetadata::New();
- }
- value.meta.entity->type = fidl::VectorPtr(types);
-}
-
-bool MaybeFindParentValueId(ContextRepository* repository,
- const fuchsia::modular::ContextSelector& selector,
- ContextRepository::Id* out) {
- // There is technically a race condition here, since on construction, we
- // are given a fuchsia::modular::ComponentScope, which contains some metadata
- // to find a value in the context engine. It is the responsibility of the
- // story_info acquierer to actually create that value, so we query at
- // CreateValue()-time because it makes it less likely to hit the race
- // condition.
- //
- // This is only exercised when a Module publishes context explicitly,
- // something that we plan to disallow once Links speak in Entities, as then
- // Modules that wish to store context can simply write Entities into a new
- // link.
- auto ids = repository->Select(selector);
- if (ids.size() == 1) {
- *out = *ids.begin();
- return true;
- }
- return false;
-}
-
-} // namespace
-
-void ContextWriterImpl::CreateValue(
- fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request,
- fuchsia::modular::ContextValueType type) {
- ContextRepository::Id parent_id;
- // We ignore the return value - if it returns false |parent_id| will stay
- // default-initialized.
- MaybeFindParentValueId(repository_, parent_value_selector_, &parent_id);
- auto ptr =
- new ContextValueWriterImpl(this, parent_id, type, std::move(request));
- AddContextValueWriter(ptr);
-}
-
-void ContextWriterImpl::AddContextValueWriter(ContextValueWriterImpl* ptr) {
- value_writer_storage_.emplace_back(ptr);
-}
-
-void ContextWriterImpl::DestroyContextValueWriter(ContextValueWriterImpl* ptr) {
- auto it = std::remove_if(
- value_writer_storage_.begin(), value_writer_storage_.end(),
- [ptr](const std::unique_ptr<ContextValueWriterImpl>& u_ptr) {
- return u_ptr.get() == ptr;
- });
- value_writer_storage_.erase(it, value_writer_storage_.end());
-}
-
-void ContextWriterImpl::WriteEntityTopic(std::string topic,
- fidl::StringPtr value) {
- auto activity =
- repository_->debug()->GetIdleWaiter()->RegisterOngoingActivity();
-
- if (!value) {
- // Remove this value.
- auto it = topic_value_ids_.find(topic);
- if (it != topic_value_ids_.end()) {
- repository_->Remove(it->second);
- }
- return;
- }
-
- GetEntityTypesFromEntityReference(
- value, [this, activity, topic,
- value](const std::vector<std::string>& types) {
- fuchsia::modular::ContextValue context_value;
- context_value.type = fuchsia::modular::ContextValueType::ENTITY;
- context_value.content = value;
- context_value.meta.entity = fuchsia::modular::EntityMetadata::New();
- context_value.meta.entity->topic = topic;
- context_value.meta.entity->type = fidl::VectorPtr(types);
-
- auto it = topic_value_ids_.find(topic);
- if (it == topic_value_ids_.end()) {
- ContextRepository::Id parent_id;
- ContextRepository::Id id;
- if (MaybeFindParentValueId(repository_, parent_value_selector_,
- &parent_id)) {
- id = repository_->Add(parent_id, std::move(context_value));
- } else {
- id = repository_->Add(std::move(context_value));
- }
- topic_value_ids_[topic] = id;
- } else {
- repository_->Update(it->second, std::move(context_value));
- }
- });
-}
-
-void ContextWriterImpl::GetEntityTypesFromEntityReference(
- const fidl::StringPtr& reference,
- std::function<void(const std::vector<std::string>&)> done) {
- auto activity =
- repository_->debug()->GetIdleWaiter()->RegisterOngoingActivity();
-
- // TODO(thatguy): This function could be re-used in multiple places. Move it
- // somewhere other places can reach it.
- std::unique_ptr<fuchsia::modular::EntityPtr> entity =
- std::make_unique<fuchsia::modular::EntityPtr>();
- entity_resolver_->ResolveEntity(reference, entity->NewRequest());
-
- auto fallback = fit::defer([done, reference] {
- // The contents of the fuchsia::modular::Entity value could be a deprecated
- // JSON fuchsia::modular::Entity, not an fuchsia::modular::Entity reference.
- done(Deprecated_GetTypesFromJsonEntity(reference));
- });
-
- (*entity)->GetTypes(fxl::MakeCopyable(
- [this, activity, id = entities_.GetId(&entity), done = std::move(done),
- fallback = std::move(fallback)](
- const std::vector<std::string>& types) mutable {
- done(types);
- fallback.cancel();
- entities_.erase(id);
- }));
-
- entities_.emplace(std::move(entity));
-}
-
-ContextValueWriterImpl::ContextValueWriterImpl(
- ContextWriterImpl* writer, const ContextRepository::Id& parent_id,
- fuchsia::modular::ContextValueType type,
- fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request)
- : binding_(this, std::move(request)),
- writer_(writer),
- parent_id_(parent_id),
- type_(type),
- value_id_(Future<ContextRepository::Id>::Create(
- "ContextValueWriterImpl.value_id_")),
- weak_factory_(this) {
- binding_.set_error_handler(
- [this](zx_status_t status) { writer_->DestroyContextValueWriter(this); });
-
- // When |value_id_| completes, we want to remember it so that we know what
- // branch to execute in Set().
- value_id_->WeakConstThen(
- weak_factory_.GetWeakPtr(),
- [this](const ContextRepository::Id& id) { have_value_id_ = true; });
-}
-
-ContextValueWriterImpl::~ContextValueWriterImpl() {
- // It's possible we haven't actually created a value in |repository_| yet.
- // Either we have, and |value_id_| is complete and this callback will be
- // called synchronously, or we haven't and |value_id_| will go out of scope
- // with *this goes out of scope.
- value_id_->WeakConstThen(weak_factory_.GetWeakPtr(),
- [this](const ContextRepository::Id& id) {
- // Remove the value.
- writer_->repository()->Remove(id);
- });
-}
-
-void ContextValueWriterImpl::CreateChildValue(
- fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request,
- fuchsia::modular::ContextValueType type) {
- // We can't create a child value until this value has an ID.
- value_id_->WeakConstThen(
- weak_factory_.GetWeakPtr(),
- fxl::MakeCopyable([this, request = std::move(request),
- type](const ContextRepository::Id& value_id) mutable {
- auto ptr = new ContextValueWriterImpl(writer_, value_id, type,
- std::move(request));
- writer_->AddContextValueWriter(ptr);
- }));
-}
-
-void ContextValueWriterImpl::Set(
- fidl::StringPtr content, fuchsia::modular::ContextMetadataPtr metadata) {
- auto activity = writer_->repository()
- ->debug()
- ->GetIdleWaiter()
- ->RegisterOngoingActivity();
-
- auto done_getting_types =
- [weak_this = weak_factory_.GetWeakPtr(), activity, content,
- metadata = std::move(metadata)](
- const std::vector<std::string>& entity_types) mutable {
- if (!weak_this)
- return;
-
- if (!weak_this->have_value_id_) {
- // We're creating this value for the first time.
- fuchsia::modular::ContextValue value;
- value.type = weak_this->type_;
- value.content = content;
- if (metadata) {
- fidl::Clone(*metadata, &value.meta);
- }
- MaybeFillEntityTypeMetadata(entity_types, value);
-
- if (weak_this->parent_id_.empty()) {
- weak_this->value_id_->Complete(
- weak_this->writer_->repository()->Add(std::move(value)));
- } else {
- weak_this->value_id_->Complete(
- weak_this->writer_->repository()->Add(weak_this->parent_id_,
- std::move(value)));
- }
- } else {
- // We can safely capture everything by reference because we know
- // |weak_this->value_id_| has been completed, which means this
- // callback will be executed immediately.
- weak_this->value_id_->ConstThen(
- [weak_this, &content, &metadata,
- &entity_types](const ContextRepository::Id& value_id) {
- if (!weak_this->writer_->repository()->Contains(value_id)) {
- FXL_LOG(FATAL)
- << "Trying to update non-existent context value ("
- << value_id << "). New content: " << content
- << ", new metadata: " << metadata;
- }
-
- auto value = weak_this->writer_->repository()->Get(value_id);
- if (content) {
- value->content = content;
- }
- if (metadata) {
- fidl::Clone(*metadata, &value->meta);
- }
- MaybeFillEntityTypeMetadata(entity_types, *value);
- weak_this->writer_->repository()->Update(value_id,
- std::move(*value));
- });
- }
- };
-
- if (type_ != fuchsia::modular::ContextValueType::ENTITY || !content) {
- // Avoid an extra round-trip to fuchsia::modular::EntityResolver that won't
- // get us anything.
- done_getting_types({});
- } else {
- writer_->GetEntityTypesFromEntityReference(
- content, fxl::MakeCopyable(std::move(done_getting_types)));
- }
-}
-
-} // namespace modular
diff --git a/bin/context_engine/context_writer_impl.h b/bin/context_engine/context_writer_impl.h
deleted file mode 100644
index 5ccb9dd..0000000
--- a/bin/context_engine/context_writer_impl.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_WRITER_IMPL_H_
-#define PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_WRITER_IMPL_H_
-
-#include <map>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/context_engine/context_repository.h"
-#include "peridot/lib/bound_set/bound_set.h"
-
-namespace modular {
-
-class ContextRepository;
-class ContextValueWriterImpl;
-class EntityResolver;
-
-class ContextWriterImpl : fuchsia::modular::ContextWriter {
- public:
- ContextWriterImpl(
- const fuchsia::modular::ComponentScope& client_info,
- ContextRepository* repository,
- fuchsia::modular::EntityResolver* entity_resolver,
- fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request);
- ~ContextWriterImpl() override;
-
- // Takes ownership of |ptr|. Used by ContextWriterImpl and
- // ContextValueWriterImpl.
- void AddContextValueWriter(ContextValueWriterImpl* ptr);
-
- // Destroys |ptr| and removes it from |value_writer_storage_|. Used by
- // ContextValueWriterImpl on connection error.
- void DestroyContextValueWriter(ContextValueWriterImpl* ptr);
-
- // Used by ContextValueWriterImpl.
- ContextRepository* repository() const { return repository_; }
-
- // Used by ContextValueWriterImpl.
- void GetEntityTypesFromEntityReference(
- const fidl::StringPtr& reference,
- std::function<void(const std::vector<std::string>&)> done);
-
- private:
- // |fuchsia::modular::ContextWriter|
- void CreateValue(
- fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request,
- fuchsia::modular::ContextValueType type) override;
-
- // |fuchsia::modular::ContextWriter|
- void WriteEntityTopic(std::string topic, fidl::StringPtr value) override;
-
- fidl::Binding<fuchsia::modular::ContextWriter> binding_;
-
- fuchsia::modular::ContextSelector parent_value_selector_;
- ContextRepository* const repository_;
- fuchsia::modular::EntityResolver* const entity_resolver_;
-
- // Supports WriteEntityTopic.
- std::map<fidl::StringPtr, ContextRepository::Id> topic_value_ids_;
-
- // Supports CreateValue().
- std::vector<std::unique_ptr<ContextValueWriterImpl>> value_writer_storage_;
-
- // Supports GetEntityTypesFromEntityReference
- //
- // TODO(rosswang): consider adding removal capability to |InterfacePtrSet|
- // instead.
- BoundPtrSet<fuchsia::modular::Entity> entities_;
-
- fxl::WeakPtrFactory<ContextWriterImpl> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ContextWriterImpl);
-};
-
-class ContextValueWriterImpl : fuchsia::modular::ContextValueWriter {
- public:
- // Binds |request| to |this|, and configures it to call
- // |writer->DestroyContextValueWriter(this)| when a connection error occurs.
- // Assumes that |writer->AddContextValueWriter(this)| has already been
- // called. If |parent_id| is set, the new value will have |parent_id| as its
- // parent value.
- //
- // Does not take ownership of |writer|.
- ContextValueWriterImpl(
- ContextWriterImpl* writer, const ContextRepository::Id& parent_id,
- fuchsia::modular::ContextValueType type,
- fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request);
- ~ContextValueWriterImpl() override;
-
- private:
- // |fuchsia::modular::ContextValueWriter|
- void CreateChildValue(
- fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request,
- fuchsia::modular::ContextValueType type) override;
-
- // |fuchsia::modular::ContextValueWriter|
- void Set(fidl::StringPtr content,
- fuchsia::modular::ContextMetadataPtr metadata) override;
-
- fidl::Binding<fuchsia::modular::ContextValueWriter> binding_;
-
- ContextWriterImpl* const writer_;
- const ContextRepository::Id parent_id_;
- fuchsia::modular::ContextValueType type_;
- FuturePtr<ContextRepository::Id> value_id_;
- bool have_value_id_{};
-
- fxl::WeakPtrFactory<ContextValueWriterImpl> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ContextValueWriterImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_WRITER_IMPL_H_
diff --git a/bin/context_engine/debug.cc b/bin/context_engine/debug.cc
deleted file mode 100644
index 8ddb375..0000000
--- a/bin/context_engine/debug.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/debug.h"
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-
-#include "peridot/bin/context_engine/context_repository.h"
-
-namespace modular {
-
-ContextDebugImpl::ContextDebugImpl(const ContextRepository* const repository)
- : repository_(repository), weak_ptr_factory_(this) {}
-ContextDebugImpl::~ContextDebugImpl() = default;
-
-fxl::WeakPtr<ContextDebugImpl> ContextDebugImpl::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
-}
-
-void ContextDebugImpl::OnValueChanged(
- const std::set<Id>& parent_ids, const Id& id,
- const fuchsia::modular::ContextValue& value) {
- fuchsia::modular::ContextDebugValue update;
- update.parent_ids.resize(0);
- for (const auto& it : parent_ids) {
- update.parent_ids.push_back(it);
- }
- update.id = id;
- fuchsia::modular::ContextValue value_clone;
- fidl::Clone(value, &value_clone);
- update.value = fidl::MakeOptional(std::move(value_clone));
- DispatchOneValue(std::move(update));
-}
-
-void ContextDebugImpl::OnValueRemoved(const Id& id) {
- fuchsia::modular::ContextDebugValue update;
- update.id = id;
- update.parent_ids.resize(0);
- DispatchOneValue(std::move(update));
-}
-
-void ContextDebugImpl::OnSubscriptionAdded(
- const Id& id, const fuchsia::modular::ContextQuery& query,
- const fuchsia::modular::SubscriptionDebugInfo& debug_info) {
- fuchsia::modular::ContextDebugSubscription update;
- update.id = id;
- fuchsia::modular::ContextQuery query_clone;
- fidl::Clone(query, &query_clone);
- update.query = fidl::MakeOptional(std::move(query_clone));
- fuchsia::modular::SubscriptionDebugInfo debug_info_clone;
- fidl::Clone(debug_info, &debug_info_clone);
- update.debug_info = fidl::MakeOptional(std::move(debug_info_clone));
- DispatchOneSubscription(std::move(update));
-}
-
-void ContextDebugImpl::OnSubscriptionRemoved(const Id& id) {
- fuchsia::modular::ContextDebugSubscription update;
- update.id = id;
- DispatchOneSubscription(std::move(update));
-}
-
-util::IdleWaiter* ContextDebugImpl::GetIdleWaiter() { return &idle_waiter_; }
-
-void ContextDebugImpl::Watch(
- fidl::InterfaceHandle<fuchsia::modular::ContextDebugListener> listener) {
- FXL_LOG(INFO) << "Watch(): entered";
- auto listener_ptr = listener.Bind();
- // Build a complete state snapshot and send it to |listener|.
- std::vector<fuchsia::modular::ContextDebugValue> all_values;
- for (const auto& entry : repository_->values_) {
- fuchsia::modular::ContextDebugValue update;
- update.id = entry.first;
- fuchsia::modular::ContextValue value_clone;
- fidl::Clone(entry.second.value, &value_clone);
- update.value = fidl::MakeOptional(std::move(value_clone));
- update.parent_ids.resize(0);
- for (const auto& it : repository_->graph_.GetParents(entry.first)) {
- update.parent_ids.push_back(it);
- }
- all_values.push_back(std::move(update));
- }
- listener_ptr->OnValuesChanged(std::move(all_values));
- // TODO(thatguy): Add subscriptions.
-
- listeners_.AddInterfacePtr(std::move(listener_ptr));
-}
-
-void ContextDebugImpl::WaitUntilIdle(WaitUntilIdleCallback callback) {
- idle_waiter_.WaitUntilIdle(callback);
-}
-
-void ContextDebugImpl::DispatchOneValue(
- fuchsia::modular::ContextDebugValue value) {
- fidl::VectorPtr<fuchsia::modular::ContextDebugValue> values;
- values.push_back(std::move(value));
- DispatchValues(std::move(values));
-}
-
-void ContextDebugImpl::DispatchValues(
- fidl::VectorPtr<fuchsia::modular::ContextDebugValue> values) {
- for (const auto& listener : listeners_.ptrs()) {
- fidl::VectorPtr<fuchsia::modular::ContextDebugValue> values_clone;
- fidl::Clone(values, &values_clone);
- (*listener)->OnValuesChanged(values_clone.take());
- }
-}
-
-void ContextDebugImpl::DispatchOneSubscription(
- fuchsia::modular::ContextDebugSubscription value) {
- fidl::VectorPtr<fuchsia::modular::ContextDebugSubscription> values;
- values.push_back(std::move(value));
- DispatchSubscriptions(std::move(values));
-}
-
-void ContextDebugImpl::DispatchSubscriptions(
- fidl::VectorPtr<fuchsia::modular::ContextDebugSubscription> subscriptions) {
- for (const auto& listener : listeners_.ptrs()) {
- fidl::VectorPtr<fuchsia::modular::ContextDebugSubscription>
- subscriptions_clone;
- fidl::Clone(subscriptions, &subscriptions_clone);
- (*listener)->OnSubscriptionsChanged(subscriptions_clone.take());
- }
-}
-
-} // namespace modular
diff --git a/bin/context_engine/debug.h b/bin/context_engine/debug.h
deleted file mode 100644
index 48e2db7..0000000
--- a/bin/context_engine/debug.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CONTEXT_ENGINE_DEBUG_H_
-#define PERIDOT_BIN_CONTEXT_ENGINE_DEBUG_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-
-#include "peridot/bin/context_engine/index.h"
-#include "peridot/lib/util/idle_waiter.h"
-
-namespace modular {
-
-class ContextRepository;
-
-class ContextDebugImpl : public fuchsia::modular::ContextDebug {
- using Id = ContextIndex::Id;
-
- public:
- ContextDebugImpl(const ContextRepository* repository);
- ~ContextDebugImpl() override;
-
- fxl::WeakPtr<ContextDebugImpl> GetWeakPtr();
-
- void OnValueChanged(const std::set<Id>& parent_ids, const Id& id,
- const fuchsia::modular::ContextValue& value);
- void OnValueRemoved(const Id& id);
-
- void OnSubscriptionAdded(
- const Id& id, const fuchsia::modular::ContextQuery& query,
- const fuchsia::modular::SubscriptionDebugInfo& debug_info);
- void OnSubscriptionRemoved(const Id& id);
-
- util::IdleWaiter* GetIdleWaiter();
-
- private:
- // |fuchsia::modular::ContextDebug|
- void Watch(fidl::InterfaceHandle<fuchsia::modular::ContextDebugListener>
- listener) override;
- // |fuchsia::modular::ContextDebug|
- void WaitUntilIdle(WaitUntilIdleCallback callback) override;
-
- void DispatchOneValue(fuchsia::modular::ContextDebugValue value);
- void DispatchValues(
- fidl::VectorPtr<fuchsia::modular::ContextDebugValue> values);
- void DispatchOneSubscription(
- fuchsia::modular::ContextDebugSubscription value);
- void DispatchSubscriptions(
- fidl::VectorPtr<fuchsia::modular::ContextDebugSubscription>
- subscriptions);
-
- // Used in order to get a complete state snapshot when Watch() is called.
- const ContextRepository* const repository_;
- fidl::InterfacePtrSet<fuchsia::modular::ContextDebugListener> listeners_;
-
- util::IdleWaiter idle_waiter_;
-
- fxl::WeakPtrFactory<ContextDebugImpl> weak_ptr_factory_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_CONTEXT_ENGINE_DEBUG_H_
diff --git a/bin/context_engine/index.cc b/bin/context_engine/index.cc
deleted file mode 100644
index 12aeeb8..0000000
--- a/bin/context_engine/index.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/index.h"
-
-#include <algorithm>
-#include <sstream>
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-ContextIndex::ContextIndex() = default;
-ContextIndex::~ContextIndex() = default;
-
-namespace internal {
-// Keys for fields within fuchsia::modular::ContextMetadata.story:
-const char kStoryIdKey[] = "si";
-const char kStoryFocusedKey[] = "sf";
-
-// Keys for fields within fuchsia::modular::ContextMetadata.mod:
-const char kModPathKey[] = "mp";
-const char kModUrlKey[] = "mu";
-const char kModuleFocusedKey[] = "mf";
-
-// Keys for fields within fuchsia::modular::ContextMetadata.entity:
-const char kEntityTopicKey[] = "et";
-const char kEntityTypeKey[] = "ey";
-// We don't index |ctime|.
-
-// Key for fuchsia::modular::ContextValueType.
-const char kContextValueTypeKey[] = "t";
-
-std::set<std::string> EncodeMetadataAndType(
- fuchsia::modular::ContextValueType node_type,
- const fuchsia::modular::ContextMetadata& metadata) {
- fuchsia::modular::ContextMetadata meta_clone;
- fidl::Clone(metadata, &meta_clone);
- return EncodeMetadataAndType(node_type,
- fidl::MakeOptional(std::move(meta_clone)));
-}
-
-std::string EncodeFocus(const std::string& key,
- fuchsia::modular::FocusedStateState focused_state) {
- std::ostringstream str;
- str << key;
- if (focused_state == fuchsia::modular::FocusedStateState::FOCUSED) {
- str << "1";
- } else {
- str << "0";
- }
- return str.str();
-}
-
-std::set<std::string> EncodeMetadataAndType(
- fuchsia::modular::ContextValueType node_type,
- const fuchsia::modular::ContextMetadataPtr& metadata) {
- std::set<std::string> ret;
-
- if (metadata) {
- if (metadata->story) {
- if (metadata->story->id) {
- std::ostringstream str;
- str << kStoryIdKey << metadata->story->id;
- ret.insert(str.str());
- }
- if (metadata->story->focused) {
- ret.insert(
- EncodeFocus(kStoryFocusedKey, metadata->story->focused->state));
- }
- }
-
- if (metadata->mod) {
- if (metadata->mod->url) {
- std::ostringstream str;
- str << kModUrlKey << metadata->mod->url;
- ret.insert(str.str());
- }
- if (metadata->mod->path) {
- std::ostringstream str;
- str << kModPathKey;
- for (const auto& part : *metadata->mod->path) {
- str << '\0' << part;
- }
- ret.insert(str.str());
- }
- if (metadata->mod->focused) {
- ret.insert(
- EncodeFocus(kModuleFocusedKey, metadata->mod->focused->state));
- }
- }
-
- if (metadata->entity) {
- if (metadata->entity->topic) {
- std::ostringstream str;
- str << kEntityTopicKey << metadata->entity->topic;
- ret.insert(str.str());
- }
- if (metadata->entity->type) {
- for (const auto& type : *metadata->entity->type) {
- std::ostringstream str;
- str << kEntityTypeKey << type;
- ret.insert(str.str());
- }
- }
- }
- }
-
- std::ostringstream str;
- str << kContextValueTypeKey << fidl::ToUnderlying(node_type);
- ret.insert(str.str());
-
- return ret;
-}
-
-} // namespace internal
-
-void ContextIndex::Add(Id id, fuchsia::modular::ContextValueType type,
- const fuchsia::modular::ContextMetadata& metadata) {
- auto keys = internal::EncodeMetadataAndType(type, metadata);
- for (const auto& key : keys) {
- index_[key].insert(id);
- }
-}
-
-void ContextIndex::Remove(Id id, fuchsia::modular::ContextValueType type,
- const fuchsia::modular::ContextMetadata& metadata) {
- auto keys = internal::EncodeMetadataAndType(type, metadata);
- for (const auto& key : keys) {
- index_[key].erase(id);
- }
-}
-
-void ContextIndex::Query(fuchsia::modular::ContextValueType type,
- const fuchsia::modular::ContextMetadataPtr& metadata,
- std::set<ContextIndex::Id>* out) {
- FXL_DCHECK(out != nullptr);
-
- auto keys = internal::EncodeMetadataAndType(type, metadata);
- std::set<ContextIndex::Id> ret;
- if (keys.empty())
- return;
- const auto& first = index_[*keys.begin()];
- ret.insert(first.begin(), first.end());
- keys.erase(keys.begin());
-
- for (const auto& key : keys) {
- std::set<ContextIndex::Id> intersection;
- const auto& posting_list = index_[key];
- std::set_intersection(ret.begin(), ret.end(), posting_list.begin(),
- posting_list.end(),
- std::inserter(intersection, intersection.begin()));
- ret.swap(intersection);
- }
-
- out->insert(ret.begin(), ret.end());
-}
-
-} // namespace modular
diff --git a/bin/context_engine/index.h b/bin/context_engine/index.h
deleted file mode 100644
index 528bd70..0000000
--- a/bin/context_engine/index.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// This class maintains an inverted index for fuchsia::modular::ContextMetadata
-// structs. It helps answer the question "what objects have metadata that
-// matches these key/value pairs" very efficiently.
-
-#ifndef PERIDOT_BIN_CONTEXT_ENGINE_INDEX_H_
-#define PERIDOT_BIN_CONTEXT_ENGINE_INDEX_H_
-
-#include <map>
-#include <set>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace modular {
-
-namespace internal {
-
-// Returns a set of strings which encode both the keys and values in |metadata|
-// and |type| for use in an inverted index.
-std::set<std::string> EncodeMetadataAndType(
- fuchsia::modular::ContextValueType node_type,
- const fuchsia::modular::ContextMetadataPtr& metadata);
-std::set<std::string> EncodeMetadataAndType(
- fuchsia::modular::ContextValueType node_type,
- const fuchsia::modular::ContextMetadata& metadata);
-} // namespace internal
-
-class ContextIndex {
- public:
- // TODO(thatguy): Move this enum into context_repository.cc.
- using Id = std::string;
-
- ContextIndex();
- ~ContextIndex();
-
- void Add(Id id, fuchsia::modular::ContextValueType type,
- const fuchsia::modular::ContextMetadata& metadata);
- void Remove(Id id, fuchsia::modular::ContextValueType type,
- const fuchsia::modular::ContextMetadata& metadata);
-
- // Intersects the ids in |out| with those of type |type| and match every
- // field in |metadata|.
- void Query(fuchsia::modular::ContextValueType type,
- const fuchsia::modular::ContextMetadataPtr& metadata,
- std::set<Id>* out);
-
- private:
- // A posting list from encoded value list to ids.
- std::map<std::string, std::set<Id>> index_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_CONTEXT_ENGINE_INDEX_H_
diff --git a/bin/context_engine/index_unittest.cc b/bin/context_engine/index_unittest.cc
deleted file mode 100644
index 6a14523..0000000
--- a/bin/context_engine/index_unittest.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/index.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/clone.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-TEST(IndexTest, Encode_Basic) {
- // Basic encoding correctness:
- // * null case(s)
- // * values are indexed along with their key
- auto type = fuchsia::modular::ContextValueType::ENTITY;
- EXPECT_EQ(1lu, internal::EncodeMetadataAndType(type, nullptr).size());
- EXPECT_EQ(1lu, internal::EncodeMetadataAndType(
- type, fuchsia::modular::ContextMetadata::New())
- .size());
-
- auto meta = fuchsia::modular::ContextMetadata::New();
- meta->story = fuchsia::modular::StoryMetadata::New();
- EXPECT_EQ(1lu, internal::EncodeMetadataAndType(type, meta).size());
-
- meta->story->id = "value";
- auto out = internal::EncodeMetadataAndType(type, meta);
- EXPECT_EQ(2lu, out.size());
-
- meta->mod = fuchsia::modular::ModuleMetadata::New();
- meta->mod->url = "value";
- out = internal::EncodeMetadataAndType(type, meta);
- // Even though we use "value" as the value for both fields above, we should
- // see them encoded differently since they are for different fields.
- EXPECT_EQ(3lu, out.size());
-}
-
-TEST(IndexTest, Encode_Differences) {
- auto kEntity = fuchsia::modular::ContextValueType::ENTITY;
- auto kStory = fuchsia::modular::ContextValueType::STORY;
- // Encoding two entirely different fuchsia::modular::ContextMetadata structs
- // should produce two non-intersecting sets of encodings.
- fuchsia::modular::ContextMetadata meta1;
- meta1.story = fuchsia::modular::StoryMetadata::New();
- meta1.story->id = "story1";
- meta1.story->focused = fuchsia::modular::FocusedState::New();
- meta1.story->focused->state = fuchsia::modular::FocusedStateState::FOCUSED;
- meta1.mod = fuchsia::modular::ModuleMetadata::New();
- meta1.mod->url = "url1";
- meta1.mod->path = fidl::VectorPtr<std::string>::New(0);
- meta1.mod->path.push_back("1");
- meta1.mod->path.push_back("2");
- meta1.mod->focused = fuchsia::modular::FocusedState::New();
- meta1.mod->focused->state = fuchsia::modular::FocusedStateState::FOCUSED;
- meta1.entity = fuchsia::modular::EntityMetadata::New();
- meta1.entity->topic = "topic1";
- meta1.entity->type = fidl::VectorPtr<std::string>::New(0);
- meta1.entity->type.push_back("type1");
- meta1.entity->type.push_back("type2");
-
- auto meta2 = fuchsia::modular::ContextMetadata::New();
- meta2->story = fuchsia::modular::StoryMetadata::New();
- meta2->story->id = "story2";
- meta2->story->focused = fuchsia::modular::FocusedState::New();
- meta2->story->focused->state =
- fuchsia::modular::FocusedStateState::NOT_FOCUSED;
- meta2->mod = fuchsia::modular::ModuleMetadata::New();
- meta2->mod->url = "url2";
- meta2->mod->path = fidl::VectorPtr<std::string>::New(0);
- meta2->mod->path.push_back("2");
- meta2->mod->focused = fuchsia::modular::FocusedState::New();
- meta2->mod->focused->state = fuchsia::modular::FocusedStateState::NOT_FOCUSED;
- meta2->entity = fuchsia::modular::EntityMetadata::New();
- meta2->entity->topic = "topic2";
- meta2->entity->type = fidl::VectorPtr<std::string>::New(0);
- meta2->entity->type.push_back("type3");
- meta2->entity->type.push_back("type4");
- meta2->entity->type.push_back("type5");
-
- auto encoded1 = internal::EncodeMetadataAndType(kEntity, meta1);
- auto encoded2 = internal::EncodeMetadataAndType(kStory, meta2);
-
- // Every field we set has a value here. entity->type fields each get their
- // own.
- EXPECT_EQ(9lu, encoded1.size());
- EXPECT_EQ(10lu, encoded2.size());
-
- std::set<std::string> intersection;
- std::set_intersection(encoded1.begin(), encoded1.end(), encoded2.begin(),
- encoded2.end(),
- std::inserter(intersection, intersection.begin()));
- EXPECT_TRUE(intersection.empty());
-
- // If we start changing some values to be equal, we should see encoded values
- // included.
- meta2->story->focused->state = fuchsia::modular::FocusedStateState::FOCUSED;
- meta2->entity->type->at(1) = "type2";
-
- encoded1 = internal::EncodeMetadataAndType(kEntity, meta1);
- encoded2 = internal::EncodeMetadataAndType(kEntity, meta2);
- intersection.clear();
- std::set_intersection(encoded1.begin(), encoded1.end(), encoded2.begin(),
- encoded2.end(),
- std::inserter(intersection, intersection.begin()));
- EXPECT_EQ(3lu, intersection.size());
-}
-
-TEST(IndexTest, AddRemoveQuery) {
- auto kEntity = fuchsia::modular::ContextValueType::ENTITY;
- auto kStory = fuchsia::modular::ContextValueType::STORY;
- // We do not need to test that querying works for every single field in
- // fuchsia::modular::ContextMetadata: between the Encode tests above, and the
- // knowledge that Encode is used internally by ContextIndex, we can test here
- // for correct query results for a subset of fields, and infer that the same
- // behavior would happen for other fields.
- ContextIndex index;
- fuchsia::modular::ContextMetadata meta1;
- meta1.story = fuchsia::modular::StoryMetadata::New();
- meta1.story->id = "story1";
- meta1.entity = fuchsia::modular::EntityMetadata::New();
- meta1.entity->topic = "topic1";
- meta1.entity->type = fidl::VectorPtr<std::string>::New(0);
- meta1.entity->type.push_back("type1");
- meta1.entity->type.push_back("type2");
-
- index.Add("e1", kEntity, meta1);
-
- // This query won't match because story->id != "s".
- auto query1 = fuchsia::modular::ContextMetadata::New();
- query1->story = fuchsia::modular::StoryMetadata::New();
- query1->story->id = "s"; // Won't match.
- std::set<std::string> res;
- index.Query(kEntity, query1, &res);
- EXPECT_TRUE(res.empty());
-
- // This one still won't because kStory != kEntity.
- query1->story->id = "story1";
- res.clear();
- index.Query(kStory, query1, &res);
- EXPECT_TRUE(res.empty());
-
- // This one will.
- query1->story->id = "story1";
- res.clear();
- index.Query(kEntity, query1, &res);
- EXPECT_EQ(1ul, res.size());
- EXPECT_TRUE(res.find("e1") != res.end());
-
- // Add more to the query that we know will match.
- query1->entity = fuchsia::modular::EntityMetadata::New();
- query1->entity->type.push_back("type1");
- res.clear();
- index.Query(kEntity, query1, &res);
- EXPECT_EQ(1ul, res.size());
- EXPECT_TRUE(res.find("e1") != res.end());
-
- // Add a new entity.
- auto meta2 = fidl::Clone(meta1);
- meta2.entity->type.push_back("type3");
- index.Add("e2", kEntity, meta2);
-
- res.clear();
- index.Query(kEntity, query1, &res);
- EXPECT_EQ(2ul, res.size());
- EXPECT_TRUE(res.find("e1") != res.end());
- EXPECT_TRUE(res.find("e2") != res.end());
-
- // Changing the query's type param to "type3" should only return "e2".
- query1->entity->type->at(0) = "type3";
- res.clear();
- index.Query(kEntity, query1, &res);
- EXPECT_EQ(1ul, res.size());
- EXPECT_TRUE(res.find("e2") != res.end());
-
- // And removing "e2" from the index makes it no longer appear in
- // query results.
- index.Remove("e2", kEntity, meta2);
- res.clear();
- index.Query(kEntity, query1, &res);
- EXPECT_TRUE(res.empty());
-
- // But "e1" is still there.
- query1->entity->type->at(0) = "type2";
- res.clear();
- index.Query(kEntity, query1, &res);
- EXPECT_EQ(1ul, res.size());
- EXPECT_TRUE(res.find("e1") != res.end());
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/context_engine/meta/context_engine.cmx b/bin/context_engine/meta/context_engine.cmx
deleted file mode 100644
index 46ad68e..0000000
--- a/bin/context_engine/meta/context_engine.cmx
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/bin/context_engine/meta/context_index_unittest.cmx b/bin/context_engine/meta/context_index_unittest.cmx
deleted file mode 100644
index a77ae85..0000000
--- a/bin/context_engine/meta/context_index_unittest.cmx
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "program": {
- "binary": "test/context_index_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
diff --git a/bin/context_engine/meta/context_repository_unittest.cmx b/bin/context_engine/meta/context_repository_unittest.cmx
deleted file mode 100644
index 8b35548..0000000
--- a/bin/context_engine/meta/context_repository_unittest.cmx
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "program": {
- "binary": "test/context_repository_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
diff --git a/bin/context_engine/scope_utils.cc b/bin/context_engine/scope_utils.cc
deleted file mode 100644
index 2338c33..0000000
--- a/bin/context_engine/scope_utils.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/context_engine/scope_utils.h"
-
-#include <regex>
-#include <sstream>
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/vector.h>
-#include <lib/fxl/logging.h>
-#include <openssl/sha.h>
-
-namespace maxwell {
-
-fuchsia::modular::ContextSelectorPtr ComponentScopeToContextSelector(
- const fuchsia::modular::ComponentScopePtr& scope) {
- fuchsia::modular::ContextSelectorPtr selector;
- if (!scope || scope->is_global_scope())
- return selector;
- selector = fuchsia::modular::ContextSelector::New();
- if (scope->is_module_scope()) {
- selector->type = fuchsia::modular::ContextValueType::MODULE;
- selector->meta = fuchsia::modular::ContextMetadata::New();
- selector->meta->story = fuchsia::modular::StoryMetadata::New();
- selector->meta->story->id = scope->module_scope().story_id;
- selector->meta->mod = fuchsia::modular::ModuleMetadata::New();
- selector->meta->mod->path = fidl::VectorPtr(scope->module_scope().module_path);
- } else if (scope->is_agent_scope()) {
- // TODO(thatguy): do.
- } else if (scope->is_story_scope()) {
- selector->type = fuchsia::modular::ContextValueType::STORY;
- selector->meta = fuchsia::modular::ContextMetadata::New();
- selector->meta->story = fuchsia::modular::StoryMetadata::New();
- selector->meta->story->id = scope->story_scope().story_id;
- }
-
- return selector;
-}
-
-} // namespace maxwell
diff --git a/bin/context_engine/scope_utils.h b/bin/context_engine/scope_utils.h
deleted file mode 100644
index 287f91d..0000000
--- a/bin/context_engine/scope_utils.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_CONTEXT_ENGINE_SCOPE_UTILS_H_
-#define PERIDOT_BIN_CONTEXT_ENGINE_SCOPE_UTILS_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace maxwell {
-
-fuchsia::modular::ContextSelectorPtr ComponentScopeToContextSelector(
- const fuchsia::modular::ComponentScopePtr& scope);
-
-} // namespace maxwell
-
-#endif // PERIDOT_BIN_CONTEXT_ENGINE_SCOPE_UTILS_H_
diff --git a/bin/ledger/BUILD.gn b/bin/ledger/BUILD.gn
deleted file mode 100644
index dc487b6..0000000
--- a/bin/ledger/BUILD.gn
+++ /dev/null
@@ -1,205 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fuzzing/fuzzer.gni")
-import("//build/package.gni")
-import("//build/testing/secret_spec.gni")
-import("//peridot/bin/ledger/testing/sync_params.gni")
-
-visibility = [ "//peridot/*" ]
-
-package("ledger") {
- deps = [
- "app",
- "cobalt:ledger_metrics_registry",
- ]
-
- binary = "ledger"
-
- meta = [
- {
- path = rebase_path("meta/ledger.cmx")
- dest = "ledger.cmx"
- },
- ]
-
- resources = [
- {
- path = rebase_path(
- get_label_info("cobalt:ledger_metrics_registry",
- "target_gen_dir") + "/ledger_metrics_registry.pb")
- dest = "ledger_cobalt_config.pb"
- },
- {
- path = rebase_path(
- get_label_info("cobalt:ledger_metrics_registry",
- "target_gen_dir") + "/ledger_metrics_registry.pb")
- dest = "firebase_auth_cobalt_config.pb"
- },
- ]
-}
-
-package("ledger_tests") {
- testonly = true
-
- deps = [
- ":ledger_e2e_sync_credentials",
- ":ledger_unittests",
- "//peridot/bin/cloud_provider_firestore:tests",
- "//peridot/bin/ledger/tests/cloud_provider",
- "//peridot/bin/ledger/tests/e2e_local",
- "//peridot/bin/ledger/tests/e2e_sync",
- "//peridot/bin/ledger/tests/integration",
- ]
-
- meta = [
- {
- path = rebase_path("tests/ledger_unittests.cmx")
- dest = "ledger_unittests.cmx"
- },
- {
- path = rebase_path("tests/integration/ledger_integration_tests.cmx")
- dest = "ledger_integration_tests.cmx"
- },
- {
- path = rebase_path("tests/e2e_local/ledger_e2e_local.cmx")
- dest = "ledger_e2e_local.cmx"
- },
- {
- path = rebase_path("tests/e2e_sync/ledger_e2e_sync.cmx")
- dest = "ledger_e2e_sync.cmx"
- },
- {
- path = rebase_path(
- "//peridot/bin/cloud_provider_firestore/cloud_provider_firestore_unittests.cmx")
- dest = "cloud_provider_firestore_unittests.cmx"
- },
- {
- path = rebase_path(
- "//peridot/bin/cloud_provider_firestore/validation/validation_firestore.cmx")
- dest = "validation_firestore.cmx"
- },
- {
- # This test must be started by validation_firestore and will fail if started on its own.
- path = rebase_path(
- "tests/cloud_provider/cloud_provider_validation_tests.cmx")
- dest = "cloud_provider_validation_tests.cmx"
- },
- ]
-
- tests = [
- {
- name = "ledger_unittests"
- },
- {
- name = "ledger_integration_tests"
- },
- {
- name = "ledger_e2e_local"
- },
- {
- name = "cloud_provider_firestore_unittests"
- },
-
- {
- name = "ledger_e2e_sync"
-
- # This test needs additional configuration and should not run by default.
- # Marking it as disabled puts the binary in `test/disabled/` under the
- # package directory.
- disabled = true
- },
- {
- name = "launch_validation_tests_firestore"
-
- # This test needs additional configuration and should not run by default.
- # Marking it as disabled puts the binary in `test/disabled/` under the
- # package directory.
- disabled = true
- },
- {
- name = "cloud_provider_validation_tests"
-
- # This test must be started by validation_firestore and will fail if started on its own.
- # Marking it as disabled puts the binary in `test/disabled/` under the
- # package directory.
- disabled = true
- },
- ]
-
- resources = []
- if (ledger_sync_credentials_file != "") {
- resources += [
- {
- path = ledger_sync_credentials_file
- dest = "sync_credentials.json"
- },
- ]
- }
-}
-
-secret_spec("ledger_e2e_sync_credentials") {
- key_name = "ledger-tests-remote"
-
- ciphertext_file = "ledger_e2e_sync_credentials.ciphertext"
-}
-
-config("ledger_config") {
- asmflags = []
-
- cflags = [
- # Remove when enabled globally by TO-99.
- "-Wunused-lambda-capture",
-
- # Remove when enabled globally by TO-100.
- "-Wuser-defined-warnings",
-
- # Warn about unreachable code.
- "-Wunreachable-code",
- ]
-
- ldflags = [
- # Use a 1M stack.
- "-Wl,-z,stack-size=0x100000",
- ]
-}
-
-executable("ledger_unittests") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/fxl:fxl_printers",
- "//peridot/bin/ledger/app:unittests",
- "//peridot/bin/ledger/cache:unittests",
- "//peridot/bin/ledger/cloud_sync/impl:unittests",
- "//peridot/bin/ledger/coroutine:unittests",
- "//peridot/bin/ledger/coroutine/context:unittests",
- "//peridot/bin/ledger/encryption/impl:unittests",
- "//peridot/bin/ledger/encryption/primitives:unittests",
- "//peridot/bin/ledger/environment:unittests",
- "//peridot/bin/ledger/fidl/error_notifier:unittests",
- "//peridot/bin/ledger/filesystem:unittests",
- "//peridot/bin/ledger/lock:unittests",
- "//peridot/bin/ledger/p2p_provider/impl:unittests",
- "//peridot/bin/ledger/p2p_sync/impl:unittests",
- "//peridot/bin/ledger/storage/impl:unittests",
- "//peridot/bin/ledger/storage/impl/btree:unittests",
- "//peridot/bin/ledger/storage/public:unittests",
- "//peridot/bin/ledger/storage/testing:unittests",
- "//peridot/bin/ledger/sync_helper:unittests",
- "//peridot/bin/ledger/testing:unittests",
- "//peridot/bin/ledger/testing/netconnector:unittests",
- "//third_party/googletest:gtest_main",
- ]
-
- configs += [ ":ledger_config" ]
-}
-
-fuzz_package("ledger_fuzzers") {
- targets = [ "//peridot/bin/ledger/storage/impl/btree:encoding_fuzzer" ]
- sanitizers = [
- "asan",
- "ubsan",
- ]
-}
diff --git a/bin/ledger/README.md b/bin/ledger/README.md
deleted file mode 100644
index aed8e87..0000000
--- a/bin/ledger/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Ledger
-
-Implementation of Ledger.
-
-## Contents
-
- - [app](app) implements Ledger fidl API
- - [cache](cache)
- - [cloud_sync](cloud_sync) implements Ledger synchronisation via cloud
- - [cobalt](cobalt) contains helper methods for reporting Cobalt events
- - [coroutine](coroutine) coroutine library
- - [encryption](encryption) implements encryption service for Ledger
- - [environment](environment)
- - [fidl](fidl) FIDL interfaces internal to Ledger and peridot framework (not exposed to upper layers)
- - [fidl_helpers](fidl_helpers)
- - [lock](lock)
- - [filesystem](filesystem) contains filesystem-related helper functions
- - [p2p_provider](p2p_provider) implements P2P primitives powering the P2P sync
- - [p2p_sync](p2p_sync) implements Ledger synchronisation via P2P
- - [storage](storage) implements persistent representation of data held in
- Ledger
- - [testing](testing) contains helper functions used for testing Ledger
- - [tests](tests) contains tests and benchmarks for Ledger
diff --git a/bin/ledger/app/BUILD.gn b/bin/ledger/app/BUILD.gn
deleted file mode 100644
index 41a3aba..0000000
--- a/bin/ledger/app/BUILD.gn
+++ /dev/null
@@ -1,203 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- # needed to access the serialization version constant
- # TODO(ppi): extract the serialization version constant to a separate library
- "//peridot/bin/cloud_provider_firestore/*",
- "//peridot/bin/ledger/*",
-]
-
-executable("app") {
- output_name = "ledger"
- sources = [
- "app.cc",
- ]
-
- deps = [
- ":lib",
- "//garnet/public/fidl/fuchsia.net.oldhttp",
- "//garnet/public/fidl/fuchsia.netconnector",
- "//garnet/public/lib/backoff",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/cobalt",
- "//peridot/bin/ledger/environment",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/ledger/fidl:error_notifier",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/p2p_sync/impl",
- "//peridot/bin/ledger/storage/impl:lib",
- "//peridot/bin/ledger/storage/public",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("lib") {
- sources = [
- "branch_tracker.cc",
- "branch_tracker.h",
- "constants.cc",
- "constants.h",
- "delaying_facade.h",
- "diff_utils.cc",
- "diff_utils.h",
- "disk_cleanup_manager.h",
- "disk_cleanup_manager_impl.cc",
- "disk_cleanup_manager_impl.h",
- "fidl/serialization_size.cc",
- "fidl/serialization_size.h",
- "ledger_impl.cc",
- "ledger_impl.h",
- "ledger_manager.cc",
- "ledger_manager.h",
- "ledger_repository_factory_impl.cc",
- "ledger_repository_factory_impl.h",
- "ledger_repository_impl.cc",
- "ledger_repository_impl.h",
- "merging/auto_merge_strategy.cc",
- "merging/auto_merge_strategy.h",
- "merging/common_ancestor.cc",
- "merging/common_ancestor.h",
- "merging/conflict_resolver_client.cc",
- "merging/conflict_resolver_client.h",
- "merging/custom_merge_strategy.cc",
- "merging/custom_merge_strategy.h",
- "merging/last_one_wins_merge_strategy.cc",
- "merging/last_one_wins_merge_strategy.h",
- "merging/ledger_merge_manager.cc",
- "merging/ledger_merge_manager.h",
- "merging/merge_resolver.cc",
- "merging/merge_resolver.h",
- "merging/merge_strategy.h",
- "page_delaying_facade.cc",
- "page_delaying_facade.h",
- "page_delegate.cc",
- "page_delegate.h",
- "page_eviction_manager.h",
- "page_eviction_manager_impl.cc",
- "page_eviction_manager_impl.h",
- "page_eviction_policies.cc",
- "page_eviction_policies.h",
- "page_impl.cc",
- "page_impl.h",
- "page_manager.cc",
- "page_manager.h",
- "page_snapshot_impl.cc",
- "page_snapshot_impl.h",
- "page_usage_db.cc",
- "page_usage_db.h",
- "page_usage_listener.h",
- "page_utils.cc",
- "page_utils.h",
- "sync_watcher_set.cc",
- "sync_watcher_set.h",
- "types.h",
- ]
-
- deps = [
- ":serialization_version",
- "//garnet/public/fidl/fuchsia.netconnector",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/cloud_sync/impl",
- "//peridot/bin/ledger/cloud_sync/public",
- "//peridot/bin/ledger/cobalt",
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/environment",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/ledger/fidl:error_notifier",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/fidl_helpers",
- "//peridot/bin/ledger/filesystem",
- "//peridot/bin/ledger/lock",
- "//peridot/bin/ledger/p2p_provider/impl",
- "//peridot/bin/ledger/p2p_sync/impl",
- "//peridot/bin/ledger/p2p_sync/public",
- "//peridot/bin/ledger/storage/impl:lib",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/sync_coordinator/impl",
- "//peridot/bin/ledger/sync_coordinator/public",
- "//peridot/lib/base64url:base64url",
- "//peridot/lib/convert",
- "//peridot/lib/socket",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//zircon/public/lib/trace",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("serialization_version") {
- sources = [
- "serialization_version.h",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "delaying_facade_unittest.cc",
- "disk_cleanup_manager_unittest.cc",
- "fidl/serialization_size_unittest.cc",
- "ledger_manager_unittest.cc",
- "ledger_repository_factory_impl_unittest.cc",
- "ledger_repository_impl_unittest.cc",
- "merging/common_ancestor_unittest.cc",
- "merging/conflict_resolver_client_unittest.cc",
- "merging/merge_resolver_unittest.cc",
- "merging/test_utils.cc",
- "merging/test_utils.h",
- "page_eviction_manager_impl_unittest.cc",
- "page_eviction_policies_unittest.cc",
- "page_impl_unittest.cc",
- "page_manager_unittest.cc",
- "page_usage_db_unittest.cc",
- "sync_watcher_set_unittest.cc",
- ]
-
- deps = [
- ":lib",
- "//garnet/public/lib/backoff/testing",
- "//garnet/public/lib/component/cpp:cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/cloud_sync/impl",
- "//peridot/bin/ledger/cloud_sync/testing",
- "//peridot/bin/ledger/encryption/fake",
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/fidl/include:include",
- "//peridot/bin/ledger/storage/fake:lib",
- "//peridot/bin/ledger/storage/impl:lib",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/storage/testing",
- "//peridot/bin/ledger/sync_coordinator/public",
- "//peridot/bin/ledger/sync_coordinator/testing",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/lib/scoped_tmpfs",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/app/app.cc b/bin/ledger/app/app.cc
deleted file mode 100644
index 864ae37..0000000
--- a/bin/ledger/app/app.cc
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <memory>
-#include <utility>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/log_settings_command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <trace-provider/provider.h>
-#include <zircon/device/vfs.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/ledger_repository_factory_impl.h"
-#include "peridot/bin/ledger/cobalt/cobalt.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/fidl/error_notifier.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/p2p_sync/impl/user_communicator_factory_impl.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kNoStatisticsReportingFlag = "disable_reporting";
-constexpr fxl::StringView kFirebaseApiKeyFlag = "firebase_api_key";
-
-struct AppParams {
- bool disable_statistics = false;
- std::string firebase_api_key = "";
-};
-
-fit::deferred_action<fit::closure> SetupCobalt(
- bool disable_statistics, async_dispatcher_t* dispatcher,
- component::StartupContext* startup_context) {
- if (disable_statistics) {
- return fit::defer<fit::closure>([] {});
- }
- return InitializeCobalt(dispatcher, startup_context);
-};
-
-// App is the main entry point of the Ledger application.
-//
-// It is responsible for setting up the LedgerRepositoryFactory, which connects
-// clients to individual Ledger instances. It should not however hold long-lived
-// objects shared between Ledger instances, as we need to be able to put them in
-// separate processes when the app becomes multi-instance.
-class App : public ledger_internal::LedgerController {
- public:
- explicit App(AppParams app_params)
- : app_params_(app_params),
- loop_(&kAsyncLoopConfigAttachToThread),
- io_loop_(&kAsyncLoopConfigNoAttachToThread),
- trace_provider_(loop_.dispatcher()),
- startup_context_(component::StartupContext::CreateFromStartupInfo()),
- cobalt_cleaner_(SetupCobalt(app_params_.disable_statistics,
- loop_.dispatcher(),
- startup_context_.get())) {
- FXL_DCHECK(startup_context_);
-
- ReportEvent(CobaltEvent::LEDGER_STARTED);
- }
- ~App() override {}
-
- bool Start() {
- io_loop_.StartThread("io thread");
-
- EnvironmentBuilder builder;
-
- if (!app_params_.firebase_api_key.empty()) {
- builder.SetFirebaseApiKey(app_params_.firebase_api_key);
- }
-
- environment_ = std::make_unique<Environment>(
- builder.SetDisableStatistics(app_params_.disable_statistics)
- .SetAsync(loop_.dispatcher())
- .SetIOAsync(io_loop_.dispatcher())
- .SetStartupContext(startup_context_.get())
- .Build());
- auto user_communicator_factory =
- std::make_unique<p2p_sync::UserCommunicatorFactoryImpl>(
- environment_.get());
-
- factory_impl_ = std::make_unique<LedgerRepositoryFactoryImpl>(
- environment_.get(), std::move(user_communicator_factory),
- *startup_context_->outgoing().object_dir());
-
- startup_context_->outgoing()
- .AddPublicService<ledger_internal::LedgerRepositoryFactory>(
- [this](
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryFactory>
- request) {
- factory_bindings_.emplace(factory_impl_.get(),
- std::move(request));
- });
- startup_context_->outgoing().AddPublicService<LedgerController>(
- [this](fidl::InterfaceRequest<LedgerController> request) {
- controller_bindings_.AddBinding(this, std::move(request));
- });
-
- startup_context_->outgoing().object_dir()->set_prop(
- "statistic_gathering", app_params_.disable_statistics ? "off" : "on");
-
- startup_context_->outgoing().object_dir()->set_children_callback(
- {kRepositoriesInspectPathComponent},
- [this](component::Object::ObjectVector* out) {
- factory_impl_->GetChildren(out);
- });
-
- loop_.Run();
-
- startup_context_->outgoing().object_dir()->set_children_callback(
- {kRepositoriesInspectPathComponent}, nullptr);
-
- return true;
- }
-
- private:
- // LedgerController:
- void Terminate() override { loop_.Quit(); }
-
- const AppParams app_params_;
- async::Loop loop_;
- async::Loop io_loop_;
- trace::TraceProvider trace_provider_;
- std::unique_ptr<component::StartupContext> startup_context_;
- fit::deferred_action<fit::closure> cobalt_cleaner_;
- std::unique_ptr<Environment> environment_;
- std::unique_ptr<LedgerRepositoryFactoryImpl> factory_impl_;
- callback::AutoCleanableSet<ErrorNotifierBinding<
- fuchsia::ledger::internal::LedgerRepositoryFactoryErrorNotifierDelegate>>
- factory_bindings_;
- fidl::BindingSet<LedgerController> controller_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(App);
-};
-
-int Main(int argc, const char** argv) {
- const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- fxl::SetLogSettingsFromCommandLine(command_line);
-
- AppParams app_params;
- app_params.disable_statistics =
- command_line.HasOption(kNoStatisticsReportingFlag);
- if (command_line.HasOption(kFirebaseApiKeyFlag)) {
- if (!command_line.GetOptionValue(kFirebaseApiKeyFlag,
- &app_params.firebase_api_key)) {
- FXL_LOG(ERROR) << "Unable to retrieve the firebase api key.";
- return 1;
- }
- }
-
- App app(app_params);
- if (!app.Start()) {
- return 1;
- }
-
- return 0;
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/app/branch_tracker.cc b/bin/ledger/app/branch_tracker.cc
deleted file mode 100644
index 7695096..0000000
--- a/bin/ledger/app/branch_tracker.cc
+++ /dev/null
@@ -1,398 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/branch_tracker.h"
-
-#include <vector>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/app/diff_utils.h"
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-
-namespace ledger {
-class BranchTracker::PageWatcherContainer {
- public:
- PageWatcherContainer(coroutine::CoroutineService* coroutine_service,
- PageWatcherPtr watcher, PageManager* page_manager,
- storage::PageStorage* storage,
- std::unique_ptr<const storage::Commit> base_commit,
- std::string key_prefix)
- : change_in_flight_(false),
- last_commit_(std::move(base_commit)),
- coroutine_service_(coroutine_service),
- key_prefix_(std::move(key_prefix)),
- manager_(page_manager),
- storage_(storage),
- interface_(std::move(watcher)),
- weak_factory_(this) {
- interface_.set_error_handler([this](zx_status_t status) {
- if (handler_) {
- handler_->Resume(coroutine::ContinuationStatus::INTERRUPTED);
- }
- FXL_DCHECK(!handler_);
- if (on_empty_callback_) {
- on_empty_callback_();
- }
- });
- }
-
- ~PageWatcherContainer() {
- if (on_drained_) {
- on_drained_();
- }
- if (handler_) {
- handler_->Resume(coroutine::ContinuationStatus::INTERRUPTED);
- }
- FXL_DCHECK(!handler_);
- }
-
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- void UpdateCommit(std::unique_ptr<const storage::Commit> commit) {
- current_commit_ = std::move(commit);
- SendCommit();
- }
-
- // Sets a callback to be called when all pending updates are sent. If all
- // updates are already sent, the callback will be called immediately. This
- // callback will only be called once; |SetOnDrainedCallback| should be called
- // again to set a new callback after the first one is called. Setting a
- // callback while a previous one is still active will execute the previous
- // callback.
- void SetOnDrainedCallback(fit::closure on_drained) {
- // If a transaction is committed or rolled back before all watchers have
- // been drained, we do not want to continue blocking until they drain. Thus,
- // we declare them drained right away and proceed.
- if (on_drained_) {
- on_drained_();
- on_drained_ = nullptr;
- }
- on_drained_ = std::move(on_drained);
- if (Drained() && on_drained_) {
- on_drained_();
- on_drained_ = nullptr;
- }
- }
-
- private:
- // Returns true if all changes have been sent to the watcher client, false
- // otherwise.
- bool Drained() {
- return !current_commit_ ||
- last_commit_->GetId() == current_commit_->GetId();
- }
-
- std::vector<PageChange> PaginateChanges(PageChangePtr change) {
- std::vector<PageChange> changes;
-
- // These are initialized to valid values in the first run of the loop.
- size_t fidl_size = -1;
- size_t handle_count = -1;
- size_t timestamp = change->timestamp;
- auto entries = std::move(change->changed_entries);
- auto deletions = std::move(change->deleted_keys);
- for (size_t i = 0, j = 0; i < entries.size() || j < deletions.size();) {
- bool add_entry = i < entries.size() &&
- (j == deletions.size() ||
- convert::ExtendedStringView(entries.at(i).key) <
- convert::ExtendedStringView(deletions.at(j)));
- size_t entry_size =
- add_entry
- ? fidl_serialization::GetEntrySize(entries.at(i).key.size())
- : fidl_serialization::GetByteVectorSize(deletions.at(j).size());
- size_t entry_handle_count = add_entry ? 1 : 0;
-
- if (changes.empty() ||
- fidl_size + entry_size > fidl_serialization::kMaxInlineDataSize ||
- handle_count + entry_handle_count >
- fidl_serialization::kMaxMessageHandles) {
- PageChange change;
- change.timestamp = timestamp;
- change.changed_entries.resize(0);
- change.deleted_keys.resize(0);
- changes.push_back(std::move(change));
- fidl_size = fidl_serialization::kPageChangeHeaderSize;
- handle_count = 0u;
- }
- fidl_size += entry_size;
- handle_count += entry_handle_count;
- if (add_entry) {
- changes.back().changed_entries.push_back(std::move(entries.at(i)));
- ++i;
- } else {
- changes.back().deleted_keys.push_back(std::move(deletions.at(j)));
- ++j;
- }
- }
- return changes;
- }
-
- void SendChange(PageChange page_change, ResultState state,
- std::unique_ptr<const storage::Commit> new_commit,
- fit::closure on_done) {
- interface_->OnChange(
- std::move(page_change), state,
- [this, state, new_commit = std::move(new_commit),
- on_done = std::move(on_done)](
- fidl::InterfaceRequest<PageSnapshot> snapshot_request) mutable {
- if (snapshot_request) {
- manager_->BindPageSnapshot(
- new_commit->Clone(), std::move(snapshot_request), key_prefix_);
- }
- if (state != ResultState::COMPLETED &&
- state != ResultState::PARTIAL_COMPLETED) {
- on_done();
- return;
- }
- change_in_flight_ = false;
- last_commit_.swap(new_commit);
- // SendCommit will start handling the following commit, so we need
- // to make sure on_done() is called before that.
- on_done();
- SendCommit();
- });
- }
-
- // Sends a commit to the watcher if needed.
- void SendCommit() {
- if (change_in_flight_) {
- return;
- }
-
- if (Drained()) {
- if (on_drained_) {
- on_drained_();
- on_drained_ = nullptr;
- }
- return;
- }
-
- change_in_flight_ = true;
-
- // TODO(etiennej): See LE-74: clean object ownership
- diff_utils::ComputePageChange(
- storage_, *last_commit_, *current_commit_, key_prefix_, key_prefix_,
- diff_utils::PaginationBehavior::NO_PAGINATION,
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, new_commit = std::move(current_commit_)](
- Status status,
- std::pair<PageChangePtr, std::string> page_change_ptr) mutable {
- if (status != Status::OK) {
- // This change notification is abandonned. At the next commit,
- // we will try again (but not before). The next notification
- // will cover both this change and the next.
- FXL_LOG(ERROR)
- << "Unable to compute PageChange for Watch update.";
- change_in_flight_ = false;
- return;
- }
-
- if (!page_change_ptr.first) {
- change_in_flight_ = false;
- last_commit_.swap(new_commit);
- SendCommit();
- return;
- }
- std::vector<PageChange> paginated_changes =
- PaginateChanges(std::move(page_change_ptr.first));
- if (paginated_changes.size() == 1) {
- SendChange(std::move(paginated_changes[0]),
- ResultState::COMPLETED, std::move(new_commit),
- [] {});
- return;
- }
- coroutine_service_->StartCoroutine(
- [this, new_commit = std::move(new_commit),
- paginated_changes = std::move(paginated_changes)](
- coroutine::CoroutineHandler* handler) mutable {
- auto guard = fit::defer([this] { handler_ = nullptr; });
- FXL_DCHECK(!handler_);
- handler_ = handler;
- for (size_t i = 0; i < paginated_changes.size(); ++i) {
- ResultState state;
- if (i == 0) {
- state = ResultState::PARTIAL_STARTED;
- } else if (i == paginated_changes.size() - 1) {
- state = ResultState::PARTIAL_COMPLETED;
- } else {
- state = ResultState::PARTIAL_CONTINUED;
- }
- if (coroutine::SyncCall(
- handler,
- [this, change = std::move(paginated_changes[i]),
- state, new_commit = new_commit->Clone()](
- fit::closure on_done) mutable {
- SendChange(std::move(change), state,
- std::move(new_commit),
- std::move(on_done));
- }) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return;
- }
- }
- });
- }));
- }
-
- fit::closure on_drained_ = nullptr;
- fit::closure on_empty_callback_ = nullptr;
- bool change_in_flight_;
- std::unique_ptr<const storage::Commit> last_commit_;
- std::unique_ptr<const storage::Commit> current_commit_;
- coroutine::CoroutineService* coroutine_service_;
- coroutine::CoroutineHandler* handler_ = nullptr;
- const std::string key_prefix_;
- PageManager* manager_;
- storage::PageStorage* storage_;
- PageWatcherPtr interface_;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<PageWatcherContainer> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageWatcherContainer);
-};
-
-BranchTracker::BranchTracker(coroutine::CoroutineService* coroutine_service,
- PageManager* manager,
- storage::PageStorage* storage)
- : coroutine_service_(coroutine_service),
- manager_(manager),
- storage_(storage),
- transaction_in_progress_(false),
- current_commit_(nullptr),
- weak_factory_(this) {
- watchers_.set_on_empty([this] { CheckEmpty(); });
-}
-
-BranchTracker::~BranchTracker() { storage_->RemoveCommitWatcher(this); }
-
-void BranchTracker::Init(fit::function<void(Status)> on_done) {
- storage_->GetHeadCommitIds(callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, on_done = std::move(on_done)](
- storage::Status status, std::vector<storage::CommitId> commit_ids) {
- if (status != storage::Status::OK) {
- on_done(PageUtils::ConvertStatus(status));
- return;
- }
-
- FXL_DCHECK(!commit_ids.empty());
- InitCommitAndSetWatcher(std::move(commit_ids[0]));
-
- on_done(Status::OK);
- }));
-}
-
-void BranchTracker::set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
-}
-
-const storage::CommitId& BranchTracker::GetBranchHeadId() {
- return current_commit_id_;
-}
-
-void BranchTracker::OnNewCommits(
- const std::vector<std::unique_ptr<const storage::Commit>>& commits,
- storage::ChangeSource /*source*/) {
- bool changed = false;
- const std::unique_ptr<const storage::Commit>* new_current_commit = nullptr;
- for (const auto& commit : commits) {
- if (commit->GetId() == current_commit_id_) {
- continue;
- }
- // This assumes commits are received in (partial) order. If the commit
- // doesn't have current_commit_id_ as a parent it is not part of this branch
- // and should be ignored.
- std::vector<storage::CommitIdView> parent_ids = commit->GetParentIds();
- if (std::find(parent_ids.begin(), parent_ids.end(), current_commit_id_) ==
- parent_ids.end()) {
- continue;
- }
- changed = true;
- current_commit_id_ = commit->GetId();
- new_current_commit = &commit;
- }
- if (changed) {
- current_commit_ = (*new_current_commit)->Clone();
- }
-
- if (!changed || transaction_in_progress_) {
- return;
- }
- for (auto& watcher : watchers_) {
- watcher.UpdateCommit(current_commit_->Clone());
- }
-}
-
-void BranchTracker::StartTransaction(fit::closure watchers_drained_callback) {
- FXL_DCHECK(!transaction_in_progress_);
- transaction_in_progress_ = true;
- auto waiter = fxl::MakeRefCounted<callback::CompletionWaiter>();
- for (auto& watcher : watchers_) {
- watcher.SetOnDrainedCallback(waiter->NewCallback());
- }
- waiter->Finalize(std::move(watchers_drained_callback));
-}
-
-void BranchTracker::StopTransaction(
- std::unique_ptr<const storage::Commit> commit) {
- FXL_DCHECK(transaction_in_progress_ || !commit);
-
- if (!transaction_in_progress_) {
- return;
- }
- transaction_in_progress_ = false;
-
- if (commit) {
- current_commit_id_ = commit->GetId();
- current_commit_ = std::move(commit);
- }
-
- if (!current_commit_) {
- // current_commit_ has a null value only if OnNewCommits has neven been
- // called. Here we are in the case where a transaction stops, but no new
- // commits have arrived in between: there is no need to update the watchers.
- return;
- }
-
- for (auto& watcher : watchers_) {
- watcher.SetOnDrainedCallback(nullptr);
- watcher.UpdateCommit(current_commit_->Clone());
- }
-}
-
-void BranchTracker::RegisterPageWatcher(
- PageWatcherPtr page_watcher_ptr,
- std::unique_ptr<const storage::Commit> base_commit,
- std::string key_prefix) {
- watchers_.emplace(coroutine_service_, std::move(page_watcher_ptr), manager_,
- storage_, std::move(base_commit), std::move(key_prefix));
-}
-
-bool BranchTracker::IsEmpty() { return watchers_.empty(); }
-
-void BranchTracker::InitCommitAndSetWatcher(storage::CommitId commit_id) {
- // current_commit_ will be updated to have a correct value after the first
- // Commit received in OnNewCommits or StopTransaction.
- FXL_DCHECK(!current_commit_);
- current_commit_id_ = std::move(commit_id);
- storage_->AddCommitWatcher(this);
-}
-
-void BranchTracker::CheckEmpty() {
- if (on_empty_callback_ && IsEmpty())
- on_empty_callback_();
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/branch_tracker.h b/bin/ledger/app/branch_tracker.h
deleted file mode 100644
index fc1707c..0000000
--- a/bin/ledger/app/branch_tracker.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_BRANCH_TRACKER_H_
-#define PERIDOT_BIN_LEDGER_APP_BRANCH_TRACKER_H_
-
-#include <memory>
-
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/app/page_snapshot_impl.h"
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/public/commit_watcher.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-class PageManager;
-
-// Tracks the head of a commit "branch". A commit is chosen arbitrarily from the
-// page's head commits at construction. Subsequently, this object will track the
-// head of this commit branch, unless reset by |SetBranchHead|. If two commits
-// have the same parent, the first one to be received will be tracked.
-class BranchTracker : public storage::CommitWatcher {
- public:
- BranchTracker(coroutine::CoroutineService* coroutine_service,
- PageManager* manager, storage::PageStorage* storage);
- ~BranchTracker() override;
-
- void Init(fit::function<void(Status)> on_done);
-
- void set_on_empty(fit::closure on_empty_callback);
-
- // Returns the head commit of the currently tracked branch.
- const storage::CommitId& GetBranchHeadId();
-
- // Registers a new PageWatcher interface.
- void RegisterPageWatcher(PageWatcherPtr page_watcher_ptr,
- std::unique_ptr<const storage::Commit> base_commit,
- std::string key_prefix);
-
- // Informs the BranchTracker that a transaction is in progress. It first
- // drains all pending Watcher updates, then stops sending them until
- // |StopTransaction| is called. |watchers_drained_callback| is called when all
- // watcher updates have been processed by the clients. This should be used by
- // |PageDelegate| when a transaction is in progress.
- void StartTransaction(fit::closure watchers_drained_callback);
-
- // Informs the BranchTracker that a transaction is no longer in progress.
- // Resumes sending updates to registered watchers. This should be used by
- // |PageDelegate| when a transaction is committed or rolled back.
- // |commit| must be the one created by the transaction if it was committed, or
- // nullptr otherwise.
- void StopTransaction(std::unique_ptr<const storage::Commit> commit);
-
- // Returns true if there are no watchers registered.
- bool IsEmpty();
-
- private:
- class PageWatcherContainer;
-
- // storage::CommitWatcher:
- void OnNewCommits(
- const std::vector<std::unique_ptr<const storage::Commit>>& commits,
- storage::ChangeSource source) override;
-
- void InitCommitAndSetWatcher(storage::CommitId commit_id);
-
- void CheckEmpty();
-
- coroutine::CoroutineService* coroutine_service_;
- PageManager* manager_;
- storage::PageStorage* storage_;
- callback::AutoCleanableSet<PageWatcherContainer> watchers_;
- fit::closure on_empty_callback_;
-
- bool transaction_in_progress_;
- // The following two variables hold the commit object and id correspondingly
- // of the commit tracked by this BranchTracker. |current_commit_| is used
- // for notifying the watchers. On initialization, |current_commit_id_| is set
- // to track the first head as returned from PageStorage. |current_commit_| at
- // that point equals nullptr and is only updated with a valid Commit,
- // corresponding to the tracked id, after the first call to OnNewCommits or
- // StopTransaction. Since the notifications are sent to the watchers only
- // after updating the tracked commit, the value of the |current_commit_| at
- // initialization (which is set to nullptr) is not necessary.
- std::unique_ptr<const storage::Commit> current_commit_;
- storage::CommitId current_commit_id_;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<BranchTracker> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BranchTracker);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_BRANCH_TRACKER_H_
diff --git a/bin/ledger/app/constants.cc b/bin/ledger/app/constants.cc
deleted file mode 100644
index 194ad95..0000000
--- a/bin/ledger/app/constants.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/constants.h"
-
-#include <string>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-
-namespace ledger {
-
-namespace {
-const char kNullPageId[::fuchsia::ledger::kPageIdSize] = {};
-} // namespace
-
-// The zero-initialized root id.
-constexpr fxl::StringView kRootPageId(kNullPageId,
- ::fuchsia::ledger::kPageIdSize);
-
-} // namespace ledger
diff --git a/bin/ledger/app/constants.h b/bin/ledger/app/constants.h
deleted file mode 100644
index cc84c4c..0000000
--- a/bin/ledger/app/constants.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_CONSTANTS_H_
-#define PERIDOT_BIN_LEDGER_APP_CONSTANTS_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-// The maximum key size.
-inline constexpr size_t kMaxKeySize = 256;
-
-// The root Page ID.
-extern const fxl::StringView kRootPageId;
-
-// Filename under which the server id used to sync a given user is stored within
-// the repository dir of that user.
-inline constexpr fxl::StringView kServerIdFilename = "server_id";
-
-// The serialization version of PageUsage DB.
-inline constexpr fxl::StringView kPageUsageDbSerializationVersion = "1";
-
-inline constexpr char kRepositoriesInspectPathComponent[] = "repositories";
-inline constexpr char kRequestsInspectPathComponent[] = "requests";
-inline constexpr char kLedgersInspectPathComponent[] = "ledgers";
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_CONSTANTS_H_
diff --git a/bin/ledger/app/delaying_facade.h b/bin/ledger/app/delaying_facade.h
deleted file mode 100644
index 4da1d0c..0000000
--- a/bin/ledger/app/delaying_facade.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_DELAYING_FACADE_H_
-#define PERIDOT_BIN_LEDGER_APP_DELAYING_FACADE_H_
-
-#include <tuple>
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/functional/apply.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-
-namespace ledger {
-
-// A delaying facade.
-//
-// Stores the methods to be called on an object, together with their arguments,
-// once that object becomes available. An example of usage is the following:
-//
-// For an object of type SomeClass:
-// class SomeClass {
-// void doSomething(int a, string b);
-// };
-//
-// We would declare a DelayingFacade:
-// DelayingFacade<SomeClass> df;
-// df.EnqueueCall(&SomeClass::doSomething, 100, "foo");
-// df.EnqueueCall(&SomeClass::doSomething, 200, "bar");
-// // None of the above is executed, yet.
-//
-// SomeClass object;
-// df.SetTargetObject(&object); // All previous operations are now executed.
-//
-// // The operations following a SetTargetObject are executed immediately.
-// df.EnqueueCall(&SomeClass::doSomething, 300, "baz");
-template <typename A>
-class DelayingFacade {
- public:
- // Adds a method to be called on an object, with the given arguments, once
- // that object becomes available. If the target object was previously set, the
- // method will be called directly.
- template <typename... Args>
- void EnqueueCall(void (A::*function_pointer)(Args...), Args... args) {
- if (object_) {
- (object_->*function_pointer)(std::forward<Args>(args)...);
- return;
- }
- delayed_calls_.push_back(
- [function_pointer,
- tuple = std::make_tuple(std::forward<Args>(args)...)](A* a) mutable {
- fxl::Apply(
- [&](auto... args) {
- (a->*function_pointer)(std::forward<Args>(args)...);
- },
- std::move(tuple));
- });
- }
-
- // Sets the target object on which all methods will be executed. This includes
- // methods added from previous calls to Front, and also all future ones.
- void SetTargetObject(A* object) {
- // Check that the object was not set before.
- FXL_DCHECK(!object_);
- FXL_DCHECK(object);
- object_ = object;
- auto calls = std::move(delayed_calls_);
- for (auto& f : calls) {
- f(object);
- }
- }
-
- private:
- std::vector<fit::function<void(A*)>> delayed_calls_;
- A* object_ = nullptr;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_DELAYING_FACADE_H_
diff --git a/bin/ledger/app/delaying_facade_unittest.cc b/bin/ledger/app/delaying_facade_unittest.cc
deleted file mode 100644
index 9714aad..0000000
--- a/bin/ledger/app/delaying_facade_unittest.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/delaying_facade.h"
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace ledger {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-using ::testing::SizeIs;
-
-class Foo {
- public:
- void AddNumber(int i) { numbers.push_back(i); }
-
- void AddUniqueNumber(std::unique_ptr<int> i) {
- unique_numbers.push_back(std::move(i));
- }
-
- std::vector<int> numbers;
- std::vector<std::unique_ptr<int>> unique_numbers;
-};
-
-TEST(DelayingFacadeTest, CallOrder) {
- Foo foo;
- DelayingFacade<Foo> delayed_foo;
-
- // None of the operations should be executed before the object is set.
- delayed_foo.EnqueueCall(&Foo::AddNumber, 0);
- EXPECT_THAT(foo.numbers, IsEmpty());
- foo.AddNumber(1);
- EXPECT_THAT(foo.numbers, ElementsAre(1));
-
- delayed_foo.EnqueueCall(&Foo::AddNumber, 2);
- EXPECT_THAT(foo.numbers, ElementsAre(1));
- foo.AddNumber(3);
- EXPECT_THAT(foo.numbers, ElementsAre(1, 3));
-
- // Set foo as the object, and expect that the previous delayed operations are
- // executed.
- delayed_foo.SetTargetObject(&foo);
- EXPECT_THAT(foo.numbers, ElementsAre(1, 3, 0, 2));
-
- // All following operations on delayed_foo should be executed immediately.
- delayed_foo.EnqueueCall(&Foo::AddNumber, 4);
- EXPECT_THAT(foo.numbers, ElementsAre(1, 3, 0, 2, 4));
- foo.AddNumber(5);
- EXPECT_THAT(foo.numbers, ElementsAre(1, 3, 0, 2, 4, 5));
- delayed_foo.EnqueueCall(&Foo::AddNumber, 6);
- EXPECT_THAT(foo.numbers, ElementsAre(1, 3, 0, 2, 4, 5, 6));
-}
-
-TEST(DelayingFacadeTest, CallWithNotCopyableObjects) {
- Foo foo;
- DelayingFacade<Foo> delayed_foo;
-
- delayed_foo.EnqueueCall(&Foo::AddUniqueNumber, std::make_unique<int>(0));
- EXPECT_THAT(foo.unique_numbers, IsEmpty());
-
- delayed_foo.SetTargetObject(&foo);
-
- EXPECT_THAT(foo.unique_numbers, SizeIs(1));
- EXPECT_EQ(*foo.unique_numbers[0], 0);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/diff_utils.cc b/bin/ledger/app/diff_utils.cc
deleted file mode 100644
index d30e46e..0000000
--- a/bin/ledger/app/diff_utils.cc
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/diff_utils.h"
-
-#include <limits>
-#include <memory>
-#include <vector>
-
-#include <lib/callback/waiter.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/lib/util/ptr.h"
-
-namespace ledger {
-namespace diff_utils {
-namespace {
-// Returns the key of a storage::ThreeWayChange object. This key is guaranteed
-// to be unique.
-const std::string& GetKey(const storage::ThreeWayChange& change) {
- if (change.base) {
- return change.base->key;
- }
- if (change.left) {
- return change.left->key;
- }
- return change.right->key;
-}
-
-// Constructs a ValuePtr object from an entry. The contents of the ValuePtr will
-// be provided through the |waiter|.
-ValuePtr GetValueFromEntry(
- storage::PageStorage* const storage,
- const std::unique_ptr<storage::Entry>& entry,
- fit::function<void(Status, fsl::SizedVmo)> callback) {
- if (!entry) {
- callback(Status::OK, fsl::SizedVmo());
- return nullptr;
- }
- ValuePtr value = Value::New();
- switch (entry->priority) {
- case storage::KeyPriority::EAGER:
- value->priority = Priority::EAGER;
- break;
- case storage::KeyPriority::LAZY:
- value->priority = Priority::LAZY;
- break;
- }
- PageUtils::ResolveObjectIdentifierAsBuffer(
- storage, entry->object_identifier, 0u,
- std::numeric_limits<int64_t>::max(),
- storage::PageStorage::Location::LOCAL, Status::OK, std::move(callback));
- return value;
-}
-
-// Returns true if the change is automatically mergeable, ie. is not
-// conflicting.
-bool IsMergeable(const storage::ThreeWayChange& change) {
- return util::EqualPtr(change.base, change.left) ||
- util::EqualPtr(change.base, change.right) ||
- util::EqualPtr(change.left, change.right);
-}
-} // namespace
-
-void ComputePageChange(
- storage::PageStorage* storage, const storage::Commit& base,
- const storage::Commit& other, std::string prefix_key, std::string min_key,
- PaginationBehavior pagination_behavior,
- fit::function<void(Status, std::pair<PageChangePtr, std::string>)>
- callback) {
- struct Context {
- // The PageChangePtr to be returned through the callback.
- PageChangePtr page_change = PageChange::New();
- // The serialization size of all entries.
- size_t fidl_size = fidl_serialization::kPageChangeHeaderSize;
- // The number of handles.
- size_t handles_count = 0u;
- // The next token to be returned through the callback.
- std::string next_token = "";
- };
-
- auto waiter =
- fxl::MakeRefCounted<callback::Waiter<Status, fsl::SizedVmo>>(Status::OK);
-
- auto context = std::make_unique<Context>();
- context->page_change->timestamp = other.GetTimestamp().get();
- context->page_change->changed_entries.resize(0);
- context->page_change->deleted_keys.resize(0);
-
- if (min_key < prefix_key) {
- min_key = prefix_key;
- }
-
- // |on_next| is called for each change on the diff
- auto on_next = [storage, waiter, prefix_key = std::move(prefix_key),
- context = context.get(),
- pagination_behavior](storage::EntryChange change) {
- if (!PageUtils::MatchesPrefix(change.entry.key, prefix_key)) {
- return false;
- }
- size_t entry_size =
- change.deleted
- ? fidl_serialization::GetByteVectorSize(change.entry.key.size())
- : fidl_serialization::GetEntrySize(change.entry.key.size());
- size_t entry_handle_count = change.deleted ? 0 : 1;
- if (pagination_behavior == PaginationBehavior::BY_SIZE &&
- (context->fidl_size + entry_size >
- fidl_serialization::kMaxInlineDataSize ||
- context->handles_count + entry_handle_count >
- fidl_serialization::kMaxMessageHandles
-
- )) {
- context->next_token = change.entry.key;
- return false;
- }
- context->fidl_size += entry_size;
- context->handles_count += entry_handle_count;
- if (change.deleted) {
- context->page_change->deleted_keys.push_back(
- convert::ToArray(change.entry.key));
- return true;
- }
-
- Entry entry;
- entry.key = convert::ToArray(change.entry.key);
- entry.priority = change.entry.priority == storage::KeyPriority::EAGER
- ? Priority::EAGER
- : Priority::LAZY;
- context->page_change->changed_entries.push_back(std::move(entry));
- PageUtils::ResolveObjectIdentifierAsBuffer(
- storage, change.entry.object_identifier, 0u,
- std::numeric_limits<int64_t>::max(),
- storage::PageStorage::Location::LOCAL, Status::OK,
- waiter->NewCallback());
- return true;
- };
-
- // |on_done| is called when the full diff is computed.
- auto on_done = [waiter = std::move(waiter), context = std::move(context),
- callback =
- std::move(callback)](storage::Status status) mutable {
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to compute diff for PageChange: "
- << fidl::ToUnderlying(status);
- callback(PageUtils::ConvertStatus(status), std::make_pair(nullptr, ""));
- return;
- }
- if (context->page_change->changed_entries.empty()) {
- if (context->page_change->deleted_keys.empty()) {
- callback(Status::OK, std::make_pair(nullptr, ""));
- } else {
- callback(Status::OK,
- std::make_pair(std::move(context->page_change), ""));
- }
- return;
- }
-
- // We need to retrieve the values for each changed key/value pair in order
- // to send it inside the PageChange object. |waiter| collates these
- // asynchronous calls and |result_callback| processes them.
- auto result_callback = [context = std::move(context),
- callback = std::move(callback)](
- Status status,
- std::vector<fsl::SizedVmo> results) mutable {
- if (status != Status::OK) {
- FXL_LOG(ERROR)
- << "Error while reading changed values when computing PageChange: "
- << fidl::ToUnderlying(status);
- callback(status, std::make_pair(nullptr, ""));
- return;
- }
- FXL_DCHECK(results.size() ==
- context->page_change->changed_entries.size());
- for (size_t i = 0; i < results.size(); i++) {
- FXL_DCHECK(results[i].vmo());
- context->page_change->changed_entries.at(i).value =
- fidl::MakeOptional(std::move(results[i]).ToTransport());
- }
- callback(Status::OK, std::make_pair(std::move(context->page_change),
- std::move(context->next_token)));
- };
- waiter->Finalize(std::move(result_callback));
- };
- storage->GetCommitContentsDiff(base, other, std::move(min_key),
- std::move(on_next), std::move(on_done));
-}
-
-void ComputeThreeWayDiff(
- storage::PageStorage* storage, const storage::Commit& base,
- const storage::Commit& left, const storage::Commit& right,
- std::string prefix_key, std::string min_key, DiffType diff_type,
- fit::function<void(Status,
- std::pair<std::vector<DiffEntry>, std::string>)>
- callback) {
- struct Context {
- // The array to be returned through the callback.
- std::vector<DiffEntry> changes;
- // The serialization size of all entries.
- size_t fidl_size = fidl_serialization::kVectorHeaderSize;
- // The number of handles.
- size_t handles_count = 0u;
- // The next token to be returned through the callback.
- std::string next_token = "";
- };
-
- // This waiter collects the values (as VMOs) for all changes that will be
- // returned. As each |DiffEntry| struct has three values, we ensure that
- // values are always returned in a specific order (base, left, right). Some
- // values may be empty, to denote a lack of diff.
- auto waiter =
- fxl::MakeRefCounted<callback::Waiter<Status, fsl::SizedVmo>>(Status::OK);
-
- auto context = std::make_unique<Context>();
-
- if (min_key < prefix_key) {
- min_key = prefix_key;
- }
-
- // |on_next| is called for each change on the diff
- auto on_next = [storage, waiter, prefix_key = std::move(prefix_key),
- context = context.get(),
- diff_type](storage::ThreeWayChange change) mutable {
- const std::string& key = GetKey(change);
- if (!PageUtils::MatchesPrefix(key, prefix_key)) {
- return false;
- }
- int number_of_values =
- bool(change.base) + bool(change.left) + bool(change.right);
- size_t diffentry_size =
- fidl_serialization::GetDiffEntrySize(key.size(), number_of_values);
- if (context->fidl_size + diffentry_size >
- fidl_serialization::kMaxInlineDataSize ||
- context->handles_count + number_of_values >
- fidl_serialization::kMaxMessageHandles) {
- context->next_token = key;
- // Stop the iteration as we are over the message capacity.
- return false;
- }
-
- if (diff_type == DiffType::CONFLICTING && IsMergeable(change)) {
- // We are not interested in this change, continue to the next one.
- return true;
- }
-
- context->fidl_size += diffentry_size;
- context->handles_count += number_of_values;
-
- DiffEntry diff_entry;
- diff_entry.key = convert::ToArray(key);
- diff_entry.base =
- GetValueFromEntry(storage, change.base, waiter->NewCallback());
- diff_entry.left =
- GetValueFromEntry(storage, change.left, waiter->NewCallback());
- diff_entry.right =
- GetValueFromEntry(storage, change.right, waiter->NewCallback());
- context->changes.push_back(std::move(diff_entry));
- return true;
- };
-
- // |on_done| is called when the full diff is computed.
- auto on_done = [waiter = std::move(waiter), context = std::move(context),
- callback =
- std::move(callback)](storage::Status status) mutable {
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to compute diff for PageChange: "
- << fidl::ToUnderlying(status);
- callback(PageUtils::ConvertStatus(status),
- std::make_pair(std::vector<DiffEntry>(), ""));
- return;
- }
- if (context->changes.empty()) {
- callback(Status::OK,
- std::make_pair(std::vector<DiffEntry>(), ""));
- return;
- }
-
- // We need to retrieve the values for each changed key/value pair in order
- // to send it inside the PageChange object. |waiter| collates these
- // asynchronous calls and |result_callback| processes them.
- auto result_callback = [context = std::move(context),
- callback = std::move(callback)](
- Status status,
- std::vector<fsl::SizedVmo> results) mutable {
- if (status != Status::OK) {
- FXL_LOG(ERROR)
- << "Error while reading changed values when computing PageChange: "
- << fidl::ToUnderlying(status);
- callback(status,
- std::make_pair(std::vector<DiffEntry>(), ""));
- return;
- }
- FXL_DCHECK(results.size() == 3 * context->changes.size());
- for (size_t i = 0; i < context->changes.size(); i++) {
- if (results[3 * i]) {
- context->changes.at(i).base->value =
- fidl::MakeOptional(std::move(results[3 * i]).ToTransport());
- }
- if (results[3 * i + 1]) {
- context->changes.at(i).left->value =
- fidl::MakeOptional(std::move(results[3 * i + 1]).ToTransport());
- }
- if (results[3 * i + 2]) {
- context->changes.at(i).right->value =
- fidl::MakeOptional(std::move(results[3 * i + 2]).ToTransport());
- }
- }
- callback(Status::OK, std::make_pair(std::move(context->changes),
- std::move(context->next_token)));
- };
- waiter->Finalize(std::move(result_callback));
- };
- storage->GetThreeWayContentsDiff(base, left, right, std::move(min_key),
- std::move(on_next), std::move(on_done));
-}
-
-} // namespace diff_utils
-} // namespace ledger
diff --git a/bin/ledger/app/diff_utils.h b/bin/ledger/app/diff_utils.h
deleted file mode 100644
index 9101239..0000000
--- a/bin/ledger/app/diff_utils.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_DIFF_UTILS_H_
-#define PERIDOT_BIN_LEDGER_APP_DIFF_UTILS_H_
-
-#include <functional>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-namespace diff_utils {
-
-// Configure the pagination behavior of |ComputePageChange|.
-enum class PaginationBehavior {
- NO_PAGINATION,
- BY_SIZE,
-};
-
-// Type of three-way diff performed. If |CONFLICTING| is selected, only
-// conflicting keys are returned.
-enum class DiffType {
- FULL,
- CONFLICTING,
-};
-
-// Asynchronously creates a PageChange representing the diff of the two provided
-// commits, starting from the given |min_key|. If |pagination_behavior| is
-// |NO_PAGINATION|, it provides all results. If |pagination_behavior| is
-// |BY_SIZE| it will provide a number of results that fit in a fidl message.
-// The result, or an error, will be provided in |callback| status. The second
-// argument of the callback is either a pair of the PageChangePtr, containing
-// the diff result and the string representation of the next token if the
-// result is paginated, or empty if there are no more results to return. Note
-// that the PageChangePtr in the callback will be nullptr if the diff is empty.
-void ComputePageChange(
- storage::PageStorage* storage, const storage::Commit& base,
- const storage::Commit& other, std::string prefix_key, std::string min_key,
- PaginationBehavior pagination_behavior,
- fit::function<void(Status, std::pair<PageChangePtr, std::string>)>
- callback);
-
-// Asynchronously computes the three-way diff between a base commit and two
-// other commits, starting from the given |min_key|.
-void ComputeThreeWayDiff(
- storage::PageStorage* storage, const storage::Commit& base,
- const storage::Commit& left, const storage::Commit& right,
- std::string prefix_key, std::string min_key, DiffType diff_type,
- fit::function<void(Status,
- std::pair<std::vector<DiffEntry>, std::string>)>
- callback);
-
-} // namespace diff_utils
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_DIFF_UTILS_H_
diff --git a/bin/ledger/app/disk_cleanup_manager.h b/bin/ledger/app/disk_cleanup_manager.h
deleted file mode 100644
index 8469dfb..0000000
--- a/bin/ledger/app/disk_cleanup_manager.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_DISK_CLEANUP_MANAGER_H_
-#define PERIDOT_BIN_LEDGER_APP_DISK_CLEANUP_MANAGER_H_
-
-#include <lib/fxl/functional/closure.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/app/page_usage_listener.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-// Manages cleanup operations in Ledger.
-//
-// Implementations of DiskCleanupManager define the policies about when and how
-// each cleanup operation is executed in Ledger.
-class DiskCleanupManager {
- public:
- DiskCleanupManager() {}
- virtual ~DiskCleanupManager() {}
-
- // Sets the callback to be called every time the DiskCleanupManager is empty.
- virtual void set_on_empty(fit::closure on_empty_callback) = 0;
-
- // Returns whether the DiskCleanupManager is empty, i.e. whether there are no
- // pending operations.
- virtual bool IsEmpty() = 0;
-
- // Tries to free up disk space.
- virtual void TryCleanUp(fit::function<void(Status)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(DiskCleanupManager);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_DISK_CLEANUP_MANAGER_H_
diff --git a/bin/ledger/app/disk_cleanup_manager_impl.cc b/bin/ledger/app/disk_cleanup_manager_impl.cc
deleted file mode 100644
index 0baecf4..0000000
--- a/bin/ledger/app/disk_cleanup_manager_impl.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/disk_cleanup_manager_impl.h"
-
-namespace ledger {
-
-DiskCleanupManagerImpl::DiskCleanupManagerImpl(Environment* environment,
- storage::DbFactory* db_factory,
- DetachedPath db_path)
- : page_eviction_manager_(environment, db_factory, std::move(db_path)),
- policy_(NewLeastRecentyUsedPolicy(environment->coroutine_service(),
- &page_eviction_manager_)) {}
-
-DiskCleanupManagerImpl::~DiskCleanupManagerImpl() {}
-
-Status DiskCleanupManagerImpl::Init() { return page_eviction_manager_.Init(); }
-
-void DiskCleanupManagerImpl::SetPageEvictionDelegate(
- PageEvictionManager::Delegate* delegate) {
- page_eviction_manager_.SetDelegate(delegate);
-}
-
-void DiskCleanupManagerImpl::set_on_empty(fit::closure on_empty_callback) {
- page_eviction_manager_.set_on_empty(std::move(on_empty_callback));
-}
-
-bool DiskCleanupManagerImpl::IsEmpty() {
- return page_eviction_manager_.IsEmpty();
-}
-
-void DiskCleanupManagerImpl::TryCleanUp(fit::function<void(Status)> callback) {
- page_eviction_manager_.TryEvictPages(policy_.get(), std::move(callback));
-}
-
-void DiskCleanupManagerImpl::OnPageOpened(fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- page_eviction_manager_.MarkPageOpened(ledger_name, page_id);
-}
-
-void DiskCleanupManagerImpl::OnPageClosed(fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- page_eviction_manager_.MarkPageClosed(ledger_name, page_id);
-}
-
-void DiskCleanupManagerImpl::OnPageUnused(fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- page_eviction_manager_.TryEvictPage(
- ledger_name, page_id, PageEvictionCondition::IF_EMPTY,
- [ledger_name = ledger_name.ToString(), page_id = page_id.ToString()](
- Status status, PageWasEvicted) {
- if (status != Status::OK && status != Status::INTERNAL_ERROR) {
- FXL_LOG(ERROR)
- << "Failed to check if page is empty and/or evict it. Status: "
- << fidl::ToUnderlying(status) << ". Ledger name: " << ledger_name
- << ". Page ID: " << convert::ToHex(page_id);
- }
- });
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/disk_cleanup_manager_impl.h b/bin/ledger/app/disk_cleanup_manager_impl.h
deleted file mode 100644
index 17ff3e3..0000000
--- a/bin/ledger/app/disk_cleanup_manager_impl.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_DISK_CLEANUP_MANAGER_IMPL_H_
-#define PERIDOT_BIN_LEDGER_APP_DISK_CLEANUP_MANAGER_IMPL_H_
-
-#include "peridot/bin/ledger/app/disk_cleanup_manager.h"
-#include "peridot/bin/ledger/app/page_eviction_manager_impl.h"
-#include "peridot/bin/ledger/app/page_usage_listener.h"
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/storage/public/db_factory.h"
-
-namespace ledger {
-
-class DiskCleanupManagerImpl : public DiskCleanupManager,
- public PageUsageListener {
- public:
- DiskCleanupManagerImpl(Environment* environment,
- storage::DbFactory* db_factory, DetachedPath db_path);
- ~DiskCleanupManagerImpl() override;
-
- // Initializes this DiskCleanupManagerImpl.
- Status Init();
-
- // Sets the delegate for PageEvictionManager owned by DiskCleanupManagerImpl.
- // The delegate should outlive this object.
- void SetPageEvictionDelegate(PageEvictionManager::Delegate* delegate);
-
- // DiskCleanupManager:
- void set_on_empty(fit::closure on_empty_callback) override;
- bool IsEmpty() override;
- void TryCleanUp(fit::function<void(Status)> callback) override;
-
- // PageUsageListener:
- void OnPageOpened(fxl::StringView ledger_name,
- storage::PageIdView page_id) override;
- void OnPageClosed(fxl::StringView ledger_name,
- storage::PageIdView page_id) override;
- void OnPageUnused(fxl::StringView ledger_name,
- storage::PageIdView page_id) override;
-
- private:
- PageEvictionManagerImpl page_eviction_manager_;
- std::unique_ptr<PageEvictionPolicy> policy_;
-
- // TODO(nellyv): Add OnLowResources and OnPeriodicCleanUp to handle cleanup
- // opeations on the corresponding cases.
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DiskCleanupManagerImpl);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_DISK_CLEANUP_MANAGER_IMPL_H_
diff --git a/bin/ledger/app/disk_cleanup_manager_unittest.cc b/bin/ledger/app/disk_cleanup_manager_unittest.cc
deleted file mode 100644
index a525448..0000000
--- a/bin/ledger/app/disk_cleanup_manager_unittest.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/disk_cleanup_manager_impl.h"
-
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/storage/fake/fake_db_factory.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-
-class FakeDelegate : public PageEvictionManager::Delegate {
- public:
- void PageIsClosedAndSynced(
- fxl::StringView /*ledger_name*/, storage::PageIdView /*page_id*/,
- fit::function<void(Status, PagePredicateResult)> callback) override {
- callback(Status::OK, PagePredicateResult::YES);
- }
-
- void PageIsClosedOfflineAndEmpty(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) override {
- callback(Status::OK, closed_offline_empty);
- }
-
- void DeletePageStorage(fxl::StringView /*ledger_name*/,
- storage::PageIdView page_id,
- fit::function<void(Status)> callback) override {
- deleted_pages.push_back(page_id.ToString());
- callback(Status::OK);
- }
-
- std::vector<storage::PageId> deleted_pages;
-
- PagePredicateResult closed_offline_empty = PagePredicateResult::YES;
-};
-
-class DiskCleanupManagerTest : public TestWithEnvironment {
- public:
- DiskCleanupManagerTest()
- : db_factory_(environment_.dispatcher()),
- disk_cleanup_manager_(&environment_, &db_factory_,
- DetachedPath(tmpfs_.root_fd())) {}
-
- // gtest::TestLoopFixture:
- void SetUp() override {
- EXPECT_EQ(Status::OK, disk_cleanup_manager_.Init());
- RunLoopUntilIdle();
- disk_cleanup_manager_.SetPageEvictionDelegate(&delegate_);
- }
-
- private:
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- coroutine::CoroutineServiceImpl coroutine_service_;
- storage::fake::FakeDbFactory db_factory_;
-
- protected:
- FakeDelegate delegate_;
- DiskCleanupManagerImpl disk_cleanup_manager_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DiskCleanupManagerTest);
-};
-
-TEST_F(DiskCleanupManagerTest, DontEvictNonEmptyPagesOnPageUnused) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- // The page cannot be evicted if its not empty and offline.
- disk_cleanup_manager_.OnPageOpened(ledger_name, page);
- delegate_.closed_offline_empty = PagePredicateResult::NO;
- disk_cleanup_manager_.OnPageUnused(ledger_name, page);
- RunLoopUntilIdle();
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-}
-
-TEST_F(DiskCleanupManagerTest, DontEvictUnknownEmptyPagesOnPageUnused) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- // The page cannot be evicted if we can't determine whether it is empty and
- // offline.
- disk_cleanup_manager_.OnPageOpened(ledger_name, page);
- delegate_.closed_offline_empty = PagePredicateResult::PAGE_OPENED;
- disk_cleanup_manager_.OnPageUnused(ledger_name, page);
- RunLoopUntilIdle();
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-}
-
-TEST_F(DiskCleanupManagerTest, EvictEmptyOfflinePagesOnPageUnused) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- // The page should be evicted is it is empty and offline.
- disk_cleanup_manager_.OnPageOpened(ledger_name, page);
- delegate_.closed_offline_empty = PagePredicateResult::YES;
- disk_cleanup_manager_.OnPageUnused(ledger_name, page);
- RunLoopUntilIdle();
- EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page));
-}
-
-TEST_F(DiskCleanupManagerTest, DontEvictPagesOnPageClosed) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- disk_cleanup_manager_.OnPageOpened(ledger_name, page);
- delegate_.closed_offline_empty = PagePredicateResult::YES;
- disk_cleanup_manager_.OnPageClosed(ledger_name, page);
- RunLoopUntilIdle();
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/fidl/serialization_size.cc b/bin/ledger/app/fidl/serialization_size.cc
deleted file mode 100644
index ca660a5..0000000
--- a/bin/ledger/app/fidl/serialization_size.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-
-namespace ledger {
-namespace fidl_serialization {
-
-size_t GetByteVectorSize(size_t vector_length) {
- return Align(vector_length) + kVectorHeaderSize;
-}
-
-size_t GetEntrySize(size_t key_length) {
- size_t key_size = GetByteVectorSize(key_length);
- size_t object_size = Align(kMemoryObjectSize);
- return key_size + object_size + Align(kPriorityEnumSize);
-}
-
-size_t GetInlinedEntrySize(const InlinedEntry& entry) {
- size_t key_size = GetByteVectorSize(entry.key.size());
- size_t object_size = kPointerSize;
- if (entry.inlined_value) {
- object_size += GetByteVectorSize(entry.inlined_value->value.size());
- }
- return key_size + object_size + Align(kPriorityEnumSize);
-}
-
-size_t GetDiffEntrySize(size_t key_length, int number_of_values) {
- size_t key_size = GetByteVectorSize(key_length);
- return key_size + number_of_values *
- (Align(kMemoryObjectSize) + Align(kPriorityEnumSize));
-}
-
-} // namespace fidl_serialization
-} // namespace ledger
diff --git a/bin/ledger/app/fidl/serialization_size.h b/bin/ledger/app/fidl/serialization_size.h
deleted file mode 100644
index 165a205..0000000
--- a/bin/ledger/app/fidl/serialization_size.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_FIDL_SERIALIZATION_SIZE_H_
-#define PERIDOT_BIN_LEDGER_APP_FIDL_SERIALIZATION_SIZE_H_
-
-#include <stddef.h>
-
-#include <zircon/fidl.h>
-#include <zircon/types.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace ledger {
-namespace fidl_serialization {
-
-// Maximal size of data that will be returned inline.
-inline constexpr size_t kMaxInlineDataSize = ZX_CHANNEL_MAX_MSG_BYTES * 9 / 10;
-inline constexpr size_t kMaxMessageHandles = ZX_CHANNEL_MAX_MSG_HANDLES;
-
-// TODO(mariagl): Remove dependency on FIDL internal structure layout, see
-// LE-449.
-inline constexpr size_t kPointerSize = sizeof(uintptr_t);
-inline constexpr size_t kStatusEnumSize = sizeof(int32_t);
-inline constexpr size_t kHandleSize = sizeof(zx_handle_t);
-inline constexpr size_t kVectorHeaderSize = sizeof(fidl_vector_t);
-inline constexpr size_t kPriorityEnumSize = sizeof(int32_t);
-inline constexpr size_t kMessageHeaderSize = sizeof(fidl_message_header_t);
-
-inline size_t Align(size_t n) { return FIDL_ALIGN(n); }
-
-// The overhead for storing the pointer, the timestamp (int64) and the two
-// arrays.
-inline constexpr size_t kPageChangeHeaderSize =
- kPointerSize + sizeof(int64_t) + 2 * kVectorHeaderSize;
-
-// Returns the fidl size of a byte vector with the given length.
-size_t GetByteVectorSize(size_t vector_length);
-
-// Returns the fidl size of an Entry holding a key with the given length.
-size_t GetEntrySize(size_t key_length);
-
-// Returns the fidl size of an InlinedEntry.
-size_t GetInlinedEntrySize(const InlinedEntry& entry);
-
-// Size of an object stored in memory (and accessed by a handle).
-inline constexpr size_t kMemoryObjectSize = 2 * kPointerSize + kHandleSize;
-
-// Returns the size of a DiffEntry object
-size_t GetDiffEntrySize(size_t key_length, int number_of_values);
-
-} // namespace fidl_serialization
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_FIDL_SERIALIZATION_SIZE_H_
diff --git a/bin/ledger/app/fidl/serialization_size_unittest.cc b/bin/ledger/app/fidl/serialization_size_unittest.cc
deleted file mode 100644
index a8002f7..0000000
--- a/bin/ledger/app/fidl/serialization_size_unittest.cc
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-
-#include <memory>
-
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/strings/string_printf.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace fidl_serialization {
-namespace {
-std::vector<uint8_t> GetKey(size_t index, size_t min_key_size = 0u) {
- std::string result = fxl::StringPrintf("key %04" PRIuMAX, index);
- result.resize(std::max(result.size(), min_key_size));
- return convert::ToArray(result);
-}
-
-std::string GetValue(size_t index, size_t min_value_size = 0u) {
- std::string result = fxl::StringPrintf("val %zu", index);
- result.resize(std::max(result.size(), min_value_size));
- return result;
-}
-
-::testing::AssertionResult CheckMessageSize(zx::channel channel,
- size_t expected_bytes,
- size_t expected_handles) {
- uint32_t actual_bytes, actual_handles;
- zx_status_t status =
- channel.read(0, nullptr, 0, &actual_bytes, nullptr, 0, &actual_handles);
- if (status != ZX_ERR_BUFFER_TOO_SMALL) {
- return ::testing::AssertionFailure()
- << "Channel read status = " << status
- << ", expected ZX_ERR_BUFFER_TOO_SMALL (" << ZX_ERR_BUFFER_TOO_SMALL
- << ").";
- }
- EXPECT_EQ(expected_bytes, actual_bytes);
- EXPECT_EQ(expected_handles, actual_handles);
- if ((expected_bytes != actual_bytes) ||
- (expected_handles != actual_handles)) {
- return ::testing::AssertionFailure() << "Unexpected message size.";
- }
- return ::testing::AssertionSuccess();
-}
-
-using SerializationSizeTest = gtest::TestLoopFixture;
-
-class FakeSnapshotImpl : public PageSnapshot {
- public:
- FakeSnapshotImpl() {}
- ~FakeSnapshotImpl() override {}
-
- GetEntriesInlineCallback get_entries_inline_callback;
- GetEntriesCallback get_entries_callback;
- GetCallback get_callback;
- GetInlineCallback get_inline_callback;
-
- // PageSnapshot:
- void GetEntriesInline(std::vector<uint8_t> /*key_start*/,
- std::unique_ptr<Token> /*token*/,
- GetEntriesInlineCallback callback) override {
- get_entries_inline_callback = std::move(callback);
- }
-
- void GetEntries(std::vector<uint8_t> /*key_start*/,
- std::unique_ptr<Token> /*token*/,
- GetEntriesCallback callback) override {
- get_entries_callback = std::move(callback);
- }
-
- void GetKeys(std::vector<uint8_t> /*key_start*/,
- std::unique_ptr<Token> /*token*/,
- GetKeysCallback /*callback*/) override {}
-
- void Get(std::vector<uint8_t> /*key*/, GetCallback callback) override {
- get_callback = std::move(callback);
- }
-
- void GetInline(std::vector<uint8_t> /*key*/,
- GetInlineCallback callback) override {
- get_inline_callback = std::move(callback);
- }
-
- void Fetch(std::vector<uint8_t> /*key*/,
- FetchCallback /*callback*/) override {
- FXL_NOTIMPLEMENTED();
- }
-
- void FetchPartial(std::vector<uint8_t> /*key*/, int64_t /*offset*/,
- int64_t /*max_size*/,
- FetchPartialCallback /*callback*/) override {
- FXL_NOTIMPLEMENTED();
- }
-};
-
-TEST_F(SerializationSizeTest, GetInline) {
- PageSnapshotPtr snapshot_proxy;
- FakeSnapshotImpl snapshot_impl;
-
- zx::channel writer, reader;
- ASSERT_EQ(ZX_OK, zx::channel::create(0, &writer, &reader));
-
- snapshot_proxy.Bind(std::move(reader));
- fidl::Binding<PageSnapshot> binding(&snapshot_impl);
- binding.Bind(std::move(writer));
-
- const size_t key_size = 125;
- const size_t value_size = 125;
- std::vector<uint8_t> key = GetKey(0, key_size);
- std::vector<uint8_t> value = convert::ToArray(GetValue(0, value_size));
-
- auto client_callback = [](Status /*status*/,
- std::unique_ptr<InlinedValue> /*value*/) {};
-
- // FakeSnapshot saves the callback instead of running it.
- snapshot_proxy->GetInline(std::move(key), std::move(client_callback));
- RunLoopUntilIdle();
-
- fidl::InterfaceHandle<PageSnapshot> handle = snapshot_proxy.Unbind();
- reader = handle.TakeChannel();
-
- // Run the callback directly.
- auto inlined_value = std::make_unique<InlinedValue>();
- inlined_value->value = std::move(value);
- snapshot_impl.get_inline_callback(Status::OK, std::move(inlined_value));
-
- const size_t expected_bytes =
- Align(kMessageHeaderSize + kPointerSize + GetByteVectorSize(value_size) +
- kStatusEnumSize);
- const size_t expected_handles = 0;
- EXPECT_TRUE(
- CheckMessageSize(std::move(reader), expected_bytes, expected_handles));
-}
-
-TEST_F(SerializationSizeTest, Get) {
- PageSnapshotPtr snapshot_proxy;
- FakeSnapshotImpl snapshot_impl;
-
- zx::channel writer, reader;
- ASSERT_EQ(ZX_OK, zx::channel::create(0, &writer, &reader));
-
- snapshot_proxy.Bind(std::move(reader));
- fidl::Binding<PageSnapshot> binding(&snapshot_impl);
- binding.Bind(std::move(writer));
-
- const size_t key_size = 8;
- const size_t value_size = 125;
- std::vector<uint8_t> key = GetKey(0, key_size);
- std::string object_data = GetValue(0, value_size);
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(object_data, &vmo));
- fuchsia::mem::BufferPtr value =
- fidl::MakeOptional(std::move(vmo).ToTransport());
-
- auto client_callback = [](Status /*status*/,
- fuchsia::mem::BufferPtr /*value*/) {};
- // FakeSnapshot saves the callback instead of running it.
- snapshot_proxy->Get(std::move(key), std::move(client_callback));
- RunLoopUntilIdle();
-
- fidl::InterfaceHandle<PageSnapshot> handle = snapshot_proxy.Unbind();
- reader = handle.TakeChannel();
-
- // Run the callback directly.
- snapshot_impl.get_callback(Status::OK, std::move(value));
-
- const size_t expected_bytes =
- Align(kMessageHeaderSize + // Header.
- kPointerSize + // BufferPtr.
- kPointerSize + // Size.
- Align(kHandleSize) + // FIDL_HANDLE_PRESENT.
- kStatusEnumSize // Status.
- );
- const size_t expected_handles = 1;
- EXPECT_TRUE(
- CheckMessageSize(std::move(reader), expected_bytes, expected_handles));
-}
-
-TEST_F(SerializationSizeTest, GetEntriesInline) {
- PageSnapshotPtr snapshot_proxy;
- FakeSnapshotImpl snapshot_impl;
- zx::channel writer, reader;
- ASSERT_EQ(ZX_OK, zx::channel::create(0, &writer, &reader));
-
- snapshot_proxy.Bind(std::move(reader));
- fidl::Binding<PageSnapshot> binding(&snapshot_impl);
- binding.Bind(std::move(writer));
-
- auto client_callback = [](Status /*status*/,
- std::vector<InlinedEntry> /*entries*/,
- std::unique_ptr<Token> /*next_token*/) {};
- // FakeSnapshot saves the callback instead of running it.
- snapshot_proxy->GetEntriesInline(fidl::VectorPtr<uint8_t>::New(0), nullptr,
- std::move(client_callback));
- RunLoopUntilIdle();
-
- fidl::InterfaceHandle<PageSnapshot> handle = snapshot_proxy.Unbind();
- reader = handle.TakeChannel();
-
- std::vector<InlinedEntry> entries_to_send;
-
- const size_t key_size = 125;
- const size_t value_size = 125;
- const size_t n_entries = 7;
- const size_t n_empty_entries = 7;
- auto token = std::make_unique<Token>();
- token->opaque_id = GetKey(0, key_size);
- InlinedEntry entry;
- entry.key = GetKey(0, key_size);
- entry.inlined_value = std::make_unique<InlinedValue>();
- entry.inlined_value->value = convert::ToArray(GetValue(0, value_size));
- size_t kExpectedEntrySize = GetInlinedEntrySize(entry);
- for (size_t i = 0; i < n_entries; i++) {
- entries_to_send.push_back(fidl::Clone(entry));
- }
- InlinedEntry empty_entry;
- empty_entry.key = GetKey(0, key_size);
- for (size_t i = 0; i < n_empty_entries; i++) {
- entries_to_send.push_back(fidl::Clone(empty_entry));
- }
- size_t kExpectedEmptyEntrySize = GetInlinedEntrySize(empty_entry);
-
- // Run the callback directly.
- snapshot_impl.get_entries_inline_callback(
- Status::OK, std::move(entries_to_send), std::move(token));
-
- const size_t expected_bytes =
- Align(kMessageHeaderSize + // Header.
- kVectorHeaderSize + // VectorPtr.
- n_entries * kExpectedEntrySize + // Vector of entries.
- n_empty_entries * kExpectedEmptyEntrySize + // Vector of entries.
- kPointerSize + // Pointer to next_token.
- GetByteVectorSize(key_size) + // next_token.
- kStatusEnumSize // Status.
- );
- const size_t expected_handles = 0;
- EXPECT_TRUE(
- CheckMessageSize(std::move(reader), expected_bytes, expected_handles));
-}
-
-TEST_F(SerializationSizeTest, GetEntries) {
- PageSnapshotPtr snapshot_proxy;
- FakeSnapshotImpl snapshot_impl;
- zx::channel writer, reader;
- ASSERT_EQ(ZX_OK, zx::channel::create(0, &writer, &reader));
-
- snapshot_proxy.Bind(std::move(reader));
- fidl::Binding<PageSnapshot> binding(&snapshot_impl);
- binding.Bind(std::move(writer));
-
- auto client_callback = [](Status /*status*/,
- std::vector<Entry> /*entries*/,
- std::unique_ptr<Token> /*next_token*/) {};
- // FakeSnapshot saves the callback instead of running it.
- snapshot_proxy->GetEntries(fidl::VectorPtr<uint8_t>::New(0), nullptr,
- std::move(client_callback));
- RunLoopUntilIdle();
-
- fidl::InterfaceHandle<PageSnapshot> handle = snapshot_proxy.Unbind();
- reader = handle.TakeChannel();
-
- std::vector<Entry> entries_to_send;
-
- const size_t key_size = 125;
- const size_t value_size = 125;
- const size_t n_entries = 10;
- auto token = std::make_unique<Token>();
- token->opaque_id = GetKey(0, key_size);
- for (size_t i = 0; i < n_entries; i++) {
- Entry entry;
- std::string object_data = GetValue(0, value_size);
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(object_data, &vmo));
- entry.value = fidl::MakeOptional(std::move(vmo).ToTransport());
- entry.key = GetKey(0, key_size);
- entry.priority = Priority::EAGER;
- entries_to_send.push_back(std::move(entry));
- }
-
- // Run the callback directly.
- snapshot_impl.get_entries_callback(Status::OK, std::move(entries_to_send),
- std::move(token));
-
- const size_t expected_bytes =
- Align(kMessageHeaderSize + // Header.
- kVectorHeaderSize + // VectorPtr.
- n_entries * GetEntrySize(key_size) + // Vector of entries.
- kPointerSize + // Pointer to next_token.
- GetByteVectorSize(key_size) + // next_token.
- kStatusEnumSize // Status.
- );
- const size_t expected_handles = n_entries;
- EXPECT_TRUE(
- CheckMessageSize(std::move(reader), expected_bytes, expected_handles));
-}
-
-} // namespace
-} // namespace fidl_serialization
-} // namespace ledger
diff --git a/bin/ledger/app/ledger_impl.cc b/bin/ledger/app/ledger_impl.cc
deleted file mode 100644
index 27a75ec..0000000
--- a/bin/ledger/app/ledger_impl.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/ledger_impl.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/callback/trace_callback.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/logging.h>
-#include <trace/event.h>
-#include <zircon/syscalls.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/page_impl.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace ledger {
-
-LedgerImpl::LedgerImpl(Environment* environment, Delegate* delegate)
- : environment_(environment), delegate_(delegate) {}
-
-LedgerImpl::~LedgerImpl() {}
-
-void LedgerImpl::GetRootPage(fidl::InterfaceRequest<Page> page_request,
- GetRootPageCallback callback) {
- delegate_->GetPage(
- kRootPageId, Delegate::PageState::NAMED, std::move(page_request),
- TRACE_CALLBACK(std::move(callback), "ledger", "ledger_get_root_page"));
-}
-
-void LedgerImpl::GetPage(PageIdPtr id,
- fidl::InterfaceRequest<Page> page_request,
- GetPageCallback callback) {
- Delegate::PageState page_state = Delegate::PageState::NAMED;
- if (!id) {
- id = fidl::MakeOptional(PageId());
- environment_->random()->Draw(&id->id);
- page_state = Delegate::PageState::NEW;
- }
- delegate_->GetPage(
- id->id, page_state, std::move(page_request),
- TRACE_CALLBACK(std::move(callback), "ledger", "ledger_get_page"));
-}
-
-void LedgerImpl::SetConflictResolverFactory(
- fidl::InterfaceHandle<ConflictResolverFactory> factory,
- SetConflictResolverFactoryCallback callback) {
- TRACE_DURATION("ledger", "ledger_set_conflict_resolver_factory");
-
- delegate_->SetConflictResolverFactory(std::move(factory));
- callback(Status::OK);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/ledger_impl.h b/bin/ledger/app/ledger_impl.h
deleted file mode 100644
index 0334b07..0000000
--- a/bin/ledger/app/ledger_impl.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_LEDGER_IMPL_H_
-#define PERIDOT_BIN_LEDGER_APP_LEDGER_IMPL_H_
-
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/ledger_storage.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-// An implementation of the |Ledger| FIDL interface.
-class LedgerImpl : public Ledger {
- public:
- // Delegate capable of actually performing the page operations.
- class Delegate {
- public:
- // State of a new page. If the state is |NEW|, it is known that it doesn't
- // have any content on the cloud or on another device.
- enum class PageState {
- // The page is new and has been created locally.
- NEW,
- // The page has been named by the client.
- // well known name
- NAMED,
- };
-
- Delegate() {}
- virtual ~Delegate() = default;
-
- virtual void GetPage(convert::ExtendedStringView page_id,
- PageState page_state,
- fidl::InterfaceRequest<Page> page_request,
- fit::function<void(Status)> callback) = 0;
-
- virtual void SetConflictResolverFactory(
- fidl::InterfaceHandle<ConflictResolverFactory> factory) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(Delegate);
- };
-
- // |delegate| outlives LedgerImpl.
- explicit LedgerImpl(Environment* environment, Delegate* delegate);
- ~LedgerImpl() override;
-
- private:
- // Ledger:
- void GetRootPage(fidl::InterfaceRequest<Page> page_request,
- GetRootPageCallback callback) override;
- void GetPage(PageIdPtr id, fidl::InterfaceRequest<Page> page_request,
- GetPageCallback callback) override;
-
- void SetConflictResolverFactory(
- fidl::InterfaceHandle<ConflictResolverFactory> factory,
- SetConflictResolverFactoryCallback callback) override;
-
- Environment* const environment_;
- Delegate* const delegate_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerImpl);
-};
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_LEDGER_IMPL_H_
diff --git a/bin/ledger/app/ledger_manager.cc b/bin/ledger/app/ledger_manager.cc
deleted file mode 100644
index 537d14f..0000000
--- a/bin/ledger/app/ledger_manager.cc
+++ /dev/null
@@ -1,715 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/ledger_manager.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/p2p_sync/public/page_communicator.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-namespace {
-
-// A token that performs a given action on destruction.
-// ExpiringToken objects are used with internal page requests to notify the
-// PageManagerContainer that the requested PageManager is no longer used.
-using ExpiringToken = fit::deferred_action<fit::closure>;
-
-// A notifier for |PageUsageListener|.
-//
-// Given information about when internal and external page connections open and
-// close, |PageConnectionNotifier| calls the corresponding methods from
-// |PageUsageListener|. The |PageUsageListener| given in the constructor should
-// outlive this object.
-class PageConnectionNotifier {
- public:
- PageConnectionNotifier(std::string ledger_name, storage::PageId page_id,
- PageUsageListener* page_usage_listener);
- ~PageConnectionNotifier();
-
- // Registers a new external page request.
- void RegisterExternalRequest();
-
- // Unregisters all active external page requests. This can be because all
- // active connections were closed, or because of failure to bind the requests.
- void UnregisterExternalRequests();
-
- // Registers a new internal page request.
- void RegisterInternalRequest();
-
- // Unregisters one active internal page request. This can be because the
- // active connection was closed, or because of failure to fulfill the request.
- void UnregisterInternalRequest();
-
- // Sets the on_empty callaback, to be called every time this object becomes
- // empty.
- void set_on_empty(fit::closure on_empty_callback);
-
- // Checks and returns whether there are no active external or internal
- // requests.
- bool IsEmpty();
-
- private:
- // Checks whether this object is empty, and if it is and the on_empty callback
- // is set, calls it.
- void CheckEmpty();
-
- const std::string ledger_name_;
- const storage::PageId page_id_;
- PageUsageListener* page_usage_listener_;
-
- // Stores whether the page was opened by an external request. Used to
- // determine whether to send the OnPageUnused notifications when this is
- // empty.
- bool must_notify_on_page_unused_ = false;
- // Stores whether the page is opened by an external request.
- bool has_external_requests_ = false;
- // Stores the number of active internal requests.
- ssize_t internal_request_count_ = 0;
-
- fit::closure on_empty_callback_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageConnectionNotifier);
-};
-
-PageConnectionNotifier::PageConnectionNotifier(
- std::string ledger_name, storage::PageId page_id,
- PageUsageListener* page_usage_listener)
- : ledger_name_(std::move(ledger_name)),
- page_id_(std::move(page_id)),
- page_usage_listener_(page_usage_listener) {}
-
-PageConnectionNotifier::~PageConnectionNotifier() {}
-
-void PageConnectionNotifier::RegisterExternalRequest() {
- if (has_external_requests_) {
- return;
- }
- must_notify_on_page_unused_ = true;
- has_external_requests_ = true;
- page_usage_listener_->OnPageOpened(ledger_name_, page_id_);
-}
-
-void PageConnectionNotifier::UnregisterExternalRequests() {
- if (has_external_requests_) {
- page_usage_listener_->OnPageClosed(ledger_name_, page_id_);
- has_external_requests_ = false;
- CheckEmpty();
- }
-}
-
-void PageConnectionNotifier::RegisterInternalRequest() {
- ++internal_request_count_;
-}
-
-void PageConnectionNotifier::UnregisterInternalRequest() {
- FXL_DCHECK(internal_request_count_ > 0);
- --internal_request_count_;
- CheckEmpty();
-}
-
-void PageConnectionNotifier::set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
-}
-
-bool PageConnectionNotifier::IsEmpty() {
- return internal_request_count_ == 0 && !has_external_requests_;
-}
-
-void PageConnectionNotifier::CheckEmpty() {
- if (!IsEmpty()) {
- return;
- }
- if (must_notify_on_page_unused_) {
- // We must set |must_notify_on_page_unused_| to false before calling
- // |OnPageUsed|: While |OnPageUsed| is executed it creates an internal
- // request to the PageManagerContainer, hence triggering a call to
- // |UnregisterInternalRequest|. Since that will be the last active request,
- // it will then trigger |CheckEmpty|, reaching again this part of the code.
- // Setting |must_notify_on_page_unused_| to false prevents this infinite
- // loop.
- must_notify_on_page_unused_ = false;
- page_usage_listener_->OnPageUnused(ledger_name_, page_id_);
- }
- if (on_empty_callback_) {
- on_empty_callback_();
- }
-}
-
-} // namespace
-
-void LedgerManager::PageAvailabilityManager::MarkPageBusy(
- convert::ExtendedStringView page_id) {
- auto result =
- busy_pages_.emplace(page_id.ToString(), std::vector<fit::closure>());
- FXL_DCHECK(result.second)
- << "Page " << convert::ToHex(page_id) << " is already busy.";
-}
-
-void LedgerManager::PageAvailabilityManager::MarkPageAvailable(
- convert::ExtendedStringView page_id) {
- storage::PageId page_id_str = page_id.ToString();
- auto it = busy_pages_.find(page_id_str);
- if (it == busy_pages_.end()) {
- return;
- }
-
- for (auto& page_callback : it->second) {
- page_callback();
- }
- busy_pages_.erase(it);
-}
-
-void LedgerManager::PageAvailabilityManager::OnPageAvailable(
- convert::ExtendedStringView page_id, fit::closure on_page_available) {
- storage::PageId page_id_str = page_id.ToString();
- auto it = busy_pages_.find(page_id_str);
- if (it == busy_pages_.end()) {
- on_page_available();
- return;
- }
- it->second.push_back(std::move(on_page_available));
-}
-
-// Container for a PageManager that keeps tracks of in-flight page requests and
-// callbacks and fires them when the PageManager is available.
-class LedgerManager::PageManagerContainer {
- public:
- PageManagerContainer(std::string ledger_name, storage::PageId page_id,
- PageUsageListener* page_usage_listener);
- ~PageManagerContainer();
-
- void set_on_empty(fit::closure on_empty_callback);
-
- // Keeps track of |page| and |callback|. Binds |page| and fires |callback|
- // when a PageManager is available or an error occurs.
- void BindPage(fidl::InterfaceRequest<Page> page_request,
- fit::function<void(Status)> callback);
-
- // Keeps track of |page_debug| and |callback|. Binds |page_debug| and fires
- // |callback| when a PageManager is available or an error occurs.
- void BindPageDebug(
- fidl::InterfaceRequest<ledger_internal::PageDebug> page_debug,
- fit::function<void(Status)> callback);
-
- // Registers a new internal request for PageStorage.
- void NewInternalRequest(
- fit::function<void(Status, ExpiringToken, PageManager*)> callback);
-
- // Sets the PageManager or the error status for the container. This notifies
- // all awaiting callbacks and binds all pages in case of success.
- void SetPageManager(Status status, std::unique_ptr<PageManager> page_manager);
-
- // Returns true if there is at least one active external page connection.
- bool PageConnectionIsOpen();
-
- private:
- // Creates a new ExpiringToken to be used while internal requests for the
- // |PageManager| remain active.
- ExpiringToken NewExpiringToken();
-
- // Checks whether this container is empty, and calls the |on_empty_callback_|
- // if it is.
- void CheckEmpty();
-
- const storage::PageId page_id_;
-
- std::unique_ptr<PageManager> page_manager_;
- // |status_| holds the status given to |SetPageManager|. If
- // |page_manager_is_set_| is true, |status_| is |Status::OK| if and only if
- // |page_manager_| is not null.
- Status status_ = Status::OK;
- // |page_manager_is_set_| if |SetPageManager| has been called. |page_manager_|
- // may still be null.
- bool page_manager_is_set_ = false;
-
- PageConnectionNotifier connection_notifier_;
- std::vector<std::pair<std::unique_ptr<PageDelayingFacade>,
- fit::function<void(Status)>>>
- requests_;
- std::vector<std::pair<fidl::InterfaceRequest<ledger_internal::PageDebug>,
- fit::function<void(Status)>>>
- debug_requests_;
- std::vector<fit::function<void(Status, ExpiringToken, PageManager*)>>
- internal_request_callbacks_;
- fit::closure on_empty_callback_;
-
- // Must be the last member.
- fxl::WeakPtrFactory<PageManagerContainer> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageManagerContainer);
-};
-
-LedgerManager::PageManagerContainer::PageManagerContainer(
- std::string ledger_name, storage::PageId page_id,
- PageUsageListener* page_usage_listener)
- : page_id_(page_id),
- connection_notifier_(std::move(ledger_name), std::move(page_id),
- page_usage_listener),
- weak_factory_(this) {}
-
-LedgerManager::PageManagerContainer::~PageManagerContainer() {
- for (const auto& request : requests_) {
- request.second(Status::INTERNAL_ERROR);
- }
- for (const auto& request : debug_requests_) {
- request.second(Status::INTERNAL_ERROR);
- }
-}
-
-void LedgerManager::PageManagerContainer::set_on_empty(
- fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- connection_notifier_.set_on_empty([this] { CheckEmpty(); });
- if (page_manager_) {
- page_manager_->set_on_empty(
- [this] { connection_notifier_.UnregisterExternalRequests(); });
- }
-}
-
-void LedgerManager::PageManagerContainer::BindPage(
- fidl::InterfaceRequest<Page> page_request,
- fit::function<void(Status)> callback) {
- connection_notifier_.RegisterExternalRequest();
-
- if (status_ != Status::OK) {
- callback(status_);
- return;
- }
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id_, std::move(page_request));
- if (page_manager_) {
- page_manager_->AddPageDelayingFacade(std::move(delaying_facade),
- std::move(callback));
- return;
- }
- requests_.emplace_back(std::move(delaying_facade), std::move(callback));
-}
-
-void LedgerManager::PageManagerContainer::BindPageDebug(
- fidl::InterfaceRequest<ledger_internal::PageDebug> page_debug,
- fit::function<void(Status)> callback) {
- connection_notifier_.RegisterExternalRequest();
-
- if (status_ != Status::OK) {
- callback(status_);
- return;
- }
- if (page_manager_) {
- page_manager_->BindPageDebug(std::move(page_debug), std::move(callback));
- return;
- }
- debug_requests_.emplace_back(std::move(page_debug), std::move(callback));
-}
-
-void LedgerManager::PageManagerContainer::NewInternalRequest(
- fit::function<void(Status, ExpiringToken, PageManager*)> callback) {
- if (status_ != Status::OK) {
- callback(status_, fit::defer<fit::closure>([] {}), nullptr);
- return;
- }
-
- if (page_manager_) {
- callback(status_, NewExpiringToken(), page_manager_.get());
- return;
- }
-
- internal_request_callbacks_.push_back(std::move(callback));
-}
-
-void LedgerManager::PageManagerContainer::SetPageManager(
- Status status, std::unique_ptr<PageManager> page_manager) {
- TRACE_DURATION("ledger", "ledger_manager_set_page_manager");
-
- FXL_DCHECK(!page_manager_is_set_);
- FXL_DCHECK((status != Status::OK) == !page_manager);
- status_ = status;
- page_manager_ = std::move(page_manager);
- page_manager_is_set_ = true;
-
- for (auto& request : requests_) {
- if (page_manager_) {
- page_manager_->AddPageDelayingFacade(std::move(request.first),
- std::move(request.second));
- } else {
- request.second(status_);
- }
- }
- requests_.clear();
-
- for (auto& request : debug_requests_) {
- if (page_manager_) {
- page_manager_->BindPageDebug(std::move(request.first),
- std::move(request.second));
- } else {
- request.second(status_);
- }
- }
- debug_requests_.clear();
-
- for (auto& callback : internal_request_callbacks_) {
- if (!page_manager_) {
- callback(status_, fit::defer<fit::closure>([] {}), nullptr);
- continue;
- }
- callback(status_, NewExpiringToken(), page_manager_.get());
- }
-
- if (page_manager_) {
- page_manager_->set_on_empty(
- [this] { connection_notifier_.UnregisterExternalRequests(); });
- } else {
- CheckEmpty();
- }
-}
-
-bool LedgerManager::PageManagerContainer::PageConnectionIsOpen() {
- return (page_manager_ && !page_manager_->IsEmpty()) || !requests_.empty() ||
- !debug_requests_.empty();
-}
-
-ExpiringToken LedgerManager::PageManagerContainer::NewExpiringToken() {
- connection_notifier_.RegisterInternalRequest();
- return ExpiringToken(callback::MakeScoped(weak_factory_.GetWeakPtr(), [this] {
- connection_notifier_.UnregisterInternalRequest();
- }));
-}
-
-void LedgerManager::PageManagerContainer::CheckEmpty() {
- // The PageManagerContainer is not considered empty until |SetPageManager| has
- // been called.
- if (on_empty_callback_ && connection_notifier_.IsEmpty() &&
- page_manager_is_set_ && (!page_manager_ || page_manager_->IsEmpty())) {
- on_empty_callback_();
- }
-}
-
-LedgerManager::LedgerManager(
- Environment* environment, std::string ledger_name,
- std::unique_ptr<encryption::EncryptionService> encryption_service,
- std::unique_ptr<storage::LedgerStorage> storage,
- std::unique_ptr<sync_coordinator::LedgerSync> ledger_sync,
- PageUsageListener* page_usage_listener)
- : environment_(environment),
- ledger_name_(std::move(ledger_name)),
- encryption_service_(std::move(encryption_service)),
- storage_(std::move(storage)),
- ledger_sync_(std::move(ledger_sync)),
- ledger_impl_(environment_, this),
- merge_manager_(environment_),
- page_usage_listener_(page_usage_listener) {
- bindings_.set_empty_set_handler([this] { CheckEmpty(); });
- page_managers_.set_on_empty([this] { CheckEmpty(); });
- ledger_debug_bindings_.set_empty_set_handler([this] { CheckEmpty(); });
-}
-
-LedgerManager::~LedgerManager() {}
-
-void LedgerManager::BindLedger(fidl::InterfaceRequest<Ledger> ledger_request) {
- bindings_.AddBinding(&ledger_impl_, std::move(ledger_request));
-}
-
-void LedgerManager::PageIsClosedAndSynced(
- storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) {
- auto is_synced = [](PageManager* page_manager,
- fit::function<void(Status, bool)> on_done) {
- page_manager->IsSynced(std::move(on_done));
- };
- PageIsClosedAndSatisfiesPredicate(page_id, std::move(is_synced),
- std::move(callback));
-}
-
-void LedgerManager::PageIsClosedOfflineAndEmpty(
- storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) {
- auto is_offline_and_empty = [](PageManager* page_manager,
- fit::function<void(Status, bool)> on_done) {
- page_manager->IsOfflineAndEmpty(std::move(on_done));
- };
- PageIsClosedAndSatisfiesPredicate(page_id, std::move(is_offline_and_empty),
- std::move(callback));
-}
-
-void LedgerManager::DeletePageStorage(convert::ExtendedStringView page_id,
- fit::function<void(Status)> callback) {
- auto it = page_managers_.find(page_id);
- if (it != page_managers_.end()) {
- callback(Status::ILLEGAL_STATE);
- return;
- }
-
- // Block all page requests until deletion is complete.
- page_availability_manager_.MarkPageBusy(page_id);
- storage_->DeletePageStorage(
- page_id, [this, page_id = page_id.ToString(),
- callback = std::move(callback)](storage::Status status) {
- page_availability_manager_.MarkPageAvailable(page_id);
- callback(PageUtils::ConvertStatus(status));
- });
-}
-
-void LedgerManager::GetPage(storage::PageIdView page_id, PageState page_state,
- fidl::InterfaceRequest<Page> page_request,
- fit::function<void(Status)> callback) {
- MaybeMarkPageOpened(page_id);
-
- // If we have the page manager ready, just bind the request and return.
- auto it = page_managers_.find(page_id);
- if (it != page_managers_.end()) {
- it->second.BindPage(std::move(page_request), std::move(callback));
- return;
- }
-
- PageManagerContainer* container = AddPageManagerContainer(page_id);
- // TODO(LE-631): We will need to remove empty pages that are unknown to the
- // user or the page usage database.
- container->BindPage(std::move(page_request), std::move(callback));
-
- InitPageManagerContainer(container, page_id,
- [this, container, page_id = page_id.ToString(),
- page_state](Status status) mutable {
- // Create the page if it wasn't found.
- if (status == Status::PAGE_NOT_FOUND) {
- CreatePageStorage(std::move(page_id), page_state,
- container);
- }
- });
-}
-
-void LedgerManager::InitPageManagerContainer(
- PageManagerContainer* container, convert::ExtendedStringView page_id,
- fit::function<void(Status)> callback) {
- page_availability_manager_.OnPageAvailable(
- page_id, [this, container, page_id = page_id.ToString(),
- callback = std::move(callback)]() mutable {
- storage_->GetPageStorage(
- std::move(page_id),
- [this, container, callback = std::move(callback)](
- storage::Status storage_status,
- std::unique_ptr<storage::PageStorage> page_storage) mutable {
- Status status =
- PageUtils::ConvertStatus(storage_status, Status::OK);
- if (status != Status::OK) {
- container->SetPageManager(status, nullptr);
- callback(status);
- return;
- }
-
- // If the page was found locally, just use it and return.
- if (page_storage) {
- container->SetPageManager(
- Status::OK,
- NewPageManager(std::move(page_storage),
- PageManager::PageStorageState::AVAILABLE));
- callback(status);
- return;
- }
-
- callback(Status::PAGE_NOT_FOUND);
- });
- });
-}
-
-void LedgerManager::CreatePageStorage(storage::PageId page_id,
- PageState page_state,
- PageManagerContainer* container) {
- page_availability_manager_.OnPageAvailable(
- page_id,
- [this, page_id = std::move(page_id), page_state, container]() mutable {
- storage_->CreatePageStorage(
- std::move(page_id),
- [this, page_state, container](
- storage::Status status,
- std::unique_ptr<storage::PageStorage> page_storage) {
- if (status != storage::Status::OK) {
- container->SetPageManager(Status::INTERNAL_ERROR, nullptr);
- return;
- }
- container->SetPageManager(
- Status::OK,
- NewPageManager(
- std::move(page_storage),
- page_state == PageState::NEW
- ? PageManager::PageStorageState::AVAILABLE
- : PageManager::PageStorageState::NEEDS_SYNC));
- });
- });
-}
-
-LedgerManager::PageManagerContainer* LedgerManager::AddPageManagerContainer(
- storage::PageIdView page_id) {
- auto ret = page_managers_.emplace(
- std::piecewise_construct, std::forward_as_tuple(page_id.ToString()),
- std::forward_as_tuple(ledger_name_, page_id.ToString(),
- page_usage_listener_));
- FXL_DCHECK(ret.second);
- return &ret.first->second;
-}
-
-std::unique_ptr<PageManager> LedgerManager::NewPageManager(
- std::unique_ptr<storage::PageStorage> page_storage,
- PageManager::PageStorageState state) {
- std::unique_ptr<sync_coordinator::PageSync> page_sync;
- if (ledger_sync_) {
- page_sync =
- ledger_sync_->CreatePageSync(page_storage.get(), page_storage.get());
- }
- return std::make_unique<PageManager>(
- environment_, std::move(page_storage), std::move(page_sync),
- merge_manager_.GetMergeResolver(page_storage.get()), state);
-}
-
-void LedgerManager::PageIsClosedAndSatisfiesPredicate(
- storage::PageIdView page_id,
- fit::function<void(PageManager*, fit::function<void(Status, bool)>)>
- predicate,
- fit::function<void(Status, PagePredicateResult)> callback) {
- // Start logging whether the page has been opened during the execution of
- // this method.
- uint64_t operation_id = page_was_opened_id_++;
- page_was_opened_map_[page_id.ToString()].push_back(operation_id);
- auto on_return =
- fit::defer([this, page_id = page_id.ToString(), operation_id] {
- RemoveTrackedPage(page_id, operation_id);
- });
-
- PageManagerContainer* container;
-
- auto it = page_managers_.find(page_id);
- if (it != page_managers_.end()) {
- // The page manager is open, check if there are any open connections.
- container = &it->second;
- if (container->PageConnectionIsOpen()) {
- callback(Status::OK, PagePredicateResult::PAGE_OPENED);
- return;
- }
- } else {
- // Create a new container and get the PageStorage.
- container = AddPageManagerContainer(page_id);
- InitPageManagerContainer(container, page_id, [container](Status status) {
- if (status == Status::PAGE_NOT_FOUND) {
- container->SetPageManager(status, nullptr);
- }
- });
- }
-
- container->NewInternalRequest(
- [this, page_id = page_id.ToString(), operation_id,
- predicate = std::move(predicate), on_return = std::move(on_return),
- callback = std::move(callback)](Status status, ExpiringToken token,
- PageManager* page_manager) mutable {
- auto final_callback =
- [token = std::move(token), callback = std::move(callback)](
- Status status, PagePredicateResult result) mutable {
- // The token needs to be valid while |predicate| is being
- // computed. Invalidate it right before calling the callback.
- token.call();
- callback(status, result);
- };
- if (status != Status::OK) {
- final_callback(status, PagePredicateResult::PAGE_OPENED);
- return;
- }
- FXL_DCHECK(page_manager);
- predicate(page_manager, [this, page_id = std::move(page_id),
- operation_id, on_return = std::move(on_return),
- callback = std::move(final_callback)](
- Status status, bool condition) mutable {
- on_return.cancel();
- if (!RemoveTrackedPage(page_id, operation_id) ||
- status != Status::OK) {
- // If |RemoveTrackedPage| returns false, this means that
- // the page was opened during this operation and
- // |PAGE_OPENED| must be returned.
- callback(status, PagePredicateResult::PAGE_OPENED);
- return;
- }
- callback(Status::OK, condition ? PagePredicateResult::YES
- : PagePredicateResult::NO);
- });
- });
-}
-
-bool LedgerManager::RemoveTrackedPage(storage::PageIdView page_id,
- uint64_t operation_id) {
- auto it = page_was_opened_map_.find(page_id.ToString());
- if (it == page_was_opened_map_.end()) {
- return false;
- }
- if (it->second.size() == 1) {
- // This is the last operation for this page: delete the page's entry.
- page_was_opened_map_.erase(it);
- return true;
- }
- // Erase the operation_id, if found, from the found vector (it->second).
- auto operation_it =
- std::find(it->second.begin(), it->second.end(), operation_id);
- if (operation_it != it->second.end()) {
- it->second.erase(operation_it);
- return true;
- }
- return false;
-}
-
-void LedgerManager::MaybeMarkPageOpened(storage::PageIdView page_id) {
- page_was_opened_map_.erase(page_id.ToString());
-}
-
-void LedgerManager::CheckEmpty() {
- if (on_empty_callback_ && bindings_.size() == 0 && page_managers_.empty() &&
- ledger_debug_bindings_.size() == 0)
- on_empty_callback_();
-}
-
-void LedgerManager::SetConflictResolverFactory(
- fidl::InterfaceHandle<ConflictResolverFactory> factory) {
- merge_manager_.AddFactory(std::move(factory));
-}
-
-void LedgerManager::BindLedgerDebug(
- fidl::InterfaceRequest<LedgerDebug> request) {
- ledger_debug_bindings_.AddBinding(this, std::move(request));
-}
-
-// TODO(ayaelattar): See LE-370: Inspect ledgers and pages not currently active.
-void LedgerManager::GetPagesList(GetPagesListCallback callback) {
- fidl::VectorPtr<PageId> result;
- result.resize(0);
- for (const auto& key_value : page_managers_) {
- PageId page_id;
- convert::ToArray(key_value.first, &page_id.id);
- result.push_back(page_id);
- }
- callback(std::move(result));
-}
-
-void LedgerManager::GetPageDebug(
- PageId page_id,
- fidl::InterfaceRequest<ledger_internal::PageDebug> page_debug,
- GetPageDebugCallback callback) {
- MaybeMarkPageOpened(page_id.id);
- auto it = page_managers_.find(convert::ExtendedStringView(page_id.id));
- if (it != page_managers_.end()) {
- it->second.BindPageDebug(std::move(page_debug), std::move(callback));
- } else {
- callback(Status::PAGE_NOT_FOUND);
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/ledger_manager.h b/bin/ledger/app/ledger_manager.h
deleted file mode 100644
index 4d6ffcd..0000000
--- a/bin/ledger/app/ledger_manager.h
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_LEDGER_MANAGER_H_
-#define PERIDOT_BIN_LEDGER_APP_LEDGER_MANAGER_H_
-
-#include <functional>
-#include <map>
-#include <memory>
-#include <type_traits>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/app/ledger_impl.h"
-#include "peridot/bin/ledger/app/merging/ledger_merge_manager.h"
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/app/page_usage_listener.h"
-#include "peridot/bin/ledger/app/types.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/bin/ledger/sync_coordinator/public/ledger_sync.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-// Manages a ledger instance. A ledger instance represents the data scoped to a
-// particular user and a particular client app.
-//
-// LedgerManager owns all per-ledger-instance objects: LedgerStorage and a FIDL
-// LedgerImpl. It is safe to delete it at any point - this closes all channels,
-// deletes the LedgerImpl and tears down the storage.
-class LedgerManager : public LedgerImpl::Delegate,
- public ledger_internal::LedgerDebug {
- public:
- LedgerManager(
- Environment* environment, std::string ledger_name,
- std::unique_ptr<encryption::EncryptionService> encryption_service,
- std::unique_ptr<storage::LedgerStorage> storage,
- std::unique_ptr<sync_coordinator::LedgerSync> ledger_sync,
- PageUsageListener* page_usage_listener);
- ~LedgerManager() override;
-
- // Creates a new proxy for the LedgerImpl managed by this LedgerManager.
- void BindLedger(fidl::InterfaceRequest<Ledger> ledger_request);
-
- // Checks whether the given page is closed and synced. The result returned in
- // the callback will be |PAGE_OPENED| if the page is opened after calling this
- // method and before the callback is called. Otherwise it will be |YES| or
- // |NO| depending on whether the page is synced or not.
- void PageIsClosedAndSynced(
- storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback);
-
- // Checks whether the given page is closed, offline and empty. The result
- // returned in the callback will be |PAGE_OPENED| if the page is opened after
- // calling this method and before the callback is called. Otherwise it will be
- // |YES| or |NO| depending on whether the page is offline and empty or not.
- void PageIsClosedOfflineAndEmpty(
- storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback);
-
- // Deletes the local copy of the page. If the page is currently open, the
- // callback will be called with |ILLEGAL_STATE|.
- void DeletePageStorage(convert::ExtendedStringView page_id,
- fit::function<void(Status)> callback);
-
- // LedgerImpl::Delegate:
- void GetPage(convert::ExtendedStringView page_id, PageState page_state,
- fidl::InterfaceRequest<Page> page_request,
- fit::function<void(Status)> callback) override;
- void SetConflictResolverFactory(
- fidl::InterfaceHandle<ConflictResolverFactory> factory) override;
-
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- // Creates a new proxy for the LedgerDebug implemented by this LedgerManager.
- void BindLedgerDebug(fidl::InterfaceRequest<LedgerDebug> request);
-
- private:
- class PageManagerContainer;
-
- // Stores whether a given page is busy or available. After |MarkPageBusy| has
- // been called, all calls to |OnPageAvailable| will be delayed until a call to
- // |MarkPageAvailable|. By default, all pages are available.
- class PageAvailabilityManager {
- public:
- // Marks the page as busy and delays calling the callback in
- // |OnPageAvailable| for this page. It is an error to call this method for a
- // page that is already busy.
- void MarkPageBusy(convert::ExtendedStringView page_id);
-
- // Marks the page as available and calls any pending callbacks from
- // |OnPageAvailable| for this page.
- void MarkPageAvailable(convert::ExtendedStringView page_id);
-
- // If the page is available calls the given callback directly. Otherwise,
- // the callback is registered util the page becomes available.
- void OnPageAvailable(convert::ExtendedStringView page_id,
- fit::closure on_page_available);
-
- private:
- // For each busy page, stores the list of pending callbacks.
- std::map<storage::PageId, std::vector<fit::closure>> busy_pages_;
- };
-
- // Requests a PageStorage object for the given |container|. If the page is not
- // locally available, the |callback| is called with |PAGE_NOT_FOUND|.
- void InitPageManagerContainer(PageManagerContainer* container,
- convert::ExtendedStringView page_id,
- fit::function<void(Status)> callback);
-
- // Creates a page storage for the given |page_id| and completes the
- // PageManagerContainer.
- void CreatePageStorage(storage::PageId page_id, PageState page_state,
- PageManagerContainer* container);
-
- // Adds a new PageManagerContainer for |page_id| and configures it so that it
- // is automatically deleted from |page_managers_| when the last local client
- // disconnects from the page. Returns the container.
- PageManagerContainer* AddPageManagerContainer(storage::PageIdView page_id);
-
- // Creates a new page manager for the given storage.
- std::unique_ptr<PageManager> NewPageManager(
- std::unique_ptr<storage::PageStorage> page_storage,
- PageManager::PageStorageState state);
-
- // Checks whether the given page is closed and staisfies the given
- // |predicate|. The result returned in the callback will be |PAGE_OPENED| if
- // the page is opened after calling this method and before the callback is
- // called. Otherwise it will be |YES| or |NO| depending on whether the
- // predicate is satisfied.
- void PageIsClosedAndSatisfiesPredicate(
- storage::PageIdView page_id,
- fit::function<void(PageManager*, fit::function<void(Status, bool)>)>
- predicate,
- fit::function<void(Status, PagePredicateResult)> callback);
-
- // Marks the page with the given id as no longer tracked by the given
- // operation. Returns true if the entry was found; false otherwise.
- bool RemoveTrackedPage(storage::PageIdView page_id, uint64_t operation_id);
-
- // If the page is among the ones whose usage is being tracked, marks this page
- // as opened. See also |page_was_opened_map_|.
- void MaybeMarkPageOpened(storage::PageIdView page_id);
-
- void CheckEmpty();
-
- // LedgerDebug:
- void GetPagesList(GetPagesListCallback callback) override;
-
- void GetPageDebug(
- PageId page_id,
- fidl::InterfaceRequest<ledger_internal::PageDebug> page_debug,
- GetPageDebugCallback callback) override;
-
- Environment* const environment_;
- std::string ledger_name_;
- std::unique_ptr<encryption::EncryptionService> encryption_service_;
- std::unique_ptr<storage::LedgerStorage> storage_;
- std::unique_ptr<sync_coordinator::LedgerSync> ledger_sync_;
- LedgerImpl ledger_impl_;
- // |merge_manager_| must be destructed after |page_managers_| to ensure it
- // outlives any page-specific merge resolver.
- LedgerMergeManager merge_manager_;
- fidl::BindingSet<Ledger> bindings_;
-
- // Mapping from each page id to the manager of that page.
- callback::AutoCleanableMap<storage::PageId, PageManagerContainer,
- convert::StringViewComparator>
- page_managers_;
- PageUsageListener* page_usage_listener_;
- fit::closure on_empty_callback_;
-
- fidl::BindingSet<LedgerDebug> ledger_debug_bindings_;
-
- PageAvailabilityManager page_availability_manager_;
-
- // |page_was_opened_map_| is used to track whether certain pages were opened
- // during a given operation. When |PageIsClosedAndSatisfiesPredicate()| is
- // called, an entry is added in this map, with the given page_id as key, while
- // a unique operation id is added in the corresponding value. That entry will
- // be deleted either when that opertion is done, or when the page is opened
- // because of an external request. This guarantees that if before calling the
- // callback of |PageIsClosedAndSatisfiesPredicate|, the entry is still present
- // in the map, the page was not opened during that operation. Otherwise, it
- // was, and |PAGE_OPENED| should be returned.
- std::map<storage::PageId, std::vector<uint64_t>> page_was_opened_map_;
- uint64_t page_was_opened_id_ = 0;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerManager);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_LEDGER_MANAGER_H_
diff --git a/bin/ledger/app/ledger_manager_unittest.cc b/bin/ledger/app/ledger_manager_unittest.cc
deleted file mode 100644
index 1faa3e6..0000000
--- a/bin/ledger/app/ledger_manager_unittest.cc
+++ /dev/null
@@ -1,1005 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/ledger_manager.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/callback/waiter.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <zircon/syscalls.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/disk_cleanup_manager_impl.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-#include "peridot/bin/ledger/storage/public/ledger_storage.h"
-#include "peridot/bin/ledger/sync_coordinator/public/ledger_sync.h"
-#include "peridot/bin/ledger/testing/fake_disk_cleanup_manager.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-class DelayingCallbacksManager {
- public:
- DelayingCallbacksManager() {}
- virtual ~DelayingCallbacksManager() {}
-
- // Returns true if the PageStorage of the page with the given id should delay
- // calling the callback of |IsSynced|.
- virtual bool ShouldDelayIsSyncedCallback(storage::PageIdView page_id) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(DelayingCallbacksManager);
-};
-
-class DelayIsSyncedCallbackFakePageStorage
- : public storage::fake::FakePageStorage {
- public:
- explicit DelayIsSyncedCallbackFakePageStorage(
- Environment* environment,
- DelayingCallbacksManager* delaying_callbacks_manager, storage::PageId id)
- : storage::fake::FakePageStorage(environment, id),
- delaying_callbacks_manager_(delaying_callbacks_manager) {}
- ~DelayIsSyncedCallbackFakePageStorage() override {}
-
- void IsSynced(fit::function<void(storage::Status, bool)> callback) override {
- if (!delaying_callbacks_manager_->ShouldDelayIsSyncedCallback(page_id_)) {
- storage::fake::FakePageStorage::IsSynced(std::move(callback));
- return;
- }
- is_synced_callback_ = std::move(callback);
- }
-
- void IsEmpty(fit::function<void(storage::Status, bool)> callback) override {
- callback(storage::Status::OK, true);
- }
-
- bool IsOnline() override { return false; }
-
- void CallIsSyncedCallback() {
- storage::fake::FakePageStorage::IsSynced(std::move(is_synced_callback_));
- }
-
- private:
- fit::function<void(storage::Status, bool)> is_synced_callback_;
- DelayingCallbacksManager* delaying_callbacks_manager_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DelayIsSyncedCallbackFakePageStorage);
-};
-
-class FakeLedgerStorage : public storage::LedgerStorage,
- public DelayingCallbacksManager {
- public:
- explicit FakeLedgerStorage(Environment* environment)
- : environment_(environment) {}
- ~FakeLedgerStorage() override {}
-
- void CreatePageStorage(
- storage::PageId page_id,
- fit::function<void(storage::Status,
- std::unique_ptr<storage::PageStorage>)>
- callback) override {
- create_page_calls.push_back(std::move(page_id));
- callback(storage::Status::IO_ERROR, nullptr);
- }
-
- void GetPageStorage(storage::PageId page_id,
- fit::function<void(storage::Status,
- std::unique_ptr<storage::PageStorage>)>
- callback) override {
- get_page_calls.push_back(page_id);
- async::PostTask(
- environment_->dispatcher(),
- [this, callback = std::move(callback), page_id]() mutable {
- if (should_get_page_fail) {
- callback(storage::Status::NOT_FOUND, nullptr);
- } else {
- auto fake_page_storage =
- std::make_unique<DelayIsSyncedCallbackFakePageStorage>(
- environment_, this, page_id);
- // If the page was opened before, restore the previous sync state.
- fake_page_storage->set_synced(synced_pages_.find(page_id) !=
- synced_pages_.end());
- page_storages_[std::move(page_id)] = fake_page_storage.get();
- callback(storage::Status::OK, std::move(fake_page_storage));
- }
- });
- }
-
- void DeletePageStorage(
- storage::PageIdView /*page_id*/,
- fit::function<void(storage::Status)> callback) override {
- delete_page_storage_callback = std::move(callback);
- }
-
- void ClearCalls() {
- create_page_calls.clear();
- get_page_calls.clear();
- page_storages_.clear();
- }
-
- void DelayIsSyncedCallback(storage::PageIdView page_id, bool delay_callback) {
- if (delay_callback) {
- pages_with_delayed_callback.insert(page_id.ToString());
- } else {
- pages_with_delayed_callback.erase(page_id.ToString());
- }
- }
-
- // DelayingCallbacksManager:
- bool ShouldDelayIsSyncedCallback(storage::PageIdView page_id) override {
- return pages_with_delayed_callback.find(page_id.ToString()) !=
- pages_with_delayed_callback.end();
- }
-
- void CallIsSyncedCallback(storage::PageIdView page_id) {
- auto it = page_storages_.find(page_id.ToString());
- FXL_CHECK(it != page_storages_.end());
- it->second->CallIsSyncedCallback();
- }
-
- void set_page_storage_synced(storage::PageIdView page_id, bool is_synced) {
- storage::PageId page_id_string = page_id.ToString();
- if (is_synced) {
- synced_pages_.insert(page_id_string);
- } else {
- auto it = synced_pages_.find(page_id_string);
- if (it != synced_pages_.end()) {
- synced_pages_.erase(it);
- }
- }
-
- FXL_CHECK(page_storages_.find(page_id_string) != page_storages_.end());
- page_storages_[page_id_string]->set_synced(is_synced);
- }
-
- void set_page_storage_offline_empty(storage::PageIdView page_id,
- bool is_offline_empty) {
- storage::PageId page_id_string = page_id.ToString();
- if (is_offline_empty) {
- offline_empty_pages_.insert(page_id_string);
- } else {
- auto it = offline_empty_pages_.find(page_id_string);
- if (it != offline_empty_pages_.end()) {
- offline_empty_pages_.erase(it);
- }
- }
- }
-
- bool should_get_page_fail = false;
- std::vector<storage::PageId> create_page_calls;
- std::vector<storage::PageId> get_page_calls;
- fit::function<void(storage::Status)> delete_page_storage_callback;
-
- private:
- Environment* const environment_;
- std::map<storage::PageId, DelayIsSyncedCallbackFakePageStorage*>
- page_storages_;
- std::set<storage::PageId> synced_pages_;
- std::set<storage::PageId> offline_empty_pages_;
- std::set<storage::PageId> pages_with_delayed_callback;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeLedgerStorage);
-};
-
-class FakeLedgerSync : public sync_coordinator::LedgerSync {
- public:
- FakeLedgerSync() {}
- ~FakeLedgerSync() override {}
-
- std::unique_ptr<sync_coordinator::PageSync> CreatePageSync(
- storage::PageStorage* /*page_storage*/,
- storage::PageSyncClient* /*page_sync_client*/) override {
- called = true;
- return nullptr;
- }
-
- bool called = false;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeLedgerSync);
-};
-
-class LedgerManagerTest : public TestWithEnvironment {
- public:
- LedgerManagerTest() {}
-
- ~LedgerManagerTest() override {}
-
- // gtest::TestWithEnvironment:
- void SetUp() override {
- TestWithEnvironment::SetUp();
- std::unique_ptr<FakeLedgerStorage> storage =
- std::make_unique<FakeLedgerStorage>(&environment_);
- storage_ptr = storage.get();
- std::unique_ptr<FakeLedgerSync> sync = std::make_unique<FakeLedgerSync>();
- sync_ptr = sync.get();
- disk_cleanup_manager_ = std::make_unique<FakeDiskCleanupManager>();
- ledger_manager_ = std::make_unique<LedgerManager>(
- &environment_, "test_ledger",
- std::make_unique<encryption::FakeEncryptionService>(dispatcher()),
- std::move(storage), std::move(sync), disk_cleanup_manager_.get());
- ledger_manager_->BindLedger(ledger_.NewRequest());
- ledger_manager_->BindLedgerDebug(ledger_debug_.NewRequest());
- }
-
- PageId RandomId() {
- PageId result;
- environment_.random()->Draw(&result.id);
- return result;
- }
-
- protected:
- FakeLedgerStorage* storage_ptr;
- FakeLedgerSync* sync_ptr;
- std::unique_ptr<FakeDiskCleanupManager> disk_cleanup_manager_;
- std::unique_ptr<LedgerManager> ledger_manager_;
- LedgerPtr ledger_;
- ledger_internal::LedgerDebugPtr ledger_debug_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerManagerTest);
-};
-
-class StubConflictResolverFactory : public ConflictResolverFactory {
- public:
- explicit StubConflictResolverFactory(
- fidl::InterfaceRequest<ConflictResolverFactory> request)
- : binding_(this, std::move(request)) {
- binding_.set_error_handler(
- [this](zx_status_t status) { disconnected = true; });
- }
-
- bool disconnected = false;
-
- private:
- void GetPolicy(PageId page_id,
- fit::function<void(MergePolicy)> callback) override {}
-
- void NewConflictResolver(
- PageId page_id,
- fidl::InterfaceRequest<ConflictResolver> resolver) override {}
-
- fidl::Binding<ConflictResolverFactory> binding_;
-};
-
-// Verifies that LedgerImpl proxies vended by LedgerManager work correctly,
-// that is, make correct calls to ledger storage.
-TEST_F(LedgerManagerTest, LedgerImpl) {
- EXPECT_EQ(0u, storage_ptr->create_page_calls.size());
- EXPECT_EQ(0u, storage_ptr->get_page_calls.size());
-
- PagePtr page;
- storage_ptr->should_get_page_fail = true;
- ledger_->GetPage(nullptr, page.NewRequest(), [this](Status) { QuitLoop(); });
- RunLoopUntilIdle();
- EXPECT_EQ(1u, storage_ptr->create_page_calls.size());
- EXPECT_EQ(1u, storage_ptr->get_page_calls.size());
- page.Unbind();
- storage_ptr->ClearCalls();
-
- storage_ptr->should_get_page_fail = true;
- ledger_->GetRootPage(page.NewRequest(), [this](Status) { QuitLoop(); });
- RunLoopUntilIdle();
- EXPECT_EQ(1u, storage_ptr->create_page_calls.size());
- EXPECT_EQ(1u, storage_ptr->get_page_calls.size());
- page.Unbind();
- storage_ptr->ClearCalls();
-
- PageId id = RandomId();
- ledger_->GetPage(fidl::MakeOptional(id), page.NewRequest(),
- [this](Status) { QuitLoop(); });
- RunLoopUntilIdle();
- EXPECT_EQ(1u, storage_ptr->create_page_calls.size());
- ASSERT_EQ(1u, storage_ptr->get_page_calls.size());
- EXPECT_EQ(convert::ToString(id.id), storage_ptr->get_page_calls[0]);
- page.Unbind();
- storage_ptr->ClearCalls();
-}
-
-// Verifies that deleting the LedgerManager closes the channels connected to
-// LedgerImpl.
-TEST_F(LedgerManagerTest, DeletingLedgerManagerClosesConnections) {
- bool ledger_closed = false;
- ledger_.set_error_handler([this, &ledger_closed](zx_status_t status) {
- ledger_closed = true;
- QuitLoop();
- });
-
- ledger_manager_.reset();
- RunLoopUntilIdle();
- EXPECT_TRUE(ledger_closed);
-}
-
-TEST_F(LedgerManagerTest, OnEmptyCalled) {
- bool on_empty_called;
- ledger_manager_->set_on_empty(callback::SetWhenCalled(&on_empty_called));
-
- ledger_.Unbind();
- ledger_debug_.Unbind();
- RunLoopUntilIdle();
- EXPECT_TRUE(on_empty_called);
-}
-
-TEST_F(LedgerManagerTest, PageIsClosedAndSyncedCheckNotFound) {
- bool called;
- Status status;
- PagePredicateResult is_closed_and_synced;
-
- PageId id = RandomId();
-
- // Check for a page that doesn't exist.
- storage_ptr->should_get_page_fail = true;
- ledger_manager_->PageIsClosedAndSynced(
- id.id, callback::Capture(callback::SetWhenCalled(&called), &status,
- &is_closed_and_synced));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PAGE_NOT_FOUND, status);
-}
-
-// Check for a page that exists, is synced and open. PageIsClosedAndSynced
-// should be false.
-TEST_F(LedgerManagerTest, PageIsClosedAndSyncedCheckClosed) {
- bool called;
- Status status;
- PagePredicateResult is_closed_and_synced;
-
- storage_ptr->should_get_page_fail = false;
- PagePtr page;
- PageId id = RandomId();
- storage::PageIdView storage_page_id = convert::ExtendedStringView(id.id);
-
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- storage_ptr->set_page_storage_synced(storage_page_id, true);
- ledger_manager_->PageIsClosedAndSynced(
- storage_page_id, callback::Capture(callback::SetWhenCalled(&called),
- &status, &is_closed_and_synced));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(PagePredicateResult::PAGE_OPENED, is_closed_and_synced);
-
- // Close the page. PageIsClosedAndSynced should now be true.
- page.Unbind();
- RunLoopUntilIdle();
-
- ledger_manager_->PageIsClosedAndSynced(
- storage_page_id, callback::Capture(callback::SetWhenCalled(&called),
- &status, &is_closed_and_synced));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(PagePredicateResult::YES, is_closed_and_synced);
-}
-
-// Check for a page that exists, is closed, but is not synced.
-// PageIsClosedAndSynced should be false.
-TEST_F(LedgerManagerTest, PageIsClosedAndSyncedCheckSynced) {
- bool called;
- Status status;
- PagePredicateResult is_closed_and_synced;
-
- storage_ptr->should_get_page_fail = false;
- PagePtr page;
- PageId id = RandomId();
- storage::PageIdView storage_page_id = convert::ExtendedStringView(id.id);
-
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- // Mark the page as unsynced and close it.
- storage_ptr->set_page_storage_synced(storage_page_id, false);
- page.Unbind();
- RunLoopUntilIdle();
-
- ledger_manager_->PageIsClosedAndSynced(
- storage_page_id, callback::Capture(callback::SetWhenCalled(&called),
- &status, &is_closed_and_synced));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(PagePredicateResult::NO, is_closed_and_synced);
-}
-
-// Check for a page that exists, is closed, and synced, but was opened during
-// the PageIsClosedAndSynced call. Expect an |PAGE_OPENED| result.
-TEST_F(LedgerManagerTest, PageIsClosedAndSyncedCheckPageOpened) {
- bool called;
- Status status;
- PagePredicateResult is_closed_and_synced;
-
- storage_ptr->should_get_page_fail = false;
- PagePtr page;
- PageId id = RandomId();
- storage::PageIdView storage_page_id = convert::ExtendedStringView(id.id);
-
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- // Mark the page as synced and close it.
- storage_ptr->set_page_storage_synced(storage_page_id, true);
- page.Unbind();
- RunLoopUntilIdle();
-
- // Call PageIsClosedAndSynced but don't let it terminate.
- bool page_is_closed_and_synced_called = false;
- storage_ptr->DelayIsSyncedCallback(storage_page_id, true);
- ledger_manager_->PageIsClosedAndSynced(
- storage_page_id, callback::Capture(callback::SetWhenCalled(
- &page_is_closed_and_synced_called),
- &status, &is_closed_and_synced));
- RunLoopUntilIdle();
- EXPECT_FALSE(page_is_closed_and_synced_called);
-
- // Open and close the page.
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- page.Unbind();
- RunLoopUntilIdle();
-
- // Make sure PageIsClosedAndSynced terminates with a |PAGE_OPENED| result.
- storage_ptr->CallIsSyncedCallback(storage_page_id);
- EXPECT_TRUE(page_is_closed_and_synced_called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(PagePredicateResult::PAGE_OPENED, is_closed_and_synced);
-}
-
-// Check for a page that exists, is closed, and synced. Test two concurrent
-// calls to PageIsClosedAndSynced, where the second one will start and terminate
-// without the page being opened by external requests.
-TEST_F(LedgerManagerTest, PageIsClosedAndSyncedConcurrentCalls) {
- bool called;
- Status status;
-
- storage_ptr->should_get_page_fail = false;
- PagePtr page;
- PageId id = RandomId();
- storage::PageIdView storage_page_id = convert::ExtendedStringView(id.id);
-
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- // Mark the page as synced and close it.
- storage_ptr->set_page_storage_synced(storage_page_id, true);
- page.Unbind();
- RunLoopUntilIdle();
-
- // Make a first call to PageIsClosedAndSynced but don't let it terminate.
- bool called1 = false;
- Status status1;
- PagePredicateResult is_closed_and_synced1;
- storage_ptr->DelayIsSyncedCallback(storage_page_id, true);
- ledger_manager_->PageIsClosedAndSynced(
- storage_page_id, callback::Capture(callback::SetWhenCalled(&called1),
- &status1, &is_closed_and_synced1));
- RunLoopUntilIdle();
-
- // Prepare for the second call: it will return immediately and the expected
- // result is |YES|.
- bool called2 = false;
- Status status2;
- PagePredicateResult is_closed_and_synced2;
- storage_ptr->DelayIsSyncedCallback(storage_page_id, false);
- ledger_manager_->PageIsClosedAndSynced(
- storage_page_id, callback::Capture(callback::SetWhenCalled(&called2),
- &status2, &is_closed_and_synced2));
- RunLoopUntilIdle();
- EXPECT_FALSE(called1);
- EXPECT_TRUE(called2);
- EXPECT_EQ(Status::OK, status2);
- EXPECT_EQ(PagePredicateResult::YES, is_closed_and_synced2);
-
- // Open and close the page.
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- page.Unbind();
- RunLoopUntilIdle();
-
- // Call the callback and let the first call to PageIsClosedAndSynced
- // terminate. The expected returned result is |PAGE_OPENED|.
- storage_ptr->CallIsSyncedCallback(storage_page_id);
- EXPECT_TRUE(called1);
- EXPECT_EQ(Status::OK, status1);
- EXPECT_EQ(PagePredicateResult::PAGE_OPENED, is_closed_and_synced1);
-}
-
-TEST_F(LedgerManagerTest, PageIsClosedOfflineAndEmptyCheckNotFound) {
- bool called;
- Status status;
- PagePredicateResult is_closed_offline_empty;
-
- PageId id = RandomId();
-
- // Check for a page that doesn't exist.
- storage_ptr->should_get_page_fail = true;
- ledger_manager_->PageIsClosedOfflineAndEmpty(
- id.id, callback::Capture(callback::SetWhenCalled(&called), &status,
- &is_closed_offline_empty));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PAGE_NOT_FOUND, status);
-}
-
-TEST_F(LedgerManagerTest, PageIsClosedOfflineAndEmptyCheckClosed) {
- bool called;
- Status status;
- PagePredicateResult is_closed_offline_empty;
-
- storage_ptr->should_get_page_fail = false;
- PagePtr page;
- PageId id = RandomId();
- storage::PageIdView storage_page_id = convert::ExtendedStringView(id.id);
-
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- storage_ptr->set_page_storage_offline_empty(storage_page_id, true);
- ledger_manager_->PageIsClosedOfflineAndEmpty(
- storage_page_id, callback::Capture(callback::SetWhenCalled(&called),
- &status, &is_closed_offline_empty));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(PagePredicateResult::PAGE_OPENED, is_closed_offline_empty);
-
- // Close the page. PagePredicateResult should now be true.
- page.Unbind();
- RunLoopUntilIdle();
-
- ledger_manager_->PageIsClosedOfflineAndEmpty(
- storage_page_id, callback::Capture(callback::SetWhenCalled(&called),
- &status, &is_closed_offline_empty));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(PagePredicateResult::YES, is_closed_offline_empty);
-}
-
-TEST_F(LedgerManagerTest, PageIsClosedOfflineAndEmptyCanDeletePageOnCallback) {
- bool page_is_empty_called = false;
- Status page_is_empty_status;
- PagePredicateResult is_closed_offline_empty;
- bool delete_page_called = false;
- Status delete_page_status;
- PageId id = RandomId();
-
- // The page is closed, offline and empty. Try to delete the page storage in
- // the callback.
- storage_ptr->set_page_storage_offline_empty(id.id, true);
- ledger_manager_->PageIsClosedOfflineAndEmpty(
- id.id, [&](Status status, PagePredicateResult result) {
- page_is_empty_called = true;
- page_is_empty_status = status;
- is_closed_offline_empty = result;
-
- ledger_manager_->DeletePageStorage(
- id.id,
- callback::Capture(callback::SetWhenCalled(&delete_page_called),
- &delete_page_status));
- });
- RunLoopUntilIdle();
- // Make sure the deletion finishes successfully.
- ASSERT_NE(nullptr, storage_ptr->delete_page_storage_callback);
- storage_ptr->delete_page_storage_callback(storage::Status::OK);
-
- EXPECT_TRUE(page_is_empty_called);
- EXPECT_EQ(Status::OK, page_is_empty_status);
- EXPECT_EQ(PagePredicateResult::YES, is_closed_offline_empty);
-
- EXPECT_TRUE(delete_page_called);
- EXPECT_EQ(Status::OK, delete_page_status);
-}
-
-// Verifies that two successive calls to GetPage do not create 2 storages.
-TEST_F(LedgerManagerTest, CallGetPageTwice) {
- PageId id = RandomId();
-
- uint8_t calls = 0;
- PagePtr page1;
- ledger_->GetPage(fidl::MakeOptional(id), page1.NewRequest(),
- [&calls](Status) { calls++; });
- PagePtr page2;
- ledger_->GetPage(fidl::MakeOptional(id), page2.NewRequest(),
- [&calls](Status) { calls++; });
- RunLoopUntilIdle();
- EXPECT_EQ(2u, calls);
- EXPECT_EQ(0u, storage_ptr->create_page_calls.size());
- ASSERT_EQ(1u, storage_ptr->get_page_calls.size());
- EXPECT_EQ(convert::ToString(id.id), storage_ptr->get_page_calls[0]);
-}
-
-// Cloud should never be queried.
-TEST_F(LedgerManagerTest, GetPageDoNotCallTheCloud) {
- storage_ptr->should_get_page_fail = true;
- Status status;
-
- PagePtr page;
- PageId id = RandomId();
- bool called;
- // Get the root page.
- storage_ptr->ClearCalls();
- ledger_->GetRootPage(
- page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::INTERNAL_ERROR, status);
- EXPECT_FALSE(sync_ptr->called);
-
- // Get a new page with a random id.
- storage_ptr->ClearCalls();
- page.Unbind();
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::INTERNAL_ERROR, status);
- EXPECT_FALSE(sync_ptr->called);
-
- // Create a new page.
- storage_ptr->ClearCalls();
- page.Unbind();
- ledger_->GetPage(
- nullptr, page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::INTERNAL_ERROR, status);
- EXPECT_FALSE(sync_ptr->called);
-}
-
-// Verifies that LedgerDebugImpl proxy vended by LedgerManager works correctly.
-TEST_F(LedgerManagerTest, CallGetPagesList) {
- std::vector<PagePtr> pages(3);
- std::vector<PageId> ids;
-
- for (size_t i = 0; i < pages.size(); ++i) {
- ids.push_back(RandomId());
- }
-
- Status status;
-
- std::vector<PageId> actual_pages_list;
-
- EXPECT_EQ(0u, actual_pages_list.size());
-
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- for (size_t i = 0; i < pages.size(); ++i) {
- ledger_->GetPage(fidl::MakeOptional(ids[i]), pages[i].NewRequest(),
- waiter->NewCallback());
- }
-
- bool called;
- waiter->Finalize(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- ledger_debug_->GetPagesList(
- callback::Capture(callback::SetWhenCalled(&called), &actual_pages_list));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(pages.size(), actual_pages_list.size());
-
- std::sort(ids.begin(), ids.end(), [](const PageId& lhs, const PageId& rhs) {
- return convert::ToStringView(lhs.id) < convert::ToStringView(rhs.id);
- });
- for (size_t i = 0; i < ids.size(); i++)
- EXPECT_EQ(ids[i].id, actual_pages_list.at(i).id);
-}
-
-TEST_F(LedgerManagerTest, OnPageOpenedClosedCalls) {
- PagePtr page1;
- PagePtr page2;
- PageId id = RandomId();
-
- EXPECT_EQ(0, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_unused_count);
-
- // Open a page and check that OnPageOpened was called once.
- bool called;
- Status status;
- ledger_->GetPage(
- fidl::MakeOptional(id), page1.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_unused_count);
-
- // Open the page again and check that there is no new call to OnPageOpened.
- ledger_->GetPage(
- fidl::MakeOptional(id), page2.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_unused_count);
-
- // Close one of the two connections and check that there is still no call to
- // OnPageClosed.
- page1.Unbind();
- RunLoopUntilIdle();
- EXPECT_EQ(1, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_unused_count);
-
- // Close the second connection and check that OnPageClosed was called once.
- page2.Unbind();
- RunLoopUntilIdle();
- EXPECT_EQ(1, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_unused_count);
-}
-
-TEST_F(LedgerManagerTest, OnPageOpenedClosedCallInternalRequest) {
- PagePtr page;
- PageId id = RandomId();
-
- EXPECT_EQ(0, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_unused_count);
-
- // Make an internal request by calling PageIsClosedAndSynced. No calls to page
- // opened/closed should be made.
- bool called;
- Status status;
- PagePredicateResult page_state;
- ledger_manager_->PageIsClosedAndSynced(
- convert::ToString(id.id),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &page_state));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(PagePredicateResult::NO, page_state);
- EXPECT_EQ(0, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_unused_count);
-
- // Open the same page with an external request and check that OnPageOpened
- // was called once.
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_unused_count);
-}
-
-TEST_F(LedgerManagerTest, OnPageOpenedClosedUnused) {
- PagePtr page;
- PageId id = RandomId();
- storage::PageIdView storage_page_id = convert::ExtendedStringView(id.id);
-
- Status status;
- bool called = false;
-
- EXPECT_EQ(0, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(0, disk_cleanup_manager_->page_unused_count);
-
- // Open and close the page through an external request.
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- // Mark the page as synced and close it.
- storage_ptr->set_page_storage_synced(storage_page_id, true);
- page.Unbind();
- RunLoopUntilIdle();
- EXPECT_EQ(1, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_unused_count);
-
- // Start an internal request but don't let it terminate. Nothing should have
- // changed in the notifications received.
- PagePredicateResult is_synced;
- bool page_is_synced_called = false;
- storage_ptr->DelayIsSyncedCallback(storage_page_id, true);
- ledger_manager_->PageIsClosedAndSynced(
- storage_page_id,
- callback::Capture(callback::SetWhenCalled(&page_is_synced_called),
- &status, &is_synced));
- RunLoopUntilIdle();
- EXPECT_FALSE(page_is_synced_called);
- EXPECT_EQ(1, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_unused_count);
-
- // Open the same page with an external request and check that OnPageOpened
- // was called once.
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(2, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_unused_count);
-
- // Close the page. We should get the page closed notification, but not the
- // unused one: the internal request is still running.
- page.Unbind();
- RunLoopUntilIdle();
- EXPECT_EQ(2, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(2, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(1, disk_cleanup_manager_->page_unused_count);
-
- // Terminate the internal request. We should now see the unused page
- // notification.
- storage_ptr->CallIsSyncedCallback(storage_page_id);
- EXPECT_EQ(2, disk_cleanup_manager_->page_opened_count);
- EXPECT_EQ(2, disk_cleanup_manager_->page_closed_count);
- EXPECT_EQ(2, disk_cleanup_manager_->page_unused_count);
-}
-
-TEST_F(LedgerManagerTest, DeletePageStorageWhenPageOpenFails) {
- PagePtr page;
- PageId id = RandomId();
- bool called;
- Status status;
-
- ledger_->GetPage(
- fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- // Try to delete the page while it is open. Expect to get an error.
- ledger_manager_->DeletePageStorage(
- id.id, callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::ILLEGAL_STATE, status);
-}
-
-TEST_F(LedgerManagerTest, OpenPageWithDeletePageStorageInProgress) {
- PagePtr page;
- PageId id = RandomId();
-
- // Start deleting the page.
- bool delete_called;
- Status delete_status;
- ledger_manager_->DeletePageStorage(
- id.id, callback::Capture(callback::SetWhenCalled(&delete_called),
- &delete_status));
- RunLoopUntilIdle();
- EXPECT_FALSE(delete_called);
-
- // Try to open the same page.
- bool get_page_called;
- Status get_page_status;
- ledger_->GetPage(fidl::MakeOptional(id), page.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&get_page_called),
- &get_page_status));
- RunLoopUntilIdle();
- EXPECT_FALSE(get_page_called);
-
- // After calling the callback registered in |DeletePageStorage| both
- // operations should terminate without an error.
- storage_ptr->delete_page_storage_callback(storage::Status::OK);
-
- RunLoopUntilIdle();
- EXPECT_TRUE(delete_called);
- EXPECT_EQ(Status::OK, delete_status);
-
- EXPECT_TRUE(get_page_called);
- EXPECT_EQ(Status::OK, get_page_status);
-}
-
-TEST_F(LedgerManagerTest, ChangeConflictResolver) {
- fidl::InterfaceHandle<ConflictResolverFactory> handle1;
- fidl::InterfaceHandle<ConflictResolverFactory> handle2;
- StubConflictResolverFactory factory1(handle1.NewRequest());
- StubConflictResolverFactory factory2(handle2.NewRequest());
- Status status;
- bool called;
-
- ledger_->SetConflictResolverFactory(
- std::move(handle1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(status, Status::OK);
-
- ledger_->SetConflictResolverFactory(
- std::move(handle2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(status, Status::OK);
- EXPECT_FALSE(factory1.disconnected);
- EXPECT_FALSE(factory2.disconnected);
-}
-
-TEST_F(LedgerManagerTest, MultipleConflictResolvers) {
- fidl::InterfaceHandle<ConflictResolverFactory> handle1;
- fidl::InterfaceHandle<ConflictResolverFactory> handle2;
- StubConflictResolverFactory factory1(handle1.NewRequest());
- StubConflictResolverFactory factory2(handle2.NewRequest());
- Status status;
- bool called;
-
- LedgerPtr ledger2;
- ledger_manager_->BindLedger(ledger2.NewRequest());
-
- ledger_->SetConflictResolverFactory(
- std::move(handle1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(status, Status::OK);
-
- ledger2->SetConflictResolverFactory(
- std::move(handle2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(status, Status::OK);
- EXPECT_FALSE(factory1.disconnected);
- EXPECT_FALSE(factory2.disconnected);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/ledger_repository_factory_impl.cc b/bin/ledger/app/ledger_repository_factory_impl.cc
deleted file mode 100644
index 5682137..0000000
--- a/bin/ledger/app/ledger_repository_factory_impl.cc
+++ /dev/null
@@ -1,421 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/ledger_repository_factory_impl.h"
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/component/cpp/expose.h>
-#include <lib/component/cpp/object_dir.h>
-#include <lib/fdio/util.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/io/fd.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/eintr_wrapper.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/path.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/strings/concatenate.h>
-#include <lib/fxl/strings/string_view.h>
-#include <trace/event.h>
-#include <zircon/processargs.h>
-#include <zircon/syscalls.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/disk_cleanup_manager_impl.h"
-#include "peridot/bin/ledger/app/serialization_version.h"
-#include "peridot/bin/ledger/cloud_sync/impl/user_sync_impl.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/p2p_provider/impl/p2p_provider_impl.h"
-#include "peridot/bin/ledger/p2p_provider/impl/static_user_id_provider.h"
-#include "peridot/bin/ledger/p2p_sync/impl/user_communicator_impl.h"
-#include "peridot/bin/ledger/storage/impl/leveldb_factory.h"
-#include "peridot/bin/ledger/sync_coordinator/impl/user_sync_impl.h"
-
-namespace ledger {
-
-namespace {
-
-// The contents of each repository are organized in the following way:
-// <base_path>
-// ├── <serialization_version>
-// │ ├── name
-// │ ├── cache/
-// │ ├── page_usage_db/
-// │ └── ledgers
-// │ └── ...
-// └── staging/
-//
-// - <base_path>/
-// The base path of this repository. It is defined by the channel given in
-// |LedgerRepositoryFactory::GetRepository| (see the internal.fidl API).
-// - <base_path>/<serialization_version>/
-// Stores all the contents of this repository for that serialization
-// version. It is used to store the `name` file, and subdirectories `cache/`,
-// `page_usage_db/` and `ledgers/` (see below).
-// - <base_path>/<serialization_version>/name
-// Stores the name of the repository, which is randomly chosen on creation.
-// - <base_path>/<serialization_version>/cache/
-// The path used by |LevelDbFactory| as the cache directory.
-// - <base_path>/<serialization_version>/page_usage_db/
-// The path used by |DiskCleanupManagerImpl| to store statistics on pages.
-// - <base_path>/<serialization_version>/ledgers/
-// The path used by |LedgerRepositoryImpl| to store all Ledger instances for
-// this repository.
-// - <base_path>/staging/
-// The staging path. Used for removing all contents of this repository.
-//
-// Note that content/ should be the only directory storing information on the
-// repository: When deleting a repository, the content/ directory is moved
-// atomically to the staging path and then contents are recursively deleted.
-// This two-phase deletion guarantees that the repository will be in a correct
-// state even if the deletion execution is unexpectedly terminated.
-
-constexpr fxl::StringView kCachePath = "cache";
-constexpr fxl::StringView kPageUsageDbPath = "page_usage_db";
-constexpr fxl::StringView kLedgersPath = "ledgers";
-constexpr fxl::StringView kStagingPath = "staging";
-constexpr fxl::StringView kNamePath = "name";
-
-bool GetRepositoryName(rng::Random* random, const DetachedPath& content_path,
- std::string* name) {
- DetachedPath name_path = content_path.SubPath(kNamePath);
-
- if (files::ReadFileToStringAt(name_path.root_fd(), name_path.path(), name)) {
- return true;
- }
-
- if (!files::CreateDirectoryAt(content_path.root_fd(), content_path.path())) {
- return false;
- }
-
- std::string new_name;
- new_name.resize(16);
- random->Draw(&new_name);
- if (!files::WriteFileAt(name_path.root_fd(), name_path.path(),
- new_name.c_str(), new_name.size())) {
- FXL_LOG(ERROR) << "Unable to write file at: " << name_path.path();
- return false;
- }
-
- name->swap(new_name);
- return true;
-}
-
-} // namespace
-
-// Container for a LedgerRepositoryImpl that keeps track of the in-flight FIDL
-// requests and callbacks and fires them when the repository is available.
-class LedgerRepositoryFactoryImpl::LedgerRepositoryContainer {
- public:
- explicit LedgerRepositoryContainer(fxl::UniqueFD root_fd)
- : root_fd_(std::move(root_fd)) {}
- ~LedgerRepositoryContainer() {
- for (const auto& request : requests_) {
- request.second(Status::INTERNAL_ERROR);
- }
- }
-
- void set_on_empty(fit::closure on_empty_callback) {
- if (ledger_repository_) {
- ledger_repository_->set_on_empty(std::move(on_empty_callback));
- } else {
- on_empty_callback_ = std::move(on_empty_callback);
- }
- };
-
- // Forwards to the Inspect method of the wrapped LedgerRepositoryImpl, if the
- // wrapped LedgerRepositoryImpl is present. Otherwise does nothing.
- void Inspect(std::string display_name,
- component::Object::ObjectVector* out) const {
- if (ledger_repository_) {
- ledger_repository_->Inspect(std::move(display_name), out);
- }
- }
-
- // Keeps track of |request| and |callback|. Binds |request| and fires
- // |callback| when the repository is available or an error occurs.
- void BindRepository(
- fidl::InterfaceRequest<ledger_internal::LedgerRepository> request,
- fit::function<void(Status)> callback) {
- if (status_ != Status::OK) {
- callback(status_);
- return;
- }
- if (ledger_repository_) {
- ledger_repository_->BindRepository(std::move(request));
- callback(status_);
- return;
- }
- requests_.emplace_back(std::move(request), std::move(callback));
- }
-
- // Sets the implementation or the error status for the container. This
- // notifies all awaiting callbacks and binds all pages in case of success.
- void SetRepository(Status status,
- std::unique_ptr<LedgerRepositoryImpl> ledger_repository) {
- FXL_DCHECK(!ledger_repository_);
- FXL_DCHECK(status != Status::OK || ledger_repository);
- status_ = status;
- ledger_repository_ = std::move(ledger_repository);
- for (auto& request : requests_) {
- if (ledger_repository_) {
- ledger_repository_->BindRepository(std::move(request.first));
- }
- request.second(status_);
- }
- requests_.clear();
- if (on_empty_callback_) {
- if (ledger_repository_) {
- ledger_repository_->set_on_empty(std::move(on_empty_callback_));
- } else {
- on_empty_callback_();
- }
- }
- }
-
- // Shuts down the repository impl (if already initialized) and detaches all
- // handles bound to it, moving their owneship to the container.
- void Detach() {
- if (ledger_repository_) {
- detached_handles_ = ledger_repository_->Unbind();
- ledger_repository_.reset();
- }
- for (auto& request : requests_) {
- detached_handles_.push_back(std::move(request.first));
- }
-
- // TODO(ppi): rather than failing all already pending and future requests,
- // we should stash them and fulfill them once the deletion is finished.
- status_ = Status::INTERNAL_ERROR;
- }
-
- private:
- fxl::UniqueFD root_fd_;
- std::unique_ptr<LedgerRepositoryImpl> ledger_repository_;
- Status status_ = Status::OK;
- std::vector<
- std::pair<fidl::InterfaceRequest<ledger_internal::LedgerRepository>,
- fit::function<void(Status)>>>
- requests_;
- fit::closure on_empty_callback_;
- std::vector<fidl::InterfaceRequest<ledger_internal::LedgerRepository>>
- detached_handles_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerRepositoryContainer);
-};
-
-struct LedgerRepositoryFactoryImpl::RepositoryInformation {
- public:
- explicit RepositoryInformation(int root_fd, std::string user_id)
- : base_path(root_fd),
- content_path(base_path.SubPath(kSerializationVersion)),
- cache_path(content_path.SubPath(kCachePath)),
- page_usage_db_path(content_path.SubPath(kPageUsageDbPath)),
- ledgers_path(content_path.SubPath(kLedgersPath)),
- staging_path(base_path.SubPath(kStagingPath)),
- user_id(std::move(user_id)) {}
-
- RepositoryInformation(const RepositoryInformation& other) = default;
- RepositoryInformation(RepositoryInformation&& other) = default;
-
- bool Init(rng::Random* random) {
- return GetRepositoryName(random, content_path, &name);
- }
-
- DetachedPath base_path;
- DetachedPath content_path;
- DetachedPath cache_path;
- DetachedPath page_usage_db_path;
- DetachedPath ledgers_path;
- DetachedPath staging_path;
- std::string user_id;
- std::string name;
-};
-
-LedgerRepositoryFactoryImpl::LedgerRepositoryFactoryImpl(
- Environment* environment,
- std::unique_ptr<p2p_sync::UserCommunicatorFactory>
- user_communicator_factory,
- component::ObjectDir inspect_object_dir)
- : environment_(environment),
- user_communicator_factory_(std::move(user_communicator_factory)),
- inspect_object_dir_(std::move(inspect_object_dir)) {}
-
-LedgerRepositoryFactoryImpl::~LedgerRepositoryFactoryImpl() {}
-
-void LedgerRepositoryFactoryImpl::GetChildren(
- component::Object::ObjectVector* out) {
- for (const auto& [name, container] : repositories_) {
- container.Inspect(convert::ToHex(name), out);
- }
-}
-
-void LedgerRepositoryFactoryImpl::GetRepository(
- zx::channel repository_handle,
- fidl::InterfaceHandle<cloud_provider::CloudProvider> cloud_provider,
- std::string user_id,
- fidl::InterfaceRequest<ledger_internal::LedgerRepository>
- repository_request,
- fit::function<void(Status)> callback) {
- fxl::UniqueFD root_fd =
- fsl::OpenChannelAsFileDescriptor(std::move(repository_handle));
- if (!root_fd.is_valid()) {
- callback(Status::IO_ERROR);
- return;
- }
- GetRepositoryByFD(std::move(root_fd), std::move(cloud_provider), user_id,
- std::move(repository_request), std::move(callback));
-}
-
-void LedgerRepositoryFactoryImpl::GetRepositoryByFD(
- fxl::UniqueFD root_fd,
- fidl::InterfaceHandle<cloud_provider::CloudProvider> cloud_provider,
- std::string user_id,
- fidl::InterfaceRequest<ledger_internal::LedgerRepository>
- repository_request,
- fit::function<void(Status)> callback) {
- TRACE_DURATION("ledger", "repository_factory_get_repository");
-
- RepositoryInformation repository_information(root_fd.get(),
- std::move(user_id));
- if (!repository_information.Init(environment_->random())) {
- callback(Status::IO_ERROR);
- return;
- }
-
- auto it = repositories_.find(repository_information.name);
- if (it != repositories_.end()) {
- it->second.BindRepository(std::move(repository_request),
- std::move(callback));
- return;
- }
-
- auto ret =
- repositories_.emplace(std::piecewise_construct,
- std::forward_as_tuple(repository_information.name),
- std::forward_as_tuple(std::move(root_fd)));
- LedgerRepositoryContainer* container = &ret.first->second;
- container->BindRepository(std::move(repository_request), std::move(callback));
-
- auto db_factory = std::make_unique<storage::LevelDbFactory>(
- environment_, repository_information.cache_path);
- db_factory->Init();
- auto disk_cleanup_manager = std::make_unique<DiskCleanupManagerImpl>(
- environment_, db_factory.get(),
- repository_information.page_usage_db_path);
- Status status = disk_cleanup_manager->Init();
- if (status != Status::OK) {
- container->SetRepository(status, nullptr);
- return;
- }
-
- std::unique_ptr<SyncWatcherSet> watchers = std::make_unique<SyncWatcherSet>();
- std::unique_ptr<sync_coordinator::UserSyncImpl> user_sync;
- if (cloud_provider) {
- user_sync = CreateUserSync(repository_information,
- std::move(cloud_provider), watchers.get());
- } else {
- FXL_LOG(WARNING) << "No cloud provider - Ledger will work locally but "
- << "not sync. (running in Guest mode?)";
- }
-
- DiskCleanupManagerImpl* disk_cleanup_manager_ptr = disk_cleanup_manager.get();
- auto repository = std::make_unique<LedgerRepositoryImpl>(
- repository_information.ledgers_path, environment_, std::move(db_factory),
- std::move(watchers), std::move(user_sync),
- std::move(disk_cleanup_manager), disk_cleanup_manager_ptr);
- disk_cleanup_manager_ptr->SetPageEvictionDelegate(repository.get());
- container->SetRepository(Status::OK, std::move(repository));
-}
-
-std::unique_ptr<sync_coordinator::UserSyncImpl>
-LedgerRepositoryFactoryImpl::CreateUserSync(
- const RepositoryInformation& repository_information,
- fidl::InterfaceHandle<cloud_provider::CloudProvider> cloud_provider,
- SyncWatcherSet* watchers) {
- auto cloud_provider_ptr = cloud_provider.Bind();
- cloud_provider_ptr.set_error_handler([](zx_status_t status) {
- FXL_LOG(ERROR)
- << "Lost connection to cloud provider; cloud sync will no longer work.";
- });
-
- cloud_sync::UserConfig user_config;
- user_config.user_directory = repository_information.content_path;
- user_config.cloud_provider = std::move(cloud_provider_ptr);
- fit::closure on_version_mismatch = [this, repository_information]() mutable {
- OnVersionMismatch(repository_information);
- };
- auto cloud_sync = std::make_unique<cloud_sync::UserSyncImpl>(
- environment_, std::move(user_config), environment_->MakeBackoff(),
- std::move(on_version_mismatch));
- std::unique_ptr<p2p_sync::UserCommunicator> p2p_sync =
- CreateP2PSync(repository_information);
-
- auto user_sync = std::make_unique<sync_coordinator::UserSyncImpl>(
- std::move(cloud_sync), std::move(p2p_sync));
- user_sync->SetWatcher(watchers);
- user_sync->Start();
- return user_sync;
-}
-
-std::unique_ptr<p2p_sync::UserCommunicator>
-LedgerRepositoryFactoryImpl::CreateP2PSync(
- const RepositoryInformation& repository_information) {
- if (!user_communicator_factory_) {
- return nullptr;
- }
-
- if (repository_information.user_id.empty()) {
- return nullptr;
- }
-
- auto user_id_provider = std::make_unique<p2p_provider::StaticUserIdProvider>(
- repository_information.user_id);
-
- return user_communicator_factory_->GetUserCommunicator(
- std::move(user_id_provider));
-}
-
-void LedgerRepositoryFactoryImpl::OnVersionMismatch(
- RepositoryInformation repository_information) {
- FXL_LOG(WARNING)
- << "Data in the cloud was wiped out, erasing local state. "
- << "This should log you out, log back in to start syncing again.";
-
- // First, shut down the repository so that we can delete the files while it's
- // not running.
- auto find_repository = repositories_.find(repository_information.name);
- FXL_DCHECK(find_repository != repositories_.end());
- find_repository->second.Detach();
- DeleteRepositoryDirectory(repository_information);
- repositories_.erase(find_repository);
-}
-
-Status LedgerRepositoryFactoryImpl::DeleteRepositoryDirectory(
- const RepositoryInformation& repository_information) {
- files::ScopedTempDirAt tmp_directory(
- repository_information.staging_path.root_fd(),
- repository_information.staging_path.path());
- std::string destination = tmp_directory.path() + "/content";
-
- if (renameat(repository_information.content_path.root_fd(),
- repository_information.content_path.path().c_str(),
- tmp_directory.root_fd(), destination.c_str()) != 0) {
- FXL_LOG(ERROR) << "Unable to move repository local storage to "
- << destination << ". Error: " << strerror(errno);
- return Status::IO_ERROR;
- }
- if (!files::DeletePathAt(tmp_directory.root_fd(), destination, true)) {
- FXL_LOG(ERROR) << "Unable to delete repository staging storage at "
- << destination;
- return Status::IO_ERROR;
- }
- return Status::OK;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/ledger_repository_factory_impl.h b/bin/ledger/app/ledger_repository_factory_impl.h
deleted file mode 100644
index 631d50e..0000000
--- a/bin/ledger/app/ledger_repository_factory_impl.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_LEDGER_REPOSITORY_FACTORY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_APP_LEDGER_REPOSITORY_FACTORY_IMPL_H_
-
-#include <memory>
-#include <string>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <fuchsia/netconnector/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/callback/cancellable.h>
-#include <lib/callback/managed_container.h>
-#include <lib/component/cpp/expose.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/app/disk_cleanup_manager_impl.h"
-#include "peridot/bin/ledger/app/ledger_repository_impl.h"
-#include "peridot/bin/ledger/cloud_sync/public/user_config.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/fidl/error_notifier.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/p2p_sync/public/user_communicator_factory.h"
-#include "peridot/bin/ledger/sync_coordinator/impl/user_sync_impl.h"
-
-namespace ledger {
-
-class LedgerRepositoryFactoryImpl
- : public ::fuchsia::ledger::internal::
- LedgerRepositoryFactoryErrorNotifierDelegate {
- public:
- explicit LedgerRepositoryFactoryImpl(
- Environment* environment,
- std::unique_ptr<p2p_sync::UserCommunicatorFactory>
- user_communicator_factory,
- component::ObjectDir inspect_object_dir);
- ~LedgerRepositoryFactoryImpl() override;
-
- // Populates |out| with children to be traversed (or not) during an
- // inspection.
- void GetChildren(component::Object::ObjectVector* out);
-
- // LedgerRepositoryFactoryErrorNotifierDelegate:
- void GetRepository(
- zx::channel repository_handle,
- fidl::InterfaceHandle<cloud_provider::CloudProvider> cloud_provider,
- std::string user_id,
- fidl::InterfaceRequest<ledger_internal::LedgerRepository>
- repository_request,
- fit::function<void(Status)> callback) override;
-
- private:
- class LedgerRepositoryContainer;
- struct RepositoryInformation;
-
- // Binds |repository_request| to the repository stored in the directory opened
- // in |root_fd|.
- void GetRepositoryByFD(
- fxl::UniqueFD root_fd,
- fidl::InterfaceHandle<cloud_provider::CloudProvider> cloud_provider,
- std::string user_id,
- fidl::InterfaceRequest<ledger_internal::LedgerRepository>
- repository_request,
- fit::function<void(Status)> callback);
- std::unique_ptr<sync_coordinator::UserSyncImpl> CreateUserSync(
- const RepositoryInformation& repository_information,
- fidl::InterfaceHandle<cloud_provider::CloudProvider> cloud_provider,
- SyncWatcherSet* watchers);
- std::unique_ptr<p2p_sync::UserCommunicator> CreateP2PSync(
- const RepositoryInformation& repository_information);
- void OnVersionMismatch(RepositoryInformation repository_information);
-
- Status DeleteRepositoryDirectory(
- const RepositoryInformation& repository_information);
-
- Environment* const environment_;
- std::unique_ptr<p2p_sync::UserCommunicatorFactory> const
- user_communicator_factory_;
-
- callback::AutoCleanableMap<std::string, LedgerRepositoryContainer>
- repositories_;
-
- component::ObjectDir inspect_object_dir_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerRepositoryFactoryImpl);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_LEDGER_REPOSITORY_FACTORY_IMPL_H_
diff --git a/bin/ledger/app/ledger_repository_factory_impl_unittest.cc b/bin/ledger/app/ledger_repository_factory_impl_unittest.cc
deleted file mode 100644
index af543c6..0000000
--- a/bin/ledger/app/ledger_repository_factory_impl_unittest.cc
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/ledger_repository_factory_impl.h"
-
-#include <fuchsia/inspect/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fsl/io/fd.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/testing/inspect.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-using ::testing::Not;
-using ::testing::SizeIs;
-using ::testing::UnorderedElementsAre;
-
-constexpr fxl::StringView kObjectsName = "test objects";
-constexpr fxl::StringView kUserID = "test user ID";
-
-class LedgerRepositoryFactoryImplTest : public TestWithEnvironment {
- public:
- LedgerRepositoryFactoryImplTest() {
- object_dir_ =
- component::ObjectDir::Make({kObjectsName.data(), kObjectsName.size()});
- repository_factory_ = std::make_unique<LedgerRepositoryFactoryImpl>(
- &environment_, nullptr, object_dir_);
- object_dir_.set_children_callback(
- {kRepositoriesInspectPathComponent},
- [this](component::Object::ObjectVector* out) {
- repository_factory_->GetChildren(out);
- });
- }
-
- ~LedgerRepositoryFactoryImplTest() override {
- object_dir_.set_children_callback({kRepositoriesInspectPathComponent},
- nullptr);
- }
-
- protected:
- ::testing::AssertionResult CreateDirectory(std::string name);
- ::testing::AssertionResult CallGetRepository(
- std::string name,
- ledger_internal::LedgerRepositoryPtr* ledger_repository_ptr);
- ::testing::AssertionResult ReadTopLevelData(fuchsia::inspect::Object* object);
- ::testing::AssertionResult ListTopLevelChildren(
- std::vector<std::string>* children);
- ::testing::AssertionResult OpenTopLevelRepositoriesChild(
- fuchsia::inspect::InspectPtr* repositories_inspect_ptr);
- ::testing::AssertionResult ReadData(fuchsia::inspect::InspectPtr* inspect_ptr,
- fuchsia::inspect::Object* object);
- ::testing::AssertionResult ListChildren(
- fuchsia::inspect::InspectPtr* inspect_ptr,
- std::vector<std::string>* children_names);
- ::testing::AssertionResult OpenChild(
- fuchsia::inspect::InspectPtr* parent_inspect_ptr,
- std::string child_name,
- fuchsia::inspect::InspectPtr* child_inspect_ptr);
-
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- component::ObjectDir object_dir_;
- std::unique_ptr<LedgerRepositoryFactoryImpl> repository_factory_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerRepositoryFactoryImplTest);
-};
-
-::testing::AssertionResult LedgerRepositoryFactoryImplTest::CreateDirectory(
- std::string name) {
- if (!files::CreateDirectoryAt(tmpfs_.root_fd(), name)) {
- return ::testing::AssertionFailure()
- << "Failed to create directory \"" << name << "\"!";
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult LedgerRepositoryFactoryImplTest::CallGetRepository(
- std::string name,
- ledger_internal::LedgerRepositoryPtr* ledger_repository_ptr) {
- fxl::UniqueFD fd(openat(tmpfs_.root_fd(), name.c_str(), O_PATH));
- if (!fd.is_valid()) {
- return ::testing::AssertionFailure()
- << "Failed to validate directory \"" << name << "\"!";
- }
-
- bool callback_called;
- Status status = Status::UNKNOWN_ERROR;
-
- repository_factory_->GetRepository(
- fsl::CloneChannelFromFileDescriptor(fd.get()), nullptr,
- kUserID.ToString(), ledger_repository_ptr->NewRequest(),
- callback::Capture(callback::SetWhenCalled(&callback_called), &status));
-
- if (!callback_called) {
- return ::testing::AssertionFailure()
- << "Callback passed to GetRepository not called!";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure() << "Status of GetRepository call was "
- << static_cast<int32_t>(status) << "!";
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult LedgerRepositoryFactoryImplTest::ReadTopLevelData(
- fuchsia::inspect::Object* object) {
- bool callback_called;
-
- object_dir_.object()->ReadData(
- callback::Capture(callback::SetWhenCalled(&callback_called), object));
- RunLoopUntilIdle();
-
- if (!callback_called) {
- return ::testing::AssertionFailure()
- << "Callback passed to object_dir_.object()->ReadData not called!";
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult
-LedgerRepositoryFactoryImplTest::ListTopLevelChildren(
- std::vector<std::string>* children) {
- bool callback_called;
-
- object_dir_.object()->ListChildren(
- callback::Capture(callback::SetWhenCalled(&callback_called), children));
- RunLoopUntilIdle();
-
- if (!callback_called) {
- return ::testing::AssertionFailure()
- << "Callback passed to object_dir_.object()->ListChildren not "
- "called!";
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult
-LedgerRepositoryFactoryImplTest::OpenTopLevelRepositoriesChild(
- fuchsia::inspect::InspectPtr* repositories_inspect_ptr) {
- bool callback_called;
- bool success = false;
-
- object_dir_.object()->OpenChild(
- kRepositoriesInspectPathComponent, repositories_inspect_ptr->NewRequest(),
- callback::Capture(callback::SetWhenCalled(&callback_called), &success));
- RunLoopUntilIdle();
-
- if (!callback_called) {
- return ::testing::AssertionFailure()
- << "Callback passed to object_dir_.object()->OpenChild not called!";
- }
- if (!success) {
- return ::testing::AssertionFailure()
- << "object_dir_.object()->OpenChild call unsuccessful!";
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult LedgerRepositoryFactoryImplTest::ReadData(
- fuchsia::inspect::InspectPtr* inspect_ptr,
- fuchsia::inspect::Object* object) {
- bool callback_called;
-
- (*inspect_ptr)
- ->ReadData(
- callback::Capture(callback::SetWhenCalled(&callback_called), object));
- RunLoopUntilIdle();
-
- if (!callback_called) {
- return ::testing::AssertionFailure() << "ReadData callback not called!";
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult LedgerRepositoryFactoryImplTest::ListChildren(
- fuchsia::inspect::InspectPtr* inspect_ptr,
- std::vector<std::string>* children_names) {
- bool callback_called;
-
- (*inspect_ptr)
- ->ListChildren(callback::Capture(
- callback::SetWhenCalled(&callback_called), children_names));
- RunLoopUntilIdle();
-
- if (!callback_called) {
- return ::testing::AssertionFailure() << "ListChildren callback not called!";
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult LedgerRepositoryFactoryImplTest::OpenChild(
- fuchsia::inspect::InspectPtr* parent_inspect_ptr,
- std::string child_name,
- fuchsia::inspect::InspectPtr* child_inspect_ptr) {
- bool callback_called;
- bool success = false;
-
- (*parent_inspect_ptr)
- ->OpenChild(child_name, child_inspect_ptr->NewRequest(),
- callback::Capture(callback::SetWhenCalled(&callback_called),
- &success));
- RunLoopUntilIdle();
-
- if (!callback_called) {
- return ::testing::AssertionFailure() << "OpenChild callback not called!";
- }
- if (!success) {
- return ::testing::AssertionFailure() << "OpenChild call unsuccessful!";
- }
- return ::testing::AssertionSuccess();
-}
-
-TEST_F(LedgerRepositoryFactoryImplTest, InspectAPINoRepositories) {
- fuchsia::inspect::Object object;
- std::vector<std::string> children;
-
- ASSERT_TRUE(ReadTopLevelData(&object));
- ASSERT_TRUE(ListTopLevelChildren(&children));
-
- EXPECT_EQ(kObjectsName, object.name);
- EXPECT_THAT(*object.properties, IsEmpty());
- EXPECT_THAT(*object.metrics, IsEmpty());
- EXPECT_THAT(children, ElementsAre(kRepositoriesInspectPathComponent));
-}
-
-TEST_F(LedgerRepositoryFactoryImplTest,
- InspectAPITwoRepositoriesOneAccessedTwice) {
- // The directories in which the two repositories will be created.
- std::string first_directory = "first directory";
- std::string second_directory = "second directory";
-
- // The names of the two repositories, determined by the
- // LedgerRepositoryFactoryImpl under test.
- fidl::StringPtr first_repository_name;
- fidl::StringPtr second_repository_name;
-
- // Bindings to the two repositories. If these are not maintained, the
- // LedgerRepositoryFactoryImpl::LedgerRepositoryContainer objects associated
- // with the repositories will be destroyed and the repositories will no
- // longer appear represented in the Inspect API.
- ledger_internal::LedgerRepositoryPtr first_ledger_repository_ptr;
- ledger_internal::LedgerRepositoryPtr second_ledger_repository_ptr;
- ledger_internal::LedgerRepositoryPtr first_again_ledger_repository_ptr;
-
- // Bindings to Inspect API "Inspect" objects. Because the Ledger objects'
- // parent-child relationships are dynamically computed, these need to be
- // unbound and rebound for each inspection of the repositories.
- fuchsia::inspect::InspectPtr repositories_inspect_ptr;
- fuchsia::inspect::InspectPtr first_repository_inspect_ptr;
- fuchsia::inspect::InspectPtr second_repository_inspect_ptr;
-
- // Temporary objects populated and cleared throughout the test.
- fuchsia::inspect::Object object;
- std::vector<std::string> children_names;
-
- // Create the directories for the repositories.
- ASSERT_TRUE(CreateDirectory(first_directory));
- ASSERT_TRUE(CreateDirectory(second_directory));
-
- // Request one repository, then query the object_dir_ (and its children) to
- // verify that that repository is listed (and to learn the name under which
- // it is listed) and that it was requested once.
- ASSERT_TRUE(CallGetRepository(first_directory, &first_ledger_repository_ptr));
- ASSERT_TRUE(ListTopLevelChildren(&children_names));
- EXPECT_THAT(children_names, ElementsAre(kRepositoriesInspectPathComponent));
- ASSERT_TRUE(OpenTopLevelRepositoriesChild(&repositories_inspect_ptr));
- ASSERT_TRUE(ListChildren(&repositories_inspect_ptr, &children_names));
- EXPECT_THAT(children_names, SizeIs(1));
- first_repository_name = children_names.at(0);
- EXPECT_THAT(*first_repository_name, Not(IsEmpty()));
- ASSERT_TRUE(OpenChild(&repositories_inspect_ptr, first_repository_name,
- &first_repository_inspect_ptr));
- ASSERT_TRUE(ReadData(&first_repository_inspect_ptr, &object));
- EXPECT_EQ(first_repository_name, object.name);
- ExpectRequestsMetric(&object, 1UL);
-
- // Request a second repository, then query the "repositories" Inspect object
- // to verify that that second repository is listed in addition to the first
- // (and to learn the name under which it is listed) and that the two
- // repositories were each requested once.
- ASSERT_TRUE(
- CallGetRepository(second_directory, &second_ledger_repository_ptr));
- ASSERT_TRUE(ListTopLevelChildren(&children_names));
- EXPECT_THAT(children_names, ElementsAre(kRepositoriesInspectPathComponent));
- ASSERT_TRUE(OpenTopLevelRepositoriesChild(&repositories_inspect_ptr));
- ASSERT_TRUE(ListChildren(&repositories_inspect_ptr, &children_names));
- EXPECT_THAT(children_names, SizeIs(2));
- second_repository_name =
- *find_if_not(children_names.begin(), children_names.end(),
- [&first_repository_name](const auto& name) {
- return name == first_repository_name;
- });
- EXPECT_THAT(children_names, UnorderedElementsAre(first_repository_name,
- second_repository_name));
- EXPECT_THAT(*second_repository_name, Not(IsEmpty()));
- ASSERT_TRUE(OpenChild(&repositories_inspect_ptr, first_repository_name,
- &first_repository_inspect_ptr));
- ASSERT_TRUE(OpenChild(&repositories_inspect_ptr, second_repository_name,
- &second_repository_inspect_ptr));
- ASSERT_TRUE(ReadData(&first_repository_inspect_ptr, &object));
- EXPECT_EQ(first_repository_name, object.name);
- ExpectRequestsMetric(&object, 1UL);
- ASSERT_TRUE(ReadData(&second_repository_inspect_ptr, &object));
- EXPECT_EQ(second_repository_name, object.name);
- ExpectRequestsMetric(&object, 1UL);
-
- // Request the first repository a second time, then query the "repositories"
- // Inspect object to verify that both repositories remain listed (with their
- // same names) and are described as having been requested twice and once,
- // respectively.
- ASSERT_TRUE(
- CallGetRepository(first_directory, &first_again_ledger_repository_ptr));
- ASSERT_TRUE(ListTopLevelChildren(&children_names));
- EXPECT_THAT(children_names, ElementsAre(kRepositoriesInspectPathComponent));
- ASSERT_TRUE(OpenTopLevelRepositoriesChild(&repositories_inspect_ptr));
- ASSERT_TRUE(ListChildren(&repositories_inspect_ptr, &children_names));
- EXPECT_THAT(children_names, UnorderedElementsAre(first_repository_name,
- second_repository_name));
- ASSERT_TRUE(OpenChild(&repositories_inspect_ptr, first_repository_name,
- &first_repository_inspect_ptr));
- ASSERT_TRUE(OpenChild(&repositories_inspect_ptr, second_repository_name,
- &second_repository_inspect_ptr));
- ASSERT_TRUE(ReadData(&first_repository_inspect_ptr, &object));
- EXPECT_EQ(first_repository_name, object.name);
- ExpectRequestsMetric(&object, 2UL);
- ASSERT_TRUE(ReadData(&second_repository_inspect_ptr, &object));
- EXPECT_EQ(second_repository_name, object.name);
- ExpectRequestsMetric(&object, 1UL);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/ledger_repository_impl.cc b/bin/ledger/app/ledger_repository_impl.cc
deleted file mode 100644
index 3c95ba9..0000000
--- a/bin/ledger/app/ledger_repository_impl.cc
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/ledger_repository_impl.h"
-
-#include <lib/component/cpp/expose.h>
-#include <lib/component/cpp/object_dir.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/cloud_sync/impl/ledger_sync_impl.h"
-#include "peridot/bin/ledger/p2p_sync/public/ledger_communicator.h"
-#include "peridot/bin/ledger/storage/impl/ledger_storage_impl.h"
-#include "peridot/bin/ledger/sync_coordinator/public/ledger_sync.h"
-#include "peridot/lib/base64url/base64url.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-// Encodes opaque bytes in a way that is usable as a directory name.
-std::string GetDirectoryName(fxl::StringView bytes) {
- return base64url::Base64UrlEncode(bytes);
-}
-} // namespace
-
-LedgerRepositoryImpl::LedgerRepositoryImpl(
- DetachedPath content_path, Environment* environment,
- std::unique_ptr<storage::DbFactory> db_factory,
- std::unique_ptr<SyncWatcherSet> watchers,
- std::unique_ptr<sync_coordinator::UserSync> user_sync,
- std::unique_ptr<DiskCleanupManager> disk_cleanup_manager,
- PageUsageListener* page_usage_listener)
- : content_path_(std::move(content_path)),
- environment_(environment),
- db_factory_(std::move(db_factory)),
- encryption_service_factory_(environment),
- watchers_(std::move(watchers)),
- user_sync_(std::move(user_sync)),
- disk_cleanup_manager_(std::move(disk_cleanup_manager)),
- page_usage_listener_(page_usage_listener) {
- bindings_.set_on_empty([this] { CheckEmpty(); });
- ledger_managers_.set_on_empty([this] { CheckEmpty(); });
- ledger_repository_debug_bindings_.set_empty_set_handler(
- [this] { CheckEmpty(); });
- disk_cleanup_manager_->set_on_empty([this] { CheckEmpty(); });
-}
-
-LedgerRepositoryImpl::~LedgerRepositoryImpl() {}
-
-void LedgerRepositoryImpl::Inspect(std::string display_name,
- component::Object::ObjectVector* out) const {
- auto object_dir = component::ObjectDir::Make(std::move(display_name));
- object_dir.set_metric({kRequestsInspectPathComponent},
- component::UIntMetric(bindings_.size()));
- object_dir.set_children_callback(
- [/*this*/](component::Object::ObjectVector* out) {
- // TODO(nathaniel): This is the next level down of inspection...
- });
- out->push_back(object_dir.object());
-}
-
-void LedgerRepositoryImpl::BindRepository(
- fidl::InterfaceRequest<ledger_internal::LedgerRepository>
- repository_request) {
- bindings_.emplace(this, std::move(repository_request));
-}
-
-void LedgerRepositoryImpl::PageIsClosedAndSynced(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) {
- LedgerManager* ledger_manager;
- Status status = GetLedgerManager(ledger_name, &ledger_manager);
- if (status != Status::OK) {
- callback(status, PagePredicateResult::PAGE_OPENED);
- return;
- }
-
- FXL_DCHECK(ledger_manager);
- ledger_manager->PageIsClosedAndSynced(page_id, std::move(callback));
-}
-
-void LedgerRepositoryImpl::PageIsClosedOfflineAndEmpty(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) {
- LedgerManager* ledger_manager;
- Status status = GetLedgerManager(ledger_name, &ledger_manager);
- if (status != Status::OK) {
- callback(status, PagePredicateResult::PAGE_OPENED);
- return;
- }
- FXL_DCHECK(ledger_manager);
- ledger_manager->PageIsClosedOfflineAndEmpty(page_id, std::move(callback));
-}
-
-void LedgerRepositoryImpl::DeletePageStorage(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status)> callback) {
- LedgerManager* ledger_manager;
- Status status = GetLedgerManager(ledger_name, &ledger_manager);
- if (status != Status::OK) {
- callback(status);
- return;
- }
- FXL_DCHECK(ledger_manager);
- return ledger_manager->DeletePageStorage(page_id, std::move(callback));
-}
-
-std::vector<fidl::InterfaceRequest<ledger_internal::LedgerRepository>>
-LedgerRepositoryImpl::Unbind() {
- std::vector<fidl::InterfaceRequest<ledger_internal::LedgerRepository>>
- handles;
- for (auto& binding : bindings_) {
- handles.push_back(binding.Unbind());
- }
- bindings_.clear();
- return handles;
-}
-
-Status LedgerRepositoryImpl::GetLedgerManager(
- convert::ExtendedStringView ledger_name, LedgerManager** ledger_manager) {
- FXL_DCHECK(!ledger_name.empty());
-
- // If the Ledger instance is already open return it directly.
- auto it = ledger_managers_.find(ledger_name);
- if (it != ledger_managers_.end()) {
- *ledger_manager = &(it->second);
- return Status::OK;
- }
-
- std::string name_as_string = convert::ToString(ledger_name);
- std::unique_ptr<encryption::EncryptionService> encryption_service =
- encryption_service_factory_.MakeEncryptionService(name_as_string);
- auto ledger_storage = std::make_unique<storage::LedgerStorageImpl>(
- environment_, encryption_service.get(), db_factory_.get(),
- GetPathFor(name_as_string));
- storage::Status status = ledger_storage->Init();
- if (status != storage::Status::OK) {
- return PageUtils::ConvertStatus(status);
- }
- std::unique_ptr<sync_coordinator::LedgerSync> ledger_sync;
- if (user_sync_) {
- ledger_sync =
- user_sync_->CreateLedgerSync(name_as_string, encryption_service.get());
- }
- auto result = ledger_managers_.emplace(
- std::piecewise_construct, std::forward_as_tuple(name_as_string),
- std::forward_as_tuple(environment_, std::move(name_as_string),
- std::move(encryption_service),
- std::move(ledger_storage), std::move(ledger_sync),
- page_usage_listener_));
- FXL_DCHECK(result.second);
- *ledger_manager = &(result.first->second);
- return Status::OK;
-}
-
-void LedgerRepositoryImpl::GetLedger(
- std::vector<uint8_t> ledger_name,
- fidl::InterfaceRequest<Ledger> ledger_request,
- fit::function<void(Status)> callback) {
- TRACE_DURATION("ledger", "repository_get_ledger");
- if (ledger_name.empty()) {
- callback(Status::INVALID_ARGUMENT);
- return;
- }
-
- LedgerManager* ledger_manager;
- Status status = GetLedgerManager(ledger_name, &ledger_manager);
- if (status != Status::OK) {
- callback(status);
- return;
- }
- FXL_DCHECK(ledger_manager);
- ledger_manager->BindLedger(std::move(ledger_request));
- callback(Status::OK);
-}
-
-void LedgerRepositoryImpl::Duplicate(
- fidl::InterfaceRequest<ledger_internal::LedgerRepository> request,
- fit::function<void(Status)> callback) {
- BindRepository(std::move(request));
- callback(Status::OK);
-}
-
-void LedgerRepositoryImpl::SetSyncStateWatcher(
- fidl::InterfaceHandle<SyncWatcher> watcher,
- fit::function<void(Status)> callback) {
- watchers_->AddSyncWatcher(std::move(watcher));
- callback(Status::OK);
-}
-
-void LedgerRepositoryImpl::CheckEmpty() {
- if (!on_empty_callback_)
- return;
- if (ledger_managers_.empty() && bindings_.empty() &&
- ledger_repository_debug_bindings_.size() == 0 &&
- disk_cleanup_manager_->IsEmpty()) {
- on_empty_callback_();
- }
-}
-
-void LedgerRepositoryImpl::GetLedgerRepositoryDebug(
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryDebug> request,
- fit::function<void(Status)> callback) {
- ledger_repository_debug_bindings_.AddBinding(this, std::move(request));
- callback(Status::OK);
-}
-
-void LedgerRepositoryImpl::DiskCleanUp(fit::function<void(Status)> callback) {
- cleanup_callbacks_.push_back(std::move(callback));
- if (cleanup_callbacks_.size() > 1) {
- return;
- }
- disk_cleanup_manager_->TryCleanUp([this](Status status) {
- FXL_DCHECK(!cleanup_callbacks_.empty());
-
- auto callbacks = std::move(cleanup_callbacks_);
- cleanup_callbacks_.clear();
- for (auto& callback : callbacks) {
- callback(status);
- }
- });
-}
-
-DetachedPath LedgerRepositoryImpl::GetPathFor(fxl::StringView ledger_name) {
- FXL_DCHECK(!ledger_name.empty());
- return content_path_.SubPath(GetDirectoryName(ledger_name));
-}
-
-void LedgerRepositoryImpl::GetInstancesList(GetInstancesListCallback callback) {
- std::vector<std::vector<uint8_t>> result;
- for (const auto& key_value : ledger_managers_) {
- result.push_back(convert::ToArray(key_value.first));
- }
- callback(std::move(result));
-}
-
-void LedgerRepositoryImpl::GetLedgerDebug(
- std::vector<uint8_t> ledger_name,
- fidl::InterfaceRequest<ledger_internal::LedgerDebug> request,
- GetLedgerDebugCallback callback) {
- auto it = ledger_managers_.find(ledger_name);
- if (it == ledger_managers_.end()) {
- callback(Status::KEY_NOT_FOUND);
- } else {
- it->second.BindLedgerDebug(std::move(request));
- callback(Status::OK);
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/ledger_repository_impl.h b/bin/ledger/app/ledger_repository_impl.h
deleted file mode 100644
index 9ead887..0000000
--- a/bin/ledger/app/ledger_repository_impl.h
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_LEDGER_REPOSITORY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_APP_LEDGER_REPOSITORY_IMPL_H_
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/component/cpp/expose.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/app/disk_cleanup_manager.h"
-#include "peridot/bin/ledger/app/ledger_manager.h"
-#include "peridot/bin/ledger/app/page_eviction_manager.h"
-#include "peridot/bin/ledger/app/sync_watcher_set.h"
-#include "peridot/bin/ledger/app/types.h"
-#include "peridot/bin/ledger/encryption/impl/encryption_service_factory_impl.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/fidl/error_notifier.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/p2p_sync/public/user_communicator.h"
-#include "peridot/bin/ledger/storage/public/db_factory.h"
-#include "peridot/bin/ledger/sync_coordinator/public/user_sync.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-class LedgerRepositoryImpl
- : public fuchsia::ledger::internal::LedgerRepositoryErrorNotifierDelegate,
- public ledger_internal::LedgerRepositoryDebug,
- public PageEvictionManager::Delegate {
- public:
- // Creates a new LedgerRepositoryImpl object. Guarantees that |db_factory|
- // will outlive the given |disk_cleanup_manager|.
- LedgerRepositoryImpl(DetachedPath content_path, Environment* environment,
- std::unique_ptr<storage::DbFactory> db_factory,
- std::unique_ptr<SyncWatcherSet> watchers,
- std::unique_ptr<sync_coordinator::UserSync> user_sync,
- std::unique_ptr<DiskCleanupManager> disk_cleanup_manager,
- PageUsageListener* page_usage_listener);
- ~LedgerRepositoryImpl() override;
-
- // Satisfies an inspection by adding to |out| an object with properties,
- // metrics, and (callbacks affording access to) children of its own.
- void Inspect(std::string display_name,
- component::Object::ObjectVector* out) const;
-
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- void BindRepository(fidl::InterfaceRequest<ledger_internal::LedgerRepository>
- repository_request);
-
- // Releases all handles bound to this repository impl.
- std::vector<fidl::InterfaceRequest<ledger_internal::LedgerRepository>>
- Unbind();
-
- // PageEvictionManager::Delegate:
- void PageIsClosedAndSynced(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) override;
- void PageIsClosedOfflineAndEmpty(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) override;
- void DeletePageStorage(fxl::StringView ledger_name,
- storage::PageIdView page_id,
- fit::function<void(Status)> callback) override;
-
- // LedgerRepository:
- void GetLedger(std::vector<uint8_t> ledger_name,
- fidl::InterfaceRequest<Ledger> ledger_request,
- fit::function<void(Status)> callback) override;
- void Duplicate(
- fidl::InterfaceRequest<ledger_internal::LedgerRepository> request,
- fit::function<void(Status)> callback) override;
- void SetSyncStateWatcher(fidl::InterfaceHandle<SyncWatcher> watcher,
- fit::function<void(Status)> callback) override;
- void GetLedgerRepositoryDebug(
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryDebug> request,
- fit::function<void(Status)> callback) override;
- void DiskCleanUp(fit::function<void(Status)> callback) override;
-
- private:
- // Retrieves the existing, or creates a new LedgerManager object with the
- // given |ledger_name|.
- Status GetLedgerManager(convert::ExtendedStringView ledger_name,
- LedgerManager** ledger_manager);
-
- void CheckEmpty();
-
- DetachedPath GetPathFor(fxl::StringView ledger_name);
-
- // LedgerRepositoryDebug:
- void GetInstancesList(GetInstancesListCallback callback) override;
-
- void GetLedgerDebug(
- std::vector<uint8_t> ledger_name,
- fidl::InterfaceRequest<ledger_internal::LedgerDebug> request,
- GetLedgerDebugCallback callback) override;
-
- const DetachedPath content_path_;
- Environment* const environment_;
- std::unique_ptr<storage::DbFactory> db_factory_;
- encryption::EncryptionServiceFactoryImpl encryption_service_factory_;
- std::unique_ptr<SyncWatcherSet> watchers_;
- std::unique_ptr<sync_coordinator::UserSync> user_sync_;
- std::unique_ptr<DiskCleanupManager> disk_cleanup_manager_;
- PageUsageListener* page_usage_listener_;
- callback::AutoCleanableMap<std::string, LedgerManager,
- convert::StringViewComparator>
- ledger_managers_;
- callback::AutoCleanableSet<ErrorNotifierBinding<
- fuchsia::ledger::internal::LedgerRepositoryErrorNotifierDelegate>>
- bindings_;
- fit::closure on_empty_callback_;
-
- fidl::BindingSet<ledger_internal::LedgerRepositoryDebug>
- ledger_repository_debug_bindings_;
-
- std::vector<fit::function<void(Status)>> cleanup_callbacks_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerRepositoryImpl);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_LEDGER_REPOSITORY_IMPL_H_
diff --git a/bin/ledger/app/ledger_repository_impl_unittest.cc b/bin/ledger/app/ledger_repository_impl_unittest.cc
deleted file mode 100644
index 378a9e6..0000000
--- a/bin/ledger/app/ledger_repository_impl_unittest.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/ledger_repository_impl.h"
-
-#include <fuchsia/inspect/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/component/cpp/expose.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/ledger_repository_factory_impl.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/fake/fake_db_factory.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/bin/ledger/testing/fake_disk_cleanup_manager.h"
-#include "peridot/bin/ledger/testing/inspect.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-namespace {
-
-class LedgerRepositoryImplTest : public TestWithEnvironment {
- public:
- LedgerRepositoryImplTest() {
- auto fake_page_eviction_manager =
- std::make_unique<FakeDiskCleanupManager>();
- disk_cleanup_manager_ = fake_page_eviction_manager.get();
-
- repository_ = std::make_unique<LedgerRepositoryImpl>(
- DetachedPath(tmpfs_.root_fd()), &environment_,
- std::make_unique<storage::fake::FakeDbFactory>(dispatcher()), nullptr,
- nullptr, std::move(fake_page_eviction_manager), disk_cleanup_manager_);
- }
-
- ~LedgerRepositoryImplTest() override {}
-
- protected:
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- FakeDiskCleanupManager* disk_cleanup_manager_;
- std::unique_ptr<LedgerRepositoryImpl> repository_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerRepositoryImplTest);
-};
-
-TEST_F(LedgerRepositoryImplTest, ConcurrentCalls) {
- // Make a first call to DiskCleanUp.
- bool callback_called1 = false;
- Status status1;
- repository_->DiskCleanUp(
- callback::Capture(callback::SetWhenCalled(&callback_called1), &status1));
-
- // Make a second one before the first one has finished.
- bool callback_called2 = false;
- Status status2;
- repository_->DiskCleanUp(
- callback::Capture(callback::SetWhenCalled(&callback_called2), &status2));
-
- // Make sure both of them start running.
- RunLoopUntilIdle();
-
- // Both calls must wait for the cleanup manager.
- EXPECT_FALSE(callback_called1);
- EXPECT_FALSE(callback_called2);
-
- // Call the cleanup manager callback and expect to see an ok status for both
- // pending callbacks.
- disk_cleanup_manager_->cleanup_callback(Status::OK);
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called1);
- EXPECT_TRUE(callback_called2);
- EXPECT_EQ(Status::OK, status1);
- EXPECT_EQ(Status::OK, status2);
-}
-
-TEST_F(LedgerRepositoryImplTest, InspectAPIRequestsMetricOnMultipleBindings) {
- // When nothing has bound to the repository, check that the "requests" metric
- // is present and is zero.
- bool zeroth_callback_called = false;
- fuchsia::inspect::Object zeroth_read_object;
- component::Object::ObjectVector zeroth_out;
-
- repository_->Inspect("zeroth", &zeroth_out);
-
- ASSERT_EQ(1UL, zeroth_out.size());
- zeroth_out.at(0).get()->ReadData(callback::Capture(
- callback::SetWhenCalled(&zeroth_callback_called), &zeroth_read_object));
- EXPECT_TRUE(zeroth_callback_called);
- ExpectRequestsMetric(&zeroth_read_object, 0UL);
-
- // When one binding has been made to the repository, check that the "requests"
- // metric is present and is one.
- ledger_internal::LedgerRepositoryPtr first_ledger_repository_ptr;
- bool first_callback_called = false;
- fuchsia::inspect::Object first_read_object;
- component::Object::ObjectVector first_out;
- repository_->BindRepository(first_ledger_repository_ptr.NewRequest());
-
- repository_->Inspect("first", &first_out);
-
- ASSERT_EQ(1UL, first_out.size());
- first_out.at(0).get()->ReadData(callback::Capture(
- callback::SetWhenCalled(&first_callback_called), &first_read_object));
- EXPECT_TRUE(first_callback_called);
- ExpectRequestsMetric(&first_read_object, 1UL);
-
- // When two bindings have been made to the repository, check that the
- // "requests" metric is present and is two.
- ledger_internal::LedgerRepositoryPtr second_ledger_repository_ptr;
- bool second_callback_called = false;
- fuchsia::inspect::Object second_read_object;
- component::Object::ObjectVector second_out;
- repository_->BindRepository(second_ledger_repository_ptr.NewRequest());
-
- repository_->Inspect("second", &second_out);
-
- ASSERT_EQ(1UL, second_out.size());
- second_out.at(0).get()->ReadData(callback::Capture(
- callback::SetWhenCalled(&second_callback_called), &second_read_object));
- EXPECT_TRUE(second_callback_called);
- ExpectRequestsMetric(&second_read_object, 2UL);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/merging/auto_merge_strategy.cc b/bin/ledger/app/merging/auto_merge_strategy.cc
deleted file mode 100644
index 071d5d2..0000000
--- a/bin/ledger/app/merging/auto_merge_strategy.cc
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/auto_merge_strategy.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/app/merging/conflict_resolver_client.h"
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-
-namespace ledger {
-class AutoMergeStrategy::AutoMerger {
- public:
- AutoMerger(storage::PageStorage* storage, PageManager* page_manager,
- ConflictResolver* conflict_resolver,
- std::unique_ptr<const storage::Commit> left,
- std::unique_ptr<const storage::Commit> right,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback);
- ~AutoMerger();
-
- void Start();
- void Cancel();
- void Done(Status status);
-
- private:
- void OnRightChangeReady(
- storage::Status status,
- std::unique_ptr<std::vector<storage::EntryChange>> right_change);
- void OnComparisonDone(
- storage::Status status,
- std::unique_ptr<std::vector<storage::EntryChange>> right_changes,
- bool distinct);
- void ApplyDiffOnJournal(
- std::unique_ptr<storage::Journal> journal,
- std::unique_ptr<std::vector<storage::EntryChange>> diff);
-
- storage::PageStorage* const storage_;
- PageManager* const manager_;
- ConflictResolver* const conflict_resolver_;
-
- std::unique_ptr<const storage::Commit> left_;
- std::unique_ptr<const storage::Commit> right_;
- std::unique_ptr<const storage::Commit> ancestor_;
-
- std::unique_ptr<ConflictResolverClient> delegated_merge_;
-
- fit::function<void(Status)> callback_;
-
- bool cancelled_ = false;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<AutoMergeStrategy::AutoMerger> weak_factory_;
-};
-
-AutoMergeStrategy::AutoMerger::AutoMerger(
- storage::PageStorage* storage, PageManager* page_manager,
- ConflictResolver* conflict_resolver,
- std::unique_ptr<const storage::Commit> left,
- std::unique_ptr<const storage::Commit> right,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback)
- : storage_(storage),
- manager_(page_manager),
- conflict_resolver_(conflict_resolver),
- left_(std::move(left)),
- right_(std::move(right)),
- ancestor_(std::move(ancestor)),
- callback_(std::move(callback)),
- weak_factory_(this) {
- FXL_DCHECK(callback_);
-}
-
-AutoMergeStrategy::AutoMerger::~AutoMerger() {}
-
-void AutoMergeStrategy::AutoMerger::Start() {
- auto changes = std::make_unique<std::vector<storage::EntryChange>>();
- auto on_next = [weak_this = weak_factory_.GetWeakPtr(),
- changes = changes.get()](storage::EntryChange change) {
- if (!weak_this) {
- return false;
- }
-
- if (weak_this->cancelled_) {
- return false;
- }
-
- changes->push_back(change);
- return true;
- };
-
- auto callback = callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, changes = std::move(changes)](storage::Status status) mutable {
- if (cancelled_) {
- Done(Status::INTERNAL_ERROR);
- return;
- }
- OnRightChangeReady(status, std::move(changes));
- });
-
- storage_->GetCommitContentsDiff(*ancestor_, *right_, "", std::move(on_next),
- std::move(callback));
-}
-
-void AutoMergeStrategy::AutoMerger::OnRightChangeReady(
- storage::Status status,
- std::unique_ptr<std::vector<storage::EntryChange>> right_change) {
- if (cancelled_) {
- Done(Status::INTERNAL_ERROR);
- return;
- }
-
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to compute right diff due to error " << status
- << ", aborting.";
- Done(PageUtils::ConvertStatus(status));
- return;
- }
-
- if (right_change->empty()) {
- OnComparisonDone(storage::Status::OK, std::move(right_change), true);
- return;
- }
-
- struct PageChangeIndex {
- size_t entry_index = 0;
- bool distinct = true;
- };
-
- auto index = std::make_unique<PageChangeIndex>();
-
- auto on_next = [weak_this = weak_factory_.GetWeakPtr(), index = index.get(),
- right_change =
- right_change.get()](storage::EntryChange change) {
- if (!weak_this || weak_this->cancelled_) {
- return false;
- }
-
- while (change.entry.key > (*right_change)[index->entry_index].entry.key) {
- index->entry_index++;
- if (index->entry_index >= right_change->size()) {
- return false;
- }
- }
- if (change.entry.key == (*right_change)[index->entry_index].entry.key) {
- if (change == (*right_change)[index->entry_index]) {
- return true;
- }
- index->distinct = false;
- return false;
- }
- return true;
- };
-
- // |callback| is called when the full diff is computed.
- auto callback = callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, right_change = std::move(right_change),
- index = std::move(index)](storage::Status status) mutable {
- if (cancelled_) {
- Done(Status::INTERNAL_ERROR);
- return;
- }
- OnComparisonDone(status, std::move(right_change), index->distinct);
- });
-
- storage_->GetCommitContentsDiff(*ancestor_, *left_, "", std::move(on_next),
- std::move(callback));
-}
-
-void AutoMergeStrategy::AutoMerger::OnComparisonDone(
- storage::Status status,
- std::unique_ptr<std::vector<storage::EntryChange>> right_changes,
- bool distinct) {
- if (cancelled_) {
- Done(Status::INTERNAL_ERROR);
- return;
- }
-
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to compute left diff due to error " << status
- << ", aborting.";
- Done(PageUtils::ConvertStatus(status));
- return;
- }
-
- if (!distinct) {
- // Some keys are overlapping, so we need to proceed like the CUSTOM
- // strategy. We could be more efficient if we reused |right_changes| instead
- // of re-computing the diff inside |ConflictResolverClient|.
- delegated_merge_ = std::make_unique<ConflictResolverClient>(
- storage_, manager_, conflict_resolver_, std::move(left_),
- std::move(right_), std::move(ancestor_),
- callback::MakeScoped(weak_factory_.GetWeakPtr(), [this](Status status) {
- if (cancelled_) {
- Done(Status::INTERNAL_ERROR);
- return;
- }
- Done(status);
- }));
-
- delegated_merge_->Start();
- return;
- }
-
- // Here, we reuse the diff we computed before to create the merge commit. As
- // StartMergeCommit uses the left commit (first parameter) as its base, we
- // only have to apply the right diff to it and we are done.
- storage_->StartMergeCommit(
- left_->GetId(), right_->GetId(),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, right_changes = std::move(right_changes)](
- storage::Status s,
- std::unique_ptr<storage::Journal> journal) mutable {
- if (cancelled_) {
- Done(Status::INTERNAL_ERROR);
- return;
- }
- if (s != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to start merge commit: " << s;
- Done(PageUtils::ConvertStatus(s));
- return;
- }
- ApplyDiffOnJournal(std::move(journal), std::move(right_changes));
- }));
-}
-
-void AutoMergeStrategy::AutoMerger::ApplyDiffOnJournal(
- std::unique_ptr<storage::Journal> journal,
- std::unique_ptr<std::vector<storage::EntryChange>> diff) {
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<storage::Status>>(
- storage::Status::OK);
- for (const storage::EntryChange& change : *diff) {
- if (change.deleted) {
- journal->Delete(change.entry.key, waiter->NewCallback());
- } else {
- journal->Put(change.entry.key, change.entry.object_identifier,
- change.entry.priority, waiter->NewCallback());
- }
- }
-
- waiter->Finalize([weak_this = weak_factory_.GetWeakPtr(),
- journal = std::move(journal)](storage::Status s) mutable {
- if (!weak_this) {
- return;
- }
- if (weak_this->cancelled_) {
- weak_this->Done(Status::INTERNAL_ERROR);
- return;
- }
- if (s != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to commit merge journal: " << s;
- weak_this->Done(PageUtils::ConvertStatus(s));
- return;
- }
- weak_this->storage_->CommitJournal(
- std::move(journal),
- [weak_this = std::move(weak_this)](
- storage::Status s,
- std::unique_ptr<const storage::Commit> /*commit*/) {
- if (s != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to commit merge journal: " << s;
- }
- if (weak_this) {
- weak_this->Done(PageUtils::ConvertStatus(s));
- }
- });
- });
-}
-
-void AutoMergeStrategy::AutoMerger::Cancel() {
- cancelled_ = true;
- if (delegated_merge_) {
- delegated_merge_->Cancel();
- }
-}
-
-void AutoMergeStrategy::AutoMerger::Done(Status status) {
- delegated_merge_.reset();
- auto callback = std::move(callback_);
- callback_ = nullptr;
- callback(status);
-}
-
-AutoMergeStrategy::AutoMergeStrategy(ConflictResolverPtr conflict_resolver)
- : conflict_resolver_(std::move(conflict_resolver)) {
- conflict_resolver_.set_error_handler([this](zx_status_t status) {
- // If a merge is in progress, it must be terminated.
- if (in_progress_merge_) {
- // The actual cleanup of in_progress_merge_ will happen in its callback
- // callback.
- in_progress_merge_->Cancel();
- }
- if (on_error_) {
- // It is safe to call |on_error_| because the error handler waits for the
- // merges to finish before deleting this object.
- on_error_();
- }
- });
-}
-
-AutoMergeStrategy::~AutoMergeStrategy() {}
-
-void AutoMergeStrategy::SetOnError(fit::closure on_error) {
- on_error_ = std::move(on_error);
-}
-
-void AutoMergeStrategy::Merge(storage::PageStorage* storage,
- PageManager* page_manager,
- std::unique_ptr<const storage::Commit> head_1,
- std::unique_ptr<const storage::Commit> head_2,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback) {
- FXL_DCHECK(head_1->GetTimestamp() <= head_2->GetTimestamp());
- FXL_DCHECK(!in_progress_merge_);
-
- in_progress_merge_ = std::make_unique<AutoMergeStrategy::AutoMerger>(
- storage, page_manager, conflict_resolver_.get(), std::move(head_2),
- std::move(head_1), std::move(ancestor),
- [this, callback = std::move(callback)](Status status) {
- in_progress_merge_.reset();
- callback(status);
- });
-
- in_progress_merge_->Start();
-}
-
-void AutoMergeStrategy::Cancel() {
- if (in_progress_merge_) {
- in_progress_merge_->Cancel();
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/merging/auto_merge_strategy.h b/bin/ledger/app/merging/auto_merge_strategy.h
deleted file mode 100644
index c68e24d..0000000
--- a/bin/ledger/app/merging/auto_merge_strategy.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_AUTO_MERGE_STRATEGY_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_AUTO_MERGE_STRATEGY_H_
-
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/app/merging/merge_strategy.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-// Strategy for merging commits using the AUTOMATIC_WITH_FALLBACK policy.
-class AutoMergeStrategy : public MergeStrategy {
- public:
- explicit AutoMergeStrategy(ConflictResolverPtr conflict_resolver);
- ~AutoMergeStrategy() override;
-
- // MergeStrategy:
- void SetOnError(fit::closure on_error) override;
-
- void Merge(storage::PageStorage* storage, PageManager* page_manager,
- std::unique_ptr<const storage::Commit> head_1,
- std::unique_ptr<const storage::Commit> head_2,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback) override;
-
- void Cancel() override;
-
- private:
- class AutoMerger;
-
- fit::closure on_error_;
-
- ConflictResolverPtr conflict_resolver_;
-
- std::unique_ptr<AutoMerger> in_progress_merge_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AutoMergeStrategy);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_AUTO_MERGE_STRATEGY_H_
diff --git a/bin/ledger/app/merging/common_ancestor.cc b/bin/ledger/app/merging/common_ancestor.cc
deleted file mode 100644
index fdb12e5..0000000
--- a/bin/ledger/app/merging/common_ancestor.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/common_ancestor.h"
-
-#include <utility>
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/coroutine/coroutine_waiter.h"
-
-namespace ledger {
-
-namespace {
-
-// Comparator for commits that order commits based on their generation, then on
-// their id.
-struct GenerationComparator {
- bool operator()(const std::unique_ptr<const storage::Commit>& lhs,
- const std::unique_ptr<const storage::Commit>& rhs) const {
- uint64_t lhs_generation = lhs->GetGeneration();
- uint64_t rhs_generation = rhs->GetGeneration();
- return lhs_generation == rhs_generation ? lhs->GetId() < rhs->GetId()
- : lhs_generation < rhs_generation;
- }
-};
-
-// Find the common ancestor the 2 given commits.
-//
-// The algorithm goes as follows: we keep a set of "active" commits, ordered
-// by generation order. Until this set has only one element, we take the
-// commit with the greater generation (the one deepest in the commit graph)
-// and replace it by its parent. If we seed the initial set with two commits,
-// we get their unique lowest common ancestor.
-// At each step of the iteration we request the parent commits of all commits
-// with the same generation.
-storage::Status FindCommonAncestorSync(
- coroutine::CoroutineHandler* handler, storage::PageStorage* storage,
- std::unique_ptr<const storage::Commit> head1,
- std::unique_ptr<const storage::Commit> head2,
- std::unique_ptr<const storage::Commit>* result) {
- std::set<std::unique_ptr<const storage::Commit>, GenerationComparator>
- commits;
- commits.emplace(std::move(head1));
- commits.emplace(std::move(head2));
-
- while (commits.size() > 1) {
- // Pop the newest commits and retrieve their parents.
- uint64_t expected_generation = (*commits.rbegin())->GetGeneration();
- auto waiter = fxl::MakeRefCounted<callback::Waiter<
- storage::Status, std::unique_ptr<const storage::Commit>>>(
- storage::Status::OK);
- while (commits.size() > 1 &&
- expected_generation == (*commits.rbegin())->GetGeneration()) {
- // Pop the newest commit.
- std::unique_ptr<const storage::Commit> commit =
- std::move(commits.extract(std::prev(commits.end())).value());
- // Request its parents.
- for (const auto& parent_id : commit->GetParentIds()) {
- storage->GetCommit(parent_id, waiter->NewCallback());
- }
- }
- storage::Status status;
- std::vector<std::unique_ptr<const storage::Commit>> parents;
- if (coroutine::Wait(handler, std::move(waiter), &status, &parents) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return storage::Status::INTERRUPTED;
- }
- if (status != storage::Status::OK) {
- return status;
- }
- // Once the parents have been retrieved, add these in the set.
- // ancestor in that generation.
- for (auto& parent : parents) {
- commits.insert(std::move(parent));
- }
- }
- FXL_DCHECK(commits.size() == 1);
- *result = std::move(commits.extract(commits.begin()).value());
- return storage::Status::OK;
-}
-
-} // namespace
-
-void FindCommonAncestor(
- coroutine::CoroutineService* coroutine_service,
- storage::PageStorage* const storage,
- std::unique_ptr<const storage::Commit> head1,
- std::unique_ptr<const storage::Commit> head2,
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- coroutine_service->StartCoroutine(
- [storage, head1 = std::move(head1), head2 = std::move(head2),
- callback =
- std::move(callback)](coroutine::CoroutineHandler* handler) mutable {
- std::unique_ptr<const storage::Commit> result;
- storage::Status status = FindCommonAncestorSync(
- handler, storage, std::move(head1), std::move(head2), &result);
- callback(PageUtils::ConvertStatus(status), std::move(result));
- });
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/merging/common_ancestor.h b/bin/ledger/app/merging/common_ancestor.h
deleted file mode 100644
index b44eca8..0000000
--- a/bin/ledger/app/merging/common_ancestor.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_COMMON_ANCESTOR_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_COMMON_ANCESTOR_H_
-
-#include <functional>
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_counted.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-
-void FindCommonAncestor(
- coroutine::CoroutineService* coroutine_service,
- storage::PageStorage* storage, std::unique_ptr<const storage::Commit> head1,
- std::unique_ptr<const storage::Commit> head2,
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_COMMON_ANCESTOR_H_
diff --git a/bin/ledger/app/merging/common_ancestor_unittest.cc b/bin/ledger/app/merging/common_ancestor_unittest.cc
deleted file mode 100644
index b15d279..0000000
--- a/bin/ledger/app/merging/common_ancestor_unittest.cc
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/common_ancestor.h"
-
-#include <algorithm>
-#include <string>
-
-#include <lib/callback/cancellable_helper.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/merging/test_utils.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-namespace {
-class CommonAncestorTest : public TestWithPageStorage {
- public:
- CommonAncestorTest() {}
- ~CommonAncestorTest() override {}
-
- protected:
- storage::PageStorage* page_storage() override { return storage_.get(); }
-
- void SetUp() override {
- TestWithPageStorage::SetUp();
- ASSERT_TRUE(CreatePageStorage(&storage_));
- }
-
- std::unique_ptr<const storage::Commit> CreateCommit(
- storage::CommitIdView parent_id,
- fit::function<void(storage::Journal*)> contents) {
- bool called;
- storage::Status status;
- std::unique_ptr<storage::Journal> journal;
- storage_->StartCommit(
- parent_id.ToString(), storage::JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
-
- contents(journal.get());
- std::unique_ptr<const storage::Commit> commit;
- storage_->CommitJournal(
- std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- return commit;
- }
-
- std::unique_ptr<const storage::Commit> CreateMergeCommit(
- storage::CommitIdView left, storage::CommitIdView right,
- fit::function<void(storage::Journal*)> contents) {
- bool called;
- storage::Status status;
- std::unique_ptr<storage::Journal> journal;
- storage_->StartMergeCommit(
- left.ToString(), right.ToString(),
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
-
- contents(journal.get());
- storage::Status actual_status;
- std::unique_ptr<const storage::Commit> actual_commit;
- storage_->CommitJournal(std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called),
- &actual_status, &actual_commit));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, actual_status);
- return actual_commit;
- }
-
- std::unique_ptr<const storage::Commit> GetRoot() {
- bool called;
- storage::Status status;
- std::unique_ptr<const storage::Commit> root;
- storage_->GetCommit(
- storage::kFirstPageCommitId,
- callback::Capture(callback::SetWhenCalled(&called), &status, &root));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- return root;
- }
-
- coroutine::CoroutineServiceImpl coroutine_service_;
- std::unique_ptr<storage::PageStorage> storage_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(CommonAncestorTest);
-};
-
-TEST_F(CommonAncestorTest, TwoChildrenOfRoot) {
- std::unique_ptr<const storage::Commit> commit_1 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key", "a"));
- std::unique_ptr<const storage::Commit> commit_2 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key", "b"));
-
- bool called;
- Status status;
- std::unique_ptr<const storage::Commit> result;
- FindCommonAncestor(
- &coroutine_service_, storage_.get(), std::move(commit_1),
- std::move(commit_2),
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(storage::kFirstPageCommitId, result->GetId());
-}
-
-TEST_F(CommonAncestorTest, RootAndChild) {
- std::unique_ptr<const storage::Commit> root = GetRoot();
-
- std::unique_ptr<const storage::Commit> child = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key", "a"));
-
- bool called;
- Status status;
- std::unique_ptr<const storage::Commit> result;
- FindCommonAncestor(
- &coroutine_service_, storage_.get(), std::move(root), std::move(child),
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(storage::kFirstPageCommitId, result->GetId());
-}
-
-// In this test the commits have the following structure:
-// (root)
-// / \
-// (A) (B)
-// / \ / \
-// (1) (merge) (2)
-TEST_F(CommonAncestorTest, MergeCommitAndSomeOthers) {
- std::unique_ptr<const storage::Commit> commit_a = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key", "a"));
- std::unique_ptr<const storage::Commit> commit_b = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key", "b"));
-
- std::unique_ptr<const storage::Commit> commit_merge = CreateMergeCommit(
- commit_a->GetId(), commit_b->GetId(), AddKeyValueToJournal("key", "c"));
-
- std::unique_ptr<const storage::Commit> commit_1 =
- CreateCommit(commit_a->GetId(), AddKeyValueToJournal("key", "1"));
- std::unique_ptr<const storage::Commit> commit_2 =
- CreateCommit(commit_b->GetId(), AddKeyValueToJournal("key", "2"));
-
- // Ancestor of (1) and (merge) needs to be (root).
- bool called;
- Status status;
- std::unique_ptr<const storage::Commit> result;
- FindCommonAncestor(
- &coroutine_service_, storage_.get(), std::move(commit_1),
- std::move(commit_merge),
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(storage::kFirstPageCommitId, result->GetId());
-
- // Ancestor of (2) and (A).
- FindCommonAncestor(
- &coroutine_service_, storage_.get(), std::move(commit_2),
- std::move(commit_a),
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(storage::kFirstPageCommitId, result->GetId());
-}
-
-// Regression test for LE-187.
-TEST_F(CommonAncestorTest, LongChain) {
- const int length = 180;
-
- std::unique_ptr<const storage::Commit> commit_a = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key", "a"));
- std::unique_ptr<const storage::Commit> commit_b = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key", "b"));
-
- std::unique_ptr<const storage::Commit> last_commit = std::move(commit_a);
- for (int i = 0; i < length; i++) {
- last_commit = CreateCommit(last_commit->GetId(),
- AddKeyValueToJournal(std::to_string(i), "val"));
- }
-
- // Ancestor of (last commit) and (b) needs to be (root).
- bool called;
- Status status;
- std::unique_ptr<const storage::Commit> result;
- FindCommonAncestor(
- &coroutine_service_, storage_.get(), std::move(last_commit),
- std::move(commit_b),
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- // This test lasts ~2.5s on x86+qemu+kvm.
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(storage::kFirstPageCommitId, result->GetId());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/merging/conflict_resolver_client.cc b/bin/ledger/app/merging/conflict_resolver_client.cc
deleted file mode 100644
index e38690d..0000000
--- a/bin/ledger/app/merging/conflict_resolver_client.cc
+++ /dev/null
@@ -1,450 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/conflict_resolver_client.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/app/diff_utils.h"
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/lib/util/ptr.h"
-
-namespace ledger {
-
-ConflictResolverClient::ConflictResolverClient(
- storage::PageStorage* storage, PageManager* page_manager,
- ConflictResolver* conflict_resolver,
- std::unique_ptr<const storage::Commit> left,
- std::unique_ptr<const storage::Commit> right,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback)
- : storage_(storage),
- manager_(page_manager),
- conflict_resolver_(conflict_resolver),
- left_(std::move(left)),
- right_(std::move(right)),
- ancestor_(std::move(ancestor)),
- callback_(std::move(callback)),
- merge_result_provider_binding_(this),
- weak_factory_(this) {
- FXL_DCHECK(left_->GetTimestamp() >= right_->GetTimestamp());
- FXL_DCHECK(callback_);
-}
-
-ConflictResolverClient::~ConflictResolverClient() {
- if (journal_) {
- storage_->RollbackJournal(std::move(journal_),
- [](storage::Status /*status*/) {});
- }
-}
-
-void ConflictResolverClient::Start() {
- // Prepare the journal for the merge commit.
- storage_->StartMergeCommit(
- left_->GetId(), right_->GetId(),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this](storage::Status status,
- std::unique_ptr<storage::Journal> journal) {
- if (cancelled_) {
- Finalize(Status::INTERNAL_ERROR);
- return;
- }
- journal_ = std::move(journal);
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to start merge commit: "
- << fidl::ToUnderlying(status);
- Finalize(PageUtils::ConvertStatus(status));
- return;
- }
-
- PageSnapshotPtr page_snapshot_ancestor;
- manager_->BindPageSnapshot(ancestor_->Clone(),
- page_snapshot_ancestor.NewRequest(), "");
-
- PageSnapshotPtr page_snapshot_left;
- manager_->BindPageSnapshot(left_->Clone(),
- page_snapshot_left.NewRequest(), "");
-
- PageSnapshotPtr page_snapshot_right;
- manager_->BindPageSnapshot(right_->Clone(),
- page_snapshot_right.NewRequest(), "");
-
- in_client_request_ = true;
- conflict_resolver_->Resolve(
- std::move(page_snapshot_left), std::move(page_snapshot_right),
- std::move(page_snapshot_ancestor),
- merge_result_provider_binding_.NewBinding());
- }));
-}
-
-void ConflictResolverClient::Cancel() {
- cancelled_ = true;
- if (in_client_request_) {
- Finalize(Status::INTERNAL_ERROR);
- }
-}
-
-void ConflictResolverClient::OnNextMergeResult(
- const MergedValue& merged_value,
- const fxl::RefPtr<
- callback::Waiter<storage::Status, storage::ObjectIdentifier>>& waiter) {
- switch (merged_value.source) {
- case ValueSource::RIGHT: {
- std::string key = convert::ToString(merged_value.key);
- storage_->GetEntryFromCommit(
- *right_, key,
- [key, callback = waiter->NewCallback()](storage::Status status,
- storage::Entry entry) {
- if (status != storage::Status::OK) {
- if (status == storage::Status::NOT_FOUND) {
- FXL_LOG(ERROR)
- << "Key " << key
- << " is not present in the right change. Unable to proceed";
- }
- callback(status, {});
- return;
- }
- callback(storage::Status::OK, entry.object_identifier);
- });
- break;
- }
- case ValueSource::NEW: {
- if (merged_value.new_value->is_bytes()) {
- storage_->AddObjectFromLocal(storage::ObjectType::BLOB,
- storage::DataSource::Create(std::move(
- merged_value.new_value->bytes())),
- waiter->NewCallback());
- } else {
- storage::ObjectIdentifier object_identifier;
- Status status = manager_->ResolveReference(
- std::move(merged_value.new_value->reference()), &object_identifier);
- if (status != Status::OK) {
- waiter->NewCallback()(storage::Status::NOT_FOUND, {});
- return;
- }
- waiter->NewCallback()(storage::Status::OK,
- std::move(object_identifier));
- }
- break;
- }
- case ValueSource::DELETE: {
- journal_->Delete(merged_value.key,
- [callback = waiter->NewCallback()](
- storage::Status status) { callback(status, {}); });
- break;
- }
- }
-}
-
-void ConflictResolverClient::Finalize(Status status) {
- FXL_DCHECK(callback_) << "Finalize must only be called once.";
- if (journal_) {
- storage_->RollbackJournal(std::move(journal_),
- [](storage::Status /*rollback_status*/) {});
- journal_.reset();
- }
- merge_result_provider_binding_.Close(status);
- auto callback = std::move(callback_);
- callback_ = nullptr;
- callback(status);
-}
-
-void ConflictResolverClient::GetFullDiffNew(
- std::unique_ptr<Token> token,
- fit::function<void(Status, IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) {
- GetDiff(diff_utils::DiffType::FULL, std::move(token), std::move(callback));
-}
-
-void ConflictResolverClient::GetFullDiff(
- std::unique_ptr<Token> token,
- fit::function<void(Status, Status, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) {
- GetFullDiffNew(
- std::move(token),
- [callback = std::move(callback)](
- Status status, IterationStatus diff_status,
- std::vector<DiffEntry> entries, std::unique_ptr<Token> token) {
- if (status != Status::OK && status != Status::PARTIAL_RESULT) {
- callback(status, status, std::move(entries), std::move(token));
- return;
- }
- callback(Status::OK,
- diff_status == IterationStatus::OK ? Status::OK
- : Status::PARTIAL_RESULT,
- std::move(entries), std::move(token));
- });
-}
-
-void ConflictResolverClient::GetConflictingDiffNew(
- std::unique_ptr<Token> token,
- fit::function<void(Status, IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) {
- GetDiff(diff_utils::DiffType::CONFLICTING, std::move(token),
- std::move(callback));
-}
-
-void ConflictResolverClient::GetConflictingDiff(
- std::unique_ptr<Token> token,
- fit::function<void(Status, Status, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) {
- GetConflictingDiffNew(
- std::move(token),
- [callback = std::move(callback)](
- Status status, IterationStatus diff_status,
- std::vector<DiffEntry> entries, std::unique_ptr<Token> token) {
- if (status != Status::OK && status != Status::PARTIAL_RESULT) {
- callback(status, status, std::move(entries), std::move(token));
- return;
- }
- callback(Status::OK,
- diff_status == IterationStatus::OK ? Status::OK
- : Status::PARTIAL_RESULT,
- std::move(entries), std::move(token));
- });
-}
-
-void ConflictResolverClient::GetDiff(
- diff_utils::DiffType type, std::unique_ptr<Token> token,
- fit::function<void(Status, IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) {
- diff_utils::ComputeThreeWayDiff(
- storage_, *ancestor_, *left_, *right_, "",
- token ? convert::ToString(token->opaque_id) : "", type,
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, callback = std::move(callback)](
- Status status,
- std::pair<std::vector<DiffEntry>, std::string> page_change) {
- if (cancelled_) {
- callback(Status::INTERNAL_ERROR, IterationStatus::OK,
- {}, nullptr);
- Finalize(Status::INTERNAL_ERROR);
- return;
- }
- if (status != Status::OK) {
- FXL_LOG(ERROR) << "Unable to compute diff due to error "
- << fidl::ToUnderlying(status) << ", aborting.";
- callback(status, IterationStatus::OK,
- {}, nullptr);
- Finalize(status);
- return;
- }
-
- const std::string& next_token = page_change.second;
- IterationStatus diff_status = next_token.empty()
- ? IterationStatus::OK
- : IterationStatus::PARTIAL_RESULT;
- std::unique_ptr<Token> token;
- if (!next_token.empty()) {
- token = std::make_unique<Token>();
- token->opaque_id = convert::ToArray(next_token);
- }
- callback(Status::OK, diff_status, std::move(page_change.first),
- std::move(token));
- }));
-}
-
-void ConflictResolverClient::MergeNew(
- std::vector<MergedValue> merged_values,
- fit::function<void(Status)> callback) {
- has_merged_values_ = true;
- operation_serializer_.Serialize<Status>(
- std::move(callback), [this, weak_this = weak_factory_.GetWeakPtr(),
- merged_values = std::move(merged_values)](
- fit::function<void(Status)> callback) mutable {
- if (!IsInValidStateAndNotify(weak_this, callback)) {
- return;
- }
- auto waiter = fxl::MakeRefCounted<
- callback::Waiter<storage::Status, storage::ObjectIdentifier>>(
- storage::Status::OK);
- for (const MergedValue& merged_value : merged_values) {
- OnNextMergeResult(merged_value, waiter);
- }
- waiter->Finalize([this, weak_this,
- merged_values = std::move(merged_values),
- callback = std::move(callback)](
- storage::Status status,
- std::vector<storage::ObjectIdentifier>
- object_identifiers) mutable {
- if (!IsInValidStateAndNotify(weak_this, callback, status)) {
- return;
- }
-
- auto waiter =
- fxl::MakeRefCounted<callback::StatusWaiter<storage::Status>>(
- storage::Status::OK);
- for (size_t i = 0; i < object_identifiers.size(); ++i) {
- // DELETE is encoded with an invalid digest in OnNextMergeResult.
- if (!object_identifiers[i].object_digest().IsValid()) {
- continue;
- }
- journal_->Put(merged_values.at(i).key, object_identifiers[i],
- merged_values.at(i).priority == Priority::EAGER
- ? storage::KeyPriority::EAGER
- : storage::KeyPriority::LAZY,
- waiter->NewCallback());
- }
- waiter->Finalize(
- [callback = std::move(callback)](storage::Status status) {
- callback(PageUtils::ConvertStatus(status));
- });
- });
- });
-}
-
-void ConflictResolverClient::Merge(
- std::vector<MergedValue> merged_values,
- fit::function<void(Status, Status)> callback) {
- MergeNew(std::move(merged_values),
- [callback = std::move(callback)](Status status) {
- callback(status, status);
- });
-}
-
-void ConflictResolverClient::MergeNonConflictingEntriesNew(
- fit::function<void(Status)> callback) {
- operation_serializer_.Serialize<Status>(
- std::move(callback), [this, weak_this = weak_factory_.GetWeakPtr()](
- fit::function<void(Status)> callback) mutable {
- if (!IsInValidStateAndNotify(weak_this, callback)) {
- return;
- }
- auto waiter =
- fxl::MakeRefCounted<callback::StatusWaiter<storage::Status>>(
- storage::Status::OK);
-
- auto on_next = [this, weak_this,
- waiter](storage::ThreeWayChange change) {
- if (!weak_this) {
- return false;
- }
- // When |MergeNonConflictingEntries| is called first, we know that the
- // base state of |journal_| is equal to the left version. In that
- // case, we only want to merge diffs where the change is only on the
- // right side: no change means no diff, 3 different versions means
- // conflict (so we skip), and left-only changes are already taken into
- // account.
- if (util::EqualPtr(change.base, change.left)) {
- if (change.right) {
- journal_->Put(change.right->key, change.right->object_identifier,
- change.right->priority, waiter->NewCallback());
- } else {
- journal_->Delete(change.base->key, waiter->NewCallback());
- }
- } else if (util::EqualPtr(change.base, change.right) &&
- has_merged_values_) {
- if (change.left) {
- journal_->Put(change.left->key, change.left->object_identifier,
- change.left->priority, waiter->NewCallback());
- } else {
- journal_->Delete(change.base->key, waiter->NewCallback());
- }
- }
- return true;
- };
- auto on_done = [waiter, callback = std::move(callback)](
- storage::Status status) mutable {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status));
- return;
- }
- waiter->Finalize(
- [callback = std::move(callback)](storage::Status status) {
- callback(PageUtils::ConvertStatus(status));
- });
- };
- storage_->GetThreeWayContentsDiff(*ancestor_, *left_, *right_, "",
- std::move(on_next),
- std::move(on_done));
- });
-}
-
-void ConflictResolverClient::MergeNonConflictingEntries(
- fit::function<void(Status, Status)> callback) {
- MergeNonConflictingEntriesNew(
- [callback = std::move(callback)](Status status) {
- callback(status, status);
- });
-}
-
-void ConflictResolverClient::DoneNew(fit::function<void(Status)> callback) {
- operation_serializer_.Serialize<Status>(
- std::move(callback), [this, weak_this = weak_factory_.GetWeakPtr()](
- fit::function<void(Status)> callback) mutable {
- if (!IsInValidStateAndNotify(weak_this, callback)) {
- return;
- }
- in_client_request_ = false;
- FXL_DCHECK(!cancelled_);
- FXL_DCHECK(journal_);
-
- storage_->CommitJournal(
- std::move(journal_),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, weak_this, callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<const storage::Commit>) {
- if (!IsInValidStateAndNotify(weak_this, callback, status)) {
- return;
- }
- callback(Status::OK);
- Finalize(Status::OK);
- }));
- });
-}
-
-void ConflictResolverClient::Done(
- fit::function<void(Status, Status)> callback) {
- DoneNew([callback = std::move(callback)](Status status) {
- callback(status, status);
- });
-}
-
-bool ConflictResolverClient::IsInValidStateAndNotify(
- const fxl::WeakPtr<ConflictResolverClient>& weak_this,
- const fit::function<void(Status)>& callback, storage::Status status) {
- if (!weak_this) {
- callback(Status::INTERNAL_ERROR);
- return false;
- }
- if (!weak_this->cancelled_ && status == storage::Status::OK) {
- return true;
- }
- Status ledger_status =
- weak_this->cancelled_
- ? Status::INTERNAL_ERROR
- // The only not found error that can occur is a key not
- // found when processing a MergedValue with
- // ValueSource::RIGHT.
- : PageUtils::ConvertStatus(status, Status::KEY_NOT_FOUND);
- // An eventual error was logged before, no need to do it again here.
- callback(ledger_status);
- // Finalize destroys this object; we need to do it after executing
- // the callback.
- weak_this->Finalize(ledger_status);
- return false;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/merging/conflict_resolver_client.h b/bin/ledger/app/merging/conflict_resolver_client.h
deleted file mode 100644
index b576866..0000000
--- a/bin/ledger/app/merging/conflict_resolver_client.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_CONFLICT_RESOLVER_CLIENT_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_CONFLICT_RESOLVER_CLIENT_H_
-
-#include <memory>
-#include <vector>
-
-#include <lib/callback/operation_serializer.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/app/diff_utils.h"
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/fidl/error_notifier.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-// Client handling communication with a ConflictResolver interface in order to
-// merge conflicting commit branches. It is used both by AutoMergeStrategy and
-// CustomMergeStrategy.
-class ConflictResolverClient
- : public fuchsia::ledger::MergeResultProviderErrorNotifierDelegate {
- public:
- explicit ConflictResolverClient(
- storage::PageStorage* storage, PageManager* page_manager,
- ConflictResolver* conflict_resolver,
- std::unique_ptr<const storage::Commit> left,
- std::unique_ptr<const storage::Commit> right,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback);
- ~ConflictResolverClient() override;
-
- void Start();
- void Cancel();
-
- private:
- void OnNextMergeResult(
- const MergedValue& merged_value,
- const fxl::RefPtr<callback::Waiter<storage::Status,
- storage::ObjectIdentifier>>& waiter);
-
- // Rolls back journal, closes merge result provider and invokes callback_ with
- // |status|. This method must be called at most once.
- void Finalize(Status status);
-
- // Performs a diff of the given type on the conflict. Return a |Status|
- // different than OK if an error occured. If no error, return an
- // |IterationStatus|.
- void GetDiff(
- diff_utils::DiffType type, std::unique_ptr<Token> token,
- fit::function<void(Status, IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback);
-
- // MergeResultProviderNotifierDelegate:
- void GetFullDiff(
- std::unique_ptr<Token> token,
- fit::function<void(Status, Status, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) override;
- void GetFullDiffNew(
- std::unique_ptr<Token> token,
- fit::function<void(Status, IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) override;
- void GetConflictingDiff(
- std::unique_ptr<Token> token,
- fit::function<void(Status, Status, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) override;
- void GetConflictingDiffNew(
- std::unique_ptr<Token> token,
- fit::function<void(Status, IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) override;
- void Merge(std::vector<MergedValue> merged_values,
- fit::function<void(Status, Status)> callback) override;
- void MergeNew(std::vector<MergedValue> merged_values,
- fit::function<void(Status)> callback) override;
- void MergeNonConflictingEntries(
- fit::function<void(Status, Status)> callback) override;
- void MergeNonConflictingEntriesNew(
- fit::function<void(Status)> callback) override;
- void Done(fit::function<void(Status, Status)> callback) override;
- void DoneNew(fit::function<void(Status)> callback) override;
-
- // Checks whether this ConflictResolverClient is still valid (not deleted nor
- // cancelled) and the status is OK. Returns |true| in that case. Otherwise,
- // calls |callback| with the given |status| and calls |Finalize| if this
- // object is not deleted, then return |false|.
- static bool IsInValidStateAndNotify(
- const fxl::WeakPtr<ConflictResolverClient>& weak_this,
- const fit::function<void(Status)>& callback,
- storage::Status status = storage::Status::OK);
-
- storage::PageStorage* const storage_;
- PageManager* const manager_;
- ConflictResolver* const conflict_resolver_;
-
- std::unique_ptr<const storage::Commit> const left_;
- std::unique_ptr<const storage::Commit> const right_;
- std::unique_ptr<const storage::Commit> const ancestor_;
-
- // Called when the merge process is finished.
- fit::function<void(Status)> callback_;
-
- // |has_merged_values_| is true when |Merge| has been called to set some
- // values. It is used as an optimization in |MergeNonConflictingEntries|.
- bool has_merged_values_ = false;
- std::unique_ptr<storage::Journal> journal_;
- // |in_client_request_| is true when waiting for the callback of the
- // ConflictResolver.Resolve call. When this merge is cancelled, we check this
- // boolean to know if we should abort immediately (when in a client request,
- // as the client may have disconnected) and when we should wait for the
- // operation to finish (the other cases, such as committing the merge).
- bool in_client_request_ = false;
- bool cancelled_ = false;
-
- // Operations are operating on the state of the merge commit. They must be
- // serialized.
- callback::OperationSerializer operation_serializer_;
-
- ledger::ErrorNotifierBinding<
- fuchsia::ledger::MergeResultProviderErrorNotifierDelegate>
- merge_result_provider_binding_;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<ConflictResolverClient> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ConflictResolverClient);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_CONFLICT_RESOLVER_CLIENT_H_
diff --git a/bin/ledger/app/merging/conflict_resolver_client_unittest.cc b/bin/ledger/app/merging/conflict_resolver_client_unittest.cc
deleted file mode 100644
index 4924571..0000000
--- a/bin/ledger/app/merging/conflict_resolver_client_unittest.cc
+++ /dev/null
@@ -1,350 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-
-#include <lib/backoff/testing/test_backoff.h>
-#include <lib/callback/cancellable_helper.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/macros.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/merging/custom_merge_strategy.h"
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-#include "peridot/bin/ledger/app/merging/test_utils.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/impl/page_storage_impl.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-namespace {
-class ConflictResolverClientTest : public TestWithPageStorage {
- public:
- ConflictResolverClientTest() {}
- ~ConflictResolverClientTest() override {}
-
- protected:
- storage::PageStorage* page_storage() override { return page_storage_; }
-
- void SetUp() override {
- TestWithPageStorage::SetUp();
- std::unique_ptr<storage::PageStorage> page_storage;
- ASSERT_TRUE(CreatePageStorage(&page_storage));
- page_storage_ = page_storage.get();
-
- std::unique_ptr<MergeResolver> resolver = std::make_unique<MergeResolver>(
- [] {}, &environment_, page_storage_,
- std::make_unique<backoff::TestBackoff>());
- resolver->SetMergeStrategy(nullptr);
- resolver->set_on_empty(QuitLoopClosure());
- merge_resolver_ = resolver.get();
-
- page_manager_ = std::make_unique<PageManager>(
- &environment_, std::move(page_storage), nullptr, std::move(resolver),
- PageManager::PageStorageState::NEEDS_SYNC);
- }
-
- storage::CommitId CreateCommit(
- storage::CommitIdView parent_id,
- fit::function<void(storage::Journal*)> contents) {
- storage::Status status;
- bool called;
- std::unique_ptr<storage::Journal> journal;
- page_storage_->StartCommit(
- parent_id.ToString(), storage::JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
-
- contents(journal.get());
- std::unique_ptr<const storage::Commit> commit;
- page_storage_->CommitJournal(
- std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- return commit->GetId();
- }
-
- storage::PageStorage* page_storage_;
- MergeResolver* merge_resolver_;
-
- private:
- std::unique_ptr<PageManager> page_manager_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ConflictResolverClientTest);
-};
-
-class ConflictResolverImpl : public ConflictResolver {
- public:
- explicit ConflictResolverImpl(
- fidl::InterfaceRequest<ConflictResolver> request,
- fit::closure quit_callback)
- : binding_(this, std::move(request)),
- quit_callback_(std::move(quit_callback)) {
- binding_.set_error_handler(
- [this](zx_status_t status) { this->disconnected = true; });
- }
- ~ConflictResolverImpl() override {}
-
- struct ResolveRequest {
- fidl::InterfaceHandle<PageSnapshot> left_version;
- fidl::InterfaceHandle<PageSnapshot> right_version;
- fidl::InterfaceHandle<PageSnapshot> common_version;
- MergeResultProviderPtr result_provider_ptr;
- bool result_provider_disconnected = false;
- zx_status_t result_provider_status = ZX_OK;
-
- ResolveRequest(fidl::InterfaceHandle<PageSnapshot> left_version,
- fidl::InterfaceHandle<PageSnapshot> right_version,
- fidl::InterfaceHandle<PageSnapshot> common_version,
- fidl::InterfaceHandle<MergeResultProvider> result_provider)
- : left_version(std::move(left_version)),
- right_version(std::move(right_version)),
- common_version(std::move(common_version)),
- result_provider_ptr(result_provider.Bind()) {
- result_provider_ptr.set_error_handler(callback::Capture(
- callback::SetWhenCalled(&result_provider_disconnected),
- &result_provider_status));
- }
- };
-
- std::vector<std::unique_ptr<ResolveRequest>> requests;
- bool disconnected = false;
-
- private:
- // ConflictResolver:
- void Resolve(
- fidl::InterfaceHandle<PageSnapshot> left_version,
- fidl::InterfaceHandle<PageSnapshot> right_version,
- fidl::InterfaceHandle<PageSnapshot> common_version,
- fidl::InterfaceHandle<MergeResultProvider> result_provider) override {
- requests.push_back(std::make_unique<ResolveRequest>(
- std::move(left_version), std::move(right_version),
- std::move(common_version), std::move(result_provider)));
- quit_callback_();
- }
-
- fidl::Binding<ConflictResolver> binding_;
- fit::closure quit_callback_;
-};
-
-TEST_F(ConflictResolverClientTest, Error) {
- // Set up conflict.
- CreateCommit(storage::kFirstPageCommitId,
- AddKeyValueToJournal("key1", "value1"));
- CreateCommit(storage::kFirstPageCommitId,
- AddKeyValueToJournal("key2", "value2"));
-
- // Set the resolver.
- ConflictResolverPtr conflict_resolver_ptr;
- ConflictResolverImpl conflict_resolver_impl(
- conflict_resolver_ptr.NewRequest(), QuitLoopClosure());
- std::unique_ptr<CustomMergeStrategy> custom_merge_strategy =
- std::make_unique<CustomMergeStrategy>(std::move(conflict_resolver_ptr));
-
- bool custom_strategy_error = false;
- custom_merge_strategy->SetOnError([this, &custom_strategy_error]() {
- custom_strategy_error = true;
- QuitLoop();
- });
-
- merge_resolver_->SetMergeStrategy(std::move(custom_merge_strategy));
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
-
- EXPECT_FALSE(merge_resolver_->IsEmpty());
- EXPECT_EQ(1u, conflict_resolver_impl.requests.size());
-
- // Create a bogus conflict resolution.
- std::vector<MergedValue> merged_values;
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("unknown_key");
- merged_value.source = ValueSource::RIGHT;
- merged_values.push_back(std::move(merged_value));
- }
-
- conflict_resolver_impl.requests[0]->result_provider_ptr->MergeNew(
- std::move(merged_values));
- RunLoopUntilIdle();
-
- EXPECT_EQ(Status::KEY_NOT_FOUND,
- static_cast<Status>(
- conflict_resolver_impl.requests[0]->result_provider_status));
- EXPECT_EQ(2u, conflict_resolver_impl.requests.size());
-}
-
-TEST_F(ConflictResolverClientTest, MergeNonConflicting) {
- // Set up conflict.
- CreateCommit(storage::kFirstPageCommitId,
- AddKeyValueToJournal("key1", "value1"));
- CreateCommit(storage::kFirstPageCommitId,
- AddKeyValueToJournal("key2", "value2"));
-
- // Set the resolver.
- ConflictResolverPtr conflict_resolver_ptr;
- ConflictResolverImpl conflict_resolver_impl(
- conflict_resolver_ptr.NewRequest(), QuitLoopClosure());
- std::unique_ptr<CustomMergeStrategy> custom_merge_strategy =
- std::make_unique<CustomMergeStrategy>(std::move(conflict_resolver_ptr));
-
- merge_resolver_->SetMergeStrategy(std::move(custom_merge_strategy));
-
- RunLoopUntilIdle();
-
- EXPECT_FALSE(merge_resolver_->IsEmpty());
- EXPECT_EQ(1u, conflict_resolver_impl.requests.size());
-
- conflict_resolver_impl.requests[0]
- ->result_provider_ptr->MergeNonConflictingEntriesNew();
- conflict_resolver_impl.requests[0]->result_provider_ptr->DoneNew();
- RunLoopUntilIdle();
- ASSERT_TRUE(conflict_resolver_impl.requests[0]->result_provider_disconnected);
- EXPECT_EQ(ZX_OK, conflict_resolver_impl.requests[0]->result_provider_status);
-
- bool called;
- storage::Status storage_status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(callback::Capture(
- callback::SetWhenCalled(&called), &storage_status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, storage_status);
- // The merge happened.
- EXPECT_EQ(1u, ids.size());
-
- // Let's verify the contents.
- std::unique_ptr<const storage::Commit> commit;
- page_storage_->GetCommit(ids[0],
- callback::Capture(callback::SetWhenCalled(&called),
- &storage_status, &commit));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, storage_status);
-
- storage::Entry key1_entry, key2_entry;
- page_storage_->GetEntryFromCommit(
- *commit, "key1",
- callback::Capture(callback::SetWhenCalled(&called), &storage_status,
- &key1_entry));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, storage_status);
-
- page_storage_->GetEntryFromCommit(
- *commit, "key2",
- callback::Capture(callback::SetWhenCalled(&called), &storage_status,
- &key2_entry));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, storage_status);
-
- std::string value1, value2;
- GetValue(key1_entry.object_identifier, &value1);
- EXPECT_EQ("value1", value1);
- GetValue(key2_entry.object_identifier, &value2);
- EXPECT_EQ("value2", value2);
-}
-
-TEST_F(ConflictResolverClientTest, MergeNonConflictingOrdering) {
- // Set up conflict.
- storage::CommitId base_id = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key1", "value1"));
- CreateCommit(base_id, AddKeyValueToJournal("key2", "value2"));
- CreateCommit(base_id, AddKeyValueToJournal("key1", "value1bis"));
-
- // Set the resolver.
- ConflictResolverPtr conflict_resolver_ptr;
- ConflictResolverImpl conflict_resolver_impl(
- conflict_resolver_ptr.NewRequest(), QuitLoopClosure());
- std::unique_ptr<CustomMergeStrategy> custom_merge_strategy =
- std::make_unique<CustomMergeStrategy>(std::move(conflict_resolver_ptr));
-
- merge_resolver_->SetMergeStrategy(std::move(custom_merge_strategy));
-
- RunLoopUntilIdle();
-
- EXPECT_FALSE(merge_resolver_->IsEmpty());
- EXPECT_EQ(1u, conflict_resolver_impl.requests.size());
-
- std::vector<MergedValue> merged_values;
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("key1");
- merged_value.source = ValueSource::RIGHT;
- merged_values.push_back(std::move(merged_value));
- }
-
- conflict_resolver_impl.requests[0]->result_provider_ptr->MergeNew(
- std::move(merged_values));
- conflict_resolver_impl.requests[0]
- ->result_provider_ptr->MergeNonConflictingEntriesNew();
- conflict_resolver_impl.requests[0]->result_provider_ptr->DoneNew();
- RunLoopUntilIdle();
- ASSERT_TRUE(conflict_resolver_impl.requests[0]->result_provider_disconnected);
- EXPECT_EQ(ZX_OK, conflict_resolver_impl.requests[0]->result_provider_status);
-
- bool called;
- storage::Status storage_status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(callback::Capture(
- callback::SetWhenCalled(&called), &storage_status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, storage_status);
- // The merge happened.
- EXPECT_EQ(1u, ids.size());
-
- // Let's verify the contents.
- std::unique_ptr<const storage::Commit> commit;
- page_storage_->GetCommit(ids[0],
- callback::Capture(callback::SetWhenCalled(&called),
- &storage_status, &commit));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, storage_status);
-
- storage::Entry key1_entry, key2_entry;
- page_storage_->GetEntryFromCommit(
- *commit, "key1",
- callback::Capture(callback::SetWhenCalled(&called), &storage_status,
- &key1_entry));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, storage_status);
-
- page_storage_->GetEntryFromCommit(
- *commit, "key2",
- callback::Capture(callback::SetWhenCalled(&called), &storage_status,
- &key2_entry));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, storage_status);
-
- std::string value1, value2;
- GetValue(key1_entry.object_identifier, &value1);
- EXPECT_EQ("value1bis", value1);
- GetValue(key2_entry.object_identifier, &value2);
- EXPECT_EQ("value2", value2);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/merging/custom_merge_strategy.cc b/bin/ledger/app/merging/custom_merge_strategy.cc
deleted file mode 100644
index 69c587f..0000000
--- a/bin/ledger/app/merging/custom_merge_strategy.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/custom_merge_strategy.h"
-
-#include <memory>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/app/page_manager.h"
-
-namespace ledger {
-CustomMergeStrategy::CustomMergeStrategy(ConflictResolverPtr conflict_resolver)
- : conflict_resolver_(std::move(conflict_resolver)) {
- conflict_resolver_.set_error_handler([this](zx_status_t status) {
- // If a merge is in progress, it must be terminated.
- if (in_progress_merge_) {
- // The actual cleanup of in_progress_merge_ will happen in its on_done
- // callback.
- in_progress_merge_->Cancel();
- }
- if (on_error_) {
- // It is safe to call |on_error_| because the error handler waits for the
- // merges to finish before deleting this object.
- on_error_();
- }
- });
-}
-
-CustomMergeStrategy::~CustomMergeStrategy() {}
-
-void CustomMergeStrategy::SetOnError(fit::closure on_error) {
- on_error_ = std::move(on_error);
-}
-
-void CustomMergeStrategy::Merge(storage::PageStorage* storage,
- PageManager* page_manager,
- std::unique_ptr<const storage::Commit> head_1,
- std::unique_ptr<const storage::Commit> head_2,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback) {
- FXL_DCHECK(head_1->GetTimestamp() <= head_2->GetTimestamp());
- FXL_DCHECK(!in_progress_merge_);
-
- in_progress_merge_ = std::make_unique<ConflictResolverClient>(
- storage, page_manager, conflict_resolver_.get(), std::move(head_2),
- std::move(head_1), std::move(ancestor),
- [this, callback = std::move(callback)](Status status) {
- in_progress_merge_.reset();
- callback(status);
- });
-
- in_progress_merge_->Start();
-}
-
-void CustomMergeStrategy::Cancel() {
- if (in_progress_merge_) {
- in_progress_merge_->Cancel();
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/merging/custom_merge_strategy.h b/bin/ledger/app/merging/custom_merge_strategy.h
deleted file mode 100644
index fb92e4e..0000000
--- a/bin/ledger/app/merging/custom_merge_strategy.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_CUSTOM_MERGE_STRATEGY_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_CUSTOM_MERGE_STRATEGY_H_
-
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/app/merging/conflict_resolver_client.h"
-#include "peridot/bin/ledger/app/merging/merge_strategy.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-// Strategy for merging commits using the CUSTOM policy.
-class CustomMergeStrategy : public MergeStrategy {
- public:
- explicit CustomMergeStrategy(ConflictResolverPtr conflict_resolver);
- ~CustomMergeStrategy() override;
-
- // MergeStrategy:
- void SetOnError(fit::closure on_error) override;
-
- void Merge(storage::PageStorage* storage, PageManager* page_manager,
- std::unique_ptr<const storage::Commit> head_1,
- std::unique_ptr<const storage::Commit> head_2,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback) override;
-
- void Cancel() override;
-
- private:
- fit::closure on_error_;
-
- ConflictResolverPtr conflict_resolver_;
-
- std::unique_ptr<ConflictResolverClient> in_progress_merge_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(CustomMergeStrategy);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_CUSTOM_MERGE_STRATEGY_H_
diff --git a/bin/ledger/app/merging/last_one_wins_merge_strategy.cc b/bin/ledger/app/merging/last_one_wins_merge_strategy.cc
deleted file mode 100644
index da56323..0000000
--- a/bin/ledger/app/merging/last_one_wins_merge_strategy.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/last_one_wins_merge_strategy.h"
-
-#include <memory>
-#include <string>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-
-namespace ledger {
-
-class LastOneWinsMergeStrategy::LastOneWinsMerger {
- public:
- LastOneWinsMerger(storage::PageStorage* storage,
- std::unique_ptr<const storage::Commit> left,
- std::unique_ptr<const storage::Commit> right,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback);
- ~LastOneWinsMerger();
-
- void Start();
- void Cancel();
-
- private:
- void Done(Status status);
- void BuildAndCommitJournal();
-
- storage::PageStorage* const storage_;
-
- std::unique_ptr<const storage::Commit> const left_;
- std::unique_ptr<const storage::Commit> const right_;
- std::unique_ptr<const storage::Commit> const ancestor_;
-
- fit::function<void(Status)> callback_;
-
- std::unique_ptr<storage::Journal> journal_;
- bool cancelled_ = false;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<LastOneWinsMerger> weak_factory_;
-};
-
-LastOneWinsMergeStrategy::LastOneWinsMerger::LastOneWinsMerger(
- storage::PageStorage* storage, std::unique_ptr<const storage::Commit> left,
- std::unique_ptr<const storage::Commit> right,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback)
- : storage_(storage),
- left_(std::move(left)),
- right_(std::move(right)),
- ancestor_(std::move(ancestor)),
- callback_(std::move(callback)),
- weak_factory_(this) {
- FXL_DCHECK(callback_);
-}
-
-LastOneWinsMergeStrategy::LastOneWinsMerger::~LastOneWinsMerger() {
- if (journal_) {
- storage_->RollbackJournal(std::move(journal_),
- [](storage::Status /*status*/) {});
- }
-}
-
-void LastOneWinsMergeStrategy::LastOneWinsMerger::Start() {
- storage_->StartMergeCommit(
- left_->GetId(), right_->GetId(),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this](storage::Status s, std::unique_ptr<storage::Journal> journal) {
- if (cancelled_ || s != storage::Status::OK) {
- Done(cancelled_ ? Status::INTERNAL_ERROR
- : PageUtils::ConvertStatus(s));
- return;
- }
- journal_ = std::move(journal);
- BuildAndCommitJournal();
- }));
-}
-
-void LastOneWinsMergeStrategy::LastOneWinsMerger::Cancel() {
- cancelled_ = true;
- if (journal_) {
- storage_->RollbackJournal(std::move(journal_),
- [](storage::Status /*status*/) {});
- journal_.reset();
- }
-}
-
-void LastOneWinsMergeStrategy::LastOneWinsMerger::Done(Status status) {
- auto callback = std::move(callback_);
- callback_ = nullptr;
- callback(status);
-}
-
-void LastOneWinsMergeStrategy::LastOneWinsMerger::BuildAndCommitJournal() {
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<storage::Status>>(
- storage::Status::OK);
- auto on_next = [weak_this = weak_factory_.GetWeakPtr(),
- waiter = waiter.get()](storage::EntryChange change) {
- if (!weak_this || weak_this->cancelled_) {
- // No need to call Done, as it will be called in the on_done callback.
- return false;
- }
- const std::string& key = change.entry.key;
- if (change.deleted) {
- weak_this->journal_->Delete(key, waiter->NewCallback());
- } else {
- weak_this->journal_->Put(key, change.entry.object_identifier,
- change.entry.priority, waiter->NewCallback());
- }
- return true;
- };
-
- auto on_diff_done = [weak_this = weak_factory_.GetWeakPtr(),
- waiter = std::move(waiter)](storage::Status s) {
- if (!weak_this) {
- return;
- }
- if (weak_this->cancelled_) {
- weak_this->Done(Status::INTERNAL_ERROR);
- return;
- }
- if (s != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to create diff for merging: " << s;
- weak_this->Done(PageUtils::ConvertStatus(s));
- return;
- }
- waiter->Finalize([weak_this](storage::Status s) {
- if (!weak_this) {
- return;
- }
- if (weak_this->cancelled_) {
- weak_this->Done(Status::INTERNAL_ERROR);
- return;
- }
- if (s != storage::Status::OK) {
- FXL_LOG(ERROR) << "Error while merging commits: " << s;
- weak_this->Done(PageUtils::ConvertStatus(s));
- return;
- }
- weak_this->storage_->CommitJournal(
- std::move(weak_this->journal_),
- [weak_this](storage::Status s,
- std::unique_ptr<const storage::Commit>) {
- if (s != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to commit merge journal: " << s;
- }
- if (weak_this) {
- weak_this->Done(
- PageUtils::ConvertStatus(s, Status::INTERNAL_ERROR));
- }
- });
- });
- };
- storage_->GetCommitContentsDiff(*(ancestor_), *(right_), "",
- std::move(on_next), std::move(on_diff_done));
-}
-
-LastOneWinsMergeStrategy::LastOneWinsMergeStrategy() {}
-
-LastOneWinsMergeStrategy::~LastOneWinsMergeStrategy() {}
-
-void LastOneWinsMergeStrategy::SetOnError(fit::function<void()> /*on_error*/) {}
-
-void LastOneWinsMergeStrategy::Merge(
- storage::PageStorage* storage, PageManager* /*page_manager*/,
- std::unique_ptr<const storage::Commit> head_1,
- std::unique_ptr<const storage::Commit> head_2,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback) {
- FXL_DCHECK(!in_progress_merge_);
- FXL_DCHECK(head_1->GetTimestamp() <= head_2->GetTimestamp());
-
- in_progress_merge_ =
- std::make_unique<LastOneWinsMergeStrategy::LastOneWinsMerger>(
- storage, std::move(head_1), std::move(head_2), std::move(ancestor),
- [this, callback = std::move(callback)](Status status) {
- in_progress_merge_.reset();
- callback(status);
- });
-
- in_progress_merge_->Start();
-}
-
-void LastOneWinsMergeStrategy::Cancel() {
- if (in_progress_merge_) {
- in_progress_merge_->Cancel();
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/merging/last_one_wins_merge_strategy.h b/bin/ledger/app/merging/last_one_wins_merge_strategy.h
deleted file mode 100644
index 905600e..0000000
--- a/bin/ledger/app/merging/last_one_wins_merge_strategy.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_LAST_ONE_WINS_MERGE_STRATEGY_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_LAST_ONE_WINS_MERGE_STRATEGY_H_
-
-#include <memory>
-
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/app/merging/merge_strategy.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-// Strategy for merging commits using a last-one-wins policy for conflicts.
-// Commits are merged key-by-key. When a key has been modified on both sides,
-// the value from the most recent commit is used.
-class LastOneWinsMergeStrategy : public MergeStrategy {
- public:
- LastOneWinsMergeStrategy();
- ~LastOneWinsMergeStrategy() override;
-
- void SetOnError(fit::function<void()> on_error) override;
-
- void Merge(storage::PageStorage* storage, PageManager* page_manager,
- std::unique_ptr<const storage::Commit> head_1,
- std::unique_ptr<const storage::Commit> head_2,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback) override;
-
- void Cancel() override;
-
- private:
- class LastOneWinsMerger;
-
- std::unique_ptr<LastOneWinsMerger> in_progress_merge_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_LAST_ONE_WINS_MERGE_STRATEGY_H_
diff --git a/bin/ledger/app/merging/ledger_merge_manager.cc b/bin/ledger/app/merging/ledger_merge_manager.cc
deleted file mode 100644
index 32fc88e..0000000
--- a/bin/ledger/app/merging/ledger_merge_manager.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/ledger_merge_manager.h"
-
-#include <memory>
-#include <string>
-
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/app/merging/auto_merge_strategy.h"
-#include "peridot/bin/ledger/app/merging/custom_merge_strategy.h"
-#include "peridot/bin/ledger/app/merging/last_one_wins_merge_strategy.h"
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-
-namespace ledger {
-
-class LedgerMergeManager::ConflictResolverFactoryPtrContainer {
- public:
- explicit ConflictResolverFactoryPtrContainer(
- fidl::InterfaceHandle<ConflictResolverFactory> factory)
- : ptr_(factory.Bind()) {
- ptr_.set_error_handler([this](zx_status_t status) { OnEmpty(); });
- }
-
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- // Returns the pointer and disappear from the AutoCleanableMap
- ConflictResolverFactoryPtr TakePtr() {
- ConflictResolverFactoryPtr ptr = std::move(ptr_);
- ptr.set_error_handler(nullptr);
- // Deletes |this|
- OnEmpty();
- return ptr;
- }
-
- private:
- // Deletes the object when in an AutoCleanableMap
- void OnEmpty() {
- if (on_empty_callback_)
- on_empty_callback_();
- }
-
- ConflictResolverFactoryPtr ptr_;
- fit::closure on_empty_callback_;
-};
-
-LedgerMergeManager::LedgerMergeManager(Environment* environment)
- : environment_(environment) {}
-
-LedgerMergeManager::~LedgerMergeManager() {}
-
-void LedgerMergeManager::AddFactory(
- fidl::InterfaceHandle<ConflictResolverFactory> factory) {
- using_default_conflict_resolver_ = false;
-
- conflict_resolver_factories_.emplace(std::move(factory));
-
- if (!current_conflict_resolver_factory_) {
- ResetFactory();
- }
-}
-
-void LedgerMergeManager::ResetFactory() {
- if (conflict_resolver_factories_.empty())
- return;
-
- current_conflict_resolver_factory_ =
- conflict_resolver_factories_.begin()->TakePtr();
- current_conflict_resolver_factory_.set_error_handler(
- [this](zx_status_t status) { this->ResetFactory(); });
-
- for (const auto& item : resolvers_) {
- item.second->SetMergeStrategy(nullptr);
- GetResolverStrategyForPage(
- item.first, [this, page_id = item.first](
- std::unique_ptr<MergeStrategy> strategy) mutable {
- if (resolvers_.find(page_id) != resolvers_.end()) {
- resolvers_[page_id]->SetMergeStrategy(std::move(strategy));
- }
- });
- }
-}
-
-void LedgerMergeManager::RemoveResolver(const storage::PageId& page_id) {
- resolvers_.erase(page_id);
-}
-
-std::unique_ptr<MergeResolver> LedgerMergeManager::GetMergeResolver(
- storage::PageStorage* storage) {
- storage::PageId page_id = storage->GetId();
- std::unique_ptr<MergeResolver> resolver = std::make_unique<MergeResolver>(
- [this, page_id]() { RemoveResolver(page_id); }, environment_, storage,
- std::make_unique<backoff::ExponentialBackoff>(
- zx::msec(10), 2u, zx::sec(60 * 60),
- environment_->random()->NewBitGenerator<uint64_t>()));
- resolvers_[page_id] = resolver.get();
- GetResolverStrategyForPage(
- page_id,
- [this, page_id](std::unique_ptr<MergeStrategy> strategy) mutable {
- if (resolvers_.find(page_id) != resolvers_.end()) {
- resolvers_[page_id]->SetMergeStrategy(std::move(strategy));
- }
- });
- return resolver;
-}
-
-void LedgerMergeManager::GetResolverStrategyForPage(
- const storage::PageId& page_id,
- fit::function<void(std::unique_ptr<MergeStrategy>)> strategy_callback) {
- if (using_default_conflict_resolver_) {
- strategy_callback(std::make_unique<LastOneWinsMergeStrategy>());
- } else if (!current_conflict_resolver_factory_) {
- // When no |ConflictResolverFactory| is connected, no conflict resolution
- // happens for pages where conflict resolution has not been setup.
- // Conflict resolution continues for pages that already have a policy.
- } else {
- PageId converted_page_id;
- convert::ToArray(page_id, &converted_page_id.id);
- current_conflict_resolver_factory_->GetPolicy(
- converted_page_id,
- [this, page_id, converted_page_id,
- strategy_callback = std::move(strategy_callback)](MergePolicy policy) {
- switch (policy) {
- case MergePolicy::LAST_ONE_WINS:
- strategy_callback(std::make_unique<LastOneWinsMergeStrategy>());
- break;
- case MergePolicy::AUTOMATIC_WITH_FALLBACK: {
- ConflictResolverPtr conflict_resolver;
- current_conflict_resolver_factory_->NewConflictResolver(
- converted_page_id, conflict_resolver.NewRequest());
- std::unique_ptr<AutoMergeStrategy> auto_merge_strategy =
- std::make_unique<AutoMergeStrategy>(
- std::move(conflict_resolver));
- auto_merge_strategy->SetOnError(
- [this, page_id]() { ResetStrategyForPage(page_id); });
- strategy_callback(std::move(auto_merge_strategy));
- break;
- }
- case MergePolicy::CUSTOM: {
- PageId converted_page_id;
- convert::ToArray(page_id, &converted_page_id.id);
- ConflictResolverPtr conflict_resolver;
- current_conflict_resolver_factory_->NewConflictResolver(
- converted_page_id, conflict_resolver.NewRequest());
- std::unique_ptr<CustomMergeStrategy> custom_merge_strategy =
- std::make_unique<CustomMergeStrategy>(
- std::move(conflict_resolver));
- custom_merge_strategy->SetOnError(
- [this, page_id]() { ResetStrategyForPage(page_id); });
- strategy_callback(std::move(custom_merge_strategy));
- break;
- }
- }
- });
- }
-}
-
-void LedgerMergeManager::ResetStrategyForPage(storage::PageId page_id) {
- if (resolvers_.find(page_id) == resolvers_.end()) {
- return;
- }
- resolvers_[page_id]->SetMergeStrategy(nullptr);
- GetResolverStrategyForPage(
- page_id,
- [this, page_id](std::unique_ptr<MergeStrategy> strategy) mutable {
- if (resolvers_.find(page_id) != resolvers_.end()) {
- resolvers_[page_id]->SetMergeStrategy(std::move(strategy));
- }
- });
-}
-} // namespace ledger
diff --git a/bin/ledger/app/merging/ledger_merge_manager.h b/bin/ledger/app/merging/ledger_merge_manager.h
deleted file mode 100644
index dbddb45..0000000
--- a/bin/ledger/app/merging/ledger_merge_manager.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_LEDGER_MERGE_MANAGER_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_LEDGER_MERGE_MANAGER_H_
-
-#include <map>
-#include <memory>
-
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-
-// Manages the strategies for handling merges and conflicts for a ledger as
-// managed by |LedgerManager|.
-// Holds a ConflictResolverFactory if the client provides one.
-// |LedgerMergeManager| must outlive all MergeResolver it provides.
-class LedgerMergeManager {
- public:
- explicit LedgerMergeManager(Environment* environment);
- ~LedgerMergeManager();
-
- void AddFactory(fidl::InterfaceHandle<ConflictResolverFactory> factory);
-
- std::unique_ptr<MergeResolver> GetMergeResolver(
- storage::PageStorage* storage);
-
- private:
- void ResetFactory();
- void RemoveResolver(const storage::PageId& page_id);
- void GetResolverStrategyForPage(
- const storage::PageId& page_id,
- fit::function<void(std::unique_ptr<MergeStrategy>)> strategy_callback);
- void ResetStrategyForPage(storage::PageId page_id);
-
- Environment* const environment_;
-
- class ConflictResolverFactoryPtrContainer;
-
- // Inactive, available conflict resolver factories
- callback::AutoCleanableSet<ConflictResolverFactoryPtrContainer>
- conflict_resolver_factories_;
- // The ConflictResolverFactory that is currently in use
- fidl::InterfacePtr<ConflictResolverFactory>
- current_conflict_resolver_factory_;
- // |true| if using the default last-one-wins conflict resolver factory
- bool using_default_conflict_resolver_ = true;
-
- std::map<storage::PageId, MergeResolver*> resolvers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerMergeManager);
-};
-} // namespace ledger
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_LEDGER_MERGE_MANAGER_H_
diff --git a/bin/ledger/app/merging/merge_resolver.cc b/bin/ledger/app/merging/merge_resolver.cc
deleted file mode 100644
index b8d0268..0000000
--- a/bin/ledger/app/merging/merge_resolver.cc
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-
-#include <algorithm>
-#include <memory>
-#include <queue>
-#include <set>
-#include <utility>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/trace_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/app/merging/common_ancestor.h"
-#include "peridot/bin/ledger/app/merging/ledger_merge_manager.h"
-#include "peridot/bin/ledger/app/merging/merge_strategy.h"
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/cobalt/cobalt.h"
-
-namespace ledger {
-
-// Enumerates merge candidates' indexes among current head commits.
-class MergeResolver::MergeCandidates {
- public:
- MergeCandidates();
-
- // Resets the MergeCandidates and sets the total number of head commits to
- // |head_count|.
- void ResetCandidates(size_t head_count);
-
- // Returns whether MergeCandidates should be reset. A reset is necessary
- // when the head commits have changed, i.e. when there is a successful merge
- // or on a new commit.
- bool NeedsReset() { return needs_reset_; }
-
- // Returns the current pair on indexes of head commits to be merged.
- std::pair<size_t, size_t> GetCurrentPair();
-
- // Returns whether there is a merge candidate pair available.
- bool HasCandidate();
-
- // Returns true if there was a network error in one of the previous merge
- // attempts. This does not include merges before |ResetCandidates| was
- // called.
- bool HadNetworkErrors() { return had_network_errors_; }
-
- // Should be called after a successful merge.
- void OnMergeSuccess();
-
- // Should be called after an unsuccessful merge.
- void OnMergeError(Status status);
-
- // Should be called when new commits are available.
- void OnNewCommits();
-
- // Returns the number of head commits.
- size_t head_count() { return head_count_; }
-
- private:
- // Advances to the next available pair of merge candidates.
- void PrepareNext();
-
- size_t head_count_;
- std::pair<size_t, size_t> current_pair_;
- bool needs_reset_ = true;
- bool had_network_errors_ = false;
-};
-
-MergeResolver::MergeCandidates::MergeCandidates() {}
-
-void MergeResolver::MergeCandidates::ResetCandidates(size_t head_count) {
- head_count_ = head_count;
- current_pair_ = {0, 1};
- needs_reset_ = false;
- had_network_errors_ = false;
-}
-
-bool MergeResolver::MergeCandidates::HasCandidate() {
- return current_pair_.first != head_count_ - 1;
-}
-
-std::pair<size_t, size_t> MergeResolver::MergeCandidates::GetCurrentPair() {
- return current_pair_;
-}
-
-void MergeResolver::MergeCandidates::OnMergeSuccess() { needs_reset_ = true; }
-
-void MergeResolver::MergeCandidates::OnMergeError(Status status) {
- if (status == Status::NETWORK_ERROR) {
- // The contents of the common ancestor are unavailable locally and it wasn't
- // possible to retrieve them through the network: Ignore this pair of heads
- // for now.
- had_network_errors_ = true;
- PrepareNext();
- } else {
- FXL_LOG(WARNING) << "Merging failed. Will try again later.";
- }
-}
-
-void MergeResolver::MergeCandidates::OnNewCommits() { needs_reset_ = true; }
-
-void MergeResolver::MergeCandidates::PrepareNext() {
- ++current_pair_.second;
- if (current_pair_.second == head_count_) {
- ++current_pair_.first;
- current_pair_.second = current_pair_.first + 1;
- }
-}
-
-MergeResolver::MergeResolver(fit::closure on_destroyed,
- Environment* environment,
- storage::PageStorage* storage,
- std::unique_ptr<backoff::Backoff> backoff)
- : coroutine_service_(environment->coroutine_service()),
- storage_(storage),
- backoff_(std::move(backoff)),
- merge_candidates_(std::make_unique<MergeCandidates>()),
- on_destroyed_(std::move(on_destroyed)),
- task_runner_(environment->dispatcher()) {
- storage_->AddCommitWatcher(this);
- PostCheckConflicts(DelayedStatus::DONT_DELAY);
-}
-
-MergeResolver::~MergeResolver() {
- storage_->RemoveCommitWatcher(this);
- on_destroyed_();
-}
-
-void MergeResolver::set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
-}
-
-bool MergeResolver::IsEmpty() { return !merge_in_progress_; }
-
-bool MergeResolver::HasUnfinishedMerges() {
- return merge_in_progress_ || check_conflicts_in_progress_ ||
- check_conflicts_task_count_ != 0 || in_delay_ ||
- merge_candidates_->HadNetworkErrors();
-}
-
-void MergeResolver::SetMergeStrategy(std::unique_ptr<MergeStrategy> strategy) {
- if (merge_in_progress_) {
- FXL_DCHECK(strategy_);
- // The new strategy can be the empty strategy (nullptr), so we need a
- // separate boolean to know if we have a pending strategy change to make.
- has_next_strategy_ = true;
- next_strategy_ = std::move(strategy);
- strategy_->Cancel();
- return;
- }
- strategy_.swap(strategy);
- if (strategy_) {
- PostCheckConflicts(DelayedStatus::DONT_DELAY);
- }
-}
-
-void MergeResolver::SetPageManager(PageManager* page_manager) {
- FXL_DCHECK(page_manager_ == nullptr);
- page_manager_ = page_manager;
-}
-
-void MergeResolver::RegisterNoConflictCallback(
- fit::function<void(ConflictResolutionWaitStatus)> callback) {
- no_conflict_callbacks_.push_back(std::move(callback));
-}
-
-void MergeResolver::OnNewCommits(
- const std::vector<std::unique_ptr<const storage::Commit>>& /*commits*/,
- storage::ChangeSource source) {
- merge_candidates_->OnNewCommits();
- PostCheckConflicts(source == storage::ChangeSource::LOCAL
- ? DelayedStatus::DONT_DELAY
- // We delay remote commits.
- : DelayedStatus::MAY_DELAY);
-}
-
-void MergeResolver::PostCheckConflicts(DelayedStatus delayed_status) {
- check_conflicts_task_count_++;
- task_runner_.PostTask([this, delayed_status] {
- check_conflicts_task_count_--;
- CheckConflicts(delayed_status);
- });
-}
-
-void MergeResolver::CheckConflicts(DelayedStatus delayed_status) {
- if (!strategy_ || merge_in_progress_ || check_conflicts_in_progress_ ||
- in_delay_) {
- // No strategy is set, or a merge is already in progress, or we are already
- // checking for conflicts, or we are delaying merges. Let's bail out early.
- return;
- }
- check_conflicts_in_progress_ = true;
- storage_->GetHeadCommitIds(task_runner_.MakeScoped(
- [this, delayed_status](storage::Status s,
- std::vector<storage::CommitId> heads) {
- check_conflicts_in_progress_ = false;
-
- if (merge_candidates_->NeedsReset()) {
- merge_candidates_->ResetCandidates(heads.size());
- }
- FXL_DCHECK(merge_candidates_->head_count() == heads.size())
- << merge_candidates_->head_count() << " != " << heads.size();
-
- if (s != storage::Status::OK || heads.size() == 1 ||
- !(merge_candidates_->HasCandidate())) {
- // An error occurred, or there is no conflict we can resolve. In
- // either case, return early.
- if (s != storage::Status::OK) {
- FXL_LOG(ERROR) << "Failed to get head commits with status " << s;
- } else if (heads.size() == 1) {
- for (auto& callback : no_conflict_callbacks_) {
- callback(has_merged_
- ? ConflictResolutionWaitStatus::CONFLICTS_RESOLVED
- : ConflictResolutionWaitStatus::NO_CONFLICTS);
- }
- no_conflict_callbacks_.clear();
- has_merged_ = false;
- }
- if (on_empty_callback_) {
- on_empty_callback_();
- }
- return;
- }
- if (!strategy_) {
- if (on_empty_callback_) {
- on_empty_callback_();
- }
- return;
- }
- merge_in_progress_ = true;
- std::pair<size_t, size_t> head_indexes =
- merge_candidates_->GetCurrentPair();
- ResolveConflicts(delayed_status, std::move(heads[head_indexes.first]),
- std::move(heads[head_indexes.second]));
- }));
-}
-
-void MergeResolver::ResolveConflicts(DelayedStatus delayed_status,
- storage::CommitId head1,
- storage::CommitId head2) {
- auto cleanup = fit::defer(task_runner_.MakeScoped([this, delayed_status] {
- // |merge_in_progress_| must be reset before calling
- // |on_empty_callback_|.
- merge_in_progress_ = false;
-
- if (has_next_strategy_) {
- strategy_ = std::move(next_strategy_);
- next_strategy_.reset();
- has_next_strategy_ = false;
- }
- PostCheckConflicts(delayed_status);
- // Call on_empty_callback_ at the very end as it might delete the
- // resolver.
- if (on_empty_callback_) {
- on_empty_callback_();
- }
- }));
- uint64_t id = TRACE_NONCE();
- TRACE_ASYNC_BEGIN("ledger", "merge", id);
- auto tracing = fit::defer([id] { TRACE_ASYNC_END("ledger", "merge", id); });
-
- auto waiter = fxl::MakeRefCounted<callback::Waiter<
- storage::Status, std::unique_ptr<const storage::Commit>>>(
- storage::Status::OK);
- storage_->GetCommit(head1, waiter->NewCallback());
- storage_->GetCommit(head2, waiter->NewCallback());
- waiter->Finalize(TRACE_CALLBACK(
- task_runner_.MakeScoped(
- [this, delayed_status, cleanup = std::move(cleanup),
- tracing = std::move(tracing)](
- storage::Status status,
- std::vector<std::unique_ptr<const storage::Commit>>
- commits) mutable {
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR)
- << "Failed to retrieve head commits. Status: " << status;
- return;
- }
- FXL_DCHECK(commits.size() == 2);
- FXL_DCHECK(commits[0]->GetTimestamp() <=
- commits[1]->GetTimestamp());
-
- if (commits[0]->GetParentIds().size() == 2 &&
- commits[1]->GetParentIds().size() == 2) {
- if (delayed_status == DelayedStatus::MAY_DELAY) {
- // If trying to merge 2 merge commits, add some delay with
- // exponential backoff.
- auto delay_callback = [this] {
- in_delay_ = false;
- CheckConflicts(DelayedStatus::DONT_DELAY);
- };
- in_delay_ = true;
- task_runner_.PostDelayedTask(
- TRACE_CALLBACK(std::move(delay_callback), "ledger",
- "merge_delay"),
- backoff_->GetNext());
- cleanup.cancel();
- merge_in_progress_ = false;
- // We don't want to continue merging if nobody is interested
- // (all clients disconnected).
- if (on_empty_callback_) {
- on_empty_callback_();
- }
- return;
- }
- // If delayed_status is not initial, report the merge.
- ReportEvent(CobaltEvent::MERGED_COMMITS_MERGED);
- } else {
- // No longer merging 2 merge commits, reinitialize the exponential
- // backoff.
- backoff_->Reset();
- }
-
- // Check if the 2 parents have the same content.
- if (commits[0]->GetRootIdentifier() ==
- commits[1]->GetRootIdentifier()) {
- // In that case, the result must be a commit with the same
- // content.
- MergeCommitsWithSameContent(
- std::move(commits[0]), std::move(commits[1]),
- [cleanup = std::move(cleanup), tracing = std::move(tracing)] {
- // Report the merge.
- ReportEvent(CobaltEvent::COMMITS_MERGED);
- });
- return;
- }
-
- // If the strategy has been changed, bail early.
- if (has_next_strategy_) {
- return;
- }
-
- // Merge the first two commits using the most recent one as the
- // base.
- FindCommonAncestorAndMerge(
- std::move(commits[0]), std::move(commits[1]),
- [cleanup = std::move(cleanup), tracing = std::move(tracing)] {
- ReportEvent(CobaltEvent::COMMITS_MERGED);
- });
- }),
- "ledger", "merge_get_commit_finalize"));
-}
-
-void MergeResolver::MergeCommitsWithSameContent(
- std::unique_ptr<const storage::Commit> head1,
- std::unique_ptr<const storage::Commit> head2,
- fit::closure on_successful_merge) {
- storage_->StartMergeCommit(
- head1->GetId(), head2->GetId(),
- TRACE_CALLBACK(
- task_runner_.MakeScoped(
- [this, on_successful_merge = std::move(on_successful_merge)](
- storage::Status status,
- std::unique_ptr<storage::Journal> journal) mutable {
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR)
- << "Unable to start merge commit for identical commits.";
- return;
- }
- has_merged_ = true;
- storage_->CommitJournal(
- std::move(journal),
- [on_successful_merge = std::move(on_successful_merge)](
- storage::Status status,
- std::unique_ptr<const storage::Commit>) {
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to merge identical commits.";
- return;
- }
- on_successful_merge();
- });
- }),
- "ledger", "merge_same_commit_journal"));
-}
-
-void MergeResolver::FindCommonAncestorAndMerge(
- std::unique_ptr<const storage::Commit> head1,
- std::unique_ptr<const storage::Commit> head2,
- fit::closure on_successful_merge) {
- FindCommonAncestor(
- coroutine_service_, storage_, head1->Clone(), head2->Clone(),
- TRACE_CALLBACK(
- task_runner_.MakeScoped(
- [this, head1 = std::move(head1), head2 = std::move(head2),
- on_successful_merge = std::move(on_successful_merge)](
- Status status, std::unique_ptr<const storage::Commit>
- common_ancestor) mutable {
- // If the strategy has been changed, bail early.
- if (has_next_strategy_) {
- return;
- }
-
- if (status != Status::OK) {
- FXL_LOG(ERROR)
- << "Failed to find common ancestor of head commits.";
- return;
- }
- auto strategy_callback =
- [this, on_successful_merge =
- std::move(on_successful_merge)](Status status) {
- if (status != Status::OK) {
- merge_candidates_->OnMergeError(status);
- return;
- }
- merge_candidates_->OnMergeSuccess();
- on_successful_merge();
- };
- has_merged_ = true;
- strategy_->Merge(
- storage_, page_manager_, std::move(head1), std::move(head2),
- std::move(common_ancestor),
- TRACE_CALLBACK(std::move(strategy_callback), "ledger",
- "merge_strategy_merge"));
- }),
- "ledger", "merge_find_common_ancestor"));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/merging/merge_resolver.h b/bin/ledger/app/merging/merge_resolver.h
deleted file mode 100644
index ac01c3c..0000000
--- a/bin/ledger/app/merging/merge_resolver.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_MERGE_RESOLVER_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_MERGE_RESOLVER_H_
-
-#include <vector>
-
-#include <lib/backoff/backoff.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-class PageManager;
-class MergeStrategy;
-
-// MergeResolver watches a page and resolves conflicts as they appear using the
-// provided merge strategy.
-class MergeResolver : public storage::CommitWatcher {
- public:
- MergeResolver(fit::closure on_destroyed, Environment* environment,
- storage::PageStorage* storage,
- std::unique_ptr<backoff::Backoff> backoff);
- ~MergeResolver() override;
-
- void set_on_empty(fit::closure on_empty_callback);
-
- // Returns true if no merge is currently in progress. Note that returning
- // true, does not mean that there are no pending conflicts.
- bool IsEmpty();
-
- // Returns true if a merge is pending or in progress. A merge is pending when
- // a merge is currently processed (|IsEmpty| returns false), but also when
- // checking for conflict, or when in backoff delay between merges.
- bool HasUnfinishedMerges();
-
- // Changes the current merge strategy. Any pending merge will be cancelled.
- void SetMergeStrategy(std::unique_ptr<MergeStrategy> strategy);
-
- void SetPageManager(PageManager* page_manager);
-
- // Adds an action to perform when all the pending conflicts are resolved
- // (once).
- void RegisterNoConflictCallback(
- fit::function<void(ConflictResolutionWaitStatus)> callback);
-
- private:
- class MergeCandidates;
-
- // DelayedStatus allows us to avoid merge storms (several devices battling
- // to merge branches but not agreeing). We use the following algorithm:
- // - Old (local or originally remote) changes are always merged right away.
- // Local changes do not pose any risk risk of storm, as you cannot storm with
- // yourself.
- // - When a remote change arrives, that is a merge of two merges, then we are
- // at risk of a merge storm. In that case, we delay.
- // - If we receive any new commit while we are delaying, these are not merged
- // right away; they are only merged after the delay.
- // - Once the delay is finished, we merge everything we know. Upload will not
- // happen until we finish merging all branches, so we don't risk amplifying a
- // storm while merging.
- // - If, after that, we still need to do a merge of a merge from remote
- // commits, then we delay again, but more (exponential backoff).
- // - We reset this backoff delay to its initial value once we see a non
- // merge-of-a-merge commit.
- enum class DelayedStatus {
- // Whatever the commits, we won't delay merging. Used for local commits.
- DONT_DELAY,
- // May delay
- MAY_DELAY,
- };
-
- // storage::CommitWatcher:
- void OnNewCommits(
- const std::vector<std::unique_ptr<const storage::Commit>>& commits,
- storage::ChangeSource source) override;
-
- void PostCheckConflicts(DelayedStatus delayed_status);
- void CheckConflicts(DelayedStatus delayed_status);
- void ResolveConflicts(DelayedStatus delayed_status, storage::CommitId head1,
- storage::CommitId head2);
- void MergeCommitsWithSameContent(std::unique_ptr<const storage::Commit> head1,
- std::unique_ptr<const storage::Commit> head2,
- fit::closure on_successful_merge);
- void FindCommonAncestorAndMerge(std::unique_ptr<const storage::Commit> head1,
- std::unique_ptr<const storage::Commit> head2,
- fit::closure on_successful_merge);
-
- coroutine::CoroutineService* coroutine_service_;
- storage::PageStorage* const storage_;
- std::unique_ptr<backoff::Backoff> backoff_;
- PageManager* page_manager_ = nullptr;
- std::unique_ptr<MergeStrategy> strategy_;
- std::unique_ptr<MergeStrategy> next_strategy_;
- bool has_next_strategy_ = false;
- // TODO(LE-384): Convert the fields below into a single enum to track the
- // state of this class.
- bool merge_in_progress_ = false;
- // True between the time we commit a merge and we check if there are more
- // conflicts. It is used to report to conflict callbacks (see
- // |no_conflict_callbacks_|) whether a conflict has been merged while waiting.
- bool has_merged_ = false;
- // Counts the number of currently pending |CheckConflict| tasks posted on the
- // run loop. We use a counter instead of a single flag as multiple
- // |CheckConflict| tasks could be pending at the same time.
- int check_conflicts_task_count_ = 0;
- bool check_conflicts_in_progress_ = false;
- bool in_delay_ = false;
- std::unique_ptr<MergeCandidates> merge_candidates_;
- fit::closure on_empty_callback_;
- fit::closure on_destroyed_;
- std::vector<fit::function<void(ConflictResolutionWaitStatus)>>
- no_conflict_callbacks_;
-
- // ScopedTaskRunner must be the last member of the class.
- callback::ScopedTaskRunner task_runner_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(MergeResolver);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_MERGE_RESOLVER_H_
diff --git a/bin/ledger/app/merging/merge_resolver_unittest.cc b/bin/ledger/app/merging/merge_resolver_unittest.cc
deleted file mode 100644
index a3ff9fa..0000000
--- a/bin/ledger/app/merging/merge_resolver_unittest.cc
+++ /dev/null
@@ -1,811 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-
-#include <string>
-#include <utility>
-
-#include <lib/async/cpp/task.h>
-#include <lib/backoff/testing/test_backoff.h>
-#include <lib/callback/cancellable_helper.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/macros.h>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/merging/last_one_wins_merge_strategy.h"
-#include "peridot/bin/ledger/app/merging/test_utils.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-namespace {
-
-using ::testing::UnorderedElementsAre;
-
-class FakePageStorageImpl : public storage::PageStorageEmptyImpl {
- public:
- FakePageStorageImpl(std::unique_ptr<storage::PageStorage> page_storage)
- : storage_(std::move(page_storage)) {}
-
- void MarkCommitContentsUnavailable(storage::CommitIdView commit_id) {
- removed_commit_ids_.insert(commit_id.ToString());
- }
-
- void GetHeadCommitIds(
- fit::function<void(storage::Status, std::vector<storage::CommitId>)>
- callback) override {
- storage_->GetHeadCommitIds(std::move(callback));
- }
-
- void GetCommit(storage::CommitIdView commit_id,
- fit::function<void(storage::Status,
- std::unique_ptr<const storage::Commit>)>
- callback) override {
- storage_->GetCommit(commit_id, std::move(callback));
- }
-
- storage::Status AddCommitWatcher(storage::CommitWatcher* watcher) override {
- return storage_->AddCommitWatcher(watcher);
- }
-
- storage::Status RemoveCommitWatcher(
- storage::CommitWatcher* watcher) override {
- return storage_->RemoveCommitWatcher(watcher);
- }
-
- void GetObject(storage::ObjectIdentifier object_identifier, Location location,
- fit::function<void(storage::Status,
- std::unique_ptr<const storage::Object>)>
- callback) override {
- storage_->GetObject(std::move(object_identifier), location,
- std::move(callback));
- }
-
- void StartCommit(
- const storage::CommitId& commit_id, storage::JournalType journal_type,
- fit::function<void(storage::Status, std::unique_ptr<storage::Journal>)>
- callback) override {
- storage_->StartCommit(commit_id, journal_type, std::move(callback));
- }
-
- void StartMergeCommit(
- const storage::CommitId& left, const storage::CommitId& right,
- fit::function<void(storage::Status, std::unique_ptr<storage::Journal>)>
- callback) override {
- storage_->StartMergeCommit(left, right, std::move(callback));
- }
-
- void CommitJournal(std::unique_ptr<storage::Journal> journal,
- fit::function<void(storage::Status,
- std::unique_ptr<const storage::Commit>)>
- callback) override {
- storage_->CommitJournal(std::move(journal), std::move(callback));
- }
-
- void RollbackJournal(std::unique_ptr<storage::Journal> journal,
- fit::function<void(storage::Status)> callback) override {
- storage_->RollbackJournal(std::move(journal), std::move(callback));
- }
-
- void AddObjectFromLocal(
- storage::ObjectType object_type,
- std::unique_ptr<storage::DataSource> data_source,
- fit::function<void(storage::Status, storage::ObjectIdentifier)> callback)
- override {
- storage_->AddObjectFromLocal(object_type, std::move(data_source),
- std::move(callback));
- }
-
- void GetCommitContents(
- const storage::Commit& commit, std::string min_key,
- fit::function<bool(storage::Entry)> on_next,
- fit::function<void(storage::Status)> on_done) override {
- storage_->GetCommitContents(commit, std::move(min_key), std::move(on_next),
- std::move(on_done));
- }
-
- void GetCommitContentsDiff(
- const storage::Commit& base_commit, const storage::Commit& other_commit,
- std::string min_key,
- fit::function<bool(storage::EntryChange)> on_next_diff,
- fit::function<void(storage::Status)> on_done) override {
- if (removed_commit_ids_.find(base_commit.GetId()) !=
- removed_commit_ids_.end() ||
- removed_commit_ids_.find(other_commit.GetId()) !=
- removed_commit_ids_.end()) {
- on_done(storage::Status::NOT_CONNECTED_ERROR);
- return;
- }
- storage_->GetCommitContentsDiff(base_commit, other_commit,
- std::move(min_key), std::move(on_next_diff),
- std::move(on_done));
- }
-
- private:
- std::set<storage::CommitId> removed_commit_ids_;
-
- std::unique_ptr<storage::PageStorage> storage_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakePageStorageImpl);
-};
-
-class RecordingTestStrategy : public MergeStrategy {
- public:
- RecordingTestStrategy() {}
- ~RecordingTestStrategy() override {}
- void SetOnError(fit::closure on_error) override {
- this->on_error = std::move(on_error);
- }
-
- void SetOnMerge(fit::closure on_merge) { on_merge_ = std::move(on_merge); }
-
- void Merge(storage::PageStorage* /*storage*/, PageManager* /*page_manager*/,
- std::unique_ptr<const storage::Commit> /*head_1*/,
- std::unique_ptr<const storage::Commit> /*head_2*/,
- std::unique_ptr<const storage::Commit> /*ancestor*/,
- fit::function<void(Status)> callback) override {
- this->callback = std::move(callback);
- merge_calls++;
- if (on_merge_) {
- on_merge_();
- }
- }
-
- void Cancel() override { cancel_calls++; }
-
- fit::closure on_error;
-
- fit::function<void(Status)> callback;
- uint32_t merge_calls = 0;
- uint32_t cancel_calls = 0;
-
- private:
- fit::closure on_merge_;
-};
-
-class MergeResolverTest : public TestWithPageStorage {
- public:
- MergeResolverTest() {}
- ~MergeResolverTest() override {}
-
- protected:
- storage::PageStorage* page_storage() override { return page_storage_.get(); }
-
- void SetUp() override {
- TestWithPageStorage::SetUp();
- std::unique_ptr<storage::PageStorage> storage;
- ASSERT_TRUE(CreatePageStorage(&storage));
- page_storage_ = std::make_unique<FakePageStorageImpl>(std::move(storage));
- }
-
- storage::CommitId CreateCommit(
- storage::CommitIdView parent_id,
- fit::function<void(storage::Journal*)> contents) {
- return CreateCommit(page_storage_.get(), parent_id, std::move(contents));
- }
-
- storage::CommitId CreateCommit(
- storage::PageStorage* storage, storage::CommitIdView parent_id,
- fit::function<void(storage::Journal*)> contents) {
- bool called;
- storage::Status status;
- std::unique_ptr<storage::Journal> journal;
- storage->StartCommit(
- parent_id.ToString(), storage::JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
-
- contents(journal.get());
- std::unique_ptr<const storage::Commit> commit;
- storage->CommitJournal(
- std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- return commit->GetId();
- }
-
- storage::CommitId CreateMergeCommit(
- storage::CommitIdView parent_id1, storage::CommitIdView parent_id2,
- fit::function<void(storage::Journal*)> contents) {
- return CreateMergeCommit(page_storage_.get(), parent_id1, parent_id2,
- std::move(contents));
- }
-
- storage::CommitId CreateMergeCommit(
- storage::PageStorage* storage, storage::CommitIdView parent_id1,
- storage::CommitIdView parent_id2,
- fit::function<void(storage::Journal*)> contents) {
- bool called;
- storage::Status status;
- std::unique_ptr<storage::Journal> journal;
- storage->StartMergeCommit(
- parent_id1.ToString(), parent_id2.ToString(),
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- contents(journal.get());
- storage::Status actual_status;
- std::unique_ptr<const storage::Commit> actual_commit;
- storage->CommitJournal(std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called),
- &actual_status, &actual_commit));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, actual_status);
- return actual_commit->GetId();
- }
-
- std::vector<storage::Entry> GetCommitContents(const storage::Commit& commit) {
- storage::Status status;
- std::vector<storage::Entry> result;
- auto on_next = [&result](storage::Entry e) {
- result.push_back(e);
- return true;
- };
- bool called;
- page_storage_->GetCommitContents(
- commit, "", std::move(on_next),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(storage::Status::OK, status);
- return result;
- }
-
- std::unique_ptr<FakePageStorageImpl> page_storage_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(MergeResolverTest);
-};
-
-TEST_F(MergeResolverTest, Empty) {
- // Set up conflict
- CreateCommit(storage::kFirstPageCommitId, AddKeyValueToJournal("foo", "bar"));
- CreateCommit(storage::kFirstPageCommitId, AddKeyValueToJournal("foo", "baz"));
- std::unique_ptr<LastOneWinsMergeStrategy> strategy =
- std::make_unique<LastOneWinsMergeStrategy>();
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- resolver.SetMergeStrategy(std::move(strategy));
- resolver.set_on_empty(QuitLoopClosure());
-
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
-
- RunLoopUntilIdle();
- EXPECT_TRUE(resolver.IsEmpty());
-
- ids.clear();
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(1u, ids.size());
-}
-
-class CapturingMergeStrategy : public MergeStrategy {
- public:
- CapturingMergeStrategy() {}
- ~CapturingMergeStrategy() override {}
-
- void SetOnError(fit::function<void()> /*on_error*/) override {}
-
- void Merge(storage::PageStorage* /*storage*/, PageManager* /*page_manager*/,
- std::unique_ptr<const storage::Commit> merge_head_1,
- std::unique_ptr<const storage::Commit> merge_head_2,
- std::unique_ptr<const storage::Commit> merge_ancestor,
- fit::function<void(Status)> merge_callback) override {
- head_1 = std::move(merge_head_1);
- head_2 = std::move(merge_head_2);
- ancestor = std::move(merge_ancestor);
- callback = std::move(merge_callback);
- }
-
- void Cancel() override{};
-
- std::unique_ptr<const storage::Commit> head_1;
- std::unique_ptr<const storage::Commit> head_2;
- std::unique_ptr<const storage::Commit> ancestor;
- fit::function<void(Status)> callback;
-
- private:
- FXL_DISALLOW_ASSIGN(CapturingMergeStrategy);
-};
-
-TEST_F(MergeResolverTest, CommonAncestor) {
- // Add commits forming the following history graph:
- // (root) -> (1) -> (2) -> (3)
- // \
- // -> (4) -> (5)
- storage::CommitId commit_1 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key1", "val1.0"));
- storage::CommitId commit_2 =
- CreateCommit(commit_1, AddKeyValueToJournal("key2", "val2.0"));
- storage::CommitId commit_3 =
- CreateCommit(commit_2, AddKeyValueToJournal("key3", "val3.0"));
- storage::CommitId commit_4 =
- CreateCommit(commit_2, DeleteKeyFromJournal("key1"));
- storage::CommitId commit_5 =
- CreateCommit(commit_4, AddKeyValueToJournal("key2", "val2.1"));
- RunLoopUntilIdle();
-
- // Set a merge strategy to capture the requested merge.
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- std::unique_ptr<CapturingMergeStrategy> strategy =
- std::make_unique<CapturingMergeStrategy>();
- auto strategy_ptr = strategy.get();
- resolver.SetMergeStrategy(std::move(strategy));
- RunLoopUntilIdle();
-
- // Verify that the strategy is asked to merge commits 5 and 3, with 2 as the
- // common ancestor.
- EXPECT_EQ(commit_3, strategy_ptr->head_1->GetId());
- EXPECT_EQ(commit_5, strategy_ptr->head_2->GetId());
- EXPECT_EQ(commit_2, strategy_ptr->ancestor->GetId());
-
- // Resolve the conflict.
- CreateMergeCommit(strategy_ptr->head_1->GetId(),
- strategy_ptr->head_2->GetId(),
- AddKeyValueToJournal("key_foo", "abc"));
- strategy_ptr->callback(Status::OK);
- strategy_ptr->callback = nullptr;
- RunLoopUntilIdle();
- EXPECT_TRUE(resolver.IsEmpty());
-}
-
-TEST_F(MergeResolverTest, LastOneWins) {
- // Set up conflict
- storage::CommitId commit_1 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key1", "val1.0"));
-
- storage::CommitId commit_2 =
- CreateCommit(commit_1, AddKeyValueToJournal("key2", "val2.0"));
-
- storage::CommitId commit_3 =
- CreateCommit(commit_2, AddKeyValueToJournal("key3", "val3.0"));
-
- storage::CommitId commit_4 =
- CreateCommit(commit_2, DeleteKeyFromJournal("key1"));
-
- storage::CommitId commit_5 =
- CreateCommit(commit_4, AddKeyValueToJournal("key2", "val2.1"));
-
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), commit_3));
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), commit_5));
-
- std::unique_ptr<LastOneWinsMergeStrategy> strategy =
- std::make_unique<LastOneWinsMergeStrategy>();
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- resolver.SetMergeStrategy(std::move(strategy));
- resolver.set_on_empty(callback::SetWhenCalled(&called));
-
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_TRUE(resolver.IsEmpty());
-
- ids.clear();
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(1u, ids.size());
-
- std::unique_ptr<const storage::Commit> commit;
- page_storage_->GetCommit(
- ids[0],
- ::callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- ASSERT_TRUE(commit);
-
- std::vector<storage::Entry> content_vector = GetCommitContents(*commit);
- // Entries are ordered by keys
- ASSERT_EQ(2u, content_vector.size());
- EXPECT_EQ("key2", content_vector[0].key);
- std::string value;
- EXPECT_TRUE(GetValue(content_vector[0].object_identifier, &value));
- EXPECT_EQ("val2.1", value);
- EXPECT_EQ("key3", content_vector[1].key);
- EXPECT_TRUE(GetValue(content_vector[1].object_identifier, &value));
- EXPECT_EQ("val3.0", value);
-}
-
-TEST_F(MergeResolverTest, LastOneWinsDiffNotAvailable) {
- // Set up conflict
- storage::CommitId commit_1 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key1", "val1.0"));
-
- storage::CommitId commit_2 =
- CreateCommit(commit_1, AddKeyValueToJournal("key2", "val2.0"));
-
- storage::CommitId commit_3 =
- CreateCommit(commit_2, AddKeyValueToJournal("key3", "val3.0"));
-
- storage::CommitId commit_4 =
- CreateCommit(commit_2, DeleteKeyFromJournal("key1"));
-
- storage::CommitId commit_5 =
- CreateCommit(commit_4, AddKeyValueToJournal("key2", "val2.1"));
-
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_THAT(ids, UnorderedElementsAre(commit_3, commit_5));
-
- page_storage_->MarkCommitContentsUnavailable(commit_2);
-
- std::unique_ptr<LastOneWinsMergeStrategy> strategy =
- std::make_unique<LastOneWinsMergeStrategy>();
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- resolver.SetMergeStrategy(std::move(strategy));
- resolver.set_on_empty(callback::SetWhenCalled(&called));
-
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_TRUE(resolver.IsEmpty());
- ids.clear();
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
-}
-
-TEST_F(MergeResolverTest, None) {
- // Set up conflict
- storage::CommitId commit_1 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key1", "val1.0"));
-
- storage::CommitId commit_2 =
- CreateCommit(commit_1, AddKeyValueToJournal("key2", "val2.0"));
-
- storage::CommitId commit_3 =
- CreateCommit(commit_2, AddKeyValueToJournal("key3", "val3.0"));
-
- storage::CommitId commit_4 =
- CreateCommit(commit_2, DeleteKeyFromJournal("key1"));
-
- storage::CommitId commit_5 =
- CreateCommit(commit_4, AddKeyValueToJournal("key2", "val2.1"));
-
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), commit_3));
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), commit_5));
-
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- resolver.set_on_empty(QuitLoopClosure());
- RunLoopUntilIdle();
- EXPECT_TRUE(resolver.IsEmpty());
- ids.clear();
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
-}
-
-TEST_F(MergeResolverTest, UpdateMidResolution) {
- // Set up conflict
- storage::CommitId commit_1 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key1", "val1.0"));
-
- storage::CommitId commit_2 =
- CreateCommit(commit_1, AddKeyValueToJournal("key2", "val2.0"));
-
- storage::CommitId commit_3 =
- CreateCommit(commit_1, AddKeyValueToJournal("key3", "val3.0"));
-
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), commit_2));
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), commit_3));
-
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- resolver.set_on_empty(callback::SetWhenCalled(&called));
- resolver.SetMergeStrategy(std::make_unique<LastOneWinsMergeStrategy>());
- async::PostTask(dispatcher(), [&resolver] {
- resolver.SetMergeStrategy(std::make_unique<LastOneWinsMergeStrategy>());
- });
-
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- EXPECT_TRUE(resolver.IsEmpty());
- ids.clear();
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(1u, ids.size());
-}
-
-// Merge of merges backoff is only triggered when commits are coming from sync.
-// To test this, we need to create conflicts and make it as if they are not
-// created locally. This is done by preventing commit notifications for new
-// commits, then issuing manually a commit notification "from sync". As this
-// implies using a fake PageStorage, we don't test the resolution itself, only
-// that backoff is triggered correctly.
-TEST_F(MergeResolverTest, WaitOnMergeOfMerges) {
- storage::fake::FakePageStorage page_storage(&environment_, "page_id");
-
- bool on_empty_called;
- auto backoff = std::make_unique<backoff::TestBackoff>();
- auto backoff_ptr = backoff.get();
- MergeResolver resolver([] {}, &environment_, &page_storage,
- std::move(backoff));
- resolver.set_on_empty(callback::SetWhenCalled(&on_empty_called));
- auto strategy = std::make_unique<RecordingTestStrategy>();
- strategy->SetOnMerge(QuitLoopClosure());
- resolver.SetMergeStrategy(std::move(strategy));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(on_empty_called);
-
- page_storage.SetDropCommitNotifications(true);
-
- // Set up conflict
- storage::CommitId commit_0 = CreateCommit(
- &page_storage, storage::kFirstPageCommitId, [](storage::Journal*) {});
-
- storage::CommitId commit_1 = CreateCommit(
- &page_storage, commit_0, AddKeyValueToJournal("key1", "val1.0"));
-
- storage::CommitId commit_2 = CreateCommit(
- &page_storage, commit_0, AddKeyValueToJournal("key1", "val1.0"));
-
- storage::CommitId commit_3 = CreateCommit(
- &page_storage, commit_0, AddKeyValueToJournal("key2", "val2.0"));
-
- storage::CommitId merge_1 =
- CreateMergeCommit(&page_storage, commit_1, commit_3,
- AddKeyValueToJournal("key3", "val3.0"));
-
- storage::CommitId merge_2 =
- CreateMergeCommit(&page_storage, commit_2, commit_3,
- AddKeyValueToJournal("key3", "val3.0"));
-
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage.GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), merge_1));
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), merge_2));
-
- page_storage.SetDropCommitNotifications(false);
-
- storage::CommitWatcher* watcher = &resolver;
- watcher->OnNewCommits({}, storage::ChangeSource::CLOUD);
-
- // Note we can't use "RunLoopUntilIdle()" because the FakePageStorage delays
- // before inserting tasks into the message loop.
- RunLoopFor(zx::sec(5));
-
- EXPECT_GT(backoff_ptr->get_next_count, 0);
-}
-
-TEST_F(MergeResolverTest, AutomaticallyMergeIdenticalCommits) {
- // Set up conflict
- storage::CommitId commit_1 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key1", "val1.0"));
-
- storage::CommitId commit_2 = CreateCommit(
- storage::kFirstPageCommitId, AddKeyValueToJournal("key1", "val1.0"));
-
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), commit_1));
- EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), commit_2));
-
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- resolver.set_on_empty(callback::SetWhenCalled(&called));
- auto merge_strategy = std::make_unique<RecordingTestStrategy>();
- auto merge_strategy_ptr = merge_strategy.get();
- resolver.SetMergeStrategy(std::move(merge_strategy));
-
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_TRUE(resolver.IsEmpty());
- ids.clear();
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(1u, ids.size());
- EXPECT_EQ(0u, merge_strategy_ptr->merge_calls);
-}
-
-TEST_F(MergeResolverTest, NoConflictCallback_ConflictsResolved) {
- // Set up conflict.
- CreateCommit(storage::kFirstPageCommitId, AddKeyValueToJournal("foo", "bar"));
- CreateCommit(storage::kFirstPageCommitId, AddKeyValueToJournal("foo", "baz"));
- std::unique_ptr<LastOneWinsMergeStrategy> strategy =
- std::make_unique<LastOneWinsMergeStrategy>();
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- resolver.SetMergeStrategy(std::move(strategy));
- resolver.set_on_empty(MakeQuitTaskOnce());
-
- bool called;
- storage::Status status;
- std::vector<storage::CommitId> ids;
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(2u, ids.size());
-
- size_t callback_calls = 0;
- auto conflicts_resolved_callback = [&resolver, &callback_calls]() {
- EXPECT_TRUE(resolver.IsEmpty());
- callback_calls++;
- };
- ConflictResolutionWaitStatus wait_status;
- resolver.RegisterNoConflictCallback(
- callback::Capture(conflicts_resolved_callback, &wait_status));
- resolver.RegisterNoConflictCallback(
- callback::Capture(conflicts_resolved_callback, &wait_status));
-
- // Check that the callback was called 2 times.
- RunLoopUntilIdle();
- EXPECT_TRUE(resolver.IsEmpty());
- EXPECT_EQ(2u, callback_calls);
- EXPECT_EQ(ConflictResolutionWaitStatus::CONFLICTS_RESOLVED, wait_status);
-
- ids.clear();
- page_storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(1u, ids.size());
-
- callback_calls = 0;
- CreateCommit(ids[0], AddKeyValueToJournal("foo", "baw"));
- CreateCommit(ids[0], AddKeyValueToJournal("foo", "bat"));
- RunLoopUntilIdle();
- EXPECT_TRUE(resolver.IsEmpty());
-
- // Check that callback wasn't called (callback queue cleared after all the
- // callbacks in it were called).
- RunLoopFor(zx::sec(10));
- EXPECT_EQ(0u, callback_calls);
-}
-
-TEST_F(MergeResolverTest, NoConflictCallback_NoConflicts) {
- CreateCommit(storage::kFirstPageCommitId, AddKeyValueToJournal("foo", "baz"));
- std::unique_ptr<LastOneWinsMergeStrategy> strategy =
- std::make_unique<LastOneWinsMergeStrategy>();
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- resolver.SetMergeStrategy(std::move(strategy));
- resolver.set_on_empty(MakeQuitTaskOnce());
-
- size_t callback_calls = 0;
- auto conflicts_resolved_callback = [&resolver, &callback_calls]() {
- EXPECT_TRUE(resolver.IsEmpty());
- callback_calls++;
- };
- ConflictResolutionWaitStatus wait_status;
- resolver.RegisterNoConflictCallback(
- callback::Capture(conflicts_resolved_callback, &wait_status));
-
- // Check that the callback was called 1 times.
- RunLoopUntilIdle();
- EXPECT_TRUE(resolver.IsEmpty());
- EXPECT_EQ(1u, callback_calls);
- EXPECT_EQ(ConflictResolutionWaitStatus::NO_CONFLICTS, wait_status);
-}
-
-TEST_F(MergeResolverTest, HasUnfinishedMerges) {
- MergeResolver resolver([] {}, &environment_, page_storage_.get(),
- std::make_unique<backoff::TestBackoff>());
- std::unique_ptr<CapturingMergeStrategy> strategy =
- std::make_unique<CapturingMergeStrategy>();
- auto strategy_ptr = strategy.get();
- resolver.SetMergeStrategy(std::move(strategy));
- RunLoopUntilIdle();
- EXPECT_FALSE(resolver.HasUnfinishedMerges());
-
- // Set up a conflict and verify that HasUnfinishedMerges() returns true.
- storage::CommitId commit_1 = CreateCommit(storage::kFirstPageCommitId,
- AddKeyValueToJournal("foo", "bar"));
- storage::CommitId commit_2 = CreateCommit(storage::kFirstPageCommitId,
- AddKeyValueToJournal("foo", "baz"));
- RunLoopUntilIdle();
- EXPECT_TRUE(resolver.HasUnfinishedMerges());
-
- // Resolve the conflict and verify that HasUnfinishedMerges() returns false.
- ASSERT_TRUE(strategy_ptr->head_1);
- ASSERT_TRUE(strategy_ptr->head_2);
- ASSERT_TRUE(strategy_ptr->ancestor);
- ASSERT_TRUE(strategy_ptr->callback);
- CreateMergeCommit(strategy_ptr->head_1->GetId(),
- strategy_ptr->head_2->GetId(),
- AddKeyValueToJournal("key3", "val3.0"));
- strategy_ptr->callback(Status::OK);
- strategy_ptr->callback = nullptr;
- RunLoopUntilIdle();
- EXPECT_FALSE(resolver.HasUnfinishedMerges());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/merging/merge_strategy.h b/bin/ledger/app/merging/merge_strategy.h
deleted file mode 100644
index 78a4069..0000000
--- a/bin/ledger/app/merging/merge_strategy.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_MERGE_STRATEGY_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_MERGE_STRATEGY_H_
-
-#include <memory>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-class PageManager;
-
-// Interface for a merge algorithm.
-class MergeStrategy {
- public:
- MergeStrategy() {}
- virtual ~MergeStrategy() {}
-
- // Sets a callback that will be called if this strategy is not to be used
- // anymore, for instance when the underlying merge mechanism is no longer
- // available. This callback should not delete the strategy if there are merges
- // in progress.
- virtual void SetOnError(fit::function<void()> on_error) = 0;
-
- // Merge the given commits. head_1.timesteamp must be less or equals to
- // head_2.timestamp. MergeStrategy should not be deleted while merges are in
- // progress.
- virtual void Merge(storage::PageStorage* storage, PageManager* page_manager,
- std::unique_ptr<const storage::Commit> head_1,
- std::unique_ptr<const storage::Commit> head_2,
- std::unique_ptr<const storage::Commit> ancestor,
- fit::function<void(Status)> callback) = 0;
-
- // Cancel an in-progress merge. This must be called after |Merge| has been
- // called, and before the |on_done| callback.
- virtual void Cancel() = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(MergeStrategy);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_MERGE_STRATEGY_H_
diff --git a/bin/ledger/app/merging/test_utils.cc b/bin/ledger/app/merging/test_utils.cc
deleted file mode 100644
index c82dbd3..0000000
--- a/bin/ledger/app/merging/test_utils.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/merging/test_utils.h"
-
-#include <lib/async/dispatcher.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/impl/leveldb.h"
-#include "peridot/bin/ledger/storage/impl/page_storage_impl.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace ledger {
-
-TestWithPageStorage::TestWithPageStorage()
- : encryption_service_(dispatcher()) {}
-
-TestWithPageStorage::~TestWithPageStorage() {}
-
-fit::function<void(storage::Journal*)>
-TestWithPageStorage::AddKeyValueToJournal(const std::string& key,
- std::string value) {
- return [this, key,
- value = std::move(value)](storage::Journal* journal) mutable {
- storage::Status status;
- storage::ObjectIdentifier object_identifier;
- bool called;
- page_storage()->AddObjectFromLocal(
- storage::ObjectType::BLOB,
- storage::DataSource::Create(std::move(value)),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
-
- journal->Put(key, object_identifier, storage::KeyPriority::EAGER,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- };
-}
-
-fit::function<void(storage::Journal*)>
-TestWithPageStorage::DeleteKeyFromJournal(const std::string& key) {
- return [this, key](storage::Journal* journal) {
- storage::Status status;
- bool called;
- journal->Delete(
- key, callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- };
-}
-
-::testing::AssertionResult TestWithPageStorage::GetValue(
- storage::ObjectIdentifier object_identifier, std::string* value) {
- storage::Status status;
- std::unique_ptr<const storage::Object> object;
- bool called;
- page_storage()->GetObject(
- std::move(object_identifier), storage::PageStorage::Location::LOCAL,
- callback::Capture(callback::SetWhenCalled(&called), &status, &object));
- RunLoopUntilIdle();
- if (!called) {
- return ::testing::AssertionFailure()
- << "PageStorage::GetObject never called the callback.";
- }
- if (status != storage::Status::OK) {
- return ::testing::AssertionFailure()
- << "PageStorage::GetObject returned status: " << status;
- }
-
- fxl::StringView data;
- status = object->GetData(&data);
- if (status != storage::Status::OK) {
- return ::testing::AssertionFailure()
- << "Object::GetData returned status: " << status;
- }
-
- *value = data.ToString();
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult TestWithPageStorage::CreatePageStorage(
- std::unique_ptr<storage::PageStorage>* page_storage) {
- auto db = std::make_unique<storage::LevelDb>(environment_.dispatcher(),
- DetachedPath(tmpfs_.root_fd()));
- storage::Status status = db->Init();
- if (status != storage::Status::OK) {
- return ::testing::AssertionFailure()
- << "LevelDb::Init failed with status " << status;
- }
- auto local_page_storage = std::make_unique<storage::PageStorageImpl>(
- &environment_, &encryption_service_, std::move(db),
- kRootPageId.ToString());
-
- bool called;
- local_page_storage->Init(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- if (!called) {
- return ::testing::AssertionFailure()
- << "PageStorage::Init never called the callback.";
- }
-
- if (status != storage::Status::OK) {
- return ::testing::AssertionFailure()
- << "PageStorageImpl::Init returned status: " << status;
- }
- *page_storage = std::move(local_page_storage);
- return ::testing::AssertionSuccess();
-}
-
-fit::closure TestWithPageStorage::MakeQuitTaskOnce() {
- return [this, called = false]() mutable {
- if (!called) {
- called = true;
- QuitLoop();
- }
- };
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/merging/test_utils.h b/bin/ledger/app/merging/test_utils.h
deleted file mode 100644
index ea76078..0000000
--- a/bin/ledger/app/merging/test_utils.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_MERGING_TEST_UTILS_H_
-#define PERIDOT_BIN_LEDGER_APP_MERGING_TEST_UTILS_H_
-
-#include <functional>
-#include <memory>
-
-#include <lib/backoff/backoff.h>
-#include <lib/fit/function.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/public/journal.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-
-class TestWithPageStorage : public TestWithEnvironment {
- public:
- TestWithPageStorage();
- ~TestWithPageStorage() override;
-
- protected:
- virtual storage::PageStorage* page_storage() = 0;
-
- // Returns a function that, when executed, adds the provided key and object to
- // a journal.
- fit::function<void(storage::Journal*)> AddKeyValueToJournal(
- const std::string& key, std::string value);
-
- // Returns a function that, when executed, deleted the provided key from a
- // journal.
- fit::function<void(storage::Journal*)> DeleteKeyFromJournal(
- const std::string& key);
-
- ::testing::AssertionResult GetValue(
- storage::ObjectIdentifier object_identifier, std::string* value);
-
- ::testing::AssertionResult CreatePageStorage(
- std::unique_ptr<storage::PageStorage>* page_storage);
-
- fit::closure MakeQuitTaskOnce();
-
- private:
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- encryption::FakeEncryptionService encryption_service_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_MERGING_TEST_UTILS_H_
diff --git a/bin/ledger/app/page_delaying_facade.cc b/bin/ledger/app/page_delaying_facade.cc
deleted file mode 100644
index 4ce0b4c..0000000
--- a/bin/ledger/app/page_delaying_facade.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_delaying_facade.h"
-
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-PageDelayingFacade::PageDelayingFacade(storage::PageIdView page_id,
- fidl::InterfaceRequest<Page> request)
- : interface_(this) {
- convert::ToArray(page_id, &page_id_.id);
-
- interface_.set_on_empty([this] {
- if (on_empty_callback_) {
- on_empty_callback_();
- }
- });
- interface_.Bind(std::move(request));
-}
-
-void PageDelayingFacade::SetPageDelegate(PageDelegate* page_delegate) {
- delaying_facade_.SetTargetObject(page_delegate);
-}
-
-bool PageDelayingFacade::IsEmpty() { return !interface_.is_bound(); }
-
-void PageDelayingFacade::GetId(Page::GetIdCallback callback) {
- callback(page_id_);
-}
-
-void PageDelayingFacade::GetSnapshot(
- fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- std::vector<uint8_t> key_prefix,
- fidl::InterfaceHandle<PageWatcher> watcher,
- Page::GetSnapshotCallback callback) {
- delaying_facade_.EnqueueCall(
- &PageDelegate::GetSnapshot, std::move(snapshot_request),
- std::move(key_prefix), std::move(watcher), std::move(callback));
-}
-
-void PageDelayingFacade::Put(std::vector<uint8_t> key,
- std::vector<uint8_t> value,
- Page::PutCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::Put, std::move(key),
- std::move(value), std::move(callback));
-}
-
-void PageDelayingFacade::PutWithPriority(
- std::vector<uint8_t> key, std::vector<uint8_t> value,
- Priority priority, Page::PutWithPriorityCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::PutWithPriority, std::move(key),
- std::move(value), priority, std::move(callback));
-}
-
-void PageDelayingFacade::PutReference(std::vector<uint8_t> key,
- Reference reference, Priority priority,
- Page::PutReferenceCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::PutReference, std::move(key),
- std::move(reference), priority,
- std::move(callback));
-}
-
-void PageDelayingFacade::Delete(std::vector<uint8_t> key,
- Page::DeleteCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::Delete, std::move(key),
- std::move(callback));
-}
-
-void PageDelayingFacade::Clear(Page::ClearCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::Clear, std::move(callback));
-}
-
-void PageDelayingFacade::CreateReference(
- std::unique_ptr<storage::DataSource> data,
- fit::function<void(Status, ReferencePtr)> callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::CreateReference, std::move(data),
- std::move(callback));
-}
-
-void PageDelayingFacade::StartTransaction(
- Page::StartTransactionCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::StartTransaction,
- std::move(callback));
-}
-
-void PageDelayingFacade::Commit(Page::CommitCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::Commit, std::move(callback));
-}
-
-void PageDelayingFacade::Rollback(Page::RollbackCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::Rollback, std::move(callback));
-}
-
-void PageDelayingFacade::SetSyncStateWatcher(
- fidl::InterfaceHandle<SyncWatcher> watcher,
- Page::SetSyncStateWatcherCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::SetSyncStateWatcher,
- std::move(watcher), std::move(callback));
-}
-
-void PageDelayingFacade::WaitForConflictResolution(
- Page::WaitForConflictResolutionCallback callback) {
- delaying_facade_.EnqueueCall(&PageDelegate::WaitForConflictResolution,
- std::move(callback));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_delaying_facade.h b/bin/ledger/app/page_delaying_facade.h
deleted file mode 100644
index 424ad89..0000000
--- a/bin/ledger/app/page_delaying_facade.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_DELAYING_FACADE_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_DELAYING_FACADE_H_
-
-#include "peridot/bin/ledger/app/delaying_facade.h"
-#include "peridot/bin/ledger/app/page_delegate.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-// A handler for all calls to methods from the |Page| interface.
-//
-// |PageDelayingFacade| owns PageImpl. It makes sure that |Page::GetId| can be
-// answered immediately after the page is bound, but also that all other methods
-// are queued until the page initialization is complete.
-//
-// On |Page| request, a |PageDelayingFacade| should immediately be created and
-// |BindPage| should be called. This will guarantee that |GetId| will get an
-// immediate response and that the other method calls will be queued. Once page
-// initialization is complete, |SetPageDelegate| should be called. After that,
-// all pending operations, as well as any new ones, will be delegated to the
-// given PageDelegate.
-class PageDelayingFacade {
- public:
- // PageDelayingFacade constructor. The given request is bound immediately.
- PageDelayingFacade(storage::PageIdView page_id,
- fidl::InterfaceRequest<Page> request);
-
- void SetPageDelegate(PageDelegate* page_delegate);
-
- bool IsEmpty();
-
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- // From Page interface, called by PageImpl:
- void GetId(Page::GetIdCallback callback);
-
- void GetSnapshot(fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- std::vector<uint8_t> key_prefix,
- fidl::InterfaceHandle<PageWatcher> watcher,
- Page::GetSnapshotCallback callback);
- void Put(std::vector<uint8_t> key, std::vector<uint8_t> value,
- Page::PutCallback callback);
- void PutWithPriority(std::vector<uint8_t> key,
- std::vector<uint8_t> value, Priority priority,
- Page::PutWithPriorityCallback callback);
- void PutReference(std::vector<uint8_t> key, Reference reference,
- Priority priority, Page::PutReferenceCallback callback);
- void Delete(std::vector<uint8_t> key, Page::DeleteCallback callback);
- void Clear(Page::ClearCallback callback);
- void CreateReference(std::unique_ptr<storage::DataSource> data,
- fit::function<void(Status, ReferencePtr)> callback);
- void StartTransaction(Page::StartTransactionCallback callback);
- void Commit(Page::CommitCallback callback);
- void Rollback(Page::RollbackCallback callback);
- void SetSyncStateWatcher(fidl::InterfaceHandle<SyncWatcher> watcher,
- Page::SetSyncStateWatcherCallback callback);
- void WaitForConflictResolution(
- Page::WaitForConflictResolutionCallback callback);
-
- private:
- PageId page_id_;
- DelayingFacade<PageDelegate> delaying_facade_;
-
- fit::closure on_empty_callback_;
-
- fidl_helpers::BoundInterface<Page, PageImpl> interface_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageDelayingFacade);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_DELAYING_FACADE_H_
diff --git a/bin/ledger/app/page_delegate.cc b/bin/ledger/app/page_delegate.cc
deleted file mode 100644
index b42771b..0000000
--- a/bin/ledger/app/page_delegate.cc
+++ /dev/null
@@ -1,419 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_delegate.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/page_delaying_facade.h"
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/app/page_snapshot_impl.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-PageDelegate::PageDelegate(
- coroutine::CoroutineService* coroutine_service, PageManager* manager,
- storage::PageStorage* storage, MergeResolver* merge_resolver,
- SyncWatcherSet* watchers,
- std::unique_ptr<PageDelayingFacade> page_delaying_facade)
- : manager_(manager),
- storage_(storage),
- merge_resolver_(merge_resolver),
- branch_tracker_(coroutine_service, manager, storage),
- watcher_set_(watchers),
- page_delaying_facade_(std::move(page_delaying_facade)),
- weak_factory_(this) {
- page_delaying_facade_->set_on_empty([this] {
- operation_serializer_.Serialize<Status>(
- [](Status status) {},
- [this](fit::function<void(Status)> callback) {
- branch_tracker_.StopTransaction(nullptr);
- callback(Status::OK);
- });
- });
- branch_tracker_.set_on_empty([this] { CheckEmpty(); });
- operation_serializer_.set_on_empty([this] { CheckEmpty(); });
-}
-
-PageDelegate::~PageDelegate() {}
-
-void PageDelegate::Init(fit::function<void(Status)> on_done) {
- branch_tracker_.Init([this, on_done = std::move(on_done)](Status status) {
- if (status != Status::OK) {
- on_done(status);
- return;
- }
- page_delaying_facade_->SetPageDelegate(this);
- on_done(Status::OK);
- });
-}
-
-void PageDelegate::GetSnapshot(
- fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- std::vector<uint8_t> key_prefix,
- fidl::InterfaceHandle<PageWatcher> watcher,
- Page::GetSnapshotCallback callback) {
- // TODO(qsr): Update this so that only |GetCurrentCommitId| is done in a the
- // operation serializer.
- operation_serializer_.Serialize<Status>(
- std::move(callback),
- [this, snapshot_request = std::move(snapshot_request),
- key_prefix = std::move(key_prefix), watcher = std::move(watcher)](
- Page::GetSnapshotCallback callback) mutable {
- storage_->GetCommit(
- GetCurrentCommitId(),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, snapshot_request = std::move(snapshot_request),
- key_prefix = std::move(key_prefix),
- watcher = std::move(watcher), callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<const storage::Commit> commit) mutable {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status));
- return;
- }
- std::string prefix = convert::ToString(key_prefix);
- if (watcher) {
- PageWatcherPtr watcher_ptr = watcher.Bind();
- branch_tracker_.RegisterPageWatcher(
- std::move(watcher_ptr), commit->Clone(), prefix);
- }
- manager_->BindPageSnapshot(std::move(commit),
- std::move(snapshot_request),
- std::move(prefix));
- callback(Status::OK);
- }));
- });
-}
-
-void PageDelegate::Put(std::vector<uint8_t> key,
- std::vector<uint8_t> value,
- Page::PutCallback callback) {
- PutWithPriority(std::move(key), std::move(value), Priority::EAGER,
- std::move(callback));
-}
-
-void PageDelegate::PutWithPriority(std::vector<uint8_t> key,
- std::vector<uint8_t> value,
- Priority priority,
- Page::PutWithPriorityCallback callback) {
- FXL_DCHECK(key.size() <= kMaxKeySize);
- auto promise = fxl::MakeRefCounted<
- callback::Promise<storage::Status, storage::ObjectIdentifier>>(
- storage::Status::ILLEGAL_STATE);
- storage_->AddObjectFromLocal(storage::ObjectType::BLOB,
- storage::DataSource::Create(std::move(value)),
- promise->NewCallback());
-
- operation_serializer_.Serialize<Status>(
- std::move(callback),
- [this, promise = std::move(promise), key = std::move(key),
- priority](Page::PutWithPriorityCallback callback) mutable {
- promise->Finalize(callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, key = std::move(key), priority,
- callback = std::move(callback)](
- storage::Status status,
- storage::ObjectIdentifier object_identifier) mutable {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status));
- return;
- }
-
- PutInCommit(std::move(key), std::move(object_identifier),
- priority == Priority::EAGER
- ? storage::KeyPriority::EAGER
- : storage::KeyPriority::LAZY,
- std::move(callback));
- }));
- });
-}
-
-void PageDelegate::PutReference(std::vector<uint8_t> key,
- Reference reference, Priority priority,
- Page::PutReferenceCallback callback) {
- FXL_DCHECK(key.size() <= kMaxKeySize);
- // |ResolveReference| also makes sure that the reference was created for this
- // page.
- storage::ObjectIdentifier object_identifier;
- Status status =
- manager_->ResolveReference(std::move(reference), &object_identifier);
- if (status != Status::OK) {
- callback(status);
- return;
- }
-
- operation_serializer_.Serialize<Status>(
- std::move(callback),
- [this, key = std::move(key),
- object_identifier = std::move(object_identifier),
- priority](Page::PutReferenceCallback callback) mutable {
- PutInCommit(std::move(key), std::move(object_identifier),
- priority == Priority::EAGER ? storage::KeyPriority::EAGER
- : storage::KeyPriority::LAZY,
- std::move(callback));
- });
-}
-
-void PageDelegate::Delete(std::vector<uint8_t> key,
- Page::DeleteCallback callback) {
- operation_serializer_.Serialize<Status>(
- std::move(callback),
- [this, key = std::move(key)](Page::DeleteCallback callback) mutable {
- RunInTransaction(
- [key = std::move(key)](storage::Journal* journal,
- fit::function<void(Status)> callback) {
- journal->Delete(key, [callback = std::move(callback)](
- storage::Status status) {
- callback(
- PageUtils::ConvertStatus(status, Status::KEY_NOT_FOUND));
- });
- },
- std::move(callback));
- });
-}
-
-void PageDelegate::Clear(Page::ClearCallback callback) {
- operation_serializer_.Serialize<Status>(
- std::move(callback), [this](Page::ClearCallback callback) mutable {
- RunInTransaction(
- [](storage::Journal* journal,
- fit::function<void(Status)> callback) {
- journal->Clear(
- [callback = std::move(callback)](storage::Status status) {
- callback(PageUtils::ConvertStatus(status));
- });
- },
- std::move(callback));
- });
-}
-
-void PageDelegate::CreateReference(
- std::unique_ptr<storage::DataSource> data,
- fit::function<void(Status, ReferencePtr)> callback) {
- storage_->AddObjectFromLocal(
- storage::ObjectType::BLOB, std::move(data),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, callback = std::move(callback)](
- storage::Status status,
- storage::ObjectIdentifier object_identifier) {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status), nullptr);
- return;
- }
-
- callback(Status::OK, fidl::MakeOptional(manager_->CreateReference(
- std::move(object_identifier))));
- }));
-}
-
-void PageDelegate::StartTransaction(Page::StartTransactionCallback callback) {
- operation_serializer_.Serialize<Status>(
- std::move(callback), [this](StatusCallback callback) {
- if (journal_) {
- callback(Status::TRANSACTION_ALREADY_IN_PROGRESS);
- return;
- }
- storage::CommitId commit_id = branch_tracker_.GetBranchHeadId();
- storage_->StartCommit(
- commit_id, storage::JournalType::EXPLICIT,
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, commit_id, callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<storage::Journal> journal) mutable {
- journal_ = std::move(journal);
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status));
- return;
- }
- journal_parent_commit_ = commit_id;
-
- branch_tracker_.StartTransaction(
- [callback = std::move(callback)]() {
- callback(Status::OK);
- });
- }));
- });
-}
-
-void PageDelegate::Commit(Page::CommitCallback callback) {
- operation_serializer_.Serialize<Status>(
- std::move(callback), [this](StatusCallback callback) {
- if (!journal_) {
- callback(Status::NO_TRANSACTION_IN_PROGRESS);
- return;
- }
- journal_parent_commit_.clear();
- CommitJournal(std::move(journal_),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, callback = std::move(callback)](
- Status status,
- std::unique_ptr<const storage::Commit> commit) {
- branch_tracker_.StopTransaction(std::move(commit));
- callback(status);
- }));
- });
-}
-
-void PageDelegate::Rollback(Page::RollbackCallback callback) {
- operation_serializer_.Serialize<Status>(
- std::move(callback), [this](StatusCallback callback) {
- if (!journal_) {
- callback(Status::NO_TRANSACTION_IN_PROGRESS);
- return;
- }
- storage_->RollbackJournal(
- std::move(journal_),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, callback = std::move(callback)](storage::Status status) {
- journal_.reset();
- journal_parent_commit_.clear();
- callback(PageUtils::ConvertStatus(status));
- branch_tracker_.StopTransaction(nullptr);
- }));
- });
-}
-
-void PageDelegate::SetSyncStateWatcher(
- fidl::InterfaceHandle<SyncWatcher> watcher,
- Page::SetSyncStateWatcherCallback callback) {
- SyncWatcherPtr watcher_ptr = watcher.Bind();
- watcher_set_->AddSyncWatcher(std::move(watcher_ptr));
- callback(Status::OK);
-}
-
-void PageDelegate::WaitForConflictResolution(
- Page::WaitForConflictResolutionCallback callback) {
- if (!merge_resolver_->HasUnfinishedMerges()) {
- callback(ConflictResolutionWaitStatus::NO_CONFLICTS);
- return;
- }
- merge_resolver_->RegisterNoConflictCallback(std::move(callback));
-}
-
-const storage::CommitId& PageDelegate::GetCurrentCommitId() {
- // TODO(etiennej): Commit implicit transactions when we have those.
- if (!journal_) {
- return branch_tracker_.GetBranchHeadId();
- }
- return journal_parent_commit_;
-}
-
-void PageDelegate::PutInCommit(std::vector<uint8_t> key,
- storage::ObjectIdentifier object_identifier,
- storage::KeyPriority priority,
- fit::function<void(Status)> callback) {
- RunInTransaction(
- [key = std::move(key), object_identifier = std::move(object_identifier),
- priority](storage::Journal* journal,
- fit::function<void(Status status)> callback) mutable {
- journal->Put(key, std::move(object_identifier), priority,
- [callback = std::move(callback)](storage::Status status) {
- callback(PageUtils::ConvertStatus(status));
- });
- },
- std::move(callback));
-}
-
-void PageDelegate::RunInTransaction(
- fit::function<void(storage::Journal*, fit::function<void(Status)>)>
- runnable,
- fit::function<void(Status)> callback) {
- if (journal_) {
- // A transaction is in progress; add this change to it.
- runnable(journal_.get(), std::move(callback));
- return;
- }
- // No transaction is in progress; create one just for this change.
- // TODO(etiennej): Add a change batching strategy for operations outside
- // transactions. Currently, we create a commit for every change; we
- // would like to group changes that happen "close enough" together in
- // one commit.
- branch_tracker_.StartTransaction([] {});
- storage::CommitId commit_id = branch_tracker_.GetBranchHeadId();
- std::unique_ptr<storage::Journal> journal;
- storage_->StartCommit(
- commit_id, storage::JournalType::IMPLICIT,
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, runnable = std::move(runnable),
- callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<storage::Journal> journal) mutable {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status));
- branch_tracker_.StopTransaction(nullptr);
- return;
- }
- runnable(
- journal.get(),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, journal = std::move(journal),
- callback =
- std::move(callback)](Status ledger_status) mutable {
- if (ledger_status != Status::OK) {
- callback(ledger_status);
- storage_->RollbackJournal(
- std::move(journal),
- [](storage::Status /*rollback_status*/) {});
- branch_tracker_.StopTransaction(nullptr);
- return;
- }
-
- CommitJournal(
- std::move(journal),
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, callback = std::move(callback)](
- Status status,
- std::unique_ptr<const storage::Commit>
- commit) {
- branch_tracker_.StopTransaction(
- status == Status::OK ? std::move(commit)
- : nullptr);
- callback(status);
- }));
- }));
- }));
-}
-
-void PageDelegate::CommitJournal(
- std::unique_ptr<storage::Journal> journal,
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- storage_->CommitJournal(
- std::move(journal), [callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<const storage::Commit> commit) {
- callback(PageUtils::ConvertStatus(status), std::move(commit));
- });
-}
-
-void PageDelegate::CheckEmpty() {
- if (on_empty_callback_ && page_delaying_facade_->IsEmpty() &&
- branch_tracker_.IsEmpty() && operation_serializer_.empty()) {
- on_empty_callback_();
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_delegate.h b/bin/ledger/app/page_delegate.h
deleted file mode 100644
index 6520708..0000000
--- a/bin/ledger/app/page_delegate.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_DELEGATE_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_DELEGATE_H_
-
-#include <memory>
-#include <queue>
-#include <string>
-#include <vector>
-
-#include <lib/callback/operation_serializer.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/app/branch_tracker.h"
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-#include "peridot/bin/ledger/app/page_impl.h"
-#include "peridot/bin/ledger/app/sync_watcher_set.h"
-#include "peridot/bin/ledger/fidl_helpers/bound_interface.h"
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/bin/ledger/storage/public/journal.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-class PageManager;
-
-// A delegate for the implementation of the |Page| interface.
-//
-// PageDelegate owns PageDelayingFacade and BranchTracker. It makes sure that
-// all operations in progress will terminate, even if the Page is no longer
-// connected. When the page connection is closed and BranchTracker is also
-// empty, the client is notified through |on_empty_callback| (registered by
-// |set_on_empty()|).
-class PageDelegate {
- public:
- PageDelegate(coroutine::CoroutineService* coroutine_service,
- PageManager* manager, storage::PageStorage* storage,
- MergeResolver* merge_resolver, SyncWatcherSet* watchers,
- std::unique_ptr<PageDelayingFacade> page_delaying_facade);
- ~PageDelegate();
-
- void Init(fit::function<void(Status)> on_done);
-
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- // From Page interface, called by PageDelayingFacade:
-
- void GetSnapshot(fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- std::vector<uint8_t> key_prefix,
- fidl::InterfaceHandle<PageWatcher> watcher,
- Page::GetSnapshotCallback callback);
-
- void Put(std::vector<uint8_t> key, std::vector<uint8_t> value,
- Page::PutCallback callback);
-
- void PutWithPriority(std::vector<uint8_t> key,
- std::vector<uint8_t> value, Priority priority,
- Page::PutWithPriorityCallback callback);
-
- void PutReference(std::vector<uint8_t> key, Reference reference,
- Priority priority, Page::PutReferenceCallback callback);
-
- void Delete(std::vector<uint8_t> key, Page::DeleteCallback callback);
-
- void Clear(Page::ClearCallback callback);
-
- void CreateReference(std::unique_ptr<storage::DataSource> data,
- fit::function<void(Status, ReferencePtr)> callback);
-
- void StartTransaction(Page::StartTransactionCallback callback);
-
- void Commit(Page::CommitCallback callback);
-
- void Rollback(Page::RollbackCallback callback);
-
- void SetSyncStateWatcher(fidl::InterfaceHandle<SyncWatcher> watcher,
- Page::SetSyncStateWatcherCallback callback);
-
- void WaitForConflictResolution(
- Page::WaitForConflictResolutionCallback callback);
-
- private:
- using StatusCallback = fit::function<void(Status)>;
-
- const storage::CommitId& GetCurrentCommitId();
-
- void PutInCommit(std::vector<uint8_t> key,
- storage::ObjectIdentifier object_identifier,
- storage::KeyPriority priority, StatusCallback callback);
-
- // Runs |runnable| in a transaction, and notifies |callback| of the result. If
- // a transaction is currently in progress, it reuses it, otherwise creates a
- // new one and commits it before calling |callback|. This method is not
- // serialized, and should only be called from a callsite that is serialized.
- void RunInTransaction(
- fit::function<void(storage::Journal*, fit::function<void(Status)>)>
- runnable,
- StatusCallback callback);
-
- void CommitJournal(
- std::unique_ptr<storage::Journal> journal,
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback);
-
- void CheckEmpty();
-
- PageManager* manager_;
- storage::PageStorage* storage_;
- MergeResolver* merge_resolver_;
-
- BranchTracker branch_tracker_;
-
- fit::closure on_empty_callback_;
-
- storage::CommitId journal_parent_commit_;
- std::unique_ptr<storage::Journal> journal_;
- callback::OperationSerializer operation_serializer_;
- SyncWatcherSet* watcher_set_;
-
- std::unique_ptr<PageDelayingFacade> page_delaying_facade_;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<PageDelegate> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageDelegate);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_DELEGATE_H_
diff --git a/bin/ledger/app/page_eviction_manager.h b/bin/ledger/app/page_eviction_manager.h
deleted file mode 100644
index 4514896..0000000
--- a/bin/ledger/app/page_eviction_manager.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_MANAGER_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_MANAGER_H_
-
-#include <map>
-#include <string>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/app/page_eviction_policies.h"
-#include "peridot/bin/ledger/app/page_usage_listener.h"
-#include "peridot/bin/ledger/app/types.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-// Manages page eviction based on page usage information.
-//
-// |PageEvictionManager| provides the |TryEvictPage| method which evicts a given
-// page, as well as one that selects and evicts a set of pages, among those
-// that are stored on the device.
-//
-// Regardless of the method used, a page can only be evicted if it is closed,
-// i.e. is not currently opened by an external request, and either of the
-// following is true:
-// - All contents of the page (commits and objects) are synced to the cloud.
-// - The page is offline and empty. A page is offline if it has never been
-// synced to the cloud or a peer. It is empty, if it has a single head commit
-// and the contents of that commit is empty.
-//
-// If neither of these conditions is fulfilled, the page will fail to be
-// evicted.
-class PageEvictionManager {
- public:
- // A Delegate, providing the necessary functionality to allow
- // PageEvictionManager to perform storage clean up operations.
- class Delegate {
- public:
- // Checks whether the given page is closed and synced. The result returned
- // in the callback will be |PAGE_OPENED| if the page is opened after calling
- // this method and before the callback is called. Otherwise it will be |YES|
- // or |NO| depending on whether the page is synced.
- virtual void PageIsClosedAndSynced(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) = 0;
-
- // Checks whether the given page is closed, offline and empty. The result
- // returned in the callback will be |PAGE_OPENED| if the page is opened
- // after calling this method and before the callback is called. Otherwise it
- // will be |YES| or |NO| depending on whether the page is offline and empty.
- virtual void PageIsClosedOfflineAndEmpty(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) = 0;
-
- // Deletes the local copy of the given page from storage.
- virtual void DeletePageStorage(fxl::StringView ledger_name,
- storage::PageIdView page_id,
- fit::function<void(Status)> callback) = 0;
- };
-
- PageEvictionManager() {}
- virtual ~PageEvictionManager() {}
-
- // Sets the callback to be called every time the PageEvictionManager is empty.
- virtual void set_on_empty(fit::closure on_empty_callback) = 0;
-
- // Returns whether the PageEvictionManager is empty, i.e. whether there are no
- // pending operations.
- virtual bool IsEmpty() = 0;
-
- // Tries to evict from the local storage the least recently used page among
- // those that are not currectly in use and can be evicted. Returns |IO_ERROR|
- // through the callback in case of failure to retrieve data on page usage, or
- // when trying to evict a given page; |OK| otherwise. It is not an error if
- // there is no page fulfilling the requirements.
- virtual void TryEvictPages(PageEvictionPolicy* policy,
- fit::function<void(Status)> callback) = 0;
-
- // Marks the page as open.
- virtual void MarkPageOpened(fxl::StringView ledger_name,
- storage::PageIdView page_id) = 0;
-
- // Marks the page as closed.
- virtual void MarkPageClosed(fxl::StringView ledger_name,
- storage::PageIdView page_id) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageEvictionManager);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_MANAGER_H_
diff --git a/bin/ledger/app/page_eviction_manager_impl.cc b/bin/ledger/app/page_eviction_manager_impl.cc
deleted file mode 100644
index aa13c2a..0000000
--- a/bin/ledger/app/page_eviction_manager_impl.cc
+++ /dev/null
@@ -1,396 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_eviction_manager_impl.h"
-
-#include <algorithm>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/strings/concatenate.h>
-#include <zx/time.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/ledger_repository_impl.h"
-#include "peridot/bin/ledger/app/page_usage_db.h"
-#include "peridot/bin/ledger/app/types.h"
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/coroutine/coroutine_waiter.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-namespace {
-
-// Logs an error message if the given |status| is not |OK| or |INTERNAL_ERROR|.
-void LogOnPageUpdateError(fxl::StringView operation_description, Status status,
- fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- // Don't print an error on |INTERNAL_ERROR|: it means that the operation was
- // interrupted, because PageEvictionManagerImpl was destroyed before being
- // empty.
- if (status != Status::OK && status != Status::INTERNAL_ERROR) {
- FXL_LOG(ERROR) << "Failed to " << operation_description
- << " in PageUsage DB. Status: " << fidl::ToUnderlying(status)
- << ". Ledger name: " << ledger_name
- << ". Page ID: " << convert::ToHex(page_id);
- }
-}
-
-// If the given |status| is not |OK|, logs an error message on failure to
-// initialize. Returns true in case of error; false otherwise.
-bool LogOnInitializationError(fxl::StringView operation_description,
- Status status) {
- if (status != Status::OK) {
- FXL_LOG(ERROR) << operation_description
- << " failed because of initialization error: "
- << fidl::ToUnderlying(status);
- return true;
- }
- return false;
-}
-
-} // namespace
-
-PageEvictionManagerImpl::Completer::Completer() {}
-
-PageEvictionManagerImpl::Completer::~Completer() {
- CallCallbacks(Status::INTERNAL_ERROR);
-}
-
-void PageEvictionManagerImpl::Completer::Complete(Status status) {
- FXL_DCHECK(!completed_);
- CallCallbacks(status);
-}
-
-Status PageEvictionManagerImpl::Completer::WaitUntilDone(
- coroutine::CoroutineHandler* handler) {
- if (completed_) {
- return status_;
- }
-
- auto sync_call_status =
- coroutine::SyncCall(handler, [this](fit::closure callback) {
- // SyncCall finishes its execution when the given |callback| is called.
- // To block the termination of |SyncCall| (and of |WaitUntilDone|), here
- // we push this |callback| in the vector of |callbacks_|. Once
- // |Complete| is called, we will call all of these callbacks, which will
- // eventually unblock all pending |WaitUntilDone| calls.
- callbacks_.push_back(std::move(callback));
- });
- if (sync_call_status == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERNAL_ERROR;
- }
- return status_;
-}
-
-void PageEvictionManagerImpl::Completer::CallCallbacks(Status status) {
- if (completed_) {
- return;
- }
- completed_ = true;
- status_ = status;
- // We need to move the callbacks in the stack since calling any of the
- // them might lead to the deletion of this object, invalidating callbacks_.
- std::vector<fit::closure> callbacks = std::move(callbacks_);
- callbacks_.clear();
- for (const auto& callback : callbacks) {
- callback();
- }
-}
-
-PageEvictionManagerImpl::PageEvictionManagerImpl(Environment* environment,
- storage::DbFactory* db_factory,
- DetachedPath db_path)
- : environment_(environment),
- db_factory_(db_factory),
- db_path_(db_path.SubPath(kPageUsageDbSerializationVersion)),
- coroutine_manager_(environment_->coroutine_service()),
- weak_factory_(this) {}
-
-PageEvictionManagerImpl::~PageEvictionManagerImpl() {}
-
-Status PageEvictionManagerImpl::Init() {
- // Initializing the DB and marking pages as closed are slow operations and we
- // shouldn't wait for them to finish, before returning from initialization:
- // Start these operations and finalize the initialization completer when done.
- coroutine_manager_.StartCoroutine([this](
- coroutine::CoroutineHandler* handler) {
- ExpiringToken token = NewExpiringToken();
- if (!files::CreateDirectoryAt(db_path_.root_fd(), db_path_.path())) {
- initialization_completer_.Complete(Status::IO_ERROR);
- return;
- }
- storage::Status storage_status;
- std::unique_ptr<storage::Db> db_instance;
- if (coroutine::SyncCall(
- handler,
- [this](fit::function<void(storage::Status,
- std::unique_ptr<storage::Db>)>
- callback) {
- db_factory_->GetOrCreateDb(
- std::move(db_path_), storage::DbFactory::OnDbNotFound::CREATE,
- std::move(callback));
- },
- &storage_status,
- &db_instance) == coroutine::ContinuationStatus::INTERRUPTED) {
- initialization_completer_.Complete(Status::INTERNAL_ERROR);
- return;
- }
- if (storage_status != storage::Status::OK) {
- initialization_completer_.Complete(
- PageUtils::ConvertStatus(storage_status));
- return;
- }
- db_ = std::make_unique<PageUsageDb>(environment_->clock(),
- std::move(db_instance));
- Status status = db_->MarkAllPagesClosed(handler);
- initialization_completer_.Complete(status);
- });
- return Status::OK;
-}
-
-void PageEvictionManagerImpl::SetDelegate(
- PageEvictionManager::Delegate* delegate) {
- FXL_DCHECK(delegate);
- FXL_DCHECK(!delegate_);
- delegate_ = delegate;
-}
-
-void PageEvictionManagerImpl::set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
-}
-
-bool PageEvictionManagerImpl::IsEmpty() { return pending_operations_ == 0; }
-
-void PageEvictionManagerImpl::TryEvictPages(
- PageEvictionPolicy* policy, fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, policy](coroutine::CoroutineHandler* handler,
- fit::function<void(Status)> callback) mutable {
- ExpiringToken token = NewExpiringToken();
- Status status = initialization_completer_.WaitUntilDone(handler);
- if (LogOnInitializationError("TryEvictPages", status)) {
- callback(status);
- return;
- }
- std::unique_ptr<storage::Iterator<const PageInfo>> pages_it;
- status = db_->GetPages(handler, &pages_it);
- if (status != Status::OK) {
- callback(status);
- return;
- }
- policy->SelectAndEvict(std::move(pages_it), std::move(callback));
- });
-}
-
-void PageEvictionManagerImpl::MarkPageOpened(fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- coroutine_manager_.StartCoroutine([this, ledger_name = ledger_name.ToString(),
- page_id = page_id.ToString()](
- coroutine::CoroutineHandler* handler) {
- ExpiringToken token = NewExpiringToken();
- Status status = initialization_completer_.WaitUntilDone(handler);
- if (LogOnInitializationError("MarkPageOpened", status)) {
- return;
- }
- status = db_->MarkPageOpened(handler, ledger_name, page_id);
- LogOnPageUpdateError("mark page as opened", status, ledger_name, page_id);
- });
-}
-
-void PageEvictionManagerImpl::MarkPageClosed(fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- coroutine_manager_.StartCoroutine([this, ledger_name = ledger_name.ToString(),
- page_id = page_id.ToString()](
- coroutine::CoroutineHandler* handler) {
- ExpiringToken token = NewExpiringToken();
- Status status = initialization_completer_.WaitUntilDone(handler);
- if (LogOnInitializationError("MarkPageClosed", status)) {
- return;
- }
- status = db_->MarkPageClosed(handler, ledger_name, page_id);
- LogOnPageUpdateError("mark page as closed", status, ledger_name, page_id);
- });
-}
-
-void PageEvictionManagerImpl::TryEvictPage(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- PageEvictionCondition condition,
- fit::function<void(Status, PageWasEvicted)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, ledger_name = ledger_name.ToString(), page_id = page_id.ToString(),
- condition](
- coroutine::CoroutineHandler* handler,
- fit::function<void(Status, PageWasEvicted)> callback) mutable {
- ExpiringToken token = NewExpiringToken();
- Status status = initialization_completer_.WaitUntilDone(handler);
- if (LogOnInitializationError("TryEvictPage", status)) {
- callback(status, PageWasEvicted(false));
- return;
- }
- PageWasEvicted was_evicted;
- status = SynchronousTryEvictPage(handler, ledger_name, page_id,
- condition, &was_evicted);
- callback(status, was_evicted);
- });
-}
-
-void PageEvictionManagerImpl::EvictPage(fxl::StringView ledger_name,
- storage::PageIdView page_id,
- fit::function<void(Status)> callback) {
- FXL_DCHECK(delegate_);
- // We cannot delete the page storage and mark the deletion atomically. We thus
- // delete the page first, and then mark it as evicted in Page Usage DB. If at
- // some point a page gets deleted, but marking fails, on the next attempt to
- // evict it we will get a |PAGE_NOT_FOUND| error, indicating we should remove
- // the entry then. Therefore, |PAGE_NOT_FOUND| errors are handled internally
- // and never returned to the callback.
- delegate_->DeletePageStorage(
- ledger_name, page_id,
- [this, ledger_name = ledger_name.ToString(), page_id = page_id.ToString(),
- callback = std::move(callback)](Status status) mutable {
- // |PAGE_NOT_FOUND| is not an error, but it must have been handled
- // before we try to evict the page.
- FXL_DCHECK(status != Status::PAGE_NOT_FOUND);
- if (status == Status::OK) {
- MarkPageEvicted(std::move(ledger_name), std::move(page_id));
- }
- callback(status);
- });
-}
-
-Status PageEvictionManagerImpl::CanEvictPage(
- coroutine::CoroutineHandler* handler, fxl::StringView ledger_name,
- storage::PageIdView page_id, bool* can_evict) {
- FXL_DCHECK(delegate_);
-
- auto waiter =
- fxl::MakeRefCounted<callback::Waiter<Status, PagePredicateResult>>(
- Status::OK);
-
- delegate_->PageIsClosedAndSynced(ledger_name, page_id, waiter->NewCallback());
- delegate_->PageIsClosedOfflineAndEmpty(ledger_name, page_id,
- waiter->NewCallback());
-
- Status status;
- std::vector<PagePredicateResult> can_evict_states;
- auto sync_call_status =
- coroutine::Wait(handler, std::move(waiter), &status, &can_evict_states);
- if (sync_call_status == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERNAL_ERROR;
- }
- if (status != Status::OK) {
- return status;
- }
- FXL_DCHECK(can_evict_states.size() == 2);
- // Receiving status |PAGE_OPENED| means that the page was opened during the
- // query. If either result is |PAGE_OPENED| the page cannot be evicted, as the
- // result of the other might be invalid at this point.
- *can_evict = std::any_of(can_evict_states.begin(), can_evict_states.end(),
- [](PagePredicateResult result) {
- return result == PagePredicateResult::YES;
- }) &&
- std::none_of(can_evict_states.begin(), can_evict_states.end(),
- [](PagePredicateResult result) {
- return result == PagePredicateResult::PAGE_OPENED;
- });
-
- return Status::OK;
-}
-
-Status PageEvictionManagerImpl::CanEvictEmptyPage(
- coroutine::CoroutineHandler* handler, fxl::StringView ledger_name,
- storage::PageIdView page_id, bool* can_evict) {
- FXL_DCHECK(delegate_);
-
- Status status;
- PagePredicateResult empty_state;
- auto sync_call_status = coroutine::SyncCall(
- handler,
- [this, ledger_name = ledger_name.ToString(),
- page_id = page_id.ToString()](auto callback) {
- delegate_->PageIsClosedOfflineAndEmpty(ledger_name, page_id,
- std::move(callback));
- },
- &status, &empty_state);
- if (sync_call_status == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERNAL_ERROR;
- }
- *can_evict = (empty_state == PagePredicateResult::YES);
- return status;
-}
-
-void PageEvictionManagerImpl::MarkPageEvicted(std::string ledger_name,
- storage::PageId page_id) {
- coroutine_manager_.StartCoroutine([this, ledger_name = std::move(ledger_name),
- page_id = std::move(page_id)](
- coroutine::CoroutineHandler* handler) {
- Status status = db_->MarkPageEvicted(handler, ledger_name, page_id);
- LogOnPageUpdateError("mark page as evicted", status, ledger_name, page_id);
- });
-}
-
-Status PageEvictionManagerImpl::SynchronousTryEvictPage(
- coroutine::CoroutineHandler* handler, std::string ledger_name,
- storage::PageId page_id, PageEvictionCondition condition,
- PageWasEvicted* was_evicted) {
- bool can_evict;
- Status status;
- switch (condition) {
- case IF_EMPTY:
- status = CanEvictEmptyPage(handler, ledger_name, page_id, &can_evict);
- break;
- case IF_POSSIBLE:
- status = CanEvictPage(handler, ledger_name, page_id, &can_evict);
- }
- if (status == Status::PAGE_NOT_FOUND) {
- // The page was already removed. Mark it as evicted in Page Usage DB.
- MarkPageEvicted(ledger_name, page_id);
- *was_evicted = PageWasEvicted(false);
- return Status::OK;
- }
- if (status != Status::OK || !can_evict) {
- *was_evicted = PageWasEvicted(false);
- return status;
- }
-
- auto sync_call_status = coroutine::SyncCall(
- handler,
- [this, ledger_name = std::move(ledger_name),
- page_id = std::move(page_id)](auto callback) {
- EvictPage(ledger_name, page_id, std::move(callback));
- },
- &status);
- if (sync_call_status == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERNAL_ERROR;
- }
- *was_evicted = PageWasEvicted(status == Status::OK);
- return status;
-}
-
-PageEvictionManagerImpl::ExpiringToken
-PageEvictionManagerImpl::NewExpiringToken() {
- ++pending_operations_;
- return ExpiringToken(callback::MakeScoped(weak_factory_.GetWeakPtr(), [this] {
- --pending_operations_;
- // We need to post a task here: Tokens expire while a coroutine is being
- // executed, and if |on_empty_callback_| is executed directly, it might end
- // up deleting the PageEvictionManagerImpl object, which will delete the
- // |coroutine_manager_|.
- async::PostTask(environment_->dispatcher(),
- callback::MakeScoped(weak_factory_.GetWeakPtr(), [this] {
- if (on_empty_callback_ && pending_operations_ == 0) {
- on_empty_callback_();
- }
- }));
- }));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_eviction_manager_impl.h b/bin/ledger/app/page_eviction_manager_impl.h
deleted file mode 100644
index adc1a1b..0000000
--- a/bin/ledger/app/page_eviction_manager_impl.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_MANAGER_IMPL_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_MANAGER_IMPL_H_
-
-#include "peridot/bin/ledger/app/page_eviction_manager.h"
-
-#include <memory>
-#include <utility>
-
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/app/page_usage_db.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/coroutine/coroutine_manager.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/storage/public/db_factory.h"
-
-namespace ledger {
-
-class PageEvictionManagerImpl : public PageEvictionManager,
- public PageEvictionDelegate {
- public:
- PageEvictionManagerImpl(Environment* environment,
- storage::DbFactory* db_factory, DetachedPath db_path);
- ~PageEvictionManagerImpl() override;
-
- // Initializes this PageEvictionManager. |IO_ERROR| will be returned in case
- // of an error while initializing the underlying database.
- Status Init();
-
- // Sets the delegate for this PageEvictionManagerImpl. The delegate should
- // outlive this object.
- void SetDelegate(PageEvictionManager::Delegate* delegate);
-
- // PageEvictionManager:
- void set_on_empty(fit::closure on_empty_callback) override;
-
- bool IsEmpty() override;
-
- void TryEvictPages(PageEvictionPolicy* policy,
- fit::function<void(Status)> callback) override;
-
- void MarkPageOpened(fxl::StringView ledger_name,
- storage::PageIdView page_id) override;
-
- void MarkPageClosed(fxl::StringView ledger_name,
- storage::PageIdView page_id) override;
-
- // PageEvictionDelegate:
- void TryEvictPage(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- PageEvictionCondition condition,
- fit::function<void(Status, PageWasEvicted)> callback) override;
-
- private:
- // A token that performs a given action on destruction. ExpiringToken objects
- // are used to keep track of pending operations.
- using ExpiringToken = fit::deferred_action<fit::closure>;
-
- // A Completer allowing waiting until the target operation is completed.
- class Completer {
- public:
- Completer();
-
- ~Completer();
-
- // Completes the operation with the given status and unblocks all pending
- // |WaitUntilDone| calls. |Complete| can only be called once.
- void Complete(Status status);
-
- // Blocks execution until |Complete| is called, and then returns its status.
- // If the operation is already completed, |WaitUntilDone| returns
- // immediately with the result status.
- Status WaitUntilDone(coroutine::CoroutineHandler* handler);
-
- private:
- // Marks the Completer as completed with the given status and calls the
- // pending callbacks.
- void CallCallbacks(Status status);
-
- bool completed_ = false;
- Status status_;
- // Closures invoked upon completion to unblock the waiting coroutines.
- std::vector<fit::closure> callbacks_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(Completer);
- };
-
- // Removes the page from the local storage.
- void EvictPage(fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status)> callback);
-
- // Checks whether a page can be evicted. A page can be evicted if it is
- // currently closed and either:
- // - has no unsynced commits or objects, or
- // - is empty and offline, i.e. was never synced to the cloud or a peer.
- Status CanEvictPage(coroutine::CoroutineHandler* handler,
- fxl::StringView ledger_name, storage::PageIdView page_id,
- bool* can_evict);
-
- // Checks whether a page is closed, offline and empty, and thus can be
- // evicted.
- Status CanEvictEmptyPage(coroutine::CoroutineHandler* handler,
- fxl::StringView ledger_name,
- storage::PageIdView page_id, bool* can_evict);
-
- // Marks the given page as evicted in the page usage database.
- void MarkPageEvicted(std::string ledger_name, storage::PageId page_id);
-
- Status SynchronousTryEvictPage(coroutine::CoroutineHandler* handler,
- std::string ledger_name,
- storage::PageId page_id,
- PageEvictionCondition condition,
- PageWasEvicted* was_evicted);
-
- ExpiringToken NewExpiringToken();
-
- Environment* environment_;
- // The initialization completer. |Init| method starts marking pages as closed,
- // and returns before that operation is done. This completer makes sure that
- // all methods accessing the page usage database wait until the initialization
- // has finished, before reading or updating information.
- Completer initialization_completer_;
- // A closure to be called every time all pending operations are completed.
- fit::closure on_empty_callback_;
- ssize_t pending_operations_ = 0;
- PageEvictionManager::Delegate* delegate_ = nullptr;
- // |db_factory_| and |db_path_| should only be used during initialization.
- // After Init() has been called their contents are no longer valid.
- storage::DbFactory* db_factory_;
- DetachedPath db_path_;
- std::unique_ptr<PageUsageDb> db_;
- coroutine::CoroutineManager coroutine_manager_;
-
- // Must be the last member.
- fxl::WeakPtrFactory<PageEvictionManagerImpl> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageEvictionManagerImpl);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_MANAGER_IMPL_H_
diff --git a/bin/ledger/app/page_eviction_manager_impl_unittest.cc b/bin/ledger/app/page_eviction_manager_impl_unittest.cc
deleted file mode 100644
index cb5fb2d..0000000
--- a/bin/ledger/app/page_eviction_manager_impl_unittest.cc
+++ /dev/null
@@ -1,509 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_eviction_manager_impl.h"
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/storage/fake/fake_db_factory.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-
-class FakeDelegate : public PageEvictionManager::Delegate {
- public:
- void PageIsClosedAndSynced(
- fxl::StringView /*ledger_name*/, storage::PageIdView /*page_id*/,
- fit::function<void(Status, PagePredicateResult)> callback) override {
- callback(page_closed_and_synced_status, closed_and_synced);
- }
-
- void PageIsClosedOfflineAndEmpty(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- fit::function<void(Status, PagePredicateResult)> callback) override {
- callback(Status::OK, closed_and_empty);
- }
-
- void DeletePageStorage(fxl::StringView /*ledger_name*/,
- storage::PageIdView page_id,
- fit::function<void(Status)> callback) override {
- deleted_pages.push_back(page_id.ToString());
- callback(Status::OK);
- }
-
- std::vector<storage::PageId> deleted_pages;
-
- PagePredicateResult closed_and_synced = PagePredicateResult::YES;
- Status page_closed_and_synced_status = Status::OK;
-
- PagePredicateResult closed_and_empty = PagePredicateResult::YES;
-};
-
-class PageEvictionManagerTest : public TestWithEnvironment {
- public:
- PageEvictionManagerTest()
- : db_factory_(environment_.dispatcher()),
- page_eviction_manager_(&environment_, &db_factory_,
- DetachedPath(tmpfs_.root_fd())),
- policy_(NewLeastRecentyUsedPolicy(environment_.coroutine_service(),
- &page_eviction_manager_)) {}
-
- // TestWithEnvironment:
- void SetUp() override {
- EXPECT_EQ(Status::OK, page_eviction_manager_.Init());
- RunLoopUntilIdle();
- page_eviction_manager_.SetDelegate(&delegate_);
- }
-
- private:
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- storage::fake::FakeDbFactory db_factory_;
-
- protected:
- FakeDelegate delegate_;
- PageEvictionManagerImpl page_eviction_manager_;
- std::unique_ptr<PageEvictionPolicy> policy_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageEvictionManagerTest);
-};
-
-TEST_F(PageEvictionManagerTest, NoEvictionWithoutPages) {
- bool called;
- Status status;
-
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-}
-
-TEST_F(PageEvictionManagerTest, AtLeastOneEvictionWhenPossible) {
- std::string ledger_name = "ledger";
- storage::PageId page1 = std::string(::fuchsia::ledger::kPageIdSize, '1');
- storage::PageId page2 = std::string(::fuchsia::ledger::kPageIdSize, '2');
-
- delegate_.closed_and_synced = PagePredicateResult::YES;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page1);
- page_eviction_manager_.MarkPageClosed(ledger_name, page1);
- page_eviction_manager_.MarkPageOpened(ledger_name, page2);
- page_eviction_manager_.MarkPageClosed(ledger_name, page2);
- RunLoopUntilIdle();
-
- bool called;
- Status status;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(delegate_.deleted_pages.empty());
-}
-
-TEST_F(PageEvictionManagerTest, DontEvictUnsyncedNotEmptyPages) {
- std::string ledger_name = "ledger";
- storage::PageId page1 = std::string(::fuchsia::ledger::kPageIdSize, '1');
- storage::PageId page2 = std::string(::fuchsia::ledger::kPageIdSize, '2');
-
- delegate_.closed_and_synced = PagePredicateResult::NO;
- delegate_.closed_and_empty = PagePredicateResult::NO;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page1);
- page_eviction_manager_.MarkPageClosed(ledger_name, page1);
- page_eviction_manager_.MarkPageOpened(ledger_name, page2);
- page_eviction_manager_.MarkPageClosed(ledger_name, page2);
- RunLoopUntilIdle();
-
- bool called;
- Status status;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-}
-
-TEST_F(PageEvictionManagerTest, DontEvictOpenPages) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- delegate_.closed_and_synced = PagePredicateResult::YES;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page);
- RunLoopUntilIdle();
-
- bool called;
- Status status;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-
- // Close the page. It can now be evicted.
- page_eviction_manager_.MarkPageClosed(ledger_name, page);
- RunLoopUntilIdle();
-
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page));
-}
-
-TEST_F(PageEvictionManagerTest, DontEvictAnEvictedPage) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- delegate_.closed_and_synced = PagePredicateResult::YES;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page);
- page_eviction_manager_.MarkPageClosed(ledger_name, page);
- RunLoopUntilIdle();
-
- bool called;
- Status status;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page));
-
- delegate_.deleted_pages.clear();
- // Try to clean up again. We shouldn't be able to evict any pages.
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-}
-
-TEST_F(PageEvictionManagerTest, PageNotFoundIsNotAnError) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- delegate_.closed_and_synced = PagePredicateResult::YES;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page);
- page_eviction_manager_.MarkPageClosed(ledger_name, page);
- RunLoopUntilIdle();
-
- delegate_.page_closed_and_synced_status = Status::PAGE_NOT_FOUND;
-
- bool called;
- Status status;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-}
-
-TEST_F(PageEvictionManagerTest, EvictUnsyncedButEmptyPages) {
- std::string ledger_name = "ledger";
- storage::PageId page1 = std::string(::fuchsia::ledger::kPageIdSize, '1');
- storage::PageId page2 = std::string(::fuchsia::ledger::kPageIdSize, '2');
-
- delegate_.closed_and_synced = PagePredicateResult::NO;
- delegate_.closed_and_empty = PagePredicateResult::YES;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page1);
- page_eviction_manager_.MarkPageClosed(ledger_name, page1);
- page_eviction_manager_.MarkPageOpened(ledger_name, page2);
- page_eviction_manager_.MarkPageClosed(ledger_name, page2);
- RunLoopUntilIdle();
-
- bool called;
- Status status;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page1));
-}
-
-TEST_F(PageEvictionManagerTest, EvictSyncedAndNotEmptyPages) {
- std::string ledger_name = "ledger";
- storage::PageId page1 = std::string(::fuchsia::ledger::kPageIdSize, '1');
- storage::PageId page2 = std::string(::fuchsia::ledger::kPageIdSize, '2');
-
- delegate_.closed_and_synced = PagePredicateResult::YES;
- delegate_.closed_and_empty = PagePredicateResult::NO;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page1);
- page_eviction_manager_.MarkPageClosed(ledger_name, page1);
- page_eviction_manager_.MarkPageOpened(ledger_name, page2);
- page_eviction_manager_.MarkPageClosed(ledger_name, page2);
- RunLoopUntilIdle();
-
- bool called;
- Status status;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page1));
-}
-
-TEST_F(PageEvictionManagerTest, DontEvictIfPageWasOpenedDuringQuery) {
- std::string ledger_name = "ledger";
- storage::PageId page1 = std::string(::fuchsia::ledger::kPageIdSize, '1');
- storage::PageId page2 = std::string(::fuchsia::ledger::kPageIdSize, '2');
-
- // Page is offline and synced, but PageIsClosedOfflineAndEmpty returned
- // |PAGE_OPENED|, meaning it was opened during the operation. The page cannot
- // be evicted.
- delegate_.closed_and_synced = PagePredicateResult::YES;
- delegate_.closed_and_empty = PagePredicateResult::PAGE_OPENED;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page1);
- page_eviction_manager_.MarkPageClosed(ledger_name, page1);
- page_eviction_manager_.MarkPageOpened(ledger_name, page2);
- page_eviction_manager_.MarkPageClosed(ledger_name, page2);
- RunLoopUntilIdle();
-
- bool called;
- Status status;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
- delegate_.deleted_pages.clear();
-
- // Page is offline and empty, but PageIsClosedAndSynced returned
- // |PAGE_OPENED|. The page cannot be evicted.
- delegate_.closed_and_synced = PagePredicateResult::PAGE_OPENED;
- delegate_.closed_and_empty = PagePredicateResult::YES;
-
- page_eviction_manager_.MarkPageOpened(ledger_name, page2);
- page_eviction_manager_.MarkPageClosed(ledger_name, page2);
- RunLoopUntilIdle();
-
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-}
-
-TEST_F(PageEvictionManagerTest, IsEmpty) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
- bool on_empty_called = false;
-
- page_eviction_manager_.set_on_empty([&] { on_empty_called = true; });
-
- EXPECT_TRUE(page_eviction_manager_.IsEmpty());
- EXPECT_FALSE(on_empty_called);
-
- // PageEvictionManagerImpl should be empty if there is no pending operation
- // on: OnPageOpened, OnPageClosed, or TryEvictPages.
- on_empty_called = false;
- page_eviction_manager_.MarkPageOpened(ledger_name, page);
- EXPECT_FALSE(page_eviction_manager_.IsEmpty());
- EXPECT_FALSE(on_empty_called);
- RunLoopUntilIdle();
- EXPECT_TRUE(page_eviction_manager_.IsEmpty());
- EXPECT_TRUE(on_empty_called);
-
- on_empty_called = false;
- page_eviction_manager_.MarkPageClosed(ledger_name, page);
- EXPECT_FALSE(page_eviction_manager_.IsEmpty());
- EXPECT_FALSE(on_empty_called);
- RunLoopUntilIdle();
- EXPECT_TRUE(page_eviction_manager_.IsEmpty());
- EXPECT_TRUE(on_empty_called);
-
- bool called;
- Status status;
- on_empty_called = false;
- page_eviction_manager_.TryEvictPages(
- policy_.get(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- EXPECT_FALSE(page_eviction_manager_.IsEmpty());
- EXPECT_FALSE(on_empty_called);
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(page_eviction_manager_.IsEmpty());
- EXPECT_TRUE(on_empty_called);
-}
-
-TEST_F(PageEvictionManagerTest, TryEvictPage) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- // The page is not evicted if the result from PageIsClosedOfflineAndEmpty and
- // from PageIsClosedAndSynced is |NO|.
- delegate_.closed_and_empty = PagePredicateResult::NO;
- delegate_.closed_and_synced = PagePredicateResult::NO;
-
- bool called;
- Status status;
- PageWasEvicted was_evicted;
- page_eviction_manager_.TryEvictPage(
- ledger_name, page, PageEvictionCondition::IF_POSSIBLE,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &was_evicted));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(was_evicted);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-
- // The page is not evicted if the result from PageIsClosedOfflineAndEmpty is
- // |PAGE_OPENED|.
- delegate_.closed_and_empty = PagePredicateResult::PAGE_OPENED;
- delegate_.closed_and_synced = PagePredicateResult::YES;
- page_eviction_manager_.TryEvictPage(
- ledger_name, page, PageEvictionCondition::IF_POSSIBLE,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &was_evicted));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(was_evicted);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-
- // The page is not evicted if the result from PageIsClosedAndSynced is
- // |PAGE_OPENED|.
- delegate_.closed_and_empty = PagePredicateResult::YES;
- delegate_.closed_and_synced = PagePredicateResult::PAGE_OPENED;
- page_eviction_manager_.TryEvictPage(
- ledger_name, page, PageEvictionCondition::IF_POSSIBLE,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &was_evicted));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(was_evicted);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-
- // The page is evicted if the result from PageIsClosedOfflineAndEmpty is
- // |YES|.
- delegate_.closed_and_empty = PagePredicateResult::YES;
- delegate_.closed_and_synced = PagePredicateResult::NO;
- page_eviction_manager_.TryEvictPage(
- ledger_name, page, PageEvictionCondition::IF_POSSIBLE,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &was_evicted));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(was_evicted);
- EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page));
-
- // The page is evicted if the result from PageIsClosedAndSynced is |YES|.
- delegate_.deleted_pages.clear();
- delegate_.closed_and_empty = PagePredicateResult::NO;
- delegate_.closed_and_synced = PagePredicateResult::YES;
- page_eviction_manager_.TryEvictPage(
- ledger_name, page, PageEvictionCondition::IF_POSSIBLE,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &was_evicted));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(was_evicted);
- EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page));
-}
-
-TEST_F(PageEvictionManagerTest, EvictEmptyPage) {
- std::string ledger_name = "ledger";
- storage::PageId page = std::string(::fuchsia::ledger::kPageIdSize, '1');
-
- // The page is not evicted if the result from PageIsClosedOfflineAndEmpty is
- // |NO|.
- delegate_.closed_and_empty = PagePredicateResult::NO;
-
- bool called;
- Status status;
- PageWasEvicted was_evicted;
- page_eviction_manager_.TryEvictPage(
- ledger_name, page, PageEvictionCondition::IF_EMPTY,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &was_evicted));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(was_evicted);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-
- // The page is not evicted if the result from PageIsClosedOfflineAndEmpty is
- // |PAGE_OPENED|.
- delegate_.closed_and_empty = PagePredicateResult::PAGE_OPENED;
- page_eviction_manager_.TryEvictPage(
- ledger_name, page, PageEvictionCondition::IF_EMPTY,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &was_evicted));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(was_evicted);
- EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
-
- // The page is evicted if the result from PageIsClosedOfflineAndEmpty is
- // |YES|.
- delegate_.closed_and_empty = PagePredicateResult::YES;
- page_eviction_manager_.TryEvictPage(
- ledger_name, page, PageEvictionCondition::IF_EMPTY,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &was_evicted));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(was_evicted);
- EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page));
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/page_eviction_policies.cc b/bin/ledger/app/page_eviction_policies.cc
deleted file mode 100644
index df9af41..0000000
--- a/bin/ledger/app/page_eviction_policies.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_eviction_policies.h"
-
-#include "peridot/bin/ledger/coroutine/coroutine_manager.h"
-
-namespace ledger {
-namespace {
-
-// Computes the list of PageInfo for all pages that are not currently open,
-// ordered by the timestamp of their last usage, in ascending order.
-Status GetPagesByTimestamp(
- std::unique_ptr<storage::Iterator<const PageInfo>> pages_it,
- std::vector<PageInfo>* sorted_pages) {
- std::vector<PageInfo> pages;
- while (pages_it->Valid()) {
- // Sort out pages that are currently in use, i.e. those for which timestamp
- // is |PageInfo::kOpenedPageTimestamp|.
- if ((*pages_it)->timestamp != PageInfo::kOpenedPageTimestamp) {
- pages.push_back(**pages_it);
- }
- pages_it->Next();
- }
-
- // Order pages by the last used timestamp.
- std::sort(
- pages.begin(), pages.end(),
- [](const PageInfo& info1, const PageInfo& info2) {
- return std::tie(info1.timestamp, info1.ledger_name, info1.page_id) <
- std::tie(info2.timestamp, info2.ledger_name, info2.page_id);
- });
-
- sorted_pages->swap(pages);
- return Status::OK;
-}
-
-class LeastRecentlyUsedPageEvictionPolicy : public PageEvictionPolicy {
- public:
- LeastRecentlyUsedPageEvictionPolicy(
- coroutine::CoroutineService* coroutine_service,
- PageEvictionDelegate* delegate);
-
- void SelectAndEvict(std::unique_ptr<storage::Iterator<const PageInfo>> pages,
- fit::function<void(Status)> callback) override;
-
- private:
- PageEvictionDelegate* delegate_;
- coroutine::CoroutineManager coroutine_manager_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LeastRecentlyUsedPageEvictionPolicy);
-};
-
-LeastRecentlyUsedPageEvictionPolicy::LeastRecentlyUsedPageEvictionPolicy(
- coroutine::CoroutineService* coroutine_service,
- PageEvictionDelegate* delegate)
- : delegate_(delegate), coroutine_manager_(coroutine_service) {}
-
-void LeastRecentlyUsedPageEvictionPolicy::SelectAndEvict(
- std::unique_ptr<storage::Iterator<const PageInfo>> pages_it,
- fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback), [this, pages_it = std::move(pages_it)](
- coroutine::CoroutineHandler* handler,
- fit::function<void(Status)> callback) mutable {
- std::vector<PageInfo> pages;
- Status status = GetPagesByTimestamp(std::move(pages_it), &pages);
- if (status != Status::OK) {
- callback(status);
- return;
- }
- for (const auto& page_info : pages) {
- PageWasEvicted was_evicted;
- auto sync_call_status = coroutine::SyncCall(
- handler,
- [this, ledger_name = std::move(page_info.ledger_name),
- page_id = std::move(page_info.page_id)](auto callback) {
- delegate_->TryEvictPage(ledger_name, page_id,
- PageEvictionCondition::IF_POSSIBLE,
- std::move(callback));
- },
- &status, &was_evicted);
- if (sync_call_status == coroutine::ContinuationStatus::INTERRUPTED) {
- callback(Status::INTERNAL_ERROR);
- return;
- }
- if (status != Status::OK || was_evicted) {
- callback(status);
- return;
- }
- }
- callback(Status::OK);
- });
-}
-
-} // namespace
-
-std::unique_ptr<PageEvictionPolicy> NewLeastRecentyUsedPolicy(
- coroutine::CoroutineService* coroutine_service,
- PageEvictionDelegate* delegate) {
- return std::make_unique<LeastRecentlyUsedPageEvictionPolicy>(
- coroutine_service, delegate);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_eviction_policies.h b/bin/ledger/app/page_eviction_policies.h
deleted file mode 100644
index 2bb8d68..0000000
--- a/bin/ledger/app/page_eviction_policies.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_POLICIES_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_POLICIES_H_
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/app/types.h"
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/iterator.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-using PageWasEvicted = bool;
-
-// The policy for evicting pages.
-class PageEvictionPolicy {
- public:
- PageEvictionPolicy() {}
- virtual ~PageEvictionPolicy() {}
-
- // Given an iterator over all pages currently stored on disk, chooses and
- // tries to evict those that match the implementing policy. The status
- // returned through the |callback| will be |IO_ERROR| in case of failure
- // during trying to evict a page; |OK| otherwise. It is not an error if no
- // page was evited.
- virtual void SelectAndEvict(
- std::unique_ptr<storage::Iterator<const PageInfo>> pages,
- fit::function<void(Status)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageEvictionPolicy);
-};
-
-// The condition to be checked before evicting a page.
-enum PageEvictionCondition {
- // Indicates the page should be deleted if possible.
- IF_POSSIBLE,
- // Indicates the page should be deleted only if it is empty and offline.
- IF_EMPTY,
-};
-
-// The delegate used for the |PageEvictionPolicy|. Provides the methods
-// necessary to evict pages.
-class PageEvictionDelegate {
- public:
- PageEvictionDelegate() {}
- virtual ~PageEvictionDelegate() {}
-
- // Checks whether the given page can be evicted based on the given
- // |condition| and if it can, evicts it. Note that evicting a page with
- // |IF_EMPTY| has no observable effect for the user, i.e. doesn't break the
- // offline case. |IF_POSSIBLE| on the other hand means that a completely
- // synced page might be evicted, and thus become unavailable to the user, if
- // offline. Returns |IO_ERROR| through the callback in case of failure while
- // retrieving information on the page, or when trying to evict it; |OK|
- // otherwise. The boolean in the callback indicates whether the page was
- // evicted.
- virtual void TryEvictPage(
- fxl::StringView ledger_name, storage::PageIdView page_id,
- PageEvictionCondition condition,
- fit::function<void(Status, PageWasEvicted)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageEvictionDelegate);
-};
-
-// Creates and returns a new Least-Recently-Used policy, which evicts the least
-// recently used page among those that can be evicted. The given delegate should
-// outlive the returned object.
-std::unique_ptr<PageEvictionPolicy> NewLeastRecentyUsedPolicy(
- coroutine::CoroutineService* corroutine_service,
- PageEvictionDelegate* delegate);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_EVICTION_POLICIES_H_
diff --git a/bin/ledger/app/page_eviction_policies_unittest.cc b/bin/ledger/app/page_eviction_policies_unittest.cc
deleted file mode 100644
index a2e08fe..0000000
--- a/bin/ledger/app/page_eviction_policies_unittest.cc
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_eviction_policies.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-
-namespace ledger {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-
-// A wrapper storage::Iterator for the elements of an std::vector<T>.
-template <class T>
-class VectorIterator : public storage::Iterator<T> {
- public:
- VectorIterator(const std::vector<T>& v) : it_(v.begin()), end_(v.end()) {}
-
- ~VectorIterator() {}
-
- storage::Iterator<T>& Next() override {
- ++it_;
- return *this;
- }
-
- bool Valid() const override { return it_ != end_; }
-
- storage::Status GetStatus() const override { return storage::Status::OK; }
-
- T& operator*() const override { return *it_; }
-
- T* operator->() const override { return &*it_; }
-
- private:
- typename std::vector<T>::iterator it_;
- typename std::vector<T>::iterator end_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(VectorIterator);
-};
-
-// A fake PageEvictionDelegate, that stores the set of pages that were evicted.
-class FakePageEvictionDelegate : public PageEvictionDelegate {
- public:
- FakePageEvictionDelegate() {}
- ~FakePageEvictionDelegate() {}
-
- void TryEvictPage(fxl::StringView ledger_name, storage::PageIdView page_id,
- PageEvictionCondition condition,
- fit::function<void(Status, PageWasEvicted)> callback) {
- if (try_evict_page_status_ != Status::OK) {
- callback(try_evict_page_status_, PageWasEvicted(false));
- return;
- }
- if (pages_not_to_evict_.find(page_id.ToString()) !=
- pages_not_to_evict_.end()) {
- callback(Status::OK, PageWasEvicted(false));
- return;
- }
- evicted_pages_.push_back(page_id.ToString());
- callback(Status::OK, PageWasEvicted(true));
- }
-
- const std::vector<storage::PageId>& GetEvictedPages() {
- return evicted_pages_;
- }
-
- void SetPagesNotToEvict(std::set<storage::PageId> pages_not_to_evict) {
- pages_not_to_evict_ = std::move(pages_not_to_evict);
- }
-
- void SetTryEvictPageStatus(Status status) { try_evict_page_status_ = status; }
-
- private:
- // The vector of pages for which |TryEvictPage| returned PageWasEvicted(true).
- std::vector<storage::PageId> evicted_pages_;
- // Pages in this set will return PageWasEvicted(false) if TryEvictPage is
- // called on them.
- std::set<storage::PageId> pages_not_to_evict_;
- // The status to be returned by |TryEvictPage|.
- Status try_evict_page_status_ = Status::OK;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakePageEvictionDelegate);
-};
-
-using PageEvictionPoliciesTest = TestWithEnvironment;
-
-TEST_F(PageEvictionPoliciesTest, LeastRecentyUsed) {
- FakePageEvictionDelegate delegate;
- std::string ledger_name = "ledger";
- std::vector<const PageInfo> pages = {
- {ledger_name, "page1", zx::time_utc(1)},
- {ledger_name, "page2", zx::time_utc(2)},
- {ledger_name, "page3", zx::time_utc(3)},
- {ledger_name, "page4", zx::time_utc(4)},
- };
-
- std::unique_ptr<PageEvictionPolicy> policy =
- NewLeastRecentyUsedPolicy(environment_.coroutine_service(), &delegate);
-
- // Expect to only evict the least recently used page, i.e. "page1".
- bool called;
- Status status;
- policy->SelectAndEvict(
- std::make_unique<VectorIterator<const PageInfo>>(pages),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate.GetEvictedPages(), ElementsAre("page1"));
-}
-
-TEST_F(PageEvictionPoliciesTest, LeastRecentyUsedWithOpenPages) {
- FakePageEvictionDelegate delegate;
- std::string ledger_name = "ledger";
- std::vector<const PageInfo> pages = {
- {ledger_name, "page1", PageInfo::kOpenedPageTimestamp},
- {ledger_name, "page2", zx::time_utc(2)},
- {ledger_name, "page3", zx::time_utc(3)},
- {ledger_name, "page4", zx::time_utc(4)},
- };
-
- std::unique_ptr<PageEvictionPolicy> policy =
- NewLeastRecentyUsedPolicy(environment_.coroutine_service(), &delegate);
-
- // "page1" should not be evicted as it is marked as open. Expect to only evict
- // the least recently used page, i.e. "page2".
- bool called;
- Status status;
- policy->SelectAndEvict(
- std::make_unique<VectorIterator<const PageInfo>>(pages),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate.GetEvictedPages(), ElementsAre("page2"));
-}
-
-TEST_F(PageEvictionPoliciesTest, LeastRecentyUsedNoPagesToEvict) {
- FakePageEvictionDelegate delegate;
- std::string ledger_name = "ledger";
- std::vector<const PageInfo> pages = {
- {ledger_name, "page1", PageInfo::kOpenedPageTimestamp},
- {ledger_name, "page2", zx::time_utc(2)},
- {ledger_name, "page3", zx::time_utc(3)},
- {ledger_name, "page4", zx::time_utc(4)},
- };
-
- delegate.SetPagesNotToEvict({"page2", "page3", "page4"});
-
- std::unique_ptr<PageEvictionPolicy> policy =
- NewLeastRecentyUsedPolicy(environment_.coroutine_service(), &delegate);
-
- // "page1" is marked as open, and pages 2-4 will fail to be evicted. The
- // returned status should be ok, and not pages will be evicted.
- bool called;
- Status status;
- policy->SelectAndEvict(
- std::make_unique<VectorIterator<const PageInfo>>(pages),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_THAT(delegate.GetEvictedPages(), IsEmpty());
-}
-
-TEST_F(PageEvictionPoliciesTest, LeastRecentyUsedErrorWhileEvicting) {
- FakePageEvictionDelegate delegate;
- std::string ledger_name = "ledger";
- std::vector<const PageInfo> pages = {
- {ledger_name, "page1", zx::time_utc(1)},
- {ledger_name, "page2", zx::time_utc(2)},
- {ledger_name, "page3", zx::time_utc(3)},
- {ledger_name, "page4", zx::time_utc(4)},
- };
- delegate.SetTryEvictPageStatus(Status::INTERNAL_ERROR);
-
- // If |TryEvictPage| fails, so should |SelectAndEvict|. Expect to find the
- // same error status.
- std::unique_ptr<PageEvictionPolicy> policy =
- NewLeastRecentyUsedPolicy(environment_.coroutine_service(), &delegate);
- bool called;
- Status status;
- policy->SelectAndEvict(
- std::make_unique<VectorIterator<const PageInfo>>(pages),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::INTERNAL_ERROR, status);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/page_impl.cc b/bin/ledger/app/page_impl.cc
deleted file mode 100644
index 32946f3..0000000
--- a/bin/ledger/app/page_impl.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_impl.h"
-
-#include <lib/callback/trace_callback.h>
-#include <lib/fxl/logging.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/app/page_delaying_facade.h"
-
-namespace ledger {
-
-PageImpl::PageImpl(PageDelayingFacade* delaying_facade)
- : delaying_facade_(delaying_facade) {}
-
-PageImpl::~PageImpl() {}
-
-void PageImpl::GetId(GetIdCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_get_id");
- delaying_facade_->GetId(std::move(timed_callback));
-}
-
-void PageImpl::GetSnapshot(
- fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- std::vector<uint8_t> key_prefix,
- fidl::InterfaceHandle<PageWatcher> watcher, GetSnapshotCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_get_snapshot");
- delaying_facade_->GetSnapshot(std::move(snapshot_request),
- std::move(key_prefix), std::move(watcher),
- std::move(timed_callback));
-}
-
-void PageImpl::Put(std::vector<uint8_t> key, std::vector<uint8_t> value,
- PutCallback callback) {
- PutWithPriority(std::move(key), std::move(value), Priority::EAGER,
- std::move(callback));
-}
-
-void PageImpl::PutWithPriority(std::vector<uint8_t> key,
- std::vector<uint8_t> value,
- Priority priority,
- PutWithPriorityCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_put_with_priority");
- delaying_facade_->PutWithPriority(std::move(key), std::move(value), priority,
- std::move(timed_callback));
-}
-
-void PageImpl::PutReference(std::vector<uint8_t> key, Reference reference,
- Priority priority, PutReferenceCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_put_reference");
- delaying_facade_->PutReference(std::move(key), std::move(reference), priority,
- std::move(timed_callback));
-}
-
-void PageImpl::Delete(std::vector<uint8_t> key, DeleteCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_delete");
- delaying_facade_->Delete(std::move(key), std::move(timed_callback));
-}
-
-void PageImpl::Clear(ClearCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_clear");
- delaying_facade_->Clear(std::move(timed_callback));
-}
-
-void PageImpl::CreateReferenceFromSocket(
- uint64_t size, zx::socket data,
- CreateReferenceFromSocketCallback callback) {
- auto timed_callback = TRACE_CALLBACK(std::move(callback), "ledger",
- "page_create_reference_from_socket");
- delaying_facade_->CreateReference(
- storage::DataSource::Create(std::move(data), size),
- std::move(timed_callback));
-}
-
-void PageImpl::CreateReferenceFromBuffer(
- fuchsia::mem::Buffer data, CreateReferenceFromBufferCallback callback) {
- auto timed_callback = TRACE_CALLBACK(std::move(callback), "ledger",
- "page_create_reference_from_vmo");
- fsl::SizedVmo vmo;
- if (!fsl::SizedVmo::FromTransport(std::move(data), &vmo)) {
- callback(Status::INVALID_ARGUMENT, nullptr);
- return;
- }
- delaying_facade_->CreateReference(storage::DataSource::Create(std::move(vmo)),
- std::move(timed_callback));
-}
-
-void PageImpl::StartTransaction(StartTransactionCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_start_transaction");
- delaying_facade_->StartTransaction(std::move(timed_callback));
-}
-
-void PageImpl::Commit(CommitCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_commit");
- delaying_facade_->Commit(std::move(timed_callback));
-}
-
-void PageImpl::Rollback(RollbackCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_rollback");
- delaying_facade_->Rollback(std::move(timed_callback));
-}
-
-void PageImpl::SetSyncStateWatcher(fidl::InterfaceHandle<SyncWatcher> watcher,
- SetSyncStateWatcherCallback callback) {
- delaying_facade_->SetSyncStateWatcher(std::move(watcher),
- std::move(callback));
-}
-
-void PageImpl::WaitForConflictResolution(
- WaitForConflictResolutionCallback callback) {
- delaying_facade_->WaitForConflictResolution(std::move(callback));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_impl.h b/bin/ledger/app/page_impl.h
deleted file mode 100644
index 2c2c748..0000000
--- a/bin/ledger/app/page_impl.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_IMPL_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_IMPL_H_
-
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace ledger {
-class PageDelayingFacade;
-
-// An implementation of the |Page| FIDL interface.
-class PageImpl : public Page {
- public:
- explicit PageImpl(PageDelayingFacade* delaying_facade);
- ~PageImpl() override;
-
- private:
- // Page:
- void GetId(GetIdCallback callback) override;
-
- void GetSnapshot(fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- std::vector<uint8_t> key_prefix,
- fidl::InterfaceHandle<PageWatcher> watcher,
- GetSnapshotCallback callback) override;
-
- void Put(std::vector<uint8_t> key, std::vector<uint8_t> value,
- PutCallback callback) override;
-
- void PutWithPriority(std::vector<uint8_t> key,
- std::vector<uint8_t> value, Priority priority,
- PutWithPriorityCallback callback) override;
-
- void PutReference(std::vector<uint8_t> key, Reference reference,
- Priority priority, PutReferenceCallback callback) override;
-
- void Delete(std::vector<uint8_t> key, DeleteCallback callback) override;
-
- void Clear(ClearCallback callback) override;
-
- void CreateReferenceFromSocket(
- uint64_t size, zx::socket data,
- CreateReferenceFromSocketCallback callback) override;
-
- void CreateReferenceFromBuffer(
- fuchsia::mem::Buffer data,
- CreateReferenceFromBufferCallback callback) override;
-
- void StartTransaction(StartTransactionCallback callback) override;
-
- void Commit(CommitCallback callback) override;
-
- void Rollback(RollbackCallback callback) override;
-
- void SetSyncStateWatcher(fidl::InterfaceHandle<SyncWatcher> watcher,
- SetSyncStateWatcherCallback callback) override;
-
- void WaitForConflictResolution(
- WaitForConflictResolutionCallback callback) override;
-
- PageDelayingFacade* delaying_facade_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageImpl);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_IMPL_H_
diff --git a/bin/ledger/app/page_impl_unittest.cc b/bin/ledger/app/page_impl_unittest.cc
deleted file mode 100644
index bf0e35b..0000000
--- a/bin/ledger/app/page_impl_unittest.cc
+++ /dev/null
@@ -1,1753 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_impl.h"
-
-#include <algorithm>
-#include <map>
-#include <memory>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_printf.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-#include "peridot/bin/ledger/app/page_manager.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/storage/fake/fake_journal.h"
-#include "peridot/bin/ledger/storage/fake/fake_journal_delegate.h"
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-#include "peridot/bin/ledger/storage/testing/storage_matcher.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/convert/convert.h"
-
-using testing::Contains;
-using testing::ElementsAre;
-using testing::IsEmpty;
-using testing::Key;
-using testing::Not;
-using testing::Pair;
-using testing::SizeIs;
-
-namespace ledger {
-namespace {
-
-std::string ToString(const fuchsia::mem::BufferPtr& vmo) {
- std::string value;
- bool status = fsl::StringFromVmo(*vmo, &value);
- FXL_DCHECK(status);
- return value;
-}
-
-class PageImplTest : public TestWithEnvironment {
- public:
- PageImplTest() {}
- ~PageImplTest() override {}
-
- protected:
- // ApplicationTestBase:
- void SetUp() override {
- ::testing::Test::SetUp();
- page_id1_ = storage::PageId(::fuchsia::ledger::kPageIdSize, 'a');
- auto fake_storage = std::make_unique<storage::fake::FakePageStorage>(
- &environment_, page_id1_);
- fake_storage_ = fake_storage.get();
- auto resolver = std::make_unique<MergeResolver>(
- [] {}, &environment_, fake_storage_,
- std::make_unique<backoff::ExponentialBackoff>(
- zx::sec(0), 1u, zx::sec(0),
- environment_.random()->NewBitGenerator<uint64_t>()));
- resolver_ = resolver.get();
-
- manager_ = std::make_unique<PageManager>(
- &environment_, std::move(fake_storage), nullptr, std::move(resolver),
- PageManager::PageStorageState::NEEDS_SYNC);
- bool called;
- Status status;
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id1_, page_ptr_.NewRequest());
- manager_->AddPageDelayingFacade(
- std::move(delaying_facade),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- DrainLoop();
- }
-
- // Run the message loop until there is nothing left to dispatch.
- void DrainLoop() {
- RunLoopRepeatedlyFor(storage::fake::kFakePageStorageDelay);
- }
-
- void CommitFirstPendingJournal(
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals) {
- for (const auto& journal_pair : journals) {
- const auto& journal = journal_pair.second;
- if (!journal->IsCommitted() && !journal->IsRolledBack()) {
- journal->ResolvePendingCommit(storage::Status::OK);
- return;
- }
- }
- }
-
- storage::ObjectIdentifier AddObjectToStorage(std::string value_string) {
- bool called;
- storage::Status status;
- storage::ObjectIdentifier object_identifier;
- fake_storage_->AddObjectFromLocal(
- storage::ObjectType::BLOB,
- storage::DataSource::Create(std::move(value_string)),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- return object_identifier;
- }
-
- std::unique_ptr<const storage::Object> AddObject(const std::string& value) {
- storage::ObjectIdentifier object_identifier = AddObjectToStorage(value);
-
- bool called;
- storage::Status status;
- std::unique_ptr<const storage::Object> object;
- fake_storage_->GetObject(
- object_identifier, storage::PageStorage::Location::LOCAL,
- callback::Capture(callback::SetWhenCalled(&called), &status, &object));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- return object;
- }
-
- std::string GetKey(size_t index, size_t min_key_size = 0u) {
- std::string result = fxl::StringPrintf("key %04" PRIuMAX, index);
- result.resize(std::max(result.size(), min_key_size));
- return result;
- }
-
- std::string GetValue(size_t index, size_t min_value_size = 0u) {
- std::string result = fxl::StringPrintf("val %zu", index);
- result.resize(std::max(result.size(), min_value_size));
- return result;
- }
-
- void AddEntries(int entry_count, size_t min_key_size = 0u,
- size_t min_value_size = 0u) {
- FXL_DCHECK(entry_count <= 10000);
- bool called;
- Status status;
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- for (int i = 0; i < entry_count; ++i) {
- page_ptr_->Put(
- convert::ToArray(GetKey(i, min_key_size)),
- convert::ToArray(GetValue(i, min_value_size)),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- }
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- }
-
- PageSnapshotPtr GetSnapshot(
- std::vector<uint8_t> prefix = std::vector<uint8_t>()) {
- bool called;
- Status status;
- PageSnapshotPtr snapshot;
- page_ptr_->GetSnapshot(
- snapshot.NewRequest(), std::move(prefix), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(status, Status::OK);
- return snapshot;
- }
-
- storage::PageId page_id1_;
- storage::fake::FakePageStorage* fake_storage_;
- std::unique_ptr<PageManager> manager_;
- MergeResolver* resolver_;
-
- PagePtr page_ptr_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageImplTest);
-};
-
-TEST_F(PageImplTest, GetId) {
- bool called;
- PageId page_id;
- page_ptr_->GetId(
- callback::Capture(callback::SetWhenCalled(&called), &page_id));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(page_id1_, convert::ToString(page_id.id));
-}
-
-TEST_F(PageImplTest, PutNoTransaction) {
- std::string key("some_key");
- std::string value("a small value");
- bool called;
- Status status;
- page_ptr_->Put(convert::ToArray(key), convert::ToArray(value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- auto objects = fake_storage_->GetObjects();
- EXPECT_EQ(1u, objects.size());
- storage::ObjectIdentifier object_identifier = objects.begin()->first;
- std::string actual_value = objects.begin()->second;
- EXPECT_EQ(value, actual_value);
-
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_TRUE(it->second->IsCommitted());
- EXPECT_EQ(1u, it->second->GetData().size());
- storage::Entry entry = it->second->GetData().at(key);
- EXPECT_EQ(object_identifier, entry.object_identifier);
- EXPECT_EQ(storage::KeyPriority::EAGER, entry.priority);
-}
-
-TEST_F(PageImplTest, PutReferenceNoTransaction) {
- std::string object_data("some_data");
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(object_data, &vmo));
-
- bool called;
- Status status;
- ReferencePtr reference;
- page_ptr_->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- callback::Capture(callback::SetWhenCalled(&called), &status, &reference));
- DrainLoop();
-
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- std::string key("some_key");
- page_ptr_->PutReference(
- convert::ToArray(key), std::move(*reference), Priority::LAZY,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- auto objects = fake_storage_->GetObjects();
- // No object should have been added.
- EXPECT_EQ(1u, objects.size());
-
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_TRUE(it->second->IsCommitted());
- EXPECT_EQ(1u, it->second->GetData().size());
- storage::Entry entry = it->second->GetData().at(key);
- std::unique_ptr<const storage::Object> object = AddObject(object_data);
- EXPECT_EQ(object->GetIdentifier().object_digest(),
- entry.object_identifier.object_digest());
- EXPECT_EQ(storage::KeyPriority::LAZY, entry.priority);
-}
-
-TEST_F(PageImplTest, PutUnknownReference) {
- std::string key("some_key");
- ReferencePtr reference = Reference::New();
- reference->opaque_id = convert::ToArray("12345678");
-
- bool called;
- Status status;
- page_ptr_->PutReference(
- convert::ToArray(key), std::move(*reference), Priority::LAZY,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::REFERENCE_NOT_FOUND, status);
- auto objects = fake_storage_->GetObjects();
- // No object should have been added.
- EXPECT_EQ(0u, objects.size());
-
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(0u, journals.size());
-}
-
-TEST_F(PageImplTest, PutKeyTooLarge) {
- std::string value("a small value");
-
- zx::channel writer, reader;
- ASSERT_EQ(ZX_OK, zx::channel::create(0, &writer, &reader));
- page_ptr_.Bind(std::move(writer));
-
- // Key too large; message doesn't go through, failing on validation.
- const size_t key_size = kMaxKeySize + 1;
- std::string key = GetKey(1, key_size);
- page_ptr_->Put(convert::ToArray(key), convert::ToArray(value),
- [](Status status) {});
- zx_status_t status = reader.read(0, nullptr, 0, nullptr, nullptr, 0, nullptr);
- DrainLoop();
- EXPECT_EQ(ZX_ERR_SHOULD_WAIT, status);
-
- // With a smaller key, message goes through.
- key = GetKey(1, kMaxKeySize);
- page_ptr_->Put(convert::ToArray(key), convert::ToArray(value),
- [](Status status) {});
- status = reader.read(0, nullptr, 0, nullptr, nullptr, 0, nullptr);
- DrainLoop();
- EXPECT_EQ(ZX_ERR_BUFFER_TOO_SMALL, status);
-}
-
-TEST_F(PageImplTest, PutReferenceKeyTooLarge) {
- std::string object_data("some_data");
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(object_data, &vmo));
-
- bool called;
- Status reference_status;
- ReferencePtr reference;
- page_ptr_->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- callback::Capture(callback::SetWhenCalled(&called), &reference_status,
- &reference));
- DrainLoop();
- ASSERT_EQ(Status::OK, reference_status);
-
- zx::channel writer, reader;
- ASSERT_EQ(ZX_OK, zx::channel::create(0, &writer, &reader));
- page_ptr_.Bind(std::move(writer));
-
- // Key too large; message doesn't go through, failing on validation.
- const size_t key_size = kMaxKeySize + 1;
- std::string key = GetKey(1, key_size);
- page_ptr_->PutReference(convert::ToArray(key), fidl::Clone(*reference),
- Priority::EAGER, [](Status status) {});
- zx_status_t status = reader.read(0, nullptr, 0, nullptr, nullptr, 0, nullptr);
- DrainLoop();
- EXPECT_EQ(ZX_ERR_SHOULD_WAIT, status);
-
- // With a smaller key, message goes through.
- key = GetKey(1, kMaxKeySize);
- page_ptr_->PutReference(convert::ToArray(key), std::move(*reference),
- Priority::EAGER, [](Status status) {});
- status = reader.read(0, nullptr, 0, nullptr, nullptr, 0, nullptr);
- DrainLoop();
- EXPECT_EQ(ZX_ERR_BUFFER_TOO_SMALL, status);
-}
-
-TEST_F(PageImplTest, DeleteNoTransaction) {
- std::string key("some_key");
-
- bool called;
- Status status;
- page_ptr_->Delete(
- convert::ToArray(key),
- callback::Capture(callback::SetWhenCalled(&called), &status));
-
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- auto objects = fake_storage_->GetObjects();
- // No object should have been added.
- EXPECT_EQ(0u, objects.size());
-
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_TRUE(it->second->IsCommitted());
- EXPECT_THAT(it->second->GetData(), IsEmpty());
-}
-
-TEST_F(PageImplTest, ClearNoTransaction) {
- bool called;
- Status status;
- page_ptr_->Clear(
- callback::Capture(callback::SetWhenCalled(&called), &status));
-
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- auto objects = fake_storage_->GetObjects();
- // No object should have been added.
- EXPECT_THAT(objects, IsEmpty());
-
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_TRUE(it->second->IsCommitted());
- EXPECT_THAT(it->second->GetData(), IsEmpty());
-}
-
-TEST_F(PageImplTest, TransactionCommit) {
- std::string key1("some_key1");
- storage::ObjectDigest object_digest1;
- std::string value("a small value");
-
- std::string key2("some_key2");
- std::string value2("another value");
-
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(value2, &vmo));
-
- bool called;
- Status status;
- ReferencePtr reference;
- page_ptr_->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- callback::Capture(callback::SetWhenCalled(&called), &status, &reference));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- // Sequence of operations:
- // - StartTransaction
- // - Put
- // - PutReference
- // - Delete
- // - Commit
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Put(convert::ToArray(key1), convert::ToArray(value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- {
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- auto objects = fake_storage_->GetObjects();
- EXPECT_EQ(2u, objects.size());
- // Objects are ordered by a randomly assigned object id, so we can't know
- // the correct possition of the value in the map.
- bool object_found = false;
- for (const auto& object : objects) {
- if (object.second == value) {
- object_found = true;
- object_digest1 = object.first.object_digest();
- break;
- }
- }
- EXPECT_TRUE(object_found);
-
- // No finished commit yet.
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_FALSE(it->second->IsCommitted());
- EXPECT_EQ(1u, it->second->GetData().size());
- storage::Entry entry = it->second->GetData().at(key1);
- EXPECT_EQ(object_digest1, entry.object_identifier.object_digest());
- EXPECT_EQ(storage::KeyPriority::EAGER, entry.priority);
- }
-
- page_ptr_->PutReference(
- convert::ToArray(key2), std::move(*reference), Priority::LAZY,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- {
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(2u, fake_storage_->GetObjects().size());
-
- // No finished commit yet, with now two entries.
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_FALSE(it->second->IsCommitted());
- EXPECT_EQ(2u, it->second->GetData().size());
- storage::Entry entry = it->second->GetData().at(key2);
- EXPECT_EQ(AddObject(value2)->GetIdentifier().object_digest(),
- entry.object_identifier.object_digest());
- EXPECT_EQ(storage::KeyPriority::LAZY, entry.priority);
- }
-
- page_ptr_->Delete(
- convert::ToArray(key2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- {
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(2u, fake_storage_->GetObjects().size());
-
- // No finished commit yet, with the second entry deleted.
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_FALSE(it->second->IsCommitted());
- EXPECT_EQ(1u, it->second->GetData().size());
- EXPECT_THAT(it->second->GetData(), Not(Contains(Key(key2))));
- }
-
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- {
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(2u, fake_storage_->GetObjects().size());
-
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_TRUE(it->second->IsCommitted());
- EXPECT_EQ(1u, it->second->GetData().size());
- }
-}
-
-TEST_F(PageImplTest, TransactionClearCommit) {
- std::string key1("some_key1");
- std::string value1("a small value");
-
- std::string key2("some_key2");
- std::string value2("another value");
- storage::ObjectDigest object_digest2;
-
- bool called;
- Status status;
-
- // Sequence of operations:
- // - Put key1
- // - StartTransaction
- // - Clear
- // - Put key2
- // - Commit
-
- page_ptr_->Put(convert::ToArray(key1), convert::ToArray(value1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- {
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- }
-
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(2u, journals.size());
- const auto& journal_it = std::find_if(
- journals.begin(), journals.end(),
- [](const auto& pair) { return !pair.second->IsCommitted(); });
- EXPECT_NE(journals.end(), journal_it);
- const auto& journal = journal_it->second;
-
- {
- EXPECT_FALSE(journal->IsCommitted());
- EXPECT_THAT(journal->GetData(), SizeIs(1));
- }
-
- page_ptr_->Clear(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- {
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1u, fake_storage_->GetObjects().size());
-
- EXPECT_FALSE(journal->IsCommitted());
- EXPECT_THAT(journal->GetData(), IsEmpty());
- }
-
- page_ptr_->Put(convert::ToArray(key2), convert::ToArray(value2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- {
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- auto objects = fake_storage_->GetObjects();
- EXPECT_EQ(2u, objects.size());
- bool object_found = false;
- for (const auto& object : objects) {
- if (object.second == value2) {
- object_found = true;
- object_digest2 = object.first.object_digest();
- break;
- }
- }
- EXPECT_TRUE(object_found);
-
- // No finished commit yet.
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_THAT(journals, SizeIs(2));
- EXPECT_FALSE(journal->IsCommitted());
- EXPECT_THAT(journal->GetData(),
- ElementsAre(Pair(
- key2, storage::MatchesEntry(
- {key2, storage::MatchesDigest(object_digest2),
- storage::KeyPriority::EAGER}))));
- }
-
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
-
- {
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(2u, fake_storage_->GetObjects().size());
-
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_THAT(journals, SizeIs(2));
- EXPECT_TRUE(journal->IsCommitted());
- EXPECT_THAT(journal->GetData(),
- ElementsAre(Pair(
- key2, storage::MatchesEntry(
- {key2, storage::MatchesDigest(object_digest2),
- storage::KeyPriority::EAGER}))));
- }
-}
-
-TEST_F(PageImplTest, TransactionRollback) {
- // Sequence of operations:
- // - StartTransaction
- // - Rollback
- bool called_start;
- Status status_start;
- bool called_rollback;
- Status status_rollback;
-
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called_start), &status_start));
- page_ptr_->Rollback(callback::Capture(
- callback::SetWhenCalled(&called_rollback), &status_rollback));
-
- DrainLoop();
- EXPECT_TRUE(called_start);
- EXPECT_EQ(Status::OK, status_start);
- EXPECT_TRUE(called_rollback);
- EXPECT_EQ(Status::OK, status_rollback);
- EXPECT_EQ(0u, fake_storage_->GetObjects().size());
-
- // Only one journal, rollbacked.
- const std::map<std::string,
- std::unique_ptr<storage::fake::FakeJournalDelegate>>&
- journals = fake_storage_->GetJournals();
- EXPECT_EQ(1u, journals.size());
- auto it = journals.begin();
- EXPECT_TRUE(it->second->IsRolledBack());
- EXPECT_EQ(0u, it->second->GetData().size());
-}
-
-TEST_F(PageImplTest, NoTwoTransactions) {
- // Sequence of operations:
- // - StartTransaction
- // - StartTransaction
- bool called1;
- Status status1;
- bool called2;
- Status status2;
-
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called1), &status1));
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called2), &status2));
-
- DrainLoop();
- EXPECT_TRUE(called1);
- EXPECT_EQ(Status::OK, status1);
- EXPECT_TRUE(called2);
- EXPECT_EQ(Status::TRANSACTION_ALREADY_IN_PROGRESS, status2);
-}
-
-TEST_F(PageImplTest, NoTransactionCommit) {
- // Sequence of operations:
- // - Commit
- bool called;
- Status status;
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::NO_TRANSACTION_IN_PROGRESS, status);
-}
-
-TEST_F(PageImplTest, NoTransactionRollback) {
- // Sequence of operations:
- // - Rollback
- bool called;
- Status status;
- page_ptr_->Rollback(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::NO_TRANSACTION_IN_PROGRESS, status);
-}
-
-TEST_F(PageImplTest, CreateReferenceFromSocket) {
- ASSERT_EQ(0u, fake_storage_->GetObjects().size());
-
- std::string value("a small value");
- bool called;
- Status status;
- ReferencePtr reference;
- page_ptr_->CreateReferenceFromSocket(
- value.size(), fsl::WriteStringToSocket(value),
- callback::Capture(callback::SetWhenCalled(&called), &status, &reference));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- ASSERT_EQ(1u, fake_storage_->GetObjects().size());
- ASSERT_EQ(value, fake_storage_->GetObjects().begin()->second);
-}
-
-TEST_F(PageImplTest, CreateReferenceFromBuffer) {
- ASSERT_EQ(0u, fake_storage_->GetObjects().size());
-
- std::string value("a small value");
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(value, &vmo));
-
- bool called;
- Status status;
- ReferencePtr reference;
- page_ptr_->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- callback::Capture(callback::SetWhenCalled(&called), &status, &reference));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- ASSERT_EQ(1u, fake_storage_->GetObjects().size());
- ASSERT_EQ(value, fake_storage_->GetObjects().begin()->second);
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntries) {
- std::string eager_key("a_key");
- std::string eager_value("an eager value");
- std::string lazy_key("another_key");
- std::string lazy_value("a lazy value");
-
- bool called;
- Status status;
- page_ptr_->Put(convert::ToArray(eager_key), convert::ToArray(eager_value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- status = Status::UNKNOWN_ERROR;
- page_ptr_->PutWithPriority(
- convert::ToArray(lazy_key), convert::ToArray(lazy_value), Priority::LAZY,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- std::vector<Entry> actual_entries;
- std::unique_ptr<Token> next_token;
- snapshot->GetEntries(
- std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(next_token);
- ASSERT_EQ(2u, actual_entries.size());
- EXPECT_EQ(eager_key, convert::ExtendedStringView(actual_entries.at(0).key));
- EXPECT_EQ(eager_value, ToString(actual_entries.at(0).value));
- EXPECT_EQ(Priority::EAGER, actual_entries.at(0).priority);
-
- EXPECT_EQ(lazy_key, convert::ExtendedStringView(actual_entries.at(1).key));
- EXPECT_EQ(lazy_value, ToString(actual_entries.at(1).value));
- EXPECT_EQ(Priority::LAZY, actual_entries.at(1).priority);
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntriesInline) {
- std::string eager_key("a_key");
- std::string eager_value("an eager value");
- std::string lazy_key("another_key");
- std::string lazy_value("a lazy value");
-
- bool called;
- Status status;
- page_ptr_->Put(convert::ToArray(eager_key), convert::ToArray(eager_value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
-
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->PutWithPriority(
- convert::ToArray(lazy_key), convert::ToArray(lazy_value), Priority::LAZY,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- std::unique_ptr<Token> next_token;
- std::vector<InlinedEntry> actual_entries;
- snapshot->GetEntriesInline(
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(next_token);
-
- ASSERT_EQ(2u, actual_entries.size());
- EXPECT_EQ(eager_key, convert::ExtendedStringView(actual_entries.at(0).key));
- EXPECT_TRUE(actual_entries.at(0).inlined_value);
- EXPECT_EQ(eager_value,
- convert::ToString(actual_entries.at(0).inlined_value->value));
- EXPECT_EQ(Priority::EAGER, actual_entries.at(0).priority);
-
- EXPECT_EQ(lazy_key, convert::ExtendedStringView(actual_entries.at(1).key));
- EXPECT_TRUE(actual_entries.at(1).inlined_value);
- EXPECT_EQ(lazy_value,
- convert::ToString(actual_entries.at(1).inlined_value->value));
- EXPECT_EQ(Priority::LAZY, actual_entries.at(1).priority);
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntriesWithTokenForSize) {
- const size_t min_key_size = kMaxKeySize;
- // Put enough entries to ensure pagination of the result.
- // The number of entries in a Page is bounded by the maximum number of
- // handles, and the size of a fidl message (which cannot exceed
- // |kMaxInlineDataSize|), so we put one entry more than that.
- const size_t entry_count =
- std::min(fidl_serialization::kMaxMessageHandles,
- (fidl_serialization::kMaxInlineDataSize -
- fidl_serialization::kVectorHeaderSize) /
- fidl_serialization::GetEntrySize(min_key_size)) +
- 1;
- AddEntries(entry_count, min_key_size);
- PageSnapshotPtr snapshot = GetSnapshot();
-
- // Call GetEntries and find a partial result.
- bool called;
- Status status;
- std::vector<Entry> actual_entries;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetEntries(
- std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PARTIAL_RESULT, status);
- EXPECT_TRUE(actual_next_token);
-
- // Call GetEntries with the previous token and receive the remaining results.
- std::vector<Entry> actual_next_entries;
- snapshot->GetEntries(
- std::vector<uint8_t>(), std::move(actual_next_token),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_next_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
-
- for (auto& entry : actual_next_entries) {
- actual_entries.push_back(std::move(entry));
- }
- EXPECT_EQ(static_cast<size_t>(entry_count), actual_entries.size());
-
- // Check that the correct values of the keys are all present in the result and
- // in the correct order.
- for (int i = 0; i < static_cast<int>(actual_entries.size()); ++i) {
- ASSERT_EQ(GetKey(i, min_key_size),
- convert::ToString(actual_entries.at(i).key));
- ASSERT_EQ(GetValue(i, 0), ToString(actual_entries.at(i).value));
- }
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntriesInlineWithTokenForSize) {
- const size_t entry_count = 20;
- const size_t min_value_size =
- fidl_serialization::kMaxInlineDataSize * 3 / 2 / entry_count;
- AddEntries(entry_count, 0, min_value_size);
- PageSnapshotPtr snapshot = GetSnapshot();
-
- // Call GetEntries and find a partial result.
- bool called;
- Status status;
- std::vector<InlinedEntry> actual_entries;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetEntriesInline(
- std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PARTIAL_RESULT, status);
- EXPECT_TRUE(actual_next_token);
-
- // Call GetEntries with the previous token and receive the remaining results.
- std::vector<InlinedEntry> actual_entries2;
- std::unique_ptr<Token> actual_next_token2;
- snapshot->GetEntriesInline(
- std::vector<uint8_t>(), std::move(actual_next_token),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries2, &actual_next_token2));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token2);
- for (auto& entry : actual_entries2) {
- actual_entries.push_back(std::move(entry));
- }
- EXPECT_EQ(static_cast<size_t>(entry_count), actual_entries.size());
-
- // Check that the correct values of the keys are all present in the result and
- // in the correct order.
- for (int i = 0; i < static_cast<int>(actual_entries.size()); ++i) {
- ASSERT_EQ(GetKey(i, 0), convert::ToString(actual_entries.at(i).key));
- ASSERT_TRUE(actual_entries.at(i).inlined_value);
- ASSERT_EQ(GetValue(i, min_value_size),
- convert::ToString(actual_entries.at(i).inlined_value->value));
- }
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntriesInlineWithTokenForEntryCount) {
- const size_t min_key_size = 8;
- const size_t min_value_size = 1;
- // Approximate size of the entry: takes into account size of the pointers for
- // key, object and entry itself; enum size for Priority and size of the header
- // for the InlinedEntry struct.
- const size_t min_entry_size =
- fidl_serialization::Align(fidl_serialization::kPriorityEnumSize) +
- fidl_serialization::GetByteVectorSize(min_key_size) +
- fidl_serialization::GetByteVectorSize(min_value_size);
- // Put enough inlined entries to cause pagination based on size of the
- // message.
- const size_t entry_count =
- fidl_serialization::kMaxInlineDataSize * 3 / 2 / min_entry_size;
- AddEntries(entry_count, 0, min_value_size);
- PageSnapshotPtr snapshot = GetSnapshot();
-
- // Call GetEntries and find a partial result.
- bool called;
- Status status;
- std::vector<InlinedEntry> actual_entries;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetEntriesInline(
- std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PARTIAL_RESULT, status);
- EXPECT_TRUE(actual_next_token);
-
- // Call GetEntries with the previous token and receive the remaining results.
- std::vector<InlinedEntry> actual_entries2;
- std::unique_ptr<Token> actual_next_token2;
- snapshot->GetEntriesInline(
- std::vector<uint8_t>(), std::move(actual_next_token),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries2, &actual_next_token2));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token2);
- for (auto& entry : actual_entries2) {
- actual_entries.push_back(std::move(entry));
- }
- EXPECT_EQ(static_cast<size_t>(entry_count), actual_entries.size());
-
- // Check that the correct values of the keys are all present in the result and
- // in the correct order.
- for (int i = 0; i < static_cast<int>(actual_entries.size()); ++i) {
- ASSERT_EQ(GetKey(i, 0), convert::ToString(actual_entries.at(i).key));
- ASSERT_TRUE(actual_entries.at(i).inlined_value);
- ASSERT_EQ(GetValue(i, min_value_size),
- convert::ToString(actual_entries.at(i).inlined_value->value));
- }
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntriesWithTokenForHandles) {
- const size_t entry_count = 100;
- AddEntries(entry_count);
- PageSnapshotPtr snapshot = GetSnapshot();
-
- // Call GetEntries and find a partial result.
- bool called;
- Status status;
- std::vector<Entry> actual_entries;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetEntries(
- std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PARTIAL_RESULT, status);
- EXPECT_TRUE(actual_next_token);
-
- // Call GetEntries with the previous token and receive the remaining results.
- std::vector<Entry> actual_next_entries;
- snapshot->GetEntries(
- std::vector<uint8_t>(), std::move(actual_next_token),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_next_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- for (auto& entry : actual_next_entries) {
- actual_entries.push_back(std::move(entry));
- }
- EXPECT_EQ(static_cast<size_t>(entry_count), actual_entries.size());
-
- // Check that the correct values of the keys are all present in the result and
- // in the correct order.
- for (int i = 0; i < static_cast<int>(actual_entries.size()); ++i) {
- ASSERT_EQ(GetKey(i), convert::ToString(actual_entries.at(i).key));
- ASSERT_EQ(GetValue(i, 0), ToString(actual_entries.at(i).value));
- }
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntriesWithFetch) {
- std::string eager_key("a_key");
- std::string eager_value("an eager value");
- std::string lazy_key("another_key");
- std::string lazy_value("a lazy value");
-
- bool called;
- Status status;
- page_ptr_->PutWithPriority(
- convert::ToArray(lazy_key), convert::ToArray(lazy_value), Priority::LAZY,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- storage::ObjectIdentifier lazy_object_identifier =
- fake_storage_->GetObjects().begin()->first;
-
- status = Status::UNKNOWN_ERROR;
- page_ptr_->Put(convert::ToArray(eager_key), convert::ToArray(eager_value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- fake_storage_->DeleteObjectFromLocal(lazy_object_identifier);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- std::vector<Entry> actual_entries;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetEntries(
- std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- ASSERT_EQ(2u, actual_entries.size());
- EXPECT_EQ(eager_key, convert::ExtendedStringView(actual_entries.at(0).key));
- EXPECT_EQ(eager_value, ToString(actual_entries.at(0).value));
- EXPECT_EQ(Priority::EAGER, actual_entries.at(0).priority);
-
- EXPECT_EQ(lazy_key, convert::ExtendedStringView(actual_entries.at(1).key));
- EXPECT_FALSE(actual_entries.at(1).value);
- EXPECT_EQ(Priority::LAZY, actual_entries.at(1).priority);
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntriesWithPrefix) {
- std::string eager_key("001-a_key");
- std::string eager_value("an eager value");
- std::string lazy_key("002-another_key");
- std::string lazy_value("a lazy value");
-
- bool called;
- Status status;
- page_ptr_->Put(convert::ToArray(eager_key), convert::ToArray(eager_value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- status = Status::UNKNOWN_ERROR;
- page_ptr_->PutWithPriority(
- convert::ToArray(lazy_key), convert::ToArray(lazy_value), Priority::LAZY,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot(convert::ToArray("001"));
- std::vector<Entry> actual_entries;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetEntries(
- std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- ASSERT_EQ(1u, actual_entries.size());
- EXPECT_EQ(eager_key, convert::ExtendedStringView(actual_entries.at(0).key));
-
- snapshot = GetSnapshot(convert::ToArray("00"));
- snapshot->GetEntries(
- std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- ASSERT_EQ(2u, actual_entries.size());
- EXPECT_EQ(eager_key, convert::ExtendedStringView(actual_entries.at(0).key));
- EXPECT_EQ(lazy_key, convert::ExtendedStringView(actual_entries.at(1).key));
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetEntriesWithStart) {
- std::string eager_key("001-a_key");
- std::string eager_value("an eager value");
- std::string lazy_key("002-another_key");
- std::string lazy_value("a lazy value");
-
- bool called;
- Status status;
- page_ptr_->Put(convert::ToArray(eager_key), convert::ToArray(eager_value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- status = Status::UNKNOWN_ERROR;
- page_ptr_->PutWithPriority(
- convert::ToArray(lazy_key), convert::ToArray(lazy_value), Priority::LAZY,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot();
- std::vector<Entry> actual_entries;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetEntries(
- convert::ToArray("002"), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- ASSERT_EQ(1u, actual_entries.size());
- EXPECT_EQ(lazy_key, convert::ExtendedStringView(actual_entries.at(0).key));
-
- snapshot->GetEntries(
- convert::ToArray("001"), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_entries, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- ASSERT_EQ(2u, actual_entries.size());
- EXPECT_EQ(eager_key, convert::ExtendedStringView(actual_entries.at(0).key));
- EXPECT_EQ(lazy_key, convert::ExtendedStringView(actual_entries.at(1).key));
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetKeys) {
- std::string key1("some_key");
- std::string value1("a small value");
- std::string key2("some_key2");
- std::string value2("another value");
-
- bool called;
- Status status;
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Put(convert::ToArray(key1), convert::ToArray(value1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Put(convert::ToArray(key2), convert::ToArray(value2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- std::vector<std::vector<uint8_t>> actual_keys;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetKeys(std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_keys, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- EXPECT_EQ(key1, convert::ExtendedStringView(actual_keys.at(0)));
- EXPECT_EQ(key2, convert::ExtendedStringView(actual_keys.at(1)));
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetKeysWithToken) {
- const size_t min_key_size = kMaxKeySize;
- const size_t key_count =
- fidl_serialization::kMaxInlineDataSize /
- fidl_serialization::GetByteVectorSize(min_key_size) +
- 1;
- AddEntries(key_count, min_key_size);
- PageSnapshotPtr snapshot = GetSnapshot();
-
- // Call GetKeys and find a partial result.
- bool called;
- Status status;
- std::vector<std::vector<uint8_t>> actual_keys;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetKeys(std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_keys, &actual_next_token));
-
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PARTIAL_RESULT, status);
- EXPECT_TRUE(actual_next_token);
-
- // Call GetKeys with the previous token and receive the remaining results.
- std::vector<std::vector<uint8_t>> actual_next_keys;
- snapshot->GetKeys(std::vector<uint8_t>(),
- std::move(actual_next_token),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_next_keys, &actual_next_token));
-
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- for (auto& key : actual_next_keys) {
- actual_keys.push_back(std::move(key));
- }
- EXPECT_EQ(static_cast<size_t>(key_count), actual_keys.size());
-
- // Check that the correct values of the keys are all present in the result and
- // in the correct order.
- for (size_t i = 0; i < actual_keys.size(); ++i) {
- ASSERT_EQ(GetKey(i, min_key_size), convert::ToString(actual_keys.at(i)));
- }
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetKeysWithPrefix) {
- std::string key1("001-some_key");
- std::string value1("a small value");
- std::string key2("002-some_key2");
- std::string value2("another value");
-
- bool called;
- Status status;
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Put(convert::ToArray(key1), convert::ToArray(value1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Put(convert::ToArray(key2), convert::ToArray(value2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot(convert::ToArray("001"));
-
- std::vector<std::vector<uint8_t>> actual_keys;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetKeys(std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_keys, &actual_next_token));
-
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- EXPECT_EQ(1u, actual_keys.size());
- EXPECT_EQ(key1, convert::ExtendedStringView(actual_keys.at(0)));
-
- snapshot = GetSnapshot(convert::ToArray("00"));
- snapshot->GetKeys(std::vector<uint8_t>(), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_keys, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- EXPECT_EQ(2u, actual_keys.size());
- EXPECT_EQ(key1, convert::ExtendedStringView(actual_keys.at(0)));
- EXPECT_EQ(key2, convert::ExtendedStringView(actual_keys.at(1)));
-}
-
-TEST_F(PageImplTest, PutGetSnapshotGetKeysWithStart) {
- std::string key1("001-some_key");
- std::string value1("a small value");
- std::string key2("002-some_key2");
- std::string value2("another value");
-
- bool called;
- Status status;
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Put(convert::ToArray(key1), convert::ToArray(value1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Put(convert::ToArray(key2), convert::ToArray(value2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- std::vector<std::vector<uint8_t>> actual_keys;
- std::unique_ptr<Token> actual_next_token;
- snapshot->GetKeys(convert::ToArray("002"), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_keys, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- EXPECT_EQ(1u, actual_keys.size());
- EXPECT_EQ(key2, convert::ExtendedStringView(actual_keys.at(0)));
-
- snapshot = GetSnapshot();
- snapshot->GetKeys(convert::ToArray("001"), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_keys, &actual_next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(actual_next_token);
- EXPECT_EQ(2u, actual_keys.size());
- EXPECT_EQ(key1, convert::ExtendedStringView(actual_keys.at(0)));
- EXPECT_EQ(key2, convert::ExtendedStringView(actual_keys.at(1)));
-}
-
-TEST_F(PageImplTest, SnapshotGetSmall) {
- std::string key("some_key");
- std::string value("a small value");
-
- bool called;
- Status status;
- page_ptr_->Put(convert::ToArray(key), convert::ToArray(value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- fuchsia::mem::BufferPtr actual_value;
- snapshot->Get(convert::ToArray(key),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_value));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(value, ToString(actual_value));
-
- std::unique_ptr<InlinedValue> actual_inlined_value;
- snapshot->GetInline(convert::ToArray(key),
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &actual_inlined_value));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(actual_inlined_value);
- EXPECT_EQ(value, convert::ToString(actual_inlined_value->value));
-}
-
-TEST_F(PageImplTest, SnapshotGetLarge) {
- std::string value_string(fidl_serialization::kMaxInlineDataSize + 1, 'a');
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(value_string, &vmo));
-
- bool called;
- Status status;
- ReferencePtr reference;
- page_ptr_->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- callback::Capture(callback::SetWhenCalled(&called), &status, &reference));
- DrainLoop();
-
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- std::string key("some_key");
- page_ptr_->PutReference(
- convert::ToArray(key), std::move(*reference), Priority::EAGER,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- fuchsia::mem::BufferPtr actual_value;
- snapshot->Get(convert::ExtendedStringView(key).ToArray(),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_value));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_EQ(value_string, ToString(actual_value));
-
- std::unique_ptr<InlinedValue> inlined_value;
- snapshot->GetInline(convert::ToArray(key),
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &inlined_value));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::VALUE_TOO_LARGE, status);
- EXPECT_FALSE(inlined_value);
-}
-
-TEST_F(PageImplTest, SnapshotGetNeedsFetch) {
- std::string key("some_key");
- std::string value("a small value");
-
- bool called;
- Status status;
- page_ptr_->PutWithPriority(
- convert::ToArray(key), convert::ToArray(value), Priority::LAZY,
- ::callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- storage::ObjectIdentifier lazy_object_identifier =
- fake_storage_->GetObjects().begin()->first;
- fake_storage_->DeleteObjectFromLocal(lazy_object_identifier);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- fuchsia::mem::BufferPtr actual_value;
- snapshot->Get(convert::ToArray(key),
- ::callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_value));
- DrainLoop();
-
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::NEEDS_FETCH, status);
- EXPECT_FALSE(actual_value);
-
- std::unique_ptr<InlinedValue> actual_inlined_value;
- snapshot->GetInline(convert::ToArray(key),
- ::callback::Capture(callback::SetWhenCalled(&called),
- &status, &actual_inlined_value));
- DrainLoop();
-
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::NEEDS_FETCH, status);
- EXPECT_FALSE(actual_inlined_value);
-}
-
-TEST_F(PageImplTest, SnapshotFetchPartial) {
- std::string key("some_key");
- std::string value("a small value");
-
- bool called;
- Status status;
- page_ptr_->Put(convert::ToArray(key), convert::ToArray(value),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = GetSnapshot();
-
- fuchsia::mem::BufferPtr buffer;
- snapshot->FetchPartial(
- convert::ToArray(key), 2, 5,
- callback::Capture(callback::SetWhenCalled(&called), &status, &buffer));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- std::string content;
- EXPECT_TRUE(fsl::StringFromVmo(*buffer, &content));
- EXPECT_EQ("small", content);
-}
-
-TEST_F(PageImplTest, ParallelPut) {
- bool called;
- Status status;
- PagePtr page_ptr2;
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id1_, page_ptr2.NewRequest());
- manager_->AddPageDelayingFacade(
- std::move(delaying_facade),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- std::string key("some_key");
- std::string value1("a small value");
- std::string value2("another value");
-
- PageSnapshotPtr snapshot1;
- PageSnapshotPtr snapshot2;
-
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Put(convert::ToArray(key), convert::ToArray(value1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr2->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr2->Put(convert::ToArray(key), convert::ToArray(value2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr2->Commit(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr_->GetSnapshot(
- snapshot1.NewRequest(), fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page_ptr2->GetSnapshot(
- snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- fuchsia::mem::BufferPtr actual_value1;
- snapshot1->Get(convert::ToArray(key),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_value1));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- fuchsia::mem::BufferPtr actual_value2;
- snapshot2->Get(convert::ToArray(key),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &actual_value2));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- // The two snapshots should have different contents.
- EXPECT_EQ(value1, ToString(actual_value1));
- EXPECT_EQ(value2, ToString(actual_value2));
-}
-
-TEST_F(PageImplTest, SerializedOperations) {
- fake_storage_->set_autocommit(false);
-
- std::string key("some_key");
- std::string value1("a value");
- std::string value2("a second value");
- std::string value3("a third value");
-
- bool called[7] = {false, false, false, false, false, false, false};
- Status statuses[7] = {Status::UNKNOWN_ERROR, Status::UNKNOWN_ERROR,
- Status::UNKNOWN_ERROR, Status::UNKNOWN_ERROR,
- Status::UNKNOWN_ERROR, Status::UNKNOWN_ERROR,
- Status::UNKNOWN_ERROR};
-
- page_ptr_->Put(
- convert::ToArray(key), convert::ToArray(value1),
- callback::Capture(callback::SetWhenCalled(&called[0]), &statuses[0]));
- page_ptr_->Clear(
- callback::Capture(callback::SetWhenCalled(&called[1]), &statuses[1]));
- page_ptr_->Put(
- convert::ToArray(key), convert::ToArray(value2),
- callback::Capture(callback::SetWhenCalled(&called[2]), &statuses[2]));
- page_ptr_->Delete(
- convert::ToArray(key),
- callback::Capture(callback::SetWhenCalled(&called[3]), &statuses[3]));
- page_ptr_->StartTransaction(
- callback::Capture(callback::SetWhenCalled(&called[4]), &statuses[4]));
- page_ptr_->Put(
- convert::ToArray(key), convert::ToArray(value3),
- callback::Capture(callback::SetWhenCalled(&called[5]), &statuses[5]));
- page_ptr_->Commit(
- callback::Capture(callback::SetWhenCalled(&called[6]), &statuses[6]));
-
- // 4 first operations need to be serialized and blocked on commits.
- for (size_t i = 0; i < 4; ++i) {
- // Callbacks are blocked until operation commits.
- DrainLoop();
- EXPECT_FALSE(called[i]);
-
- // The commit queue contains the new commit.
- ASSERT_EQ(i + 1, fake_storage_->GetJournals().size());
- CommitFirstPendingJournal(fake_storage_->GetJournals());
-
- // The operation can now succeed.
- DrainLoop();
- EXPECT_TRUE(called[i]);
- EXPECT_EQ(Status::OK, statuses[i]);
- }
-
- // Neither StartTransaction, nor Put in a transaction should now be blocked.
- DrainLoop();
- for (size_t i = 4; i < 6; ++i) {
- EXPECT_TRUE(called[i]);
- EXPECT_EQ(Status::OK, statuses[i]);
- }
-
- // But committing the transaction should still be blocked.
- DrainLoop();
- EXPECT_FALSE(called[6]);
- EXPECT_NE(Status::OK, statuses[6]);
-
- // Unblocking the transaction commit.
- CommitFirstPendingJournal(fake_storage_->GetJournals());
- // The operation can now succeed.
- DrainLoop();
- EXPECT_TRUE(called[6]);
- EXPECT_EQ(Status::OK, statuses[6]);
-}
-
-TEST_F(PageImplTest, WaitForConflictResolutionNoConflicts) {
- bool called;
- ConflictResolutionWaitStatus status;
- page_ptr_->WaitForConflictResolution(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- EXPECT_EQ(ConflictResolutionWaitStatus::NO_CONFLICTS, status);
- EXPECT_TRUE(resolver_->IsEmpty());
-
- // Special case: no changes from the previous call; event OnEmpty is not
- // triggered, but WaitForConflictResolution should return right away, as there
- // are no pending merges.
- page_ptr_->WaitForConflictResolution(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- EXPECT_EQ(ConflictResolutionWaitStatus::NO_CONFLICTS, status);
- EXPECT_TRUE(resolver_->IsEmpty());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/page_manager.cc b/bin/ledger/app/page_manager.cc
deleted file mode 100644
index e9cb942..0000000
--- a/bin/ledger/app/page_manager.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_manager.h"
-
-#include <algorithm>
-
-#include <lib/callback/trace_callback.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-#include <zircon/syscalls.h>
-
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/impl/data_serialization.h"
-
-namespace ledger {
-
-PageManager::PageManager(Environment* environment,
- std::unique_ptr<storage::PageStorage> page_storage,
- std::unique_ptr<sync_coordinator::PageSync> page_sync,
- std::unique_ptr<MergeResolver> merge_resolver,
- PageManager::PageStorageState state,
- zx::duration sync_timeout)
- : environment_(environment),
- page_storage_(std::move(page_storage)),
- page_sync_(std::move(page_sync)),
- merge_resolver_(std::move(merge_resolver)),
- sync_timeout_(sync_timeout),
- task_runner_(environment->dispatcher()) {
- pages_.set_on_empty([this] { CheckEmpty(); });
- snapshots_.set_on_empty([this] { CheckEmpty(); });
- page_debug_bindings_.set_empty_set_handler([this] { CheckEmpty(); });
-
- if (page_sync_) {
- page_sync_->SetSyncWatcher(&watchers_);
- page_sync_->SetOnIdle([this] { CheckEmpty(); });
- page_sync_->SetOnBacklogDownloaded([this] { OnSyncBacklogDownloaded(); });
- page_sync_->Start();
- if (state == PageManager::PageStorageState::NEEDS_SYNC) {
- // The page storage was created locally. We wait a bit in order to get the
- // initial state from the network before accepting requests.
- task_runner_.PostDelayedTask(
- [this] {
- if (!sync_backlog_downloaded_) {
- FXL_LOG(INFO) << "Initial sync will continue in background, "
- << "in the meantime binding to local page data "
- << "(might be stale or empty).";
- OnSyncBacklogDownloaded();
- }
- },
- sync_timeout_);
- } else {
- sync_backlog_downloaded_ = true;
- }
- } else {
- sync_backlog_downloaded_ = true;
- }
- merge_resolver_->set_on_empty([this] { CheckEmpty(); });
- merge_resolver_->SetPageManager(this);
-}
-
-PageManager::~PageManager() {
- for (const auto& delaying_facade : delaying_facades_) {
- delaying_facade.second(Status::INTERNAL_ERROR);
- }
- delaying_facades_.clear();
-}
-
-void PageManager::AddPageDelayingFacade(
- std::unique_ptr<PageDelayingFacade> delaying_facade,
- fit::function<void(Status)> on_done) {
- auto traced_on_done = TRACE_CALLBACK(std::move(on_done), "ledger",
- "page_manager_add_page_delaying_facade");
- if (!sync_backlog_downloaded_) {
- delaying_facades_.emplace_back(std::move(delaying_facade),
- std::move(traced_on_done));
- return;
- }
- pages_
- .emplace(environment_->coroutine_service(), this, page_storage_.get(),
- merge_resolver_.get(), &watchers_, std::move(delaying_facade))
- .Init(std::move(traced_on_done));
-}
-
-void PageManager::BindPageDebug(fidl::InterfaceRequest<PageDebug> page_debug,
- fit::function<void(Status)> callback) {
- page_debug_bindings_.AddBinding(this, std::move(page_debug));
- callback(Status::OK);
-}
-
-void PageManager::BindPageSnapshot(
- std::unique_ptr<const storage::Commit> commit,
- fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- std::string key_prefix) {
- snapshots_.emplace(std::move(snapshot_request), page_storage_.get(),
- std::move(commit), std::move(key_prefix));
-}
-
-Reference PageManager::CreateReference(
- storage::ObjectIdentifier object_identifier) {
- uint64_t index = environment_->random()->Draw<uint64_t>();
- FXL_DCHECK(references_.find(index) == references_.end());
- references_[index] = std::move(object_identifier);
- Reference reference;
- reference.opaque_id = convert::ToArray(storage::SerializeData(index));
- return reference;
-}
-
-Status PageManager::ResolveReference(
- Reference reference, storage::ObjectIdentifier* object_identifier) {
- if (reference.opaque_id.size() != sizeof(uint64_t)) {
- return Status::REFERENCE_NOT_FOUND;
- }
- uint64_t index = storage::DeserializeData<uint64_t>(
- convert::ToStringView(reference.opaque_id));
- auto iterator = references_.find(index);
- if (iterator == references_.end()) {
- return Status::REFERENCE_NOT_FOUND;
- }
- *object_identifier = iterator->second;
- return Status::OK;
-}
-
-void PageManager::IsSynced(fit::function<void(Status, bool)> callback) {
- page_storage_->IsSynced(
- [callback = std::move(callback)](storage::Status status, bool is_synced) {
- callback(PageUtils::ConvertStatus(status), is_synced);
- });
-}
-
-void PageManager::IsOfflineAndEmpty(
- fit::function<void(Status, bool)> callback) {
- if (page_storage_->IsOnline()) {
- callback(Status::OK, false);
- return;
- }
- // The page is offline. Check and return if it's also empty.
- page_storage_->IsEmpty(
- [callback = std::move(callback)](storage::Status status, bool is_empty) {
- callback(PageUtils::ConvertStatus(status), is_empty);
- });
-}
-
-bool PageManager::IsEmpty() {
- return pages_.empty() && snapshots_.empty() && delaying_facades_.empty() &&
- merge_resolver_->IsEmpty() && (!page_sync_ || page_sync_->IsIdle()) &&
- page_debug_bindings_.size() == 0;
-}
-
-void PageManager::CheckEmpty() {
- if (on_empty_callback_ && IsEmpty()) {
- on_empty_callback_();
- }
-}
-
-void PageManager::OnSyncBacklogDownloaded() {
- if (sync_backlog_downloaded_) {
- FXL_LOG(INFO) << "Initial sync in background finished. "
- << "Clients will receive a change notification.";
- }
- sync_backlog_downloaded_ = true;
- for (auto& delaying_facade : delaying_facades_) {
- AddPageDelayingFacade(std::move(delaying_facade.first),
- std::move(delaying_facade.second));
- }
- delaying_facades_.clear();
-}
-
-void PageManager::GetHeadCommitsIds(GetHeadCommitsIdsCallback callback) {
- page_storage_->GetHeadCommitIds(
- [callback = std::move(callback)](storage::Status status,
- std::vector<storage::CommitId> heads) {
- fidl::VectorPtr<ledger_internal::CommitId> result;
- result.resize(0);
- for (const auto& head : heads) {
- ledger_internal::CommitId commit_id;
- commit_id.id = convert::ToArray(head);
- result.push_back(std::move(commit_id));
- }
-
- callback(PageUtils::ConvertStatus(status, Status::INVALID_ARGUMENT),
- std::move(result));
- });
-}
-
-void PageManager::GetSnapshot(
- ledger_internal::CommitId commit_id,
- fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- GetSnapshotCallback callback) {
- page_storage_->GetCommit(
- convert::ToStringView(commit_id.id),
- [this, snapshot_request = std::move(snapshot_request),
- callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<const storage::Commit> commit) mutable {
- if (status == storage::Status::OK) {
- BindPageSnapshot(std::move(commit), std::move(snapshot_request), "");
- }
- callback(PageUtils::ConvertStatus(status, Status::INVALID_ARGUMENT));
- });
-}
-
-void PageManager::GetCommit(ledger_internal::CommitId commit_id,
- GetCommitCallback callback) {
- page_storage_->GetCommit(
- convert::ToStringView(commit_id.id),
- [callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<const storage::Commit> commit) mutable {
- ledger_internal::CommitPtr commit_struct = nullptr;
- if (status == storage::Status::OK) {
- commit_struct = ledger_internal::Commit::New();
- commit_struct->commit_id.id = convert::ToArray(commit->GetId());
- commit_struct->parents_ids.resize(0);
- for (const storage::CommitIdView& parent : commit->GetParentIds()) {
- ledger_internal::CommitId id;
- id.id = convert::ToArray(parent);
- commit_struct->parents_ids.push_back(std::move(id));
- }
- commit_struct->timestamp = commit->GetTimestamp().get();
- commit_struct->generation = commit->GetGeneration();
- }
- callback(PageUtils::ConvertStatus(status, Status::INVALID_ARGUMENT),
- std::move(commit_struct));
- });
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_manager.h b/bin/ledger/app/page_manager.h
deleted file mode 100644
index 2164f2a..0000000
--- a/bin/ledger/app/page_manager.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_MANAGER_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_MANAGER_H_
-
-#include <memory>
-#include <vector>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/time/time_delta.h>
-
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-#include "peridot/bin/ledger/app/page_delaying_facade.h"
-#include "peridot/bin/ledger/app/page_delegate.h"
-#include "peridot/bin/ledger/app/page_snapshot_impl.h"
-#include "peridot/bin/ledger/app/sync_watcher_set.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/fidl_helpers/bound_interface.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/page_sync_delegate.h"
-#include "peridot/bin/ledger/sync_coordinator/public/page_sync.h"
-
-namespace ledger {
-// Manages a ledger page.
-//
-// PageManager owns all page-level objects related to a single page: page
-// storage, and a set of FIDL PageImpls backed by the page storage. It is safe
-// to delete it at any point - this closes all channels, deletes PageImpls and
-// tears down the storage.
-//
-// When the set of PageImpls becomes empty, client is notified through
-// |on_empty_callback|.
-class PageManager : public ledger_internal::PageDebug {
- public:
- // Whether the page storage needs to sync with the cloud provider before
- // binding new pages (|NEEDS_SYNC|) or whether it is immediately available
- // (|AVAILABLE|).
- enum class PageStorageState {
- AVAILABLE,
- NEEDS_SYNC,
- };
-
- // Both |page_storage| and |page_sync| are owned by PageManager and are
- // deleted when it goes away.
- PageManager(Environment* environment,
- std::unique_ptr<storage::PageStorage> page_storage,
- std::unique_ptr<sync_coordinator::PageSync> page_sync,
- std::unique_ptr<MergeResolver> merge_resolver,
- PageManager::PageStorageState state,
- zx::duration sync_timeout = zx::sec(5));
- ~PageManager() override;
-
- // Creates a new PageDelegate managed by this PageManager, and binds it to the
- // given PageDelayingFacade.
- void AddPageDelayingFacade(
- std::unique_ptr<PageDelayingFacade> delaying_facade,
- fit::function<void(Status)> on_done);
-
- // Binds |page_debug| request and fires |callback| with Status::OK.
- void BindPageDebug(fidl::InterfaceRequest<PageDebug> page_debug,
- fit::function<void(Status)> callback);
-
- // Creates a new PageSnapshotImpl managed by this PageManager, and binds it to
- // the request.
- void BindPageSnapshot(std::unique_ptr<const storage::Commit> commit,
- fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- std::string key_prefix);
-
- // Create a new reference for the given object identifier.
- Reference CreateReference(storage::ObjectIdentifier object_identifier);
-
- // Retrieve an object identifier from a Reference.
- Status ResolveReference(Reference reference,
- storage::ObjectIdentifier* object_identifier);
-
- // Checks whether there are any unsynced commits or pieces in this page.
- void IsSynced(fit::function<void(Status, bool)> callback);
-
- // Checks whether the page is offline and has no entries.
- void IsOfflineAndEmpty(fit::function<void(Status, bool)> callback);
-
- // Returns true if this PageManager can be deleted without interrupting
- // syncing, merging, or requests related to this page.
- bool IsEmpty();
-
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- private:
- void CheckEmpty();
- void OnSyncBacklogDownloaded();
-
- void GetHeadCommitsIds(GetHeadCommitsIdsCallback callback) override;
-
- void GetSnapshot(ledger_internal::CommitId commit_id,
- fidl::InterfaceRequest<PageSnapshot> snapshot_request,
- GetSnapshotCallback callback) override;
-
- void GetCommit(ledger_internal::CommitId commit_id,
- GetCommitCallback callback) override;
-
- Environment* const environment_;
- std::unique_ptr<storage::PageStorage> page_storage_;
- std::unique_ptr<sync_coordinator::PageSync> page_sync_;
- std::unique_ptr<MergeResolver> merge_resolver_;
- const zx::duration sync_timeout_;
- callback::AutoCleanableSet<
- fidl_helpers::BoundInterface<PageSnapshot, PageSnapshotImpl>>
- snapshots_;
- callback::AutoCleanableSet<PageDelegate> pages_;
- fit::closure on_empty_callback_;
-
- bool sync_backlog_downloaded_ = false;
- std::vector<std::pair<std::unique_ptr<PageDelayingFacade>,
- fit::function<void(Status)>>>
- delaying_facades_;
-
- SyncWatcherSet watchers_;
-
- fidl::BindingSet<PageDebug> page_debug_bindings_;
-
- // Registered references.
- std::map<uint64_t, storage::ObjectIdentifier> references_;
-
- // Must be the last member field.
- callback::ScopedTaskRunner task_runner_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageManager);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_MANAGER_H_
diff --git a/bin/ledger/app/page_manager_unittest.cc b/bin/ledger/app/page_manager_unittest.cc
deleted file mode 100644
index 4eb5978..0000000
--- a/bin/ledger/app/page_manager_unittest.cc
+++ /dev/null
@@ -1,651 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_manager.h"
-
-#include <memory>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/merging/merge_resolver.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-#include "peridot/bin/ledger/sync_coordinator/public/ledger_sync.h"
-#include "peridot/bin/ledger/sync_coordinator/testing/page_sync_empty_impl.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-
-namespace ledger {
-namespace {
-
-std::unique_ptr<MergeResolver> GetDummyResolver(Environment* environment,
- storage::PageStorage* storage) {
- return std::make_unique<MergeResolver>(
- [] {}, environment, storage,
- std::make_unique<backoff::ExponentialBackoff>(
- zx::sec(0), 1u, zx::sec(0),
- environment->random()->NewBitGenerator<uint64_t>()));
-}
-
-std::string ToString(const fuchsia::mem::BufferPtr& vmo) {
- std::string value;
- bool status = fsl::StringFromVmo(*vmo, &value);
- FXL_DCHECK(status);
- return value;
-}
-
-class FakePageSync : public sync_coordinator::PageSyncEmptyImpl {
- public:
- void Start() override { start_called = true; }
-
- void SetOnBacklogDownloaded(
- fit::closure on_backlog_downloaded_callback) override {
- this->on_backlog_downloaded_callback =
- std::move(on_backlog_downloaded_callback);
- }
-
- void SetOnIdle(fit::closure on_idle) override {
- this->on_idle = std::move(on_idle);
- }
-
- void SetSyncWatcher(sync_coordinator::SyncStateWatcher* watcher) override {
- this->watcher = watcher;
- }
-
- bool start_called = false;
- sync_coordinator::SyncStateWatcher* watcher = nullptr;
- fit::closure on_backlog_downloaded_callback;
- fit::closure on_idle;
-};
-
-class PageManagerTest : public TestWithEnvironment {
- public:
- PageManagerTest() {}
- ~PageManagerTest() override {}
-
- protected:
- // ApplicationTestBase:
- void SetUp() override {
- ::testing::Test::SetUp();
- page_id_ = storage::PageId(::fuchsia::ledger::kPageIdSize, 'a');
- }
-
- void DrainLoop() {
- RunLoopRepeatedlyFor(storage::fake::kFakePageStorageDelay);
- }
-
- std::unique_ptr<storage::PageStorage> MakeStorage() {
- return std::make_unique<storage::fake::FakePageStorage>(&environment_,
- page_id_);
- }
-
- storage::PageId page_id_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageManagerTest);
-};
-
-TEST_F(PageManagerTest, OnEmptyCallback) {
- bool on_empty_called = false;
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
- PageManager page_manager(&environment_, std::move(storage), nullptr,
- std::move(merger),
- PageManager::PageStorageState::NEEDS_SYNC);
- page_manager.set_on_empty(callback::SetWhenCalled(&on_empty_called));
- DrainLoop();
- EXPECT_FALSE(on_empty_called);
-
- bool called;
- Status status;
- PagePtr page1;
- PagePtr page2;
-
- auto delaying_facade1 =
- std::make_unique<PageDelayingFacade>(page_id_, page1.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- auto delaying_facade2 =
- std::make_unique<PageDelayingFacade>(page_id_, page2.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- page1.Unbind();
- page2.Unbind();
- DrainLoop();
- EXPECT_TRUE(on_empty_called);
- EXPECT_TRUE(page_manager.IsEmpty());
-
- on_empty_called = false;
- PagePtr page3;
- auto delaying_facade3 =
- std::make_unique<PageDelayingFacade>(page_id_, page3.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade3),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_FALSE(page_manager.IsEmpty());
-
- page3.Unbind();
- DrainLoop();
- EXPECT_TRUE(on_empty_called);
- EXPECT_TRUE(page_manager.IsEmpty());
-
- on_empty_called = false;
- PageSnapshotPtr snapshot;
- page_manager.BindPageSnapshot(
- std::make_unique<const storage::CommitEmptyImpl>(), snapshot.NewRequest(),
- "");
- DrainLoop();
- EXPECT_FALSE(page_manager.IsEmpty());
- snapshot.Unbind();
- DrainLoop();
- EXPECT_TRUE(on_empty_called);
-}
-
-TEST_F(PageManagerTest, DeletingPageManagerClosesConnections) {
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
- auto page_manager = std::make_unique<PageManager>(
- &environment_, std::move(storage), nullptr, std::move(merger),
- PageManager::PageStorageState::NEEDS_SYNC);
-
- bool called;
- Status status;
- PagePtr page;
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id_, page.NewRequest());
- page_manager->AddPageDelayingFacade(
- std::move(delaying_facade),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- bool page_closed;
- page.set_error_handler([callback = callback::SetWhenCalled(&page_closed)](
- zx_status_t status) { callback(); });
-
- page_manager.reset();
- DrainLoop();
- EXPECT_TRUE(page_closed);
-}
-
-TEST_F(PageManagerTest, OnEmptyCallbackWithWatcher) {
- bool on_empty_called = false;
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
- PageManager page_manager(&environment_, std::move(storage), nullptr,
- std::move(merger),
- PageManager::PageStorageState::NEEDS_SYNC);
- page_manager.set_on_empty(callback::SetWhenCalled(&on_empty_called));
- DrainLoop();
- // PageManager is empty, but on_empty should not have be called, yet.
- EXPECT_FALSE(on_empty_called);
- EXPECT_TRUE(page_manager.IsEmpty());
-
- bool called;
- Status status;
- PagePtr page1;
- PagePtr page2;
- auto delaying_facade1 =
- std::make_unique<PageDelayingFacade>(page_id_, page1.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- auto delaying_facade2 =
- std::make_unique<PageDelayingFacade>(page_id_, page2.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- page1->Put(convert::ToArray("key1"), convert::ToArray("value1"),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageWatcherPtr watcher;
- fidl::InterfaceRequest<PageWatcher> watcher_request = watcher.NewRequest();
- PageSnapshotPtr snapshot;
- page1->GetSnapshot(
- snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- page1.Unbind();
- page2.Unbind();
- snapshot.Unbind();
- DrainLoop();
- EXPECT_FALSE(page_manager.IsEmpty());
- EXPECT_FALSE(on_empty_called);
-
- watcher_request.TakeChannel();
- DrainLoop();
- EXPECT_TRUE(page_manager.IsEmpty());
- EXPECT_TRUE(on_empty_called);
-}
-
-TEST_F(PageManagerTest, DelayBindingUntilSyncBacklogDownloaded) {
- auto fake_page_sync = std::make_unique<FakePageSync>();
- auto fake_page_sync_ptr = fake_page_sync.get();
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
-
- EXPECT_EQ(nullptr, fake_page_sync_ptr->watcher);
- EXPECT_FALSE(fake_page_sync_ptr->start_called);
- EXPECT_FALSE(fake_page_sync_ptr->on_backlog_downloaded_callback);
-
- PageManager page_manager(&environment_, std::move(storage),
- std::move(fake_page_sync), std::move(merger),
- PageManager::PageStorageState::NEEDS_SYNC);
-
- EXPECT_NE(nullptr, fake_page_sync_ptr->watcher);
- EXPECT_TRUE(fake_page_sync_ptr->start_called);
- EXPECT_TRUE(fake_page_sync_ptr->on_backlog_downloaded_callback);
-
- bool called;
- Status status;
- PagePtr page;
- auto delaying_facade1 =
- std::make_unique<PageDelayingFacade>(page_id_, page.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- // The page should be bound, but except from GetId, no other method should
- // be executed, until the sync backlog is downloaded.
- DrainLoop();
- EXPECT_FALSE(called);
-
- PageId found_page_id;
- page->GetId(
- callback::Capture(callback::SetWhenCalled(&called), &found_page_id));
- DrainLoop();
- EXPECT_TRUE(called);
- PageId expected_page_id;
- convert::ToArray(page_id_, &expected_page_id.id);
- EXPECT_EQ(expected_page_id.id, found_page_id.id);
-
- // Clear should not be executed.
- page->Clear(callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_FALSE(called);
-
- fake_page_sync_ptr->on_backlog_downloaded_callback();
- // BindPage callback can now be executed; Clear callback should then be
- // called.
- DrainLoop();
- EXPECT_TRUE(called);
-
- // Check that a second call on the same manager is not delayed.
- page.Unbind();
- auto delaying_facade2 =
- std::make_unique<PageDelayingFacade>(page_id_, page.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- page->GetId(
- callback::Capture(callback::SetWhenCalled(&called), &std::ignore));
- DrainLoop();
- EXPECT_TRUE(called);
-}
-
-TEST_F(PageManagerTest, DelayBindingUntilSyncTimeout) {
- auto fake_page_sync = std::make_unique<FakePageSync>();
- auto fake_page_sync_ptr = fake_page_sync.get();
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
-
- EXPECT_EQ(nullptr, fake_page_sync_ptr->watcher);
- EXPECT_FALSE(fake_page_sync_ptr->start_called);
- EXPECT_FALSE(fake_page_sync_ptr->on_backlog_downloaded_callback);
-
- PageManager page_manager(
- &environment_, std::move(storage), std::move(fake_page_sync),
- std::move(merger), PageManager::PageStorageState::NEEDS_SYNC, zx::sec(0));
-
- EXPECT_NE(nullptr, fake_page_sync_ptr->watcher);
- EXPECT_TRUE(fake_page_sync_ptr->start_called);
- EXPECT_TRUE(fake_page_sync_ptr->on_backlog_downloaded_callback);
-
- bool called;
- Status status;
- PagePtr page;
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id_, page.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- page->GetId(
- callback::Capture(callback::SetWhenCalled(&called), &std::ignore));
- DrainLoop();
- EXPECT_TRUE(called);
-}
-
-TEST_F(PageManagerTest, ExitWhenSyncFinishes) {
- auto fake_page_sync = std::make_unique<FakePageSync>();
- auto fake_page_sync_ptr = fake_page_sync.get();
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
-
- EXPECT_EQ(nullptr, fake_page_sync_ptr->watcher);
- EXPECT_FALSE(fake_page_sync_ptr->start_called);
- EXPECT_FALSE(fake_page_sync_ptr->on_backlog_downloaded_callback);
-
- PageManager page_manager(
- &environment_, std::move(storage), std::move(fake_page_sync),
- std::move(merger), PageManager::PageStorageState::NEEDS_SYNC, zx::sec(0));
-
- EXPECT_NE(nullptr, fake_page_sync_ptr->watcher);
-
- bool called;
- page_manager.set_on_empty(callback::SetWhenCalled(&called));
-
- async::PostTask(dispatcher(),
- [fake_page_sync_ptr] { fake_page_sync_ptr->on_idle(); });
-
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_TRUE(page_manager.IsEmpty());
-}
-
-TEST_F(PageManagerTest, DontDelayBindingWithLocalPageStorage) {
- auto fake_page_sync = std::make_unique<FakePageSync>();
- auto fake_page_sync_ptr = fake_page_sync.get();
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
-
- EXPECT_EQ(nullptr, fake_page_sync_ptr->watcher);
- EXPECT_FALSE(fake_page_sync_ptr->start_called);
- EXPECT_FALSE(fake_page_sync_ptr->on_backlog_downloaded_callback);
-
- PageManager page_manager(
- &environment_, std::move(storage), std::move(fake_page_sync),
- std::move(merger), PageManager::PageStorageState::AVAILABLE,
- // Use a long timeout to ensure the test does not hit it.
- zx::sec(3600));
-
- EXPECT_NE(nullptr, fake_page_sync_ptr->watcher);
- EXPECT_TRUE(fake_page_sync_ptr->start_called);
- EXPECT_TRUE(fake_page_sync_ptr->on_backlog_downloaded_callback);
-
- bool called;
- Status status;
- PagePtr page;
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id_, page.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- // The page should be bound immediately.
- DrainLoop();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- page->GetId(
- callback::Capture(callback::SetWhenCalled(&called), &std::ignore));
- DrainLoop();
- EXPECT_TRUE(called);
-}
-
-TEST_F(PageManagerTest, GetHeadCommitEntries) {
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
- PageManager page_manager(&environment_, std::move(storage), nullptr,
- std::move(merger),
- PageManager::PageStorageState::NEEDS_SYNC);
- bool called;
- Status status;
- PagePtr page;
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id_, page.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- ledger_internal::PageDebugPtr page_debug;
- page_manager.BindPageDebug(
- page_debug.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::string key1("001-some_key");
- std::string value1("a small value");
-
- page->Put(convert::ToArray(key1), convert::ToArray(value1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::vector<ledger_internal::CommitId> heads1;
- page_debug->GetHeadCommitsIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &heads1));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1u, heads1.size());
-
- std::string key2("002-some_key2");
- std::string value2("another value");
-
- page->Put(convert::ToArray(key2), convert::ToArray(value2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::vector<ledger_internal::CommitId> heads2;
- page_debug->GetHeadCommitsIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &heads2));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1u, heads2.size());
-
- EXPECT_NE(convert::ToString(heads1.at(0).id),
- convert::ToString(heads2.at(0).id));
-
- PageSnapshotPtr snapshot1;
- page_debug->GetSnapshot(
- std::move(heads1.at(0)), snapshot1.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot2;
- page_debug->GetSnapshot(
- std::move(heads2.at(0)), snapshot2.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::vector<Entry> expected_entries1;
- std::unique_ptr<Token> next_token;
- snapshot1->GetEntries(
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &expected_entries1, &next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1u, expected_entries1.size());
- EXPECT_EQ(key1, convert::ToString(expected_entries1.at(0).key));
- EXPECT_EQ(value1, ToString(expected_entries1.at(0).value));
-
- std::vector<Entry> expected_entries2;
- snapshot2->GetEntries(
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &expected_entries2, &next_token));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(2u, expected_entries2.size());
- EXPECT_EQ(key1, convert::ToString(expected_entries2.at(0).key));
- EXPECT_EQ(value1, ToString(expected_entries2.at(0).value));
- EXPECT_EQ(key2, convert::ToString(expected_entries2.at(1).key));
- EXPECT_EQ(value2, ToString(expected_entries2.at(1).value));
-}
-
-TEST_F(PageManagerTest, GetCommit) {
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
- PageManager page_manager(&environment_, std::move(storage), nullptr,
- std::move(merger),
- PageManager::PageStorageState::NEEDS_SYNC);
- bool called;
- Status status;
- PagePtr page;
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id_, page.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- ledger_internal::PageDebugPtr page_debug;
- page_manager.BindPageDebug(
- page_debug.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::string key1("001-some_key");
- std::string value1("a small value");
-
- page->Put(convert::ToArray(key1), convert::ToArray(value1),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::vector<ledger_internal::CommitId> heads1;
- page_debug->GetHeadCommitsIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &heads1));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1u, heads1.size());
-
- std::string key2("002-some_key2");
- std::string value2("another value");
-
- page->Put(convert::ToArray(key2), convert::ToArray(value2),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::vector<ledger_internal::CommitId> heads2;
- page_debug->GetHeadCommitsIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &heads2));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(1u, heads2.size());
-
- ledger_internal::CommitPtr commit_struct;
- ledger_internal::CommitId currHeadCommit = fidl::Clone(heads2.at(0));
- page_debug->GetCommit(std::move(currHeadCommit),
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &commit_struct));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(heads2.at(0).id, commit_struct->commit_id.id);
- EXPECT_EQ(1u, commit_struct->parents_ids.size());
- EXPECT_EQ(1u, commit_struct->generation);
- EXPECT_EQ(heads1.at(0).id, commit_struct->parents_ids.at(0).id);
-}
-
-TEST_F(PageManagerTest, GetCommitError) {
- auto storage = MakeStorage();
- auto merger = GetDummyResolver(&environment_, storage.get());
- PageManager page_manager(&environment_, std::move(storage), nullptr,
- std::move(merger),
- PageManager::PageStorageState::NEEDS_SYNC);
- bool called;
- Status status;
- PagePtr page;
- auto delaying_facade =
- std::make_unique<PageDelayingFacade>(page_id_, page.NewRequest());
- page_manager.AddPageDelayingFacade(
- std::move(delaying_facade),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- ledger_internal::PageDebugPtr page_debug;
- page_manager.BindPageDebug(
- page_debug.NewRequest(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- ledger_internal::CommitPtr commit_struct;
- page_debug->GetCommit({convert::ToArray("fake_commit_id")},
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &commit_struct));
- DrainLoop();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::INVALID_ARGUMENT, status);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/page_snapshot_impl.cc b/bin/ledger/app/page_snapshot_impl.cc
deleted file mode 100644
index fe2e38a..0000000
--- a/bin/ledger/app/page_snapshot_impl.cc
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_snapshot_impl.h"
-
-#include <algorithm>
-#include <functional>
-#include <limits>
-#include <queue>
-#include <vector>
-
-#include <lib/callback/trace_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/memory/ref_counted.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-// Transform a SizedVmo to an optional Buffer. Returns null when
-// status is not OK, or a not-null transport otherwise.
-fuchsia::mem::BufferPtr ToOptionalTransport(Status status, fsl::SizedVmo vmo) {
- if (status != Status::OK) {
- return nullptr;
- }
- return fidl::MakeOptional(std::move(vmo).ToTransport());
-}
-
-template <typename EntryType>
-EntryType CreateEntry(const storage::Entry& entry) {
- EntryType result;
- result.key = convert::ToArray(entry.key);
- result.priority = entry.priority == storage::KeyPriority::EAGER
- ? Priority::EAGER
- : Priority::LAZY;
- return result;
-}
-
-// Returns the number of handles used by an entry of the given type. Specialized
-// for each entry type.
-template <class EntryType>
-size_t HandleUsed();
-
-template <>
-size_t HandleUsed<Entry>() {
- return 1;
-}
-
-template <>
-size_t HandleUsed<InlinedEntry>() {
- return 0;
-}
-
-// Computes the size of an Entry.
-size_t ComputeEntrySize(const Entry& entry) {
- return fidl_serialization::GetEntrySize(entry.key.size());
-}
-
-// Computes the size of an InlinedEntry.
-size_t ComputeEntrySize(const InlinedEntry& entry) {
- return fidl_serialization::GetInlinedEntrySize(entry);
-}
-
-// Fills an Entry from the content of object.
-storage::Status FillSingleEntry(const storage::Object& object, Entry* entry) {
- fsl::SizedVmo vmo;
- storage::Status status = object.GetVmo(&vmo);
- if (status != storage::Status::OK) {
- return status;
- }
- entry->value = fidl::MakeOptional(std::move(vmo).ToTransport());
- return storage::Status::OK;
-}
-
-// Fills an InlinedEntry from the content of object.
-storage::Status FillSingleEntry(const storage::Object& object,
- InlinedEntry* entry) {
- fxl::StringView data;
- storage::Status status = object.GetData(&data);
- if (status != storage::Status::OK) {
- return status;
- }
- entry->inlined_value = std::make_unique<InlinedValue>();
- entry->inlined_value->value = convert::ToArray(data);
- return storage::Status::OK;
-}
-
-// Calls |callback| with filled entries of the provided type per
-// GetEntries/GetEntriesInline semantics.
-// |fill_value| is a callback that fills the entry pointer with the content of
-// the provided object.
-template <typename EntryType>
-void FillEntries(storage::PageStorage* page_storage,
- const std::string& key_prefix, const storage::Commit* commit,
- std::vector<uint8_t> key_start,
- std::unique_ptr<Token> token,
- fit::function<void(Status, std::vector<EntryType>,
- std::unique_ptr<Token>)>
- callback) {
- // |token| represents the first key to be returned in the list of entries.
- // Initially, all entries starting from |token| are requested from storage.
- // Iteration stops if either all entries were found, or if the estimated
- // serialization size of entries exceeds the maximum size of a FIDL message
- // (fidl_serialization::kMaxInlineDataSize), or if the number of entries
- // exceeds fidl_serialization::kMaxMessageHandles. If inline entries are
- // requested, then the actual size of the message is computed as the values
- // are added to the entries. This may result in less entries sent than
- // initially planned. In the case when not all entries have been sent,
- // callback will run with a PARTIAL_RESULT status and a token appropriate for
- // resuming the iteration at the right place.
-
- // Represents information shared between on_next and on_done callbacks.
- struct Context {
- std::vector<EntryType> entries;
- // The serialization size of all entries.
- size_t size = fidl_serialization::kVectorHeaderSize;
- // The number of handles used.
- size_t handle_count = 0u;
- // If |entries| array size exceeds kMaxInlineDataSize, |next_token| will
- // have the value of the following entry's key.
- std::unique_ptr<Token> next_token;
- };
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "snapshot_get_entries");
-
- auto waiter = fxl::MakeRefCounted<callback::Waiter<
- storage::Status, std::unique_ptr<const storage::Object>>>(
- storage::Status::OK);
-
- auto context = std::make_unique<Context>();
- // Use |token| for the first key if present.
- std::string start = token
- ? convert::ToString(token->opaque_id)
- : std::max(key_prefix, convert::ToString(key_start));
- auto on_next = [page_storage, &key_prefix, context = context.get(),
- waiter](storage::Entry entry) {
- if (!PageUtils::MatchesPrefix(entry.key, key_prefix)) {
- return false;
- }
- context->size += fidl_serialization::GetEntrySize(entry.key.size());
- context->handle_count += HandleUsed<EntryType>();
- if ((context->size > fidl_serialization::kMaxInlineDataSize ||
- context->handle_count > fidl_serialization::kMaxMessageHandles) &&
- !context->entries.empty()) {
- context->next_token = std::make_unique<Token>();
- context->next_token->opaque_id = convert::ToArray(entry.key);
- return false;
- }
- context->entries.push_back(CreateEntry<EntryType>(entry));
- page_storage->GetObject(
- entry.object_identifier, storage::PageStorage::Location::LOCAL,
- [priority = entry.priority, waiter_callback = waiter->NewCallback()](
- storage::Status status,
- std::unique_ptr<const storage::Object> object) {
- if (status == storage::Status::NOT_FOUND &&
- priority == storage::KeyPriority::LAZY) {
- waiter_callback(storage::Status::OK, nullptr);
- } else {
- waiter_callback(status, std::move(object));
- }
- });
- return true;
- };
-
- auto on_done = [waiter, context = std::move(context),
- callback = std::move(timed_callback)](
- storage::Status status) mutable {
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Error while reading: " << status;
- callback(Status::IO_ERROR, std::vector<EntryType>(), nullptr);
- return;
- }
- fit::function<void(storage::Status,
- std::vector<std::unique_ptr<const storage::Object>>)>
- result_callback =
- [callback = std::move(callback), context = std::move(context)](
- storage::Status status,
- std::vector<std::unique_ptr<const storage::Object>>
- results) mutable {
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Error while reading: " << status;
- callback(Status::IO_ERROR, std::vector<EntryType>(), nullptr);
- return;
- }
- FXL_DCHECK(context->entries.size() == results.size());
- size_t real_size = 0;
- size_t i = 0;
- for (; i < results.size(); i++) {
- EntryType& entry = context->entries.at(i);
- size_t next_token_size =
- i + 1 >= results.size()
- ? 0
- : fidl_serialization::GetByteVectorSize(
- context->entries.at(i + 1).key.size());
- if (!results[i]) {
- size_t entry_size = ComputeEntrySize(entry);
- if (real_size + entry_size + next_token_size >
- fidl_serialization::kMaxInlineDataSize) {
- break;
- }
- real_size += entry_size;
- // We don't have the object locally, but we decided not to
- // abort. This means this object is a value of a lazy key and
- // the client should ask to retrieve it over the network if
- // they need it. Here, we just leave the value part of the
- // entry null.
- continue;
- }
-
- storage::Status read_status =
- FillSingleEntry(*results[i], &entry);
- if (read_status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(read_status), std::vector<EntryType>(), nullptr);
- return;
- }
- size_t entry_size = ComputeEntrySize(entry);
- if (real_size + entry_size + next_token_size >
- fidl_serialization::kMaxInlineDataSize) {
- break;
- }
- real_size += entry_size;
- }
- if (i != results.size()) {
- if (i == 0) {
- callback(Status::VALUE_TOO_LARGE, std::vector<EntryType>(), nullptr);
- return;
- }
- // We had to bail out early because the result would be too big
- // otherwise.
- context->next_token = std::make_unique<Token>();
- context->next_token->opaque_id =
- std::move(context->entries.at(i).key);
- context->entries.resize(i);
- }
- if (context->next_token) {
- callback(Status::PARTIAL_RESULT, std::move(context->entries),
- std::move(context->next_token));
- return;
- }
- callback(Status::OK, std::move(context->entries), nullptr);
- };
- waiter->Finalize(std::move(result_callback));
- };
- page_storage->GetCommitContents(*commit, std::move(start), std::move(on_next),
- std::move(on_done));
-}
-} // namespace
-
-PageSnapshotImpl::PageSnapshotImpl(
- storage::PageStorage* page_storage,
- std::unique_ptr<const storage::Commit> commit, std::string key_prefix)
- : page_storage_(page_storage),
- commit_(std::move(commit)),
- key_prefix_(std::move(key_prefix)) {}
-
-PageSnapshotImpl::~PageSnapshotImpl() {}
-
-void PageSnapshotImpl::GetEntries(std::vector<uint8_t> key_start,
- std::unique_ptr<Token> token,
- GetEntriesCallback callback) {
- FillEntries<Entry>(page_storage_, key_prefix_, commit_.get(),
- std::move(key_start), std::move(token),
- std::move(callback));
-}
-
-void PageSnapshotImpl::GetEntriesInline(std::vector<uint8_t> key_start,
- std::unique_ptr<Token> token,
- GetEntriesInlineCallback callback) {
- FillEntries<InlinedEntry>(page_storage_, key_prefix_, commit_.get(),
- std::move(key_start), std::move(token),
- std::move(callback));
-}
-
-void PageSnapshotImpl::GetKeys(std::vector<uint8_t> key_start,
- std::unique_ptr<Token> token,
- GetKeysCallback callback) {
- // Represents the information that needs to be shared between on_next and
- // on_done callbacks.
- struct Context {
- // The result of GetKeys. New keys from on_next are appended to this array.
- std::vector<std::vector<uint8_t>> keys;
- // The total size in number of bytes of the |keys| array.
- size_t size = fidl_serialization::kVectorHeaderSize;
- // If the |keys| array size exceeds the maximum allowed inlined data size,
- // |next_token| will have the value of the next key (not included in array)
- // which can be used as the next token.
- std::unique_ptr<Token> next_token;
- };
-
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "snapshot_get_keys");
-
- auto context = std::make_unique<Context>();
- auto on_next = [this, context = context.get()](storage::Entry entry) {
- if (!PageUtils::MatchesPrefix(entry.key, key_prefix_)) {
- return false;
- }
- context->size += fidl_serialization::GetByteVectorSize(entry.key.size());
- if (context->size > fidl_serialization::kMaxInlineDataSize) {
- context->next_token = std::make_unique<Token>();
- context->next_token->opaque_id = convert::ToArray(entry.key);
- return false;
- }
- context->keys.push_back(convert::ToArray(entry.key));
- return true;
- };
- auto on_done = [context = std::move(context),
- callback =
- std::move(timed_callback)](storage::Status status) {
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Error while reading: " << status;
- callback(Status::IO_ERROR,
- std::vector<std::vector<uint8_t>>(), nullptr);
- return;
- }
- if (context->next_token) {
- callback(Status::PARTIAL_RESULT, std::move(context->keys),
- std::move(context->next_token));
- } else {
- callback(Status::OK, std::move(context->keys), nullptr);
- }
- };
- if (token) {
- page_storage_->GetCommitContents(*commit_,
- convert::ToString(token->opaque_id),
- std::move(on_next), std::move(on_done));
- } else {
- page_storage_->GetCommitContents(
- *commit_, std::max(convert::ToString(key_start), key_prefix_),
- std::move(on_next), std::move(on_done));
- }
-}
-
-void PageSnapshotImpl::Get(std::vector<uint8_t> key, GetCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "snapshot_get");
-
- page_storage_->GetEntryFromCommit(
- *commit_, convert::ToString(key),
- [this, callback = std::move(timed_callback)](
- storage::Status status, storage::Entry entry) mutable {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status, Status::KEY_NOT_FOUND),
- nullptr);
- return;
- }
- PageUtils::ResolveObjectIdentifierAsBuffer(
- page_storage_, entry.object_identifier, 0u,
- std::numeric_limits<int64_t>::max(),
- storage::PageStorage::Location::LOCAL, Status::NEEDS_FETCH,
- [callback = std::move(callback)](Status status,
- fsl::SizedVmo data) {
- callback(status, ToOptionalTransport(status, std::move(data)));
- });
- });
-}
-
-void PageSnapshotImpl::GetInline(std::vector<uint8_t> key,
- GetInlineCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "snapshot_get_inline");
-
- page_storage_->GetEntryFromCommit(
- *commit_, convert::ToString(key),
- [this, callback = std::move(timed_callback)](
- storage::Status status, storage::Entry entry) mutable {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status, Status::KEY_NOT_FOUND),
- nullptr);
- return;
- }
- PageUtils::ResolveObjectIdentifierAsStringView(
- page_storage_, entry.object_identifier,
- storage::PageStorage::Location::LOCAL, Status::NEEDS_FETCH,
- [callback = std::move(callback)](Status status,
- fxl::StringView data_view) {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- if (fidl_serialization::GetByteVectorSize(data_view.size()) +
- fidl_serialization::kStatusEnumSize >
- fidl_serialization::kMaxInlineDataSize) {
- callback(Status::VALUE_TOO_LARGE, nullptr);
- return;
- }
- auto inlined_value = std::make_unique<InlinedValue>();
- inlined_value->value = convert::ToArray(data_view);
- callback(status, std::move(inlined_value));
- });
- });
-}
-
-void PageSnapshotImpl::Fetch(std::vector<uint8_t> key,
- FetchCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "snapshot_fetch");
-
- page_storage_->GetEntryFromCommit(
- *commit_, convert::ToString(key),
- [this, callback = std::move(timed_callback)](
- storage::Status status, storage::Entry entry) mutable {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status, Status::KEY_NOT_FOUND),
- nullptr);
- return;
- }
- PageUtils::ResolveObjectIdentifierAsBuffer(
- page_storage_, entry.object_identifier, 0u,
- std::numeric_limits<int64_t>::max(),
- storage::PageStorage::Location::NETWORK, Status::INTERNAL_ERROR,
- [callback = std::move(callback)](Status status,
- fsl::SizedVmo data) {
- callback(status, ToOptionalTransport(status, std::move(data)));
- });
- });
-}
-
-void PageSnapshotImpl::FetchPartial(std::vector<uint8_t> key,
- int64_t offset, int64_t max_size,
- FetchPartialCallback callback) {
- auto timed_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "snapshot_fetch_partial");
-
- page_storage_->GetEntryFromCommit(
- *commit_, convert::ToString(key),
- [this, offset, max_size, callback = std::move(timed_callback)](
- storage::Status status, storage::Entry entry) mutable {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status, Status::KEY_NOT_FOUND),
- nullptr);
- return;
- }
-
- PageUtils::ResolveObjectIdentifierAsBuffer(
- page_storage_, entry.object_identifier, offset, max_size,
- storage::PageStorage::Location::NETWORK, Status::INTERNAL_ERROR,
- [callback = std::move(callback)](Status status,
- fsl::SizedVmo data) {
- callback(status, ToOptionalTransport(status, std::move(data)));
- });
- });
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_snapshot_impl.h b/bin/ledger/app/page_snapshot_impl.h
deleted file mode 100644
index fccac8d..0000000
--- a/bin/ledger/app/page_snapshot_impl.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_SNAPSHOT_IMPL_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_SNAPSHOT_IMPL_H_
-
-#include <memory>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace ledger {
-
-// An implementation of the |PageSnapshot| FIDL interface.
-class PageSnapshotImpl : public PageSnapshot {
- public:
- PageSnapshotImpl(storage::PageStorage* page_storage,
- std::unique_ptr<const storage::Commit> commit,
- std::string key_prefix);
- ~PageSnapshotImpl() override;
-
- private:
- // PageSnapshot:
- void GetEntries(std::vector<uint8_t> key_start,
- std::unique_ptr<Token> token,
- GetEntriesCallback callback) override;
- void GetEntriesInline(std::vector<uint8_t> key_start,
- std::unique_ptr<Token> token,
- GetEntriesInlineCallback callback) override;
- void GetKeys(std::vector<uint8_t> key_start, std::unique_ptr<Token> token,
- GetKeysCallback callback) override;
- void Get(std::vector<uint8_t> key, GetCallback callback) override;
- void GetInline(std::vector<uint8_t> key,
- GetInlineCallback callback) override;
- void Fetch(std::vector<uint8_t> key, FetchCallback callback) override;
- void FetchPartial(std::vector<uint8_t> key, int64_t offset,
- int64_t max_size, FetchPartialCallback callback) override;
-
- storage::PageStorage* page_storage_;
- std::unique_ptr<const storage::Commit> commit_;
- const std::string key_prefix_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_SNAPSHOT_IMPL_H_
diff --git a/bin/ledger/app/page_usage_db.cc b/bin/ledger/app/page_usage_db.cc
deleted file mode 100644
index be58663..0000000
--- a/bin/ledger/app/page_usage_db.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_usage_db.h"
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <zx/time.h>
-
-#include "lib/fxl/strings/concatenate.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/lock/lock.h"
-#include "peridot/bin/ledger/storage/impl/data_serialization.h"
-#include "peridot/bin/ledger/storage/public/iterator.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kOpenedPagePrefix = "opened/";
-
-std::string GetKeyForOpenedPage(fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- FXL_DCHECK(page_id.size() == ::fuchsia::ledger::kPageIdSize);
- return fxl::Concatenate({kOpenedPagePrefix, ledger_name, page_id});
-}
-
-void GetPageFromOpenedRow(fxl::StringView row, std::string* ledger_name,
- storage::PageId* page_id) {
- FXL_DCHECK(row.size() >
- ::fuchsia::ledger::kPageIdSize + kOpenedPagePrefix.size());
- size_t ledger_name_size =
- row.size() - ::fuchsia::ledger::kPageIdSize - kOpenedPagePrefix.size();
- *ledger_name =
- row.substr(kOpenedPagePrefix.size(), ledger_name_size).ToString();
- *page_id = row.substr(kOpenedPagePrefix.size() + ledger_name_size).ToString();
-}
-
-// An iterator over PageInfo.
-// This class is a wrapper from a LevelDB iterator, deserializing the
-// ExtendedStringView key-value pairs to PageInfo entries.
-class PageInfoIterator final : public storage::Iterator<const PageInfo> {
- public:
- explicit PageInfoIterator(
- std::unique_ptr<storage::Iterator<const std::pair<
- convert::ExtendedStringView, convert::ExtendedStringView>>>
- it)
- : it_(std::move(it)) {
- PrepareEntry();
- }
-
- ~PageInfoIterator() override {}
-
- storage::Iterator<const PageInfo>& Next() override {
- it_->Next();
- PrepareEntry();
- return *this;
- }
-
- bool Valid() const override { return it_->Valid(); }
-
- storage::Status GetStatus() const override { return it_->GetStatus(); }
-
- const PageInfo& operator*() const override { return *(page_.get()); }
-
- const PageInfo* operator->() const override { return page_.get(); }
-
- private:
- // Updates `page_` with page info extracted from the current key-value in
- // `it_`.
- void PrepareEntry() {
- if (!Valid()) {
- page_.reset(nullptr);
- return;
- }
- page_ = std::make_unique<PageInfo>();
-
- const std::pair<convert::ExtendedStringView, convert::ExtendedStringView>&
- key_value = **it_;
- GetPageFromOpenedRow(key_value.first, &(page_->ledger_name),
- &(page_->page_id));
- page_->timestamp = storage::DeserializeData<zx::time_utc>(key_value.second);
- }
-
- std::unique_ptr<storage::Iterator<const std::pair<
- convert::ExtendedStringView, convert::ExtendedStringView>>>
- it_;
-
- // The current page info served by the iterator.
- std::unique_ptr<PageInfo> page_;
-};
-} // namespace
-
-PageUsageDb::PageUsageDb(timekeeper::Clock* clock,
- std::unique_ptr<storage::Db> db)
- : clock_(clock), db_(std::move(db)) {}
-
-PageUsageDb::~PageUsageDb() {}
-
-Status PageUsageDb::MarkPageOpened(coroutine::CoroutineHandler* handler,
- fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- return Put(handler, GetKeyForOpenedPage(ledger_name, page_id),
- storage::SerializeData(PageInfo::kOpenedPageTimestamp));
-}
-
-Status PageUsageDb::MarkPageClosed(coroutine::CoroutineHandler* handler,
- fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- FXL_DCHECK(page_id.size() == ::fuchsia::ledger::kPageIdSize);
- zx::time_utc now;
- if (clock_->Now(&now) != ZX_OK) {
- return Status::IO_ERROR;
- }
- return Put(handler, GetKeyForOpenedPage(ledger_name, page_id),
- storage::SerializeData(now));
-}
-
-Status PageUsageDb::MarkPageEvicted(coroutine::CoroutineHandler* handler,
- fxl::StringView ledger_name,
- storage::PageIdView page_id) {
- return Delete(handler, GetKeyForOpenedPage(ledger_name, page_id));
-}
-
-Status PageUsageDb::MarkAllPagesClosed(coroutine::CoroutineHandler* handler) {
- zx::time_utc now;
- if (clock_->Now(&now) != ZX_OK) {
- return Status::IO_ERROR;
- }
-
- std::unique_ptr<storage::Iterator<const std::pair<
- convert::ExtendedStringView, convert::ExtendedStringView>>>
- rows;
- storage::Status db_status =
- db_->GetIteratorAtPrefix(handler, kOpenedPagePrefix, &rows);
- if (db_status != storage::Status::OK) {
- return PageUtils::ConvertStatus(db_status);
- }
- while (rows->Valid()) {
- if (storage::DeserializeData<zx::time_utc>((*rows)->second) ==
- PageInfo::kOpenedPageTimestamp) {
- // No need to deserialize the key.
- Status status = Put(handler, (*rows)->first, storage::SerializeData(now));
- if (status != Status::OK) {
- return status;
- }
- }
- rows->Next();
- }
- return Status::OK;
-}
-
-Status PageUsageDb::GetPages(
- coroutine::CoroutineHandler* handler,
- std::unique_ptr<storage::Iterator<const PageInfo>>* pages) {
- std::unique_ptr<storage::Iterator<const std::pair<
- convert::ExtendedStringView, convert::ExtendedStringView>>>
- it;
- storage::Status status =
- db_->GetIteratorAtPrefix(handler, kOpenedPagePrefix, &it);
- if (status != storage::Status::OK) {
- return PageUtils::ConvertStatus(status);
- }
- *pages = std::make_unique<PageInfoIterator>(std::move(it));
- return Status::OK;
-}
-
-Status PageUsageDb::Put(coroutine::CoroutineHandler* handler,
- fxl::StringView key, fxl::StringView value) {
- std::unique_ptr<storage::Db::Batch> batch;
- std::unique_ptr<lock::Lock> lock;
- // Used for serializing Put and Delete operations.
- if (lock::AcquireLock(handler, &serializer_, &lock) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERNAL_ERROR;
- }
- storage::Status status = db_->StartBatch(handler, &batch);
- if (status != storage::Status::OK) {
- return PageUtils::ConvertStatus(status);
- }
- status = batch->Put(handler, key, value);
- if (status != storage::Status::OK) {
- return PageUtils::ConvertStatus(status);
- }
- return PageUtils::ConvertStatus(batch->Execute(handler));
-}
-
-Status PageUsageDb::Delete(coroutine::CoroutineHandler* handler,
- fxl::StringView key) {
- std::unique_ptr<storage::Db::Batch> batch;
- // Used for serializing Put and Delete operations.
- std::unique_ptr<lock::Lock> lock;
- if (lock::AcquireLock(handler, &serializer_, &lock) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERNAL_ERROR;
- }
- storage::Status status = db_->StartBatch(handler, &batch);
- if (status != storage::Status::OK) {
- return PageUtils::ConvertStatus(status);
- }
- status = batch->Delete(handler, key);
- if (status != storage::Status::OK) {
- return PageUtils::ConvertStatus(status);
- }
- return PageUtils::ConvertStatus(batch->Execute(handler));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_usage_db.h b/bin/ledger/app/page_usage_db.h
deleted file mode 100644
index 1013afd..0000000
--- a/bin/ledger/app/page_usage_db.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_DB_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_DB_H_
-
-#include <functional>
-#include <memory>
-
-#include <lib/callback/operation_serializer.h>
-#include <lib/timekeeper/clock.h>
-
-#include "lib/fxl/strings/concatenate.h"
-#include "peridot/bin/ledger/app/page_utils.h"
-#include "peridot/bin/ledger/app/types.h"
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/impl/leveldb.h"
-#include "peridot/bin/ledger/storage/public/db.h"
-#include "peridot/bin/ledger/storage/public/iterator.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-// |PageUsageDb| persists all information on page usage.
-//
-// Calls to |MarkPageOpened| and |MarkPageClosed| will update the underlying
-// database in the order in which they are called.
-//
-// Rows in the underlying database are serialized as follows:
-// Last usage row:
-// - Key: "opened/<ledger_name><page_id>"
-// - Value: "<timestamp>" or timestamp 0 for open pages
-class PageUsageDb {
- public:
- PageUsageDb(timekeeper::Clock* clock, std::unique_ptr<storage::Db> db);
- ~PageUsageDb();
-
- // Marks the page with the given id as opened. |INTERNAL_ERROR| is returned if
- // the operation is interrupted.
- Status MarkPageOpened(coroutine::CoroutineHandler* handler,
- fxl::StringView ledger_name,
- storage::PageIdView page_id);
-
- // Marks the page with the given id as closed. |INTERNAL_ERROR| is returned if
- // the operation is interrupted.
- Status MarkPageClosed(coroutine::CoroutineHandler* handler,
- fxl::StringView ledger_name,
- storage::PageIdView page_id);
-
- // Marks the page with the given id as evicted. |INTERNAL_ERROR| is returned
- // if the operation is interrupted.
- Status MarkPageEvicted(coroutine::CoroutineHandler* handler,
- fxl::StringView ledger_name,
- storage::PageIdView page_id);
-
- // Marks all open pages as closed. |INTERNAL_ERROR| is returned if the
- // operation is interrupted.
- Status MarkAllPagesClosed(coroutine::CoroutineHandler* handler);
-
- // Updates |pages| to contain an iterator over all entries of page
- // information.
- Status GetPages(coroutine::CoroutineHandler* handler,
- std::unique_ptr<storage::Iterator<const PageInfo>>* pages);
-
- private:
- // Inserts the given |key|-|value| pair in the underlying database.
- Status Put(coroutine::CoroutineHandler* handler, fxl::StringView key,
- fxl::StringView value);
-
- // Deletes the row with the given |key| in the underlying database.
- Status Delete(coroutine::CoroutineHandler* handler, fxl::StringView key);
-
- timekeeper::Clock* clock_;
- std::unique_ptr<storage::Db> db_;
-
- // A serializer used for Put and Delete. Both these operations need to be
- // serialized to guarantee that consecutive calls to update the contents of a
- // single page (e.g. a page is opened and then closed) are written in |db_| in
- // the right order, i.e. the order in which they were called.
- callback::OperationSerializer serializer_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageUsageDb);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_DB_H_
diff --git a/bin/ledger/app/page_usage_db_unittest.cc b/bin/ledger/app/page_usage_db_unittest.cc
deleted file mode 100644
index b785c6d..0000000
--- a/bin/ledger/app/page_usage_db_unittest.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_usage_db.h"
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <zircon/syscalls.h>
-
-#include "gtest/gtest.h"
-#include "lib/callback/capture.h"
-#include "lib/callback/set_when_called.h"
-#include "lib/fxl/macros.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/storage/fake/fake_db.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-
-namespace ledger {
-namespace {
-
-class PageUsageDbTest : public TestWithEnvironment {
- public:
- PageUsageDbTest()
- : db_(environment_.clock(), std::make_unique<storage::fake::FakeDb>(
- environment_.dispatcher())) {}
-
- ~PageUsageDbTest() override {}
-
- std::string RandomString(size_t size) {
- std::string result;
- result.resize(size);
- environment_.random()->Draw(&result);
- return result;
- }
-
- protected:
- PageUsageDb db_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageUsageDbTest);
-};
-
-TEST_F(PageUsageDbTest, GetPagesEmpty) {
- RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
- std::string ledger_name = "ledger_name";
- std::string page_id(::fuchsia::ledger::kPageIdSize, 'p');
-
- std::unique_ptr<storage::Iterator<const PageInfo>> pages;
- EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));
-
- EXPECT_EQ(storage::Status::OK, pages->GetStatus());
- EXPECT_FALSE(pages->Valid());
- });
-}
-
-TEST_F(PageUsageDbTest, MarkPageOpened) {
- RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
- std::string ledger_name = "ledger_name";
- std::string page_id(::fuchsia::ledger::kPageIdSize, 'p');
-
- // Open the same page.
- EXPECT_EQ(Status::OK, db_.MarkPageOpened(handler, ledger_name, page_id));
-
- // Expect to find a single entry with the opened page marker timestamp.
- std::unique_ptr<storage::Iterator<const PageInfo>> pages;
- EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));
-
- EXPECT_EQ(storage::Status::OK, pages->GetStatus());
- EXPECT_TRUE(pages->Valid());
- EXPECT_EQ(ledger_name, (*pages)->ledger_name);
- EXPECT_EQ(page_id, (*pages)->page_id);
- EXPECT_EQ(PageInfo::kOpenedPageTimestamp, (*pages)->timestamp);
-
- pages->Next();
- EXPECT_EQ(storage::Status::OK, pages->GetStatus());
- EXPECT_FALSE(pages->Valid());
- });
-}
-
-TEST_F(PageUsageDbTest, MarkPageOpenedAndClosed) {
- RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
- std::string ledger_name = "ledger_name";
- std::string page_id(::fuchsia::ledger::kPageIdSize, 'p');
-
- // Open and close the same page.
- EXPECT_EQ(Status::OK, db_.MarkPageOpened(handler, ledger_name, page_id));
- EXPECT_EQ(Status::OK, db_.MarkPageClosed(handler, ledger_name, page_id));
-
- // Expect to find a single entry with timestamp != the opened page marker
- // timestamp.
- std::unique_ptr<storage::Iterator<const PageInfo>> pages;
- EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));
-
- EXPECT_EQ(storage::Status::OK, pages->GetStatus());
- EXPECT_TRUE(pages->Valid());
- EXPECT_EQ(ledger_name, (*pages)->ledger_name);
- EXPECT_EQ(page_id, (*pages)->page_id);
- EXPECT_NE(PageInfo::kOpenedPageTimestamp, (*pages)->timestamp);
-
- pages->Next();
- EXPECT_EQ(storage::Status::OK, pages->GetStatus());
- EXPECT_FALSE(pages->Valid());
- });
-}
-
-TEST_F(PageUsageDbTest, MarkAllPagesClosed) {
- RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
- std::string ledger_name = "ledger_name";
- int N = 5;
- std::string page_ids[N];
- for (int i = 0; i < N; ++i) {
- page_ids[i] = RandomString(::fuchsia::ledger::kPageIdSize);
- }
-
- // Open 5 pages.
- for (int i = 0; i < N; ++i) {
- EXPECT_EQ(Status::OK,
- db_.MarkPageOpened(handler, ledger_name, page_ids[i]));
- }
-
- // Close 1 of them.
- EXPECT_EQ(Status::OK,
- db_.MarkPageClosed(handler, ledger_name, page_ids[0]));
-
- // Expect to find 4 entries with timestamp equal to the opened page marker
- // timestamp.
- std::unique_ptr<storage::Iterator<const PageInfo>> pages;
- EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));
-
- int open_pages_count = 0;
- zx::time_utc page_0_timestamp(0);
- for (int i = 0; i < N; ++i) {
- EXPECT_EQ(storage::Status::OK, pages->GetStatus());
- ASSERT_TRUE(pages->Valid());
- EXPECT_EQ(ledger_name, (*pages)->ledger_name);
- if ((*pages)->page_id == page_ids[0]) {
- page_0_timestamp = (*pages)->timestamp;
- EXPECT_NE(PageInfo::kOpenedPageTimestamp, page_0_timestamp);
- } else {
- ++open_pages_count;
- EXPECT_EQ(PageInfo::kOpenedPageTimestamp, (*pages)->timestamp);
- }
- pages->Next();
- }
- EXPECT_EQ(N - 1, open_pages_count);
-
- EXPECT_EQ(storage::Status::OK, pages->GetStatus());
- EXPECT_FALSE(pages->Valid());
-
- // Call MarkAllPagesClosed and expect all 5 pages to be closed, 4 with the
- // same value.
- EXPECT_EQ(Status::OK, db_.MarkAllPagesClosed(handler));
-
- EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));
- zx::time_utc timestamp(PageInfo::kOpenedPageTimestamp);
- for (int i = 0; i < N; ++i) {
- EXPECT_EQ(storage::Status::OK, pages->GetStatus());
- ASSERT_TRUE(pages->Valid());
- EXPECT_EQ(ledger_name, (*pages)->ledger_name);
- if ((*pages)->page_id == page_ids[0]) {
- EXPECT_EQ(page_0_timestamp, (*pages)->timestamp);
- } else {
- // Expect from page 0, the others should have the same timestamp.
- EXPECT_NE(PageInfo::kOpenedPageTimestamp, (*pages)->timestamp);
- if (timestamp == PageInfo::kOpenedPageTimestamp) {
- timestamp = (*pages)->timestamp;
- } else {
- EXPECT_EQ(timestamp, (*pages)->timestamp);
- }
- }
- pages->Next();
- }
- EXPECT_EQ(N - 1, open_pages_count);
- });
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/page_usage_listener.h b/bin/ledger/app/page_usage_listener.h
deleted file mode 100644
index 3f43482..0000000
--- a/bin/ledger/app/page_usage_listener.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_LISTENER_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_LISTENER_H_
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-// A listener on page usage, that receives notifications when a page is opened
-// or closed.
-class PageUsageListener {
- public:
- PageUsageListener() {}
- virtual ~PageUsageListener() {}
-
- // Called when a page connection has been requested. In case of concurrent
- // connections to the same page, this should only be called once, on the first
- // connection.
- virtual void OnPageOpened(fxl::StringView ledger_name,
- storage::PageIdView page_id) = 0;
-
- // Called when all external connections to a page are closed. In case of
- // concurrent connections to the same page, this should only be called once,
- // when the last connection closes.
- // TODO(nellyv): Add argument on whether the page is synced and and cache it.
- virtual void OnPageClosed(fxl::StringView ledger_name,
- storage::PageIdView page_id) = 0;
-
- // Called when there are no longer any active connections to a page. This
- // includes both internal and external connections. Note that if the last
- // active connection to a page is an external one, both |OnPageClosed| and
- // then |OnPageUnused| will be called.
- virtual void OnPageUnused(fxl::StringView ledger_name,
- storage::PageIdView page_id) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageUsageListener);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_USAGE_LISTENER_H_
diff --git a/bin/ledger/app/page_utils.cc b/bin/ledger/app/page_utils.cc
deleted file mode 100644
index 7f0ed50..0000000
--- a/bin/ledger/app/page_utils.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/page_utils.h"
-
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-void PageUtils::ResolveObjectIdentifierAsStringView(
- storage::PageStorage* storage, storage::ObjectIdentifier object_identifier,
- storage::PageStorage::Location location, Status not_found_status,
- fit::function<void(Status, fxl::StringView)> callback) {
- storage->GetObject(
- object_identifier, location,
- [not_found_status, callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<const storage::Object> object) {
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status, not_found_status),
- fxl::StringView());
- return;
- }
- fxl::StringView data;
- status = object->GetData(&data);
- if (status != storage::Status::OK) {
- callback(PageUtils::ConvertStatus(status, not_found_status),
- fxl::StringView());
- return;
- }
-
- callback(Status::OK, data);
- });
-}
-
-Status PageUtils::ConvertStatus(storage::Status status,
- Status not_found_status) {
- switch (status) {
- case storage::Status::OK:
- return Status::OK;
- case storage::Status::IO_ERROR:
- return Status::IO_ERROR;
- case storage::Status::NOT_FOUND:
- FXL_DCHECK(not_found_status != Status::INTERNAL_ERROR);
- return not_found_status;
- case storage::Status::NOT_CONNECTED_ERROR:
- return Status::NETWORK_ERROR;
- case storage::Status::INTERRUPTED:
- return Status::INTERNAL_ERROR;
- default:
- FXL_DCHECK(false) << "Internal error in Ledger storage. Status: "
- << status;
- return Status::INTERNAL_ERROR;
- }
-}
-
-void PageUtils::ResolveObjectIdentifierAsBuffer(
- storage::PageStorage* storage, storage::ObjectIdentifier object_identifier,
- int64_t offset, int64_t max_size, storage::PageStorage::Location location,
- Status not_found_status,
- fit::function<void(Status, fsl::SizedVmo)> callback) {
- storage->GetObjectPart(
- object_identifier, offset, max_size, location,
- [not_found_status, callback = std::move(callback)](
- storage::Status status, fsl::SizedVmo object_part) {
- callback(ConvertStatus(status, not_found_status),
- std::move(object_part));
- });
-}
-
-bool PageUtils::MatchesPrefix(const std::string& key,
- const std::string& prefix) {
- return convert::ExtendedStringView(key).substr(0, prefix.size()) ==
- convert::ExtendedStringView(prefix);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/page_utils.h b/bin/ledger/app/page_utils.h
deleted file mode 100644
index d211939..0000000
--- a/bin/ledger/app/page_utils.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_PAGE_UTILS_H_
-#define PERIDOT_BIN_LEDGER_APP_PAGE_UTILS_H_
-
-#include <functional>
-
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-class PageUtils {
- public:
- // Converts a status from storage into a status from the FIDL API. If the
- // storage status is storage::Status::NOT_FOUND, |not_found_status| will be
- // returned.
- static Status ConvertStatus(storage::Status status,
- Status not_found_status = Status::INTERNAL_ERROR);
-
- // Retrieves the data referenced by the given identifier as a StringView with
- // no offset.
- static void ResolveObjectIdentifierAsStringView(
- storage::PageStorage* storage,
- storage::ObjectIdentifier object_identifier,
- storage::PageStorage::Location location, Status not_found_status,
- fit::function<void(Status, fxl::StringView)> callback);
-
- // Retrieves the data referenced by the given identifier and returns a subset
- // of its contents as a buffer. |offset| can be negative. In that case, the
- // offset is understood as starting from the end of the contents.
- static void ResolveObjectIdentifierAsBuffer(
- storage::PageStorage* storage,
- storage::ObjectIdentifier object_identifier, int64_t offset,
- int64_t max_size, storage::PageStorage::Location location,
- Status not_found_status,
- fit::function<void(Status, fsl::SizedVmo)> callback);
-
- // Returns true if a key matches the provided prefix, false otherwise.
- static bool MatchesPrefix(const std::string& key, const std::string& prefix);
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageUtils);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_PAGE_UTILS_H_
diff --git a/bin/ledger/app/serialization_version.h b/bin/ledger/app/serialization_version.h
deleted file mode 100644
index 0612b3b..0000000
--- a/bin/ledger/app/serialization_version.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_SERIALIZATION_VERSION_H_
-#define PERIDOT_BIN_LEDGER_APP_SERIALIZATION_VERSION_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace ledger {
-
-// The serialization version of anything Ledger stores on local storage
-// (directory structure, object/LevelDb serialization).
-inline constexpr fxl::StringView kSerializationVersion = "29";
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_SERIALIZATION_VERSION_H_
diff --git a/bin/ledger/app/sync_watcher_set.cc b/bin/ledger/app/sync_watcher_set.cc
deleted file mode 100644
index 4f0e3f0..0000000
--- a/bin/ledger/app/sync_watcher_set.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/sync_watcher_set.h"
-
-#include <lib/fit/function.h>
-
-namespace ledger {
-namespace {
-SyncState ConvertToSyncState(sync_coordinator::DownloadSyncState download) {
- switch (download) {
- case sync_coordinator::DOWNLOAD_IDLE:
- return SyncState::IDLE;
- case sync_coordinator::DOWNLOAD_PENDING:
- return SyncState::PENDING;
- case sync_coordinator::DOWNLOAD_IN_PROGRESS:
- return SyncState::IN_PROGRESS;
- case sync_coordinator::DOWNLOAD_ERROR:
- return SyncState::ERROR;
- }
-}
-
-SyncState ConvertToSyncState(sync_coordinator::UploadSyncState upload) {
- switch (upload) {
- case sync_coordinator::UPLOAD_IDLE:
- return SyncState::IDLE;
- case sync_coordinator::UPLOAD_PENDING:
- return SyncState::PENDING;
- case sync_coordinator::UPLOAD_IN_PROGRESS:
- return SyncState::IN_PROGRESS;
- case sync_coordinator::UPLOAD_ERROR:
- return SyncState::ERROR;
- }
-}
-
-bool operator==(
- const sync_coordinator::SyncStateWatcher::SyncStateContainer& lhs,
- const sync_coordinator::SyncStateWatcher::SyncStateContainer& rhs) {
- return std::tie(lhs.download, lhs.upload) ==
- std::tie(rhs.download, rhs.upload);
-}
-} // namespace
-
-class SyncWatcherSet::SyncWatcherContainer
- : public sync_coordinator::SyncStateWatcher {
- public:
- explicit SyncWatcherContainer(SyncWatcherPtr watcher)
- : watcher_(std::move(watcher)) {}
-
- ~SyncWatcherContainer() override {}
-
- void Start(SyncStateContainer base_state) {
- pending_ = base_state;
- Send();
- }
-
- void Notify(SyncStateContainer sync_state) override {
- if (sync_state == pending_) {
- return;
- }
- pending_ = sync_state;
-
- SendIfPending();
- }
-
- void set_on_empty(fit::closure on_empty_callback) {
- if (on_empty_callback) {
- watcher_.set_error_handler([callback = std::move(on_empty_callback)](
- zx_status_t status) { callback(); });
- }
- }
-
- private:
- void SendIfPending() {
- if (!watcher_ || notification_in_progress_ || last_ == pending_) {
- return;
- }
- Send();
- }
-
- void Send() {
- notification_in_progress_ = true;
- last_ = pending_;
- watcher_->SyncStateChanged(ConvertToSyncState(last_.download),
- ConvertToSyncState(last_.upload), [this]() {
- notification_in_progress_ = false;
- SendIfPending();
- });
- }
-
- // fidl interface to the client.
- SyncWatcherPtr watcher_;
-
- // True if a notification has been sent but not acknowledged by the client.
- bool notification_in_progress_ = false;
- // pending_ contains the next synchronization state to send to the watcher,
- // or the current one if no notification is currently in progress
- SyncStateContainer pending_;
- // last_ contains the last sent notification.
- SyncStateContainer last_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SyncWatcherContainer);
-};
-
-SyncWatcherSet::SyncWatcherSet() {}
-
-SyncWatcherSet::~SyncWatcherSet() {}
-
-void SyncWatcherSet::AddSyncWatcher(
- fidl::InterfaceHandle<SyncWatcher> watcher) {
- SyncWatcherContainer& container = watchers_.emplace(watcher.Bind());
- container.Start(current_);
-}
-
-void SyncWatcherSet::Notify(SyncStateContainer sync_state) {
- if (current_ == sync_state) {
- // Skip notifying if nothing has changed.
- return;
- }
- current_ = sync_state;
- for (SyncWatcherContainer& watcher : watchers_) {
- watcher.Notify(current_);
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/app/sync_watcher_set.h b/bin/ledger/app/sync_watcher_set.h
deleted file mode 100644
index 447e988..0000000
--- a/bin/ledger/app/sync_watcher_set.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_SYNC_WATCHER_SET_H_
-#define PERIDOT_BIN_LEDGER_APP_SYNC_WATCHER_SET_H_
-
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/sync_coordinator/public/sync_state_watcher.h"
-
-namespace ledger {
-
-class SyncWatcherSet : public sync_coordinator::SyncStateWatcher {
- public:
- SyncWatcherSet();
- ~SyncWatcherSet() override;
-
- // Adds a new SyncWatcher.
- void AddSyncWatcher(fidl::InterfaceHandle<SyncWatcher> watcher);
-
- // Notify the client watchers of a new state.
- void Notify(SyncStateContainer sync_state) override;
-
- private:
- class SyncWatcherContainer;
-
- void SendIfPending();
-
- SyncStateContainer current_;
- callback::AutoCleanableSet<SyncWatcherContainer> watchers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SyncWatcherSet);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_SYNC_WATCHER_SET_H_
diff --git a/bin/ledger/app/sync_watcher_set_unittest.cc b/bin/ledger/app/sync_watcher_set_unittest.cc
deleted file mode 100644
index 0124059..0000000
--- a/bin/ledger/app/sync_watcher_set_unittest.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/app/sync_watcher_set.h"
-
-#include <algorithm>
-#include <string>
-
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-
-namespace ledger {
-namespace {
-
-class SyncWatcherSetTest : public gtest::TestLoopFixture {
- public:
- SyncWatcherSetTest() {}
- ~SyncWatcherSetTest() override {}
-
- protected:
- void SetUp() override { ::testing::Test::SetUp(); }
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(SyncWatcherSetTest);
-};
-
-class SyncWatcherImpl : public SyncWatcher {
- public:
- explicit SyncWatcherImpl(fidl::InterfaceRequest<SyncWatcher> request)
- : binding_(this, std::move(request)) {}
- void SyncStateChanged(SyncState download_status, SyncState upload_status,
- SyncStateChangedCallback callback) override {
- download_states.push_back(download_status);
- upload_states.push_back(upload_status);
- callback();
- }
-
- std::vector<SyncState> download_states;
- std::vector<SyncState> upload_states;
-
- private:
- fidl::Binding<SyncWatcher> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SyncWatcherImpl);
-};
-
-TEST_F(SyncWatcherSetTest, OneWatcher) {
- SyncWatcherSet watcher_set;
- SyncWatcherPtr watcher_ptr;
-
- SyncWatcherImpl impl(watcher_ptr.NewRequest());
-
- watcher_set.Notify({sync_coordinator::DOWNLOAD_IN_PROGRESS,
- sync_coordinator::UPLOAD_PENDING});
-
- watcher_set.AddSyncWatcher(std::move(watcher_ptr));
-
- RunLoopUntilIdle();
-
- ASSERT_EQ(1u, impl.download_states.size());
- EXPECT_EQ(SyncState::IN_PROGRESS, *impl.download_states.rbegin());
- ASSERT_EQ(1u, impl.upload_states.size());
- EXPECT_EQ(SyncState::PENDING, *impl.upload_states.rbegin());
-
- watcher_set.Notify(
- {sync_coordinator::DOWNLOAD_ERROR, sync_coordinator::UPLOAD_IDLE});
-
- RunLoopUntilIdle();
-
- ASSERT_EQ(2u, impl.download_states.size());
- EXPECT_EQ(SyncState::ERROR, *impl.download_states.rbegin());
- ASSERT_EQ(2u, impl.upload_states.size());
- EXPECT_EQ(SyncState::IDLE, *impl.upload_states.rbegin());
-}
-
-TEST_F(SyncWatcherSetTest, TwoWatchers) {
- SyncWatcherSet watcher_set;
-
- SyncWatcherPtr watcher_ptr1;
- SyncWatcherImpl impl1(watcher_ptr1.NewRequest());
- watcher_set.AddSyncWatcher(std::move(watcher_ptr1));
-
- RunLoopUntilIdle();
- EXPECT_EQ(1u, impl1.download_states.size());
- EXPECT_EQ(SyncState::IDLE, *impl1.download_states.rbegin());
- EXPECT_EQ(1u, impl1.upload_states.size());
- EXPECT_EQ(SyncState::IDLE, *impl1.upload_states.rbegin());
-
- SyncWatcherPtr watcher_ptr2;
- SyncWatcherImpl impl2(watcher_ptr2.NewRequest());
- watcher_set.AddSyncWatcher(std::move(watcher_ptr2));
-
- RunLoopUntilIdle();
- EXPECT_EQ(1u, impl2.download_states.size());
- EXPECT_EQ(SyncState::IDLE, *impl2.download_states.rbegin());
- EXPECT_EQ(1u, impl2.upload_states.size());
- EXPECT_EQ(SyncState::IDLE, *impl2.upload_states.rbegin());
-
- watcher_set.Notify({sync_coordinator::DOWNLOAD_IN_PROGRESS,
- sync_coordinator::UPLOAD_PENDING});
-
- RunLoopUntilIdle();
-
- ASSERT_EQ(2u, impl1.download_states.size());
- EXPECT_EQ(SyncState::IN_PROGRESS, *impl1.download_states.rbegin());
- ASSERT_EQ(2u, impl1.upload_states.size());
- EXPECT_EQ(SyncState::PENDING, *impl1.upload_states.rbegin());
-
- ASSERT_EQ(2u, impl2.download_states.size());
- EXPECT_EQ(SyncState::IN_PROGRESS, *impl2.download_states.rbegin());
- ASSERT_EQ(2u, impl2.upload_states.size());
- EXPECT_EQ(SyncState::PENDING, *impl2.upload_states.rbegin());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/app/types.h b/bin/ledger/app/types.h
deleted file mode 100644
index 600af5d..0000000
--- a/bin/ledger/app/types.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_APP_TYPES_H_
-#define PERIDOT_BIN_LEDGER_APP_TYPES_H_
-
-#include <string>
-
-#include <zx/time.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-// The result of a predicate, meant to be checked on a closed page. The result
-// is |YES| or |NO| depending on whether the predicate is satisfied or not. If
-// however the page was opened during the operation, |PAGE_OPENED| is returned.
-enum class PagePredicateResult { YES, NO, PAGE_OPENED };
-
-// Holds information on when a page was last used.
-struct PageInfo {
- // The timestamp used for all currently opened pages.
- static constexpr zx::time_utc kOpenedPageTimestamp =
- zx::time_utc::infinite_past();
-
- std::string ledger_name;
- storage::PageId page_id;
- // The timestamp in UTC of when the page was last closed, as an indication
- // of when it was last used. If the page is currently open, the value is set
- // to |PageInfo::kOpenedPageTimestamp|.
- zx::time_utc timestamp;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_APP_TYPES_H_
diff --git a/bin/ledger/cache/BUILD.gn b/bin/ledger/cache/BUILD.gn
deleted file mode 100644
index 6b2b3e0..0000000
--- a/bin/ledger/cache/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("cache") {
- sources = [
- "lazy_value.h",
- "lru_cache.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
- sources = [
- "lazy_value_unittest.cc",
- "lru_cache_unittest.cc",
- ]
-
- deps = [
- ":cache",
- "//garnet/public/lib/callback",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/cache/lazy_value.h b/bin/ledger/cache/lazy_value.h
deleted file mode 100644
index 20f8675..0000000
--- a/bin/ledger/cache/lazy_value.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CACHE_LAZY_VALUE_H_
-#define PERIDOT_BIN_LEDGER_CACHE_LAZY_VALUE_H_
-
-#include <functional>
-#include <vector>
-
-#include <lib/fit/function.h>
-
-namespace cache {
-// Implements a self-populating lazy value.
-//
-// This class allows to setup a lazy value that will be generated asynchronously
-// the first time it is requested.
-//
-// V is the type of the lazy value. V must be default-constructible and either
-// copyable or movable.
-// S is the type of the success status for the data generator.
-template <typename V, typename S>
-class LazyValue {
- public:
- // Constructor.
- //
- // |ok_status| is the success status of the generator.
- // |generator| generates the value. It takes a callback to returns its result.
- // It must return |ok_status| as a status when the request is successful.
- // Any other return value is considered a failure.
- LazyValue(S ok_status,
- fit::function<void(fit::function<void(S, V)>)> generator)
- : ok_status_(ok_status),
- generator_(std::move(generator)),
- value_set_(false) {}
-
- // Retrieves the value and returns it to |callback|.
- //
- // If the value is cached, |callback| will be called synchronously. Otherwise,
- // |generator| will be called, and depending on its implementation, |callback|
- // might be called synchronously or not.
- void Get(fit::function<void(S, const V&)> callback) {
- if (value_set_) {
- callback(ok_status_, value_);
- return;
- }
- requests_.push_back(std::move(callback));
- if (requests_.size() == 1) {
- generator_([this](S status, V value) {
- auto callbacks = std::move(requests_);
- requests_.clear();
-
- if (status == ok_status_) {
- value_ = std::move(value);
- value_set_ = true;
- }
- for (const auto& callback : callbacks) {
- callback(status, value_);
- }
- });
- }
- }
-
- private:
- S ok_status_;
- fit::function<void(fit::function<void(S, V)>)> generator_;
- V value_;
- bool value_set_;
- std::vector<fit::function<void(S, const V&)>> requests_;
-};
-
-} // namespace cache
-
-#endif // PERIDOT_BIN_LEDGER_CACHE_LAZY_VALUE_H_
diff --git a/bin/ledger/cache/lazy_value_unittest.cc b/bin/ledger/cache/lazy_value_unittest.cc
deleted file mode 100644
index 198902f..0000000
--- a/bin/ledger/cache/lazy_value_unittest.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cache/lazy_value.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-
-namespace cache {
-namespace {
-TEST(LazyValueTest, SimpleGet) {
- auto generator = [](fit::function<void(size_t, size_t)> callback) {
- callback(0, 1);
- };
-
- LazyValue<size_t, size_t> cache(0, generator);
-
- bool called;
- size_t status;
- size_t value;
- cache.Get(
- callback::Capture(callback::SetWhenCalled(&called), &status, &value));
- ASSERT_TRUE(called);
- EXPECT_EQ(0u, status);
- EXPECT_EQ(1u, value);
-}
-
-TEST(LazyValueTest, FailingGenerator) {
- size_t nb_called = 0;
- auto generator = [&nb_called](fit::function<void(size_t, size_t)> callback) {
- ++nb_called;
- callback(1, 0);
- };
-
- LazyValue<size_t, size_t> cache(0, generator);
-
- bool called;
- size_t status;
- size_t value;
-
- cache.Get(
- callback::Capture(callback::SetWhenCalled(&called), &status, &value));
- ASSERT_TRUE(called);
- EXPECT_EQ(1u, status);
- EXPECT_EQ(1u, nb_called);
-
- cache.Get(
- callback::Capture(callback::SetWhenCalled(&called), &status, &value));
- ASSERT_TRUE(called);
- EXPECT_EQ(1u, status);
- EXPECT_EQ(2u, nb_called);
-}
-
-TEST(LazyValueTest, CacheCallback) {
- size_t nb_called = 0;
- fit::function<void(size_t, size_t)> generator_callback;
- auto generator = [&nb_called, &generator_callback](
- fit::function<void(size_t, size_t)> callback) {
- ++nb_called;
- generator_callback = std::move(callback);
- };
-
- LazyValue<size_t, size_t> cache(0, generator);
-
- bool called1, called2;
- size_t status1, status2;
- size_t value1, value2;
-
- cache.Get(
- callback::Capture(callback::SetWhenCalled(&called1), &status1, &value1));
-
- EXPECT_FALSE(called1);
- EXPECT_EQ(1u, nb_called);
-
- cache.Get(
- callback::Capture(callback::SetWhenCalled(&called2), &status2, &value2));
-
- EXPECT_FALSE(called2);
- EXPECT_EQ(1u, nb_called);
-
- generator_callback(0, 42);
-
- ASSERT_TRUE(called1);
- ASSERT_TRUE(called2);
- EXPECT_EQ(1u, nb_called);
- EXPECT_EQ(0u, status1);
- EXPECT_EQ(42u, value1);
- EXPECT_EQ(0u, status2);
- EXPECT_EQ(42u, value2);
-}
-
-} // namespace
-} // namespace cache
diff --git a/bin/ledger/cache/lru_cache.h b/bin/ledger/cache/lru_cache.h
deleted file mode 100644
index 32a7845..0000000
--- a/bin/ledger/cache/lru_cache.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CACHE_LRU_CACHE_H_
-#define PERIDOT_BIN_LEDGER_CACHE_LRU_CACHE_H_
-
-#include <functional>
-#include <list>
-#include <map>
-#include <set>
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-namespace cache {
-// Implements a self-populating LRU cache.
-//
-// This class allows the user to provide a generator for its data, and will
-// cache a given number of entries, discarding least used entries once its reach
-// its maximum capacity.
-//
-// K is the type of the key of the cached data.
-// V is the type of the cached data.
-// S is the type of the success status for the data generator.
-template <typename K, typename V, typename S>
-class LRUCache {
- public:
- // Constructor.
- //
- // |size| is the maximum capacity of the cache.
- // |ok_status| is the success status of the generator.
- // |generator| generates the value to be cached for the given key. It takes a
- // callback to returns its result. It must return |ok_status| as a status
- // when the request is successful. Any other return value is considered a
- // failure.
- LRUCache(size_t size, S ok_status,
- fit::function<void(K, fit::function<void(S, V)>)> generator)
- : size_(size), ok_status_(ok_status), generator_(std::move(generator)) {}
-
- // Retrieves the value for |key| and returns it to |callback|.
- //
- // If the value is cached, |callback| will be called synchronously. Otherwise,
- // |generator| will be called, and depending on its implementation, |callback|
- // might be called synchronously or not.
- void Get(const K& key, fit::function<void(S, const V&)> callback) {
- auto iterator = map_.find(key);
- if (iterator != map_.end()) {
- // Move the list iterator to the front.
- auto list_iterator = iterator->second;
- values_.splice(values_.begin(), values_, list_iterator);
-
- // Call back.
- callback(ok_status_, iterator->second->second);
- return;
- }
- auto request_iterator = requests_.find(key);
- if (request_iterator != requests_.end()) {
- request_iterator->second.push_back(std::move(callback));
- return;
- }
- requests_[key].push_back(std::move(callback));
- generator_(key, [this, key](S status, V value) {
- auto request_iterator = requests_.find(key);
- FXL_DCHECK(request_iterator != requests_.end());
- auto callbacks = std::move(request_iterator->second);
- requests_.erase(request_iterator);
-
- if (status != ok_status_) {
- for (const auto& callback : callbacks) {
- callback(status, value);
- }
- return;
- }
-
- values_.emplace_front(key, value);
- map_[std::move(key)] = values_.begin();
- if (values_.size() > size_) {
- map_.erase(values_.rbegin()->first);
- values_.pop_back();
- }
- for (const auto& callback : callbacks) {
- callback(status, value);
- }
- });
- }
-
- private:
- using ValueList = std::list<std::pair<K, V>>;
- ValueList values_;
- std::map<K, typename ValueList::iterator> map_;
- std::map<K, std::vector<fit::function<void(S, const V&)>>> requests_;
- size_t size_;
- S ok_status_;
- fit::function<void(K, fit::function<void(S, V)>)> generator_;
-};
-
-} // namespace cache
-
-#endif // PERIDOT_BIN_LEDGER_CACHE_LRU_CACHE_H_
diff --git a/bin/ledger/cache/lru_cache_unittest.cc b/bin/ledger/cache/lru_cache_unittest.cc
deleted file mode 100644
index d65d0c0..0000000
--- a/bin/ledger/cache/lru_cache_unittest.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cache/lru_cache.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-
-namespace cache {
-namespace {
-TEST(LRUCacheTest, SimpleGet) {
- auto generator = [](size_t i, fit::function<void(size_t, size_t)> callback) {
- callback(0, 2 * i);
- };
-
- LRUCache<size_t, size_t, size_t> cache(200, 0, generator);
-
- bool called;
- size_t status;
- size_t value;
- cache.Get(
- 0, callback::Capture(callback::SetWhenCalled(&called), &status, &value));
- ASSERT_TRUE(called);
- EXPECT_EQ(0u, status);
- EXPECT_EQ(0u, value);
-
- cache.Get(
- 42, callback::Capture(callback::SetWhenCalled(&called), &status, &value));
- ASSERT_TRUE(called);
- EXPECT_EQ(0u, status);
- EXPECT_EQ(84u, value);
-}
-
-TEST(LRUCacheTest, FailingGenerator) {
- size_t nb_called = 0;
- auto generator = [&nb_called](size_t i,
- fit::function<void(size_t, size_t)> callback) {
- ++nb_called;
- callback(1, 0);
- };
-
- LRUCache<size_t, size_t, size_t> cache(200, 0, generator);
-
- bool called;
- size_t status;
- size_t value;
-
- cache.Get(
- 0, callback::Capture(callback::SetWhenCalled(&called), &status, &value));
- ASSERT_TRUE(called);
- EXPECT_EQ(1u, status);
- EXPECT_EQ(1u, nb_called);
-
- cache.Get(
- 0, callback::Capture(callback::SetWhenCalled(&called), &status, &value));
- ASSERT_TRUE(called);
- EXPECT_EQ(1u, status);
- EXPECT_EQ(2u, nb_called);
-}
-
-TEST(LRUCacheTest, CacheCallback) {
- size_t nb_called = 0;
- fit::function<void(size_t, size_t)> generator_callback;
- auto generator = [&nb_called, &generator_callback](
- size_t i, fit::function<void(size_t, size_t)> callback) {
- ++nb_called;
- generator_callback = std::move(callback);
- };
-
- LRUCache<size_t, size_t, size_t> cache(200, 0, generator);
-
- bool called1, called2;
- size_t status1, status2;
- size_t value1, value2;
-
- cache.Get(0, callback::Capture(callback::SetWhenCalled(&called1), &status1,
- &value1));
-
- EXPECT_FALSE(called1);
- EXPECT_EQ(1u, nb_called);
-
- cache.Get(0, callback::Capture(callback::SetWhenCalled(&called2), &status2,
- &value2));
-
- EXPECT_FALSE(called2);
- EXPECT_EQ(1u, nb_called);
-
- generator_callback(0, 42);
-
- ASSERT_TRUE(called1);
- ASSERT_TRUE(called2);
- EXPECT_EQ(1u, nb_called);
- EXPECT_EQ(0u, status1);
- EXPECT_EQ(42u, value1);
- EXPECT_EQ(0u, status2);
- EXPECT_EQ(42u, value2);
-}
-
-TEST(LRUCacheTest, LRUPolicy) {
- size_t nb_called = 0;
- fit::function<void(size_t, size_t)> generator_callback;
- auto generator = [&nb_called](size_t i,
- fit::function<void(size_t, size_t)> callback) {
- ++nb_called;
- callback(0u, 0u);
- };
-
- LRUCache<size_t, size_t, size_t> cache(3, 0, generator);
-
- size_t status;
- size_t value;
-
- cache.Get(0, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(1u, nb_called);
- cache.Get(0, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(1u, nb_called);
- cache.Get(1, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(2u, nb_called);
- cache.Get(2, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(3u, nb_called);
- cache.Get(0, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(3u, nb_called);
- cache.Get(1, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(3u, nb_called);
- cache.Get(2, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(3u, nb_called);
- cache.Get(3, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(4u, nb_called);
- cache.Get(1, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(4u, nb_called);
- cache.Get(2, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(4u, nb_called);
- cache.Get(3, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(4u, nb_called);
- cache.Get(0, callback::Capture([] {}, &status, &value));
- EXPECT_EQ(5u, nb_called);
-}
-
-} // namespace
-} // namespace cache
diff --git a/bin/ledger/cloud_sync/BUILD.gn b/bin/ledger/cloud_sync/BUILD.gn
deleted file mode 100644
index e84d990..0000000
--- a/bin/ledger/cloud_sync/BUILD.gn
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("cloud_sync") {
- deps = [
- "//peridot/bin/ledger/cloud_sync/impl",
- "//peridot/bin/ledger/cloud_sync/public",
- ]
-}
diff --git a/bin/ledger/cloud_sync/impl/BUILD.gn b/bin/ledger/cloud_sync/impl/BUILD.gn
deleted file mode 100644
index f5406ae..0000000
--- a/bin/ledger/cloud_sync/impl/BUILD.gn
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("impl") {
- sources = [
- "aggregator.cc",
- "aggregator.h",
- "batch_download.cc",
- "batch_download.h",
- "batch_upload.cc",
- "batch_upload.h",
- "constants.h",
- "ledger_sync_impl.cc",
- "ledger_sync_impl.h",
- "page_download.cc",
- "page_download.h",
- "page_sync_impl.cc",
- "page_sync_impl.h",
- "page_upload.cc",
- "page_upload.h",
- "user_sync_impl.cc",
- "user_sync_impl.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/backoff",
- "//peridot/bin/ledger/cloud_sync/public",
- "//peridot/bin/ledger/encryption/impl",
- "//peridot/bin/ledger/encryption/public",
- "//peridot/bin/ledger/environment",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/storage/public",
- "//peridot/lib/commit_pack",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//peridot/bin/ledger/encryption/primitives",
- "//zircon/public/lib/trace",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "aggregator_unittest.cc",
- "batch_download_unittest.cc",
- "batch_upload_unittest.cc",
- "page_download_unittest.cc",
- "page_sync_impl_unittest.cc",
- "page_upload_unittest.cc",
- "user_sync_impl_unittest.cc",
- ]
-
- deps = [
- ":impl",
- "//garnet/public/lib/backoff/testing",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/cloud_sync/impl/testing",
- "//peridot/bin/ledger/cloud_sync/testing",
- "//peridot/bin/ledger/encryption/fake",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/storage/testing",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/scoped_tmpfs",
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/cloud_sync/impl/aggregator.cc b/bin/ledger/cloud_sync/impl/aggregator.cc
deleted file mode 100644
index 6667c04..0000000
--- a/bin/ledger/cloud_sync/impl/aggregator.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/aggregator.h"
-
-#include <memory>
-
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-
-namespace cloud_sync {
-class Aggregator::Listener : public SyncStateWatcher {
- public:
- explicit Listener(Aggregator* aggregator);
- ~Listener() override;
-
- // Notify the client watcher, if present, of a new state.
- void Notify(SyncStateWatcher::SyncStateContainer sync_state) override;
-
- SyncStateWatcher::SyncStateContainer GetCurrentState();
-
- private:
- SyncStateWatcher::SyncStateContainer state_;
-
- Aggregator* aggregator_;
-};
-
-Aggregator::Listener::Listener(Aggregator* aggregator)
- : aggregator_(aggregator) {}
-
-Aggregator::Listener::~Listener() { aggregator_->UnregisterListener(this); }
-
-void Aggregator::Listener::Notify(
- SyncStateWatcher::SyncStateContainer sync_state) {
- state_ = sync_state;
- aggregator_->NewStateAvailable();
-}
-
-SyncStateWatcher::SyncStateContainer Aggregator::Listener::GetCurrentState() {
- return state_;
-}
-
-Aggregator::Aggregator() {}
-
-Aggregator::~Aggregator() {
- // There should be no listener left when destroying this object.
- FXL_DCHECK(listeners_.empty());
-}
-
-void Aggregator::SetBaseWatcher(SyncStateWatcher* base_watcher) {
- base_watcher_ = base_watcher;
- if (base_watcher_) {
- base_watcher_->Notify(state_);
- }
-}
-
-std::unique_ptr<SyncStateWatcher> Aggregator::GetNewStateWatcher() {
- std::unique_ptr<Listener> listener = std::make_unique<Listener>(this);
- listeners_.insert(listener.get());
- return listener;
-}
-
-void Aggregator::UnregisterListener(Listener* listener) {
- listeners_.erase(listener);
-}
-
-void Aggregator::NewStateAvailable() {
- SyncStateWatcher::SyncStateContainer new_state;
- for (Aggregator::Listener* listener : listeners_) {
- new_state.Merge(listener->GetCurrentState());
- }
- if (new_state != state_) {
- state_ = new_state;
- if (base_watcher_) {
- base_watcher_->Notify(state_);
- }
- }
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/aggregator.h b/bin/ledger/cloud_sync/impl/aggregator.h
deleted file mode 100644
index 994556d..0000000
--- a/bin/ledger/cloud_sync/impl/aggregator.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_AGGREGATOR_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_AGGREGATOR_H_
-
-#include <memory>
-#include <set>
-
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-
-namespace cloud_sync {
-
-// Aggregator collects notifications from several watchers generated using
-// |GetNewStateWatcher| into one notification stream sent to the watcher set in
-// the constructor.
-class Aggregator {
- public:
- Aggregator();
- ~Aggregator();
-
- // Sets the base watcher that will receive the aggregated notification stream.
- void SetBaseWatcher(cloud_sync::SyncStateWatcher* base_watcher);
-
- // Generates a new source of notifications for this aggregator. Note that
- // std::unique_ptr<SyncStateWatcher> should remain alive as long as the
- // Aggregator object is alive.
- std::unique_ptr<SyncStateWatcher> GetNewStateWatcher();
-
- private:
- class Listener;
-
- void UnregisterListener(Listener* listener);
- void NewStateAvailable();
-
- SyncStateWatcher::SyncStateContainer state_;
-
- std::set<Listener*> listeners_;
- SyncStateWatcher* base_watcher_ = nullptr;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(Aggregator);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_AGGREGATOR_H_
diff --git a/bin/ledger/cloud_sync/impl/aggregator_unittest.cc b/bin/ledger/cloud_sync/impl/aggregator_unittest.cc
deleted file mode 100644
index 45ef36b..0000000
--- a/bin/ledger/cloud_sync/impl/aggregator_unittest.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/aggregator.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-
-namespace cloud_sync {
-
-namespace {
-
-class RecordingWatcher : public SyncStateWatcher {
- public:
- void Notify(SyncStateContainer sync_state) override {
- states.push_back(sync_state);
- }
-
- std::vector<SyncStateContainer> states;
-};
-
-TEST(AggregatorTest, SendFirstNotification) {
- std::unique_ptr<RecordingWatcher> base_watcher =
- std::make_unique<RecordingWatcher>();
- Aggregator aggregator;
- aggregator.SetBaseWatcher(base_watcher.get());
-
- std::unique_ptr<SyncStateWatcher> watcher1 = aggregator.GetNewStateWatcher();
- watcher1->Notify(DOWNLOAD_IN_PROGRESS, UPLOAD_WAIT_REMOTE_DOWNLOAD);
-
- ASSERT_EQ(2u, base_watcher->states.size());
- EXPECT_EQ(DOWNLOAD_IN_PROGRESS, base_watcher->states[1].download);
- EXPECT_EQ(UPLOAD_WAIT_REMOTE_DOWNLOAD, base_watcher->states[1].upload);
-}
-
-TEST(AggregatorTest, AggregateTwo) {
- std::unique_ptr<RecordingWatcher> base_watcher =
- std::make_unique<RecordingWatcher>();
-
- Aggregator aggregator;
- aggregator.SetBaseWatcher(base_watcher.get());
-
- std::unique_ptr<SyncStateWatcher> watcher1 = aggregator.GetNewStateWatcher();
- std::unique_ptr<SyncStateWatcher> watcher2 = aggregator.GetNewStateWatcher();
-
- EXPECT_EQ(DOWNLOAD_IDLE, base_watcher->states.rbegin()->download);
- EXPECT_EQ(UPLOAD_IDLE, base_watcher->states.rbegin()->upload);
-
- watcher1->Notify(DOWNLOAD_IN_PROGRESS, UPLOAD_WAIT_REMOTE_DOWNLOAD);
-
- EXPECT_EQ(DOWNLOAD_IN_PROGRESS, base_watcher->states.rbegin()->download);
- EXPECT_EQ(UPLOAD_WAIT_REMOTE_DOWNLOAD, base_watcher->states.rbegin()->upload);
-
- watcher2->Notify(DOWNLOAD_IDLE, UPLOAD_IDLE);
- EXPECT_EQ(DOWNLOAD_IN_PROGRESS, base_watcher->states.rbegin()->download);
- EXPECT_EQ(UPLOAD_WAIT_REMOTE_DOWNLOAD, base_watcher->states.rbegin()->upload);
-
- watcher1->Notify(DOWNLOAD_IDLE, UPLOAD_IN_PROGRESS);
- EXPECT_EQ(DOWNLOAD_IDLE, base_watcher->states.rbegin()->download);
- EXPECT_EQ(UPLOAD_IN_PROGRESS, base_watcher->states.rbegin()->upload);
-}
-
-TEST(AggregatorTest, ResetWatcher) {
- std::unique_ptr<RecordingWatcher> base_watcher =
- std::make_unique<RecordingWatcher>();
- Aggregator aggregator;
- aggregator.SetBaseWatcher(base_watcher.get());
-
- std::unique_ptr<SyncStateWatcher> watcher1 = aggregator.GetNewStateWatcher();
- watcher1->Notify(DOWNLOAD_IN_PROGRESS, UPLOAD_WAIT_REMOTE_DOWNLOAD);
-
- ASSERT_EQ(2u, base_watcher->states.size());
- EXPECT_EQ(DOWNLOAD_IN_PROGRESS, base_watcher->states[1].download);
- EXPECT_EQ(UPLOAD_WAIT_REMOTE_DOWNLOAD, base_watcher->states[1].upload);
-
- std::unique_ptr<RecordingWatcher> base_watcher2 =
- std::make_unique<RecordingWatcher>();
- aggregator.SetBaseWatcher(base_watcher2.get());
-
- ASSERT_EQ(1u, base_watcher2->states.size());
- EXPECT_EQ(DOWNLOAD_IN_PROGRESS, base_watcher2->states[0].download);
- EXPECT_EQ(UPLOAD_WAIT_REMOTE_DOWNLOAD, base_watcher2->states[0].upload);
-
- watcher1->Notify(DOWNLOAD_IDLE, UPLOAD_IDLE);
-
- ASSERT_EQ(2u, base_watcher2->states.size());
- EXPECT_EQ(DOWNLOAD_IDLE, base_watcher2->states[1].download);
- EXPECT_EQ(UPLOAD_IDLE, base_watcher2->states[1].upload);
-
- // States in first base watcher have not changed.
- EXPECT_EQ(2u, base_watcher->states.size());
-}
-
-} // namespace
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/batch_download.cc b/bin/ledger/cloud_sync/impl/batch_download.cc
deleted file mode 100644
index 6264c2f..0000000
--- a/bin/ledger/cloud_sync/impl/batch_download.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/batch_download.h"
-
-#include <utility>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/constants.h"
-
-namespace cloud_sync {
-
-BatchDownload::BatchDownload(
- storage::PageStorage* storage,
- encryption::EncryptionService* encryption_service,
- std::vector<cloud_provider::CommitPackEntry> entries,
- std::unique_ptr<cloud_provider::Token> position_token, fit::closure on_done,
- fit::closure on_error)
- : storage_(storage),
- encryption_service_(encryption_service),
- entries_(std::move(entries)),
- position_token_(std::move(position_token)),
- on_done_(std::move(on_done)),
- on_error_(std::move(on_error)),
- weak_ptr_factory_(this) {
- FXL_DCHECK(storage);
- TRACE_ASYNC_BEGIN("ledger", "batch_download",
- reinterpret_cast<uintptr_t>(this));
-}
-
-BatchDownload::~BatchDownload() {
- TRACE_ASYNC_END("ledger", "batch_download",
- reinterpret_cast<uintptr_t>(this));
-}
-
-void BatchDownload::Start() {
- FXL_DCHECK(!started_);
- started_ = true;
- auto waiter = fxl::MakeRefCounted<callback::Waiter<
- encryption::Status, storage::PageStorage::CommitIdAndBytes>>(
- encryption::Status::OK);
- for (auto& entry : entries_) {
- encryption_service_->DecryptCommit(
- entry.data,
- [id = entry.id, callback = waiter->NewCallback()](
- encryption::Status status, std::string content) mutable {
- callback(status, storage::PageStorage::CommitIdAndBytes(
- std::move(id), std::move(content)));
- });
- }
- waiter->Finalize(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this](encryption::Status status,
- std::vector<storage::PageStorage::CommitIdAndBytes> commits) {
- if (status != encryption::Status::OK) {
- on_error_();
- return;
- }
-
- storage_->AddCommitsFromSync(
- std::move(commits), storage::ChangeSource::CLOUD,
- callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this](storage::Status status,
- std::vector<storage::CommitId> /*commit_ids*/) {
- if (status != storage::Status::OK) {
- on_error_();
- return;
- }
-
- UpdateTimestampAndQuit();
- }));
- }));
-}
-
-void BatchDownload::UpdateTimestampAndQuit() {
- if (!position_token_) {
- // Can be deleted within.
- on_done_();
- return;
- }
-
- storage_->SetSyncMetadata(
- kTimestampKey, convert::ToString(position_token_->opaque_id),
- callback::MakeScoped(weak_ptr_factory_.GetWeakPtr(),
- [this](storage::Status status) {
- if (status != storage::Status::OK) {
- on_error_();
- return;
- }
-
- // Can be deleted within.
- on_done_();
- }));
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/batch_download.h b/bin/ledger/cloud_sync/impl/batch_download.h
deleted file mode 100644
index f26139d..0000000
--- a/bin/ledger/cloud_sync/impl/batch_download.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_BATCH_DOWNLOAD_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_BATCH_DOWNLOAD_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-namespace cloud_sync {
-
-// Adds a batch of remote commits to storage.
-//
-// Given a list of commit metadata, this class makes a request to add them to
-// storage, and waits until storage confirms that the operation completed before
-// calling |on_done|.
-//
-// The operation is not retryable, and errors reported through |on_error| are
-// not recoverable.
-class BatchDownload {
- public:
- BatchDownload(storage::PageStorage* storage,
- encryption::EncryptionService* encryption_service,
- std::vector<cloud_provider::CommitPackEntry> entries,
- std::unique_ptr<cloud_provider::Token> position_token,
- fit::closure on_done, fit::closure on_error);
- ~BatchDownload();
-
- // Can be called only once.
- void Start();
-
- private:
- void UpdateTimestampAndQuit();
-
- storage::PageStorage* const storage_;
- encryption::EncryptionService* const encryption_service_;
- std::vector<cloud_provider::CommitPackEntry> entries_;
- std::unique_ptr<cloud_provider::Token> position_token_;
- fit::closure on_done_;
- fit::closure on_error_;
- bool started_ = false;
-
- // Must be the last member.
- fxl::WeakPtrFactory<BatchDownload> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BatchDownload);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_BATCH_DOWNLOAD_H_
diff --git a/bin/ledger/cloud_sync/impl/batch_download_unittest.cc b/bin/ledger/cloud_sync/impl/batch_download_unittest.cc
deleted file mode 100644
index 70c5333..0000000
--- a/bin/ledger/cloud_sync/impl/batch_download_unittest.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/batch_download.h"
-
-#include <map>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/capture.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/cloud_sync/impl/constants.h"
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-namespace cloud_sync {
-
-namespace {
-
-// Creates a dummy continuation token.
-std::unique_ptr<cloud_provider::Token> MakeToken(
- convert::ExtendedStringView token_id) {
- auto token = std::make_unique<cloud_provider::Token>();
- token->opaque_id = convert::ToArray(token_id);
- return token;
-}
-
-// Fake implementation of storage::PageStorage. Injects the data that
-// CommitUpload asks about: page id and unsynced objects to be uploaded.
-// Registers the reported results of the upload: commits and objects marked as
-// synced.
-class TestPageStorage : public storage::PageStorageEmptyImpl {
- public:
- explicit TestPageStorage(async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher) {}
-
- void AddCommitsFromSync(
- std::vector<storage::PageStorage::CommitIdAndBytes> ids_and_bytes,
- storage::ChangeSource source,
- fit::function<void(storage::Status, std::vector<storage::CommitId>)>
- callback) override {
- ASSERT_EQ(storage::ChangeSource::CLOUD, source);
- if (should_fail_add_commit_from_sync) {
- async::PostTask(dispatcher_, [callback = std::move(callback)]() {
- callback(storage::Status::IO_ERROR, {});
- });
- return;
- }
- async::PostTask(
- dispatcher_, [this, ids_and_bytes = std::move(ids_and_bytes),
- callback = std::move(callback)]() mutable {
- for (auto& commit : ids_and_bytes) {
- received_commits[std::move(commit.id)] = std::move(commit.bytes);
- }
- callback(storage::Status::OK, {});
- });
- }
-
- void SetSyncMetadata(fxl::StringView key, fxl::StringView value,
- fit::function<void(storage::Status)> callback) override {
- sync_metadata[key.ToString()] = value.ToString();
- async::PostTask(dispatcher_, [callback = std::move(callback)]() {
- callback(storage::Status::OK);
- });
- }
-
- bool should_fail_add_commit_from_sync = false;
- std::map<storage::CommitId, std::string> received_commits;
- std::map<std::string, std::string> sync_metadata;
-
- private:
- async_dispatcher_t* const dispatcher_;
-};
-
-class BatchDownloadTest : public gtest::TestLoopFixture {
- public:
- BatchDownloadTest()
- : storage_(dispatcher()), encryption_service_(dispatcher()) {}
- ~BatchDownloadTest() override {}
-
- protected:
- TestPageStorage storage_;
- encryption::FakeEncryptionService encryption_service_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(BatchDownloadTest);
-};
-
-TEST_F(BatchDownloadTest, AddCommit) {
- int done_calls = 0;
- int error_calls = 0;
- std::vector<cloud_provider::CommitPackEntry> entries;
- entries.push_back(MakeTestCommit(&encryption_service_, "id1", "content1"));
- BatchDownload batch_download(
- &storage_, &encryption_service_, std::move(entries), MakeToken("42"),
- [&done_calls] { done_calls++; }, [&error_calls] { error_calls++; });
- batch_download.Start();
-
- RunLoopUntilIdle();
- EXPECT_EQ(1, done_calls);
- EXPECT_EQ(0, error_calls);
- EXPECT_EQ(1u, storage_.received_commits.size());
- EXPECT_EQ("content1", storage_.received_commits["id1"]);
- EXPECT_EQ("42", storage_.sync_metadata[kTimestampKey.ToString()]);
-}
-
-TEST_F(BatchDownloadTest, AddMultipleCommits) {
- int done_calls = 0;
- int error_calls = 0;
- std::vector<cloud_provider::CommitPackEntry> entries;
- entries.push_back(MakeTestCommit(&encryption_service_, "id1", "content1"));
- entries.push_back(MakeTestCommit(&encryption_service_, "id2", "content2"));
- BatchDownload batch_download(
- &storage_, &encryption_service_, std::move(entries), MakeToken("43"),
- [&done_calls] { done_calls++; }, [&error_calls] { error_calls++; });
- batch_download.Start();
-
- RunLoopUntilIdle();
- EXPECT_EQ(1, done_calls);
- EXPECT_EQ(0, error_calls);
- EXPECT_EQ(2u, storage_.received_commits.size());
- EXPECT_EQ("content1", storage_.received_commits["id1"]);
- EXPECT_EQ("content2", storage_.received_commits["id2"]);
- EXPECT_EQ("43", storage_.sync_metadata[kTimestampKey.ToString()]);
-}
-
-TEST_F(BatchDownloadTest, FailToAddCommit) {
- int done_calls = 0;
- int error_calls = 0;
- std::vector<cloud_provider::CommitPackEntry> entries;
- entries.push_back(MakeTestCommit(&encryption_service_, "id1", "content1"));
- BatchDownload batch_download(
- &storage_, &encryption_service_, std::move(entries), MakeToken("42"),
- [&done_calls] { done_calls++; }, [&error_calls] { error_calls++; });
- storage_.should_fail_add_commit_from_sync = true;
- batch_download.Start();
-
- RunLoopUntilIdle();
- EXPECT_EQ(0, done_calls);
- EXPECT_EQ(1, error_calls);
- EXPECT_TRUE(storage_.received_commits.empty());
- EXPECT_EQ(0u, storage_.sync_metadata.count(kTimestampKey.ToString()));
-}
-
-} // namespace
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/batch_upload.cc b/bin/ledger/cloud_sync/impl/batch_upload.cc
deleted file mode 100644
index 229f3a1..0000000
--- a/bin/ledger/cloud_sync/impl/batch_upload.cc
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/batch_upload.h"
-
-#include <algorithm>
-#include <set>
-#include <utility>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/trace_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <trace/event.h>
-
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-namespace cloud_sync {
-
-BatchUpload::BatchUpload(
- storage::PageStorage* storage,
- encryption::EncryptionService* encryption_service,
- cloud_provider::PageCloudPtr* page_cloud,
- std::vector<std::unique_ptr<const storage::Commit>> commits,
- fit::closure on_done, fit::function<void(ErrorType)> on_error,
- unsigned int max_concurrent_uploads)
- : storage_(storage),
- encryption_service_(encryption_service),
- page_cloud_(page_cloud),
- commits_(std::move(commits)),
- on_done_(std::move(on_done)),
- on_error_(std::move(on_error)),
- max_concurrent_uploads_(max_concurrent_uploads),
- weak_ptr_factory_(this) {
- TRACE_ASYNC_BEGIN("ledger", "batch_upload",
- reinterpret_cast<uintptr_t>(this));
- FXL_DCHECK(storage_);
- FXL_DCHECK(page_cloud_);
-}
-
-BatchUpload::~BatchUpload() {
- TRACE_ASYNC_END("ledger", "batch_upload", reinterpret_cast<uintptr_t>(this));
-}
-
-void BatchUpload::Start() {
- FXL_DCHECK(!started_);
- FXL_DCHECK(!errored_);
- started_ = true;
- storage_->GetUnsyncedPieces(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this](storage::Status status,
- std::vector<storage::ObjectIdentifier> object_identifiers) {
- if (status != storage::Status::OK) {
- errored_ = true;
- on_error_(ErrorType::PERMANENT);
- return;
- }
- remaining_object_identifiers_ = std::move(object_identifiers);
- StartObjectUpload();
- }));
-}
-
-void BatchUpload::Retry() {
- FXL_DCHECK(started_);
- FXL_DCHECK(errored_);
- errored_ = false;
- error_type_ = ErrorType::TEMPORARY;
- StartObjectUpload();
-}
-
-void BatchUpload::StartObjectUpload() {
- FXL_DCHECK(current_uploads_ == 0u);
- // If there are no unsynced objects left, upload the commits.
- if (remaining_object_identifiers_.empty()) {
- FilterAndUploadCommits();
- return;
- }
-
- while (current_uploads_ < max_concurrent_uploads_ &&
- !remaining_object_identifiers_.empty()) {
- UploadNextObject();
- }
-}
-
-void BatchUpload::UploadNextObject() {
- FXL_DCHECK(!remaining_object_identifiers_.empty());
- FXL_DCHECK(current_uploads_ < max_concurrent_uploads_);
- current_uploads_++;
- current_objects_handled_++;
- auto object_identifier_to_send =
- std::move(remaining_object_identifiers_.back());
- // Pop the object from the queue - if the upload fails, we will re-enqueue it.
- remaining_object_identifiers_.pop_back();
-
- // TODO(qsr): Retrieving the object name should be done in parallel with
- // retrieving the object content.
- encryption_service_->GetObjectName(
- object_identifier_to_send,
- callback::MakeScoped(weak_ptr_factory_.GetWeakPtr(),
- [this, object_identifier_to_send](
- encryption::Status encryption_status,
- std::string object_name) mutable {
- if (encryption_status != encryption::Status::OK) {
- EnqueueForRetryAndSignalError(
- std::move(object_identifier_to_send));
- return;
- }
-
- GetObjectContentAndUpload(
- std::move(object_identifier_to_send),
- std::move(object_name));
- }));
-}
-
-void BatchUpload::GetObjectContentAndUpload(
- storage::ObjectIdentifier object_identifier, std::string object_name) {
- storage_->GetPiece(
- object_identifier,
- callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this, object_identifier, object_name = std::move(object_name)](
- storage::Status storage_status,
- std::unique_ptr<const storage::Object> object) mutable {
- FXL_DCHECK(storage_status == storage::Status::OK);
- UploadObject(std::move(object_identifier), std::move(object_name),
- std::move(object));
- }));
-}
-
-void BatchUpload::UploadObject(storage::ObjectIdentifier object_identifier,
- std::string object_name,
- std::unique_ptr<const storage::Object> object) {
- fsl::SizedVmo data;
- auto status = object->GetVmo(&data);
- // TODO(ppi): LE-225 Handle disk IO errors.
- FXL_DCHECK(status == storage::Status::OK);
-
- encryption_service_->EncryptObject(
- std::move(object_identifier), std::move(data),
- callback::MakeScoped(weak_ptr_factory_.GetWeakPtr(),
- [this, object_identifier = object->GetIdentifier(),
- object_name = std::move(object_name)](
- encryption::Status encryption_status,
- std::string encrypted_data) mutable {
- if (encryption_status != encryption::Status::OK) {
- EnqueueForRetryAndSignalError(
- std::move(object_identifier));
- return;
- }
-
- UploadEncryptedObject(std::move(object_identifier),
- std::move(object_name),
- std::move(encrypted_data));
- }));
-}
-
-void BatchUpload::UploadEncryptedObject(
- storage::ObjectIdentifier object_identifier, std::string object_name,
- std::string content) {
- fsl::SizedVmo data;
- if (!fsl::VmoFromString(content, &data)) {
- EnqueueForRetryAndSignalError(std::move(object_identifier));
- return;
- }
-
- (*page_cloud_)
- ->AddObject(
- convert::ToArray(object_name), std::move(data).ToTransport(),
- callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this, object_identifier = std::move(object_identifier)](
- cloud_provider::Status status) mutable {
- FXL_DCHECK(current_uploads_ > 0);
- current_uploads_--;
-
- if (status != cloud_provider::Status::OK) {
- EnqueueForRetryAndSignalError(std::move(object_identifier));
- return;
- }
-
- // Uploading the object succeeded.
- storage_->MarkPieceSynced(
- std::move(object_identifier),
- callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this](storage::Status status) {
- FXL_DCHECK(current_objects_handled_ > 0);
- current_objects_handled_--;
-
- if (status != storage::Status::OK) {
- errored_ = true;
- error_type_ = ErrorType::PERMANENT;
- }
-
- // Notify the user about the error once all pending
- // operations of the recent retry complete.
- if (errored_ && current_objects_handled_ == 0u) {
- on_error_(error_type_);
- return;
- }
-
- if (current_objects_handled_ == 0 &&
- remaining_object_identifiers_.empty()) {
- // All the referenced objects are uploaded and
- // marked as synced, upload the commits.
- FilterAndUploadCommits();
- return;
- }
-
- if (!errored_ &&
- !remaining_object_identifiers_.empty()) {
- UploadNextObject();
- }
- }));
- }));
-}
-
-void BatchUpload::FilterAndUploadCommits() {
- // Remove all commits that have been synced since this upload object was
- // created. This will happen if a merge is executed on multiple devices at the
- // same time.
- storage_->GetUnsyncedCommits(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this](storage::Status status,
- std::vector<std::unique_ptr<const storage::Commit>> commits) {
- std::set<storage::CommitId> commit_ids;
- std::transform(
- commits.begin(), commits.end(),
- std::inserter(commit_ids, commit_ids.begin()),
- [](const std::unique_ptr<const storage::Commit>& commit) {
- return commit->GetId();
- });
-
- commits_.erase(
- std::remove_if(
- commits_.begin(), commits_.end(),
- [&commit_ids](
- const std::unique_ptr<const storage::Commit>& commit) {
- return commit_ids.count(commit->GetId()) == 0;
- }),
- commits_.end());
-
- if (commits_.empty()) {
- // Return early, all commits are synced.
- on_done_();
- return;
- }
- UploadCommits();
- }));
-}
-
-void BatchUpload::UploadCommits() {
- FXL_DCHECK(!errored_);
- std::vector<storage::CommitId> ids;
- auto waiter = fxl::MakeRefCounted<
- callback::Waiter<encryption::Status, cloud_provider::CommitPackEntry>>(
- encryption::Status::OK);
- for (auto& storage_commit : commits_) {
- storage::CommitId id = storage_commit->GetId();
- encryption_service_->EncryptCommit(
- storage_commit->GetStorageBytes().ToString(),
- [id, callback = waiter->NewCallback()](
- encryption::Status status,
- std::string encrypted_storage_bytes) mutable {
- cloud_provider::CommitPackEntry entry;
- entry.id = std::move(id);
- entry.data = std::move(encrypted_storage_bytes);
- callback(status, std::move(entry));
- });
- ids.push_back(std::move(id));
- }
- waiter->Finalize(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this, ids = std::move(ids)](
- encryption::Status status,
- std::vector<cloud_provider::CommitPackEntry> entries) mutable {
- if (status != encryption::Status::OK) {
- errored_ = true;
- on_error_(ErrorType::PERMANENT);
- return;
- }
- cloud_provider::CommitPack commit_pack;
- if (!cloud_provider::EncodeCommitPack(entries, &commit_pack)) {
- errored_ = true;
- on_error_(ErrorType::PERMANENT);
- return;
- }
- (*page_cloud_)
- ->AddCommits(
- std::move(commit_pack),
- callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this, commit_ids =
- std::move(ids)](cloud_provider::Status status) {
- // UploadCommit() is called as a last step of a
- // so-far-successful upload attempt, so we couldn't have
- // failed before.
- FXL_DCHECK(!errored_);
- if (status != cloud_provider::Status::OK) {
- errored_ = true;
- on_error_(ErrorType::TEMPORARY);
- return;
- }
- auto waiter = fxl::MakeRefCounted<
- callback::StatusWaiter<storage::Status>>(
- storage::Status::OK);
-
- for (auto& id : commit_ids) {
- storage_->MarkCommitSynced(id, waiter->NewCallback());
- }
- waiter->Finalize(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this](storage::Status status) {
- if (status != storage::Status::OK) {
- errored_ = true;
- on_error_(ErrorType::PERMANENT);
- return;
- }
-
- // This object can be deleted in the
- // on_done_() callback, don't do
- // anything after the call.
- on_done_();
- }));
- }));
- }));
-}
-
-void BatchUpload::EnqueueForRetryAndSignalError(
- storage::ObjectIdentifier object_identifier) {
- FXL_DCHECK(current_objects_handled_ > 0);
- current_objects_handled_--;
-
- errored_ = true;
- // Re-enqueue the object for another upload attempt.
- remaining_object_identifiers_.push_back(std::move(object_identifier));
-
- if (current_objects_handled_ == 0u) {
- on_error_(error_type_);
- }
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/batch_upload.h b/bin/ledger/cloud_sync/impl/batch_upload.h
deleted file mode 100644
index 93cb011..0000000
--- a/bin/ledger/cloud_sync/impl/batch_upload.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_BATCH_UPLOAD_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_BATCH_UPLOAD_H_
-
-#include <functional>
-#include <memory>
-#include <vector>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace cloud_sync {
-
-// Uploads a batch of commits along with unsynced storage objects and marks
-// the uploaded artifacts as synced.
-//
-// Contract: The class doesn't reason about objects referenced by each commit,
-// and instead uploads each unsynced object present in storage at the moment of
-// calling Start(). Unsynced objects are marked as synced as they are uploaded.
-// The commits in the batch are uploaded in one network request once all objects
-// are uploaded.
-//
-// Usage: call Start() to kick off the upload. |on_done| is called after the
-// upload is successfully completed. |on_error| will be called at most once
-// after each error. Each time after |on_error| is called the client can
-// call Retry() once to retry the upload.
-// TODO(ppi): rather than DCHECK on storage errors, take separate callbacks for
-// network and disk errors and let PageSync decide on how to handle each.
-//
-// Lifetime: if BatchUpload is deleted between Start() and |on_done| being
-// called, it has to be deleted along with |storage| and |cloud_provider|, which
-// otherwise can retain callbacks for pending uploads. This isn't a problem as
-// long as the lifetime of page storage and page sync is managed together.
-class BatchUpload {
- public:
- // In case of error in BatchUpload, ErrorType defines whether the error that
- // occurred is temporary (from cloud or auth provider), or permanent (from
- // storage or from encryption).
- enum class ErrorType {
- PERMANENT,
- TEMPORARY,
- };
-
- BatchUpload(storage::PageStorage* storage,
- encryption::EncryptionService* encryption_service,
- cloud_provider::PageCloudPtr* page_cloud,
- std::vector<std::unique_ptr<const storage::Commit>> commits,
- fit::closure on_done, fit::function<void(ErrorType)> on_error,
- unsigned int max_concurrent_uploads = 10);
- ~BatchUpload();
-
- // Starts a new upload attempt. Results are reported through |on_done|
- // and |on_error| passed in the constructor. Can be called only once.
- void Start();
-
- // Retries the attempt to upload the commit batch. Each time after |on_error|
- // is called, the client can retry by calling this method.
- void Retry();
-
- private:
- void StartObjectUpload();
-
- void UploadNextObject();
-
- // Retrieves the content of the given object and uploads it.
- void GetObjectContentAndUpload(storage::ObjectIdentifier object_identifier,
- std::string object_name);
-
- // Uploads the given object.
- void UploadObject(storage::ObjectIdentifier object_identifier,
- std::string object_name,
- std::unique_ptr<const storage::Object> object);
-
- // Uploads the given object.
- void UploadEncryptedObject(storage::ObjectIdentifier object_identifier,
- std::string object_name, std::string content);
-
- // Filters already synced commits.
- void FilterAndUploadCommits();
-
- // Uploads the commits.
- void UploadCommits();
-
- // Notifies an error when trying to upload the given object.
- void EnqueueForRetryAndSignalError(
- storage::ObjectIdentifier object_identifier);
-
- storage::PageStorage* const storage_;
- encryption::EncryptionService* const encryption_service_;
- cloud_provider::PageCloudPtr* const page_cloud_;
- std::vector<std::unique_ptr<const storage::Commit>> commits_;
- fit::closure on_done_;
- fit::function<void(ErrorType)> on_error_;
- const unsigned int max_concurrent_uploads_;
-
- // All remaining object ids to be uploaded along with this batch of commits.
- std::vector<storage::ObjectIdentifier> remaining_object_identifiers_;
-
- // Number of object uploads currently in progress.
- unsigned int current_uploads_ = 0u;
-
- // Number of object being handled, including those being uploaded and those
- // whose metadata are being updated in storage.
- unsigned int current_objects_handled_ = 0u;
-
- bool started_ = false;
- bool errored_ = false;
- // If an error has occurred while handling the objects, |error_types_|
- // stores the type of error.
- ErrorType error_type_ = ErrorType::TEMPORARY;
-
- // Must be the last member.
- fxl::WeakPtrFactory<BatchUpload> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BatchUpload);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_BATCH_UPLOAD_H_
diff --git a/bin/ledger/cloud_sync/impl/batch_upload_unittest.cc b/bin/ledger/cloud_sync/impl/batch_upload_unittest.cc
deleted file mode 100644
index 0e0711f..0000000
--- a/bin/ledger/cloud_sync/impl/batch_upload_unittest.cc
+++ /dev/null
@@ -1,733 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/batch_upload.h"
-
-#include <functional>
-#include <map>
-#include <utility>
-
-#include <lib/async/dispatcher.h>
-#include <lib/callback/capture.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-namespace cloud_sync {
-namespace {
-
-// Fake implementation of storage::Commit.
-class TestCommit : public storage::CommitEmptyImpl {
- public:
- TestCommit(std::string id, std::string storage_bytes)
- : id(std::move(id)), storage_bytes(std::move(storage_bytes)) {}
- ~TestCommit() override = default;
-
- const storage::CommitId& GetId() const override { return id; }
-
- fxl::StringView GetStorageBytes() const override { return storage_bytes; }
-
- std::unique_ptr<const storage::Commit> Clone() const override {
- return std::make_unique<TestCommit>(id, storage_bytes);
- }
-
- storage::CommitId id;
- std::string storage_bytes;
-};
-
-// Fake implementation of storage::Object.
-class TestObject : public storage::Object {
- public:
- TestObject() = default;
- TestObject(storage::ObjectIdentifier identifier, std::string data)
- : identifier(std::move(identifier)), data(std::move(data)) {}
- ~TestObject() override = default;
-
- storage::ObjectIdentifier GetIdentifier() const override {
- return identifier;
- };
-
- storage::Status GetData(fxl::StringView* result) const override {
- *result = fxl::StringView(data);
- return storage::Status::OK;
- }
-
- storage::ObjectIdentifier identifier;
- std::string data;
-};
-
-// Fake implementation of storage::PageStorage. Injects the data that
-// BatchUpload asks about: page id and unsynced objects to be uploaded.
-// Registers the reported results of the upload: commits and objects marked as
-// synced.
-class TestPageStorage : public storage::PageStorageEmptyImpl {
- public:
- TestPageStorage() = default;
- ~TestPageStorage() override = default;
-
- void GetUnsyncedCommits(
- fit::function<void(storage::Status,
- std::vector<std::unique_ptr<const storage::Commit>>)>
- callback) override {
- std::vector<std::unique_ptr<const storage::Commit>> results;
- std::transform(unsynced_commits.begin(), unsynced_commits.end(),
- std::inserter(results, results.begin()),
- [](const std::unique_ptr<const storage::Commit>& commit) {
- return commit->Clone();
- });
- callback(storage::Status::OK, std::move(results));
- }
-
- void GetUnsyncedPieces(
- fit::function<void(storage::Status,
- std::vector<storage::ObjectIdentifier>)>
- callback) override {
- std::vector<storage::ObjectIdentifier> object_identifiers;
- for (auto& digest_object_pair : unsynced_objects_to_return) {
- object_identifiers.push_back(digest_object_pair.first);
- }
- callback(storage::Status::OK, std::move(object_identifiers));
- }
-
- void GetObject(storage::ObjectIdentifier object_identifier,
- Location /*location*/,
- fit::function<void(storage::Status,
- std::unique_ptr<const storage::Object>)>
- callback) override {
- GetPiece(std::move(object_identifier), std::move(callback));
- }
-
- void GetPiece(storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status,
- std::unique_ptr<const storage::Object>)>
- callback) override {
- callback(
- storage::Status::OK,
- std::move(unsynced_objects_to_return[std::move(object_identifier)]));
- }
-
- void MarkPieceSynced(storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status)> callback) override {
- objects_marked_as_synced.insert(object_identifier);
- callback(storage::Status::OK);
- }
-
- void MarkCommitSynced(
- const storage::CommitId& commit_id,
- fit::function<void(storage::Status)> callback) override {
- commits_marked_as_synced.insert(commit_id);
- unsynced_commits.erase(
- std::remove_if(
- unsynced_commits.begin(), unsynced_commits.end(),
- [&commit_id](const std::unique_ptr<const storage::Commit>& commit) {
- return commit->GetId() == commit_id;
- }),
- unsynced_commits.end());
- callback(storage::Status::OK);
- }
-
- std::unique_ptr<TestCommit> NewCommit(std::string id, std::string content) {
- auto commit =
- std::make_unique<TestCommit>(std::move(id), std::move(content));
- unsynced_commits.push_back(commit->Clone());
- return commit;
- }
-
- std::map<storage::ObjectIdentifier, std::unique_ptr<const TestObject>>
- unsynced_objects_to_return;
- std::set<storage::ObjectIdentifier> objects_marked_as_synced;
- std::set<storage::CommitId> commits_marked_as_synced;
- std::vector<std::unique_ptr<const storage::Commit>> unsynced_commits;
-};
-
-// Fake implementation of storage::PageStorage. Fails when trying to mark
-// objects as synced and can be used to verify behavior on object upload storage
-// errors.
-class TestPageStorageFailingToMarkPieces : public TestPageStorage {
- public:
- void MarkPieceSynced(storage::ObjectIdentifier /*object_identifier*/,
- fit::function<void(storage::Status)> callback) override {
- callback(storage::Status::NOT_IMPLEMENTED);
- }
-};
-
-template <typename E>
-class BaseBatchUploadTest : public gtest::TestLoopFixture {
- public:
- BaseBatchUploadTest()
- : encryption_service_(dispatcher()),
- page_cloud_(page_cloud_ptr_.NewRequest()) {}
- ~BaseBatchUploadTest() override {}
-
- public:
- TestPageStorage storage_;
- E encryption_service_;
- cloud_provider::PageCloudPtr page_cloud_ptr_;
- TestPageCloud page_cloud_;
-
- unsigned int done_calls_ = 0u;
- unsigned int error_calls_ = 0u;
- BatchUpload::ErrorType last_error_type_ = BatchUpload::ErrorType::PERMANENT;
-
- std::unique_ptr<BatchUpload> MakeBatchUpload(
- std::vector<std::unique_ptr<const storage::Commit>> commits,
- unsigned int max_concurrent_uploads = 10) {
- return MakeBatchUploadWithStorage(&storage_, std::move(commits),
- max_concurrent_uploads);
- }
-
- std::unique_ptr<BatchUpload> MakeBatchUploadWithStorage(
- storage::PageStorage* storage,
- std::vector<std::unique_ptr<const storage::Commit>> commits,
- unsigned int max_concurrent_uploads = 10) {
- return std::make_unique<BatchUpload>(
- storage, &encryption_service_, &page_cloud_ptr_, std::move(commits),
- [this] {
- done_calls_++;
- QuitLoop();
- },
- [this](BatchUpload::ErrorType error_type) {
- error_calls_++;
- last_error_type_ = error_type;
- QuitLoop();
- },
- max_concurrent_uploads);
- }
-
- // Returns an object identifier for the provided fake |object_digest|.
- // |object_digest| need not be valid (wrt. internal storage constraints) as it
- // is only used as an opaque identifier for cloud_sync.
- storage::ObjectIdentifier MakeObjectIdentifier(std::string object_digest) {
- return encryption_service_.MakeObjectIdentifier(
- storage::ObjectDigest(std::move(object_digest)));
- }
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(BaseBatchUploadTest);
-};
-
-using BatchUploadTest = BaseBatchUploadTest<encryption::FakeEncryptionService>;
-
-// Test an upload of a single commit with no unsynced objects.
-TEST_F(BatchUploadTest, SingleCommit) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(1u, done_calls_);
- EXPECT_EQ(0u, error_calls_);
-
- // Verify the artifacts uploaded to cloud provider.
- EXPECT_EQ(1u, page_cloud_.received_commits.size());
- EXPECT_EQ("id", page_cloud_.received_commits.front().id);
- EXPECT_EQ("content", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits.front().data));
- EXPECT_TRUE(page_cloud_.received_objects.empty());
-
- // Verify the sync status in storage.
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id"));
- EXPECT_EQ(0u, storage_.objects_marked_as_synced.size());
-}
-
-// Test an upload of multiple commits with no unsynced objects.
-TEST_F(BatchUploadTest, MultipleCommits) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id0", "content0"));
- commits.push_back(storage_.NewCommit("id1", "content1"));
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(1u, done_calls_);
- EXPECT_EQ(0u, error_calls_);
-
- // Verify that the commits were uploaded correctly and in a single call.
- EXPECT_EQ(1u, page_cloud_.add_commits_calls);
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("id0", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content0", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("id1", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- EXPECT_TRUE(page_cloud_.received_objects.empty());
-
- // Verify the sync status in storage.
- EXPECT_EQ(2u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id0"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id1"));
-}
-
-// Test an upload of a commit with a few unsynced objects.
-TEST_F(BatchUploadTest, SingleCommitWithObjects) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
- auto id1 = MakeObjectIdentifier("obj_digest1");
- auto id2 = MakeObjectIdentifier("obj_digest2");
-
- storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(1u, done_calls_);
- EXPECT_EQ(0u, error_calls_);
-
- // Verify the artifacts uploaded to cloud provider.
- EXPECT_EQ(1u, page_cloud_.received_commits.size());
- EXPECT_EQ("id", page_cloud_.received_commits.front().id);
- EXPECT_EQ("content", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits.front().data));
- EXPECT_EQ(2u, page_cloud_.received_objects.size());
- EXPECT_EQ(
- "obj_data1",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id1)]));
- EXPECT_EQ(
- "obj_data2",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id2)]));
-
- // Verify the sync status in storage.
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id"));
- EXPECT_EQ(2u, storage_.objects_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id1));
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id2));
-}
-
-// Verifies that the number of concurrent object uploads is limited to
-// |max_concurrent_uploads|.
-TEST_F(BatchUploadTest, ThrottleConcurrentUploads) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
- storage::ObjectIdentifier id0 = MakeObjectIdentifier("obj_digest0");
- storage::ObjectIdentifier id1 = MakeObjectIdentifier("obj_digest1");
- storage::ObjectIdentifier id2 = MakeObjectIdentifier("obj_digest2");
-
- storage_.unsynced_objects_to_return[id0] =
- std::make_unique<TestObject>(id0, "obj_data0");
- storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- // Create the commit upload with |max_concurrent_uploads| = 2.
- auto batch_upload = MakeBatchUpload(std::move(commits), 2);
-
- page_cloud_.delay_add_object_callbacks = true;
- batch_upload->Start();
- RunLoopUntilIdle();
- // Verify that only two object uploads are in progress.
- EXPECT_EQ(2u, page_cloud_.add_object_calls);
-
- page_cloud_.delay_add_object_callbacks = false;
- page_cloud_.RunPendingCallbacks();
- RunLoopUntilIdle();
- EXPECT_EQ(1u, done_calls_);
- EXPECT_EQ(0u, error_calls_);
- EXPECT_EQ(3u, page_cloud_.add_object_calls);
- EXPECT_EQ(3u, page_cloud_.received_objects.size());
- EXPECT_EQ(
- "obj_data0",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id0)]));
- EXPECT_EQ(
- "obj_data1",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id1)]));
- EXPECT_EQ(
- "obj_data2",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id2)]));
-
- // Verify the sync status in storage.
- EXPECT_EQ(3u, storage_.objects_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id0));
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id1));
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id2));
-}
-
-// Test an upload that fails on uploading objects.
-TEST_F(BatchUploadTest, FailedObjectUpload) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
-
- storage::ObjectIdentifier id1 = MakeObjectIdentifier("obj_digest1");
- storage::ObjectIdentifier id2 = MakeObjectIdentifier("obj_digest2");
-
- storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- page_cloud_.object_status_to_return = cloud_provider::Status::NETWORK_ERROR;
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(0u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
- EXPECT_EQ(BatchUpload::ErrorType::TEMPORARY, last_error_type_);
-
- // Verify that no commits were uploaded.
- EXPECT_EQ(0u, page_cloud_.received_commits.size());
-
- // Verify that neither the objects nor the commit were marked as synced.
- EXPECT_TRUE(storage_.commits_marked_as_synced.empty());
- EXPECT_TRUE(storage_.objects_marked_as_synced.empty());
-}
-
-// Test an upload that fails on uploading the commit.
-TEST_F(BatchUploadTest, FailedCommitUpload) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
-
- storage::ObjectIdentifier id1 = MakeObjectIdentifier("obj_digest1");
- storage::ObjectIdentifier id2 = MakeObjectIdentifier("obj_digest2");
-
- storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- page_cloud_.commit_status_to_return = cloud_provider::Status::NETWORK_ERROR;
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(0u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
- EXPECT_EQ(BatchUpload::ErrorType::TEMPORARY, last_error_type_);
-
- // Verify that the objects were uploaded to cloud provider and marked as
- // synced.
- EXPECT_EQ(2u, page_cloud_.received_objects.size());
- EXPECT_EQ(
- "obj_data1",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id1)]));
- EXPECT_EQ(
- "obj_data2",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id2)]));
- EXPECT_EQ(2u, storage_.objects_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id1));
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id2));
-
- // Verify that neither the commit wasn't marked as synced.
- EXPECT_TRUE(storage_.commits_marked_as_synced.empty());
-}
-
-// Test an upload that fails and a subsequent retry that succeeds.
-TEST_F(BatchUploadTest, ErrorAndRetry) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
-
- storage::ObjectIdentifier id1 = MakeObjectIdentifier("obj_digest1");
- storage::ObjectIdentifier id2 = MakeObjectIdentifier("obj_digest2");
-
- storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- page_cloud_.object_status_to_return = cloud_provider::Status::NETWORK_ERROR;
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(0u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
- EXPECT_EQ(BatchUpload::ErrorType::TEMPORARY, last_error_type_);
-
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(0u, storage_.objects_marked_as_synced.size());
-
- // TestStorage moved the objects to be returned out, need to add them again
- // before retry.
- storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
- page_cloud_.object_status_to_return = cloud_provider::Status::OK;
- batch_upload->Retry();
- RunLoopUntilIdle();
-
- // Verify the artifacts uploaded to cloud provider.
- EXPECT_EQ(1u, page_cloud_.received_commits.size());
- EXPECT_EQ("id", page_cloud_.received_commits.front().id);
- EXPECT_EQ("content", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits.front().data));
- EXPECT_EQ(2u, page_cloud_.received_objects.size());
- EXPECT_EQ(
- "obj_data1",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id1)]));
- EXPECT_EQ(
- "obj_data2",
- encryption_service_.DecryptObjectSynchronous(
- page_cloud_.received_objects[encryption_service_
- .GetObjectNameSynchronous(id2)]));
-
- // Verify the sync status in storage.
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id"));
- EXPECT_EQ(2u, storage_.objects_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id1));
- EXPECT_EQ(1u, storage_.objects_marked_as_synced.count(id2));
-}
-
-// Test a commit upload that gets an error from storage.
-TEST_F(BatchUploadTest, FailedCommitUploadWitStorageError) {
- storage::PageStorageEmptyImpl test_storage;
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
-
- auto batch_upload =
- MakeBatchUploadWithStorage(&test_storage, std::move(commits));
-
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(0u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
- EXPECT_EQ(BatchUpload::ErrorType::PERMANENT, last_error_type_);
-
- // Verify that no commits were uploaded.
- EXPECT_EQ(0u, page_cloud_.received_commits.size());
-}
-
-// Test objects upload that get an error from storage.
-TEST_F(BatchUploadTest, FailedObjectUploadWitStorageError) {
- TestPageStorageFailingToMarkPieces test_storage;
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
-
- storage::ObjectIdentifier id1 = MakeObjectIdentifier("obj_digest1");
- storage::ObjectIdentifier id2 = MakeObjectIdentifier("obj_digest2");
-
- test_storage.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- test_storage.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- auto batch_upload =
- MakeBatchUploadWithStorage(&test_storage, std::move(commits));
-
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(0u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
- EXPECT_EQ(BatchUpload::ErrorType::PERMANENT, last_error_type_);
-
- // Verify that no commit or objects were uploaded.
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(0u, storage_.objects_marked_as_synced.size());
-}
-
-// Verifies that if only one of many uploads fails, we still stop and notify the
-// client.
-TEST_F(BatchUploadTest, ErrorOneOfMultipleObject) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
-
- storage::ObjectIdentifier id0 = MakeObjectIdentifier("obj_digest0");
- storage::ObjectIdentifier id1 = MakeObjectIdentifier("obj_digest1");
- storage::ObjectIdentifier id2 = MakeObjectIdentifier("obj_digest2");
-
- storage_.unsynced_objects_to_return[id0] =
- std::make_unique<TestObject>(id0, "obj_data0");
- storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- page_cloud_.object_status_to_return = cloud_provider::Status::NETWORK_ERROR;
- page_cloud_.reset_object_status_after_call = true;
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(0u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
-
- // Verify that two storage objects were correctly marked as synced.
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(2u, storage_.objects_marked_as_synced.size());
- EXPECT_EQ(0u, page_cloud_.received_commits.size());
-
- // TestStorage moved the objects to be returned out, need to add them again
- // before retry.
- storage_.unsynced_objects_to_return[id0] =
- std::make_unique<TestObject>(id0, "obj_data0");
- storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- // Try upload again.
- batch_upload->Retry();
- RunLoopUntilIdle();
- EXPECT_EQ(1u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
-
- // Verify the sync status in storage.
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(3u, storage_.objects_marked_as_synced.size());
-}
-
-// Verifies that we do not upload synced commits.
-TEST_F(BatchUploadTest, DoNotUploadSyncedCommits) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(std::make_unique<TestCommit>("id", "content"));
-
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(1u, done_calls_);
- EXPECT_EQ(0u, error_calls_);
-
- // Verify that the commit was not synced.
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(0u, page_cloud_.received_commits.size());
-}
-
-// Verifies that we do not upload synced commits on retries.
-TEST_F(BatchUploadTest, DoNotUploadSyncedCommitsOnRetry) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(storage_.NewCommit("id", "content"));
-
- auto batch_upload = MakeBatchUpload(std::move(commits));
-
- page_cloud_.commit_status_to_return = cloud_provider::Status::NETWORK_ERROR;
-
- batch_upload->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(0u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
-
- // Verify that the commit was not synced.
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.size());
-
- // Mark commit as synced.
- storage::Status status;
- storage_.MarkCommitSynced("id",
- callback::Capture(QuitLoopClosure(), &status));
- RunLoopUntilIdle();
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(0u, storage_.unsynced_commits.size());
-
- // Retry.
- page_cloud_.add_commits_calls = 0;
- page_cloud_.commit_status_to_return = cloud_provider::Status::OK;
- batch_upload->Retry();
- RunLoopUntilIdle();
- EXPECT_EQ(1u, done_calls_);
- EXPECT_EQ(1u, error_calls_);
-
- // Verify that no calls were made to attempt to upload the commit.
- EXPECT_EQ(0u, page_cloud_.add_commits_calls);
-}
-
-class FailingEncryptCommitEncryptionService
- : public encryption::FakeEncryptionService {
- public:
- explicit FailingEncryptCommitEncryptionService(async_dispatcher_t* dispatcher)
- : encryption::FakeEncryptionService(dispatcher) {}
-
- void EncryptCommit(
- std::string /*commit_storage*/,
- fit::function<void(encryption::Status, std::string)> callback) override {
- callback(encryption::Status::INVALID_ARGUMENT, "");
- }
-};
-
-class FailingGetNameEncryptionService
- : public encryption::FakeEncryptionService {
- public:
- explicit FailingGetNameEncryptionService(async_dispatcher_t* dispatcher)
- : encryption::FakeEncryptionService(dispatcher) {}
-
- void GetObjectName(
- storage::ObjectIdentifier /*object_identifier*/,
- fit::function<void(encryption::Status, std::string)> callback) override {
- callback(encryption::Status::INVALID_ARGUMENT, "");
- }
-};
-
-class FailingEncryptObjectEncryptionService
- : public encryption::FakeEncryptionService {
- public:
- explicit FailingEncryptObjectEncryptionService(async_dispatcher_t* dispatcher)
- : encryption::FakeEncryptionService(dispatcher) {}
-
- void EncryptObject(
- storage::ObjectIdentifier /*object_identifier*/,
- fsl::SizedVmo /*content*/,
- fit::function<void(encryption::Status, std::string)> callback) override {
- callback(encryption::Status::INVALID_ARGUMENT, "");
- }
-};
-
-template <typename E>
-using FailingBatchUploadTest = BaseBatchUploadTest<E>;
-
-using FailingEncryptionServices =
- ::testing::Types<FailingEncryptCommitEncryptionService,
- FailingGetNameEncryptionService,
- FailingEncryptObjectEncryptionService>;
-
-TYPED_TEST_CASE(FailingBatchUploadTest, FailingEncryptionServices);
-
-TYPED_TEST(FailingBatchUploadTest, Fail) {
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.push_back(this->storage_.NewCommit("id", "content"));
- auto id1 = this->MakeObjectIdentifier("obj_digest1");
- auto id2 = this->MakeObjectIdentifier("obj_digest2");
-
- this->storage_.unsynced_objects_to_return[id1] =
- std::make_unique<TestObject>(id1, "obj_data1");
- this->storage_.unsynced_objects_to_return[id2] =
- std::make_unique<TestObject>(id2, "obj_data2");
-
- auto batch_upload = this->MakeBatchUpload(std::move(commits));
-
- batch_upload->Start();
- this->RunLoopUntilIdle();
- EXPECT_EQ(0u, this->done_calls_);
- EXPECT_GE(this->error_calls_, 1u);
-
- // Verify the artifacts uploaded to cloud provider.
- EXPECT_EQ(0u, this->page_cloud_.received_commits.size());
-}
-
-} // namespace
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/constants.h b/bin/ledger/cloud_sync/impl/constants.h
deleted file mode 100644
index 0ac138b..0000000
--- a/bin/ledger/cloud_sync/impl/constants.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_CONSTANTS_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_CONSTANTS_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace cloud_sync {
-
-// Key for the timestamp metadata in the SyncMetadata KV store.
-inline constexpr fxl::StringView kTimestampKey = "timestamp";
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_CONSTANTS_H_
diff --git a/bin/ledger/cloud_sync/impl/ledger_sync_impl.cc b/bin/ledger/cloud_sync/impl/ledger_sync_impl.cc
deleted file mode 100644
index 6b8db50..0000000
--- a/bin/ledger/cloud_sync/impl/ledger_sync_impl.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/ledger_sync_impl.h"
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/page_sync_impl.h"
-#include "peridot/bin/ledger/encryption/impl/encryption_service_impl.h"
-
-namespace cloud_sync {
-
-LedgerSyncImpl::LedgerSyncImpl(
- ledger::Environment* environment, const UserConfig* user_config,
- encryption::EncryptionService* encryption_service, fxl::StringView app_id,
- std::unique_ptr<SyncStateWatcher> watcher)
- : environment_(environment),
- user_config_(user_config),
- encryption_service_(encryption_service),
- app_id_(app_id.ToString()),
- user_watcher_(std::move(watcher)) {
- FXL_DCHECK(user_config_->cloud_provider);
- aggregator_.SetBaseWatcher(user_watcher_.get());
-}
-
-LedgerSyncImpl::~LedgerSyncImpl() {
- FXL_DCHECK(active_page_syncs_.empty());
-
- if (on_delete_) {
- on_delete_();
- }
-}
-
-std::unique_ptr<PageSync> LedgerSyncImpl::CreatePageSync(
- storage::PageStorage* page_storage,
- storage::PageSyncClient* page_sync_client) {
- FXL_DCHECK(page_storage);
- if (!user_config_->cloud_provider) {
- // TODO(ppi): handle recovery from cloud provider disconnection, LE-567.
- FXL_LOG(WARNING) << "Skipped initializing the cloud sync. "
- << "Cloud provider is disconnected.";
- return nullptr;
- }
-
- cloud_provider::PageCloudPtr page_cloud;
- user_config_->cloud_provider->GetPageCloud(
- convert::ToArray(app_id_), convert::ToArray(page_storage->GetId()),
- page_cloud.NewRequest(), [](auto status) {
- if (status != cloud_provider::Status::OK) {
- FXL_LOG(ERROR) << "Failed to retrieve page cloud, status: "
- << fidl::ToUnderlying(status);
- // Only log. This should be handled by page cloud connection error
- // handler.
- }
- });
- auto page_sync = std::make_unique<PageSyncImpl>(
- environment_->dispatcher(), page_storage, page_sync_client,
- encryption_service_, std::move(page_cloud), environment_->MakeBackoff(),
- environment_->MakeBackoff(), aggregator_.GetNewStateWatcher());
- if (upload_enabled_) {
- page_sync->EnableUpload();
- }
- active_page_syncs_.insert(page_sync.get());
- page_sync->set_on_delete([this, page_sync = page_sync.get()]() {
- active_page_syncs_.erase(page_sync);
- });
- return page_sync;
-}
-
-void LedgerSyncImpl::EnableUpload() {
- if (upload_enabled_) {
- return;
- }
-
- upload_enabled_ = true;
- for (auto page_sync : active_page_syncs_) {
- page_sync->EnableUpload();
- }
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/ledger_sync_impl.h b/bin/ledger/cloud_sync/impl/ledger_sync_impl.h
deleted file mode 100644
index 0049658..0000000
--- a/bin/ledger/cloud_sync/impl/ledger_sync_impl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_LEDGER_SYNC_IMPL_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_LEDGER_SYNC_IMPL_H_
-
-#include <memory>
-#include <set>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/aggregator.h"
-#include "peridot/bin/ledger/cloud_sync/impl/page_sync_impl.h"
-#include "peridot/bin/ledger/cloud_sync/public/ledger_sync.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/cloud_sync/public/user_config.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/environment/environment.h"
-
-namespace cloud_sync {
-
-class LedgerSyncImpl : public LedgerSync {
- public:
- LedgerSyncImpl(ledger::Environment* environment,
- const UserConfig* user_config,
- encryption::EncryptionService* encryption_service,
- fxl::StringView app_id,
- std::unique_ptr<SyncStateWatcher> watcher);
- ~LedgerSyncImpl() override;
-
- std::unique_ptr<PageSync> CreatePageSync(
- storage::PageStorage* page_storage,
- storage::PageSyncClient* page_sync_client) override;
-
- // Enables upload. Has no effect if this method has already been called.
- void EnableUpload();
-
- bool IsUploadEnabled() const { return upload_enabled_; }
-
- // |on_delete| will be called when this class is deleted.
- void set_on_delete(fit::function<void()> on_delete) {
- FXL_DCHECK(!on_delete_);
- on_delete_ = std::move(on_delete);
- }
-
- private:
- ledger::Environment* const environment_;
- const UserConfig* const user_config_;
- encryption::EncryptionService* const encryption_service_;
- const std::string app_id_;
- bool upload_enabled_ = false;
- std::set<PageSyncImpl*> active_page_syncs_;
- // Called on destruction.
- fit::function<void()> on_delete_;
- std::unique_ptr<SyncStateWatcher> user_watcher_;
- Aggregator aggregator_;
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_LEDGER_SYNC_IMPL_H_
diff --git a/bin/ledger/cloud_sync/impl/page_download.cc b/bin/ledger/cloud_sync/impl/page_download.cc
deleted file mode 100644
index b3f4794..0000000
--- a/bin/ledger/cloud_sync/impl/page_download.cc
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/page_download.h"
-
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/constants.h"
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/bin/ledger/storage/public/read_data_source.h"
-
-namespace cloud_sync {
-namespace {
-DownloadSyncState GetMergedState(DownloadSyncState commit_state,
- int current_get_object_calls) {
- if (commit_state != DOWNLOAD_IDLE) {
- return commit_state;
- }
- return current_get_object_calls == 0 ? DOWNLOAD_IDLE : DOWNLOAD_IN_PROGRESS;
-}
-
-bool IsPermanentError(cloud_provider::Status status) {
- switch (status) {
- case cloud_provider::Status::OK:
- case cloud_provider::Status::AUTH_ERROR:
- case cloud_provider::Status::NETWORK_ERROR:
- return false;
- case cloud_provider::Status::ARGUMENT_ERROR:
- case cloud_provider::Status::INTERNAL_ERROR:
- case cloud_provider::Status::NOT_FOUND:
- case cloud_provider::Status::PARSE_ERROR:
- case cloud_provider::Status::SERVER_ERROR:
- case cloud_provider::Status::UNKNOWN_ERROR:
- return true;
- }
-}
-} // namespace
-
-PageDownload::PageDownload(callback::ScopedTaskRunner* task_runner,
- storage::PageStorage* storage,
- storage::PageSyncClient* sync_client,
- encryption::EncryptionService* encryption_service,
- cloud_provider::PageCloudPtr* page_cloud,
- Delegate* delegate,
- std::unique_ptr<backoff::Backoff> backoff)
- : task_runner_(task_runner),
- storage_(storage),
- sync_client_(sync_client),
- encryption_service_(encryption_service),
- page_cloud_(page_cloud),
- delegate_(delegate),
- backoff_(std::move(backoff)),
- log_prefix_(fxl::Concatenate(
- {"Page ", convert::ToHex(storage->GetId()), " download sync: "})),
- watcher_binding_(this) {}
-
-PageDownload::~PageDownload() { sync_client_->SetSyncDelegate(nullptr); }
-
-void PageDownload::StartDownload() {
- SetCommitState(DOWNLOAD_BACKLOG);
-
- sync_client_->SetSyncDelegate(this);
-
- // Retrieve the server-side timestamp of the last commit we received.
- storage_->GetSyncMetadata(
- kTimestampKey,
- task_runner_->MakeScoped([this](storage::Status status,
- std::string last_commit_token_id) {
- // NOT_FOUND means that we haven't persisted the state yet, e.g. because
- // we haven't received any remote commits yet. In this case an empty
- // timestamp is the right value.
- if (status != storage::Status::OK &&
- status != storage::Status::NOT_FOUND) {
- HandleDownloadCommitError("Failed to retrieve the sync metadata.");
- return;
- }
- if (last_commit_token_id.empty()) {
- FXL_VLOG(1) << log_prefix_ << "starting sync for the first time, "
- << "retrieving all remote commits";
- } else {
- // TODO(ppi): print the timestamp out as human-readable wall time.
- FXL_VLOG(1) << log_prefix_ << "starting sync again, "
- << "retrieving commits uploaded after: "
- << last_commit_token_id;
- }
-
- std::unique_ptr<cloud_provider::Token> position_token;
- if (!last_commit_token_id.empty()) {
- position_token = std::make_unique<cloud_provider::Token>();
- position_token->opaque_id = convert::ToArray(last_commit_token_id);
- }
- (*page_cloud_)
- ->GetCommits(
- std::move(position_token),
- [this](cloud_provider::Status cloud_status,
- std::unique_ptr<cloud_provider::CommitPack> commit_pack,
- std::unique_ptr<cloud_provider::Token> position_token) {
- if (cloud_status != cloud_provider::Status::OK) {
- // Fetching the remote commits failed, schedule a retry.
- FXL_LOG(WARNING)
- << log_prefix_
- << "fetching the remote commits failed due to a "
- << "connection error, status: "
- << fidl::ToUnderlying(cloud_status) << ", retrying.";
- SetCommitState(DOWNLOAD_TEMPORARY_ERROR);
- RetryWithBackoff([this] { StartDownload(); });
- return;
- }
- if (!commit_pack) {
- FXL_LOG(ERROR) << "Null commits despite status OK.";
- SetCommitState(DOWNLOAD_PERMANENT_ERROR);
- return;
- }
- backoff_->Reset();
-
- std::vector<cloud_provider::CommitPackEntry> entries;
- if (!cloud_provider::DecodeCommitPack(*commit_pack,
- &entries)) {
- FXL_LOG(ERROR) << "Failed to decode the commits.";
- SetCommitState(DOWNLOAD_PERMANENT_ERROR);
- return;
- }
-
- if (entries.empty()) {
- // If there is no remote commits to add, announce that
- // we're done.
- FXL_VLOG(1)
- << log_prefix_
- << "initial sync finished, no new remote commits";
- BacklogDownloaded();
- } else {
- FXL_VLOG(1) << log_prefix_ << "retrieved " << entries.size()
- << " (possibly) new remote commits, "
- << "adding them to storage.";
- // If not, fire the backlog download callback when the
- // remote commits are downloaded.
- const auto commit_count = entries.size();
- DownloadBatch(std::move(entries), std::move(position_token),
- [this, commit_count] {
- FXL_VLOG(1)
- << log_prefix_
- << "initial sync finished, added "
- << commit_count << " remote commits.";
- BacklogDownloaded();
- });
- }
- });
- }));
-}
-
-bool PageDownload::IsIdle() {
- switch (GetMergedState(commit_state_, current_get_object_calls_)) {
- case DOWNLOAD_NOT_STARTED:
- case DOWNLOAD_IDLE:
- case DOWNLOAD_PERMANENT_ERROR:
- return true;
- break;
- case DOWNLOAD_BACKLOG:
- case DOWNLOAD_TEMPORARY_ERROR:
- case DOWNLOAD_SETTING_REMOTE_WATCHER:
- case DOWNLOAD_IN_PROGRESS:
- return false;
- break;
- }
-}
-
-void PageDownload::BacklogDownloaded() { SetRemoteWatcher(false); }
-
-void PageDownload::SetRemoteWatcher(bool is_retry) {
- FXL_DCHECK(commit_state_ == DOWNLOAD_BACKLOG ||
- commit_state_ == DOWNLOAD_TEMPORARY_ERROR)
- << "Current state: " << commit_state_;
- SetCommitState(DOWNLOAD_SETTING_REMOTE_WATCHER);
- // Retrieve the server-side token of the last commit we received.
- std::string last_commit_token_id;
- storage_->GetSyncMetadata(
- kTimestampKey,
- task_runner_->MakeScoped([this, is_retry](
- storage::Status status,
- std::string last_commit_token_id) {
- if (status != storage::Status::OK &&
- status != storage::Status::NOT_FOUND) {
- HandleDownloadCommitError("Failed to retrieve the sync metadata.");
- return;
- }
-
- std::unique_ptr<cloud_provider::Token> position_token;
- if (!last_commit_token_id.empty()) {
- position_token = std::make_unique<cloud_provider::Token>();
- position_token->opaque_id = convert::ToArray(last_commit_token_id);
- }
- cloud_provider::PageCloudWatcherPtr watcher;
- watcher_binding_.Bind(watcher.NewRequest());
- (*page_cloud_)
- ->SetWatcher(
- std::move(position_token), std::move(watcher),
- [this](auto status) {
- // This should always succeed - any errors are reported
- // through OnError().
- if (status != cloud_provider::Status::OK) {
- HandleDownloadCommitError(
- "Unexpected error when setting the PageCloudWatcher.");
- }
- });
- SetCommitState(DOWNLOAD_IDLE);
- if (is_retry) {
- FXL_LOG(INFO) << log_prefix_ << "Cloud watcher re-established";
- }
- }));
-}
-
-void PageDownload::OnNewCommits(cloud_provider::CommitPack commits,
- cloud_provider::Token position_token,
- OnNewCommitsCallback callback) {
- std::vector<cloud_provider::CommitPackEntry> entries;
- if (!cloud_provider::DecodeCommitPack(commits, &entries)) {
- HandleDownloadCommitError("Failed to decode the commits");
- return;
- }
-
- if (batch_download_) {
- // If there is already a commit batch being downloaded, save the new commits
- // to be downloaded when it is done.
- std::move(entries.begin(), entries.end(),
- std::back_inserter(commits_to_download_));
- position_token_ = fidl::MakeOptional(std::move(position_token));
- callback();
- return;
- }
- SetCommitState(DOWNLOAD_IN_PROGRESS);
- DownloadBatch(std::move(entries),
- fidl::MakeOptional(std::move(position_token)),
- std::move(callback));
-}
-
-void PageDownload::OnNewObject(std::vector<uint8_t> /*id*/,
- fuchsia::mem::Buffer /*data*/,
- OnNewObjectCallback /*callback*/) {
- // No known cloud provider implementations use this method.
- // TODO(ppi): implement this method when we have such cloud provider
- // implementations.
- FXL_NOTIMPLEMENTED();
-}
-
-void PageDownload::OnError(cloud_provider::Status status) {
- FXL_DCHECK(commit_state_ == DOWNLOAD_IDLE ||
- commit_state_ == DOWNLOAD_IN_PROGRESS);
- if (!IsPermanentError(status)) {
- // Reset the watcher and schedule a retry.
- if (watcher_binding_.is_bound()) {
- watcher_binding_.Unbind();
- }
- SetCommitState(DOWNLOAD_TEMPORARY_ERROR);
- FXL_LOG(WARNING)
- << log_prefix_
- << "Connection error in the remote commit watcher, retrying.";
- RetryWithBackoff([this] { SetRemoteWatcher(true); });
- return;
- }
-
- if (status == cloud_provider::Status::PARSE_ERROR) {
- HandleDownloadCommitError(
- "Received a malformed remote commit notification.");
- return;
- }
-
- FXL_LOG(WARNING) << "Received unexpected error from PageCloudWatcher: "
- << fidl::ToUnderlying(status);
- HandleDownloadCommitError("Received unexpected error from PageCloudWatcher.");
-}
-
-void PageDownload::DownloadBatch(
- std::vector<cloud_provider::CommitPackEntry> entries,
- std::unique_ptr<cloud_provider::Token> position_token,
- fit::closure on_done) {
- FXL_DCHECK(!batch_download_);
- batch_download_ = std::make_unique<BatchDownload>(
- storage_, encryption_service_, std::move(entries),
- std::move(position_token),
- [this, on_done = std::move(on_done)] {
- if (on_done) {
- on_done();
- }
- batch_download_.reset();
-
- if (commits_to_download_.empty()) {
- // Don't set to idle if we're in process of setting the remote
- // watcher.
- if (commit_state_ == DOWNLOAD_IN_PROGRESS) {
- SetCommitState(DOWNLOAD_IDLE);
- }
- return;
- }
- auto entries = std::move(commits_to_download_);
- commits_to_download_.clear();
- DownloadBatch(std::move(entries), std::move(position_token_), nullptr);
- },
- [this] {
- HandleDownloadCommitError(
- "Failed to persist a remote commit in storage");
- });
- batch_download_->Start();
-}
-
-void PageDownload::GetObject(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) {
- current_get_object_calls_++;
- UpdateDownloadState();
- encryption_service_->GetObjectName(
- object_identifier,
- task_runner_->MakeScoped(
- [this, object_identifier, callback = std::move(callback)](
- encryption::Status status, std::string object_name) mutable {
- if (status != encryption::Status::OK) {
- HandleGetObjectError(std::move(object_identifier),
- encryption::IsPermanentError(status),
- "encryption", std::move(callback));
- return;
- }
- (*page_cloud_)
- ->GetObject(
- convert::ToArray(object_name),
- [this, object_identifier = std::move(object_identifier),
- callback = std::move(callback)](
- cloud_provider::Status status,
- ::fuchsia::mem::BufferPtr data) mutable {
- if (status != cloud_provider::Status::OK) {
- HandleGetObjectError(std::move(object_identifier),
- IsPermanentError(status),
- "cloud provider",
- std::move(callback));
- return;
- }
- fsl::SizedVmo sized_vmo;
- if (!fsl::SizedVmo::FromTransport(std::move(*data),
- &sized_vmo)) {
- HandleGetObjectError(std::move(object_identifier), true,
- "converting to SizedVmo",
- std::move(callback));
- return;
- }
-
- DecryptObject(
- std::move(object_identifier),
- storage::DataSource::Create(std::move(sized_vmo)),
- std::move(callback));
- });
- }));
-}
-
-void PageDownload::DecryptObject(
- storage::ObjectIdentifier object_identifier,
- std::unique_ptr<storage::DataSource> content,
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) {
- storage::ReadDataSource(
- &managed_container_, std::move(content),
- [this, object_identifier = std::move(object_identifier),
- callback = std::move(callback)](
- storage::Status status,
- std::unique_ptr<storage::DataSource::DataChunk> content) mutable {
- if (status != storage::Status::OK) {
- HandleGetObjectError(std::move(object_identifier), true, "io",
- std::move(callback));
- return;
- }
- encryption_service_->DecryptObject(
- object_identifier, content->Get().ToString(),
- [this, object_identifier, callback = std::move(callback)](
- encryption::Status status, std::string content) mutable {
- if (status != encryption::Status::OK) {
- HandleGetObjectError(object_identifier,
- encryption::IsPermanentError(status),
- "encryption", std::move(callback));
- return;
- }
- backoff_->Reset();
- callback(
- storage::Status::OK, storage::ChangeSource::CLOUD,
- storage::IsObjectSynced::YES,
- storage::DataSource::DataChunk::Create(std::move(content)));
- current_get_object_calls_--;
- UpdateDownloadState();
- });
- });
-}
-
-void PageDownload::HandleGetObjectError(
- storage::ObjectIdentifier object_identifier, bool is_permanent,
- const char error_name[],
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) {
- if (is_permanent) {
- backoff_->Reset();
- FXL_LOG(WARNING) << log_prefix_ << "GetObject() failed due to a permanent "
- << error_name << " error.";
- callback(storage::Status::IO_ERROR, storage::ChangeSource::CLOUD,
- storage::IsObjectSynced::YES, nullptr);
- current_get_object_calls_--;
- UpdateDownloadState();
- return;
- }
- FXL_LOG(WARNING) << log_prefix_ << "GetObject() failed due to a "
- << error_name << " error, retrying.";
- current_get_object_calls_--;
- UpdateDownloadState();
- RetryWithBackoff([this, object_identifier = std::move(object_identifier),
- callback = std::move(callback)]() mutable {
- GetObject(object_identifier, std::move(callback));
- });
-}
-
-void PageDownload::HandleDownloadCommitError(const char error_description[]) {
- FXL_LOG(ERROR) << log_prefix_ << error_description << " Stopping sync.";
- if (watcher_binding_.is_bound()) {
- watcher_binding_.Unbind();
- }
- sync_client_->SetSyncDelegate(nullptr);
- SetCommitState(DOWNLOAD_PERMANENT_ERROR);
-}
-
-void PageDownload::SetCommitState(DownloadSyncState new_state) {
- if (new_state == commit_state_) {
- return;
- }
-
- commit_state_ = new_state;
- UpdateDownloadState();
-}
-
-void PageDownload::UpdateDownloadState() {
- DownloadSyncState new_state =
- GetMergedState(commit_state_, current_get_object_calls_);
-
- // Notify only if the externally visible state changed.
- if (new_state != merged_state_) {
- merged_state_ = new_state;
- delegate_->SetDownloadState(
- GetMergedState(commit_state_, current_get_object_calls_));
- }
-}
-
-void PageDownload::RetryWithBackoff(fit::closure callable) {
- task_runner_->PostDelayedTask(
- [this, callable = std::move(callable)]() {
- if (this->commit_state_ != DOWNLOAD_PERMANENT_ERROR) {
- callable();
- }
- },
- backoff_->GetNext());
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/page_download.h b/bin/ledger/cloud_sync/impl/page_download.h
deleted file mode 100644
index 1221c81..0000000
--- a/bin/ledger/cloud_sync/impl/page_download.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_DOWNLOAD_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_DOWNLOAD_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/backoff/backoff.h>
-#include <lib/callback/managed_container.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/batch_download.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/storage/public/page_sync_delegate.h"
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-namespace cloud_sync {
-// PageDownload handles all the download operations (commits and objects) for a
-// page.
-class PageDownload : public cloud_provider::PageCloudWatcher,
- public storage::PageSyncDelegate {
- public:
- // Delegate ensuring coordination between PageDownload and the class that owns
- // it.
- class Delegate {
- public:
- // Report that the download state changed.
- virtual void SetDownloadState(DownloadSyncState sync_state) = 0;
- };
-
- PageDownload(callback::ScopedTaskRunner* task_runner,
- storage::PageStorage* storage,
- storage::PageSyncClient* sync_client,
- encryption::EncryptionService* encryption_service,
- cloud_provider::PageCloudPtr* page_cloud, Delegate* delegate,
- std::unique_ptr<backoff::Backoff> backoff);
-
- ~PageDownload() override;
-
- // Downloads the initial backlog of remote commits, and sets up the remote
- // watcher upon success.
- void StartDownload();
-
- // Returns if PageDownload is idle.
- bool IsIdle();
-
- private:
- // cloud_provider::PageCloudWatcher:
- void OnNewCommits(cloud_provider::CommitPack commits,
- cloud_provider::Token position_token,
- OnNewCommitsCallback callback) override;
-
- void OnNewObject(std::vector<uint8_t> id, fuchsia::mem::Buffer data,
- OnNewObjectCallback callback) override;
-
- void OnError(cloud_provider::Status status) override;
-
- // Called when the initial commit backlog is downloaded.
- void BacklogDownloaded();
-
- // Starts watching for Cloud commit notifications.
- void SetRemoteWatcher(bool is_retry);
-
- // Downloads the given batch of commits.
- void DownloadBatch(std::vector<cloud_provider::CommitPackEntry> entries,
- std::unique_ptr<cloud_provider::Token> position_token,
- fit::closure on_done);
-
- // storage::PageSyncDelegate:
- void GetObject(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) override;
-
- void DecryptObject(
- storage::ObjectIdentifier object_identifier,
- std::unique_ptr<storage::DataSource> content,
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback);
-
- void HandleGetObjectError(
- storage::ObjectIdentifier object_identifier, bool is_permanent,
- const char error_name[],
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback);
-
- void HandleDownloadCommitError(const char error_description[]);
-
- // Sets the state for commit download.
- void SetCommitState(DownloadSyncState new_state);
- void UpdateDownloadState();
-
- void RetryWithBackoff(fit::closure callable);
-
- // Owned by whoever owns this class.
- callback::ScopedTaskRunner* const task_runner_;
- storage::PageStorage* const storage_;
- storage::PageSyncClient* sync_client_;
- encryption::EncryptionService* const encryption_service_;
- cloud_provider::PageCloudPtr* const page_cloud_;
- Delegate* const delegate_;
-
- std::unique_ptr<backoff::Backoff> backoff_;
-
- const std::string log_prefix_;
-
- // Work queue:
- // The current batch of remote commits being downloaded.
- std::unique_ptr<BatchDownload> batch_download_;
- // Pending remote commits to download.
- std::vector<cloud_provider::CommitPackEntry> commits_to_download_;
- std::unique_ptr<cloud_provider::Token> position_token_;
- // Container for in-progress datasource.
- callback::ManagedContainer managed_container_;
-
- // State:
- // Commit download state.
- DownloadSyncState commit_state_ = DOWNLOAD_NOT_STARTED;
- int current_get_object_calls_ = 0;
- // Merged state of commit and object download.
- DownloadSyncState merged_state_ = DOWNLOAD_NOT_STARTED;
-
- fidl::Binding<cloud_provider::PageCloudWatcher> watcher_binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageDownload);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_DOWNLOAD_H_
diff --git a/bin/ledger/cloud_sync/impl/page_download_unittest.cc b/bin/ledger/cloud_sync/impl/page_download_unittest.cc
deleted file mode 100644
index ec252ba..0000000
--- a/bin/ledger/cloud_sync/impl/page_download_unittest.cc
+++ /dev/null
@@ -1,519 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/page_download.h"
-
-#include <memory>
-#include <sstream>
-#include <utility>
-#include <vector>
-
-#include <lib/async/dispatcher.h>
-#include <lib/backoff/testing/test_backoff.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/cloud_sync/impl/constants.h"
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h"
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_storage.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-namespace cloud_sync {
-namespace {
-
-// Creates a dummy continuation token.
-cloud_provider::Token MakeToken(convert::ExtendedStringView token_id) {
- cloud_provider::Token token;
- token.opaque_id = convert::ToArray(token_id);
- return token;
-}
-
-// Creates a dummy object identifier.
-storage::ObjectIdentifier MakeObjectIdentifier() {
- // Need not be valid (wrt. internal storage constraints) as it is only used as
- // an opaque identifier for cloud_sync.
- return storage::ObjectIdentifier(1u, 1u,
- storage::ObjectDigest("object_digest"));
-}
-
-constexpr zx::duration kTestBackoffInterval = zx::msec(50);
-std::unique_ptr<backoff::TestBackoff> NewTestBackoff() {
- auto result = std::make_unique<backoff::TestBackoff>(kTestBackoffInterval);
- return result;
-}
-
-// Dummy implementation of a backoff policy, which always returns zero backoff
-// time.
-template <typename E>
-class BasePageDownloadTest : public gtest::TestLoopFixture,
- public PageDownload::Delegate {
- public:
- BasePageDownloadTest()
- : storage_(dispatcher()),
- encryption_service_(dispatcher()),
- page_cloud_(page_cloud_ptr_.NewRequest()),
- task_runner_(dispatcher()) {
- page_download_ = std::make_unique<PageDownload>(
- &task_runner_, &storage_, &storage_, &encryption_service_,
- &page_cloud_ptr_, this, NewTestBackoff());
- }
- ~BasePageDownloadTest() override {}
-
- protected:
- void SetOnNewStateCallback(fit::closure callback) {
- new_state_callback_ = std::move(callback);
- }
-
- // Starts download and runs the loop until the download state is idle. Returns
- // true iff the download state went to idle as expected.
- ::testing::AssertionResult StartDownloadAndWaitForIdle() {
- bool on_idle_called = false;
- SetOnNewStateCallback([this, &on_idle_called] {
- if (states_.back() == DOWNLOAD_IDLE) {
- on_idle_called = true;
- }
- });
- page_download_->StartDownload();
- RunLoopUntilIdle();
- SetOnNewStateCallback([] {});
-
- if (on_idle_called) {
- return ::testing::AssertionSuccess();
- }
- return ::testing::AssertionFailure()
- << "The download state never reached idle.";
- }
-
- TestPageStorage storage_;
- E encryption_service_;
- cloud_provider::PageCloudPtr page_cloud_ptr_;
- TestPageCloud page_cloud_;
- std::vector<DownloadSyncState> states_;
- std::unique_ptr<PageDownload> page_download_;
- int error_callback_calls_ = 0;
-
- private:
- void SetDownloadState(DownloadSyncState sync_state) override {
- if (!states_.empty() && sync_state == states_.back()) {
- // Skip identical states.
- return;
- }
- states_.push_back(sync_state);
- if (new_state_callback_) {
- new_state_callback_();
- }
- }
-
- fit::closure new_state_callback_;
- callback::ScopedTaskRunner task_runner_;
- FXL_DISALLOW_COPY_AND_ASSIGN(BasePageDownloadTest);
-};
-
-using PageDownloadTest =
- BasePageDownloadTest<encryption::FakeEncryptionService>;
-
-// Verifies that the backlog of unsynced commits is retrieved from the cloud
-// provider and saved in storage.
-TEST_F(PageDownloadTest, DownloadBacklog) {
- EXPECT_EQ(0u, storage_.received_commits.size());
- EXPECT_EQ(0u, storage_.sync_metadata.count(kTimestampKey.ToString()));
-
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id1", "content1"));
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id2", "content2"));
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("43"));
-
- ASSERT_TRUE(StartDownloadAndWaitForIdle());
-
- EXPECT_EQ(2u, storage_.received_commits.size());
- EXPECT_EQ("content1", storage_.received_commits["id1"]);
- EXPECT_EQ("content2", storage_.received_commits["id2"]);
- EXPECT_EQ("43", storage_.sync_metadata[kTimestampKey.ToString()]);
- EXPECT_EQ(DOWNLOAD_IDLE, states_.back());
-}
-
-TEST_F(PageDownloadTest, DownloadLongBacklog) {
- EXPECT_EQ(0u, storage_.received_commits.size());
- EXPECT_EQ(0u, storage_.sync_metadata.count(kTimestampKey.ToString()));
-
- const size_t commit_count = 100'000;
- for (size_t i = 0; i < commit_count; i++) {
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id" + std::to_string(i),
- "content" + std::to_string(i)));
- }
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("43"));
-
- ASSERT_TRUE(StartDownloadAndWaitForIdle());
-
- EXPECT_EQ(commit_count, storage_.received_commits.size());
- EXPECT_EQ("43", storage_.sync_metadata[kTimestampKey.ToString()]);
- EXPECT_EQ(DOWNLOAD_IDLE, states_.back());
-}
-
-TEST_F(PageDownloadTest, DownloadEmptyBacklog) {
- ASSERT_TRUE(StartDownloadAndWaitForIdle());
-}
-
-// Verifies that the cloud watcher is registered for the timestamp of the most
-// recent commit downloaded from the backlog.
-TEST_F(PageDownloadTest, RegisterWatcher) {
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id1", "content1"));
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id2", "content2"));
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("43"));
-
- ASSERT_TRUE(StartDownloadAndWaitForIdle());
-
- ASSERT_EQ(1u, page_cloud_.set_watcher_position_tokens.size());
- EXPECT_EQ("43",
- convert::ToString(
- page_cloud_.set_watcher_position_tokens.front()->opaque_id));
-}
-
-// Verifies that commit notifications about new commits in cloud provider are
-// received and passed to storage.
-TEST_F(PageDownloadTest, ReceiveNotifications) {
- ASSERT_TRUE(StartDownloadAndWaitForIdle());
-
- // Deliver a remote notification.
- EXPECT_EQ(0u, storage_.received_commits.size());
- EXPECT_EQ(0u, storage_.sync_metadata.count(kTimestampKey.ToString()));
- auto commit_pack = MakeTestCommitPack(
- &encryption_service_, {{"id1", "content1"}, {"id2", "content2"}});
- ASSERT_TRUE(commit_pack);
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("43"), [] {});
- RunLoopUntilIdle();
-
- // Verify that the remote commits were added to storage.
- EXPECT_EQ(2u, storage_.received_commits.size());
- EXPECT_EQ("content1", storage_.received_commits["id1"]);
- EXPECT_EQ("content2", storage_.received_commits["id2"]);
- EXPECT_EQ("43", storage_.sync_metadata[kTimestampKey.ToString()]);
-}
-
-// Verify that we retry setting the remote watcher on connection errors
-// and when the auth token expires.
-TEST_F(PageDownloadTest, RetryRemoteWatcher) {
- page_download_->StartDownload();
- EXPECT_EQ(0u, storage_.received_commits.size());
-
- RunLoopUntilIdle();
- EXPECT_EQ(1u, page_cloud_.set_watcher_position_tokens.size());
-
- page_cloud_.set_watcher->OnError(cloud_provider::Status::NETWORK_ERROR);
- RunLoopFor(kTestBackoffInterval);
- EXPECT_EQ(2u, page_cloud_.set_watcher_position_tokens.size());
-
- page_cloud_.set_watcher->OnError(cloud_provider::Status::AUTH_ERROR);
- RunLoopFor(kTestBackoffInterval);
- EXPECT_EQ(3u, page_cloud_.set_watcher_position_tokens.size());
-}
-
-// Verifies that if multiple remote commits are received while one batch is
-// already being downloaded, the new remote commits are added to storage in one
-// request.
-TEST_F(PageDownloadTest, CoalesceMultipleNotifications) {
- ASSERT_TRUE(StartDownloadAndWaitForIdle());
-
- // Make the storage delay requests to add remote commits.
- storage_.should_delay_add_commit_confirmation = true;
-
- // Deliver a remote notification.
- EXPECT_EQ(0u, storage_.received_commits.size());
- EXPECT_EQ(0u, storage_.sync_metadata.count(kTimestampKey.ToString()));
- auto commit_pack =
- MakeTestCommitPack(&encryption_service_, {{"id1", "content1"}});
- ASSERT_TRUE(commit_pack);
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("42"), [] {});
- RunLoopUntilIdle();
- EXPECT_EQ(1u, storage_.delayed_add_commit_confirmations.size());
-
- // Add two more remote commits, before storage confirms adding the first one.
- commit_pack = MakeTestCommitPack(&encryption_service_,
- {{"id2", "content2"}, {"id3", "content3"}});
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("44"), [] {});
-
- // Make storage confirm adding the first commit.
- storage_.should_delay_add_commit_confirmation = false;
- storage_.delayed_add_commit_confirmations.front()();
- RunLoopUntilIdle();
- EXPECT_EQ(3u, storage_.received_commits.size());
-
- // Verify that all three commits were delivered in total of two calls to
- // storage.
- EXPECT_EQ(3u, storage_.received_commits.size());
- EXPECT_EQ("content1", storage_.received_commits["id1"]);
- EXPECT_EQ("content2", storage_.received_commits["id2"]);
- EXPECT_EQ("content3", storage_.received_commits["id3"]);
- EXPECT_EQ("44", storage_.sync_metadata[kTimestampKey.ToString()]);
- EXPECT_EQ(2u, storage_.add_commits_from_sync_calls);
-}
-
-// TODO(LE-497): The following should not pass. Investigate why.
-// Verifies that failing attempts to download the backlog of unsynced commits
-// are retried.
-TEST_F(PageDownloadTest, RetryDownloadBacklog) {
- page_cloud_.status_to_return = cloud_provider::Status::NETWORK_ERROR;
- page_download_->StartDownload();
-
- // Loop through five attempts to download the backlog.
- SetOnNewStateCallback([this] {
- if (page_cloud_.get_commits_calls >= 5u) {
- QuitLoop();
- }
- });
- RunLoopUntilIdle();
- EXPECT_GE(5u, page_cloud_.get_commits_calls);
- EXPECT_EQ(0u, storage_.received_commits.size());
-
- SetOnNewStateCallback([] {});
- page_cloud_.status_to_return = cloud_provider::Status::OK;
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id1", "content1"));
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("42"));
- RunLoopFor(kTestBackoffInterval);
- EXPECT_TRUE(page_download_->IsIdle());
-
- EXPECT_EQ(1u, storage_.received_commits.size());
- EXPECT_EQ("content1", storage_.received_commits["id1"]);
- EXPECT_EQ("42", storage_.sync_metadata[kTimestampKey.ToString()]);
-}
-
-// Verifies that a failure to persist the remote commit stops syncing remote
-// commits and the error status is returned.
-TEST_F(PageDownloadTest, FailToStoreRemoteCommit) {
- ASSERT_TRUE(StartDownloadAndWaitForIdle());
- EXPECT_TRUE(page_cloud_.set_watcher.is_bound());
-
- storage_.should_fail_add_commit_from_sync = true;
- auto commit_pack =
- MakeTestCommitPack(&encryption_service_, {{"id1", "content1"}});
- ASSERT_TRUE(commit_pack);
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("42"), [] {});
-
- RunLoopUntilIdle();
- ASSERT_FALSE(states_.empty());
- EXPECT_EQ(DOWNLOAD_PERMANENT_ERROR, states_.back());
- EXPECT_FALSE(page_cloud_.set_watcher.is_bound());
-}
-
-// Verifies that the idle status is returned when there is no download in
-// progress.
-TEST_F(PageDownloadTest, DownloadIdleCallback) {
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id1", "content1"));
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id2", "content2"));
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("43"));
-
- int on_idle_calls = 0;
- SetOnNewStateCallback([this, &on_idle_calls] {
- if (states_.back() == DOWNLOAD_IDLE) {
- on_idle_calls++;
- }
- });
- page_download_->StartDownload();
- EXPECT_EQ(0, on_idle_calls);
- EXPECT_FALSE(page_download_->IsIdle());
-
- // Run the message loop and verify that the sync is idle after all remote
- // commits are added to storage.
- RunLoopUntilIdle();
- EXPECT_EQ(1, on_idle_calls);
- EXPECT_TRUE(page_download_->IsIdle());
-
- // Notify about a new commit to download and verify that the idle callback was
- // called again on completion.
- auto commit_pack =
- MakeTestCommitPack(&encryption_service_, {{"id3", "content3"}});
- ASSERT_TRUE(commit_pack);
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("44"), [] {});
- RunLoopUntilIdle();
- EXPECT_EQ(3u, storage_.received_commits.size());
- EXPECT_EQ(2, on_idle_calls);
- EXPECT_TRUE(page_download_->IsIdle());
-}
-
-// Verifies that sync correctly fetches objects from the cloud provider.
-TEST_F(PageDownloadTest, GetObject) {
- storage::ObjectIdentifier object_identifier = MakeObjectIdentifier();
- std::string object_name =
- encryption_service_.GetObjectNameSynchronous(object_identifier);
- page_cloud_.objects_to_return[object_name] =
- encryption_service_.EncryptObjectSynchronous("content");
- page_download_->StartDownload();
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data_chunk;
- RunLoopUntilIdle();
- states_.clear();
- storage_.page_sync_delegate_->GetObject(
- object_identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data_chunk));
- RunLoopUntilIdle();
-
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(storage::ChangeSource::CLOUD, source);
- EXPECT_EQ(storage::IsObjectSynced::YES, is_object_synced);
- EXPECT_EQ("content", data_chunk->Get().ToString());
- EXPECT_EQ(2u, states_.size());
- EXPECT_EQ(DOWNLOAD_IN_PROGRESS, states_[0]);
- EXPECT_EQ(DOWNLOAD_IDLE, states_[1]);
-}
-
-// Verifies that sync retries GetObject() attempts upon connection error.
-TEST_F(PageDownloadTest, RetryGetObject) {
- storage::ObjectIdentifier object_identifier = MakeObjectIdentifier();
- std::string object_name =
- encryption_service_.GetObjectNameSynchronous(object_identifier);
-
- page_cloud_.status_to_return = cloud_provider::Status::NETWORK_ERROR;
- SetOnNewStateCallback([this] {
- if (states_.back() == DOWNLOAD_PERMANENT_ERROR) {
- QuitLoop();
- }
- });
-
- page_download_->StartDownload();
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data_chunk;
- storage_.page_sync_delegate_->GetObject(
- object_identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data_chunk));
-
- // Allow the operation to succeed after looping through five attempts.
- RunLoopFor(kTestBackoffInterval * 4);
- page_cloud_.status_to_return = cloud_provider::Status::OK;
- page_cloud_.objects_to_return[object_name] =
- encryption_service_.EncryptObjectSynchronous("content");
- RunLoopFor(kTestBackoffInterval);
-
- ASSERT_TRUE(called);
- EXPECT_EQ(6u, page_cloud_.get_object_calls);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ(storage::ChangeSource::CLOUD, source);
- EXPECT_EQ("content", data_chunk->Get().ToString());
- EXPECT_EQ(storage::IsObjectSynced::YES, is_object_synced);
-}
-
-class FailingDecryptCommitEncryptionService
- : public encryption::FakeEncryptionService {
- public:
- explicit FailingDecryptCommitEncryptionService(async_dispatcher_t* dispatcher)
- : encryption::FakeEncryptionService(dispatcher) {}
-
- void DecryptCommit(
- convert::ExtendedStringView /*storage_bytes*/,
- fit::function<void(encryption::Status, std::string)> callback) override {
- callback(encryption::Status::INVALID_ARGUMENT, "");
- }
-};
-
-class FailingGetNameEncryptionService
- : public encryption::FakeEncryptionService {
- public:
- explicit FailingGetNameEncryptionService(async_dispatcher_t* dispatcher)
- : encryption::FakeEncryptionService(dispatcher) {}
-
- void GetObjectName(
- storage::ObjectIdentifier /*object_identifier*/,
- fit::function<void(encryption::Status, std::string)> callback) override {
- callback(encryption::Status::INVALID_ARGUMENT, "");
- }
-};
-
-class FailingDecryptObjectEncryptionService
- : public encryption::FakeEncryptionService {
- public:
- explicit FailingDecryptObjectEncryptionService(async_dispatcher_t* dispatcher)
- : encryption::FakeEncryptionService(dispatcher) {}
-
- void DecryptObject(
- storage::ObjectIdentifier /*object_identifier*/,
- std::string /*encrypted_data*/,
- fit::function<void(encryption::Status, std::string)> callback) override {
- callback(encryption::Status::INVALID_ARGUMENT, "");
- }
-};
-
-using FailingDecryptCommitPageDownloadTest =
- BasePageDownloadTest<FailingDecryptCommitEncryptionService>;
-TEST_F(FailingDecryptCommitPageDownloadTest, Fail) {
- EXPECT_EQ(0u, storage_.received_commits.size());
- EXPECT_EQ(0u, storage_.sync_metadata.count(kTimestampKey.ToString()));
-
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id1", "content1"));
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id2", "content2"));
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("43"));
-
- EXPECT_FALSE(StartDownloadAndWaitForIdle());
- ASSERT_FALSE(states_.empty());
- EXPECT_EQ(DOWNLOAD_PERMANENT_ERROR, states_.back());
-}
-
-template <typename E>
-using FailingPageDownloadTest = BasePageDownloadTest<E>;
-
-using FailingEncryptionServices =
- ::testing::Types<FailingGetNameEncryptionService,
- FailingDecryptObjectEncryptionService>;
-
-TYPED_TEST_CASE(FailingPageDownloadTest, FailingEncryptionServices);
-
-TYPED_TEST(FailingPageDownloadTest, Fail) {
- storage::ObjectIdentifier object_identifier = MakeObjectIdentifier();
- std::string object_name =
- this->encryption_service_.GetObjectNameSynchronous(object_identifier);
- this->page_cloud_.objects_to_return[object_name] =
- this->encryption_service_.EncryptObjectSynchronous("content");
- this->page_download_->StartDownload();
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data_chunk;
- this->storage_.page_sync_delegate_->GetObject(
- object_identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data_chunk));
- this->RunLoopUntilIdle();
-
- ASSERT_TRUE(called);
- EXPECT_EQ(storage::Status::IO_ERROR, status);
- EXPECT_EQ(storage::ChangeSource::CLOUD, source);
-}
-
-} // namespace
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/page_sync_impl.cc b/bin/ledger/cloud_sync/impl/page_sync_impl.cc
deleted file mode 100644
index 21bb2a7..0000000
--- a/bin/ledger/cloud_sync/impl/page_sync_impl.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/page_sync_impl.h"
-
-#include <algorithm>
-#include <map>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/constants.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace cloud_sync {
-
-PageSyncImpl::PageSyncImpl(async_dispatcher_t* dispatcher,
- storage::PageStorage* storage,
- storage::PageSyncClient* sync_client,
- encryption::EncryptionService* encryption_service,
- cloud_provider::PageCloudPtr page_cloud,
- std::unique_ptr<backoff::Backoff> download_backoff,
- std::unique_ptr<backoff::Backoff> upload_backoff,
- std::unique_ptr<SyncStateWatcher> ledger_watcher)
- : storage_(storage),
- sync_client_(sync_client),
- encryption_service_(encryption_service),
- page_cloud_(std::move(page_cloud)),
- log_prefix_("Page " + convert::ToHex(storage->GetId()) + " sync: "),
- ledger_watcher_(std::move(ledger_watcher)),
- task_runner_(dispatcher) {
- FXL_DCHECK(storage_);
- FXL_DCHECK(page_cloud_);
- // We need to initialize page_download_ after task_runner_, but task_runner_
- // must be the last field.
- page_download_ = std::make_unique<PageDownload>(
- &task_runner_, storage_, sync_client_, encryption_service_, &page_cloud_,
- this, std::move(download_backoff));
- page_upload_ = std::make_unique<PageUpload>(&task_runner_, storage_,
- encryption_service_, &page_cloud_,
- this, std::move(upload_backoff));
- page_cloud_.set_error_handler([this](zx_status_t status) {
- if (on_unrecoverable_error_ && !error_callback_already_called_) {
- error_callback_already_called_ = true;
- on_unrecoverable_error_();
- }
- });
-}
-
-PageSyncImpl::~PageSyncImpl() {
- if (on_delete_) {
- on_delete_();
- }
-}
-
-void PageSyncImpl::EnableUpload() {
- enable_upload_ = true;
-
- if (!started_) {
- // We will start upload when this object is started.
- return;
- }
-
- if (upload_state_ == UPLOAD_NOT_STARTED) {
- page_upload_->StartOrRestartUpload();
- }
-}
-
-void PageSyncImpl::Start() {
- FXL_DCHECK(!started_);
- started_ = true;
-
- page_download_->StartDownload();
- if (enable_upload_) {
- page_upload_->StartOrRestartUpload();
- }
-}
-
-void PageSyncImpl::SetOnIdle(fit::closure on_idle) {
- FXL_DCHECK(!on_idle_);
- FXL_DCHECK(!started_);
- on_idle_ = std::move(on_idle);
-}
-
-bool PageSyncImpl::IsIdle() {
- return page_upload_->IsIdle() && page_download_->IsIdle();
-}
-
-void PageSyncImpl::SetOnBacklogDownloaded(fit::closure on_backlog_downloaded) {
- FXL_DCHECK(!on_backlog_downloaded_);
- FXL_DCHECK(!started_);
- on_backlog_downloaded_ = std::move(on_backlog_downloaded);
-}
-
-void PageSyncImpl::SetSyncWatcher(SyncStateWatcher* watcher) {
- page_watcher_ = watcher;
- if (page_watcher_) {
- page_watcher_->Notify(download_state_, upload_state_);
- }
-}
-
-void PageSyncImpl::SetOnUnrecoverableError(
- fit::closure on_unrecoverable_error) {
- on_unrecoverable_error_ = std::move(on_unrecoverable_error);
-}
-
-void PageSyncImpl::HandleError() {
- if (error_callback_already_called_) {
- return;
- }
-
- if (on_unrecoverable_error_) {
- error_callback_already_called_ = true;
- on_unrecoverable_error_();
- }
-}
-
-void PageSyncImpl::CheckIdle() {
- if (IsIdle()) {
- if (on_idle_) {
- on_idle_();
- }
- }
-}
-
-void PageSyncImpl::NotifyStateWatcher() {
- if (ledger_watcher_) {
- ledger_watcher_->Notify(download_state_, upload_state_);
- }
- if (page_watcher_) {
- page_watcher_->Notify(download_state_, upload_state_);
- }
- CheckIdle();
-}
-
-void PageSyncImpl::SetDownloadState(DownloadSyncState next_download_state) {
- if (next_download_state == DOWNLOAD_PERMANENT_ERROR) {
- HandleError();
- }
-
- if (download_state_ == DOWNLOAD_BACKLOG &&
- next_download_state != DOWNLOAD_PERMANENT_ERROR &&
- on_backlog_downloaded_) {
- on_backlog_downloaded_();
- }
-
- if (download_state_ != DOWNLOAD_IDLE &&
- next_download_state == DOWNLOAD_IDLE && enable_upload_) {
- page_upload_->StartOrRestartUpload();
- }
-
- download_state_ = next_download_state;
- NotifyStateWatcher();
-}
-
-void PageSyncImpl::SetUploadState(UploadSyncState next_upload_state) {
- if (next_upload_state == UPLOAD_PERMANENT_ERROR) {
- HandleError();
- }
-
- upload_state_ = next_upload_state;
- NotifyStateWatcher();
-}
-
-bool PageSyncImpl::IsDownloadIdle() { return page_download_->IsIdle(); }
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/page_sync_impl.h b/bin/ledger/cloud_sync/impl/page_sync_impl.h
deleted file mode 100644
index 67e4b54..0000000
--- a/bin/ledger/cloud_sync/impl/page_sync_impl.h
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_SYNC_IMPL_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_SYNC_IMPL_H_
-
-#include <functional>
-#include <queue>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/async/dispatcher.h>
-#include <lib/backoff/backoff.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/time/time_delta.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/batch_download.h"
-#include "peridot/bin/ledger/cloud_sync/impl/batch_upload.h"
-#include "peridot/bin/ledger/cloud_sync/impl/page_download.h"
-#include "peridot/bin/ledger/cloud_sync/impl/page_upload.h"
-#include "peridot/bin/ledger/cloud_sync/public/page_sync.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/storage/public/commit_watcher.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace cloud_sync {
-
-// Manages cloud sync for a single page.
-//
-// Contract: commits are uploaded in the same order as storage delivers them.
-// The backlog of unsynced commits is uploaded first, then we upload commits
-// delivered through storage watcher in the notification order.
-//
-// Conversely for the remote commits: the backlog of remote commits is
-// downloaded first, then a cloud watcher is set to track new remote commits
-// appearing in the cloud provider. Remote commits are added to storage in the
-// order in which they were added to the cloud provided.
-//
-// In order to track which remote commits were already fetched, we keep track of
-// the server-side timestamp of the last commit we added to storage. As this
-// information needs to be persisted through reboots, we store the timestamp
-// itself in storage using a dedicated API (Get/SetSyncMetadata()).
-//
-// Recoverable errors (such as network errors) are automatically retried with
-// the given backoff policy, using the given task runner to schedule the tasks.
-// TODO(ppi): once the network service can notify us about regained
-// connectivity, thread this signal through PageCloudHandler and use it as a
-// signal to trigger retries.
-//
-// Unrecoverable errors (such as internal errors accessing the storage) cause
-// the page sync to stop, in which case the client is notified using the error
-// callback set via SetOnUnrecoverableError().
-class PageSyncImpl : public PageSync,
- public PageDownload::Delegate,
- public PageUpload::Delegate {
- public:
- PageSyncImpl(async_dispatcher_t* dispatcher, storage::PageStorage* storage,
- storage::PageSyncClient* sync_client,
- encryption::EncryptionService* encryption_service,
- cloud_provider::PageCloudPtr page_cloud,
- std::unique_ptr<backoff::Backoff> download_backoff,
- std::unique_ptr<backoff::Backoff> upload_backoff,
- std::unique_ptr<SyncStateWatcher> ledger_watcher = nullptr);
- ~PageSyncImpl() override;
-
- // |on_delete| will be called when this class is deleted.
- void set_on_delete(fit::function<void()> on_delete) {
- FXL_DCHECK(!on_delete_);
- on_delete_ = std::move(on_delete);
- }
-
- // Enables upload. Has no effect if this method has already been called.
- void EnableUpload();
-
- // PageSync:
- void Start() override;
-
- void SetOnIdle(fit::closure on_idle) override;
-
- bool IsIdle() override;
-
- void SetOnBacklogDownloaded(fit::closure on_backlog_downloaded) override;
-
- void SetSyncWatcher(SyncStateWatcher* watcher) override;
-
- void SetOnUnrecoverableError(fit::closure on_unrecoverable_error) override;
-
- private:
- void HandleError();
-
- void CheckIdle();
-
- // Notify the state watcher of a change of synchronization state.
- void SetDownloadState(DownloadSyncState next_download_state) override;
- void SetUploadState(UploadSyncState next_upload_state) override;
- bool IsDownloadIdle() override;
-
- void NotifyStateWatcher();
-
- storage::PageStorage* const storage_;
- storage::PageSyncClient* const sync_client_;
- encryption::EncryptionService* const encryption_service_;
- cloud_provider::PageCloudPtr page_cloud_;
- const fit::closure on_error_;
- const std::string log_prefix_;
-
- std::unique_ptr<PageDownload> page_download_;
- std::unique_ptr<PageUpload> page_upload_;
-
- fit::closure on_idle_;
- fit::closure on_backlog_downloaded_;
- fit::closure on_unrecoverable_error_;
- // Ensures that each instance is started only once.
- bool started_ = false;
- // Set to true on unrecoverable error. This indicates that PageSyncImpl is in
- // broken state.
- bool error_callback_already_called_ = false;
- // Blocks the start of the upload process until we get an explicit signal.
- bool enable_upload_ = false;
-
- // Called on destruction.
- fit::function<void()> on_delete_;
-
- // Watcher of the synchronization state that reports to the LedgerSync object.
- std::unique_ptr<SyncStateWatcher> ledger_watcher_;
- SyncStateWatcher* page_watcher_ = nullptr;
- DownloadSyncState download_state_ = DOWNLOAD_NOT_STARTED;
- UploadSyncState upload_state_ = UPLOAD_NOT_STARTED;
-
- // Must be the last member field.
- callback::ScopedTaskRunner task_runner_;
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_SYNC_IMPL_H_
diff --git a/bin/ledger/cloud_sync/impl/page_sync_impl_unittest.cc b/bin/ledger/cloud_sync/impl/page_sync_impl_unittest.cc
deleted file mode 100644
index 55ba360..0000000
--- a/bin/ledger/cloud_sync/impl/page_sync_impl_unittest.cc
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/page_sync_impl.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <lib/async/cpp/task.h>
-#include <lib/backoff/testing/test_backoff.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/constants.h"
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h"
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_storage.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-namespace cloud_sync {
-namespace {
-
-using testing::ElementsAre;
-
-// Creates a dummy continuation token.
-cloud_provider::Token MakeToken(convert::ExtendedStringView token_id) {
- cloud_provider::Token token;
- token.opaque_id = convert::ToArray(token_id);
- return token;
-}
-
-class TestSyncStateWatcher : public SyncStateWatcher {
- public:
- TestSyncStateWatcher() {}
- ~TestSyncStateWatcher() override{};
-
- void Notify(SyncStateContainer sync_state) override {
- if (!states.empty() && sync_state == *states.rbegin()) {
- return;
- }
- states.push_back(sync_state);
- }
-
- std::vector<SyncStateContainer> states;
-};
-
-class PageSyncImplTest : public gtest::TestLoopFixture {
- public:
- PageSyncImplTest()
- : storage_(dispatcher()),
- encryption_service_(dispatcher()),
- page_cloud_(page_cloud_ptr_.NewRequest()) {
- std::unique_ptr<TestSyncStateWatcher> watcher =
- std::make_unique<TestSyncStateWatcher>();
- state_watcher_ = watcher.get();
-
- auto download_backoff =
- std::make_unique<backoff::TestBackoff>(zx::msec(50));
- download_backoff_ptr_ = download_backoff.get();
- auto upload_backoff = std::make_unique<backoff::TestBackoff>(zx::msec(50));
- upload_backoff_ptr_ = upload_backoff.get();
-
- page_sync_ = std::make_unique<PageSyncImpl>(
- dispatcher(), &storage_, &storage_, &encryption_service_,
- std::move(page_cloud_ptr_), std::move(download_backoff),
- std::move(upload_backoff), std::move(watcher));
- }
- ~PageSyncImplTest() override {}
-
- protected:
- enum class UploadStatus {
- ENABLED,
- DISABLED,
- };
- void StartPageSync(UploadStatus status = UploadStatus::ENABLED) {
- if (status == UploadStatus::ENABLED) {
- page_sync_->EnableUpload();
- }
- page_sync_->Start();
- }
-
- TestPageStorage storage_;
- encryption::FakeEncryptionService encryption_service_;
- cloud_provider::PageCloudPtr page_cloud_ptr_;
- TestPageCloud page_cloud_;
- backoff::TestBackoff* download_backoff_ptr_;
- backoff::TestBackoff* upload_backoff_ptr_;
- TestSyncStateWatcher* state_watcher_;
- std::unique_ptr<PageSyncImpl> page_sync_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageSyncImplTest);
-};
-
-SyncStateWatcher::SyncStateContainer MakeStates(DownloadSyncState download,
- UploadSyncState upload) {
- return {download, upload};
-}
-
-// Verifies that the backlog of commits to upload returned from
-// GetUnsyncedCommits() is uploaded to PageCloudHandler.
-TEST_F(PageSyncImplTest, UploadBacklog) {
- storage_.NewCommit("id1", "content1");
- storage_.NewCommit("id2", "content2");
- bool called;
- page_sync_->SetOnIdle(callback::SetWhenCalled(&called));
- StartPageSync();
-
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("id1", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("id2", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content2", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- EXPECT_EQ(2u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id2"));
-
- EXPECT_THAT(
- state_watcher_->states,
- ElementsAre(MakeStates(DOWNLOAD_BACKLOG, UPLOAD_NOT_STARTED),
- MakeStates(DOWNLOAD_BACKLOG, UPLOAD_WAIT_REMOTE_DOWNLOAD),
- MakeStates(DOWNLOAD_SETTING_REMOTE_WATCHER,
- UPLOAD_WAIT_REMOTE_DOWNLOAD),
- MakeStates(DOWNLOAD_IDLE, UPLOAD_WAIT_REMOTE_DOWNLOAD),
- MakeStates(DOWNLOAD_IDLE, UPLOAD_PENDING),
- MakeStates(DOWNLOAD_IDLE, UPLOAD_IN_PROGRESS),
- MakeStates(DOWNLOAD_IDLE, UPLOAD_IDLE)));
-}
-
-// Verifies that the backlog of commits to upload returned from
-// GetUnsyncedCommits() is uploaded to PageCloudHandler.
-TEST_F(PageSyncImplTest, PageWatcher) {
- TestSyncStateWatcher watcher;
- storage_.NewCommit("id1", "content1");
- storage_.NewCommit("id2", "content2");
- bool called;
- page_sync_->SetOnIdle(callback::SetWhenCalled(&called));
- page_sync_->SetSyncWatcher(&watcher);
- StartPageSync();
-
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- EXPECT_THAT(
- watcher.states,
- ElementsAre(MakeStates(DOWNLOAD_NOT_STARTED, UPLOAD_NOT_STARTED),
- MakeStates(DOWNLOAD_BACKLOG, UPLOAD_NOT_STARTED),
- MakeStates(DOWNLOAD_BACKLOG, UPLOAD_WAIT_REMOTE_DOWNLOAD),
- MakeStates(DOWNLOAD_SETTING_REMOTE_WATCHER,
- UPLOAD_WAIT_REMOTE_DOWNLOAD),
- MakeStates(DOWNLOAD_IDLE, UPLOAD_WAIT_REMOTE_DOWNLOAD),
- MakeStates(DOWNLOAD_IDLE, UPLOAD_PENDING),
- MakeStates(DOWNLOAD_IDLE, UPLOAD_IN_PROGRESS),
- MakeStates(DOWNLOAD_IDLE, UPLOAD_IDLE)));
-}
-
-// Verifies that sync pauses uploading commits when it is downloading a commit.
-TEST_F(PageSyncImplTest, NoUploadWhenDownloading) {
- storage_.should_delay_add_commit_confirmation = true;
-
- bool called;
- page_sync_->SetOnIdle(callback::SetWhenCalled(&called));
- StartPageSync();
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- ASSERT_TRUE(page_cloud_.set_watcher.is_bound());
- auto commit_pack =
- MakeTestCommitPack(&encryption_service_, {{"id1", "content1"}});
- ASSERT_TRUE(commit_pack);
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("44"), [] {});
- RunLoopUntilIdle();
- EXPECT_LT(0u, storage_.add_commits_from_sync_calls);
-
- storage_.watcher_->OnNewCommits(
- storage_.NewCommit("id2", "content2")->AsList(),
- storage::ChangeSource::LOCAL);
-
- RunLoopUntilIdle();
- EXPECT_FALSE(storage_.delayed_add_commit_confirmations.empty());
- EXPECT_TRUE(page_cloud_.received_commits.empty());
-
- storage_.delayed_add_commit_confirmations.front()();
-
- RunLoopUntilIdle();
- EXPECT_FALSE(page_cloud_.received_commits.empty());
-}
-
-TEST_F(PageSyncImplTest, UploadExistingCommitsOnlyAfterBacklogDownload) {
- // Verify that two local commits are not uploaded when download is in
- // progress.
- storage_.NewCommit("local1", "content1");
- storage_.NewCommit("local2", "content2");
-
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "remote3", "content3"));
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "remote4", "content4"));
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("43"));
- bool backlog_downloaded_called = false;
- page_sync_->SetOnBacklogDownloaded([this, &backlog_downloaded_called] {
- EXPECT_EQ(0u, page_cloud_.received_commits.size());
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.size());
- backlog_downloaded_called = true;
- });
- bool called;
- page_sync_->SetOnIdle(callback::SetWhenCalled(&called));
- StartPageSync();
-
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_TRUE(backlog_downloaded_called);
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("local1", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("local2", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content2", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- ASSERT_EQ(2u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("local1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("local2"));
-}
-
-// Verifies that existing commits are uploaded before the new ones.
-TEST_F(PageSyncImplTest, UploadExistingAndNewCommits) {
- storage_.NewCommit("id1", "content1");
-
- page_sync_->SetOnBacklogDownloaded([this] {
- async::PostTask(dispatcher(), [this] {
- auto commit = storage_.NewCommit("id2", "content2");
- storage_.new_commits_to_return["id2"] = commit->Clone();
- storage_.watcher_->OnNewCommits(commit->AsList(),
- storage::ChangeSource::LOCAL);
- });
- });
- bool called;
- page_sync_->SetOnIdle(callback::SetWhenCalled(&called));
-
- StartPageSync();
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("id1", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("id2", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content2", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- EXPECT_EQ(2u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id2"));
-}
-
-// Verifies that the on idle callback is called when there is no pending upload
-// tasks.
-TEST_F(PageSyncImplTest, UploadIdleCallback) {
- int on_idle_calls = 0;
-
- storage_.NewCommit("id1", "content1");
- storage_.NewCommit("id2", "content2");
-
- page_sync_->SetOnIdle([&on_idle_calls] { on_idle_calls++; });
- StartPageSync();
-
- // Verify that the idle callback is called once both commits are uploaded.
- RunLoopUntilIdle();
- EXPECT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ(1, on_idle_calls);
- EXPECT_TRUE(page_sync_->IsIdle());
-
- // Notify about a new commit to upload and verify that the idle callback was
- // called again on completion.
- auto commit3 = storage_.NewCommit("id3", "content3");
- storage_.new_commits_to_return["id3"] = commit3->Clone();
- storage_.watcher_->OnNewCommits(commit3->AsList(),
- storage::ChangeSource::LOCAL);
- EXPECT_FALSE(page_sync_->IsIdle());
- RunLoopUntilIdle();
- EXPECT_EQ(3u, page_cloud_.received_commits.size());
- EXPECT_EQ(2, on_idle_calls);
- EXPECT_TRUE(page_sync_->IsIdle());
-}
-
-// Verifies that a failure to persist the remote commit stops syncing remote
-// commits and calls the error callback.
-TEST_F(PageSyncImplTest, FailToStoreRemoteCommit) {
- bool called;
- page_sync_->SetOnIdle(callback::SetWhenCalled(&called));
- int error_callback_calls = 0;
- page_sync_->SetOnUnrecoverableError(
- [&error_callback_calls] { error_callback_calls++; });
- StartPageSync();
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- ASSERT_TRUE(page_cloud_.set_watcher.is_bound());
-
- auto commit_pack =
- MakeTestCommitPack(&encryption_service_, {{"id1", "content1"}});
- ASSERT_TRUE(commit_pack);
- storage_.should_fail_add_commit_from_sync = true;
- EXPECT_EQ(0, error_callback_calls);
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("42"), [] {});
-
- RunLoopUntilIdle();
- EXPECT_FALSE(page_cloud_.set_watcher.is_bound());
- EXPECT_EQ(1, error_callback_calls);
-}
-
-// Verifies that the on idle callback is called when there is no download in
-// progress.
-TEST_F(PageSyncImplTest, DownloadIdleCallback) {
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id1", "content1"));
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "id2", "content2"));
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("43"));
-
- int on_idle_calls = 0;
- page_sync_->SetOnIdle([&on_idle_calls] { on_idle_calls++; });
- StartPageSync();
- EXPECT_EQ(0, on_idle_calls);
- EXPECT_FALSE(page_sync_->IsIdle());
-
- // Run the message loop and verify that the sync is idle after all remote
- // commits are added to storage.
- RunLoopUntilIdle();
- EXPECT_EQ(1, on_idle_calls);
- EXPECT_TRUE(page_sync_->IsIdle());
- EXPECT_EQ(2u, storage_.received_commits.size());
-
- // Notify about a new commit to download and verify that the idle callback was
- // called again on completion.
- auto commit_pack =
- MakeTestCommitPack(&encryption_service_, {{"id3", "content3"}});
- ASSERT_TRUE(commit_pack);
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("44"), [] {});
- RunLoopUntilIdle();
- EXPECT_EQ(3u, storage_.received_commits.size());
- EXPECT_EQ(2, on_idle_calls);
- EXPECT_TRUE(page_sync_->IsIdle());
-}
-
-// Verifies that uploads are paused until EnableUpload is called.
-TEST_F(PageSyncImplTest, UploadIsPaused) {
- storage_.NewCommit("id1", "content1");
- storage_.NewCommit("id2", "content2");
- bool called;
- page_sync_->SetOnIdle(callback::SetWhenCalled(&called));
-
- StartPageSync(UploadStatus::DISABLED);
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- ASSERT_EQ(0u, page_cloud_.received_commits.size());
-
- page_sync_->EnableUpload();
- RunLoopUntilIdle();
-
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
-}
-
-// Merge commits are deterministic, so can already be in the cloud when we try
-// to upload it. The upload will then fail. However, we should stop retrying to
-// upload the commit once we received a notification for it through the cloud
-// sync watcher.
-TEST_F(PageSyncImplTest, UploadCommitAlreadyInCloud) {
- // Complete the initial sync.
- StartPageSync();
- RunLoopUntilIdle();
- EXPECT_EQ(1u, page_cloud_.get_commits_calls);
-
- // Create a local commit, but make the upload fail.
- page_cloud_.commit_status_to_return = cloud_provider::Status::SERVER_ERROR;
- auto commit1 = storage_.NewCommit("id1", "content1");
- storage_.new_commits_to_return["id1"] = commit1->Clone();
- storage_.watcher_->OnNewCommits(commit1->AsList(),
- storage::ChangeSource::LOCAL);
-
- // We need to wait for the callback to be executed on the PageSync side.
- RunLoopUntilIdle();
- EXPECT_EQ(1u, page_cloud_.add_commits_calls);
- EXPECT_EQ(1, upload_backoff_ptr_->get_next_count);
-
- // Verify that the commit is still not marked as synced in storage.
- EXPECT_TRUE(storage_.commits_marked_as_synced.empty());
-
- // Let's receive the same commit from the remote side.
- auto commit_pack =
- MakeTestCommitPack(&encryption_service_, {{"id1", "content1"}});
- ASSERT_TRUE(commit_pack);
- page_cloud_.set_watcher->OnNewCommits(std::move(*commit_pack),
- MakeToken("44"), [] {});
- RunLoopUntilIdle();
- EXPECT_TRUE(page_sync_->IsIdle());
-
- // No additional calls.
- EXPECT_EQ(1u, page_cloud_.add_commits_calls);
- EXPECT_TRUE(page_sync_->IsIdle());
-}
-
-TEST_F(PageSyncImplTest, UnrecoverableError) {
- int on_error_calls = 0;
- page_sync_->SetOnUnrecoverableError([&on_error_calls] { on_error_calls++; });
- // Complete the initial sync.
- StartPageSync();
- RunLoopUntilIdle();
- EXPECT_EQ(0, on_error_calls);
-
- page_cloud_.Unbind();
- RunLoopUntilIdle();
- EXPECT_EQ(1, on_error_calls);
-}
-
-} // namespace
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/page_upload.cc b/bin/ledger/cloud_sync/impl/page_upload.cc
deleted file mode 100644
index 222d54e..0000000
--- a/bin/ledger/cloud_sync/impl/page_upload.cc
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/page_upload.h"
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/fit/function.h>
-
-namespace cloud_sync {
-
-PageUpload::PageUpload(callback::ScopedTaskRunner* task_runner,
- storage::PageStorage* storage,
- encryption::EncryptionService* encryption_service,
- cloud_provider::PageCloudPtr* page_cloud,
- Delegate* delegate,
- std::unique_ptr<backoff::Backoff> backoff)
- : task_runner_(task_runner),
- storage_(storage),
- encryption_service_(encryption_service),
- page_cloud_(page_cloud),
- delegate_(delegate),
- log_prefix_("Page " + convert::ToHex(storage->GetId()) +
- " upload sync: "),
- backoff_(std::move(backoff)),
- weak_ptr_factory_(this) {}
-
-PageUpload::~PageUpload() {}
-
-void PageUpload::StartOrRestartUpload() {
- if (external_state_ == UPLOAD_NOT_STARTED) {
- // When called for the first time, this method is responsible for handling
- // the initial setup.
- SetState(UPLOAD_SETUP);
- // Starting to watch right away is not an issue, because new commit
- // notifications are used as a tickle only, and we use a separate call to
- // get unsynced commits.
- storage_->AddCommitWatcher(this);
- }
- // Whether called for the first time or to restart upload, prime the upload
- // process.
- NextState();
-}
-
-void PageUpload::OnNewCommits(
- const std::vector<std::unique_ptr<const storage::Commit>>& /*commits*/,
- storage::ChangeSource source) {
- // Only upload the locally created commits.
- // TODO(ppi): revisit this when we have p2p sync, too.
- if (source != storage::ChangeSource::LOCAL) {
- return;
- }
-
- if (external_state_ == UPLOAD_TEMPORARY_ERROR) {
- // Upload is already scheduled to retry uploading. No need to do anything
- // here.
- return;
- }
- NextState();
-}
-
-void PageUpload::UploadUnsyncedCommits() {
- FXL_DCHECK(internal_state_ == PageUploadState::PROCESSING);
-
- if (!delegate_->IsDownloadIdle()) {
- // If a commit batch is currently being downloaded, don't try to start the
- // upload.
- SetState(UPLOAD_WAIT_REMOTE_DOWNLOAD);
- PreviousState();
- return;
- }
-
- SetState(UPLOAD_PENDING);
-
- // Retrieve the of the existing unsynced commits and enqueue them for
- // upload.
- // TODO(ppi): either switch to a paginating API or (better?) ensure that long
- // backlogs of local commits are squashed in storage, as otherwise the list of
- // commits can be possibly very big.
- storage_->GetUnsyncedCommits(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this](storage::Status status,
- std::vector<std::unique_ptr<const storage::Commit>> commits) {
- if (status != storage::Status::OK) {
- SetState(UPLOAD_PERMANENT_ERROR);
- HandleError("Failed to retrieve the unsynced commits");
- return;
- }
-
- VerifyUnsyncedCommits(std::move(commits));
- }));
-}
-
-void PageUpload::VerifyUnsyncedCommits(
- std::vector<std::unique_ptr<const storage::Commit>> commits) {
- // If we have no commit to upload, skip.
- if (commits.empty()) {
- SetState(UPLOAD_IDLE);
- PreviousState();
- return;
- }
-
- storage_->GetHeadCommitIds(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this, commits = std::move(commits)](
- storage::Status status,
- std::vector<storage::CommitId> heads) mutable {
- if (status != storage::Status::OK) {
- HandleError("Failed to retrieve the current heads");
- return;
- }
-
- FXL_DCHECK(!heads.empty());
-
- if (!delegate_->IsDownloadIdle()) {
- // If a commit batch is currently being downloaded, don't try to start
- // the upload.
- SetState(UPLOAD_WAIT_REMOTE_DOWNLOAD);
- PreviousState();
- return;
- }
-
- if (heads.size() > 1u) {
- // Too many local heads.
- SetState(UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS);
- PreviousState();
- return;
- }
-
- HandleUnsyncedCommits(std::move(commits));
- }));
-}
-
-void PageUpload::HandleUnsyncedCommits(
- std::vector<std::unique_ptr<const storage::Commit>> commits) {
- FXL_DCHECK(!batch_upload_);
- SetState(UPLOAD_IN_PROGRESS);
- batch_upload_ = std::make_unique<BatchUpload>(
- storage_, encryption_service_, page_cloud_, std::move(commits),
- [this] {
- // Upload succeeded, reset the backoff delay.
- backoff_->Reset();
- batch_upload_.reset();
- PreviousState();
- },
- [this](BatchUpload::ErrorType error_type) {
- switch (error_type) {
- case BatchUpload::ErrorType::TEMPORARY: {
- FXL_LOG(WARNING)
- << log_prefix_
- << "commit upload failed due to a connection error, retrying.";
- SetState(UPLOAD_TEMPORARY_ERROR);
- batch_upload_.reset();
- PreviousState();
- RetryWithBackoff([this] { NextState(); });
- } break;
- case BatchUpload::ErrorType::PERMANENT: {
- FXL_LOG(WARNING) << log_prefix_
- << "commit upload failed with a permanent error.";
- SetState(UPLOAD_PERMANENT_ERROR);
- } break;
- }
- });
- batch_upload_->Start();
-}
-
-void PageUpload::HandleError(const char error_description[]) {
- FXL_LOG(ERROR) << log_prefix_ << error_description << " Stopping sync.";
- if (external_state_ > UPLOAD_SETUP) {
- storage_->RemoveCommitWatcher(this);
- }
- SetState(UPLOAD_PERMANENT_ERROR);
-}
-
-void PageUpload::RetryWithBackoff(fit::closure callable) {
- task_runner_->PostDelayedTask(
- [this, callable = std::move(callable)]() {
- if (this->external_state_ != UPLOAD_PERMANENT_ERROR) {
- callable();
- }
- },
- backoff_->GetNext());
-}
-
-void PageUpload::SetState(UploadSyncState new_state) {
- if (new_state == external_state_) {
- return;
- }
- external_state_ = new_state;
- // Posting to the run loop to handle the case where the delegate will delete
- // this class in the SetUploadState method.
- // TODO(qsr): Aggregate changed state, so that a change from A -> B -> A do
- // not send any signal.
- task_runner_->PostTask(
- [this] { delegate_->SetUploadState(external_state_); });
-}
-
-bool PageUpload::IsIdle() {
- switch (external_state_) {
- case UPLOAD_NOT_STARTED:
- case UPLOAD_IDLE:
- // Note: this is considered idle because the reason for being blocked is
- // external to the class - there's nothing to do on our side.
- case UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS:
- case UPLOAD_PERMANENT_ERROR:
- return true;
- break;
- case UPLOAD_SETUP:
- case UPLOAD_PENDING:
- case UPLOAD_WAIT_REMOTE_DOWNLOAD:
- case UPLOAD_TEMPORARY_ERROR:
- case UPLOAD_IN_PROGRESS:
- return false;
- break;
- }
-}
-
-void PageUpload::NextState() {
- switch (internal_state_) {
- case PageUploadState::NO_COMMIT:
- internal_state_ = PageUploadState::PROCESSING;
- UploadUnsyncedCommits();
- return;
- case PageUploadState::PROCESSING:
- case PageUploadState::PROCESSING_NEW_COMMIT:
- internal_state_ = PageUploadState::PROCESSING_NEW_COMMIT;
- return;
- }
-}
-
-void PageUpload::PreviousState() {
- switch (internal_state_) {
- case PageUploadState::NO_COMMIT:
- FXL_NOTREACHED() << "Bad state";
- case PageUploadState::PROCESSING:
- internal_state_ = PageUploadState::NO_COMMIT;
- if (external_state_ == UPLOAD_IN_PROGRESS) {
- SetState(UPLOAD_IDLE);
- }
- return;
- case PageUploadState::PROCESSING_NEW_COMMIT:
- internal_state_ = PageUploadState::PROCESSING;
- UploadUnsyncedCommits();
- return;
- }
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/page_upload.h b/bin/ledger/cloud_sync/impl/page_upload.h
deleted file mode 100644
index b392a36..0000000
--- a/bin/ledger/cloud_sync/impl/page_upload.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_UPLOAD_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_UPLOAD_H_
-
-#include <memory>
-#include <vector>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/backoff/backoff.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/batch_upload.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/commit_watcher.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace cloud_sync {
-// Internal state of PageUpload.
-// This ensures there is only one stream of work at any given time, and one in
-// "backlog".
-enum PageUploadState {
- // No upload attempt is in progress.
- NO_COMMIT = 0,
- // An upload attempt is in progress and after completing we should become
- // idle.
- PROCESSING,
- // An upload attempt is in progress and after completing we should start a new
- // one.
- PROCESSING_NEW_COMMIT,
-};
-
-// PageUpload handles all the upload operations for a page.
-class PageUpload : public storage::CommitWatcher {
- public:
- // Delegate ensuring coordination between PageUpload and the class that owns
- // it.
- class Delegate {
- public:
- // Reports that the upload state changed.
- virtual void SetUploadState(UploadSyncState sync_state) = 0;
-
- // Returns true if no download is in progress.
- virtual bool IsDownloadIdle() = 0;
- };
-
- PageUpload(callback::ScopedTaskRunner* task_runner,
- storage::PageStorage* storage,
- encryption::EncryptionService* encryption_service,
- cloud_provider::PageCloudPtr* page_cloud, Delegate* delegate,
- std::unique_ptr<backoff::Backoff> backoff);
-
- ~PageUpload() override;
-
- // Starts or restarts the upload process.
- //
- // The first time this method is called this sets up the storage watcher. It
- // might be called again in the future to restart the upload after it's
- // stopped due to a remote download in progress.
- void StartOrRestartUpload();
-
- // Returns true if PageUpload is idle.
- bool IsIdle();
-
- private:
- // storage::CommitWatcher:
- void OnNewCommits(
- const std::vector<std::unique_ptr<const storage::Commit>>& /*commits*/,
- storage::ChangeSource source) override;
-
- void UploadUnsyncedCommits();
- void VerifyUnsyncedCommits(
- std::vector<std::unique_ptr<const storage::Commit>> commits);
- void HandleUnsyncedCommits(
- std::vector<std::unique_ptr<const storage::Commit>> commits);
-
- // Sets the internal state.
- void SetState(UploadSyncState new_state);
-
- void HandleError(const char error_description[]);
-
- void RetryWithBackoff(fit::closure callable);
-
- // These methods manage the internal state machine.
-
- // Registers a signal to trigger an upload attempt, and triggers it if
- // appropriate, that is, if we don't have an upload process already in
- // progress.
- void NextState();
-
- // Registers completion of an upload attempt, for example due to an error, or
- // because it completed. This will trigger another upload attempt if
- // appropriate, that is, if a signal to trigger an upload attempt was
- // delivered while an earlier upload attempt was in progress.
- void PreviousState();
-
- // Owned by whoever owns this class.
- callback::ScopedTaskRunner* const task_runner_;
- storage::PageStorage* const storage_;
- encryption::EncryptionService* const encryption_service_;
- cloud_provider::PageCloudPtr* const page_cloud_;
- Delegate* const delegate_;
- const std::string log_prefix_;
-
- std::unique_ptr<backoff::Backoff> backoff_;
-
- // Work queue:
- // Current batch of local commits being uploaded.
- std::unique_ptr<BatchUpload> batch_upload_;
- // Internal state.
- PageUploadState internal_state_ = PageUploadState::NO_COMMIT;
-
- // External state.
- UploadSyncState external_state_ = UPLOAD_NOT_STARTED;
-
- // Must be the last member.
- fxl::WeakPtrFactory<PageUpload> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageUpload);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_PAGE_UPLOAD_H_
diff --git a/bin/ledger/cloud_sync/impl/page_upload_unittest.cc b/bin/ledger/cloud_sync/impl/page_upload_unittest.cc
deleted file mode 100644
index a17e586..0000000
--- a/bin/ledger/cloud_sync/impl/page_upload_unittest.cc
+++ /dev/null
@@ -1,517 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/page_upload.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include <lib/backoff/backoff.h>
-#include <lib/backoff/testing/test_backoff.h>
-#include <lib/callback/capture.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/constants.h"
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h"
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_storage.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-namespace cloud_sync {
-namespace {
-
-constexpr zx::duration kBackoffInterval = zx::msec(10);
-constexpr zx::duration kHalfBackoffInterval = zx::msec(5);
-
-// Creates a dummy continuation token.
-cloud_provider::Token MakeToken(convert::ExtendedStringView token_id) {
- cloud_provider::Token token;
- token.opaque_id = convert::ToArray(token_id);
- return token;
-}
-
-class PageUploadTest : public gtest::TestLoopFixture,
- public PageUpload::Delegate {
- public:
- PageUploadTest()
- : storage_(dispatcher()),
- encryption_service_(dispatcher()),
- page_cloud_(page_cloud_ptr_.NewRequest()),
- task_runner_(dispatcher()) {
- auto test_backoff =
- std::make_unique<backoff::TestBackoff>(kBackoffInterval);
- backoff_ = test_backoff.get();
- page_upload_ = std::make_unique<PageUpload>(
- &task_runner_, &storage_, &encryption_service_, &page_cloud_ptr_, this,
- std::move(test_backoff));
- }
- ~PageUploadTest() override {}
-
- protected:
- void SetOnNewStateCallback(fit::closure callback) {
- new_state_callback_ = std::move(callback);
- }
-
- void SetUploadState(UploadSyncState sync_state) override {
- states_.push_back(sync_state);
- if (new_state_callback_) {
- new_state_callback_();
- }
- }
-
- bool IsDownloadIdle() override { return is_download_idle_; }
-
- TestPageStorage storage_;
- encryption::FakeEncryptionService encryption_service_;
- cloud_provider::PageCloudPtr page_cloud_ptr_;
- TestPageCloud page_cloud_;
- std::vector<UploadSyncState> states_;
- std::unique_ptr<PageUpload> page_upload_;
- backoff::TestBackoff* backoff_;
- bool is_download_idle_ = true;
-
- private:
- fit::closure new_state_callback_;
- callback::ScopedTaskRunner task_runner_;
- FXL_DISALLOW_COPY_AND_ASSIGN(PageUploadTest);
-};
-
-// Verifies that the backlog of commits to upload returned from
-// GetUnsyncedCommits() is uploaded to PageCloudHandler.
-TEST_F(PageUploadTest, UploadBacklog) {
- storage_.NewCommit("id1", "content1");
- storage_.NewCommit("id2", "content2");
- bool upload_is_idle = false;
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- page_upload_->StartOrRestartUpload();
-
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
-
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("id1", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("id2", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content2", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- EXPECT_EQ(2u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id2"));
-}
-
-// Verifies that the backlog of commits to upload is not uploaded until there's
-// only one local head.
-TEST_F(PageUploadTest, UploadBacklogOnlyOnSingleHead) {
- // Verify that two local commits are not uploaded when there is two local
- // heads.
- bool upload_is_idle = false;
- storage_.head_count = 2;
- storage_.NewCommit("id0", "content0");
- storage_.NewCommit("id1", "content1");
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- page_upload_->StartOrRestartUpload();
-
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- EXPECT_EQ(0u, page_cloud_.received_commits.size());
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.size());
-
- // Add a new commit and reduce the number of heads to 1.
- upload_is_idle = false;
- storage_.head_count = 1;
- auto commit = storage_.NewCommit("id2", "content2");
- storage_.new_commits_to_return["id2"] = commit->Clone();
- storage_.watcher_->OnNewCommits(commit->AsList(),
- storage::ChangeSource::LOCAL);
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
-
- // Verify that all local commits were uploaded.
- ASSERT_EQ(3u, page_cloud_.received_commits.size());
- EXPECT_EQ("id0", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content0", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("id1", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- EXPECT_EQ("id2", page_cloud_.received_commits[2].id);
- EXPECT_EQ("content2", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[2].data));
- EXPECT_EQ(3u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id0"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id2"));
-}
-
-TEST_F(PageUploadTest, UploadExistingCommitsOnlyAfterBacklogDownload) {
- // Verify that two local commits are not uploaded when download is in
- // progress.
- storage_.NewCommit("local1", "content1");
- storage_.NewCommit("local2", "content2");
-
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "remote3", "content3"));
- page_cloud_.commits_to_return.push_back(
- MakeTestCommit(&encryption_service_, "remote4", "content4"));
- page_cloud_.position_token_to_return = fidl::MakeOptional(MakeToken("44"));
-
- is_download_idle_ = false;
- bool upload_wait_remote_download = false;
- SetOnNewStateCallback([this, &upload_wait_remote_download] {
- if (states_.back() == UPLOAD_WAIT_REMOTE_DOWNLOAD) {
- upload_wait_remote_download = true;
- }
- });
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_wait_remote_download);
-
- EXPECT_EQ(0u, page_cloud_.received_commits.size());
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.size());
-
- is_download_idle_ = true;
- bool upload_is_idle = false;
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
-
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("local1", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("local2", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content2", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- ASSERT_EQ(2u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("local1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("local2"));
-}
-
-// Verfies that the new commits that PageSync is notified about through storage
-// watcher are uploaded to PageCloudHandler, with the exception of commits that
-// themselves come from sync.
-TEST_F(PageUploadTest, UploadNewCommits) {
- bool upload_is_idle = false;
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- upload_is_idle = false;
-
- auto commit1 = storage_.NewCommit("id1", "content1");
- storage_.new_commits_to_return["id1"] = commit1->Clone();
- storage_.watcher_->OnNewCommits(commit1->AsList(),
- storage::ChangeSource::LOCAL);
-
- // The commit coming from sync should be ignored.
- auto commit2 = storage_.NewCommit("id2", "content2", false);
- storage_.new_commits_to_return["id2"] = commit2->Clone();
- storage_.watcher_->OnNewCommits(commit2->AsList(),
- storage::ChangeSource::CLOUD);
-
- auto commit3 = storage_.NewCommit("id3", "content3");
- storage_.new_commits_to_return["id3"] = commit3->Clone();
- storage_.watcher_->OnNewCommits(commit3->AsList(),
- storage::ChangeSource::LOCAL);
-
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
-
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("id1", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("id3", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content3", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- EXPECT_EQ(2u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id3"));
-}
-
-// Verifies that new commits being added to storage are only uploaded while
-// there is only a single head.
-TEST_F(PageUploadTest, UploadNewCommitsOnlyOnSingleHead) {
- bool upload_is_idle = false;
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- upload_is_idle = false;
-
- // Add a new commit when there's only one head and verify that it is
- // uploaded.
- storage_.head_count = 1;
- auto commit0 = storage_.NewCommit("id0", "content0");
- storage_.new_commits_to_return["id0"] = commit0->Clone();
- storage_.watcher_->OnNewCommits(commit0->AsList(),
- storage::ChangeSource::LOCAL);
- EXPECT_FALSE(page_upload_->IsIdle());
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- upload_is_idle = false;
- ASSERT_EQ(1u, page_cloud_.received_commits.size());
- EXPECT_EQ("id0", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content0", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id0"));
-
- // Add another commit when there's two heads and verify that it is not
- // uploaded.
- page_cloud_.received_commits.clear();
- storage_.head_count = 2;
- auto commit1 = storage_.NewCommit("id1", "content1");
- storage_.new_commits_to_return["id1"] = commit1->Clone();
- storage_.watcher_->OnNewCommits(commit1->AsList(),
- storage::ChangeSource::LOCAL);
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- upload_is_idle = false;
- ASSERT_EQ(0u, page_cloud_.received_commits.size());
- EXPECT_EQ(0u, storage_.commits_marked_as_synced.count("id1"));
-
- // Add another commit bringing the number of heads down to one and verify that
- // both commits are uploaded.
- storage_.head_count = 1;
- auto commit2 = storage_.NewCommit("id2", "content2");
- storage_.new_commits_to_return["id2"] = commit2->Clone();
- storage_.watcher_->OnNewCommits(commit2->AsList(),
- storage::ChangeSource::LOCAL);
- EXPECT_FALSE(page_upload_->IsIdle());
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("id1", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("id2", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content2", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id2"));
-}
-
-// Verifies that existing commits are uploaded before the new ones.
-TEST_F(PageUploadTest, UploadExistingAndNewCommits) {
- storage_.NewCommit("id1", "content1");
- bool upload_is_idle = false;
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- upload_is_idle = false;
-
- auto commit = storage_.NewCommit("id2", "content2");
- storage_.new_commits_to_return["id2"] = commit->Clone();
- storage_.watcher_->OnNewCommits(commit->AsList(),
- storage::ChangeSource::LOCAL);
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
-
- ASSERT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ("id1", page_cloud_.received_commits[0].id);
- EXPECT_EQ("content1", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[0].data));
- EXPECT_EQ("id2", page_cloud_.received_commits[1].id);
- EXPECT_EQ("content2", encryption_service_.DecryptCommitSynchronous(
- page_cloud_.received_commits[1].data));
- EXPECT_EQ(2u, storage_.commits_marked_as_synced.size());
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id1"));
- EXPECT_EQ(1u, storage_.commits_marked_as_synced.count("id2"));
-}
-
-// Verifies that failing uploads are retried.
-TEST_F(PageUploadTest, RetryUpload) {
- page_upload_->StartOrRestartUpload();
- bool upload_is_idle = false;
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- SetOnNewStateCallback(nullptr);
-
- page_cloud_.commit_status_to_return = cloud_provider::Status::NETWORK_ERROR;
- auto commit1 = storage_.NewCommit("id1", "content1");
- storage_.new_commits_to_return["id1"] = commit1->Clone();
- storage_.watcher_->OnNewCommits(commit1->AsList(),
- storage::ChangeSource::LOCAL);
- RunLoopFor(kHalfBackoffInterval);
- EXPECT_GE(backoff_->get_next_count, 0);
- RunLoopFor(kBackoffInterval);
- EXPECT_GE(backoff_->get_next_count, 1);
- RunLoopFor(kBackoffInterval);
- EXPECT_GE(backoff_->get_next_count, 2);
-
- // Verify that the commit is still not marked as synced in storage.
- EXPECT_TRUE(storage_.commits_marked_as_synced.empty());
-}
-
-// Verifies that the idle status is returned when there is no pending upload
-// task.
-TEST_F(PageUploadTest, UploadIdleStatus) {
- int on_idle_calls = 0;
-
- storage_.NewCommit("id1", "content1");
- storage_.NewCommit("id2", "content2");
-
- SetOnNewStateCallback([this, &on_idle_calls] {
- if (states_.back() == UPLOAD_IDLE) {
- on_idle_calls++;
- }
- });
- page_upload_->StartOrRestartUpload();
-
- // Verify that the idle callback is called once both commits are uploaded.
- RunLoopUntilIdle();
- EXPECT_EQ(2u, page_cloud_.received_commits.size());
- EXPECT_EQ(1, on_idle_calls);
- EXPECT_TRUE(page_upload_->IsIdle());
-
- // Notify about a new commit to upload and verify that the idle callback was
- // called again on completion.
- auto commit3 = storage_.NewCommit("id3", "content3");
- storage_.new_commits_to_return["id3"] = commit3->Clone();
- storage_.watcher_->OnNewCommits(commit3->AsList(),
- storage::ChangeSource::LOCAL);
- EXPECT_FALSE(page_upload_->IsIdle());
- RunLoopUntilIdle();
- EXPECT_EQ(3u, page_cloud_.received_commits.size());
- EXPECT_EQ(2, on_idle_calls);
- EXPECT_TRUE(page_upload_->IsIdle());
-}
-
-// Verifies that if listing the original commits to be uploaded fails, the
-// client is notified about the error.
-TEST_F(PageUploadTest, FailToListCommits) {
- EXPECT_FALSE(storage_.watcher_set);
- int error_calls = 0;
- storage_.should_fail_get_unsynced_commits = true;
- SetOnNewStateCallback([this, &error_calls] {
- if (states_.back() == UPLOAD_PERMANENT_ERROR) {
- error_calls++;
- }
- });
-
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- EXPECT_EQ(1, error_calls);
- EXPECT_EQ(0u, page_cloud_.received_commits.size());
-}
-
-// Verifies that already synced commits are not re-uploaded.
-TEST_F(PageUploadTest, DoNotUploadSyncedCommits) {
- bool upload_is_idle = false;
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- upload_is_idle = false;
-
- auto commit = std::make_unique<TestCommit>("id", "content");
- storage_.new_commits_to_return["id"] = commit->Clone();
- storage_.watcher_->OnNewCommits(commit->AsList(),
- storage::ChangeSource::LOCAL);
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
-
- // Commit is already synced.
- ASSERT_EQ(0u, page_cloud_.received_commits.size());
-}
-
-// Verifies that commits that are received between the first upload and the
-// retry are not sent.
-TEST_F(PageUploadTest, DoNotUploadSyncedCommitsOnRetry) {
- bool upload_is_idle = false;
- SetOnNewStateCallback([this, &upload_is_idle] {
- upload_is_idle = page_upload_->IsIdle();
- if (states_.back() == UploadSyncState::UPLOAD_TEMPORARY_ERROR) {
- QuitLoop();
- }
- });
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- upload_is_idle = false;
-
- page_cloud_.commit_status_to_return = cloud_provider::Status::NETWORK_ERROR;
-
- auto commit = storage_.NewCommit("id", "content");
- storage_.new_commits_to_return["id"] = commit->Clone();
- storage_.watcher_->OnNewCommits(commit->AsList(),
- storage::ChangeSource::LOCAL);
-
- // The page upload should run into temporary error.
- RunLoopUntilIdle();
- EXPECT_EQ(UploadSyncState::UPLOAD_TEMPORARY_ERROR, states_.back());
- EXPECT_GT(page_cloud_.add_commits_calls, 0u);
-
- // Configure the cloud to accept the next attempt to upload.
- page_cloud_.commit_status_to_return = cloud_provider::Status::OK;
- page_cloud_.add_commits_calls = 0u;
-
- // Make storage report the commit as synced (not include it in the list of
- // unsynced commits to return).
- storage_.unsynced_commits_to_return.clear();
-
- RunLoopFor(kHalfBackoffInterval);
- ASSERT_FALSE(upload_is_idle);
- RunLoopFor(kBackoffInterval);
- ASSERT_TRUE(upload_is_idle);
-
- // Verify that no calls were made to attempt to upload the commit.
- EXPECT_EQ(0u, page_cloud_.add_commits_calls);
-}
-
-// Verifies that concurrent new commit notifications do not crash PageUpload.
-TEST_F(PageUploadTest, UploadNewCommitsConcurrentNoCrash) {
- bool upload_is_idle = false;
- SetOnNewStateCallback(
- [this, &upload_is_idle] { upload_is_idle = page_upload_->IsIdle(); });
- page_upload_->StartOrRestartUpload();
- RunLoopUntilIdle();
- ASSERT_TRUE(upload_is_idle);
- upload_is_idle = false;
-
- storage_.head_count = 2;
- storage_.should_delay_get_head_commit_ids = true;
- auto commit0 = storage_.NewCommit("id0", "content0");
- storage_.new_commits_to_return["id0"] = commit0->Clone();
- storage_.watcher_->OnNewCommits(commit0->AsList(),
- storage::ChangeSource::LOCAL);
- RunLoopUntilIdle();
-
- auto commit1 = storage_.NewCommit("id1", "content1");
- storage_.new_commits_to_return["id1"] = commit1->Clone();
- storage_.watcher_->OnNewCommits(commit1->AsList(),
- storage::ChangeSource::LOCAL);
- RunLoopUntilIdle();
- ASSERT_EQ(1u, storage_.delayed_get_head_commit_ids.size());
- storage_.head_count = 1;
- storage_.delayed_get_head_commit_ids[0]();
- RunLoopUntilIdle();
-
- ASSERT_EQ(2u, storage_.delayed_get_head_commit_ids.size());
- storage_.delayed_get_head_commit_ids[1]();
- RunLoopUntilIdle();
-}
-
-} // namespace
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/testing/BUILD.gn b/bin/ledger/cloud_sync/impl/testing/BUILD.gn
deleted file mode 100644
index 50007ee..0000000
--- a/bin/ledger/cloud_sync/impl/testing/BUILD.gn
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "test_cloud_provider.cc",
- "test_cloud_provider.h",
- "test_commit.cc",
- "test_commit.h",
- "test_device_set.cc",
- "test_device_set.h",
- "test_page_cloud.cc",
- "test_page_cloud.h",
- "test_page_storage.cc",
- "test_page_storage.h",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/cloud_sync/public",
- "//peridot/bin/ledger/encryption/fake",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/storage/testing",
- "//peridot/lib/commit_pack",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fsl",
- "//zircon/public/lib/trace",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/cloud_sync/impl/testing/test_cloud_provider.cc b/bin/ledger/cloud_sync/impl/testing/test_cloud_provider.cc
deleted file mode 100644
index f94646c..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_cloud_provider.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_cloud_provider.h"
-
-#include <lib/fxl/logging.h>
-
-namespace cloud_sync {
-
-TestCloudProvider::TestCloudProvider(
- fidl::InterfaceRequest<cloud_provider::CloudProvider> request)
- : binding_(this, std::move(request)), device_set_binding_(&device_set) {}
-
-TestCloudProvider::~TestCloudProvider() {}
-
-void TestCloudProvider::GetDeviceSet(
- fidl::InterfaceRequest<cloud_provider::DeviceSet> request,
- GetDeviceSetCallback callback) {
- device_set_binding_.Bind(std::move(request));
- callback(cloud_provider::Status::OK);
-}
-
-void TestCloudProvider::GetPageCloud(
- std::vector<uint8_t> /*app_id*/, std::vector<uint8_t> /*page_id*/,
- fidl::InterfaceRequest<cloud_provider::PageCloud> /*page_cloud*/,
- GetPageCloudCallback /*callback*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/testing/test_cloud_provider.h b/bin/ledger/cloud_sync/impl/testing/test_cloud_provider.h
deleted file mode 100644
index d4aa9ac..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_cloud_provider.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_CLOUD_PROVIDER_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_CLOUD_PROVIDER_H_
-
-#include <memory>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_device_set.h"
-
-namespace cloud_sync {
-class TestCloudProvider : public cloud_provider::CloudProvider {
- public:
- explicit TestCloudProvider(
- fidl::InterfaceRequest<cloud_provider::CloudProvider> request);
- ~TestCloudProvider() override;
-
- TestDeviceSet device_set;
-
- private:
- // cloud_provider::CloudProvider:
- void GetDeviceSet(fidl::InterfaceRequest<cloud_provider::DeviceSet> request,
- GetDeviceSetCallback callback) override;
-
- void GetPageCloud(
- std::vector<uint8_t> app_id, std::vector<uint8_t> page_id,
- fidl::InterfaceRequest<cloud_provider::PageCloud> page_cloud,
- GetPageCloudCallback callback) override;
-
- fidl::Binding<cloud_provider::CloudProvider> binding_;
- fidl::Binding<cloud_provider::DeviceSet> device_set_binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestCloudProvider);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_CLOUD_PROVIDER_H_
diff --git a/bin/ledger/cloud_sync/impl/testing/test_commit.cc b/bin/ledger/cloud_sync/impl/testing/test_commit.cc
deleted file mode 100644
index a77057a..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_commit.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_commit.h"
-
-#include <memory>
-#include <vector>
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-
-namespace cloud_sync {
-TestCommit::TestCommit(storage::CommitId id, std::string content)
- : id(std::move(id)), content(std::move(content)) {}
-
-std::vector<std::unique_ptr<const storage::Commit>> TestCommit::AsList() {
- std::vector<std::unique_ptr<const storage::Commit>> result;
- result.push_back(Clone());
- return result;
-}
-
-std::unique_ptr<const storage::Commit> TestCommit::Clone() const {
- return std::make_unique<TestCommit>(id, content);
-}
-
-const storage::CommitId& TestCommit::GetId() const { return id; }
-
-fxl::StringView TestCommit::GetStorageBytes() const { return content; }
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/testing/test_commit.h b/bin/ledger/cloud_sync/impl/testing/test_commit.h
deleted file mode 100644
index 8efa89c..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_commit.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_COMMIT_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_COMMIT_H_
-
-#include <memory>
-#include <vector>
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-
-namespace cloud_sync {
-
-// Fake implementation of storage::Commit.
-class TestCommit : public storage::CommitEmptyImpl {
- public:
- TestCommit() = default;
- TestCommit(storage::CommitId id, std::string content);
- ~TestCommit() override = default;
-
- std::vector<std::unique_ptr<const Commit>> AsList();
-
- std::unique_ptr<const Commit> Clone() const override;
-
- const storage::CommitId& GetId() const override;
-
- fxl::StringView GetStorageBytes() const override;
-
- storage::CommitId id;
- std::string content;
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_COMMIT_H_
diff --git a/bin/ledger/cloud_sync/impl/testing/test_device_set.cc b/bin/ledger/cloud_sync/impl/testing/test_device_set.cc
deleted file mode 100644
index 3bdfadf..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_device_set.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_device_set.h"
-
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_sync {
-
-TestDeviceSet::TestDeviceSet() {}
-TestDeviceSet::~TestDeviceSet() {}
-
-void TestDeviceSet::CheckFingerprint(std::vector<uint8_t> fingerprint,
- CheckFingerprintCallback callback) {
- checked_fingerprint = convert::ToString(fingerprint);
- callback(status_to_return);
-}
-
-void TestDeviceSet::SetFingerprint(std::vector<uint8_t> fingerprint,
- SetFingerprintCallback callback) {
- set_fingerprint = convert::ToString(fingerprint);
- callback(status_to_return);
-}
-
-void TestDeviceSet::SetWatcher(
- std::vector<uint8_t> fingerprint,
- fidl::InterfaceHandle<cloud_provider::DeviceSetWatcher> watcher,
- SetWatcherCallback callback) {
- set_watcher_calls++;
- watched_fingerprint = convert::ToString(fingerprint);
- set_watcher = watcher.Bind();
- if (set_watcher_status_to_return == cloud_provider::Status::NETWORK_ERROR) {
- set_watcher->OnNetworkError();
- }
- callback(set_watcher_status_to_return);
-}
-
-void TestDeviceSet::Erase(EraseCallback callback) {
- callback(status_to_return);
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/testing/test_device_set.h b/bin/ledger/cloud_sync/impl/testing/test_device_set.h
deleted file mode 100644
index 46eef1c..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_device_set.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_DEVICE_SET_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_DEVICE_SET_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace cloud_sync {
-
-class TestDeviceSet : public cloud_provider::DeviceSet {
- public:
- TestDeviceSet();
- ~TestDeviceSet() override;
-
- cloud_provider::Status status_to_return = cloud_provider::Status::OK;
- cloud_provider::Status set_watcher_status_to_return =
- cloud_provider::Status::OK;
- std::string checked_fingerprint;
- std::string set_fingerprint;
-
- int set_watcher_calls = 0;
- std::string watched_fingerprint;
- cloud_provider::DeviceSetWatcherPtr set_watcher;
-
- private:
- // cloud_provider::DeviceSet:
- void CheckFingerprint(std::vector<uint8_t> fingerprint,
- CheckFingerprintCallback callback) override;
-
- void SetFingerprint(std::vector<uint8_t> fingerprint,
- SetFingerprintCallback callback) override;
-
- void SetWatcher(
- std::vector<uint8_t> fingerprint,
- fidl::InterfaceHandle<cloud_provider::DeviceSetWatcher> watcher,
- SetWatcherCallback callback) override;
-
- void Erase(EraseCallback callback) override;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestDeviceSet);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_DEVICE_SET_H_
diff --git a/bin/ledger/cloud_sync/impl/testing/test_page_cloud.cc b/bin/ledger/cloud_sync/impl/testing/test_page_cloud.cc
deleted file mode 100644
index 8dd530f..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_page_cloud.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h"
-
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_sync {
-
-cloud_provider::CommitPackEntry MakeTestCommit(
- encryption::FakeEncryptionService* encryption_service,
- const std::string& id, const std::string& data) {
- cloud_provider::CommitPackEntry commit;
- commit.id = id;
- commit.data = encryption_service->EncryptCommitSynchronous(data);
- return commit;
-}
-
-std::unique_ptr<cloud_provider::CommitPack> MakeTestCommitPack(
- encryption::FakeEncryptionService* encryption_service,
- std::vector<std::tuple<std::string, std::string>> commit_data) {
- std::vector<cloud_provider::CommitPackEntry> entries;
- for (auto& data : commit_data) {
- entries.push_back(MakeTestCommit(encryption_service, std::get<0>(data),
- std::get<1>(data)));
- }
- cloud_provider::CommitPack result;
- if (!cloud_provider::EncodeCommitPack(entries, &result)) {
- return nullptr;
- }
- return fidl::MakeOptional(std::move(result));
-}
-
-TestPageCloud::TestPageCloud(
- fidl::InterfaceRequest<cloud_provider::PageCloud> request)
- : binding_(this, std::move(request)) {}
-TestPageCloud::~TestPageCloud() {}
-
-void TestPageCloud::RunPendingCallbacks() {
- for (auto& callback : pending_add_object_callbacks) {
- callback();
- }
- pending_add_object_callbacks.clear();
-}
-
-// cloud_provider::PageCloud:
-void TestPageCloud::AddCommits(cloud_provider::CommitPack commits,
- AddCommitsCallback callback) {
- std::vector<cloud_provider::CommitPackEntry> entries;
- if (!cloud_provider::DecodeCommitPack(commits, &entries)) {
- callback(cloud_provider::Status::INTERNAL_ERROR);
- return;
- }
-
- add_commits_calls++;
- for (auto& entry : entries) {
- received_commits.push_back(std::move(entry));
- }
- callback(commit_status_to_return);
-}
-
-void TestPageCloud::GetCommits(
- std::unique_ptr<cloud_provider::Token> /*min_position_token*/,
- GetCommitsCallback callback) {
- get_commits_calls++;
- cloud_provider::CommitPack commit_pack;
- if (!cloud_provider::EncodeCommitPack(commits_to_return, &commit_pack)) {
- callback(cloud_provider::Status::INTERNAL_ERROR, nullptr, nullptr);
- return;
- }
- callback(status_to_return, fidl::MakeOptional(std::move(commit_pack)),
- std::move(position_token_to_return));
-}
-
-void TestPageCloud::AddObject(std::vector<uint8_t> id,
- fuchsia::mem::Buffer data,
- AddObjectCallback callback) {
- add_object_calls++;
- std::string received_data;
- if (!fsl::StringFromVmo(data, &received_data)) {
- callback(cloud_provider::Status::INTERNAL_ERROR);
- return;
- }
- received_objects[convert::ToString(id)] = received_data;
- fit::closure report_result = [callback = std::move(callback),
- status = object_status_to_return] {
- callback(status);
- };
- if (delay_add_object_callbacks) {
- pending_add_object_callbacks.push_back(std::move(report_result));
- } else {
- report_result();
- }
-
- if (reset_object_status_after_call) {
- object_status_to_return = cloud_provider::Status::OK;
- }
-}
-
-void TestPageCloud::GetObject(std::vector<uint8_t> id,
- GetObjectCallback callback) {
- get_object_calls++;
- if (status_to_return != cloud_provider::Status::OK) {
- callback(status_to_return, nullptr);
- return;
- }
-
- std::string object_id = convert::ToString(id);
- if (objects_to_return.count(object_id) == 0) {
- callback(cloud_provider::Status::INTERNAL_ERROR, nullptr);
- return;
- }
-
- ::fuchsia::mem::Buffer buffer;
- if (!fsl::VmoFromString(objects_to_return[object_id], &buffer)) {
- callback(cloud_provider::Status::INTERNAL_ERROR, nullptr);
- return;
- }
- callback(status_to_return, fidl::MakeOptional(std::move(buffer)));
-}
-
-void TestPageCloud::SetWatcher(
- std::unique_ptr<cloud_provider::Token> min_position_token,
- fidl::InterfaceHandle<cloud_provider::PageCloudWatcher> watcher,
- SetWatcherCallback callback) {
- set_watcher_position_tokens.push_back(std::move(min_position_token));
- set_watcher = watcher.Bind();
- callback(status_to_return);
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h b/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h
deleted file mode 100644
index 95d55ff..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_page_cloud.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_PAGE_CLOUD_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_PAGE_CLOUD_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-namespace cloud_sync {
-
-struct ReceivedCommit {
- std::string id;
- std::string data;
-};
-
-cloud_provider::CommitPackEntry MakeTestCommit(
- encryption::FakeEncryptionService* encryption_service,
- const std::string& id, const std::string& data);
-
-std::unique_ptr<cloud_provider::CommitPack> MakeTestCommitPack(
- encryption::FakeEncryptionService* encryption_service,
- std::vector<std::tuple<std::string, std::string>> commit_data);
-
-class TestPageCloud : public cloud_provider::PageCloud {
- public:
- explicit TestPageCloud(
- fidl::InterfaceRequest<cloud_provider::PageCloud> request);
- ~TestPageCloud() override;
-
- void RunPendingCallbacks();
- void Unbind() { binding_.Unbind(); }
-
- cloud_provider::Status status_to_return = cloud_provider::Status::OK;
- cloud_provider::Status commit_status_to_return = cloud_provider::Status::OK;
- cloud_provider::Status object_status_to_return = cloud_provider::Status::OK;
-
- // AddCommits().
- unsigned int add_commits_calls = 0u;
- std::vector<cloud_provider::CommitPackEntry> received_commits;
-
- // GetCommits().
- unsigned int get_commits_calls = 0u;
- std::vector<cloud_provider::CommitPackEntry> commits_to_return;
- std::unique_ptr<cloud_provider::Token> position_token_to_return;
-
- // AddObject().
- unsigned int add_object_calls = 0u;
- std::map<std::string, std::string> received_objects;
- bool delay_add_object_callbacks = false;
- std::vector<fit::closure> pending_add_object_callbacks;
- bool reset_object_status_after_call = false;
-
- // GetObject().
- unsigned int get_object_calls = 0u;
- std::map<std::string, std::string> objects_to_return;
-
- // SetWatcher().
- std::vector<std::unique_ptr<cloud_provider::Token>>
- set_watcher_position_tokens;
- cloud_provider::PageCloudWatcherPtr set_watcher;
-
- private:
- // cloud_provider::PageCloud:
- void AddCommits(cloud_provider::CommitPack commits,
- AddCommitsCallback callback) override;
- void GetCommits(std::unique_ptr<cloud_provider::Token> min_position_token,
- GetCommitsCallback callback) override;
- void AddObject(std::vector<uint8_t> id, fuchsia::mem::Buffer data,
- AddObjectCallback callback) override;
- void GetObject(std::vector<uint8_t> id,
- GetObjectCallback callback) override;
- void SetWatcher(
- std::unique_ptr<cloud_provider::Token> min_position_token,
- fidl::InterfaceHandle<cloud_provider::PageCloudWatcher> watcher,
- SetWatcherCallback callback) override;
-
- fidl::Binding<cloud_provider::PageCloud> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestPageCloud);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_PAGE_CLOUD_H_
diff --git a/bin/ledger/cloud_sync/impl/testing/test_page_storage.cc b/bin/ledger/cloud_sync/impl/testing/test_page_storage.cc
deleted file mode 100644
index 4a23989..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_page_storage.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_page_storage.h"
-
-#include <memory>
-#include <set>
-#include <utility>
-#include <vector>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/capture.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-namespace cloud_sync {
-TestPageStorage::TestPageStorage(async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher) {}
-
-std::unique_ptr<TestCommit> TestPageStorage::NewCommit(std::string id,
- std::string content,
- bool unsynced) {
- auto commit = std::make_unique<TestCommit>(std::move(id), std::move(content));
- if (unsynced) {
- unsynced_commits_to_return.push_back(commit->Clone());
- }
- return commit;
-}
-
-storage::PageId TestPageStorage::GetId() { return page_id_to_return; }
-
-void TestPageStorage::SetSyncDelegate(
- storage::PageSyncDelegate* page_sync_delegate) {
- page_sync_delegate_ = page_sync_delegate;
-}
-
-void TestPageStorage::GetHeadCommitIds(
- fit::function<void(storage::Status, std::vector<storage::CommitId>)>
- callback) {
- size_t returned_head_count = head_count;
- auto confirm = [returned_head_count, callback = std::move(callback)] {
- // Current tests only rely on the number of heads, not on the actual
- // ids.
- callback(storage::Status::OK,
- std::vector<storage::CommitId>(returned_head_count));
- };
- if (should_delay_get_head_commit_ids) {
- delayed_get_head_commit_ids.emplace_back(std::move(confirm));
- return;
- }
-
- async::PostTask(dispatcher_, std::move(confirm));
-}
-
-void TestPageStorage::GetCommit(
- storage::CommitIdView commit_id,
- fit::function<void(storage::Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- if (should_fail_get_commit) {
- async::PostTask(dispatcher_, [callback = std::move(callback)] {
- callback(storage::Status::IO_ERROR, nullptr);
- });
- return;
- }
-
- async::PostTask(dispatcher_, [this, commit_id = commit_id.ToString(),
- callback = std::move(callback)] {
- callback(storage::Status::OK, std::move(new_commits_to_return[commit_id]));
- });
- new_commits_to_return.erase(commit_id.ToString());
-}
-
-void TestPageStorage::AddCommitsFromSync(
- std::vector<PageStorage::CommitIdAndBytes> ids_and_bytes,
- storage::ChangeSource /*source*/,
- fit::function<void(storage::Status, std::vector<storage::CommitId>)>
- callback) {
- add_commits_from_sync_calls++;
-
- if (should_fail_add_commit_from_sync) {
- async::PostTask(dispatcher_, [callback = std::move(callback)]() {
- callback(storage::Status::IO_ERROR, {});
- });
- return;
- }
-
- fit::closure confirm = [this, ids_and_bytes = std::move(ids_and_bytes),
- callback = std::move(callback)]() mutable {
- for (auto& commit : ids_and_bytes) {
- received_commits[commit.id] = std::move(commit.bytes);
- unsynced_commits_to_return.erase(
- std::remove_if(
- unsynced_commits_to_return.begin(),
- unsynced_commits_to_return.end(),
- [commit_id = std::move(commit.id)](
- const std::unique_ptr<const storage::Commit>& commit) {
- return commit->GetId() == commit_id;
- }),
- unsynced_commits_to_return.end());
- }
- async::PostTask(dispatcher_, [callback = std::move(callback)] {
- callback(storage::Status::OK, {});
- });
- };
- if (should_delay_add_commit_confirmation) {
- delayed_add_commit_confirmations.push_back(std::move(confirm));
- return;
- }
- async::PostTask(dispatcher_, std::move(confirm));
-}
-
-void TestPageStorage::GetUnsyncedPieces(
- fit::function<void(storage::Status, std::vector<storage::ObjectIdentifier>)>
- callback) {
- async::PostTask(dispatcher_, [callback = std::move(callback)] {
- callback(storage::Status::OK, std::vector<storage::ObjectIdentifier>());
- });
-}
-
-storage::Status TestPageStorage::AddCommitWatcher(
- storage::CommitWatcher* watcher) {
- watcher_ = watcher;
- watcher_set = true;
- return storage::Status::OK;
-}
-
-storage::Status TestPageStorage::RemoveCommitWatcher(
- storage::CommitWatcher* /*watcher*/) {
- watcher_removed = true;
- return storage::Status::OK;
-}
-
-void TestPageStorage::GetUnsyncedCommits(
- fit::function<void(storage::Status,
- std::vector<std::unique_ptr<const storage::Commit>>)>
- callback) {
- if (should_fail_get_unsynced_commits) {
- async::PostTask(dispatcher_, [callback = std::move(callback)] {
- callback(storage::Status::IO_ERROR, {});
- });
- return;
- }
- std::vector<std::unique_ptr<const storage::Commit>> results;
- results.resize(unsynced_commits_to_return.size());
- std::transform(unsynced_commits_to_return.begin(),
- unsynced_commits_to_return.end(), results.begin(),
- [](const std::unique_ptr<const storage::Commit>& commit) {
- return commit->Clone();
- });
- async::PostTask(dispatcher_, [results = std::move(results),
- callback = std::move(callback)]() mutable {
- callback(storage::Status::OK, std::move(results));
- });
-}
-
-void TestPageStorage::MarkCommitSynced(
- const storage::CommitId& commit_id,
- fit::function<void(storage::Status)> callback) {
- unsynced_commits_to_return.erase(
- std::remove_if(
- unsynced_commits_to_return.begin(), unsynced_commits_to_return.end(),
- [&commit_id](const std::unique_ptr<const storage::Commit>& commit) {
- return commit->GetId() == commit_id;
- }),
- unsynced_commits_to_return.end());
- commits_marked_as_synced.insert(commit_id);
- async::PostTask(dispatcher_, [callback = std::move(callback)] {
- callback(storage::Status::OK);
- });
-}
-
-void TestPageStorage::SetSyncMetadata(
- fxl::StringView key, fxl::StringView value,
- fit::function<void(storage::Status)> callback) {
- sync_metadata[key.ToString()] = value.ToString();
- async::PostTask(dispatcher_, [callback = std::move(callback)] {
- callback(storage::Status::OK);
- });
-}
-
-void TestPageStorage::GetSyncMetadata(
- fxl::StringView key,
- fit::function<void(storage::Status, std::string)> callback) {
- auto it = sync_metadata.find(key.ToString());
- if (it == sync_metadata.end()) {
- async::PostTask(dispatcher_, [callback = std::move(callback)] {
- callback(storage::Status::NOT_FOUND, "");
- });
- return;
- }
- async::PostTask(dispatcher_,
- [callback = std::move(callback), metadata = it->second] {
- callback(storage::Status::OK, metadata);
- });
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/testing/test_page_storage.h b/bin/ledger/cloud_sync/impl/testing/test_page_storage.h
deleted file mode 100644
index 5213bb4..0000000
--- a/bin/ledger/cloud_sync/impl/testing/test_page_storage.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_PAGE_STORAGE_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_PAGE_STORAGE_H_
-
-#include <map>
-#include <memory>
-#include <set>
-#include <vector>
-
-#include <lib/async/dispatcher.h>
-#include <lib/callback/capture.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-namespace cloud_sync {
-// Fake implementation of storage::PageStorage. Injects the data that PageSync
-// asks about: page id, existing unsynced commits to be retrieved through
-// GetUnsyncedCommits() and new commits to be retrieved through GetCommit().
-// Registers the commits marked as synced.
-class TestPageStorage : public storage::PageStorageEmptyImpl {
- public:
- explicit TestPageStorage(async_dispatcher_t* dispatcher);
-
- std::unique_ptr<TestCommit> NewCommit(std::string id, std::string content,
- bool unsynced = true);
-
- storage::PageId GetId() override;
-
- void SetSyncDelegate(storage::PageSyncDelegate* page_sync_delegate) override;
-
- void GetHeadCommitIds(
- fit::function<void(storage::Status, std::vector<storage::CommitId>)>
- callback) override;
-
- void GetCommit(storage::CommitIdView commit_id,
- fit::function<void(storage::Status,
- std::unique_ptr<const storage::Commit>)>
- callback) override;
-
- void AddCommitsFromSync(
- std::vector<PageStorage::CommitIdAndBytes> ids_and_bytes,
- storage::ChangeSource source,
- fit::function<void(storage::Status status,
- std::vector<storage::CommitId>)>
- callback) override;
-
- void GetUnsyncedPieces(
- fit::function<void(storage::Status,
- std::vector<storage::ObjectIdentifier>)>
- callback) override;
-
- storage::Status AddCommitWatcher(storage::CommitWatcher* watcher) override;
-
- storage::Status RemoveCommitWatcher(storage::CommitWatcher* watcher) override;
-
- void GetUnsyncedCommits(
- fit::function<void(storage::Status,
- std::vector<std::unique_ptr<const storage::Commit>>)>
- callback) override;
-
- void MarkCommitSynced(const storage::CommitId& commit_id,
- fit::function<void(storage::Status)> callback) override;
-
- void SetSyncMetadata(fxl::StringView key, fxl::StringView value,
- fit::function<void(storage::Status)> callback) override;
-
- void GetSyncMetadata(
- fxl::StringView key,
- fit::function<void(storage::Status, std::string)> callback) override;
-
- storage::PageId page_id_to_return;
- // Commits to be returned from GetUnsyncedCommits calls.
- std::vector<std::unique_ptr<const storage::Commit>>
- unsynced_commits_to_return;
- size_t head_count = 1;
- // Commits to be returned from GetCommit() calls.
- std::map<storage::CommitId, std::unique_ptr<const storage::Commit>>
- new_commits_to_return;
- bool should_fail_get_unsynced_commits = false;
- bool should_fail_get_commit = false;
- bool should_fail_add_commit_from_sync = false;
- bool should_delay_add_commit_confirmation = false;
- std::vector<fit::closure> delayed_add_commit_confirmations;
- bool should_delay_get_head_commit_ids = false;
- std::vector<fit::closure> delayed_get_head_commit_ids;
-
- unsigned int add_commits_from_sync_calls = 0u;
-
- storage::PageSyncDelegate* page_sync_delegate_;
- std::set<storage::CommitId> commits_marked_as_synced;
- storage::CommitWatcher* watcher_;
- bool watcher_set = false;
- bool watcher_removed = false;
- std::map<storage::CommitId, std::string> received_commits;
- std::map<std::string, std::string> sync_metadata;
-
- private:
- async_dispatcher_t* const dispatcher_;
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_TESTING_TEST_PAGE_STORAGE_H_
diff --git a/bin/ledger/cloud_sync/impl/user_sync_impl.cc b/bin/ledger/cloud_sync/impl/user_sync_impl.cc
deleted file mode 100644
index 9f0496e..0000000
--- a/bin/ledger/cloud_sync/impl/user_sync_impl.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/user_sync_impl.h"
-
-#include <utility>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/concatenate.h>
-#include <zircon/syscalls.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/ledger_sync_impl.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace cloud_sync {
-
-namespace {
-constexpr size_t kFingerprintSize = 16;
-
-} // namespace
-
-UserSyncImpl::UserSyncImpl(ledger::Environment* environment,
- UserConfig user_config,
- std::unique_ptr<backoff::Backoff> backoff,
- fit::closure on_version_mismatch)
- : environment_(environment),
- user_config_(std::move(user_config)),
- backoff_(std::move(backoff)),
- on_version_mismatch_(std::move(on_version_mismatch)),
- watcher_binding_(this),
- task_runner_(environment_->dispatcher()) {
- FXL_DCHECK(on_version_mismatch_);
-}
-
-UserSyncImpl::~UserSyncImpl() { FXL_DCHECK(active_ledger_syncs_.empty()); }
-
-void UserSyncImpl::SetSyncWatcher(SyncStateWatcher* watcher) {
- aggregator_.SetBaseWatcher(watcher);
-}
-
-std::unique_ptr<LedgerSync> UserSyncImpl::CreateLedgerSync(
- fxl::StringView app_id, encryption::EncryptionService* encryption_service) {
- FXL_DCHECK(started_);
-
- auto result = std::make_unique<LedgerSyncImpl>(
- environment_, &user_config_, encryption_service, app_id,
- aggregator_.GetNewStateWatcher());
- result->set_on_delete([this, ledger_sync = result.get()]() {
- active_ledger_syncs_.erase(ledger_sync);
- });
- active_ledger_syncs_.insert(result.get());
- if (upload_enabled_) {
- result->EnableUpload();
- }
- return result;
-}
-
-ledger::DetachedPath UserSyncImpl::GetFingerprintPath() {
- return user_config_.user_directory.SubPath("fingerprint");
-}
-
-void UserSyncImpl::OnCloudErased() {
- // |this| can be deleted within on_version_mismatch_() - don't
- // access member variables afterwards.
- on_version_mismatch_();
-}
-
-void UserSyncImpl::OnNetworkError() {
- task_runner_.PostDelayedTask([this] { SetCloudErasedWatcher(); },
- backoff_->GetNext());
-}
-
-void UserSyncImpl::Start() {
- FXL_DCHECK(!started_);
- if (!user_config_.cloud_provider) {
- // TODO(ppi): handle recovery from cloud provider disconnection, LE-567.
- FXL_LOG(WARNING) << "Cloud provider is disconnected, will not verify "
- << "the cloud fingerprint";
- return;
- }
-
- user_config_.cloud_provider->GetDeviceSet(
- device_set_.NewRequest(), [this](auto status) {
- if (status != cloud_provider::Status::OK) {
- FXL_LOG(ERROR) << "Failed to retrieve the device map: "
- << fidl::ToUnderlying(status)
- << ", sync upload will not work.";
- return;
- }
- CheckCloudNotErased();
- });
-
- started_ = true;
-}
-
-void UserSyncImpl::CheckCloudNotErased() {
- if (!device_set_) {
- // TODO(ppi): handle recovery from cloud provider disconnection, LE-567.
- FXL_LOG(WARNING) << "Cloud provider is disconnected, will not verify "
- << "the cloud fingerprint";
- return;
- }
-
- ledger::DetachedPath fingerprint_path = GetFingerprintPath();
- if (!files::IsFileAt(fingerprint_path.root_fd(), fingerprint_path.path())) {
- CreateFingerprint();
- return;
- }
-
- if (!files::ReadFileToStringAt(fingerprint_path.root_fd(),
- fingerprint_path.path(), &fingerprint_)) {
- FXL_LOG(ERROR) << "Unable to read the fingerprint file at: "
- << fingerprint_path.path() << ", sync upload will not work.";
- return;
- }
-
- device_set_->CheckFingerprint(
- convert::ToArray(fingerprint_),
- [this](cloud_provider::Status status) { HandleDeviceSetResult(status); });
-}
-
-void UserSyncImpl::CreateFingerprint() {
- if (!device_set_) {
- // TODO(ppi): handle recovery from cloud provider disconnection, LE-567.
- FXL_LOG(WARNING) << "Cloud provider is disconnected, will not verify "
- << "the cloud fingerprint";
- return;
- }
-
- // Generate the fingerprint.
- char fingerprint_array[kFingerprintSize];
- environment_->random()->Draw(fingerprint_array, kFingerprintSize);
- fingerprint_ =
- convert::ToHex(fxl::StringView(fingerprint_array, kFingerprintSize));
-
- device_set_->SetFingerprint(
- convert::ToArray(fingerprint_), [this](cloud_provider::Status status) {
- if (status == cloud_provider::Status::OK) {
- // Persist the new fingerprint.
- FXL_DCHECK(!fingerprint_.empty());
- ledger::DetachedPath fingerprint_path = GetFingerprintPath();
- if (!files::WriteFileAt(fingerprint_path.root_fd(),
- fingerprint_path.path(), fingerprint_.data(),
- fingerprint_.size())) {
- FXL_LOG(ERROR) << "Failed to persist the fingerprint at: "
- << fingerprint_path.path()
- << ", sync upload will not work.";
- return;
- }
- }
- HandleDeviceSetResult(status);
- });
-}
-
-void UserSyncImpl::HandleDeviceSetResult(cloud_provider::Status status) {
- switch (status) {
- case cloud_provider::Status::OK:
- backoff_->Reset();
- SetCloudErasedWatcher();
- EnableUpload();
- return;
- case cloud_provider::Status::NETWORK_ERROR:
- // Retry after some backoff time.
- task_runner_.PostDelayedTask([this] { CheckCloudNotErased(); },
- backoff_->GetNext());
- return;
- case cloud_provider::Status::NOT_FOUND:
- // |this| can be deleted within on_version_mismatch_() - don't
- // access member variables afterwards.
- on_version_mismatch_();
- return;
- default:
- FXL_LOG(ERROR) << "Unexpected status returned from device set: "
- << fidl::ToUnderlying(status)
- << ", sync upload will not work.";
- return;
- }
-}
-
-void UserSyncImpl::SetCloudErasedWatcher() {
- if (!device_set_) {
- // TODO(ppi): handle recovery from cloud provider disconnection, LE-567.
- FXL_LOG(WARNING) << "Cloud provider is disconnected, will not verify "
- << "the cloud fingerprint";
- return;
- }
-
- cloud_provider::DeviceSetWatcherPtr watcher;
- if (watcher_binding_.is_bound()) {
- watcher_binding_.Unbind();
- }
- watcher_binding_.Bind(watcher.NewRequest());
- device_set_->SetWatcher(convert::ToArray(fingerprint_), std::move(watcher),
- [this](cloud_provider::Status status) {
- if (status == cloud_provider::Status::OK) {
- backoff_->Reset();
- }
- // Don't handle errors - in case of error, the
- // corresponding call is made on the watcher
- // itself and handled there (OnCloudErased(),
- // OnNetworkError()).
- });
-}
-
-void UserSyncImpl::EnableUpload() {
- upload_enabled_ = true;
- for (auto ledger_sync : active_ledger_syncs_) {
- ledger_sync->EnableUpload();
- }
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/impl/user_sync_impl.h b/bin/ledger/cloud_sync/impl/user_sync_impl.h
deleted file mode 100644
index 9dc6c32..0000000
--- a/bin/ledger/cloud_sync/impl/user_sync_impl.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_USER_SYNC_IMPL_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_USER_SYNC_IMPL_H_
-
-#include <memory>
-#include <set>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/backoff/backoff.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/aggregator.h"
-#include "peridot/bin/ledger/cloud_sync/impl/ledger_sync_impl.h"
-#include "peridot/bin/ledger/cloud_sync/public/user_sync.h"
-#include "peridot/bin/ledger/environment/environment.h"
-
-namespace cloud_sync {
-
-class UserSyncImpl : public UserSync, cloud_provider::DeviceSetWatcher {
- public:
- // Parameters:
- // |on_version_mismatch| is called when the local state is detected to be
- // incompatible with the state in the cloud and has to be erased.
- UserSyncImpl(ledger::Environment* environment, UserConfig user_config,
- std::unique_ptr<backoff::Backoff> backoff,
- fit::closure on_version_mismatch);
- ~UserSyncImpl() override;
-
- // UserSync:
- void SetSyncWatcher(SyncStateWatcher* watcher) override;
- void Start() override;
- std::unique_ptr<LedgerSync> CreateLedgerSync(
- fxl::StringView app_id,
- encryption::EncryptionService* encryption_service) override;
-
- // Returns the path where the device fingerprint is stored.
- ledger::DetachedPath GetFingerprintPath();
-
- private:
- // cloud_provider::DeviceSetWatcher:
- void OnCloudErased() override;
-
- void OnNetworkError() override;
-
- // Checks that the cloud was not erased since the last sync using the device
- // fingerprint.
- void CheckCloudNotErased();
- void CreateFingerprint();
- void HandleDeviceSetResult(cloud_provider::Status status);
-
- // Sets a watcher to detect that the cloud is cleared while sync is running.
- void SetCloudErasedWatcher();
-
- // Enables sync upload.
- void EnableUpload();
-
- ledger::Environment* environment_;
- const UserConfig user_config_;
- std::unique_ptr<backoff::Backoff> backoff_;
- fit::closure on_version_mismatch_;
-
- // UserSyncImpl must be started before it can be used.
- bool started_ = false;
- // Whether uploads should be enabled. It is false until the cloud version has
- // been checked.
- bool upload_enabled_ = false;
- cloud_provider::DeviceSetPtr device_set_;
- fidl::Binding<cloud_provider::DeviceSetWatcher> watcher_binding_;
- // Fingerprint of the device in the cloud device list.
- std::string fingerprint_;
- std::set<LedgerSyncImpl*> active_ledger_syncs_;
-
- // Aggregates the synchronization state of multiple ledgers into one
- // notification stream.
- Aggregator aggregator_;
-
- // This must be the last member of this class.
- callback::ScopedTaskRunner task_runner_;
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_IMPL_USER_SYNC_IMPL_H_
diff --git a/bin/ledger/cloud_sync/impl/user_sync_impl_unittest.cc b/bin/ledger/cloud_sync/impl/user_sync_impl_unittest.cc
deleted file mode 100644
index 500a920..0000000
--- a/bin/ledger/cloud_sync/impl/user_sync_impl_unittest.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/impl/user_sync_impl.h"
-
-#include <utility>
-
-#include <lib/backoff/backoff.h>
-#include <lib/backoff/testing/test_backoff.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/ledger/cloud_sync/impl/testing/test_cloud_provider.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace cloud_sync {
-
-namespace {
-
-class TestSyncStateWatcher : public SyncStateWatcher {
- public:
- TestSyncStateWatcher() {}
- ~TestSyncStateWatcher() override{};
-
- void Notify(SyncStateContainer /*sync_state*/) override {}
-};
-
-class UserSyncImplTest : public ledger::TestWithEnvironment {
- public:
- UserSyncImplTest()
- : cloud_provider_(cloud_provider_ptr_.NewRequest()),
- encryption_service_(dispatcher()) {
- UserConfig user_config;
- user_config.user_directory = ledger::DetachedPath(tmpfs_.root_fd());
- user_config.cloud_provider = std::move(cloud_provider_ptr_);
-
- auto backoff = std::make_unique<backoff::TestBackoff>();
- backoff->SetOnGetNext([this] {
- // Make RunLoopUntilIdle() return once a backoff is requested, to avoid an
- // infinite loop.
- QuitLoop();
- });
-
- user_sync_ = std::make_unique<UserSyncImpl>(
- &environment_, std::move(user_config), std::move(backoff),
- [this] { on_version_mismatch_calls_++; });
- user_sync_->SetSyncWatcher(&sync_state_watcher_);
- }
- ~UserSyncImplTest() override {}
-
- protected:
- bool SetFingerprintFile(std::string content) {
- ledger::DetachedPath fingerprint_path = user_sync_->GetFingerprintPath();
- return files::WriteFileAt(fingerprint_path.root_fd(),
- fingerprint_path.path(), content.data(),
- content.size());
- }
-
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- cloud_provider::CloudProviderPtr cloud_provider_ptr_;
- TestCloudProvider cloud_provider_;
- std::unique_ptr<UserSyncImpl> user_sync_;
- encryption::FakeEncryptionService encryption_service_;
- TestSyncStateWatcher sync_state_watcher_;
-
- int on_version_mismatch_calls_ = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(UserSyncImplTest);
-};
-
-// Verifies that the mismatch callback is called if the fingerprint appears to
-// be erased from the cloud.
-TEST_F(UserSyncImplTest, CloudCheckErased) {
- ASSERT_TRUE(SetFingerprintFile("some-value"));
- cloud_provider_.device_set.status_to_return =
- cloud_provider::Status::NOT_FOUND;
- EXPECT_EQ(0, on_version_mismatch_calls_);
- user_sync_->Start();
- RunLoopUntilIdle();
- EXPECT_EQ(1, on_version_mismatch_calls_);
-}
-
-// Verifies that if the version checker reports that cloud is compatible, upload
-// is enabled in LedgerSync.
-TEST_F(UserSyncImplTest, CloudCheckOk) {
- ASSERT_TRUE(SetFingerprintFile("some-value"));
- cloud_provider_.device_set.status_to_return = cloud_provider::Status::OK;
- EXPECT_EQ(0, on_version_mismatch_calls_);
- user_sync_->Start();
-
- auto ledger_a = user_sync_->CreateLedgerSync("app-id", &encryption_service_);
- auto ledger_a_ptr = static_cast<LedgerSyncImpl*>(ledger_a.get());
- EXPECT_FALSE(ledger_a_ptr->IsUploadEnabled());
- RunLoopUntilIdle();
- EXPECT_TRUE(ledger_a_ptr->IsUploadEnabled());
- EXPECT_EQ(0, on_version_mismatch_calls_);
- EXPECT_EQ("some-value", cloud_provider_.device_set.checked_fingerprint);
-
- // Verify that newly created LedgerSyncs also have the upload enabled.
- auto ledger_b = user_sync_->CreateLedgerSync("app-id", &encryption_service_);
- auto ledger_b_ptr = static_cast<LedgerSyncImpl*>(ledger_b.get());
- EXPECT_TRUE(ledger_b_ptr->IsUploadEnabled());
-}
-
-// Verifies that if there is no fingerprint file, it is created and set in the
-// cloud.
-TEST_F(UserSyncImplTest, CloudCheckSet) {
- auto fingerprint_path = user_sync_->GetFingerprintPath();
- EXPECT_FALSE(
- files::IsFileAt(fingerprint_path.root_fd(), fingerprint_path.path()));
- cloud_provider_.device_set.status_to_return = cloud_provider::Status::OK;
- EXPECT_EQ(0, on_version_mismatch_calls_);
- user_sync_->Start();
-
- auto ledger = user_sync_->CreateLedgerSync("app-id", &encryption_service_);
- auto ledger_ptr = static_cast<LedgerSyncImpl*>(ledger.get());
- EXPECT_FALSE(ledger_ptr->IsUploadEnabled());
- RunLoopUntilIdle();
- EXPECT_TRUE(ledger_ptr->IsUploadEnabled());
- EXPECT_EQ(0, on_version_mismatch_calls_);
- EXPECT_FALSE(cloud_provider_.device_set.set_fingerprint.empty());
-
- // Verify that the fingerprint file was created.
- EXPECT_TRUE(
- files::IsFileAt(fingerprint_path.root_fd(), fingerprint_path.path()));
-}
-
-// Verifies that the cloud watcher for the fingerprint is set and triggers the
-// mismatch callback when cloud erase is detected.
-TEST_F(UserSyncImplTest, WatchErase) {
- ASSERT_TRUE(SetFingerprintFile("some-value"));
- cloud_provider_.device_set.status_to_return = cloud_provider::Status::OK;
- user_sync_->Start();
-
- RunLoopUntilIdle();
- EXPECT_TRUE(cloud_provider_.device_set.set_watcher.is_bound());
- EXPECT_EQ("some-value", cloud_provider_.device_set.watched_fingerprint);
- EXPECT_EQ(0, on_version_mismatch_calls_);
-
- cloud_provider_.device_set.set_watcher->OnCloudErased();
- RunLoopUntilIdle();
- EXPECT_EQ(1, on_version_mismatch_calls_);
-}
-
-// Verifies that setting the cloud watcher for is retried on network errors.
-TEST_F(UserSyncImplTest, WatchRetry) {
- ASSERT_TRUE(SetFingerprintFile("some-value"));
- cloud_provider_.device_set.set_watcher_status_to_return =
- cloud_provider::Status::NETWORK_ERROR;
- user_sync_->Start();
-
- RunLoopUntilIdle();
- EXPECT_EQ(1, cloud_provider_.device_set.set_watcher_calls);
-}
-
-} // namespace
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/public/BUILD.gn b/bin/ledger/cloud_sync/public/BUILD.gn
deleted file mode 100644
index 33468f6..0000000
--- a/bin/ledger/cloud_sync/public/BUILD.gn
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("public") {
- sources = [
- "ledger_sync.h",
- "page_sync.h",
- "sync_state_watcher.cc",
- "sync_state_watcher.h",
- "user_config.h",
- "user_sync.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/encryption/public",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/filesystem",
- "//peridot/bin/ledger/storage/public",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/cloud_sync/public/ledger_sync.h b/bin/ledger/cloud_sync/public/ledger_sync.h
deleted file mode 100644
index 1e50f49..0000000
--- a/bin/ledger/cloud_sync/public/ledger_sync.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_LEDGER_SYNC_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_LEDGER_SYNC_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/page_sync.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace cloud_sync {
-
-// Manages Cloud Sync for a particular ledger.
-class LedgerSync {
- public:
- LedgerSync() {}
- virtual ~LedgerSync() {}
-
- // Creates a new page sync for the given page. The page could already have
- // data synced to the cloud or not.
- //
- // The provided |error_callback| is called when sync is stopped due to an
- // unrecoverable error.
- virtual std::unique_ptr<PageSync> CreatePageSync(
- storage::PageStorage* page_storage,
- storage::PageSyncClient* page_sync_client) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerSync);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_LEDGER_SYNC_H_
diff --git a/bin/ledger/cloud_sync/public/page_sync.h b/bin/ledger/cloud_sync/public/page_sync.h
deleted file mode 100644
index 6b9e0ea..0000000
--- a/bin/ledger/cloud_sync/public/page_sync.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_PAGE_SYNC_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_PAGE_SYNC_H_
-
-#include <functional>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-
-namespace cloud_sync {
-
-// Manages cloud sync for a single page.
-//
-// PageSync is responsible for uploading locally created artifacts (commits and
-// objects) of the page from storage to the cloud, and for fetching remote
-// artifacts of the same page from the cloud and putting them in storage.
-class PageSync {
- public:
- PageSync() {}
- virtual ~PageSync() {}
-
- // Starts syncing. Upon connection drop, the sync will restart automatically,
- // the client doesn't need to call Start() again.
- virtual void Start() = 0;
-
- // Sets a callback that will be called after Start() every time when PageSync
- // becomes idle, that is: finished uploading all unsynced local artifacts to
- // the cloud and not downloading any remote artifacts. Can be set at most once
- // and only before calling Start().
- virtual void SetOnIdle(fit::closure on_idle) = 0;
-
- // Returns true iff PageSync is idle, that is with no pending upload or
- // download work.
- virtual bool IsIdle() = 0;
-
- // Sets a callback that will be called at most once after Start(), when all
- // remote commits added to the cloud between the last sync and starting the
- // current sync are added to storage. This can be used by the client to delay
- // exposing the local page until it catches up with the cloud. Can be set at
- // most once and only before calling Start().
- virtual void SetOnBacklogDownloaded(fit::closure on_backlog_downloaded) = 0;
-
- // Sets a watcher for the synchronization state of this page.
- virtual void SetSyncWatcher(SyncStateWatcher* watcher) = 0;
-
- // Sets a callback that will be called at most once, before or after Start(),
- // when PageSync hits an error it cannot recover from. The class can be
- // deleted after that.
- virtual void SetOnUnrecoverableError(fit::closure on_unrecoverable_error) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageSync);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_PAGE_SYNC_H_
diff --git a/bin/ledger/cloud_sync/public/sync_state_watcher.cc b/bin/ledger/cloud_sync/public/sync_state_watcher.cc
deleted file mode 100644
index 8aaa483..0000000
--- a/bin/ledger/cloud_sync/public/sync_state_watcher.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-
-#include <tuple>
-
-namespace cloud_sync {
-
-SyncStateWatcher::SyncStateContainer::SyncStateContainer(
- DownloadSyncState download, UploadSyncState upload)
- : download(download), upload(upload) {}
-
-SyncStateWatcher::SyncStateContainer::SyncStateContainer() {}
-
-void SyncStateWatcher::SyncStateContainer::Merge(SyncStateContainer other) {
- if (other.download > this->download) {
- download = other.download;
- }
- if (other.upload > this->upload) {
- upload = other.upload;
- }
-}
-
-void SyncStateWatcher::Notify(DownloadSyncState download,
- UploadSyncState upload) {
- Notify(SyncStateContainer(download, upload));
-}
-
-bool operator==(const SyncStateWatcher::SyncStateContainer& lhs,
- const SyncStateWatcher::SyncStateContainer& rhs) {
- return std::tie(lhs.download, lhs.upload) ==
- std::tie(rhs.download, rhs.upload);
-}
-
-bool operator!=(const SyncStateWatcher::SyncStateContainer& lhs,
- const SyncStateWatcher::SyncStateContainer& rhs) {
- return !(lhs == rhs);
-}
-
-std::ostream& operator<<(
- std::ostream& strm,
- const SyncStateWatcher::SyncStateContainer& sync_state) {
- return strm << "{" << sync_state.download << ", " << sync_state.upload << "}";
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/public/sync_state_watcher.h b/bin/ledger/cloud_sync/public/sync_state_watcher.h
deleted file mode 100644
index 054ef18..0000000
--- a/bin/ledger/cloud_sync/public/sync_state_watcher.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_SYNC_STATE_WATCHER_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_SYNC_STATE_WATCHER_H_
-
-#include <ostream>
-
-namespace cloud_sync {
-// Detail of the download part of the synchronization state.
-enum DownloadSyncState {
- // Download has not started.
- // Possible successor states: DOWNLOAD_BACKLOG.
- DOWNLOAD_NOT_STARTED = 0,
- // Download is downloading the commit backlog.
- // Possible successor states: DOWNLOAD_TEMPORARY_ERROR,
- // DOWNLOAD_SETTING_REMOTE_WATCHER.
- DOWNLOAD_BACKLOG,
- // Download experienced a temporary error and will attempt to recover
- // automatically.
- // Possible successor states: DOWNLOAD_BACKLOG,
- // DOWNLOAD_SETTING_REMOTE_WATCHER.
- DOWNLOAD_TEMPORARY_ERROR,
- // Download prepares the remote watcher to be notified of new remote commits.
- // Possible successor states: DOWNLOAD_IDLE.
- DOWNLOAD_SETTING_REMOTE_WATCHER,
- // Download is idle and waits for new remote commits to download.
- // Possible successor states: DOWNLOAD_TEMPORARY_ERROR, DOWNLOAD_IN_PROGRESS,
- // DOWNLOAD_PERMANENT_ERROR.
- DOWNLOAD_IDLE,
- // Download is in progress.
- // Possible successor states: DOWNLOAD_TEMPORARY_ERROR, DOWNLOAD_IDLE,
- // DOWNLOAD_PERMANENT_ERROR.
- DOWNLOAD_IN_PROGRESS,
- // Download experienced a permanent, unrecoverable error.
- // Possible successor states: None.
- DOWNLOAD_PERMANENT_ERROR,
-};
-
-// Detail of the upload part of the synchronization state.
-enum UploadSyncState {
- // Upload has not started.
- // Possible successor states: UPLOAD_SETUP.
- UPLOAD_NOT_STARTED = 0,
- // Upload is started and being prepared.
- // Possible successor states: UPLOAD_IDLE, UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS,
- // UPLOAD_WAIT_REMOTE_DOWNLOAD, UPLOAD_PERMANENT_ERROR.
- UPLOAD_SETUP,
- // Upload is ready, but currently idle.
- // Possible successor states: UPLOAD_PENDING,
- // UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS,
- // UPLOAD_WAIT_REMOTE_DOWNLOAD, UPLOAD_PERMANENT_ERROR.
- UPLOAD_IDLE,
- // Upload has some contents to upload, but has to wait before proceeding.
- // Possible successor states: UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS,
- // UPLOAD_WAIT_REMOTE_DOWNLOAD, UPLOAD_PERMANENT_ERROR.
- UPLOAD_PENDING,
- // Upload cannot proceed as there are more than one local head commit.
- // Possible successor states: UPLOAD_IDLE, UPLOAD_IN_PROGRESS,
- // UPLOAD_WAIT_REMOTE_DOWNLOAD, UPLOAD_PERMANENT_ERROR.
- UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS,
- // Upload is waiting for a remote download to finish.
- // Possible successor states: UPLOAD_IDLE, UPLOAD_IN_PROGRESS,
- // UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS, UPLOAD_PERMANENT_ERROR.
- UPLOAD_WAIT_REMOTE_DOWNLOAD,
- // Upload experienced a temporary error and will attempt to recover
- // automatically.
- // Possible successor states: UPLOAD_IDLE, UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS,
- // UPLOAD_WAIT_REMOTE_DOWNLOAD, UPLOAD_IN_PROGRESS, UPLOAD_PERMANENT_ERROR.
- UPLOAD_TEMPORARY_ERROR,
- // Upload is uploading a local commit and its contents.
- // Possible successor states: UPLOAD_IDLE, UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS,
- // UPLOAD_WAIT_REMOTE_DOWNLOAD, UPLOAD_PERMANENT_ERROR.
- UPLOAD_IN_PROGRESS,
- // Upload has experienced an unrecoverable error and cannot continue.
- // Possible successor states: None.
- UPLOAD_PERMANENT_ERROR,
-};
-
-// Watcher interface for the current state of data synchronization
-class SyncStateWatcher {
- public:
- // Container for the synchronization state, containing both download and
- // upload components.
- struct SyncStateContainer {
- DownloadSyncState download = DOWNLOAD_IDLE;
- UploadSyncState upload = UPLOAD_IDLE;
-
- SyncStateContainer(DownloadSyncState download, UploadSyncState upload);
- SyncStateContainer();
-
- void Merge(SyncStateContainer other);
- };
-
- virtual ~SyncStateWatcher() {}
-
- // Notifies the watcher of a new state.
- virtual void Notify(SyncStateContainer sync_state) = 0;
-
- // Helper method, equivalent to |Notify| above.
- virtual void Notify(DownloadSyncState download, UploadSyncState upload);
-};
-
-bool operator==(const SyncStateWatcher::SyncStateContainer& lhs,
- const SyncStateWatcher::SyncStateContainer& rhs);
-bool operator!=(const SyncStateWatcher::SyncStateContainer& lhs,
- const SyncStateWatcher::SyncStateContainer& rhs);
-std::ostream& operator<<(
- std::ostream& strm, const SyncStateWatcher::SyncStateContainer& sync_state);
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_SYNC_STATE_WATCHER_H_
diff --git a/bin/ledger/cloud_sync/public/user_config.h b/bin/ledger/cloud_sync/public/user_config.h
deleted file mode 100644
index 7452f40..0000000
--- a/bin/ledger/cloud_sync/public/user_config.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_USER_CONFIG_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_USER_CONFIG_H_
-
-#include <memory>
-#include <string>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-
-namespace cloud_sync {
-
-// Sync configuration for a particular user.
-struct UserConfig {
- // The directory for the user persistent data.
- ledger::DetachedPath user_directory;
- // The provider of the auth data for the user.
- cloud_provider::CloudProviderPtr cloud_provider;
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_USER_CONFIG_H_
diff --git a/bin/ledger/cloud_sync/public/user_sync.h b/bin/ledger/cloud_sync/public/user_sync.h
deleted file mode 100644
index f33abd2..0000000
--- a/bin/ledger/cloud_sync/public/user_sync.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_USER_SYNC_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_USER_SYNC_H_
-
-#include <memory>
-
-#include <lib/fxl/functional/closure.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/ledger_sync.h"
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/cloud_sync/public/user_config.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-
-namespace cloud_sync {
-
-// Top level factory for every object sync related for a given user.
-class UserSync {
- public:
- UserSync() {}
- virtual ~UserSync() {}
-
- // Sets a synchronization state watcher for this user.
- //
- // Set the watcher to nullptr to unregister a previously set watcher.
- virtual void SetSyncWatcher(SyncStateWatcher* watcher) = 0;
-
- // Starts the user synchronization.
- virtual void Start() = 0;
-
- virtual std::unique_ptr<LedgerSync> CreateLedgerSync(
- fxl::StringView app_id,
- encryption::EncryptionService* encryption_service) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(UserSync);
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_PUBLIC_USER_SYNC_H_
diff --git a/bin/ledger/cloud_sync/testing/BUILD.gn b/bin/ledger/cloud_sync/testing/BUILD.gn
deleted file mode 100644
index 914ff00..0000000
--- a/bin/ledger/cloud_sync/testing/BUILD.gn
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "page_sync_empty_impl.cc",
- "page_sync_empty_impl.h",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/cloud_sync/public",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/cloud_sync/testing/page_sync_empty_impl.cc b/bin/ledger/cloud_sync/testing/page_sync_empty_impl.cc
deleted file mode 100644
index c26a25b..0000000
--- a/bin/ledger/cloud_sync/testing/page_sync_empty_impl.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cloud_sync/testing/page_sync_empty_impl.h"
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-namespace cloud_sync {
-
-void PageSyncEmptyImpl::Start() { FXL_NOTIMPLEMENTED(); }
-
-void PageSyncEmptyImpl::SetOnIdle(fit::closure /*on_idle_callback*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-bool PageSyncEmptyImpl::IsIdle() {
- FXL_NOTIMPLEMENTED();
- return true;
-}
-
-void PageSyncEmptyImpl::SetOnBacklogDownloaded(
- fit::closure /*on_backlog_downloaded_callback*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-void PageSyncEmptyImpl::SetSyncWatcher(SyncStateWatcher* /*watcher*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-void PageSyncEmptyImpl::SetOnUnrecoverableError(fit::closure /*on_error*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-} // namespace cloud_sync
diff --git a/bin/ledger/cloud_sync/testing/page_sync_empty_impl.h b/bin/ledger/cloud_sync/testing/page_sync_empty_impl.h
deleted file mode 100644
index e35d115..0000000
--- a/bin/ledger/cloud_sync/testing/page_sync_empty_impl.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_CLOUD_SYNC_TESTING_PAGE_SYNC_EMPTY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_CLOUD_SYNC_TESTING_PAGE_SYNC_EMPTY_IMPL_H_
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/page_sync.h"
-
-namespace cloud_sync {
-
-class PageSyncEmptyImpl : public PageSync {
- public:
- // PageSync:
- void Start() override;
- void SetOnIdle(fit::closure on_idle_callback) override;
- bool IsIdle() override;
- void SetOnBacklogDownloaded(
- fit::closure on_backlog_downloaded_callback) override;
- void SetSyncWatcher(SyncStateWatcher* watcher) override;
- void SetOnUnrecoverableError(fit::closure on_error) override;
-};
-
-} // namespace cloud_sync
-
-#endif // PERIDOT_BIN_LEDGER_CLOUD_SYNC_TESTING_PAGE_SYNC_EMPTY_IMPL_H_
diff --git a/bin/ledger/cobalt/BUILD.gn b/bin/ledger/cobalt/BUILD.gn
deleted file mode 100644
index c377739..0000000
--- a/bin/ledger/cobalt/BUILD.gn
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/cobalt_config/metrics_registry.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-metrics_registry("ledger_metrics_registry") {
- project_id = 100
-}
-
-source_set("cobalt") {
- sources = [
- "cobalt.cc",
- "cobalt.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fxl",
- ]
-
- deps = [
- "//garnet/public/lib/backoff",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/cobalt/cpp:cobalt_logger",
- "//zircon/public/fidl/fuchsia-cobalt",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/cobalt/cobalt.cc b/bin/ledger/cobalt/cobalt.cc
deleted file mode 100644
index 57c2831..0000000
--- a/bin/ledger/cobalt/cobalt.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/cobalt/cobalt.h"
-
-#include <lib/cobalt/cpp/cobalt_logger.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/file.h>
-
-namespace ledger {
-namespace {
-constexpr char kConfigBinProtoPath[] = "/pkg/data/ledger_cobalt_config.pb";
-constexpr int32_t kCobaltMetricId = 2;
-
-cobalt::CobaltLogger* g_cobalt_logger = nullptr;
-
-} // namespace
-
-fit::deferred_action<fit::closure> InitializeCobalt(
- async_dispatcher_t* dispatcher, component::StartupContext* context) {
- std::unique_ptr<cobalt::CobaltLogger> cobalt_logger;
- FXL_DCHECK(!g_cobalt_logger);
-
- cobalt_logger =
- cobalt::NewCobaltLogger(dispatcher, context, kConfigBinProtoPath);
-
- g_cobalt_logger = cobalt_logger.get();
- return fit::defer<fit::closure>([cobalt_logger = std::move(cobalt_logger)] {
- g_cobalt_logger = nullptr;
- });
-}
-
-void ReportEvent(CobaltEvent event) {
- // Do not do anything if cobalt reporting is disabled.
- if (!g_cobalt_logger) {
- return;
- }
- g_cobalt_logger->LogEvent(kCobaltMetricId, static_cast<uint32_t>(event));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/cobalt/cobalt.h b/bin/ledger/cobalt/cobalt.h
deleted file mode 100644
index e712493..0000000
--- a/bin/ledger/cobalt/cobalt.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COBALT_COBALT_H_
-#define PERIDOT_BIN_LEDGER_COBALT_COBALT_H_
-
-#include <lib/async/dispatcher.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-namespace ledger {
-
-// The events to report.
-// Next enum value: 6
-enum class CobaltEvent : uint32_t {
- LEDGER_STARTED = 0,
- COMMITS_RECEIVED_OUT_OF_ORDER = 1,
- COMMITS_RECEIVED_OUT_OF_ORDER_NOT_RECOVERED = 4,
- COMMITS_MERGED = 2,
- MERGED_COMMITS_MERGED = 3,
- LEDGER_LEVELDB_STATE_CORRUPTED = 5,
-};
-
-// Cobalt initialization. When cobalt is not need, the returned object must be
-// deleted. This method must not be called again until then.
-fit::deferred_action<fit::closure> InitializeCobalt(
- async_dispatcher_t* dispatcher, component::StartupContext* context);
-
-// Report an event to Cobalt. The callback returned by |InitializeCobalt|
-// must be live throughout every call to this function. This is
-// thread-compatible, as long as the previous requirement is ensured across
-// threads.
-void ReportEvent(CobaltEvent event);
-
-}; // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_COBALT_COBALT_H_
diff --git a/bin/ledger/coroutine/BUILD.gn b/bin/ledger/coroutine/BUILD.gn
deleted file mode 100644
index 22f8973..0000000
--- a/bin/ledger/coroutine/BUILD.gn
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("coroutine") {
- sources = [
- "coroutine.h",
- "coroutine_impl.cc",
- "coroutine_impl.h",
- "coroutine_manager.h",
- "coroutine_waiter.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- ]
-
- deps = [
- "//peridot/bin/ledger/coroutine/context",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "coroutine_manager_unittest.cc",
- "coroutine_unittest.cc",
- "coroutine_waiter_unittest.cc",
- ]
-
- deps = [
- ":coroutine",
- "//garnet/public/lib/fxl",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/coroutine/README.md b/bin/ledger/coroutine/README.md
deleted file mode 100644
index 739f7ac..0000000
--- a/bin/ledger/coroutine/README.md
+++ /dev/null
@@ -1,115 +0,0 @@
-# Coroutine library
-
-## Description
-This coroutine library can help you write highly asynchronous code, and avoid
-"callback hell". It does so by allowing a function (or method) to be paused and
-resumed by swapping [execution contexts](context/context.h). It makes the code
-*look* synchronous, while remaining asynchronous under the hood, with all the
-usual concurrency pitfalls, such as race conditions and deadlocks.
-
-Coroutines are different than multithreading, but both can be used together.
-See [CoroutineHandler](coroutine.h) for details.
-
-## Usage
-
-Here are some tips on good use of the Coroutine library.
-
-### Use CoroutineManager in classes
-
-Usually, coroutines created within a class object should not survive its
-destruction, whether because continuing the processing didn't make sense, or
-because resources captured by the coroutine would be destroyed (such as `this`).
-
-[CoroutineManager](coroutine_manager.h) is a proxy class for
-[CoroutineService](coroutine.h). `CoroutineManager` interrupts the coroutine it
-created when destroyed, and can be created using the `CoroutineService` vended
-by an `Environment` object.
-
-You should consider using `CoroutineManager` if you use coroutines in your
-class.
-
-Free-standing functions probably don't need `CoroutineManager` and can use
-`CoroutineService` directly.
-
-### When receiving INTERRUPTED, return
-
-`coroutine::ContinuationStatus::INTERRUPTED` means another part of your code
-requested the coroutine to terminate gracefully. This would be the case if the
-`CoroutineManager` or `CoroutineService` who created this coroutine are
-destroyed.
-
-This mechanism is needed because other parts of the program don’t know the heap
-allocations made inside the coroutine, as well as other cleanup performed by
-the destructors of objects created or owned by the coroutine. When a coroutine
-destruction is needed, it is resumed with an `ContinuationStatus::INTERRUPTED`
-and it is the coroutine's job to unwind its call stack.
-
-Usually, the only thing you need to do when receiving a
-`ContinuationStatus::INTERRUPTED` is to return immediately. Doing more work is
-dangerous as some objects you rely on may be destroyed already.
-
-
-### Don’t use Yield and Resume
-
-You probably don’t need to use `Yield()` and `Resume()` directly.
-[SyncCall](coroutine.h) is a utility function that can be used to wrap any
-asynchronous call, so that you don't have to use `CoroutineHandler` methods
-directly.
-
-If you have an asynchronous function with the signature
-`AsynchronousCall(Argument, std::function<void(Status, Result)>)`, then you can
-wrap it such as:
-``` cpp
-Argument argument(...)
-Status status;
-Result value;
-if (coroutine::SyncCall(handler,
- [argument](fit::function<void(Status, Result)> cb) {
- AsynchronousCall(argument, std::move(cb));
- }, &status, &value) == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
-}
-if (status != Status::OK)
- return status;
-Process(value);
-```
-
-`SyncCall` will ensure the asynchronous call is made and the coroutine paused,
-and then resumed when the asynchronous callback is executed.
-
-
-### Use coroutine::Wait with for loops
-
-Coroutines make it very easy to write asynchronous code, but the execution of
-the coroutine itself remains sequential. In particular, `for` loops are not run
-in parallel. If you can, avoid the following pattern:
-``` cpp
-std::vector<Result> results;
-for (auto& obj : objects_) {
- Result result;
- // Don't do that! SynchronousFrobinate does not need to wait for the previous
- // call to finish.
- if (SynchronousFrobinate(handler, obj, &result) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return;
- }
- results.push_back(std::move(result));
-}
-```
-
-Instead, make the asynchronous calls directly and use
-[coroutine::Waiter](coroutine_waiter.h) to collate the results:
-``` cpp
-auto waiter = fxl::MakeRefCounted<
- callback::Waiter<Status, std::unique_ptr<Result>>>(Status::OK);
-
-for (auto& obj : objects_) {
- AsyncFrobinate(obj, waiter->NewCallback());
-}
-
-Status status; std::vector<std::unique_ptr<Result>> result;
-if (coroutine::Wait(handler, std::move(waiter), &s, &result) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
-}
-```
diff --git a/bin/ledger/coroutine/context/BUILD.gn b/bin/ledger/coroutine/context/BUILD.gn
deleted file mode 100644
index ef4e62d..0000000
--- a/bin/ledger/coroutine/context/BUILD.gn
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("context") {
- sources = [
- "context.cc",
- "context.h",
- "stack.cc",
- "stack.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/coroutine/context/$target_cpu",
- ]
-
- public_deps = [
- "//zircon/public/lib/zx",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "context_unittest.cc",
- ]
-
- deps = [
- ":context",
- "//garnet/public/lib/fxl",
- "//third_party/googletest:gtest",
- "//zircon/public/lib/fit",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/coroutine/context/arm64/BUILD.gn b/bin/ledger/coroutine/context/arm64/BUILD.gn
deleted file mode 100644
index 964ab20..0000000
--- a/bin/ledger/coroutine/context/arm64/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("arm64") {
- sources = [
- "context.S",
- "context.h",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/coroutine/context/arm64/context.S b/bin/ledger/coroutine/context/arm64/context.S
deleted file mode 100644
index 8b5c411..0000000
--- a/bin/ledger/coroutine/context/arm64/context.S
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <zircon/tls.h>
-
-#include "peridot/bin/ledger/coroutine/context/arm64/context.h"
-
-#define FUNCTION(x) .global x; .type x,%function; x:
-
-// GetContext
-// Captures the state of the CPU in the passed struct.
-// The saved registers are:
-// - All callee saved registers.
-// - SP, Unsafe SP, LR and ARG0.
-FUNCTION(_ZN7context10GetContextEPNS_15InternalContextE)
- stp x19, x20, [x0, #X19_O]
- stp x21, x22, [x0, #X21_O]
- stp x23, x24, [x0, #X23_O]
- stp x25, x26, [x0, #X25_O]
- stp x27, x28, [x0, #X27_O]
- stp x29, x30, [x0, #X29_O]
- mov x2, sp
- str x2, [x0, #SP_O]
- stp d8, d9, [x0, #D8_O]
- stp d10, d11, [x0, #D10_O]
- stp d12, d13, [x0, #D12_O]
- stp d14, d15, [x0, #D14_O]
- mov x1, #0
- str x1, [x0, #X0_O]
-
-#if __has_feature(safe_stack)
- mrs x1, TPIDR_EL0
- ldr x1, [x1, #ZX_TLS_UNSAFE_SP_OFFSET]
- str x1, [x0, #UNSAFE_SP_O]
-#endif
-
- mov x0, #0xFFFFFFFFFFFFFFFF
- ret
-
-// SetContext
-// Restores the state of the CPU from the passed struct.
-// The restored registers are:
-// - All callee saved registers.
-// - SP, Unsafe SP, LR and ARG0.
-FUNCTION(_ZN7context10SetContextEPNS_15InternalContextE)
- // The sanitizer runtime wants to be informed of non-local exits.
- // Call __asan_handle_no_return() before doing the actual longjmp.
-#if __has_feature(address_sanitizer)
- // Save the argument register in a callee-saves register
- // around calling __asan_handle_no_return. We don't need
- // to save the return address since we'll never return to it.
- mov x19, x0
- bl __asan_handle_no_return
- mov x0, x19
-#endif
-
- ldp x19, x20, [x0, #X19_O]
- ldp x21, x22, [x0, #X21_O]
- ldp x23, x24, [x0, #X23_O]
- ldp x25, x26, [x0, #X25_O]
- ldp x27, x28, [x0, #X27_O]
- ldp x29, x30, [x0, #X29_O]
- ldr x2, [x0, #SP_O]
- mov sp, x2
- ldp d8 , d9, [x0, #D8_O]
- ldp d10, d11, [x0, #D10_O]
- ldp d12, d13, [x0, #D12_O]
- ldp d14, d15, [x0, #D14_O]
-
-#if __has_feature(safe_stack)
- ldr x2, [x0, #UNSAFE_SP_O]
- mrs x1, TPIDR_EL0
- str x2, [x1, #ZX_TLS_UNSAFE_SP_OFFSET]
-#endif
-
- ldr x0, [x0, #X0_O]
- br x30
diff --git a/bin/ledger/coroutine/context/arm64/context.h b/bin/ledger/coroutine/context/arm64/context.h
deleted file mode 100644
index 62118d8..0000000
--- a/bin/ledger/coroutine/context/arm64/context.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_ARM64_CONTEXT_H_
-#define PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_ARM64_CONTEXT_H_
-
-// Offset of all saved registers.
-#define X19_O 0
-#define X20_O 8
-#define X21_O 16
-#define X22_O 24
-#define X23_O 32
-#define X24_O 40
-#define X25_O 48
-#define X26_O 56
-#define X27_O 64
-#define X28_O 72
-#define X29_O 80
-#define X30_O 88
-#define SP_O 96
-#define D8_O 104
-#define D9_O 112
-#define D10_O 120
-#define D11_O 128
-#define D12_O 136
-#define D13_O 144
-#define D14_O 152
-#define D15_O 160
-#define X0_O 168
-
-#if __has_feature(safe_stack)
-#define UNSAFE_SP_O 176
-#endif
-
-#ifndef __ASSEMBLER__
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace context {
-
-enum Register {
- REG_X19 = 0,
- REG_X20,
- REG_X21,
- REG_X22,
- REG_X23,
- REG_X24,
- REG_X25,
- REG_X26,
- REG_X27,
- REG_X28,
- REG_X29,
- REG_X30,
- REG_SP,
- REG_D8,
- REG_D9,
- REG_D10,
- REG_D11,
- REG_D12,
- REG_D13,
- REG_D14,
- REG_D15,
- REG_X0,
-#if __has_feature(safe_stack)
- REG_UNSAFE_SP,
-#endif
- NUM_REGISTERS,
-
- // Special registers.
- REG_ARG0 = REG_X0,
- REG_LR = REG_X30,
-};
-
-inline constexpr size_t kAdditionalStackAlignment = 0;
-
-struct InternalContext {
- uint64_t registers[NUM_REGISTERS];
-};
-
-#define ASSERT_REGISTER_OFFSET(REG) \
- static_assert(offsetof(struct InternalContext, \
- registers[context::REG_##REG]) == REG##_O, \
- "offset is incorrect")
-
-ASSERT_REGISTER_OFFSET(X19);
-ASSERT_REGISTER_OFFSET(X20);
-ASSERT_REGISTER_OFFSET(X21);
-ASSERT_REGISTER_OFFSET(X22);
-ASSERT_REGISTER_OFFSET(X23);
-ASSERT_REGISTER_OFFSET(X24);
-ASSERT_REGISTER_OFFSET(X25);
-ASSERT_REGISTER_OFFSET(X26);
-ASSERT_REGISTER_OFFSET(X27);
-ASSERT_REGISTER_OFFSET(X28);
-ASSERT_REGISTER_OFFSET(X29);
-ASSERT_REGISTER_OFFSET(X30);
-ASSERT_REGISTER_OFFSET(SP);
-ASSERT_REGISTER_OFFSET(D8);
-ASSERT_REGISTER_OFFSET(D9);
-ASSERT_REGISTER_OFFSET(D10);
-ASSERT_REGISTER_OFFSET(D11);
-ASSERT_REGISTER_OFFSET(D12);
-ASSERT_REGISTER_OFFSET(D13);
-ASSERT_REGISTER_OFFSET(D14);
-ASSERT_REGISTER_OFFSET(D15);
-ASSERT_REGISTER_OFFSET(X0);
-#if __has_feature(safe_stack)
-ASSERT_REGISTER_OFFSET(UNSAFE_SP);
-#endif
-
-} // namespace context
-
-#endif // __ASSEMBLER__
-
-#endif // PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_ARM64_CONTEXT_H_
diff --git a/bin/ledger/coroutine/context/context.cc b/bin/ledger/coroutine/context/context.cc
deleted file mode 100644
index e9e8ec5..0000000
--- a/bin/ledger/coroutine/context/context.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/coroutine/context/context.h"
-
-#include <lib/fxl/logging.h>
-
-namespace context {
-
-void SwapContext(Context* out_context, Context* in_context) {
- if (!GetContext(out_context)) {
- // Returning from a SetContext, nothing else to do.
- return;
- }
- SetContext(in_context);
-
- FXL_NOTREACHED() << "SetContext should not return.";
-}
-
-void MakeContext(Context* context, Stack* stack, void (*func)(void*),
- void* data) {
- memset(context, 0, sizeof(Context));
-
- uintptr_t sp = stack->safe_stack() + stack->stack_size();
- // Align stack.
- sp = ((sp + kAdditionalStackAlignment) & (~15)) - kAdditionalStackAlignment;
-
- context->registers[REG_LR] = reinterpret_cast<uintptr_t>(func);
- context->registers[REG_ARG0] = reinterpret_cast<uintptr_t>(data);
- context->registers[REG_SP] = sp;
-
-#if __has_feature(safe_stack)
- uintptr_t unsafe_sp = stack->unsafe_stack() + stack->stack_size();
- // Align stack.
- unsafe_sp = (unsafe_sp & (~15));
-
- context->registers[REG_UNSAFE_SP] = unsafe_sp;
-#endif
-}
-
-} // namespace context
diff --git a/bin/ledger/coroutine/context/context.h b/bin/ledger/coroutine/context/context.h
deleted file mode 100644
index c8d653d..0000000
--- a/bin/ledger/coroutine/context/context.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_CONTEXT_H_
-#define PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_CONTEXT_H_
-
-#include <memory>
-
-#include <lib/fxl/build_config.h>
-
-#include "peridot/bin/ledger/coroutine/context/stack.h"
-
-#if defined(ARCH_CPU_X86_64)
-#include "peridot/bin/ledger/coroutine/context/x64/context.h"
-#elif defined(ARCH_CPU_ARM64)
-#include "peridot/bin/ledger/coroutine/context/arm64/context.h"
-#else
-#error Please add support for your architecture.
-#endif
-
-namespace context {
-
-// Context is architecture dependent.
-using Context = InternalContext;
-
-// Initializes |context| to the currently active execution context. Return
-// |true| on the first return of this function. If this context is later resumed
-// using SetContext or SwapContext, the execution will start with this function
-// returning false.
-extern bool GetContext(Context* context);
-
-// Restores the execution context pointed at by |context|. This function never
-// returns. The program execution will continue as if the call to |GetContext|,
-// |MakeContext| or |SwapContext| that created |context| just returned.
-extern void SetContext(Context* context);
-
-// Initializes |context| to a new context. When this context is later activated,
-// |func| is called with |data| as parameter. The stack will be |stack|. |func|
-// must never return.
-//
-// NOLINT suppresses false-positive redundant declaration check due to a
-// friend declaration in stack.h.
-void MakeContext(Context* context, // NOLINT
- Stack* stack, void (*func)(void*), void* data);
-
-// Saves the current execution context in |old_context| and activates the
-// execution context pointed by |in_context|.
-void SwapContext(Context* out_context, Context* in_context);
-
-} // namespace context
-
-#endif // PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_CONTEXT_H_
diff --git a/bin/ledger/coroutine/context/context_unittest.cc b/bin/ledger/coroutine/context/context_unittest.cc
deleted file mode 100644
index 5cc8030..0000000
--- a/bin/ledger/coroutine/context/context_unittest.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/coroutine/context/context.h"
-
-#include <string.h>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/compiler_specific.h>
-#include <lib/fxl/logging.h>
-
-#include "gtest/gtest.h"
-
-namespace context {
-
-#if __has_feature(safe_stack)
-char* GetUnsafeStackForTest(const Stack& stack) {
- return reinterpret_cast<char*>(stack.unsafe_stack());
-}
-#endif
-
-namespace {
-
-// Function using variable args to generate mmx code on x86_64. Running this
-// without crashing ensures that the stack is correctly aligned.
-int UseMMX(const char* format, ...) {
- va_list va;
- va_start(va, format);
- int result = vsnprintf(nullptr, 0, format, va);
- va_end(va);
- return result;
-}
-
-size_t Fact(size_t n) {
- if (n == 0) {
- return 1;
- }
- return n * Fact(n - 1);
-}
-
-void RunInContext(void* data) {
- auto runnable = reinterpret_cast<fit::function<void()>*>(data);
- (*runnable)();
-}
-
-TEST(Context, GetContext) {
- Context context;
- EXPECT_TRUE(GetContext(&context));
-}
-
-TEST(Context, SetContext) {
- Context context;
- volatile size_t nb_calls = 0;
-
- volatile bool result = GetContext(&context);
- ++nb_calls;
- if (result) {
- SetContext(&context);
- }
-
- EXPECT_EQ(2u, nb_calls);
-}
-
-TEST(Context, MakeContext) {
- Stack stack;
-
- Context new_context;
- Context old_context;
-
- size_t f = 0u;
- int va_args_result = 0;
- fit::function<void()> runnable = [&]() {
- f = Fact(5);
- va_args_result = UseMMX("Hello %d %d\n", 1, 2);
- SetContext(&old_context);
- };
-
- MakeContext(&new_context, &stack, &RunInContext, &runnable);
-
- SwapContext(&old_context, &new_context);
-
- EXPECT_EQ(120u, f);
- EXPECT_EQ(10, va_args_result);
-}
-
-struct ThreadLocalContext {
- static thread_local char* thread_local_ptr;
-
- char* ptr = nullptr;
- Context old_context;
-};
-
-thread_local char* ThreadLocalContext::thread_local_ptr = nullptr;
-
-void GetThreadLocalPointer(void* context) {
- auto thread_local_context = reinterpret_cast<ThreadLocalContext*>(context);
- thread_local_context->ptr = ThreadLocalContext::thread_local_ptr;
- SetContext(&thread_local_context->old_context);
-}
-
-TEST(Context, ThreadLocal) {
- Stack stack;
- ThreadLocalContext context;
-
- char c = 'a';
- ThreadLocalContext::thread_local_ptr = &c;
-
- Context new_context;
-
- EXPECT_TRUE(GetContext(&new_context));
- MakeContext(&new_context, &stack, &GetThreadLocalPointer, &context);
-
- SwapContext(&context.old_context, &new_context);
-
- EXPECT_EQ(&c, context.ptr);
-}
-
-#if __has_feature(safe_stack)
-// Force to set the pointed address to 1. This must be no-inline to prevent the
-// compiler to optimize away the set.
-FXL_NOINLINE void ForceSet(volatile char* addr) { *addr = 1; }
-
-// Write some data to the unsafe stack.
-void TrashStack(void* context) {
- volatile char buffer[1024];
- for (size_t i = 0; i < 6; ++i) {
- ForceSet(buffer + Fact(i));
- }
-
- SetContext(reinterpret_cast<Context*>(context));
-}
-
-TEST(Context, MakeContextUnsafeStack) {
- Stack stack;
- memset(GetUnsafeStackForTest(stack), 0, stack.stack_size());
-
- Context new_context;
- Context old_context;
-
- EXPECT_TRUE(GetContext(&new_context));
- MakeContext(&new_context, &stack, &TrashStack, &old_context);
-
- SwapContext(&old_context, &new_context);
-
- bool found = false;
- char* ptr = GetUnsafeStackForTest(stack);
- for (size_t i = 0; i < stack.stack_size(); ++i) {
- found = found || *(ptr + i);
- }
- EXPECT_TRUE(found);
-}
-
-__NO_SAFESTACK intptr_t GetSafeStackPointer() {
- char a = 0;
- // Suppress check about returning a stack memory address.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreturn-stack-address"
- return reinterpret_cast<intptr_t>(&a); // NOLINT
-#pragma clang diagnostic pop
-}
-
-void CheckDistinctStack(void* context) {
- char buff[1];
- memset(buff, 0, sizeof(buff));
- // buff is on the unsafe stack, GetSafeStackPointer() returns a value on the
- // safe stack. This checks that the address of the 2 stacks are separated at
- // least by 2 PAGE_SIZE, given that each stack has a guard.
- EXPECT_GE(std::abs(reinterpret_cast<intptr_t>(buff) - GetSafeStackPointer()),
- 2 * PAGE_SIZE);
-
- SetContext(reinterpret_cast<Context*>(context));
-}
-
-TEST(Context, CheckStacksAreDifferent) {
- Stack stack;
-
- Context new_context;
- Context old_context;
-
- EXPECT_TRUE(GetContext(&new_context));
- MakeContext(&new_context, &stack, &CheckDistinctStack, &old_context);
-
- SwapContext(&old_context, &new_context);
-}
-#endif
-
-} // namespace
-} // namespace context
diff --git a/bin/ledger/coroutine/context/stack.cc b/bin/ledger/coroutine/context/stack.cc
deleted file mode 100644
index 1868f14..0000000
--- a/bin/ledger/coroutine/context/stack.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/coroutine/context/stack.h"
-
-#include <stdlib.h>
-
-#include <lib/fxl/logging.h>
-#include <lib/zx/vmar.h>
-
-namespace context {
-
-namespace {
-size_t ToFullPages(size_t value) {
- return (value + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));
-}
-
-// ASAN doesn't instrument vmo mappings. Use traditional malloc/free when
-// running with ASAN.
-#if __has_feature(address_sanitizer)
-// ASAN doesn't support safe stack.
-static_assert(!__has_feature(safe_stack),
- "Add support for safe stack under ASAN");
-
-void AllocateASAN(size_t stack_size, uintptr_t* stack) {
- *stack = reinterpret_cast<uintptr_t>(malloc(stack_size));
- FXL_DCHECK(*stack);
-}
-
-void ReleaseASAN(uintptr_t stack) { free(reinterpret_cast<void*>(stack)); }
-
-#else // __has_feature(address_sanitizer)
-
-constexpr size_t kStackGuardSize = PAGE_SIZE;
-
-#if __has_feature(safe_stack)
-constexpr size_t kVmoSizeMultiplier = 2u;
-#else
-constexpr size_t kVmoSizeMultiplier = 1u;
-#endif
-
-void AllocateStack(const zx::vmo& vmo, size_t vmo_offset, size_t stack_size,
- zx::vmar* vmar, uintptr_t* addr) {
- uintptr_t allocate_address;
- zx_status_t status = zx::vmar::root_self()->allocate(
- 0, stack_size + 2 * kStackGuardSize,
- ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC, vmar,
- &allocate_address);
- FXL_DCHECK(status == ZX_OK);
-
- status = vmar->map(kStackGuardSize, vmo, vmo_offset, stack_size,
- ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC, addr);
- FXL_DCHECK(status == ZX_OK);
-}
-
-#endif // __has_feature(address_sanitizer)
-} // namespace
-
-#if __has_feature(address_sanitizer)
-
-Stack::Stack(size_t stack_size) : stack_size_(ToFullPages(stack_size)) {
- FXL_DCHECK(stack_size_);
-
- AllocateASAN(stack_size_, &safe_stack_);
-}
-
-Stack::~Stack() { ReleaseASAN(safe_stack_); }
-
-void Stack::Release() {
- ReleaseASAN(safe_stack_);
- AllocateASAN(stack_size_, &safe_stack_);
-}
-
-#else // __has_feature(address_sanitizer)
-
-Stack::Stack(size_t stack_size) : stack_size_(ToFullPages(stack_size)) {
- FXL_DCHECK(stack_size_);
- zx_status_t status =
- zx::vmo::create(kVmoSizeMultiplier * stack_size_, 0, &vmo_);
- FXL_DCHECK(status == ZX_OK);
-
- AllocateStack(vmo_, 0, stack_size_, &safe_stack_mapping_, &safe_stack_);
- FXL_DCHECK(safe_stack_);
-
-#if __has_feature(safe_stack)
- AllocateStack(vmo_, stack_size_, stack_size_, &unsafe_stack_mapping_,
- &unsafe_stack_);
- FXL_DCHECK(unsafe_stack_);
-#endif
-}
-
-Stack::~Stack() {
- safe_stack_mapping_.destroy();
-#if __has_feature(safe_stack)
- unsafe_stack_mapping_.destroy();
-#endif
-}
-
-void Stack::Release() {
- zx_status_t status = vmo_.op_range(
- ZX_VMO_OP_DECOMMIT, 0, kVmoSizeMultiplier * stack_size_, nullptr, 0);
- FXL_DCHECK(status == ZX_OK);
-}
-
-#endif // __has_feature(address_sanitizer)
-
-} // namespace context
diff --git a/bin/ledger/coroutine/context/stack.h b/bin/ledger/coroutine/context/stack.h
deleted file mode 100644
index a8b599c..0000000
--- a/bin/ledger/coroutine/context/stack.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_STACK_H_
-#define PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_STACK_H_
-
-#include <stddef.h>
-
-#include <lib/zx/vmar.h>
-#include <lib/zx/vmo.h>
-
-namespace context {
-
-struct InternalContext;
-using Context = InternalContext;
-
-// A stack to be used with |MakeContext|.
-class Stack {
- public:
- // Creates a new stack. |stack_size| is the minimal size of the new stack.
- explicit Stack(size_t stack_size = 64 * 1024);
- ~Stack();
-
- // Releases the memory associated with this stack. After this call, the stack
- // is ready to be used again, but its content is not specified.
- void Release();
-
- size_t stack_size() const { return stack_size_; }
-
- uintptr_t safe_stack() const { return safe_stack_; }
-#if __has_feature(safe_stack)
- uintptr_t unsafe_stack() const { return unsafe_stack_; };
-#endif
-
- private:
- const size_t stack_size_;
- zx::vmo vmo_;
- zx::vmar safe_stack_mapping_;
- uintptr_t safe_stack_;
-#if __has_feature(safe_stack)
- zx::vmar unsafe_stack_mapping_;
- uintptr_t unsafe_stack_;
-#endif
-};
-} // namespace context
-
-#endif // PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_STACK_H_
diff --git a/bin/ledger/coroutine/context/x64/BUILD.gn b/bin/ledger/coroutine/context/x64/BUILD.gn
deleted file mode 100644
index 9d4fdb4..0000000
--- a/bin/ledger/coroutine/context/x64/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("x64") {
- sources = [
- "context.S",
- "context.h",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/coroutine/context/x64/context.S b/bin/ledger/coroutine/context/x64/context.S
deleted file mode 100644
index 153c259..0000000
--- a/bin/ledger/coroutine/context/x64/context.S
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <zircon/tls.h>
-
-#include "peridot/bin/ledger/coroutine/context/x64/context.h"
-
-#define FUNCTION(x) .global x; .type x,%function; x:
-
-// GetContext
-// Captures the state of the CPU in the passed struct.
-// The saved registers are:
-// - All callee saved registers.
-// - SP, Unsafe SP, LR and ARG0.
-FUNCTION(_ZN7context10GetContextEPNS_15InternalContextE)
- movq %rbx, RBX_O(%rdi)
- movq %rbp, RBP_O(%rdi)
- movq %r12, R12_O(%rdi)
- movq %r13, R13_O(%rdi)
- movq %r14, R14_O(%rdi)
- movq %r15, R15_O(%rdi)
- movq %rdi, RDI_O(%rdi)
-
-#if __has_feature(safe_stack)
- movq %fs:ZX_TLS_UNSAFE_SP_OFFSET, %rax
- movq %rax, UNSAFE_SP_O(%rdi)
-#endif
-
- # Skip return address.
- leaq 8(%rsp), %rax
- movq %rax, RSP_O(%rdi)
- # Store return value in rip.
- movq (%rsp), %rax
- movq %rax, RIP_O(%rdi)
-
- // Returns true for initial call.
- xor %rax, %rax
- dec %rax
- ret
-
-// SetContext
-// Restores the state of the CPU from the passed struct.
-// The restored registers are:
-// - All callee saved registers.
-// - SP, Unsafe SP, LR and ARG0.
-FUNCTION(_ZN7context10SetContextEPNS_15InternalContextE)
- // The sanitizer runtime wants to be informed of non-local exits.
- // Call __asan_handle_no_return() before doing the actual longjmp.
-#if __has_feature(address_sanitizer)
- // Save our incoming argument register on the stack around calling
- // __asan_handle_no_return. The incoming stack is misaligned by one
- // word, so we need to move the stack by an odd number of words.
- push %rdi
- call __asan_handle_no_return@PLT
- pop %rdi
-#endif
-
- movq RBX_O(%rdi), %rbx
- movq RBP_O(%rdi), %rbp
- movq R12_O(%rdi), %r12
- movq R13_O(%rdi), %r13
- movq R14_O(%rdi), %r14
- movq R15_O(%rdi), %r15
- movq RSP_O(%rdi), %rsp
-
-#if __has_feature(safe_stack)
- movq UNSAFE_SP_O(%rdi), %rax
- movq %rax, %fs:ZX_TLS_UNSAFE_SP_OFFSET
-#endif
-
- # Returns 0.
- xor %rax, %rax
-
- # Get the return address.
- movq RIP_O(%rdi), %rcx
-
- # Set RDI at the end.
- movq RDI_O(%rdi), %rdi
-
- # Jump directly to the return address.
- jmp *%rcx
diff --git a/bin/ledger/coroutine/context/x64/context.h b/bin/ledger/coroutine/context/x64/context.h
deleted file mode 100644
index fbc68fc..0000000
--- a/bin/ledger/coroutine/context/x64/context.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_X64_CONTEXT_H_
-#define PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_X64_CONTEXT_H_
-
-// Offset of all saved registers.
-#define RBX_O 0
-#define RBP_O 8
-#define R12_O 16
-#define R13_O 24
-#define R14_O 32
-#define R15_O 40
-#define RDI_O 48
-#define RSP_O 56
-#define RIP_O 64
-
-#if __has_feature(safe_stack)
-#define UNSAFE_SP_O 72
-#endif
-
-#ifndef __ASSEMBLER__
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace context {
-
-enum Register {
- REG_RBX = 0,
- REG_RBP,
- REG_R12,
- REG_R13,
- REG_R14,
- REG_R15,
- REG_RDI,
- REG_RSP,
- REG_RIP,
-#if __has_feature(safe_stack)
- REG_UNSAFE_SP,
-#endif
- NUM_REGISTERS,
-
- // Special registers.
- REG_ARG0 = REG_RDI,
- REG_LR = REG_RIP,
- REG_SP = REG_RSP,
-};
-
-inline constexpr size_t kAdditionalStackAlignment = 8;
-
-struct InternalContext {
- uint64_t registers[NUM_REGISTERS];
-};
-
-#define ASSERT_REGISTER_OFFSET(REG) \
- static_assert(offsetof(struct InternalContext, \
- registers[context::REG_##REG]) == REG##_O, \
- "offset is incorrect")
-
-ASSERT_REGISTER_OFFSET(RBX);
-ASSERT_REGISTER_OFFSET(RBP);
-ASSERT_REGISTER_OFFSET(R12);
-ASSERT_REGISTER_OFFSET(R13);
-ASSERT_REGISTER_OFFSET(R14);
-ASSERT_REGISTER_OFFSET(R15);
-ASSERT_REGISTER_OFFSET(RDI);
-ASSERT_REGISTER_OFFSET(RSP);
-ASSERT_REGISTER_OFFSET(RIP);
-#if __has_feature(safe_stack)
-ASSERT_REGISTER_OFFSET(UNSAFE_SP);
-#endif
-
-} // namespace context
-
-#endif // __ASSEMBLER__
-
-#endif // PERIDOT_BIN_LEDGER_COROUTINE_CONTEXT_X64_CONTEXT_H_
diff --git a/bin/ledger/coroutine/coroutine.h b/bin/ledger/coroutine/coroutine.h
deleted file mode 100644
index 79cdb25..0000000
--- a/bin/ledger/coroutine/coroutine.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_H_
-#define PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_H_
-
-#include <functional>
-
-#include <lib/callback/capture.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_counted.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-// This Coroutine library allows to use coroutines. A coroutine is a function
-// that can interrupt itself by yielding, and the computation will resume at the
-// same point when another context of execution resumes the coroutine using
-// its handler.
-namespace coroutine {
-
-// The status of a coroutine when it returns from Yield.
-enum class ContinuationStatus : bool {
- // The coroutine is in its standard state. Computation can continue.
- OK,
- // The coroutine has been interrupted, it must unwind its stack and terminate.
- INTERRUPTED,
-};
-
-// The Handler of a coroutine. It allows a coroutine to yield and another
-// context of execution to resume the computation.
-//
-// Threading: until the first Yield(), the coroutine executes on the thread that
-// called CoroutineService::StartCoroutine(). Between Yield() and Resume(),
-// the handler can be passed to another thread - the computation resumes on the
-// thread that called Resume().
-class CoroutineHandler {
- public:
- virtual ~CoroutineHandler() {}
-
- // Yield the current coroutine. This must only be called from inside the
- // coroutine associated with this handler. If Yield returns |INTERRUPTED|, the
- // coroutine must unwind its stack and terminate.
- FXL_WARN_UNUSED_RESULT virtual ContinuationStatus Yield() = 0;
-
- // Restarts the computation of the coroutine associated with this handler.
- // This must only be called outside of the coroutine when it is yielded. If
- // |status| is |INTERRUPTED|, |Yield| will return |INTERRUPTED| when the
- // coroutine is resumed, asking it to terminate.
- virtual void Resume(ContinuationStatus status) = 0;
-};
-
-// The service handling coroutines. It allows to create new coroutines.
-// Destructing the service will terminate all active coroutines. All the
-// non-terminated coroutines will eventually be activated and asked to
-// terminate.
-class CoroutineService {
- public:
- virtual ~CoroutineService() {}
-
- // Starts a new coroutine that will execute |runnable|.
- virtual void StartCoroutine(
- fit::function<void(CoroutineHandler*)> runnable) = 0;
-};
-
-// Allows to execute an asynchronous call in a coroutine. The coroutine will
-// yield until the asynchronous call terminates, it will then be resumed and
-// will store the results of the asynchronous calls in |parameters|. If
-// |SyncCall| returns |INTERRUPTED|, the coroutine must unwind its stack and
-// terminate.
-//
-// |async_call| will be never be called after this method returns. As such, it
-// can capture local variables by reference.
-//
-// For instance, suppose you have the following asynchronous function
-// LongAsyncComputation that signals its completion by passing the computed
-// string and integer to a callback:
-//
-// void LongAsyncComputation(fit::function<void(std::string, int)> on_done);
-//
-// Here is how to execute it synchronously in a coroutine:
-//
-// CoroutineHandler* handler;
-// std::string s; int i;
-// if (SyncCall(handler, &LongAsyncComputation, &s, &i) ==
-// ContinuationStatus::INTERRUPTED) {
-// return ContinuationStatus::INTERRUPTED;
-// }
-// FXL_LOG(INFO) << "LongAsyncComputation returned: " << s << " " << i;
-//
-// Another usage pattern is to have a lambda in place of LongAsyncComputation,
-// that will immediately store the callback provided by SyncCall in some
-// ancillary data structure. The SyncCall will then yield until some other part
-// of the code invokes this callback with a result:
-//
-// if (SyncCall(handler,
-// [this](fit::function<void(string, int)> on_done) {
-// pending_callbacks_.emplace_back(std::move(on_done));
-// },
-// &s, &i) == ContinuationStatus::INTERRUPTED) {
-// return ContinuationStatus::INTERRUPTED;
-// }
-// FXL_LOG(INFO) << "Some background task computed: " << s << " " << i;
-//
-template <typename A, typename... Args>
-FXL_WARN_UNUSED_RESULT ContinuationStatus SyncCall(CoroutineHandler* handler,
- A async_call,
- Args*... parameters) {
- class TerminationSentinel
- : public fxl::RefCountedThreadSafe<TerminationSentinel> {
- public:
- bool terminated = false;
- };
-
- auto termination_sentinel = fxl::MakeRefCounted<TerminationSentinel>();
- auto on_return = fit::defer(
- [termination_sentinel] { termination_sentinel->terminated = true; });
-
- volatile bool sync_state = true;
- volatile bool callback_called = false;
- // Unblock the coroutine (by having it return early) if the asynchronous call
- // drops its callback without ever calling it.
- auto unblocker = fit::defer([termination_sentinel, &handler, &sync_state] {
- if (termination_sentinel->terminated) {
- return;
- }
-
- if (sync_state) {
- sync_state = false;
- return;
- }
- handler->Resume(ContinuationStatus::INTERRUPTED);
- });
- auto capture = callback::Capture(
- [&sync_state, &callback_called, handler,
- unblocker = std::move(unblocker)]() mutable {
- // |capture| is already gated by the termination sentinel below. No need
- // to re-check here.
-
- unblocker.cancel();
- callback_called = true;
- if (sync_state) {
- sync_state = false;
- return;
- }
- handler->Resume(ContinuationStatus::OK);
- },
- parameters...);
- async_call([termination_sentinel,
- capture = std::move(capture)](Args... args) mutable {
- if (termination_sentinel->terminated) {
- return;
- }
- capture(std::forward<Args>(args)...);
- });
- // If sync_state is still true, the callback was not called. Yield until it
- // is.
- if (sync_state) {
- sync_state = false;
- return handler->Yield();
- }
- return callback_called ? ContinuationStatus::OK
- : ContinuationStatus::INTERRUPTED;
-};
-
-} // namespace coroutine
-
-#endif // PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_H_
diff --git a/bin/ledger/coroutine/coroutine_impl.cc b/bin/ledger/coroutine/coroutine_impl.cc
deleted file mode 100644
index e250a1e..0000000
--- a/bin/ledger/coroutine/coroutine_impl.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-
-#include <lib/fit/function.h>
-
-#if __has_feature(address_sanitizer)
-#include <sanitizer/common_interface_defs.h>
-#endif
-
-#include <lib/fxl/logging.h>
-#include "peridot/bin/ledger/coroutine/context/context.h"
-#include "peridot/bin/ledger/coroutine/context/stack.h"
-
-namespace coroutine {
-
-constexpr size_t kMaxAvailableStacks = 25;
-
-class CoroutineServiceImpl::CoroutineHandlerImpl : public CoroutineHandler {
- public:
- CoroutineHandlerImpl(std::unique_ptr<context::Stack> stack,
- fit::function<void(CoroutineHandler*)> runnable);
- ~CoroutineHandlerImpl() override;
-
- // CoroutineHandler.
- ContinuationStatus Yield() override;
- void Resume(ContinuationStatus status) override;
-
- void Start();
- void set_cleanup(
- fit::function<void(std::unique_ptr<context::Stack>)> cleanup) {
- cleanup_ = std::move(cleanup);
- }
-
- private:
- static void StaticRun(void* data);
- void Run();
- ContinuationStatus DoYield();
-
- std::unique_ptr<context::Stack> stack_;
- fit::function<void(CoroutineHandler*)> runnable_;
- fit::function<void(std::unique_ptr<context::Stack>)> cleanup_;
- context::Context main_context_;
- context::Context routine_context_;
- bool interrupted_ = false;
- bool finished_ = false;
-#if __has_feature(address_sanitizer)
- const void* origin_stack_ = nullptr;
- size_t origin_stacksize_ = 0;
-#endif
-
- FXL_DISALLOW_COPY_AND_ASSIGN(CoroutineHandlerImpl);
-};
-
-CoroutineServiceImpl::CoroutineHandlerImpl::CoroutineHandlerImpl(
- std::unique_ptr<context::Stack> stack,
- fit::function<void(CoroutineHandler*)> runnable)
- : stack_(std::move(stack)), runnable_(std::move(runnable)) {
- FXL_DCHECK(stack_);
- FXL_DCHECK(runnable_);
-}
-
-CoroutineServiceImpl::CoroutineHandlerImpl::~CoroutineHandlerImpl() {
- FXL_DCHECK(!stack_);
-}
-
-ContinuationStatus CoroutineServiceImpl::CoroutineHandlerImpl::Yield() {
- FXL_DCHECK(!interrupted_);
-
- if (interrupted_) {
- return ContinuationStatus::INTERRUPTED;
- }
-
- return DoYield();
-}
-
-void CoroutineServiceImpl::CoroutineHandlerImpl::Resume(
- ContinuationStatus status) {
- FXL_DCHECK(!finished_);
-
- interrupted_ = interrupted_ || (status == ContinuationStatus::INTERRUPTED);
-#if __has_feature(address_sanitizer)
- void* fake_stack_save;
- __sanitizer_start_switch_fiber(
- &fake_stack_save, reinterpret_cast<const void*>(stack_->safe_stack()),
- stack_->stack_size());
-#endif
- context::SwapContext(&main_context_, &routine_context_);
-#if __has_feature(address_sanitizer)
- __sanitizer_finish_switch_fiber(fake_stack_save, nullptr, nullptr);
-#endif
-
- if (finished_) {
- cleanup_(std::move(stack_));
- // this object has been deleted by |cleanup_|, return.
- return;
- }
-}
-
-void CoroutineServiceImpl::CoroutineHandlerImpl::Start() {
- context::MakeContext(&routine_context_, stack_.get(),
- &CoroutineServiceImpl::CoroutineHandlerImpl::StaticRun,
- this);
- Resume(ContinuationStatus::OK);
-}
-
-void CoroutineServiceImpl::CoroutineHandlerImpl::StaticRun(void* data) {
- reinterpret_cast<CoroutineHandlerImpl*>(data)->Run();
-}
-
-void CoroutineServiceImpl::CoroutineHandlerImpl::Run() {
-#if __has_feature(address_sanitizer)
- __sanitizer_finish_switch_fiber(nullptr, &origin_stack_, &origin_stacksize_);
-#endif
- runnable_(this);
- // Delete |runnable_|, as it can have side effects that should be run inside
- // the co-routine.
- runnable_ = [](CoroutineHandler*) {};
- finished_ = true;
- DoYield();
- FXL_NOTREACHED() << "Last yield should never return.";
-}
-
-ContinuationStatus CoroutineServiceImpl::CoroutineHandlerImpl::DoYield() {
-#if __has_feature(address_sanitizer)
- FXL_DCHECK(origin_stack_);
- FXL_DCHECK(origin_stacksize_);
- void* fake_stack_save = nullptr;
- __sanitizer_start_switch_fiber(finished_ ? nullptr : &fake_stack_save,
- origin_stack_, origin_stacksize_);
-#endif
- context::SwapContext(&routine_context_, &main_context_);
-#if __has_feature(address_sanitizer)
- __sanitizer_finish_switch_fiber(fake_stack_save, &origin_stack_,
- &origin_stacksize_);
-#endif
-
- return interrupted_ ? ContinuationStatus::INTERRUPTED
- : ContinuationStatus::OK;
-}
-
-CoroutineServiceImpl::CoroutineServiceImpl() {}
-
-CoroutineServiceImpl::~CoroutineServiceImpl() {
- while (!handlers_.empty()) {
- handlers_.back()->Resume(ContinuationStatus::INTERRUPTED);
- }
-}
-
-void CoroutineServiceImpl::StartCoroutine(
- fit::function<void(CoroutineHandler* handler)> runnable) {
- std::unique_ptr<context::Stack> stack;
- if (available_stack_.empty()) {
- stack = std::make_unique<context::Stack>();
- } else {
- stack = std::move(available_stack_.back());
- available_stack_.pop_back();
- }
- auto handler = std::make_unique<CoroutineHandlerImpl>(std::move(stack),
- std::move(runnable));
- auto handler_ptr = handler.get();
- handler->set_cleanup([this,
- handler_ptr](std::unique_ptr<context::Stack> stack) {
- if (available_stack_.size() < kMaxAvailableStacks) {
- stack->Release();
- available_stack_.push_back(std::move(stack));
- }
- handlers_.erase(std::find_if(
- handlers_.begin(), handlers_.end(),
- [handler_ptr](const std::unique_ptr<CoroutineHandlerImpl>& handler) {
- return handler.get() == handler_ptr;
- }));
- });
- handlers_.push_back(std::move(handler));
- handler_ptr->Start();
-}
-
-} // namespace coroutine
diff --git a/bin/ledger/coroutine/coroutine_impl.h b/bin/ledger/coroutine/coroutine_impl.h
deleted file mode 100644
index 2677ad3..0000000
--- a/bin/ledger/coroutine/coroutine_impl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_IMPL_H_
-#define PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_IMPL_H_
-
-#include <memory>
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-
-namespace context {
-class Stack;
-}
-
-namespace coroutine {
-
-class CoroutineServiceImpl : public CoroutineService {
- public:
- CoroutineServiceImpl();
- ~CoroutineServiceImpl() override;
-
- // CoroutineService.
- void StartCoroutine(fit::function<void(CoroutineHandler*)> runnable) override;
-
- private:
- class CoroutineHandlerImpl;
-
- std::vector<std::unique_ptr<context::Stack>> available_stack_;
- std::vector<std::unique_ptr<CoroutineHandlerImpl>> handlers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(CoroutineServiceImpl);
-};
-
-} // namespace coroutine
-
-#endif // PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_IMPL_H_
diff --git a/bin/ledger/coroutine/coroutine_manager.h b/bin/ledger/coroutine/coroutine_manager.h
deleted file mode 100644
index 8748219..0000000
--- a/bin/ledger/coroutine/coroutine_manager.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_MANAGER_H_
-#define PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_MANAGER_H_
-
-#include <algorithm>
-#include <list>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-
-namespace coroutine {
-// CoroutineManager manages the lifetime of coroutines.
-class CoroutineManager {
- public:
- explicit CoroutineManager(CoroutineService* service) : service_(service) {}
-
- ~CoroutineManager() {
- // Interrupt any active handlers.
- while (!handlers_.empty()) {
- (*handlers_.begin())->Resume(coroutine::ContinuationStatus::INTERRUPTED);
- }
- }
-
- CoroutineManager(const CoroutineManager&) = delete;
- const CoroutineManager& operator=(const CoroutineManager&) = delete;
-
- // Starts a managed coroutine. This coroutine will be automatically
- // interrupted if this |CoroutineManager| object is destroyed.
- //
- // |callback| must be a callable object
- // |runnable| must be a callable object with the following signature:
- // void(CoroutineHandler*, fit::function<void(Args...)>)
- // When the second argument of |runnable| is called, the coroutine is
- // unregistered from the manager object and |callback| is called with the same
- // arguments. It is an error to exit the coroutine without calling
- // |runnable|'s callback.
- template <typename Callback, typename Runnable>
- void StartCoroutine(Callback callback, Runnable runnable) {
- service_->StartCoroutine(
- [this, callback = std::move(callback),
- runnable = std::move(runnable)](CoroutineHandler* handler) mutable {
- auto iter = handlers_.insert(handlers_.cend(), handler);
- auto final_callback = [this, iter,
- callback = std::move(callback)](auto... args) {
- // Remove the handler before calling the final callback. Otherwise
- // the handler might be unnecessarily interrupted, if this object
- // destructor is called in the callback.
- handlers_.erase(iter);
- callback(std::move(args)...);
- };
-
- runnable(handler, std::move(final_callback));
-
- // Verify that the handler is correctly unregistered. It would be a
- // bug otherwise.
- FXL_DCHECK(std::find(handlers_.begin(), handlers_.end(), handler) ==
- handlers_.end());
- });
- }
-
- // Starts a managed coroutine. This coroutine will be automatically
- // interrupted if this |CoroutineManager| object is destroyed.
- //
- // |runnable| must be a callable object with the following signature:
- // void(CoroutineHandler*)
- template <typename Runnable>
- void StartCoroutine(Runnable runnable) {
- service_->StartCoroutine([this, runnable = std::move(runnable)](
- CoroutineHandler* handler) mutable {
- auto iter = handlers_.insert(handlers_.cend(), handler);
- runnable(handler);
- handlers_.erase(iter);
- });
- }
-
- private:
- std::list<coroutine::CoroutineHandler*> handlers_;
- CoroutineService* const service_;
-};
-
-} // namespace coroutine
-
-#endif // PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_MANAGER_H_
diff --git a/bin/ledger/coroutine/coroutine_manager_unittest.cc b/bin/ledger/coroutine/coroutine_manager_unittest.cc
deleted file mode 100644
index 9c1499b..0000000
--- a/bin/ledger/coroutine/coroutine_manager_unittest.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/coroutine/coroutine_manager.h"
-
-#include <memory>
-
-#include <lib/callback/set_when_called.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-
-namespace coroutine {
-namespace {
-
-TEST(CoroutineManager, CallbackIsCalled) {
- CoroutineServiceImpl coroutine_service;
- CoroutineManager manager(&coroutine_service);
-
- bool called = false;
- CoroutineHandler* handler = nullptr;
- manager.StartCoroutine(callback::SetWhenCalled(&called),
- [&handler](CoroutineHandler* current_handler,
- fit::function<void()> callback) {
- handler = current_handler;
- EXPECT_EQ(ContinuationStatus::OK, handler->Yield());
- callback();
- });
-
- ASSERT_TRUE(handler);
- EXPECT_FALSE(called);
- handler->Resume(ContinuationStatus::OK);
- EXPECT_TRUE(called);
-}
-
-TEST(CoroutineManager, InterruptCoroutineOnDestruction) {
- CoroutineServiceImpl coroutine_service;
- std::unique_ptr<CoroutineManager> manager =
- std::make_unique<CoroutineManager>(&coroutine_service);
-
- bool called = false;
- CoroutineHandler* handler = nullptr;
- manager->StartCoroutine(callback::SetWhenCalled(&called),
- [&handler](CoroutineHandler* current_handler,
- fit::function<void()> callback) {
- handler = current_handler;
- EXPECT_EQ(ContinuationStatus::INTERRUPTED,
- handler->Yield());
- callback();
- });
-
- ASSERT_TRUE(handler);
- EXPECT_FALSE(called);
- manager.reset();
- EXPECT_TRUE(called);
-}
-
-TEST(CoroutineManager, NoCallback) {
- CoroutineServiceImpl coroutine_service;
- CoroutineManager manager(&coroutine_service);
-
- CoroutineHandler* handler = nullptr;
- manager.StartCoroutine([&handler](CoroutineHandler* current_handler) {
- handler = current_handler;
- EXPECT_EQ(ContinuationStatus::OK, handler->Yield());
- });
-
- ASSERT_TRUE(handler);
- handler->Resume(ContinuationStatus::OK);
-}
-
-} // namespace
-} // namespace coroutine
diff --git a/bin/ledger/coroutine/coroutine_unittest.cc b/bin/ledger/coroutine/coroutine_unittest.cc
deleted file mode 100644
index ce56332..0000000
--- a/bin/ledger/coroutine/coroutine_unittest.cc
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-
-namespace coroutine {
-namespace {
-
-size_t Fact(size_t n) {
- if (n == 0) {
- return 1;
- }
- return Fact(n - 1) * n;
-}
-
-void UseStack() { EXPECT_EQ(120u, Fact(5)); }
-
-TEST(Coroutine, SingleRoutine) {
- CoroutineServiceImpl coroutine_service;
-
- CoroutineHandler* handler = nullptr;
- constexpr int kLoopCount = 10;
- int result = kLoopCount;
-
- coroutine_service.StartCoroutine(
- [&handler, &result](CoroutineHandler* current_handler) {
- handler = current_handler;
- UseStack();
- do {
- EXPECT_EQ(ContinuationStatus::OK, current_handler->Yield());
- UseStack();
- --result;
- } while (result);
- });
-
- EXPECT_TRUE(handler);
- EXPECT_EQ(kLoopCount, result);
-
- for (int i = kLoopCount - 1; i >= 0; --i) {
- handler->Resume(ContinuationStatus::OK);
- EXPECT_EQ(i, result);
- }
-}
-
-TEST(Coroutine, ManyRoutines) {
- constexpr size_t nb_routines = 1000;
-
- CoroutineServiceImpl coroutine_service;
-
- std::set<CoroutineHandler*> handlers;
-
- for (size_t i = 0; i < nb_routines; ++i) {
- coroutine_service.StartCoroutine([&handlers](CoroutineHandler* handler) {
- handlers.insert(handler);
- UseStack();
-
- for (size_t i = 0; i < 3; ++i) {
- EXPECT_EQ(ContinuationStatus::OK, handler->Yield());
- UseStack();
- }
-
- handlers.erase(handlers.find(handler));
- });
- }
-
- EXPECT_EQ(nb_routines, handlers.size());
-
- for (size_t i = 0; i < 2; ++i) {
- for (CoroutineHandler* handler : handlers) {
- handler->Resume(ContinuationStatus::OK);
- }
- }
-
- EXPECT_EQ(nb_routines, handlers.size());
-
- for (size_t i = 0; i < nb_routines; ++i) {
- (*handlers.begin())->Resume(ContinuationStatus::OK);
- }
-
- EXPECT_TRUE(handlers.empty());
-}
-
-TEST(Coroutine, AsyncCall) {
- CoroutineServiceImpl coroutine_service;
-
- fit::function<void(size_t)> callback;
- auto callable = [&callback](fit::function<void(size_t)> called_callback) {
- callback = std::move(called_callback);
- };
-
- size_t received_value = 0;
- coroutine_service.StartCoroutine(
- [callable, &received_value](CoroutineHandler* handler) {
- UseStack();
- size_t value;
- EXPECT_EQ(ContinuationStatus::OK, SyncCall(handler, callable, &value));
- UseStack();
- received_value = value;
- });
-
- EXPECT_TRUE(callback);
- EXPECT_EQ(0u, received_value);
-
- callback(1);
-
- EXPECT_EQ(1u, received_value);
-}
-
-TEST(Coroutine, SynchronousAsyncCall) {
- CoroutineServiceImpl coroutine_service;
-
- size_t received_value = 0;
- coroutine_service.StartCoroutine(
- [&received_value](CoroutineHandler* handler) {
- UseStack();
- EXPECT_EQ(ContinuationStatus::OK,
- SyncCall(
- handler,
- [](fit::function<void(size_t)> callback) { callback(1); },
- &received_value));
- UseStack();
- });
- EXPECT_EQ(1u, received_value);
-}
-
-TEST(Coroutine, DroppedAsyncCall) {
- CoroutineServiceImpl coroutine_service;
-
- bool ended = false;
- coroutine_service.StartCoroutine([&ended](CoroutineHandler* handler) {
- EXPECT_EQ(ContinuationStatus::INTERRUPTED,
- SyncCall(handler, [](fit::function<void()> callback) {
- // |callback| is dropped here.
- }));
- ended = true;
- });
- EXPECT_TRUE(ended);
-}
-
-TEST(Coroutine, DroppedAsyncCallAsynchronously) {
- CoroutineServiceImpl coroutine_service;
-
- bool ended = false;
- fit::function<void()> callback;
-
- coroutine_service.StartCoroutine([&ended,
- &callback](CoroutineHandler* handler) {
- EXPECT_EQ(
- ContinuationStatus::INTERRUPTED,
- SyncCall(handler, [&callback](fit::function<void()> received_callback) {
- callback = std::move(received_callback);
- }));
- ended = true;
- });
-
- EXPECT_FALSE(ended);
- EXPECT_TRUE(callback);
- callback = [] {};
-
- EXPECT_TRUE(ended);
-}
-
-TEST(Coroutine, RunAndDroppedAsyncCallAfterCoroutineDeletion) {
- bool ended = false;
- fit::function<void()> callback;
- {
- CoroutineServiceImpl coroutine_service;
-
- coroutine_service.StartCoroutine([&ended,
- &callback](CoroutineHandler* handler) {
- EXPECT_EQ(ContinuationStatus::INTERRUPTED,
- SyncCall(handler,
- [&callback](fit::function<void()> received_callback) {
- callback = std::move(received_callback);
- }));
- ended = true;
- });
-
- EXPECT_FALSE(ended);
- EXPECT_TRUE(callback);
- }
-
- EXPECT_TRUE(ended);
- callback();
-}
-
-TEST(Coroutine, Interrupt) {
- ContinuationStatus status = ContinuationStatus::OK;
-
- {
- CoroutineServiceImpl coroutine_service;
-
- coroutine_service.StartCoroutine([&status](CoroutineHandler* handler) {
- UseStack();
- status = handler->Yield();
- UseStack();
- });
-
- EXPECT_EQ(ContinuationStatus::OK, status);
- }
-
- EXPECT_EQ(ContinuationStatus::INTERRUPTED, status);
-}
-
-#if !__has_feature(address_sanitizer)
-TEST(Coroutine, ReuseStack) {
- CoroutineServiceImpl coroutine_service;
- CoroutineHandler* handler = nullptr;
- uintptr_t stack_pointer = 0;
- size_t nb_coroutines_calls = 0;
-
- for (size_t i = 0; i < 2; ++i) {
- coroutine_service.StartCoroutine(
- [&handler, &stack_pointer,
- &nb_coroutines_calls](CoroutineHandler* called_handler) {
- UseStack();
- int a;
- uintptr_t addr = reinterpret_cast<uintptr_t>(&a);
- if (stack_pointer == 0) {
- stack_pointer = addr;
- }
- EXPECT_EQ(addr, stack_pointer);
- handler = called_handler;
- EXPECT_EQ(ContinuationStatus::OK, called_handler->Yield());
- UseStack();
-
- ++nb_coroutines_calls;
- });
- handler->Resume(ContinuationStatus::OK);
- }
-
- EXPECT_EQ(2u, nb_coroutines_calls);
-}
-#endif // !__has_feature(address_sanitizer)
-
-TEST(Coroutine, ResumeCoroutineInOtherCoroutineDestructor) {
- CoroutineServiceImpl coroutine_service;
- CoroutineHandler* handler1 = nullptr;
- CoroutineHandler* handler2 = nullptr;
- bool routine1_done = false;
- bool routine2_done = false;
-
- coroutine_service.StartCoroutine([&](CoroutineHandler* local_handler1) {
- handler1 = local_handler1;
- auto autocall =
- fit::defer([&] { handler1->Resume(ContinuationStatus::OK); });
- coroutine_service.StartCoroutine(
- [&handler2, &routine2_done,
- autocall = std::move(autocall)](CoroutineHandler* local_handler2) {
- handler2 = local_handler2;
- EXPECT_EQ(ContinuationStatus::OK, handler2->Yield());
- routine2_done = true;
- });
- EXPECT_EQ(ContinuationStatus::OK, handler1->Yield());
- routine1_done = true;
- });
-
- handler2->Resume(ContinuationStatus::OK);
-
- EXPECT_TRUE(routine1_done);
- EXPECT_TRUE(routine2_done);
-}
-
-TEST(Coroutine, AsyncCallCapture) {
- CoroutineServiceImpl coroutine_service;
-
- fit::function<void(size_t)> callback;
- auto callable = [&callback](fit::function<void(size_t)> called_callback) {
- callback = std::move(called_callback);
- };
-
- size_t value = 0;
- CoroutineHandler* coroutine_handler;
- coroutine_service.StartCoroutine(
- [callable, &coroutine_handler, &value](CoroutineHandler* handler) {
- coroutine_handler = handler;
- EXPECT_EQ(ContinuationStatus::INTERRUPTED,
- SyncCall(handler, callable, &value));
- return;
- });
-
- EXPECT_TRUE(callback);
-
- coroutine_handler->Resume(ContinuationStatus::INTERRUPTED);
-
- callback(10);
-
- EXPECT_EQ(0u, value);
-}
-
-} // namespace
-} // namespace coroutine
diff --git a/bin/ledger/coroutine/coroutine_waiter.h b/bin/ledger/coroutine/coroutine_waiter.h
deleted file mode 100644
index 349445a..0000000
--- a/bin/ledger/coroutine/coroutine_waiter.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_WAITER_H_
-#define PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_WAITER_H_
-
-#include <utility>
-
-#include <lib/fxl/compiler_specific.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-
-// Utilities to interact with coroutines and callback::Waiter.
-
-namespace coroutine {
-
-// Wait on a callback::Waiter (and other waiter utilities). This method will
-// interrupt the coroutine until the finalizer of the waiter is executed. The
-// results of the waiter will be stored in |parameters|. If |Wait| returns
-// |INTERRUPTED|, the coroutine must unwind its stack and terminate.
-
-template <typename A, typename... Args>
-FXL_WARN_UNUSED_RESULT ContinuationStatus
-Wait(coroutine::CoroutineHandler* handler, A waiter, Args... parameters) {
- return coroutine::SyncCall(handler,
- [waiter = std::move(waiter)](auto callback) {
- waiter->Finalize(std::move(callback));
- },
- std::forward<Args>(parameters)...);
-}
-
-} // namespace coroutine
-
-#endif // PERIDOT_BIN_LEDGER_COROUTINE_COROUTINE_WAITER_H_
diff --git a/bin/ledger/coroutine/coroutine_waiter_unittest.cc b/bin/ledger/coroutine/coroutine_waiter_unittest.cc
deleted file mode 100644
index 9585049..0000000
--- a/bin/ledger/coroutine/coroutine_waiter_unittest.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/coroutine/coroutine_waiter.h"
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-
-namespace coroutine {
-namespace {
-TEST(CoroutineWaiterTest, Wait) {
- CoroutineServiceImpl coroutine_service;
-
- fit::closure on_done;
- coroutine_service.StartCoroutine([&](CoroutineHandler* current_handler) {
- auto waiter = fxl::MakeRefCounted<callback::CompletionWaiter>();
- on_done = waiter->NewCallback();
- EXPECT_EQ(ContinuationStatus::OK, Wait(current_handler, std::move(waiter)));
- });
-
- on_done();
-}
-} // namespace
-} // namespace coroutine
diff --git a/bin/ledger/encryption/BUILD.gn b/bin/ledger/encryption/BUILD.gn
deleted file mode 100644
index f7eb456..0000000
--- a/bin/ledger/encryption/BUILD.gn
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("encryption") {
- deps = [
- "//peridot/bin/ledger/encryption/impl",
- "//peridot/bin/ledger/encryption/public",
- ]
-}
diff --git a/bin/ledger/encryption/fake/BUILD.gn b/bin/ledger/encryption/fake/BUILD.gn
deleted file mode 100644
index 1f269d7..0000000
--- a/bin/ledger/encryption/fake/BUILD.gn
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("fake") {
- testonly = true
-
- sources = [
- "fake_encryption_service.cc",
- "fake_encryption_service.h",
- "fake_encryption_service_factory.cc",
- "fake_encryption_service_factory.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/encryption/public",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/encryption/fake/fake_encryption_service.cc b/bin/ledger/encryption/fake/fake_encryption_service.cc
deleted file mode 100644
index 53db8da..0000000
--- a/bin/ledger/encryption/fake/fake_encryption_service.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace encryption {
-
-namespace {
-std::string Encode(fxl::StringView content) {
- return "_" + content.ToString() + "_";
-}
-
-std::string Decode(fxl::StringView encrypted_content) {
- return encrypted_content.substr(1, encrypted_content.size() - 2).ToString();
-}
-} // namespace
-
-storage::ObjectIdentifier MakeDefaultObjectIdentifier(
- storage::ObjectDigest digest) {
- return {1u, 1u, std::move(digest)};
-}
-
-FakeEncryptionService::FakeEncryptionService(async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher) {}
-
-FakeEncryptionService::~FakeEncryptionService() {}
-
-storage::ObjectIdentifier FakeEncryptionService::MakeObjectIdentifier(
- storage::ObjectDigest digest) {
- return MakeDefaultObjectIdentifier(std::move(digest));
-}
-
-void FakeEncryptionService::EncryptCommit(
- std::string commit_storage,
- fit::function<void(Status, std::string)> callback) {
- std::string encrypted_commit = EncryptCommitSynchronous(commit_storage);
- async::PostTask(dispatcher_, [encrypted_commit = std::move(encrypted_commit),
- callback = std::move(callback)]() mutable {
- callback(Status::OK, std::move(encrypted_commit));
- });
-}
-
-void FakeEncryptionService::DecryptCommit(
- convert::ExtendedStringView storage_bytes,
- fit::function<void(Status, std::string)> callback) {
- std::string commit = DecryptCommitSynchronous(storage_bytes);
- async::PostTask(dispatcher_, [commit = std::move(commit),
- callback = std::move(callback)]() mutable {
- callback(Status::OK, std::move(commit));
- });
-}
-
-void FakeEncryptionService::GetObjectName(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(Status, std::string)> callback) {
- std::string result = GetObjectNameSynchronous(object_identifier);
- async::PostTask(dispatcher_, [callback = std::move(callback),
- result = std::move(result)]() mutable {
- callback(Status::OK, std::move(result));
- });
-}
-
-void FakeEncryptionService::EncryptObject(
- storage::ObjectIdentifier /*object_identifier*/, fsl::SizedVmo content,
- fit::function<void(Status, std::string)> callback) {
- std::string content_as_string;
- if (!fsl::StringFromVmo(content, &content_as_string)) {
- callback(Status::IO_ERROR, "");
- return;
- }
- std::string result = EncryptObjectSynchronous(content_as_string);
- async::PostTask(dispatcher_, [callback = std::move(callback),
- result = std::move(result)]() mutable {
- callback(Status::OK, std::move(result));
- });
-}
-
-void FakeEncryptionService::DecryptObject(
- storage::ObjectIdentifier /*object_identifier*/, std::string encrypted_data,
- fit::function<void(Status, std::string)> callback) {
- std::string result = DecryptObjectSynchronous(encrypted_data);
- async::PostTask(dispatcher_, [callback = std::move(callback),
- result = std::move(result)]() mutable {
- callback(Status::OK, std::move(result));
- });
-}
-
-std::string FakeEncryptionService::EncryptCommitSynchronous(
- convert::ExtendedStringView commit_storage) {
- return Encode(commit_storage);
-}
-
-std::string FakeEncryptionService::DecryptCommitSynchronous(
- convert::ExtendedStringView storage_bytes) {
- return Decode(storage_bytes);
-}
-
-std::string FakeEncryptionService::GetObjectNameSynchronous(
- storage::ObjectIdentifier object_identifier) {
- return Encode(object_identifier.object_digest().Serialize());
-}
-
-std::string FakeEncryptionService::EncryptObjectSynchronous(
- convert::ExtendedStringView object_content) {
- return Encode(object_content);
-}
-
-std::string FakeEncryptionService::DecryptObjectSynchronous(
- convert::ExtendedStringView encrypted_data) {
- return Decode(encrypted_data);
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/fake/fake_encryption_service.h b/bin/ledger/encryption/fake/fake_encryption_service.h
deleted file mode 100644
index db86231..0000000
--- a/bin/ledger/encryption/fake/fake_encryption_service.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_FAKE_FAKE_ENCRYPTION_SERVICE_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_FAKE_FAKE_ENCRYPTION_SERVICE_H_
-
-#include <functional>
-#include <string>
-
-#include <lib/async/dispatcher.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace encryption {
-
-// Creates an |ObjectIdentifier| from an |ObjectDigest|.
-//
-// This method is always constructing the indentifier with the same key index
-// and deletion scope.
-storage::ObjectIdentifier MakeDefaultObjectIdentifier(
- storage::ObjectDigest digest);
-
-class FakeEncryptionService : public EncryptionService {
- public:
- explicit FakeEncryptionService(async_dispatcher_t* dispatcher);
- ~FakeEncryptionService() override;
-
- // EncryptionService:
- storage::ObjectIdentifier MakeObjectIdentifier(
- storage::ObjectDigest digest) override;
- void EncryptCommit(
- std::string commit_storage,
- fit::function<void(Status, std::string)> callback) override;
- void DecryptCommit(
- convert::ExtendedStringView storage_bytes,
- fit::function<void(Status, std::string)> callback) override;
- void GetObjectName(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(Status, std::string)> callback) override;
- void EncryptObject(
- storage::ObjectIdentifier object_identifier, fsl::SizedVmo content,
- fit::function<void(Status, std::string)> callback) override;
- void DecryptObject(
- storage::ObjectIdentifier object_identifier, std::string encrypted_data,
- fit::function<void(Status, std::string)> callback) override;
-
- // Synchronously encrypts the given commit.
- std::string EncryptCommitSynchronous(
- convert::ExtendedStringView commit_storage);
-
- // Synchronously decrypts the given commit.
- std::string DecryptCommitSynchronous(
- convert::ExtendedStringView storage_bytes);
-
- // Synchronously gets the object name.
- std::string GetObjectNameSynchronous(
- storage::ObjectIdentifier object_identifier);
-
- // Synchronously encrypts the object.
- std::string EncryptObjectSynchronous(
- convert::ExtendedStringView object_content);
-
- // Synchronously decrypts the object.
- std::string DecryptObjectSynchronous(
- convert::ExtendedStringView encrypted_data);
-
- private:
- async_dispatcher_t* dispatcher_;
-};
-
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_FAKE_FAKE_ENCRYPTION_SERVICE_H_
diff --git a/bin/ledger/encryption/fake/fake_encryption_service_factory.cc b/bin/ledger/encryption/fake/fake_encryption_service_factory.cc
deleted file mode 100644
index 0abe83b..0000000
--- a/bin/ledger/encryption/fake/fake_encryption_service_factory.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service_factory.h"
-
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-
-namespace encryption {
-
-FakeEncryptionServiceFactory::FakeEncryptionServiceFactory(
- async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher) {}
-
-FakeEncryptionServiceFactory::~FakeEncryptionServiceFactory() {}
-
-std::unique_ptr<EncryptionService>
-FakeEncryptionServiceFactory::MakeEncryptionService(
- std::string /*namespace_id*/) {
- return std::make_unique<FakeEncryptionService>(dispatcher_);
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/fake/fake_encryption_service_factory.h b/bin/ledger/encryption/fake/fake_encryption_service_factory.h
deleted file mode 100644
index 4237c56..0000000
--- a/bin/ledger/encryption/fake/fake_encryption_service_factory.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_FAKE_FAKE_ENCRYPTION_SERVICE_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_FAKE_FAKE_ENCRYPTION_SERVICE_FACTORY_H_
-
-#include <lib/async/dispatcher.h>
-
-#include "peridot/bin/ledger/encryption/public/encryption_service_factory.h"
-
-namespace encryption {
-class FakeEncryptionServiceFactory : public EncryptionServiceFactory {
- public:
- explicit FakeEncryptionServiceFactory(async_dispatcher_t* dispatcher);
- ~FakeEncryptionServiceFactory() override;
-
- // EncryptionServiceFactory
- std::unique_ptr<EncryptionService> MakeEncryptionService(
- std::string namespace_id) override;
-
- private:
- async_dispatcher_t* dispatcher_;
-};
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_FAKE_FAKE_ENCRYPTION_SERVICE_FACTORY_H_
diff --git a/bin/ledger/encryption/impl/BUILD.gn b/bin/ledger/encryption/impl/BUILD.gn
deleted file mode 100644
index 52d1337..0000000
--- a/bin/ledger/encryption/impl/BUILD.gn
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("impl") {
- sources = [
- "encryption_service_factory_impl.cc",
- "encryption_service_factory_impl.h",
- "encryption_service_impl.cc",
- "encryption_service_impl.h",
- ]
-
- deps = [
- ":encrypted_commit",
- "//garnet/public/lib/callback",
- "//peridot/bin/ledger/cache",
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/environment",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/encryption/public",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-flatbuffer("encrypted_commit") {
- sources = [
- "encrypted_commit.fbs",
- ]
-
- extra_configs = [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "encryption_service_factory_impl_unittest.cc",
- "encryption_service_impl_unittest.cc",
- ]
-
- deps = [
- ":impl",
- "//garnet/public/lib/callback",
- "//peridot/bin/ledger/storage/fake:lib",
- "//peridot/bin/ledger/testing:lib",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/encryption/impl/encrypted_commit.fbs b/bin/ledger/encryption/impl/encrypted_commit.fbs
deleted file mode 100644
index 31eb7c9..0000000
--- a/bin/ledger/encryption/impl/encrypted_commit.fbs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-namespace encryption;
-
-table EncryptedCommitStorage {
- key_index: uint;
- serialized_encrypted_commit_storage: [ubyte];
-}
-
-root_type EncryptedCommitStorage;
diff --git a/bin/ledger/encryption/impl/encryption_service_factory_impl.cc b/bin/ledger/encryption/impl/encryption_service_factory_impl.cc
deleted file mode 100644
index 5459531..0000000
--- a/bin/ledger/encryption/impl/encryption_service_factory_impl.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/impl/encryption_service_factory_impl.h"
-
-#include "peridot/bin/ledger/encryption/impl/encryption_service_impl.h"
-
-namespace encryption {
-
-EncryptionServiceFactoryImpl::EncryptionServiceFactoryImpl(
- ledger::Environment* environment)
- : environment_(environment) {}
-
-EncryptionServiceFactoryImpl::~EncryptionServiceFactoryImpl() {}
-
-std::unique_ptr<EncryptionService>
-EncryptionServiceFactoryImpl::MakeEncryptionService(std::string namespace_id) {
- return std::make_unique<EncryptionServiceImpl>(environment_,
- std::move(namespace_id));
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/impl/encryption_service_factory_impl.h b/bin/ledger/encryption/impl/encryption_service_factory_impl.h
deleted file mode 100644
index f84cf3a..0000000
--- a/bin/ledger/encryption/impl/encryption_service_factory_impl.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_IMPL_ENCRYPTION_SERVICE_FACTORY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_IMPL_ENCRYPTION_SERVICE_FACTORY_IMPL_H_
-
-#include "peridot/bin/ledger/encryption/public/encryption_service_factory.h"
-#include "peridot/bin/ledger/environment/environment.h"
-
-namespace encryption {
-class EncryptionServiceFactoryImpl : public EncryptionServiceFactory {
- public:
- explicit EncryptionServiceFactoryImpl(ledger::Environment* environment);
- ~EncryptionServiceFactoryImpl() override;
-
- // EncryptionServiceFactory
- std::unique_ptr<EncryptionService> MakeEncryptionService(
- std::string namespace_id) override;
-
- private:
- ledger::Environment* const environment_;
-};
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_IMPL_ENCRYPTION_SERVICE_FACTORY_IMPL_H_
diff --git a/bin/ledger/encryption/impl/encryption_service_factory_impl_unittest.cc b/bin/ledger/encryption/impl/encryption_service_factory_impl_unittest.cc
deleted file mode 100644
index 7c57190..0000000
--- a/bin/ledger/encryption/impl/encryption_service_factory_impl_unittest.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/impl/encryption_service_factory_impl.h"
-
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-
-#include "gtest/gtest.h"
-
-namespace encryption {
-namespace {
-
-using EncryptionServiceFactoryTest = ledger::TestWithEnvironment;
-
-TEST_F(EncryptionServiceFactoryTest, MakeEncryptionService) {
- EncryptionServiceFactoryImpl factory(&environment_);
- EXPECT_TRUE(factory.MakeEncryptionService("namespace_id"));
-}
-
-} // namespace
-} // namespace encryption
diff --git a/bin/ledger/encryption/impl/encryption_service_impl.cc b/bin/ledger/encryption/impl/encryption_service_impl.cc
deleted file mode 100644
index e27597e..0000000
--- a/bin/ledger/encryption/impl/encryption_service_impl.cc
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/impl/encryption_service_impl.h"
-
-#include <flatbuffers/flatbuffers.h>
-#include <lib/async/cpp/task.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/bin/ledger/encryption/impl/encrypted_commit_generated.h"
-#include "peridot/bin/ledger/encryption/primitives/encrypt.h"
-#include "peridot/bin/ledger/encryption/primitives/kdf.h"
-
-namespace encryption {
-namespace {
-
-// The default encryption values. Only used until real encryption is
-// implemented: LE-286
-//
-// Use max_int32 for key_index as it will never be used in practice as it is not
-// expected that any user will change its key 2^32 times.
-constexpr uint32_t kDefaultKeyIndex = std::numeric_limits<uint32_t>::max();
-// Use max_int32 - 1 for default deletion scoped id. max_int32 has a special
-// meaning in the specification and is used to have per object deletion scope.
-constexpr uint32_t kDefaultDeletionScopeId =
- std::numeric_limits<uint32_t>::max() - 1;
-// Special deletion scope id that produces a per-object deletion scope.
-constexpr uint32_t kPerObjectDeletionScopedId =
- std::numeric_limits<uint32_t>::max();
-
-// Size of keys. Key must have 128 bits of entropy. Randomly generated keys can
-// be 128 bits long, but derived ones need to be twice as big because of the
-// birthday paradox.
-// Size of the randomly generated key.
-constexpr size_t kRandomlyGeneratedKeySize = 16u;
-// Size of the derived keys.
-constexpr size_t kDerivedKeySize = 32u;
-
-// Cache size values.
-constexpr size_t kKeyIndexCacheSize = 10u;
-constexpr size_t kReferenceKeysCacheSize = 10u;
-
-// Checks whether the given |storage_bytes| are a valid serialization of an
-// encrypted commit.
-bool CheckValidSerialization(fxl::StringView storage_bytes) {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(storage_bytes.data()),
- storage_bytes.size());
-
- return VerifyEncryptedCommitStorageBuffer(verifier);
-}
-
-} // namespace
-
-// Fake implementation of a key service for the Ledger.
-//
-// This implementation generate fake keys and will need to be replaced by a
-// real component.
-class EncryptionServiceImpl::KeyService {
- public:
- explicit KeyService(async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher), weak_factory_(this) {}
-
- // Retrieves the master key.
- void GetMasterKey(uint32_t key_index,
- fit::function<void(std::string)> callback) {
- async::PostTask(dispatcher_,
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [key_index, callback = std::move(callback)]() {
- std::string master_key(16u, 0);
- memcpy(&master_key[0], &key_index, sizeof(key_index));
- callback(std::move(master_key));
- }));
- }
-
- // Retrieves the reference key associated to the given namespace and reference
- // key. If the id is not yet associated with a reference key, generates a new
- // one and associates it with the id before returning.
- void GetReferenceKey(const std::string& namespace_id,
- const std::string& reference_key_id,
- fit::function<void(const std::string&)> callback) {
- std::string result =
- HMAC256KDF(fxl::Concatenate({namespace_id, reference_key_id}),
- kRandomlyGeneratedKeySize);
- async::PostTask(
- dispatcher_,
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [result = std::move(result),
- callback = std::move(callback)]() mutable { callback(result); }));
- }
-
- private:
- async_dispatcher_t* const dispatcher_;
- fxl::WeakPtrFactory<EncryptionServiceImpl::KeyService> weak_factory_;
-};
-
-EncryptionServiceImpl::EncryptionServiceImpl(ledger::Environment* environment,
- std::string namespace_id)
- : environment_(environment),
- namespace_id_(std::move(namespace_id)),
- key_service_(std::make_unique<KeyService>(environment_->dispatcher())),
- master_keys_(kKeyIndexCacheSize, Status::OK,
- [this](auto k, auto c) {
- FetchMasterKey(std::move(k), std::move(c));
- }),
- namespace_keys_(kKeyIndexCacheSize, Status::OK,
- [this](auto k, auto c) {
- FetchNamespaceKey(std::move(k), std::move(c));
- }),
- reference_keys_(kReferenceKeysCacheSize, Status::OK,
- [this](auto k, auto c) {
- FetchReferenceKey(std::move(k), std::move(c));
- }) {}
-
-EncryptionServiceImpl::~EncryptionServiceImpl() {}
-
-storage::ObjectIdentifier EncryptionServiceImpl::MakeObjectIdentifier(
- storage::ObjectDigest digest) {
- return {GetCurrentKeyIndex(), kDefaultDeletionScopeId, std::move(digest)};
-}
-
-void EncryptionServiceImpl::EncryptCommit(
- std::string commit_storage,
- fit::function<void(Status, std::string)> callback) {
- size_t key_index = GetCurrentKeyIndex();
-
- Encrypt(key_index, std::move(commit_storage),
- [key_index, callback = std::move(callback)](
- Status status, std::string encrypted_storage) {
- if (status != Status::OK) {
- callback(status, "");
- return;
- }
-
- flatbuffers::FlatBufferBuilder builder;
-
- auto storage = CreateEncryptedCommitStorage(
- builder, key_index,
- convert::ToFlatBufferVector(&builder, encrypted_storage));
- builder.Finish(storage);
- callback(Status::OK, std::string(reinterpret_cast<const char*>(
- builder.GetBufferPointer()),
- builder.GetSize()));
- });
-}
-
-void EncryptionServiceImpl::DecryptCommit(
- convert::ExtendedStringView storage_bytes,
- fit::function<void(Status, std::string)> callback) {
- if (!CheckValidSerialization(storage_bytes)) {
- FXL_LOG(WARNING) << "Received invalid data. Cannot decrypt commit.";
- callback(Status::INVALID_ARGUMENT, "");
- return;
- }
-
- const EncryptedCommitStorage* encrypted_commit_storage =
- GetEncryptedCommitStorage(storage_bytes.data());
-
- Decrypt(encrypted_commit_storage->key_index(),
- convert::ToString(
- encrypted_commit_storage->serialized_encrypted_commit_storage()),
- std::move(callback));
-}
-
-void EncryptionServiceImpl::GetObjectName(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(Status, std::string)> callback) {
- GetReferenceKey(object_identifier, [object_identifier,
- callback = std::move(callback)](
- const std::string& reference_key) {
- callback(Status::OK,
- HMAC256KDF(fxl::Concatenate(
- {reference_key,
- object_identifier.object_digest().Serialize()}),
- kDerivedKeySize));
- });
-}
-
-void EncryptionServiceImpl::EncryptObject(
- storage::ObjectIdentifier object_identifier, fsl::SizedVmo content,
- fit::function<void(Status, std::string)> callback) {
- std::string data;
- if (!fsl::StringFromVmo(content, &data)) {
- callback(Status::IO_ERROR, "");
- return;
- }
- Encrypt(object_identifier.key_index(), std::move(data), std::move(callback));
-}
-
-void EncryptionServiceImpl::DecryptObject(
- storage::ObjectIdentifier object_identifier, std::string encrypted_data,
- fit::function<void(Status, std::string)> callback) {
- Decrypt(object_identifier.key_index(), std::move(encrypted_data),
- std::move(callback));
-}
-
-uint32_t EncryptionServiceImpl::GetCurrentKeyIndex() {
- return kDefaultKeyIndex;
-}
-
-void EncryptionServiceImpl::GetReferenceKey(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(const std::string&)> callback) {
- std::string deletion_scope_seed;
- if (object_identifier.deletion_scope_id() == kPerObjectDeletionScopedId) {
- deletion_scope_seed = object_identifier.object_digest().Serialize();
- } else {
- const uint32_t deletion_scope_id = object_identifier.deletion_scope_id();
- deletion_scope_seed =
- std::string(reinterpret_cast<const char*>(&deletion_scope_id),
- sizeof(deletion_scope_id));
- }
- DeletionScopeSeed seed = {object_identifier.key_index(),
- std::move(deletion_scope_seed)};
- reference_keys_.Get(
- seed, [callback = std::move(callback)](
- Status status, const std::string& value) { callback(value); });
-}
-
-void EncryptionServiceImpl::Encrypt(
- size_t key_index, std::string data,
- fit::function<void(Status, std::string)> callback) {
- master_keys_.Get(
- key_index,
- [environment = environment_, data = std::move(data),
- callback = std::move(callback)](Status status, const std::string& key) {
- if (status != Status::OK) {
- callback(status, "");
- return;
- }
- std::string encrypted_data;
- if (!AES128GCMSIVEncrypt(environment->random(), key, data,
- &encrypted_data)) {
- callback(Status::INTERNAL_ERROR, "");
- return;
- }
- callback(Status::OK, std::move(encrypted_data));
- });
-}
-
-void EncryptionServiceImpl::Decrypt(
- size_t key_index, std::string encrypted_data,
- fit::function<void(Status, std::string)> callback) {
- master_keys_.Get(key_index, [encrypted_data = std::move(encrypted_data),
- callback = std::move(callback)](
- Status status, const std::string& key) {
- if (status != Status::OK) {
- callback(status, "");
- return;
- }
- std::string data;
- if (!AES128GCMSIVDecrypt(key, encrypted_data, &data)) {
- callback(Status::INTERNAL_ERROR, "");
- return;
- }
- callback(Status::OK, std::move(data));
- });
-}
-
-void EncryptionServiceImpl::FetchMasterKey(
- size_t key_index, fit::function<void(Status, std::string)> callback) {
- key_service_->GetMasterKey(
- key_index, [callback = std::move(callback)](std::string master_key) {
- callback(Status::OK, std::move(master_key));
- });
-}
-
-void EncryptionServiceImpl::FetchNamespaceKey(
- size_t key_index, fit::function<void(Status, std::string)> callback) {
- master_keys_.Get(
- key_index, [this, callback = std::move(callback)](
- Status status, const std::string& master_key) {
- if (status != Status::OK) {
- callback(status, "");
- return;
- }
- callback(Status::OK,
- HMAC256KDF(fxl::Concatenate({master_key, namespace_id_}),
- kDerivedKeySize));
- });
-}
-
-void EncryptionServiceImpl::FetchReferenceKey(
- DeletionScopeSeed deletion_scope_seed,
- fit::function<void(Status, std::string)> callback) {
- namespace_keys_.Get(
- deletion_scope_seed.first,
- [this, deletion_scope_seed = std::move(deletion_scope_seed),
- callback = std::move(callback)](
- Status status, const std::string& namespace_key) mutable {
- if (status != Status::OK) {
- callback(status, "");
- return;
- }
- key_service_->GetReferenceKey(
- namespace_id_,
- HMAC256KDF(
- fxl::Concatenate({namespace_key, deletion_scope_seed.second}),
- kDerivedKeySize),
- [callback = std::move(callback)](std::string reference_key) {
- callback(Status::OK, std::move(reference_key));
- });
- });
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/impl/encryption_service_impl.h b/bin/ledger/encryption/impl/encryption_service_impl.h
deleted file mode 100644
index 2614183..0000000
--- a/bin/ledger/encryption/impl/encryption_service_impl.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_IMPL_ENCRYPTION_SERVICE_IMPL_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_IMPL_ENCRYPTION_SERVICE_IMPL_H_
-
-#include <functional>
-#include <string>
-
-#include <lib/async/dispatcher.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/cache/lazy_value.h"
-#include "peridot/bin/ledger/cache/lru_cache.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace encryption {
-
-class EncryptionServiceImpl : public EncryptionService {
- public:
- EncryptionServiceImpl(ledger::Environment* environment,
- std::string namespace_id);
- ~EncryptionServiceImpl() override;
-
- // EncryptionService:
- storage::ObjectIdentifier MakeObjectIdentifier(
- storage::ObjectDigest digest) override;
- void EncryptCommit(
- std::string commit_storage,
- fit::function<void(Status, std::string)> callback) override;
- void DecryptCommit(
- convert::ExtendedStringView storage_bytes,
- fit::function<void(Status, std::string)> callback) override;
- void GetObjectName(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(Status, std::string)> callback) override;
- void EncryptObject(
- storage::ObjectIdentifier object_identifier, fsl::SizedVmo content,
- fit::function<void(Status, std::string)> callback) override;
- void DecryptObject(
- storage::ObjectIdentifier object_identifier, std::string encrypted_data,
- fit::function<void(Status, std::string)> callback) override;
-
- private:
- class KeyService;
- using DeletionScopeSeed = std::pair<size_t, std::string>;
-
- uint32_t GetCurrentKeyIndex();
- void GetReferenceKey(storage::ObjectIdentifier object_identifier,
- fit::function<void(const std::string&)> callback);
-
- void Encrypt(size_t key_index, std::string data,
- fit::function<void(Status, std::string)> callback);
- void Decrypt(size_t key_index, std::string encrypted_data,
- fit::function<void(Status, std::string)> callback);
-
- void FetchMasterKey(size_t key_index,
- fit::function<void(Status, std::string)> callback);
- void FetchNamespaceKey(size_t key_index,
- fit::function<void(Status, std::string)> callback);
- void FetchReferenceKey(DeletionScopeSeed deletion_scope_seed,
- fit::function<void(Status, std::string)> callback);
-
- ledger::Environment* const environment_;
- const std::string namespace_id_;
- std::unique_ptr<KeyService> key_service_;
-
- // Master keys indexed by key_index.
- cache::LRUCache<uint32_t, std::string, Status> master_keys_;
- // Namespace keys indexed by key_index.
- cache::LRUCache<uint32_t, std::string, Status> namespace_keys_;
- // Reference keys indexed by deletion scope seed.
- cache::LRUCache<DeletionScopeSeed, std::string, Status> reference_keys_;
-};
-
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_IMPL_ENCRYPTION_SERVICE_IMPL_H_
diff --git a/bin/ledger/encryption/impl/encryption_service_impl_unittest.cc b/bin/ledger/encryption/impl/encryption_service_impl_unittest.cc
deleted file mode 100644
index e6fb450..0000000
--- a/bin/ledger/encryption/impl/encryption_service_impl_unittest.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/impl/encryption_service_impl.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/storage/fake/fake_object.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-
-namespace encryption {
-namespace {
-
-class EncryptionServiceTest : public ledger::TestWithEnvironment {
- public:
- EncryptionServiceTest()
- : encryption_service_(&environment_, "namespace_id") {}
-
- protected:
- void EncryptCommit(std::string commit_storage, Status* status,
- std::string* result) {
- bool called;
- encryption_service_.EncryptCommit(
- commit_storage,
- callback::Capture(callback::SetWhenCalled(&called), status, result));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- }
-
- void DecryptCommit(convert::ExtendedStringView encrypted_commit_storage,
- Status* status, std::string* result) {
- bool called;
- encryption_service_.DecryptCommit(
- encrypted_commit_storage,
- callback::Capture(callback::SetWhenCalled(&called), status, result));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- }
-
- void GetObjectName(storage::ObjectIdentifier object_identifier,
- Status* status, std::string* result) {
- bool called;
- encryption_service_.GetObjectName(
- std::move(object_identifier),
- callback::Capture(callback::SetWhenCalled(&called), status, result));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- }
-
- void EncryptObject(storage::ObjectIdentifier object_identifier,
- fsl::SizedVmo content, Status* status,
- std::string* result) {
- bool called;
- encryption_service_.EncryptObject(
- std::move(object_identifier), std::move(content),
- callback::Capture(callback::SetWhenCalled(&called), status, result));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- }
-
- void DecryptObject(storage::ObjectIdentifier object_identifier,
- std::string encrypted_data, Status* status,
- std::string* result) {
- bool called;
- encryption_service_.DecryptObject(
- std::move(object_identifier), std::move(encrypted_data),
- callback::Capture(callback::SetWhenCalled(&called), status, result));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- }
-
- EncryptionServiceImpl encryption_service_;
-};
-
-TEST_F(EncryptionServiceTest, EncryptDecryptCommit) {
- std::string contents[] = {
- "",
- "Hello",
- "0123456789012345678901234567890123456789012345678901234567890123456789",
-
- };
-
- for (const auto& content : contents) {
- Status status;
- std::string value;
- EncryptCommit(content, &status, &value);
- ASSERT_EQ(Status::OK, status);
- DecryptCommit(value, &status, &value);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(content, value);
- }
-}
-
-TEST_F(EncryptionServiceTest, GetName) {
- storage::ObjectIdentifier identifier{
- 42u, 42u, storage::ObjectDigest(std::string(33u, '\0'))};
- Status status;
- std::string name;
- GetObjectName(identifier, &status, &name);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(name.empty());
-}
-
-TEST_F(EncryptionServiceTest, EncryptDecryptObject) {
- storage::ObjectIdentifier identifier{
- 42u, 42u, storage::ObjectDigest(std::string(33u, '\0'))};
- std::string content(256u, '\0');
- auto object =
- std::make_unique<storage::fake::FakeObject>(identifier, content);
- fsl::SizedVmo content_vmo;
- ASSERT_EQ(storage::Status::OK, object->GetVmo(&content_vmo));
-
- Status status;
- std::string encrypted_bytes;
- EncryptObject(object->GetIdentifier(), std::move(content_vmo), &status,
- &encrypted_bytes);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(encrypted_bytes.empty());
-
- std::string decrypted_bytes;
- DecryptObject(identifier, encrypted_bytes, &status, &decrypted_bytes);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(content, decrypted_bytes);
-}
-
-} // namespace
-} // namespace encryption
diff --git a/bin/ledger/encryption/primitives/BUILD.gn b/bin/ledger/encryption/primitives/BUILD.gn
deleted file mode 100644
index efe990b..0000000
--- a/bin/ledger/encryption/primitives/BUILD.gn
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("primitives") {
- sources = [
- "encrypt.cc",
- "encrypt.h",
- "hash.cc",
- "hash.h",
- "hmac.cc",
- "hmac.h",
- "kdf.cc",
- "kdf.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/lib/rng",
- "//peridot/third_party/modp_b64",
- "//third_party/boringssl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
- sources = [
- "crypto_test_util.cc",
- "encrypt_unittest.cc",
- "hmac_unittest.cc",
- "kdf_unittest.cc",
- ]
-
- deps = [
- ":primitives",
- "//garnet/public/lib/fxl",
- "//peridot/lib/rng:testing",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/encryption/primitives/crypto_test_util.cc b/bin/ledger/encryption/primitives/crypto_test_util.cc
deleted file mode 100644
index c4b671e..0000000
--- a/bin/ledger/encryption/primitives/crypto_test_util.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/primitives/crypto_test_util.h"
-
-#include <lib/fxl/strings/string_number_conversions.h>
-
-namespace encryption {
-
-std::string FromHex(fxl::StringView data) {
- std::string result;
- result.reserve(data.size() / 2);
- while (!data.empty()) {
- result.push_back(
- fxl::StringToNumber<uint8_t>(data.substr(0, 2), fxl::Base::k16));
- data = data.substr(2);
- }
- return result;
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/primitives/crypto_test_util.h b/bin/ledger/encryption/primitives/crypto_test_util.h
deleted file mode 100644
index 3056d7e..0000000
--- a/bin/ledger/encryption/primitives/crypto_test_util.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_CRYPTO_TEST_UTIL_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_CRYPTO_TEST_UTIL_H_
-
-#include <string>
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace encryption {
-std::string FromHex(fxl::StringView data);
-}
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_CRYPTO_TEST_UTIL_H_
diff --git a/bin/ledger/encryption/primitives/encrypt.cc b/bin/ledger/encryption/primitives/encrypt.cc
deleted file mode 100644
index d56910a..0000000
--- a/bin/ledger/encryption/primitives/encrypt.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/primitives/encrypt.h"
-
-#include <openssl/aead.h>
-#include <zircon/syscalls.h>
-
-namespace encryption {
-
-bool AES128GCMSIVEncrypt(rng::Random* random, fxl::StringView key,
- fxl::StringView data, std::string* output) {
- if (key.size() != 16) {
- return false;
- }
-
- const EVP_AEAD* algorithm = EVP_aead_aes_128_gcm_siv();
-
- const size_t kNonceOffset = 0;
- const size_t kNonceSize = EVP_AEAD_nonce_length(algorithm);
- const size_t kTagOffset = kNonceOffset + kNonceSize;
- const size_t kTagSize = EVP_AEAD_max_tag_len(algorithm);
- const size_t kEncryptedDataOffset = kTagOffset + kTagSize;
-
- bssl::ScopedEVP_AEAD_CTX ctx;
- if (!EVP_AEAD_CTX_init_with_direction(
- ctx.get(), algorithm, reinterpret_cast<const uint8_t*>(key.data()),
- key.size(), EVP_AEAD_DEFAULT_TAG_LENGTH, evp_aead_seal)) {
- return false;
- }
- std::string result;
- result.resize(kEncryptedDataOffset + data.size() +
- EVP_AEAD_max_overhead(algorithm));
- uint8_t* result_as_int8_ptr = reinterpret_cast<uint8_t*>(&result[0]);
-
- // Generate seed.
- random->Draw(&result[0], EVP_AEAD_nonce_length(algorithm));
-
- size_t out_len;
- if (EVP_AEAD_CTX_seal(
- ctx.get(), &result_as_int8_ptr[kEncryptedDataOffset], &out_len,
- data.size() + EVP_AEAD_max_overhead(algorithm),
- &result_as_int8_ptr[kNonceOffset], kNonceSize,
- reinterpret_cast<const uint8_t*>(data.data()), data.size(),
- &result_as_int8_ptr[kTagOffset], kTagSize) == 0) {
- return false;
- }
- result.resize(kEncryptedDataOffset + out_len);
- output->swap(result);
- return true;
-}
-
-bool AES128GCMSIVDecrypt(fxl::StringView key, fxl::StringView encrypted_data,
- std::string* output) {
- if (key.size() != 16) {
- return false;
- }
-
- const EVP_AEAD* algorithm = EVP_aead_aes_128_gcm_siv();
-
- const size_t kNonceOffset = 0;
- const size_t kNonceSize = EVP_AEAD_nonce_length(algorithm);
- const size_t kTagOffset = kNonceOffset + kNonceSize;
- const size_t kTagSize = EVP_AEAD_max_tag_len(algorithm);
- const size_t kEncryptedDataOffset = kTagOffset + kTagSize;
- if (encrypted_data.size() < kEncryptedDataOffset) {
- return false;
- }
- const size_t kEncryptedDataSize =
- encrypted_data.size() - kEncryptedDataOffset;
-
- bssl::ScopedEVP_AEAD_CTX ctx;
- if (!EVP_AEAD_CTX_init_with_direction(
- ctx.get(), algorithm, reinterpret_cast<const uint8_t*>(key.data()),
- key.size(), EVP_AEAD_DEFAULT_TAG_LENGTH, evp_aead_open)) {
- return false;
- }
-
- const uint8_t* encrypted_data_as_uint8_ptr =
- reinterpret_cast<const uint8_t*>(encrypted_data.data());
-
- std::string result;
- result.resize(kEncryptedDataSize);
-
- size_t out_len;
- if (EVP_AEAD_CTX_open(
- ctx.get(), reinterpret_cast<uint8_t*>(&result[0]), &out_len,
- result.size(), &encrypted_data_as_uint8_ptr[kNonceOffset], kNonceSize,
- &encrypted_data_as_uint8_ptr[kEncryptedDataOffset],
- kEncryptedDataSize, &encrypted_data_as_uint8_ptr[kTagOffset],
- kTagSize) == 0) {
- return false;
- }
-
- result.resize(out_len);
- output->swap(result);
- return true;
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/primitives/encrypt.h b/bin/ledger/encryption/primitives/encrypt.h
deleted file mode 100644
index 8c3bead..0000000
--- a/bin/ledger/encryption/primitives/encrypt.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_ENCRYPT_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_ENCRYPT_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/lib/rng/random.h"
-
-namespace encryption {
-
-// Encrypt the given |data| with the given |key| using AES128-GCM-SIV. The key
-// size must be 128 bits.
-bool AES128GCMSIVEncrypt(rng::Random* random, fxl::StringView key,
- fxl::StringView data, std::string* output);
-
-// Descript the given |encrypteddata| with the given |key| using AES128-GCM-SIV.
-// The key size must be 128 bits.
-bool AES128GCMSIVDecrypt(fxl::StringView key, fxl::StringView encrypted_data,
- std::string* output);
-
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_ENCRYPT_H_
diff --git a/bin/ledger/encryption/primitives/encrypt_unittest.cc b/bin/ledger/encryption/primitives/encrypt_unittest.cc
deleted file mode 100644
index 2c66807..0000000
--- a/bin/ledger/encryption/primitives/encrypt_unittest.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/primitives/encrypt.h"
-
-#include <algorithm>
-
-#include <gtest/gtest.h>
-#include <zircon/syscalls.h>
-
-#include "peridot/lib/rng/test_random.h"
-
-namespace encryption {
-namespace {
-
-using EncryptTest = ::testing::TestWithParam<size_t>;
-
-TEST_P(EncryptTest, Correctness) {
- const size_t kMessageSize = GetParam();
- rng::TestRandom random(0);
-
- std::string key;
- key.resize(16);
- random.Draw(&key);
- std::string message;
- message.resize(kMessageSize);
- random.Draw(&message);
-
- std::string encrypted;
- std::string decrypted;
- ASSERT_TRUE(AES128GCMSIVEncrypt(&random, key, message, &encrypted));
-
- // Check that decrypted is the original message.
- ASSERT_TRUE(AES128GCMSIVDecrypt(key, encrypted, &decrypted));
- EXPECT_EQ(message, decrypted);
-
- // Check that changing any of the first 128 bytes breaks the encryption.
- for (size_t index = 0; index < std::min<size_t>(128u, encrypted.size());
- ++index) {
- std::string encrypted_copy = encrypted;
- encrypted_copy[index] ^= 0xFF;
- EXPECT_FALSE(AES128GCMSIVDecrypt(key, encrypted_copy, &decrypted));
- }
-}
-
-INSTANTIATE_TEST_CASE_P(, EncryptTest,
- ::testing::Values(0, 64, 127, 128, 129, 192, 256,
- 12345));
-
-} // namespace
-} // namespace encryption
diff --git a/bin/ledger/encryption/primitives/hash.cc b/bin/ledger/encryption/primitives/hash.cc
deleted file mode 100644
index daa8533..0000000
--- a/bin/ledger/encryption/primitives/hash.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-
-#include <lib/fxl/logging.h>
-#include <openssl/sha.h>
-
-namespace encryption {
-
-std::string SHA256WithLengthHash(fxl::StringView data) {
- std::string result;
- result.resize(SHA256_DIGEST_LENGTH);
- SHA256_CTX sha256;
- SHA256_Init(&sha256);
- uint64_t size = data.size();
- SHA256_Update(&sha256, &size, sizeof(size));
- SHA256_Update(&sha256, data.data(), data.size());
- SHA256_Final(reinterpret_cast<uint8_t*>(&result[0]), &sha256);
- return result;
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/primitives/hash.h b/bin/ledger/encryption/primitives/hash.h
deleted file mode 100644
index 0c79d5d..0000000
--- a/bin/ledger/encryption/primitives/hash.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_HASH_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_HASH_H_
-
-#include <memory>
-#include <string>
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-namespace encryption {
-
-inline constexpr size_t kHashSize = 32;
-
-std::string SHA256WithLengthHash(fxl::StringView data);
-
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_HASH_H_
diff --git a/bin/ledger/encryption/primitives/hmac.cc b/bin/ledger/encryption/primitives/hmac.cc
deleted file mode 100644
index 319e031..0000000
--- a/bin/ledger/encryption/primitives/hmac.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/primitives/hmac.h"
-
-#include <openssl/digest.h>
-#include <openssl/hmac.h>
-#include <openssl/sha.h>
-
-namespace encryption {
-
-std::string SHA256HMAC(fxl::StringView key, fxl::StringView data) {
- FXL_CHECK(key.size() >= SHA256_DIGEST_LENGTH);
-
- std::string result;
- result.resize(SHA256_DIGEST_LENGTH);
- unsigned int result_size;
- const uint8_t* out =
- HMAC(EVP_sha256(), key.data(), key.size(),
- reinterpret_cast<const uint8_t*>(data.data()), data.size(),
- reinterpret_cast<uint8_t*>(&result[0]), &result_size);
- FXL_CHECK(out);
- FXL_DCHECK(result_size == SHA256_DIGEST_LENGTH);
- result.resize(result_size);
- return result;
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/primitives/hmac.h b/bin/ledger/encryption/primitives/hmac.h
deleted file mode 100644
index 1cc7ec6..0000000
--- a/bin/ledger/encryption/primitives/hmac.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_HMAC_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_HMAC_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace encryption {
-// Compute the HMAC defined by RFC 2104 using SHA-256 for the hash algorithm.
-// |key| must be at least 256 bits long.
-std::string SHA256HMAC(fxl::StringView key, fxl::StringView data);
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_HMAC_H_
diff --git a/bin/ledger/encryption/primitives/hmac_unittest.cc b/bin/ledger/encryption/primitives/hmac_unittest.cc
deleted file mode 100644
index 77ee416..0000000
--- a/bin/ledger/encryption/primitives/hmac_unittest.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/primitives/hmac.h"
-
-#include <gtest/gtest.h>
-
-#include "peridot/bin/ledger/encryption/primitives/crypto_test_util.h"
-
-namespace encryption {
-namespace {
-
-TEST(HMAC, Correctness) {
- std::string key = FromHex(
- "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223"
- "2425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F");
- std::string message = "Sample message for keylen=blocklen";
- std::string expected = FromHex(
- "8BB9A1DB9806F20DF7F77B82138C7914D174D59E13DC4D0169C9057B133E1D62");
- EXPECT_EQ(32u, expected.size());
- EXPECT_EQ(expected, SHA256HMAC(key, message));
-}
-} // namespace
-} // namespace encryption
diff --git a/bin/ledger/encryption/primitives/kdf.cc b/bin/ledger/encryption/primitives/kdf.cc
deleted file mode 100644
index b70032d..0000000
--- a/bin/ledger/encryption/primitives/kdf.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/primitives/kdf.h"
-
-#include <lib/fxl/logging.h>
-#include <openssl/digest.h>
-#include <openssl/hkdf.h>
-
-namespace encryption {
-
-std::string HMAC256KDF(fxl::StringView data, size_t length) {
- std::string output;
- output.resize(length);
- int result = HKDF(reinterpret_cast<uint8_t*>(&output[0]), output.size(),
- EVP_sha256(), reinterpret_cast<const uint8_t*>(data.data()),
- data.size(), nullptr, 0u, nullptr, 0u);
- FXL_CHECK(result == 1);
- return output;
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/primitives/kdf.h b/bin/ledger/encryption/primitives/kdf.h
deleted file mode 100644
index 2545919..0000000
--- a/bin/ledger/encryption/primitives/kdf.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_KDF_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_KDF_H_
-
-#include <string>
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace encryption {
-// Compute the key derivation function defined by RFC 5869 using HMAC-256 and
-// the given |length|. The usual salt and info are omitted due to the fact that
-// our scheme always passes unique data to the KDF.
-std::string HMAC256KDF(fxl::StringView data, size_t length);
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_PRIMITIVES_KDF_H_
diff --git a/bin/ledger/encryption/primitives/kdf_unittest.cc b/bin/ledger/encryption/primitives/kdf_unittest.cc
deleted file mode 100644
index 8ba1d68..0000000
--- a/bin/ledger/encryption/primitives/kdf_unittest.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/primitives/kdf.h"
-
-#include <gtest/gtest.h>
-
-#include "peridot/bin/ledger/encryption/primitives/crypto_test_util.h"
-
-namespace encryption {
-namespace {
-
-TEST(KDF, Correctness) {
- std::string data = FromHex("0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B");
- std::string expected = FromHex(
- "8DA4E775A563C18F715F802A063C5A31B8A11F5C5EE1879EC3454E5F3C738D2D9D201395"
- "FAA4B61A96C8");
- EXPECT_EQ(expected, HMAC256KDF(data, expected.size()));
-}
-} // namespace
-} // namespace encryption
diff --git a/bin/ledger/encryption/public/BUILD.gn b/bin/ledger/encryption/public/BUILD.gn
deleted file mode 100644
index e3e90f5..0000000
--- a/bin/ledger/encryption/public/BUILD.gn
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("public") {
- sources = [
- "encryption_service.cc",
- "encryption_service.h",
- "encryption_service_factory.h",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/storage/public",
- "//peridot/lib/convert",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/encryption/public/encryption_service.cc b/bin/ledger/encryption/public/encryption_service.cc
deleted file mode 100644
index 0fa6d8f..0000000
--- a/bin/ledger/encryption/public/encryption_service.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-
-namespace encryption {
-
-bool IsPermanentError(Status status) {
- switch (status) {
- case Status::OK:
- case Status::AUTH_ERROR:
- case Status::NETWORK_ERROR:
- return false;
- case Status::INTERNAL_ERROR:
- case Status::INVALID_ARGUMENT:
- case Status::IO_ERROR:
- return true;
- }
-}
-
-} // namespace encryption
diff --git a/bin/ledger/encryption/public/encryption_service.h b/bin/ledger/encryption/public/encryption_service.h
deleted file mode 100644
index c10f390..0000000
--- a/bin/ledger/encryption/public/encryption_service.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_PUBLIC_ENCRYPTION_SERVICE_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_PUBLIC_ENCRYPTION_SERVICE_H_
-
-#include <functional>
-#include <string>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace encryption {
-
-// Status of encryption operations.
-enum class Status {
- OK,
- AUTH_ERROR,
- NETWORK_ERROR,
- INVALID_ARGUMENT,
- IO_ERROR,
- INTERNAL_ERROR,
-};
-
-// Returns whether the given |status| is a permanent error.
-bool IsPermanentError(Status status);
-
-// Handles all encryption for a page of the Ledger.
-class EncryptionService {
- public:
- EncryptionService() {}
- virtual ~EncryptionService() {}
-
- // Construct the object identifier for the given digest, using the latest key
- // index and a default |deletion_scope_id|.
- // TODO(qsr): The user should have some control on the |deletion_scope_id| to
- // decide on the scope of deletion for objects.
- virtual storage::ObjectIdentifier MakeObjectIdentifier(
- storage::ObjectDigest digest) = 0;
-
- // Encrypts the given commit storage bytes for storing in the cloud.
- virtual void EncryptCommit(
- std::string commit_storage,
- fit::function<void(Status, std::string)> callback) = 0;
-
- // Decrypts the given encrypted commit storage bytes from the cloud.
- virtual void DecryptCommit(
- convert::ExtendedStringView storage_bytes,
- fit::function<void(Status, std::string)> callback) = 0;
-
- // Returns the obfuscated object name for the given identifier.
- //
- // This method is used to translate a local object identifier to the name that
- // is used to refer the object in the cloud provider.
- virtual void GetObjectName(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(Status, std::string)> callback) = 0;
-
- // Encrypts the given object.
- virtual void EncryptObject(
- storage::ObjectIdentifier object_identifier, fsl::SizedVmo content,
- fit::function<void(Status, std::string)> callback) = 0;
-
- // Decrypts the given object.
- virtual void DecryptObject(
- storage::ObjectIdentifier object_identifier, std::string encrypted_data,
- fit::function<void(Status, std::string)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(EncryptionService);
-};
-
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_PUBLIC_ENCRYPTION_SERVICE_H_
diff --git a/bin/ledger/encryption/public/encryption_service_factory.h b/bin/ledger/encryption/public/encryption_service_factory.h
deleted file mode 100644
index 2987dfe..0000000
--- a/bin/ledger/encryption/public/encryption_service_factory.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENCRYPTION_PUBLIC_ENCRYPTION_SERVICE_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_ENCRYPTION_PUBLIC_ENCRYPTION_SERVICE_FACTORY_H_
-
-#include <memory>
-
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-
-namespace encryption {
-
-// Factory for building EncryptionService per namespace.
-class EncryptionServiceFactory {
- public:
- EncryptionServiceFactory() {}
- virtual ~EncryptionServiceFactory() {}
-
- // Creates the encryption service for the given namespace.
- virtual std::unique_ptr<EncryptionService> MakeEncryptionService(
- std::string namespace_id) = 0;
-};
-
-} // namespace encryption
-
-#endif // PERIDOT_BIN_LEDGER_ENCRYPTION_PUBLIC_ENCRYPTION_SERVICE_FACTORY_H_
diff --git a/bin/ledger/environment/BUILD.gn b/bin/ledger/environment/BUILD.gn
deleted file mode 100644
index f7f46cb..0000000
--- a/bin/ledger/environment/BUILD.gn
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("environment") {
- sources = [
- "environment.cc",
- "environment.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/backoff",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/timekeeper",
- "//garnet/public/lib/timekeeper:impl",
- "//peridot/bin/ledger/coroutine",
- "//peridot/lib/rng",
- ]
-
- deps = [
- "//peridot/lib/ledger_client:constants",
- "//peridot/lib/rng:system",
- "//zircon/public/lib/async-cpp",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "environment_unittest.cc",
- ]
-
- deps = [
- ":environment",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//garnet/public/lib/timekeeper:testing",
- "//peridot/lib/rng:testing",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/environment/environment.cc b/bin/ledger/environment/environment.cc
deleted file mode 100644
index e5c33a2..0000000
--- a/bin/ledger/environment/environment.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/environment/environment.h"
-
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/fxl/macros.h>
-#include <lib/timekeeper/system_clock.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/lib/ledger_client/constants.h"
-#include "peridot/lib/rng/system_random.h"
-
-namespace ledger {
-
-Environment::Environment(
- bool disable_statistics, async_dispatcher_t* dispatcher,
- async_dispatcher_t* io_dispatcher, std::string firebase_api_key,
- component::StartupContext* startup_context,
- std::unique_ptr<coroutine::CoroutineService> coroutine_service,
- BackoffFactory backoff_factory, std::unique_ptr<timekeeper::Clock> clock,
- std::unique_ptr<rng::Random> random)
- : disable_statistics_(disable_statistics),
- dispatcher_(dispatcher),
- io_dispatcher_(io_dispatcher),
- firebase_api_key_(std::move(firebase_api_key)),
- startup_context_(startup_context),
- coroutine_service_(std::move(coroutine_service)),
- backoff_factory_(std::move(backoff_factory)),
- clock_(std::move(clock)),
- random_(std::move(random)) {
- FXL_DCHECK(dispatcher_);
- FXL_DCHECK(io_dispatcher_);
- FXL_DCHECK(startup_context_);
- FXL_DCHECK(coroutine_service_);
- FXL_DCHECK(backoff_factory_);
- FXL_DCHECK(clock_);
- FXL_DCHECK(random_);
-}
-
-Environment::Environment(Environment&& other) noexcept {
- *this = std::move(other);
-}
-
-Environment& Environment::operator=(Environment&& other) noexcept {
- disable_statistics_ = other.disable_statistics_;
- dispatcher_ = other.dispatcher_;
- io_dispatcher_ = other.io_dispatcher_;
- firebase_api_key_ = std::move(other.firebase_api_key_);
- startup_context_ = other.startup_context_;
- coroutine_service_ = std::move(other.coroutine_service_);
- backoff_factory_ = std::move(other.backoff_factory_);
- clock_ = std::move(other.clock_);
- random_ = std::move(other.random_);
- FXL_DCHECK(dispatcher_);
- FXL_DCHECK(io_dispatcher_);
- FXL_DCHECK(startup_context_);
- FXL_DCHECK(coroutine_service_);
- FXL_DCHECK(backoff_factory_);
- FXL_DCHECK(clock_);
- FXL_DCHECK(random_);
- return *this;
-}
-
-Environment::~Environment() {}
-
-std::unique_ptr<backoff::Backoff> Environment::MakeBackoff() {
- return backoff_factory_();
-}
-
-EnvironmentBuilder::EnvironmentBuilder()
- : firebase_api_key_(modular::kFirebaseApiKey) {}
-
-EnvironmentBuilder::~EnvironmentBuilder() {}
-
-EnvironmentBuilder& EnvironmentBuilder::SetDisableStatistics(
- bool disable_statistics) {
- disable_statistics_ = disable_statistics;
- return *this;
-}
-
-EnvironmentBuilder& EnvironmentBuilder::SetAsync(
- async_dispatcher_t* dispatcher) {
- dispatcher_ = dispatcher;
- return *this;
-}
-
-EnvironmentBuilder& EnvironmentBuilder::SetIOAsync(
- async_dispatcher_t* io_dispatcher) {
- io_dispatcher_ = io_dispatcher;
- return *this;
-}
-
-EnvironmentBuilder& EnvironmentBuilder::SetFirebaseApiKey(
- std::string firebase_api_key) {
- firebase_api_key_ = std::move(firebase_api_key);
- return *this;
-}
-
-EnvironmentBuilder& EnvironmentBuilder::SetStartupContext(
- component::StartupContext* startup_context) {
- startup_context_ = startup_context;
- return *this;
-}
-
-EnvironmentBuilder& EnvironmentBuilder::SetCoroutineService(
- std::unique_ptr<coroutine::CoroutineService> coroutine_service) {
- coroutine_service_ = std::move(coroutine_service);
- return *this;
-}
-
-// public
-EnvironmentBuilder& EnvironmentBuilder::SetBackoffFactory(
- Environment::BackoffFactory backoff_factory) {
- backoff_factory_ = std::move(backoff_factory);
- return *this;
-}
-
-EnvironmentBuilder& EnvironmentBuilder::SetClock(
- std::unique_ptr<timekeeper::Clock> clock) {
- clock_ = std::move(clock);
- return *this;
-}
-
-EnvironmentBuilder& EnvironmentBuilder::SetRandom(
- std::unique_ptr<rng::Random> random) {
- random_ = std::move(random);
- return *this;
-}
-
-Environment EnvironmentBuilder::Build() {
- if (!coroutine_service_) {
- coroutine_service_ = std::make_unique<coroutine::CoroutineServiceImpl>();
- }
- if (!clock_) {
- clock_ = std::make_unique<timekeeper::SystemClock>();
- }
- if (!random_) {
- random_ = std::make_unique<rng::SystemRandom>();
- }
- if (!backoff_factory_) {
- backoff_factory_ = [random = random_.get()] {
- return std::make_unique<backoff::ExponentialBackoff>(
- random->NewBitGenerator<uint64_t>());
- };
- }
- return Environment(disable_statistics_, dispatcher_, io_dispatcher_,
- std::move(firebase_api_key_), startup_context_,
- std::move(coroutine_service_), std::move(backoff_factory_),
- std::move(clock_), std::move(random_));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/environment/environment.h b/bin/ledger/environment/environment.h
deleted file mode 100644
index b6cc858..0000000
--- a/bin/ledger/environment/environment.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_ENVIRONMENT_ENVIRONMENT_H_
-#define PERIDOT_BIN_LEDGER_ENVIRONMENT_ENVIRONMENT_H_
-
-#include <memory>
-
-#include <lib/async/dispatcher.h>
-#include <lib/backoff/backoff.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/function.h>
-#include <lib/timekeeper/clock.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/lib/rng/random.h"
-
-namespace ledger {
-
-// Environment for the ledger application. |dispatcher| must outlive
-// |io_dispatcher|.
-class Environment {
- public:
- using BackoffFactory = fit::function<std::unique_ptr<backoff::Backoff>()>;
- Environment(bool disable_statistics, async_dispatcher_t* dispatcher,
- async_dispatcher_t* io_dispatcher, std::string firebase_api_key,
- component::StartupContext* startup_context,
- std::unique_ptr<coroutine::CoroutineService> coroutine_service,
- BackoffFactory backoff_factory,
- std::unique_ptr<timekeeper::Clock> clock,
- std::unique_ptr<rng::Random> random);
- Environment(Environment&& other) noexcept;
- ~Environment();
-
- Environment& operator=(Environment&& other) noexcept;
-
- bool disable_statistics() const { return disable_statistics_; }
-
- async_dispatcher_t* dispatcher() const { return dispatcher_; }
-
- // Returns the async_dispatcher_t to be used for I/O operations.
- async_dispatcher_t* io_dispatcher() const { return io_dispatcher_; }
-
- const std::string& firebase_api_key() const { return firebase_api_key_; };
-
- component::StartupContext* startup_context() const {
- return startup_context_;
- };
-
- coroutine::CoroutineService* coroutine_service() const {
- return coroutine_service_.get();
- }
-
- std::unique_ptr<backoff::Backoff> MakeBackoff();
-
- timekeeper::Clock* clock() const { return clock_.get(); }
-
- rng::Random* random() const { return random_.get(); }
-
- private:
- bool disable_statistics_;
-
- async_dispatcher_t* dispatcher_;
-
- // The async_dispatcher_t to be used for I/O operations.
- async_dispatcher_t* io_dispatcher_;
-
- // The firebase API key.
- std::string firebase_api_key_;
-
- component::StartupContext* startup_context_;
- std::unique_ptr<coroutine::CoroutineService> coroutine_service_;
- BackoffFactory backoff_factory_;
- std::unique_ptr<timekeeper::Clock> clock_;
- std::unique_ptr<rng::Random> random_;
-};
-
-// Builder for the environment.
-//
-// The |SetAsync|, |SetIOAsync| and |SetStartupContext| methods must be called
-// before the environment can be built.
-class EnvironmentBuilder {
- public:
- EnvironmentBuilder();
- ~EnvironmentBuilder();
-
- EnvironmentBuilder(const EnvironmentBuilder& other) = delete;
- EnvironmentBuilder(EnvironmentBuilder&& other) = delete;
- EnvironmentBuilder& operator=(const EnvironmentBuilder& other) = delete;
- EnvironmentBuilder& operator=(EnvironmentBuilder&& other) = delete;
-
- EnvironmentBuilder& SetDisableStatistics(bool disable_statistics);
- EnvironmentBuilder& SetAsync(async_dispatcher_t* dispatcher);
- EnvironmentBuilder& SetIOAsync(async_dispatcher_t* io_dispatcher);
- EnvironmentBuilder& SetFirebaseApiKey(std::string firebase_api_key);
- EnvironmentBuilder& SetStartupContext(
- component::StartupContext* startup_context);
- EnvironmentBuilder& SetCoroutineService(
- std::unique_ptr<coroutine::CoroutineService> coroutine_service);
- EnvironmentBuilder& SetBackoffFactory(
- Environment::BackoffFactory backoff_factory);
- EnvironmentBuilder& SetClock(std::unique_ptr<timekeeper::Clock> clock);
- EnvironmentBuilder& SetRandom(std::unique_ptr<rng::Random> random);
-
- Environment Build();
-
- private:
- bool disable_statistics_ = true;
- async_dispatcher_t* dispatcher_ = nullptr;
- async_dispatcher_t* io_dispatcher_ = nullptr;
- std::string firebase_api_key_;
- component::StartupContext* startup_context_ = nullptr;
- std::unique_ptr<coroutine::CoroutineService> coroutine_service_;
- Environment::BackoffFactory backoff_factory_;
- std::unique_ptr<timekeeper::Clock> clock_;
- std::unique_ptr<rng::Random> random_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_ENVIRONMENT_ENVIRONMENT_H_
diff --git a/bin/ledger/environment/environment_unittest.cc b/bin/ledger/environment/environment_unittest.cc
deleted file mode 100644
index 73775ba..0000000
--- a/bin/ledger/environment/environment_unittest.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/environment/environment.h"
-
-#include <lib/component/cpp/testing/startup_context_for_test.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include <lib/timekeeper/test_clock.h>
-
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-
-class EnvironmentTest : public ::gtest::TestLoopFixture {
- public:
- EnvironmentTest()
- : startup_context_(component::testing::StartupContextForTest::Create()) {}
-
- std::unique_ptr<component::testing::StartupContextForTest> startup_context_;
-};
-
-TEST_F(EnvironmentTest, InitializationOfAsyncAndIOAsync) {
- Environment env = EnvironmentBuilder()
- .SetStartupContext(startup_context_.get())
- .SetAsync(dispatcher())
- .SetIOAsync(dispatcher())
- .Build();
-
- EXPECT_EQ(dispatcher(), env.dispatcher());
- EXPECT_EQ(dispatcher(), env.io_dispatcher());
-}
-
-TEST_F(EnvironmentTest, InitializationClock) {
- auto clock = std::make_unique<timekeeper::TestClock>();
- auto clock_ptr = clock.get();
- Environment env = EnvironmentBuilder()
- .SetStartupContext(startup_context_.get())
- .SetAsync(dispatcher())
- .SetIOAsync(dispatcher())
- .SetClock(std::move(clock))
- .Build();
-
- EXPECT_EQ(clock_ptr, env.clock());
-}
-
-TEST_F(EnvironmentTest, InitializationRandom) {
- auto random = std::make_unique<rng::TestRandom>(0);
- auto random_ptr = random.get();
- Environment env = EnvironmentBuilder()
- .SetStartupContext(startup_context_.get())
- .SetAsync(dispatcher())
- .SetIOAsync(dispatcher())
- .SetRandom(std::move(random))
- .Build();
-
- EXPECT_EQ(random_ptr, env.random());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/fidl/BUILD.gn b/bin/ledger/fidl/BUILD.gn
deleted file mode 100644
index 46515a5..0000000
--- a/bin/ledger/fidl/BUILD.gn
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-import("//garnet/public/build/fostr/fostr_fidl.gni")
-import("//peridot/bin/ledger/fidl/error_notifier/error_notifier.gni")
-
-fidl("fidl") {
- name = "fuchsia.ledger.internal"
-
- sources = [
- "debug.fidl",
- "internal.fidl",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-}
-
-error_notifier_fidl("error_notifier_internal") {
- fidl_target = ":fidl"
-}
-
-error_notifier_fidl("error_notifier_public") {
- fidl_target = "//peridot/public/fidl/fuchsia.ledger"
-}
-
-source_set("error_notifier") {
- sources = [
- "error_notifier.h",
- ]
-
- public_deps = [
- ":error_notifier_internal",
- ":error_notifier_public",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/fidl/debug.fidl b/bin/ledger/fidl/debug.fidl
deleted file mode 100644
index 90c4468..0000000
--- a/bin/ledger/fidl/debug.fidl
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.ledger.internal;
-
-using fuchsia.ledger;
-using zx;
-
-[Discoverable]
-interface LedgerRepositoryDebug {
- // Returns the instances list in LedgerRepository.
- 1: GetInstancesList() -> (vector<vector<uint8>> result);
-
- // Returns the debugging interface for the given |ledger_name|.
- 2: GetLedgerDebug(vector<uint8> ledger_name, request<LedgerDebug> ledger_debug)
- -> (fuchsia.ledger.Status status);
-};
-
-interface LedgerDebug {
- // Returns the pages list in Ledger.
- 1: GetPagesList() -> (vector<fuchsia.ledger.PageId> result);
-
- // Returns OK and binds the |page_debug| for the given |page_id|.
- // Returns PAGE_NOT_FOUND if |page_id| isn't found.
- 2: GetPageDebug(fuchsia.ledger.PageId page_id, request<PageDebug> page_debug)
- -> (fuchsia.ledger.Status status);
-};
-
-interface PageDebug {
- // Returns OK and a list of the head commits IDs.
- 1: GetHeadCommitsIds() -> (fuchsia.ledger.Status status, vector<CommitId> result);
-
- // Returns OK and creates a snapshot of the page, allowing the client app to read a
- // consistent view of the content of the page.
- 2: GetSnapshot(CommitId commit_id, request<fuchsia.ledger.PageSnapshot> snapshot_request)
- -> (fuchsia.ledger.Status status);
-
- // Returns OK and the Commit struct filled for the given |commit_id|.
- 3: GetCommit(CommitId commit_id) -> (fuchsia.ledger.Status status, Commit? commit);
-};
-
-struct CommitId {
- vector<uint8> id;
-};
-
-struct Commit {
- // The ID of this commit.
- CommitId commit_id;
-
- // The IDs of this commit parents.
- vector<CommitId> parents_ids;
-
- // The creation timestamp of this commit in nanoseconds since epoch.
- zx.time timestamp;
-
- // The generation timestamp of this commit (the number of commits to the root).
- int64 generation;
-};
diff --git a/bin/ledger/fidl/error_notifier.h b/bin/ledger/fidl/error_notifier.h
deleted file mode 100644
index a6e1ad2..0000000
--- a/bin/ledger/fidl/error_notifier.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_FIDL_ERROR_NOTIFIER_H_
-#define PERIDOT_BIN_LEDGER_FIDL_ERROR_NOTIFIER_H_
-
-// Includes generated code for ErrorNotifier for the public and private Ledger
-// APIs.
-
-#include "peridot/bin/ledger/fidl/error_notifier_internal.h"
-#include "peridot/bin/ledger/fidl/error_notifier_public.h"
-
-#endif // PERIDOT_BIN_LEDGER_FIDL_ERROR_NOTIFIER_H_
diff --git a/bin/ledger/fidl/error_notifier/BUILD.gn b/bin/ledger/fidl/error_notifier/BUILD.gn
deleted file mode 100644
index dfe0820..0000000
--- a/bin/ledger/fidl/error_notifier/BUILD.gn
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-import("//peridot/bin/ledger/fidl/error_notifier/error_notifier.gni")
-
-source_set("error_notifier") {
- sources = [
- "error_notifier_binding.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fidl/cpp",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/sync_helper",
- "//zircon/public/lib/fit",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-error_notifier_fidl("error_notifier_fidl_test") {
- testonly = true
-
- fidl_target = "//peridot/bin/ledger/fidl/error_notifier/fidl"
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "error_notifier_binding_unittest.cc",
- ]
-
- deps = [
- ":error_notifier",
- ":error_notifier_fidl_test",
- "//garnet/public/lib/callback",
- "//peridot/bin/ledger/fidl/error_notifier/fidl",
- "//third_party/googletest:gtest",
- "//zircon/public/lib/async-testutils",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/fidl/error_notifier/README.md b/bin/ledger/fidl/error_notifier/README.md
deleted file mode 100644
index cf85072..0000000
--- a/bin/ledger/fidl/error_notifier/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-## Generated ErrorNotifierDelegate ##
-
-The ledger API is sending a status and closing the connection on unexpected
-errors for every interface that extends ledger.ErrorNotifier. These interfaces
-must also implement a |Sync| method that will return when all requests called
-before the |Sync| call have been handled.
-
-When impementing such an interface, one must keep track of each connection to be
-able to close it with the correct status in case of error, and must also
-implement the |Sync| method.
-
-To reduce the amount of repeating code, the files in this directory allow to
-automatically generate an ErrorNotifierDelegate and an implementation of the
-base interface that delegates to it.
-
-When one wants to implement an interface extending ledger.ErrorNotifier, one
-therefore only need to implement the generated delegate interface. For each
-method in the initial interface, the delegate will have a corresponding method
-with an additional callback taking a ::fuchsia::ledger::Status. The implementor
-must call this additional callback when the call is finished, with either
-Status::OK if the call is successful, or with any error status if it is not.
-
-When one wants to bind a request, one can instantiate a new
-ErrorNotifierBinding, associating it with an implementation of the Delegate. The
-binding will take care of forwarding the call to the Delegate, as well as handling
-the error reporting and the |Sync| calls.
-
-For an example, see error\_notifier\_proxy\_base\_unittest.cc, which implements
-the ErrorNotifierTestDelegate interface that is automatically generated from the
-ErrorNotifierTest FIDL interface defined in fidl/error\_notifier\_test.fidl.
diff --git a/bin/ledger/fidl/error_notifier/error_notifier.fidlmerge b/bin/ledger/fidl/error_notifier/error_notifier.fidlmerge
deleted file mode 100644
index 58bd8d0..0000000
--- a/bin/ledger/fidl/error_notifier/error_notifier.fidlmerge
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// fidlmerge template for ErrorNotifier support. It generates a .h cc file for
-// the proxy and delegate handling error reporting for the ledger.
-//
-// NOTE: This template generates a "#pragma once", which should be replaced by
-// an #ifndef guard to conform to the style guide.
-
-
-// Produces the copyright messages for a file header.
-{{- define "FileHeader" -}}
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// WARNING: This file is machine generated by fidlmerge.
-{{- end }}
-
-// Produces a C++ expression for a types.EncodedCompoundIdentifier.
-{{- define "QualifiedId" }}
- {{- range .Parts.Library -}}
- ::{{ . }}
- {{- end -}}
- ::
- {{- .Parts.Name }}
-{{- end }}
-
-// Produces a C++ type for a handle.
-{{- define "CppHandleType" -}}
- {{- if .HandleSubtype -}}
-::zx::{{ .HandleSubtype }}
- {{- else -}}
-::zx::handle
- {{- end -}}
-{{- end }}
-
-// Produces a C++ type of an identifier.
-// This can be either and InterfaceHandle for interfaces, a std::unique_ptr for
-// a nullable struct, or the struct itself for a non-nullable struct.
-{{- define "CppIdentifierType" -}}
- {{- $type := declType .Identifier -}}
- {{- if eq $type "interface" -}}
-::fidl::InterfaceHandle<{{- template "QualifiedId" .Identifier }}>
- {{- else -}}
- {{- if .Nullable -}}
-std::unique_ptr<{{- template "QualifiedId" .Identifier }}>
- {{- else -}}
-{{- template "QualifiedId" .Identifier }}
- {{- end -}}
- {{- end -}}
-{{- end }}
-
-// Produces a C++ type of a |Type|
-{{- define "CppType" -}}
- {{- if eq .Kind "identifier" -}}
-{{- template "CppIdentifierType" . }}
- {{- end -}}
- {{- if eq .Kind "handle" -}}
-{{- template "CppHandleType" . }}
- {{- end -}}
- {{- if eq .Kind "vector" -}}
- {{- if .Nullable }}
-::fidl::VectorPtr<{{- template "CppType" .ElementType }}>
- {{- else }}
-::std::vector<{{- template "CppType" .ElementType }}>
- {{- end }}
- {{- end -}}
- {{- if eq .Kind "request" -}}
-::fidl::InterfaceRequest<{{- template "QualifiedId" .RequestSubtype }}>
- {{- end -}}
- {{- if eq .Kind "primitive" -}}
-{{ .PrimitiveSubtype }}_t
- {{- end }}
- {{- if eq .Kind "string" -}}
- {{- if .Nullable }}
-::fidl::StringPtr
- {{- else }}
-::std::string
- {{- end }}
- {{- end }}
-{{- end -}}
-
-// Produces a comma separated list of function parameters (C++ type and name)
-{{- define "Params" -}}
- {{- range $index, $param := . -}}
- {{- if $index }}, {{ end -}}{{ template "CppType" $param.Type }} {{ $param.Name }}
- {{- end -}}
-{{- end }}
-
-// Produces a comma separated list of move operations.
-{{- define "ForwardParams" -}}
- {{- range $index, $param := . -}}
- {{- if $index }}, {{ end -}}std::move({{ $param.Name }})
- {{- end -}}
-{{- end }}
-
-// Produces a comma separated list of C++ types.
-{{- define "ParamTypes" -}}
- {{- range $index, $param := . -}}
- {{- if $index }}, {{ end -}}{{ template "CppType" .Type }}
- {{- end -}}
-{{- end }}
-
-// Produces the type of the callback associated with the current response.
-{{- define "CallbackType" -}}
-::fit::function<void({{ template "ParamTypes" .Response }})>
-{{- end }}
-
-// Produces the type of the callback associated with the current response and an additional Status.
-{{- define "CallbackTypeWithStatus" -}}
-::fit::function<void(::fuchsia::ledger::Status{{ if .Response}}, {{end}}{{ template "ParamTypes" .Response }})>
-{{- end }}
-
-
-// Produces the signature of the FIDL interface method.
-{{- define "RequestMethodSignature" -}}
- {{- if .HasResponse -}}
-{{ .Name }}({{ template "Params" .Request }}{{ if .Request }}, {{ end }}{{ template "CallbackType" . }} callback)
- {{- else -}}
-{{ .Name }}({{ template "Params" .Request }})
- {{- end -}}
-{{ end -}}
-
-// Produces an implementation of the FIDL interface method that forward to the NotifierDelegate.
-{{- define "RequestMethodSignatureForward" -}}
- {{- if .HasResponse -}}
-{{ .Name }}({{ template "ForwardParams" .Request }}{{ if .Request }}, {{ end }}binding_->WrapOperation("{{ .Name }}", std::move(callback)))
- {{- else -}}
-{{ .Name }}({{ template "ForwardParams" .Request }}{{ if .Request }}, {{ end }}binding_->NewErrorCallback("{{ .Name }}"))
- {{- end -}}
-{{ end -}}
-
-// Produces the signature of the NotifierDelegate method associated with the FIDL interface method.
-{{- define "RequestMethodSignatureErrorNotifierDelegate" -}}
- {{- if .HasResponse -}}
-{{ .Name }}({{ template "Params" .Request }}{{ if .Request }}, {{ end }}{{ template "CallbackTypeWithStatus" . }} callback)
- {{- else -}}
-{{ .Name }}({{ template "Params" .Request }}{{ if .Request }}, {{ end }}::fit::function<void(::fuchsia::ledger::Status)> callback)
- {{- end -}}
-{{ end -}}
-
-// Produces the include for the original FIDL generated cpp file.
-{{- define "ThisFidlInclude" -}}
- #include <{{- range .Name.Parts}}{{ . }}/{{ end }}cpp/fidl.h>
-{{- end }}
-
-// Converts a library into a slashed version of its name, e.g. fuchsia/foo/.
-{{- define "LibrarySlashes" -}}
- {{- range .Name.Parts}}{{ . }}/{{ end }}
-{{- end }}
-
-{{- define "IncludeHeader" }}
- {{- template "FileHeader" }}
-
-#pragma once
-
-{{ template "ThisFidlInclude" . }}
-#include <lib/fidl/cpp/interface_request.h>
-
-#include "peridot/bin/ledger/fidl/error_notifier/error_notifier_binding.h"
-
-{{/* keep the newline */}}
- {{- range .Name.Parts }}
-namespace {{ . }} {
- {{- end }}
-
-{{/* keep the newline */}}
-{{- end }}
-
-
-{{- define "NamespaceClose" }}
-{{/* keep the newline */}}
- {{- range .Name.PartsReversed }}
-} // namespace {{ . }}
- {{- end }}
-{{- end }}
-
-
-// Define the generated classes for the given FIDL interface.
-{{- define "InterfaceDeclaration" }}
-class {{ .Name.Parts.Name }}ErrorNotifierDelegate {
- public:
- using FidlInterface = {{ .Name.Parts.Name }};
- class Impl;
-
- virtual ~{{ .Name.Parts.Name }}ErrorNotifierDelegate() = default;
- {{- range .Methods }}
- {{- if (and .HasRequest (not (eq .Name "Sync" ))) }}
- virtual void {{ template "RequestMethodSignatureErrorNotifierDelegate" . }} = 0;
- {{- end }}
- {{- end }}
-};
-
-class {{ .Name.Parts.Name }}ErrorNotifierDelegate::Impl : public {{ .Name.Parts.Name }} {
- public:
- static constexpr char kInterfaceName[] = "{{ .Name.Parts.Name }}";
- Impl({{ .Name.Parts.Name }}ErrorNotifierDelegate* delegate,
- ::ledger::ErrorNotifierBinding<{{ .Name.Parts.Name }}ErrorNotifierDelegate>* binding)
- : delegate_(delegate), binding_(binding) {}
-
- private:
- {{- range .Methods }}
- {{- if (and .HasRequest (not (eq .Name "Sync" ))) }}
- void {{ template "RequestMethodSignature" . }} override {
- delegate_->{{ template "RequestMethodSignatureForward" . }};
- }
- {{- end }}
- {{- end }}
- void Sync(::fit::function<void()> callback) override {
- binding_->Sync(std::move(callback));
- }
-
- {{ .Name.Parts.Name }}ErrorNotifierDelegate* delegate_;
- ::ledger::ErrorNotifierBinding<{{ .Name.Parts.Name }}ErrorNotifierDelegate>* binding_;
-};
-
-{{/* keep the newline */}}
-{{- end }}
-
-// Define the generated classed for the FIDL library.
-{{- define "InterfaceWriterDecls" }}
- {{/*
- * Find the interfaces that extends ErrorNotifier.
- *
- * To do this, range over all interfaces that are not ErrorNotifier, and find a method call "Sync".
- */}}
- {{- range $interface := .Interfaces }}
- {{- /* Do not generate anything for the ErrorNotifier interface */ -}}
- {{- if not (eq .Name.Parts.Name "ErrorNotifier") -}}
- {{- range .Methods }}
- {{- if .HasRequest }}
- {{- /* Use the "Sync" method has a marker to detect interfaces extending ErrorNotifier */ -}}
- {{- if eq .Name "Sync" }}
- {{- template "InterfaceDeclaration" $interface }}
- {{- end }}
- {{- end }}
- {{- end }}
- {{- end }}
- {{- end }}
-{{- end }}
-
-{{- define "IncludeFile" }}
- {{- template "IncludeHeader" . }}
- {{- template "InterfaceWriterDecls" . }}
- {{- template "NamespaceClose" . }}
-{{- end }}
-
-{{- define "Main" }}
- {{- $include_path := .Output ".h" }}
- {{- .Generate $include_path "IncludeFile" . }}
-{{- end }}
diff --git a/bin/ledger/fidl/error_notifier/error_notifier.gni b/bin/ledger/fidl/error_notifier/error_notifier.gni
deleted file mode 100644
index b7cea74..0000000
--- a/bin/ledger/fidl/error_notifier/error_notifier.gni
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/compiled_action.gni")
-import("//build/cpp/fidlmerge_cpp.gni")
-
-# Declares a error_notifier library that contains C++ delegate allowing to
-# send errors.
-#
-# Parameters
-#
-# fidl_target (required)
-# Specifies the fidl target from which to read fidl json.
-#
-# deps, public_deps, test_only, visibility (optional)
-# These parameters are forwarded to the source_set. This template lists
-# //garnet/public/lib/error_notifier and the value of fidl_target as public_deps.
-#
-
-template("error_notifier_fidl") {
- assert(is_fuchsia, "This template can only be used in $target_toolchain.")
-
- assert(defined(invoker.fidl_target),
- "error_notifier_fidl requires parameter fidl_target.")
-
- fidl_target = invoker.fidl_target
-
- name = target_name
-
- fidlmerge_cpp(name) {
- forward_variables_from(invoker,
- [
- "deps",
- "testonly",
- "visibility",
- ])
-
- fidl_target = "$fidl_target"
-
- template_path =
- "//peridot/bin/ledger/fidl/error_notifier/error_notifier.fidlmerge"
-
- generated_source_base = name
-
- generated_source_extensions = [ ".h" ]
-
- public_deps = [
- "$fidl_target",
- "//garnet/public/lib/fidl/cpp",
- "//peridot/bin/ledger/fidl/error_notifier",
- ]
-
- if (defined(invoker.public_deps)) {
- public_deps += invoker.public_deps
- }
- }
-}
diff --git a/bin/ledger/fidl/error_notifier/error_notifier_binding.h b/bin/ledger/fidl/error_notifier/error_notifier_binding.h
deleted file mode 100644
index bcc795a..0000000
--- a/bin/ledger/fidl/error_notifier/error_notifier_binding.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_FIDL_ERROR_NOTIFIER_ERROR_NOTIFIER_BINDING_H_
-#define PERIDOT_BIN_LEDGER_FIDL_ERROR_NOTIFIER_ERROR_NOTIFIER_BINDING_H_
-
-#include <map>
-#include <utility>
-
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/enum.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/sync_helper/sync_helper.h"
-
-namespace ledger {
-
-// Class for binding of FIDL interface implementing the ErrorNotifier interface
-// and using the error notifier delegate interface |D|.
-// For a FIDL interface Foo, |D| is an interface named FooErrorNotifierDelegate
-// that needs to be implemented by the user and passed to ErrorNotifierBinding.
-//
-// This class internally handles the following features:
-// - Implement the |Sync| method.
-// - Provides a factory for passing a callback to the companion implementation
-// that will handle reporting the error and closing the connection.
-// - Provides a |WrapOperation| method that needs to be called on all callback
-// before passing to the companion implementation so that |Sync| can keep
-// track of what operations are currently in progress.
-//
-// This class exposes the following features:
-// - Access to the methods of the underlying bindings.
-// - Implement the |set_on_empty| method to be usable with AutoCleanableSet.
-template <typename D>
-class ErrorNotifierBinding {
- public:
- ErrorNotifierBinding(D* delegate) : impl_(delegate, this), binding_(&impl_) {
- binding_.set_error_handler(
- [this](zx_status_t /* status */) { CheckEmpty(); });
- sync_helper_.set_on_empty([this] { CheckEmpty(); });
- }
-
- ErrorNotifierBinding(
- D* delegate, fidl::InterfaceRequest<typename D::FidlInterface> request,
- async_dispatcher_t* dispatcher = nullptr)
- : ErrorNotifierBinding(delegate) {
- binding_.Bind(std::move(request), dispatcher);
- }
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
- bool empty() { return !binding_.is_bound() && sync_helper_.empty(); }
-
- fidl::InterfaceRequest<typename D::FidlInterface> Unbind() {
- return binding_.Unbind();
- }
- fidl::InterfaceHandle<typename D::FidlInterface> NewBinding(
- async_dispatcher_t* dispatcher = nullptr) {
- return binding_.NewBinding(dispatcher);
- }
-
- void Close(zx_status_t status) { binding_.Close(status); }
-
- void Close(ledger::Status status) { Close(static_cast<zx_status_t>(status)); }
-
- private:
- friend typename D::Impl;
-
- void Sync(fit::function<void()> callback) {
- sync_helper_.RegisterSynchronizationCallback(std::move(callback));
- }
-
- // Wraps a callback in another one that preprends a Status arguments and
- // handles the status in case of error.
- template <typename... Args>
- auto WrapOperation(const char* function_name,
- fit::function<void(Args...)> callback) {
- return sync_helper_.WrapOperation(
- [this, function_name, callback = std::move(callback)](
- ::fuchsia::ledger::Status status, Args&&... args) {
- if (status == ::fuchsia::ledger::Status::OK) {
- callback(std::forward<Args>(args)...);
- return;
- }
- FXL_LOG(INFO) << "FIDL call " << D::Impl::kInterfaceName
- << "::" << function_name
- << " failed with status: " << fidl::ToUnderlying(status)
- << ". Sending the epitaph and closing the connection.";
- Close(status);
- });
- }
-
- // Returns a new callback taking a ledger::Status. This callback will be
- // responsible, in case of error, to send the status back as an event and
- // close the connection to the client.
- auto NewErrorCallback(const char* function_name) {
- return WrapOperation(function_name, fit::closure([] {}));
- }
-
- void CheckEmpty() {
- if (empty() && on_empty_) {
- on_empty_();
- }
- }
-
- typename D::Impl impl_;
- fidl::Binding<typename D::FidlInterface> binding_;
- fit::closure on_empty_;
- SyncHelper sync_helper_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_FIDL_ERROR_NOTIFIER_ERROR_NOTIFIER_BINDING_H_
diff --git a/bin/ledger/fidl/error_notifier/error_notifier_binding_unittest.cc b/bin/ledger/fidl/error_notifier/error_notifier_binding_unittest.cc
deleted file mode 100644
index 5355bfc..0000000
--- a/bin/ledger/fidl/error_notifier/error_notifier_binding_unittest.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/fidl/error_notifier/error_notifier_fidl_test.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-
-namespace ledger {
-namespace {
-
-class ErrorNotifierTestErrorNotifierDelegateImpl
- : public fuchsia::ledger::errornotifiertest::
- ErrorNotifierTestErrorNotifierDelegate {
- public:
- int no_reponse_count() { return no_reponse_count_; }
- int empty_reponse_count() { return empty_reponse_count_; }
- int not_empty_reponse_count() { return not_empty_reponse_count_; }
- int parameter_received() { return parameter_received_; }
- fuchsia::ledger::Status& status_to_return() { return status_to_return_; }
- bool& delay_callback() { return delay_callback_; }
- void RunDelayedCallback() { delayed_callback_(); }
-
- private:
- // ErrorNotifierTestErrorNotifierDelegate implementation.
- void NoResponse(
- fit::function<void(fuchsia::ledger::Status)> callback) override {
- NoResponseWithParameter(1, std::move(callback));
- }
- void NoResponseWithParameter(
- int8_t input,
- fit::function<void(fuchsia::ledger::Status)> callback) override {
- parameter_received_ = input;
- ++no_reponse_count_;
- delayed_callback_ = [callback = std::move(callback),
- status_to_return = status_to_return_] {
- callback(status_to_return);
- };
- if (!delay_callback_) {
- delayed_callback_();
- }
- }
- void EmptyResponse(
- fit::function<void(fuchsia::ledger::Status)> callback) override {
- EmptyResponseWithParameter(2, std::move(callback));
- }
- void EmptyResponseWithParameter(
- int8_t input,
- fit::function<void(fuchsia::ledger::Status)> callback) override {
- parameter_received_ = input;
- ++empty_reponse_count_;
- delayed_callback_ = [callback = std::move(callback),
- status_to_return = status_to_return_] {
- callback(status_to_return);
- };
- if (!delay_callback_) {
- delayed_callback_();
- }
- }
-
- void NotEmptyResponse(::fit::function<void(fuchsia::ledger::Status, int8_t)>
- callback) override {
- NotEmptyResponseWithParameter(3, std::move(callback));
- }
- void NotEmptyResponseWithParameter(
- int8_t input,
- fit::function<void(fuchsia::ledger::Status, int8_t)> callback) override {
- parameter_received_ = input;
- ++not_empty_reponse_count_;
- delayed_callback_ = [callback = std::move(callback),
- status_to_return = status_to_return_] {
- callback(status_to_return, 1);
- };
- if (!delay_callback_) {
- delayed_callback_();
- }
- }
-
- int32_t no_reponse_count_ = 0;
- int32_t empty_reponse_count_ = 0;
- int32_t not_empty_reponse_count_ = 0;
- int32_t parameter_received_ = 0;
- fuchsia::ledger::Status status_to_return_ = fuchsia::ledger::Status::OK;
- bool delay_callback_ = false;
- fit::closure delayed_callback_;
-};
-
-class ErrorNotifierTest : public gtest::TestLoopFixture {
- protected:
- ErrorNotifierTest() : binding_(&impl_, ptr_.NewRequest()) {}
-
- ErrorNotifierTestErrorNotifierDelegateImpl impl_;
- fuchsia::ledger::errornotifiertest::ErrorNotifierTestPtr ptr_;
- ErrorNotifierBinding<fuchsia::ledger::errornotifiertest::
- ErrorNotifierTestErrorNotifierDelegate>
- binding_;
-};
-
-TEST_F(ErrorNotifierTest, NoResponse) {
- zx_status_t status;
- bool error_called;
-
- ptr_.set_error_handler(
- callback::Capture(callback::SetWhenCalled(&error_called), &status));
-
- ptr_->NoResponse();
- RunLoopUntilIdle();
- EXPECT_EQ(1, impl_.no_reponse_count());
- EXPECT_TRUE(ptr_);
- EXPECT_FALSE(error_called);
-
- impl_.status_to_return() = fuchsia::ledger::Status::IO_ERROR;
- ptr_->NoResponse();
- RunLoopUntilIdle();
- EXPECT_EQ(2, impl_.no_reponse_count());
- EXPECT_FALSE(ptr_);
- EXPECT_TRUE(error_called);
- EXPECT_EQ(static_cast<zx_status_t>(fuchsia::ledger::Status::IO_ERROR),
- status);
-}
-
-TEST_F(ErrorNotifierTest, NoResponseWithParameter) {
- ptr_->NoResponseWithParameter(42);
- RunLoopUntilIdle();
- EXPECT_EQ(1, impl_.no_reponse_count());
- EXPECT_EQ(42, impl_.parameter_received());
-}
-
-TEST_F(ErrorNotifierTest, NoResponseSync) {
- impl_.delay_callback() = true;
-
- bool sync_called;
- ptr_->NoResponse();
- ptr_->Sync(callback::SetWhenCalled(&sync_called));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(sync_called);
-
- impl_.RunDelayedCallback();
- RunLoopUntilIdle();
- EXPECT_TRUE(sync_called);
-}
-
-TEST_F(ErrorNotifierTest, EmptyResponse) {
- zx_status_t status;
- bool error_called;
- bool callback_called;
-
- ptr_.set_error_handler(
- callback::Capture(callback::SetWhenCalled(&error_called), &status));
-
- ptr_->EmptyResponse(callback::SetWhenCalled(&callback_called));
- RunLoopUntilIdle();
- EXPECT_EQ(1, impl_.empty_reponse_count());
- EXPECT_TRUE(callback_called);
- EXPECT_TRUE(ptr_);
- EXPECT_FALSE(error_called);
-
- impl_.status_to_return() = fuchsia::ledger::Status::IO_ERROR;
- ptr_->EmptyResponse(callback::SetWhenCalled(&callback_called));
- RunLoopUntilIdle();
- EXPECT_EQ(2, impl_.empty_reponse_count());
- EXPECT_FALSE(callback_called);
- EXPECT_FALSE(ptr_);
- EXPECT_TRUE(error_called);
- EXPECT_EQ(static_cast<zx_status_t>(fuchsia::ledger::Status::IO_ERROR),
- status);
-}
-
-TEST_F(ErrorNotifierTest, EmptyResponseWithParameter) {
- bool callback_called;
-
- ptr_->EmptyResponseWithParameter(42,
- callback::SetWhenCalled(&callback_called));
- RunLoopUntilIdle();
- EXPECT_EQ(1, impl_.empty_reponse_count());
- EXPECT_EQ(42, impl_.parameter_received());
- EXPECT_TRUE(callback_called);
-}
-
-TEST_F(ErrorNotifierTest, EmptyResponseSync) {
- impl_.delay_callback() = true;
-
- bool callback_called;
- bool sync_called;
- ptr_->EmptyResponse(callback::SetWhenCalled(&callback_called));
- ptr_->Sync(callback::SetWhenCalled(&sync_called));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_FALSE(sync_called);
-
- impl_.RunDelayedCallback();
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_TRUE(sync_called);
-}
-
-TEST_F(ErrorNotifierTest, NotEmptyResponse) {
- zx_status_t status;
- bool error_called;
- bool callback_called;
- int callback_value;
-
- ptr_.set_error_handler(
- callback::Capture(callback::SetWhenCalled(&error_called), &status));
-
- ptr_->NotEmptyResponse(callback::Capture(
- callback::SetWhenCalled(&callback_called), &callback_value));
- RunLoopUntilIdle();
- EXPECT_EQ(1, impl_.not_empty_reponse_count());
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(1, callback_value);
- EXPECT_TRUE(ptr_);
- EXPECT_FALSE(error_called);
-
- impl_.status_to_return() = fuchsia::ledger::Status::IO_ERROR;
- ptr_->NotEmptyResponse(callback::Capture(
- callback::SetWhenCalled(&callback_called), &std::ignore));
- RunLoopUntilIdle();
- EXPECT_EQ(2, impl_.not_empty_reponse_count());
- EXPECT_FALSE(callback_called);
- EXPECT_FALSE(ptr_);
- EXPECT_TRUE(error_called);
- EXPECT_EQ(static_cast<zx_status_t>(fuchsia::ledger::Status::IO_ERROR),
- status);
-}
-
-TEST_F(ErrorNotifierTest, NotEmptyResponseWithParameter) {
- bool callback_called;
- int callback_value;
-
- ptr_->NotEmptyResponseWithParameter(
- 42, callback::Capture(callback::SetWhenCalled(&callback_called),
- &callback_value));
- RunLoopUntilIdle();
- EXPECT_EQ(1, impl_.not_empty_reponse_count());
- EXPECT_EQ(42, impl_.parameter_received());
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(1, callback_value);
-}
-
-TEST_F(ErrorNotifierTest, NotEmptyResponseSync) {
- impl_.delay_callback() = true;
-
- bool callback_called;
- bool sync_called;
- ptr_->NotEmptyResponse(callback::Capture(
- callback::SetWhenCalled(&callback_called), &std::ignore));
- ptr_->Sync(callback::SetWhenCalled(&sync_called));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(callback_called);
- EXPECT_FALSE(sync_called);
-
- impl_.RunDelayedCallback();
- RunLoopUntilIdle();
- EXPECT_TRUE(callback_called);
- EXPECT_TRUE(sync_called);
-}
-
-TEST_F(ErrorNotifierTest, OnEmpty) {
- bool called;
- binding_.set_on_empty(callback::SetWhenCalled(&called));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- ptr_.Unbind();
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-}
-
-TEST_F(ErrorNotifierTest, OnEmptyWithRunningOperation) {
- impl_.delay_callback() = true;
- bool called;
- binding_.set_on_empty(callback::SetWhenCalled(&called));
- ptr_->NoResponse();
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- ptr_.Unbind();
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- impl_.RunDelayedCallback();
- EXPECT_TRUE(called);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/fidl/error_notifier/fidl/BUILD.gn b/bin/ledger/fidl/error_notifier/fidl/BUILD.gn
deleted file mode 100644
index ae501f3..0000000
--- a/bin/ledger/fidl/error_notifier/fidl/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-fidl("fidl") {
- name = "fuchsia.ledger.errornotifiertest"
-
- sources = [
- "error_notifier_test.fidl",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.ledger",
- ]
-}
diff --git a/bin/ledger/fidl/error_notifier/fidl/error_notifier_test.fidl b/bin/ledger/fidl/error_notifier/fidl/error_notifier_test.fidl
deleted file mode 100644
index 5acdaaf..0000000
--- a/bin/ledger/fidl/error_notifier/fidl/error_notifier_test.fidl
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.ledger.errornotifiertest;
-
-using fuchsia.ledger;
-
-interface ErrorNotifierTest : fuchsia.ledger.ErrorNotifier {
- 1: NoResponse();
- 2: NoResponseWithParameter(int8 input);
- 3: EmptyResponse() -> ();
- 4: EmptyResponseWithParameter(int8 input) -> ();
- 5: NotEmptyResponse() -> (int8 value);
- 6: NotEmptyResponseWithParameter(int8 input) -> (int8 value);
-};
diff --git a/bin/ledger/fidl/include/BUILD.gn b/bin/ledger/fidl/include/BUILD.gn
deleted file mode 100644
index ad12044..0000000
--- a/bin/ledger/fidl/include/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("include") {
- sources = [
- "types.h",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/fidl",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-}
diff --git a/bin/ledger/fidl/include/types.h b/bin/ledger/fidl/include/types.h
deleted file mode 100644
index 9712788..0000000
--- a/bin/ledger/fidl/include/types.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_FIDL_INCLUDE_TYPES_H_
-#define PERIDOT_BIN_LEDGER_FIDL_INCLUDE_TYPES_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-
-// More convenient aliases for FIDL types.
-
-namespace cloud_provider {
-using CloudProvider = fuchsia::ledger::cloud::CloudProvider;
-using CloudProviderPtr = fuchsia::ledger::cloud::CloudProviderPtr;
-using CommitPack = fuchsia::ledger::cloud::CommitPack;
-using DeviceSet = fuchsia::ledger::cloud::DeviceSet;
-using DeviceSetPtr = fuchsia::ledger::cloud::DeviceSetPtr;
-using DeviceSetWatcher = fuchsia::ledger::cloud::DeviceSetWatcher;
-using DeviceSetWatcherPtr = fuchsia::ledger::cloud::DeviceSetWatcherPtr;
-using PageCloud = fuchsia::ledger::cloud::PageCloud;
-using PageCloudPtr = fuchsia::ledger::cloud::PageCloudPtr;
-using PageCloudWatcher = fuchsia::ledger::cloud::PageCloudWatcher;
-using PageCloudWatcherPtr = fuchsia::ledger::cloud::PageCloudWatcherPtr;
-using Status = fuchsia::ledger::cloud::Status;
-using Token = fuchsia::ledger::cloud::Token;
-} // namespace cloud_provider
-
-namespace ledger {
-using BytesOrReference = fuchsia::ledger::BytesOrReference;
-using BytesOrReferencePtr = fuchsia::ledger::BytesOrReferencePtr;
-using ConflictResolutionWaitStatus =
- fuchsia::ledger::ConflictResolutionWaitStatus;
-using ConflictResolver = fuchsia::ledger::ConflictResolver;
-using ConflictResolverFactory = fuchsia::ledger::ConflictResolverFactory;
-using ConflictResolverFactoryPtr = fuchsia::ledger::ConflictResolverFactoryPtr;
-using ConflictResolverPtr = fuchsia::ledger::ConflictResolverPtr;
-using DiffEntry = fuchsia::ledger::DiffEntry;
-using IterationStatus = fuchsia::ledger::IterationStatus;
-using Entry = fuchsia::ledger::Entry;
-using InlinedEntry = fuchsia::ledger::InlinedEntry;
-using InlinedValue = fuchsia::ledger::InlinedValue;
-using InlinedValuePtr = fuchsia::ledger::InlinedValuePtr;
-using Ledger = fuchsia::ledger::Ledger;
-using LedgerPtr = fuchsia::ledger::LedgerPtr;
-using MergePolicy = fuchsia::ledger::MergePolicy;
-using MergeResultProvider = fuchsia::ledger::MergeResultProvider;
-using MergeResultProviderPtr = fuchsia::ledger::MergeResultProviderPtr;
-using MergedValue = fuchsia::ledger::MergedValue;
-using Page = fuchsia::ledger::Page;
-using PageChange = fuchsia::ledger::PageChange;
-using PageChangePtr = fuchsia::ledger::PageChangePtr;
-using PageId = fuchsia::ledger::PageId;
-using PageIdPtr = fuchsia::ledger::PageIdPtr;
-using PagePtr = fuchsia::ledger::PagePtr;
-using PageSnapshot = fuchsia::ledger::PageSnapshot;
-using PageSnapshotPtr = fuchsia::ledger::PageSnapshotPtr;
-using PageWatcher = fuchsia::ledger::PageWatcher;
-using PageWatcherPtr = fuchsia::ledger::PageWatcherPtr;
-using Priority = fuchsia::ledger::Priority;
-using Reference = fuchsia::ledger::Reference;
-using ReferencePtr = fuchsia::ledger::ReferencePtr;
-using ResultState = fuchsia::ledger::ResultState;
-using Status = fuchsia::ledger::Status;
-using SyncState = fuchsia::ledger::SyncState;
-using SyncWatcher = fuchsia::ledger::SyncWatcher;
-using SyncWatcherPtr = fuchsia::ledger::SyncWatcherPtr;
-using Token = fuchsia::ledger::Token;
-using Value = fuchsia::ledger::Value;
-using ValuePtr = fuchsia::ledger::ValuePtr;
-using ValueSource = fuchsia::ledger::ValueSource;
-} // namespace ledger
-
-namespace ledger_internal {
-using Commit = fuchsia::ledger::internal::Commit;
-using CommitId = fuchsia::ledger::internal::CommitId;
-using CommitPtr = fuchsia::ledger::internal::CommitPtr;
-using LedgerController = fuchsia::ledger::internal::LedgerController;
-using LedgerControllerPtr = fuchsia::ledger::internal::LedgerControllerPtr;
-using LedgerDebug = fuchsia::ledger::internal::LedgerDebug;
-using LedgerDebugPtr = fuchsia::ledger::internal::LedgerDebugPtr;
-using LedgerRepository = fuchsia::ledger::internal::LedgerRepository;
-using LedgerRepositoryPtr = fuchsia::ledger::internal::LedgerRepositoryPtr;
-using LedgerRepositoryDebug = fuchsia::ledger::internal::LedgerRepositoryDebug;
-using LedgerRepositoryDebugPtr =
- fuchsia::ledger::internal::LedgerRepositoryDebugPtr;
-using LedgerRepositoryFactory =
- fuchsia::ledger::internal::LedgerRepositoryFactory;
-using LedgerRepositoryFactoryPtr =
- fuchsia::ledger::internal::LedgerRepositoryFactoryPtr;
-using PageDebug = fuchsia::ledger::internal::PageDebug;
-using PageDebugPtr = fuchsia::ledger::internal::PageDebugPtr;
-} // namespace ledger_internal
-
-#endif // PERIDOT_BIN_LEDGER_FIDL_INCLUDE_TYPES_H_
diff --git a/bin/ledger/fidl/internal.fidl b/bin/ledger/fidl/internal.fidl
deleted file mode 100644
index 0135905..0000000
--- a/bin/ledger/fidl/internal.fidl
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.ledger.internal;
-
-using fuchsia.ledger;
-using fuchsia.ledger.cloud;
-
-// Entry interface implemented by the Ledger application, intended to be used by
-// the process setting up the user environment to obtain repositories for
-// individual users.
-[Discoverable]
-interface LedgerRepositoryFactory : fuchsia.ledger.ErrorNotifier {
- // Binds to the directory referenced by |repository|. If this is called
- // multiple times for the same directory, only the first instance of
- // |server_id| / |cloud_provider| will be used. Any subsequent ones will
- // simply be ignored.
- //
- // Parameters:
- // |repository_directory| channel pointing to the disk directory where the
- // repository is stored. At any given time, at most one repository
- // instance backed by the same disk directory can be running
- // concurrently.
- // TODO(qsr): Use typed channel when remoteio has been migrated to FIDL2.
- // |cloud_provider| is used by Ledger to synchronize data through the
- // cloud. If |cloud_provider| is disconnected, Ledger shuts down the
- // repository and disconnects all clients.
- // |user_id| is a unique, not device local, user identifier. It will be
- // used to enable Peer to Peer over NetConnector, and will be removed
- // once Ledger uses Overnet for Peer to Peer communication. If it is
- // empty, Ledger will not synchronize using Peer to Peer communication.
- 1: GetRepository(handle<channel> repository_directory,
- fuchsia.ledger.cloud.CloudProvider? cloud_provider,
- string user_id,
- request<LedgerRepository> repository);
-};
-
-// Controller interface for the Ledger application lifecycle.
-[Discoverable]
-interface LedgerController {
- // Terminate the ledger application.
- 1: Terminate();
-};
-
-interface LedgerRepository : fuchsia.ledger.ErrorNotifier {
- // Creates a new Ledger for the given |ledger_name| if it doesn't already
- // exist.
- 1: GetLedger(vector<uint8> ledger_name, request<fuchsia.ledger.Ledger> ledger);
-
- // Binds a new LedgerRepository handle to this repository.
- 2: Duplicate(request<LedgerRepository> ledger_repository);
-
- // Sets a watcher to track the synchronization state of a user's Ledger. The
- // current state is immediately sent to the watcher when this method is
- // called.
- 3: SetSyncStateWatcher(fuchsia.ledger.SyncWatcher watcher);
-
- // Returns the debugging interface for this LedgerRepository
- 4: GetLedgerRepositoryDebug(request<LedgerRepositoryDebug> ledgerRepositoryDebug);
-
- // Tries to clean up disk space on the device by removing unused data that are
- // already backed up in the cloud.
- 5: DiskCleanUp();
-};
diff --git a/bin/ledger/fidl_helpers/BUILD.gn b/bin/ledger/fidl_helpers/BUILD.gn
deleted file mode 100644
index 9c6570c..0000000
--- a/bin/ledger/fidl_helpers/BUILD.gn
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("fidl_helpers") {
- sources = [
- "bound_interface.h",
- "bound_interface_set.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/fidl_helpers/bound_interface.h b/bin/ledger/fidl_helpers/bound_interface.h
deleted file mode 100644
index 1e1d3a1..0000000
--- a/bin/ledger/fidl_helpers/bound_interface.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_FIDL_HELPERS_BOUND_INTERFACE_H_
-#define PERIDOT_BIN_LEDGER_FIDL_HELPERS_BOUND_INTERFACE_H_
-
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-namespace ledger {
-namespace fidl_helpers {
-template <class Interface, class Impl>
-class BoundInterface {
- public:
- template <class... Args>
- explicit BoundInterface(fidl::InterfaceRequest<Interface> request,
- Args&&... args)
- : impl_(std::forward<Args>(args)...),
- binding_(&impl_, std::move(request)) {}
-
- template <class... Args>
- explicit BoundInterface(Args&&... args)
- : impl_(std::forward<Args>(args)...), binding_(&impl_) {}
-
- void Bind(fidl::InterfaceRequest<Interface> request) {
- binding_.Bind(std::move(request));
- }
-
- void set_on_empty(fit::closure on_empty_callback) {
- binding_.set_error_handler(
- [this,
- on_empty_callback = std::move(on_empty_callback)](zx_status_t status) {
- binding_.Unbind();
- if (on_empty_callback)
- on_empty_callback();
- });
- }
-
- bool is_bound() { return binding_.is_bound(); }
-
- Impl* impl() { return &impl_; }
-
- private:
- Impl impl_;
- fidl::Binding<Interface> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BoundInterface);
-};
-} // namespace fidl_helpers
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_FIDL_HELPERS_BOUND_INTERFACE_H_
diff --git a/bin/ledger/fidl_helpers/bound_interface_set.h b/bin/ledger/fidl_helpers/bound_interface_set.h
deleted file mode 100644
index 38532e9..0000000
--- a/bin/ledger/fidl_helpers/bound_interface_set.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_FIDL_HELPERS_BOUND_INTERFACE_SET_H_
-#define PERIDOT_BIN_LEDGER_FIDL_HELPERS_BOUND_INTERFACE_SET_H_
-
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-namespace ledger {
-namespace fidl_helpers {
-template <class Interface, class Impl>
-class BoundInterfaceSet {
- public:
- template <class... Args>
- explicit BoundInterfaceSet(Args&&... args)
- : impl_(std::forward<Args>(args)...) {}
-
- void AddBinding(fidl::InterfaceRequest<Interface> request) {
- binding_.AddBinding(&impl_, std::move(request));
- }
-
- void CloseAll() { binding_.CloseAll(); }
-
- void set_on_empty(fit::closure on_empty) {
- binding_.set_empty_set_handler(std::move(on_empty));
- }
-
- bool is_bound() { return binding_.is_bound(); }
-
- size_t size() const { return binding_.size(); }
-
- private:
- Impl impl_;
- fidl::BindingSet<Interface> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BoundInterfaceSet);
-};
-} // namespace fidl_helpers
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_FIDL_HELPERS_BOUND_INTERFACE_SET_H_
diff --git a/bin/ledger/filesystem/BUILD.gn b/bin/ledger/filesystem/BUILD.gn
deleted file mode 100644
index 845beda..0000000
--- a/bin/ledger/filesystem/BUILD.gn
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("filesystem") {
- sources = [
- "detached_path.cc",
- "detached_path.h",
- "directory_reader.cc",
- "directory_reader.h",
- "get_directory_content_size.cc",
- "get_directory_content_size.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//zircon/public/lib/fit",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "detached_path_unittest.cc",
- "directory_reader_unittest.cc",
- "get_directory_content_size_unittest.cc",
- ]
-
- deps = [
- ":filesystem",
- "//garnet/public/lib/fxl",
- "//peridot/lib/scoped_tmpfs",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/filesystem/detached_path.cc b/bin/ledger/filesystem/detached_path.cc
deleted file mode 100644
index 5a5a595..0000000
--- a/bin/ledger/filesystem/detached_path.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-
-#include <lib/fxl/strings/concatenate.h>
-
-#include <utility>
-
-namespace ledger {
-
-DetachedPath::DetachedPath(int root_fd, std::string path)
- : root_fd_(root_fd), path_(std::move(path)) {}
-
-DetachedPath::DetachedPath(std::string path)
- : root_fd_(AT_FDCWD), path_(std::move(path)) {}
-
-DetachedPath::~DetachedPath() {}
-
-DetachedPath::DetachedPath(const DetachedPath& other) = default;
-
-DetachedPath::DetachedPath(DetachedPath&& other) noexcept = default;
-
-DetachedPath& DetachedPath::operator=(const DetachedPath& other) = default;
-
-DetachedPath& DetachedPath::operator=(DetachedPath&&) noexcept = default;
-
-DetachedPath DetachedPath::SubPath(fxl::StringView path) const {
- return DetachedPath(root_fd_, fxl::Concatenate({path_, "/", path}));
-}
-
-DetachedPath DetachedPath::SubPath(
- std::initializer_list<fxl::StringView> components) const {
- std::string end_path = path_;
- for (const auto& component : components) {
- end_path.push_back('/');
- end_path.append(component.data(), component.size());
- }
- return DetachedPath(root_fd_, std::move(end_path));
-}
-
-fxl::UniqueFD DetachedPath::OpenFD(DetachedPath* detatched_path) const {
- fxl::UniqueFD fd(
- openat(root_fd_, path_.c_str(), O_RDONLY | O_PATH | O_DIRECTORY));
- if (fd.is_valid()) {
- *detatched_path = ledger::DetachedPath(fd.get());
- }
- return fd;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/filesystem/detached_path.h b/bin/ledger/filesystem/detached_path.h
deleted file mode 100644
index 286e666..0000000
--- a/bin/ledger/filesystem/detached_path.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_FILESYSTEM_DETACHED_PATH_H_
-#define PERIDOT_BIN_LEDGER_FILESYSTEM_DETACHED_PATH_H_
-
-#include <fcntl.h>
-#include <string>
-
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/strings/string_view.h>
-
-namespace ledger {
-
-// Abstraction for a path rooted at a file descriptor.
-//
-// This class doesn't take ownership of the file descriptor and it is expected
-// that the file descriptor will outlive this class and any sub path created
-// from it.
-class DetachedPath {
- public:
- // If |path| is absolute, DetachedPath is equivalent to it. If |path| is
- // relative, it is resolved with |root_fd| as reference. See |openat(2)|.
- explicit DetachedPath(int root_fd = AT_FDCWD, std::string path = ".");
- // If |path| is absolute, DetachedPath is equivalent to it. If |path| is
- // relative, it is resolved relative to the current working directory.
- explicit DetachedPath(std::string path);
- ~DetachedPath();
- DetachedPath(const DetachedPath& other);
- DetachedPath(DetachedPath&& other) noexcept;
- DetachedPath& operator=(const DetachedPath& other);
- DetachedPath& operator=(DetachedPath&& /*unused*/) noexcept;
-
- // The file descriptor to the base directory of this path.
- int root_fd() const { return root_fd_; };
- // The relative path to |root_fd|.
- const std::string& path() const { return path_; };
-
- // A |DetachedPath| representing the |path| appended to the current path.
- DetachedPath SubPath(fxl::StringView path) const;
- // A |DetachedPath| representing all the |path| in |components| appended to
- // the current path.
- DetachedPath SubPath(std::initializer_list<fxl::StringView> components) const;
-
- // Opens a UniqueFD at the current path. If the operation fails, the returned
- // UniqueFd will be invalid.
- fxl::UniqueFD OpenFD(DetachedPath* detatched_path) const;
-
- private:
- int root_fd_;
- std::string path_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_FILESYSTEM_DETACHED_PATH_H_
diff --git a/bin/ledger/filesystem/detached_path_unittest.cc b/bin/ledger/filesystem/detached_path_unittest.cc
deleted file mode 100644
index 5507326..0000000
--- a/bin/ledger/filesystem/detached_path_unittest.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-
-#include <lib/fxl/files/directory.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-namespace {
-
-TEST(DetachedPathTest, Creation) {
- DetachedPath path1;
- EXPECT_EQ(AT_FDCWD, path1.root_fd());
- EXPECT_EQ(".", path1.path());
-
- DetachedPath path2(1);
- EXPECT_EQ(1, path2.root_fd());
- EXPECT_EQ(".", path2.path());
-
- DetachedPath path3(1, "foo");
- EXPECT_EQ(1, path3.root_fd());
- EXPECT_EQ("foo", path3.path());
-}
-
-TEST(DetachedPathTest, RelativeToDotSubPath) {
- DetachedPath path(1);
- DetachedPath subpath1 = path.SubPath("foo");
- EXPECT_EQ(1, subpath1.root_fd());
- EXPECT_EQ("./foo", subpath1.path());
- DetachedPath subpath2 = path.SubPath({"foo", "bar"});
- EXPECT_EQ(1, subpath2.root_fd());
- EXPECT_EQ("./foo/bar", subpath2.path());
-}
-
-TEST(DetachedPathTest, RelativeToDirSubPath) {
- DetachedPath path(1, "base");
- DetachedPath subpath1 = path.SubPath("foo");
- EXPECT_EQ(1, subpath1.root_fd());
- EXPECT_EQ("base/foo", subpath1.path());
- DetachedPath subpath2 = path.SubPath({"foo", "bar"});
- EXPECT_EQ(1, subpath2.root_fd());
- EXPECT_EQ("base/foo/bar", subpath2.path());
-}
-
-TEST(DetachedPathTest, AbsoluteSubPath) {
- DetachedPath path(1, "/base");
- DetachedPath subpath1 = path.SubPath("foo");
- EXPECT_EQ(1, subpath1.root_fd());
- EXPECT_EQ("/base/foo", subpath1.path());
- DetachedPath subpath2 = path.SubPath({"foo", "bar"});
- EXPECT_EQ(1, subpath2.root_fd());
- EXPECT_EQ("/base/foo/bar", subpath2.path());
-}
-
-TEST(DetatchedPathTest, OpenFD) {
- scoped_tmpfs::ScopedTmpFS tmpfs;
- DetachedPath path(tmpfs.root_fd(), "base");
- DetachedPath subpath = path.SubPath("foo");
- EXPECT_EQ(path.root_fd(), subpath.root_fd());
- EXPECT_EQ("base/foo", subpath.path());
-
- DetachedPath new_subpath;
- ASSERT_TRUE(files::CreateDirectoryAt(subpath.root_fd(), subpath.path()));
- fxl::UniqueFD fd = path.OpenFD(&new_subpath);
- EXPECT_TRUE(fd.is_valid());
- EXPECT_NE(subpath.root_fd(), new_subpath.root_fd());
- EXPECT_EQ(".", new_subpath.path());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/filesystem/directory_reader.cc b/bin/ledger/filesystem/directory_reader.cc
deleted file mode 100644
index 1397dca..0000000
--- a/bin/ledger/filesystem/directory_reader.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/filesystem/directory_reader.h"
-
-#include <dirent.h>
-#include <fcntl.h>
-#include <functional>
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/strings/string_view.h>
-
-namespace ledger {
-namespace {
-
-void SafeCloseDir(DIR* dir) {
- if (dir)
- closedir(dir);
-}
-
-} // namespace
-
-bool GetDirectoryEntries(const DetachedPath& directory,
- fit::function<bool(fxl::StringView)> callback) {
- int dir_fd = openat(directory.root_fd(), directory.path().c_str(), O_RDONLY);
- if (dir_fd == -1) {
- return false;
- }
- std::unique_ptr<DIR, decltype(&SafeCloseDir)> dir(fdopendir(dir_fd),
- SafeCloseDir);
- if (!dir)
- return false;
- for (struct dirent* entry = readdir(dir.get()); entry != nullptr;
- entry = readdir(dir.get())) {
- char* name = entry->d_name;
- if (name[0]) {
- if (name[0] == '.') {
- if (!name[1] || (name[1] == '.' && !name[2])) {
- // . or ..
- continue;
- }
- }
- if (!callback(fxl::StringView(name))) {
- break;
- }
- }
- }
- return true;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/filesystem/directory_reader.h b/bin/ledger/filesystem/directory_reader.h
deleted file mode 100644
index 795b470..0000000
--- a/bin/ledger/filesystem/directory_reader.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_FILESYSTEM_DIRECTORY_READER_H_
-#define PERIDOT_BIN_LEDGER_FILESYSTEM_DIRECTORY_READER_H_
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-
-namespace ledger {
-
-// Returns the list of directories and files inside the provided directory. The
-// callback will be called once for each directory and files and is guaranteed
-// to never be called again once this method returns. This method will returns
-// immediately if |callback| returns |false|. This method will returns |false|
-// if an error occured while reading the directory and |true| otherwise.
-bool GetDirectoryEntries(const DetachedPath& directory,
- fit::function<bool(fxl::StringView)> callback);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_FILESYSTEM_DIRECTORY_READER_H_
diff --git a/bin/ledger/filesystem/directory_reader_unittest.cc b/bin/ledger/filesystem/directory_reader_unittest.cc
deleted file mode 100644
index 26c291c..0000000
--- a/bin/ledger/filesystem/directory_reader_unittest.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/filesystem/directory_reader.h"
-
-#include <fcntl.h>
-#include <set>
-
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kFileContent = "file content";
-
-TEST(DirectoryReaderTest, GetDirectoryEntries) {
- scoped_tmpfs::ScopedTmpFS tmpfs;
-
- ASSERT_TRUE(files::CreateDirectoryAt(tmpfs.root_fd(), "foo"));
- ASSERT_TRUE(files::WriteFileAt(tmpfs.root_fd(), "bar", kFileContent.data(),
- kFileContent.size()));
- ASSERT_TRUE(files::WriteFileAt(tmpfs.root_fd(), "foo/baz",
- kFileContent.data(), kFileContent.size()));
-
- std::set<std::string> expected_entries = {"foo", "bar"};
-
- EXPECT_TRUE(GetDirectoryEntries(
- DetachedPath(tmpfs.root_fd()),
- [&expected_entries](fxl::StringView entry) {
- auto entry_iterator = expected_entries.find(entry.ToString());
- EXPECT_NE(entry_iterator, expected_entries.end());
- expected_entries.erase(entry_iterator);
- return true;
- }));
- EXPECT_EQ(expected_entries.size(), 0u);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/filesystem/get_directory_content_size.cc b/bin/ledger/filesystem/get_directory_content_size.cc
deleted file mode 100644
index 732f86f..0000000
--- a/bin/ledger/filesystem/get_directory_content_size.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/filesystem/get_directory_content_size.h"
-
-#include <queue>
-#include <string>
-
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/path.h>
-
-#include "peridot/bin/ledger/filesystem/directory_reader.h"
-
-namespace ledger {
-
-bool GetDirectoryContentSize(DetachedPath directory, uint64_t* size) {
- *size = 0;
- std::queue<DetachedPath> directories;
- directories.push(std::move(directory));
- while (!directories.empty()) {
- DetachedPath parent = std::move(directories.front());
- directories.pop();
- if (!GetDirectoryEntries(parent, [&parent, size,
- &directories](fxl::StringView child) {
- DetachedPath child_path = parent.SubPath(child);
- if (files::IsDirectoryAt(child_path.root_fd(), child_path.path())) {
- directories.push(child_path);
- } else {
- uint64_t file_size = 0;
- if (!files::GetFileSizeAt(child_path.root_fd(), child_path.path(),
- &file_size)) {
- FXL_LOG(ERROR)
- << "Couldn't get file size of " << child_path.path();
- return false;
- }
- *size += file_size;
- }
- return true;
- })) {
- FXL_LOG(ERROR) << "Couldn't retrieve contents of " << parent.path();
- return false;
- }
- }
- return true;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/filesystem/get_directory_content_size.h b/bin/ledger/filesystem/get_directory_content_size.h
deleted file mode 100644
index e15969f..0000000
--- a/bin/ledger/filesystem/get_directory_content_size.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_FILESYSTEM_GET_DIRECTORY_CONTENT_SIZE_H_
-#define PERIDOT_BIN_LEDGER_FILESYSTEM_GET_DIRECTORY_CONTENT_SIZE_H_
-
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-
-namespace ledger {
-
-// Recursively compute the full size of the directory. If a directory (top-level
-// |directory| or any of the nested ones) contents can't be retrieved or the
-// size of any of the non-directory entries can't be obtained, this will return
-// false and post an error in the log. Otherwise, |size| will contain the
-// accumulated size in bytes.
-bool GetDirectoryContentSize(DetachedPath directory, uint64_t* size);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_FILESYSTEM_GET_DIRECTORY_CONTENT_SIZE_H_
diff --git a/bin/ledger/filesystem/get_directory_content_size_unittest.cc b/bin/ledger/filesystem/get_directory_content_size_unittest.cc
deleted file mode 100644
index 2ad461f..0000000
--- a/bin/ledger/filesystem/get_directory_content_size_unittest.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/filesystem/get_directory_content_size.h"
-
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-namespace {
-
-const std::string kFileContent = "file content";
-
-TEST(GetDirectoryContentSizeTest, GetDirectoryContentSize) {
- scoped_tmpfs::ScopedTmpFS scoped_tmpfs;
- DetachedPath root(scoped_tmpfs.root_fd());
- DetachedPath foo = root.SubPath("foo");
- DetachedPath bar = root.SubPath("bar");
- DetachedPath foo_baz = foo.SubPath("baz");
-
- ASSERT_TRUE(files::CreateDirectoryAt(foo.root_fd(), foo.path()));
- ASSERT_TRUE(files::WriteFileAt(bar.root_fd(), bar.path(), kFileContent.data(),
- kFileContent.size()));
- ASSERT_TRUE(files::WriteFileAt(foo_baz.root_fd(), foo_baz.path(),
- kFileContent.data(), kFileContent.size()));
- uint64_t directory_size = 0;
- ASSERT_TRUE(GetDirectoryContentSize(root, &directory_size));
- ASSERT_EQ(directory_size, 2 * kFileContent.size());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/ledger_e2e_sync_credentials.ciphertext b/bin/ledger/ledger_e2e_sync_credentials.ciphertext
deleted file mode 100644
index 19df0aa..0000000
--- a/bin/ledger/ledger_e2e_sync_credentials.ciphertext
+++ /dev/null
Binary files differ
diff --git a/bin/ledger/lock/BUILD.gn b/bin/ledger/lock/BUILD.gn
deleted file mode 100644
index 7e2f9b6..0000000
--- a/bin/ledger/lock/BUILD.gn
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("lock") {
- sources = [
- "lock.cc",
- "lock.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/coroutine",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "lock_unittest.cc",
- ]
-
- deps = [
- ":lock",
- "//garnet/public/lib/fxl",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/lock/lock.cc b/bin/ledger/lock/lock.cc
deleted file mode 100644
index 60bd642..0000000
--- a/bin/ledger/lock/lock.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/lock/lock.h"
-
-#include <lib/callback/capture.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-namespace lock {
-namespace {
-class LockImpl : public Lock {
- public:
- LockImpl() : weak_ptr_factory_(this) {}
-
- ~LockImpl() override {
- if (serialization_callback_) {
- serialization_callback_();
- }
- }
-
- coroutine::ContinuationStatus Acquire(
- coroutine::CoroutineHandler* const handler,
- callback::OperationSerializer* const serializer) {
- return SyncCall(handler, [weak_this = weak_ptr_factory_.GetWeakPtr(),
- serializer](fit::function<void()> sync_callback) {
- serializer->Serialize<>(
- [] {},
- [weak_this, sync_callback = std::move(sync_callback)](
- fit::closure serialization_callback) mutable {
- // Moving sync_callback to the stack as the serialization_callback
- // might delete this closure.
- auto sync_callback_local = std::move(sync_callback);
- if (weak_this) {
- weak_this->serialization_callback_ =
- std::move(serialization_callback);
- } else {
- serialization_callback();
- }
- sync_callback_local();
- });
- });
- }
-
- private:
- fit::closure serialization_callback_;
-
- fxl::WeakPtrFactory<LockImpl> weak_ptr_factory_;
- FXL_DISALLOW_COPY_AND_ASSIGN(LockImpl);
-};
-} // namespace
-
-coroutine::ContinuationStatus AcquireLock(
- coroutine::CoroutineHandler* const handler,
- callback::OperationSerializer* const serializer,
- std::unique_ptr<Lock>* lock) {
- std::unique_ptr<LockImpl> impl = std::make_unique<LockImpl>();
- coroutine::ContinuationStatus status = impl->Acquire(handler, serializer);
- if (status == coroutine::ContinuationStatus::OK) {
- *lock = std::move(impl);
- }
- return status;
-}
-
-} // namespace lock
diff --git a/bin/ledger/lock/lock.h b/bin/ledger/lock/lock.h
deleted file mode 100644
index 68bbdca..0000000
--- a/bin/ledger/lock/lock.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_LOCK_LOCK_H_
-#define PERIDOT_BIN_LEDGER_LOCK_LOCK_H_
-
-#include <memory>
-
-#include <lib/callback/operation_serializer.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-
-namespace lock {
-// A lock. As long as this object lives, OperationSerializer blocks all other
-// operations.
-class Lock {
- public:
- virtual ~Lock() {}
-};
-
-// Creates and acquires a lock.
-// |handler| and |serializer| are inputs, |lock| is the output.
-// Returns OK if the lock is acquired (meaning the coroutine is now running as
-// a serialized operation of |serializer|), and INTERRUPTED if the coroutine
-// stack must be unwound immediately (see coroutine::SyncCall for this case).
-FXL_WARN_UNUSED_RESULT coroutine::ContinuationStatus AcquireLock(
- coroutine::CoroutineHandler* handler,
- callback::OperationSerializer* serializer, std::unique_ptr<Lock>* lock);
-
-} // namespace lock
-
-#endif // PERIDOT_BIN_LEDGER_LOCK_LOCK_H_
diff --git a/bin/ledger/lock/lock_unittest.cc b/bin/ledger/lock/lock_unittest.cc
deleted file mode 100644
index d0cd704..0000000
--- a/bin/ledger/lock/lock_unittest.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/lock/lock.h"
-
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-
-namespace lock {
-namespace {
-size_t Fact(size_t n) {
- if (n == 0) {
- return 1;
- }
- return Fact(n - 1) * n;
-}
-
-void UseStack() { EXPECT_EQ(120u, Fact(5)); }
-
-TEST(Lock, OneLock) {
- coroutine::CoroutineServiceImpl coroutine_service;
- callback::OperationSerializer serializer;
-
- fit::function<void(size_t)> callback;
- auto callable = [&callback](fit::function<void(size_t)> called_callback) {
- callback = std::move(called_callback);
- };
-
- size_t received_value = 0;
- size_t other_value = 0;
- coroutine_service.StartCoroutine([&serializer, callable, &received_value](
- coroutine::CoroutineHandler* handler) {
- std::unique_ptr<Lock> lock;
- EXPECT_EQ(coroutine::ContinuationStatus::OK,
- AcquireLock(handler, &serializer, &lock));
- UseStack();
- size_t value;
- EXPECT_EQ(coroutine::ContinuationStatus::OK,
- SyncCall(handler, callable, &value));
- UseStack();
- received_value = value;
- });
-
- EXPECT_TRUE(callback);
- EXPECT_EQ(0u, received_value);
- EXPECT_EQ(0u, other_value);
-
- serializer.Serialize<>([&other_value] { other_value = 1u; },
- [](fit::closure closure) { closure(); });
-
- EXPECT_EQ(0u, other_value);
- callback(1);
-
- EXPECT_EQ(1u, received_value);
- EXPECT_EQ(1u, other_value);
-}
-
-TEST(Lock, ManyLocks) {
- constexpr size_t nb_routines = 10;
- coroutine::CoroutineServiceImpl coroutine_service;
- callback::OperationSerializer serializer;
-
- std::queue<fit::function<void(size_t)>> callbacks;
-
- std::vector<size_t> received_values;
- for (size_t i = 0; i < nb_routines; i++) {
- auto callable = [&callbacks](fit::function<void(size_t)> called_callback) {
- callbacks.push(std::move(called_callback));
- };
- coroutine_service.StartCoroutine([&serializer, callable, &received_values](
- coroutine::CoroutineHandler* handler) {
- std::unique_ptr<Lock> lock;
- EXPECT_EQ(coroutine::ContinuationStatus::OK,
- AcquireLock(handler, &serializer, &lock));
- UseStack();
- size_t value;
- EXPECT_EQ(coroutine::ContinuationStatus::OK,
- SyncCall(handler, callable, &value));
- UseStack();
- received_values.push_back(value);
- });
- }
-
- for (size_t i = 0; i < nb_routines; i++) {
- EXPECT_EQ(1u, callbacks.size());
- EXPECT_EQ(i, received_values.size());
- callbacks.front()(i);
- callbacks.pop();
- EXPECT_EQ(i, *received_values.rbegin());
- }
- EXPECT_EQ(nb_routines, received_values.size());
-}
-
-TEST(Lock, Interrupted) {
- callback::OperationSerializer serializer;
- coroutine::CoroutineHandler* handler_ptr = nullptr;
-
- fit::function<void()> callback;
- auto callable = [&callback](fit::function<void()> called_callback) {
- callback = std::move(called_callback);
- };
-
- serializer.Serialize<>([] {}, callable);
-
- bool executed = false;
- {
- coroutine::CoroutineServiceImpl coroutine_service;
- coroutine_service.StartCoroutine([&serializer, &executed, &handler_ptr](
- coroutine::CoroutineHandler* handler) {
- handler_ptr = handler;
- std::unique_ptr<Lock> lock;
- // We are interrupted.
- EXPECT_EQ(coroutine::ContinuationStatus::INTERRUPTED,
- AcquireLock(handler, &serializer, &lock));
- executed = true;
- return;
- });
-
- EXPECT_TRUE(callback);
- EXPECT_FALSE(executed);
- }
-
- EXPECT_TRUE(executed);
-
- callback();
-
- callback = nullptr;
-
- serializer.Serialize<>([] {}, callable);
- EXPECT_TRUE(callback);
-}
-
-} // namespace
-} // namespace lock
diff --git a/bin/ledger/meta/ledger.cmx b/bin/ledger/meta/ledger.cmx
deleted file mode 100644
index b20ae2f..0000000
--- a/bin/ledger/meta/ledger.cmx
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.netconnector.NetConnector",
- "fuchsia.net.LegacySocketProvider",
- "fuchsia.net.SocketProvider",
- "fuchsia.tracelink.Registry",
- "fuchsia.cobalt.LoggerFactory"
- ]
- }
-}
diff --git a/bin/ledger/p2p_provider/impl/BUILD.gn b/bin/ledger/p2p_provider/impl/BUILD.gn
deleted file mode 100644
index 13268d4..0000000
--- a/bin/ledger/p2p_provider/impl/BUILD.gn
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("impl") {
- sources = [
- "p2p_provider_impl.cc",
- "p2p_provider_impl.h",
- "remote_connection.cc",
- "remote_connection.h",
- "static_user_id_provider.cc",
- "static_user_id_provider.h",
- ]
-
- public_deps = [
- "//garnet/public/fidl/fuchsia.netconnector",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/netconnector/cpp",
- "//peridot/bin/ledger/filesystem",
- "//peridot/bin/ledger/p2p_provider/public",
- "//peridot/lib/convert",
- ]
-
- deps = [
- ":envelope",
- "//garnet/public/lib/backoff",
- "//garnet/public/lib/callback",
- "//peridot/bin/ledger/environment",
- "//peridot/lib/convert",
- "//peridot/lib/firebase_auth",
- "//peridot/public/fidl/fuchsia.modular.auth",
- ]
-}
-
-flatbuffer("envelope") {
- sources = [
- "envelope.fbs",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "p2p_provider_impl_unittest.cc",
- ]
-
- deps = [
- ":impl",
- "//garnet/public/lib/backoff/testing",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/bin/ledger/testing/netconnector",
-
- # gtest matchers are in gmock.
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/p2p_provider/impl/envelope.fbs b/bin/ledger/p2p_provider/impl/envelope.fbs
deleted file mode 100644
index 548ab2a..0000000
--- a/bin/ledger/p2p_provider/impl/envelope.fbs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-namespace p2p_provider;
-
-// Handshake. Gives the host_name of the device. Will be the first message
-// once a connection is established.
-table Handshake {
- version: ushort;
- host_name: [ubyte];
-}
-
-table Message {
- data: [ubyte];
-}
-
-union EnvelopeMessage {
- Handshake,
- Message,
-}
-
-// Envelope is the type of messages sent between devices. It contains either a
-// handshake, internal to the P2P provider, or a payload from the
-// synchronization layer.
-table Envelope {
- message: EnvelopeMessage;
-}
-
-root_type Envelope;
diff --git a/bin/ledger/p2p_provider/impl/p2p_provider_impl.cc b/bin/ledger/p2p_provider/impl/p2p_provider_impl.cc
deleted file mode 100644
index f710fd4..0000000
--- a/bin/ledger/p2p_provider/impl/p2p_provider_impl.cc
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_provider/impl/p2p_provider_impl.h"
-
-#include <algorithm>
-#include <iterator>
-
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/p2p_provider/impl/envelope_generated.h"
-
-namespace p2p_provider {
-namespace {
-constexpr char kRespondingServiceName[] = "ledger-p2p-";
-const uint16_t kCurrentVersion = 0;
-
-bool ValidateHandshake(const Envelope* envelope, const Handshake** message) {
- if (envelope->message_type() != EnvelopeMessage_Handshake) {
- FXL_LOG(ERROR) << "Incorrect message type: " << envelope->message_type();
- return false;
- }
- *message = static_cast<const Handshake*>(envelope->message());
- if ((*message)->version() != kCurrentVersion) {
- FXL_LOG(ERROR) << "Incorrect message version: " << (*message)->version();
- return false;
- }
- return true;
-}
-
-} // namespace
-
-P2PProviderImpl::P2PProviderImpl(
- std::string host_name, fuchsia::netconnector::NetConnectorPtr net_connector,
- std::unique_ptr<p2p_provider::UserIdProvider> user_id_provider)
- : host_name_(std::move(host_name)),
- net_connector_(std::move(net_connector)),
- user_id_provider_(std::move(user_id_provider)) {}
-
-P2PProviderImpl::~P2PProviderImpl() {}
-
-void P2PProviderImpl::Start(Client* client) {
- FXL_DCHECK(!client_);
- FXL_DCHECK(client);
- client_ = client;
- user_id_provider_->GetUserId(
- [this](UserIdProvider::Status status, std::string user_id) {
- if (status != UserIdProvider::Status::OK) {
- FXL_LOG(ERROR) << "Unable to retrieve the user ID necessary to start "
- "the peer-to-peer provider.";
- return;
- }
- user_id_ = user_id;
- StartService();
- });
-}
-
-bool P2PProviderImpl::SendMessage(fxl::StringView destination,
- fxl::StringView data) {
- flatbuffers::FlatBufferBuilder buffer;
- flatbuffers::Offset<Message> message =
- CreateMessage(buffer, convert::ToFlatBufferVector(&buffer, data));
- flatbuffers::Offset<Envelope> envelope =
- CreateEnvelope(buffer, EnvelopeMessage_Message, message.Union());
- buffer.Finish(envelope);
-
- char* buf = reinterpret_cast<char*>(buffer.GetBufferPointer());
- size_t size = buffer.GetSize();
- auto it = connection_map_.find(destination);
- if (it == connection_map_.end()) {
- return false;
- }
- it->second->SendMessage(fxl::StringView(buf, size));
- return true;
-}
-
-void P2PProviderImpl::StartService() {
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> handle;
- // When the service provider is reset and its connection cut, NetConnector
- // stops responding for its services.
- network_service_provider_.AddBinding(handle.NewRequest());
- network_service_provider_.AddServiceForName(
- [this](zx::channel channel) {
- RemoteConnection& connection = connections_.emplace(host_name_);
- connection.set_on_message(
- [this, &connection](std::vector<uint8_t> data) {
- ProcessHandshake(&connection, std::move(data), true,
- fxl::StringView());
- });
- connection.Start(std::move(channel));
- },
- kRespondingServiceName + user_id_);
- net_connector_->RegisterServiceProvider(kRespondingServiceName + user_id_,
- std::move(handle));
-
- ListenForNewDevices(fuchsia::netconnector::kInitialKnownDeviceNames);
-}
-
-void P2PProviderImpl::ProcessHandshake(RemoteConnection* connection,
- std::vector<uint8_t> data,
- bool should_send_handshake,
- fxl::StringView network_remote_name) {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(data.data()), data.size());
- if (!VerifyEnvelopeBuffer(verifier)) {
- // Wrong serialization, abort.
- FXL_LOG(ERROR) << "The message received is malformed.";
- connection->Disconnect();
- return;
- };
- const Envelope* envelope = GetEnvelope(data.data());
- const Handshake* message;
- if (!ValidateHandshake(envelope, &message)) {
- FXL_LOG(ERROR) << "The message received is not valid.";
- connection->Disconnect();
- return;
- }
-
- std::string remote_name(message->host_name()->begin(),
- message->host_name()->end());
- if (!network_remote_name.empty() && network_remote_name != remote_name) {
- // The name of the remote device as given by the network is different from
- // the self-declared name. Something is wrong here, let's abort.
- FXL_LOG(ERROR) << "Network name " << network_remote_name
- << " different from declared name " << remote_name
- << ", aborting.";
- connection->Disconnect();
- return;
- }
- bool existed_before = false;
- auto it = connection_map_.find(remote_name);
- if (it != connection_map_.end()) {
- if (remote_name < host_name_) {
- it->second->Disconnect();
- existed_before = true;
- } else {
- connection->Disconnect();
- return;
- }
- }
-
- connection_map_[remote_name] = connection;
-
- connection->set_on_close([this, remote_name]() {
- connection_map_.erase(remote_name);
- OnDeviceChange(remote_name, DeviceChangeType::DELETED);
- });
-
- connection->set_on_message([this, remote_name](std::vector<uint8_t> data) {
- Dispatch(remote_name, std::move(data));
- });
-
- if (should_send_handshake) {
- // We send an handshake to signal to the other side the connection is
- // indeed established.
- flatbuffers::FlatBufferBuilder buffer;
- flatbuffers::Offset<Handshake> request =
- CreateHandshake(buffer, kCurrentVersion,
- convert::ToFlatBufferVector(&buffer, host_name_));
- flatbuffers::Offset<Envelope> envelope =
- CreateEnvelope(buffer, EnvelopeMessage_Handshake, request.Union());
- buffer.Finish(envelope);
- char* buf = reinterpret_cast<char*>(buffer.GetBufferPointer());
- size_t size = buffer.GetSize();
- connection->SendMessage(fxl::StringView(buf, size));
- }
-
- if (!existed_before) {
- // If the connection existed before, we don't need to notify again.
- OnDeviceChange(remote_name, DeviceChangeType::NEW);
- }
-}
-
-void P2PProviderImpl::ListenForNewDevices(uint64_t version) {
- net_connector_->GetKnownDeviceNames(
- version,
- [this](uint64_t new_version, std::vector<std::string> devices) {
- std::vector<std::string> seen_devices;
- for (auto& remote_name : devices) {
- seen_devices.push_back(remote_name);
- if (contacted_hosts_.find(remote_name) != contacted_hosts_.end()) {
- continue;
- }
- if (remote_name == host_name_) {
- continue;
- }
- std::string remote_name_str(remote_name);
-
- zx::channel local;
- zx::channel remote;
- zx_status_t status = zx::channel::create(0u, &local, &remote);
-
- FXL_CHECK(status == ZX_OK)
- << "zx::channel::create failed, status " << status;
-
- fuchsia::sys::ServiceProviderPtr device_service_provider;
- net_connector_->GetDeviceServiceProvider(
- remote_name, device_service_provider.NewRequest());
-
- device_service_provider->ConnectToService(
- kRespondingServiceName + user_id_, std::move(remote));
-
- flatbuffers::FlatBufferBuilder buffer;
- flatbuffers::Offset<Handshake> request =
- CreateHandshake(buffer, kCurrentVersion,
- convert::ToFlatBufferVector(&buffer, host_name_));
- flatbuffers::Offset<Envelope> envelope = CreateEnvelope(
- buffer, EnvelopeMessage_Handshake, request.Union());
- buffer.Finish(envelope);
-
- RemoteConnection& connection = connections_.emplace(host_name_);
- connection.set_on_message(
- [this, &connection, remote_name_str](std::vector<uint8_t> data) {
- ProcessHandshake(&connection, std::move(data), false,
- remote_name_str);
- });
- connection.Start(std::move(local));
-
- char* buf = reinterpret_cast<char*>(buffer.GetBufferPointer());
- size_t size = buffer.GetSize();
- connection.SendMessage(fxl::StringView(buf, size));
- contacted_hosts_.insert(std::move(remote_name_str));
- }
- // Devices that disappeared can be recontacted again later as they might
- // have changed.
- std::vector<fxl::StringView> to_be_removed;
- std::set_difference(contacted_hosts_.begin(), contacted_hosts_.end(),
- seen_devices.begin(), seen_devices.end(),
- std::back_inserter(to_be_removed));
- for (const fxl::StringView& host : to_be_removed) {
- contacted_hosts_.erase(contacted_hosts_.find(host));
- }
- ListenForNewDevices(new_version);
- });
-}
-
-void P2PProviderImpl::Dispatch(fxl::StringView source,
- std::vector<uint8_t> data) {
- FXL_DCHECK(client_);
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(data.data()), data.size());
- if (!VerifyEnvelopeBuffer(verifier)) {
- // Wrong serialization, abort.
- FXL_LOG(ERROR) << "The message received is malformed.";
- return;
- };
- const Envelope* envelope = GetEnvelope(data.data());
- if (envelope->message_type() != EnvelopeMessage_Message) {
- FXL_LOG(ERROR) << "The message received is unexpected at this point.";
- return;
- }
-
- const Message* message = static_cast<const Message*>(envelope->message());
-
- fxl::StringView data_view(
- reinterpret_cast<const char*>(message->data()->data()),
- message->data()->size());
- client_->OnNewMessage(source, data_view);
-}
-
-void P2PProviderImpl::OnDeviceChange(fxl::StringView remote_device,
- DeviceChangeType change_type) {
- FXL_DCHECK(client_);
- client_->OnDeviceChange(remote_device, change_type);
-}
-
-} // namespace p2p_provider
diff --git a/bin/ledger/p2p_provider/impl/p2p_provider_impl.h b/bin/ledger/p2p_provider/impl/p2p_provider_impl.h
deleted file mode 100644
index fe88966..0000000
--- a/bin/ledger/p2p_provider/impl/p2p_provider_impl.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_P2P_PROVIDER_IMPL_H_
-#define PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_P2P_PROVIDER_IMPL_H_
-
-#include <memory>
-#include <set>
-#include <string>
-
-#include <fuchsia/netconnector/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/netconnector/cpp/message_relay.h>
-
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/p2p_provider/impl/remote_connection.h"
-#include "peridot/bin/ledger/p2p_provider/public/p2p_provider.h"
-#include "peridot/bin/ledger/p2p_provider/public/user_id_provider.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace p2p_provider {
-// P2PProviderImpl provides the peer-to-peer communication abstraction for the
-// Ledger, using NetConnector.
-//
-// We deploy a number of strategies to provide a consistent communication layer
-// using NetConnector:
-// - NetConnector exposes services to other devices, and allows one to connect
-// to other devices services. We thus expose a service whose name is
-// ledger-specific, and also depends on the user id. This ensures only Ledgers
-// of the same user communicate.
-// - Netconnector does not provide the connected service with the identity of
-// the device that connects to it. For this, the connecting device sends an
-// handshake as its first message to ascertain its identity.
-// - NetConnector does not allow enumeration of services on remote devices, and
-// there is no built-in connection confirmation: when we connect, we are not
-// sure whether the remote device has the service we want. Thus, the connected
-// device also sends an handshake to confirm the connection.
-class P2PProviderImpl : public P2PProvider {
- public:
- P2PProviderImpl(
- std::string host_name,
- fuchsia::netconnector::NetConnectorPtr net_connector,
- std::unique_ptr<p2p_provider::UserIdProvider> user_id_provider);
- ~P2PProviderImpl() override;
-
- // P2PProvider:
- void Start(Client* client) override;
- bool SendMessage(fxl::StringView destination, fxl::StringView data) override;
-
- private:
- // Starts the listening mDNS service.
- void StartService();
- // Processes the first message on a new connection. If
- // |should_send_handshake|, a handshake is also sent back on the connection;
- // this happens when the connection was established by the other side.
- void ProcessHandshake(RemoteConnection* connection, std::vector<uint8_t> data,
- bool should_send_handshake,
- fxl::StringView network_remote_name);
- // Retrieves and processes the current devices list
- void ListenForNewDevices(uint64_t version);
- // Dispatches an incoming message to the relevant page, or sends an error
- // back.
- void Dispatch(fxl::StringView source, std::vector<uint8_t> data);
- // Callback when we establish a new device connection, or a device breaks its
- // connection.
- void OnDeviceChange(fxl::StringView remote_device,
- DeviceChangeType change_type);
-
- Client* client_ = nullptr;
-
- // ID of a user, used to ensure all connected Ledgers are for the same user.
- std::string user_id_;
- // |connection_map_| holds the connections, keyed by the remote host name.
- std::map<std::string, RemoteConnection*, convert::StringViewComparator>
- connection_map_;
- // |connections_| holds the set of all established peer-to-peer connections.
- // We need both |connections_| and |connection_map_| as inbound connections
- // don't have an assiociated host name until we receive the handshake.
- callback::AutoCleanableSet<RemoteConnection> connections_;
- // |contacted_hosts_| lists all the hosts we tried to contact so far that
- // remain visible to us. This is useful as, when we open a connection to a
- // device, we don't know if it holds a ledger for the user we want; this set
- // allows us to not end up in an infinite loop of: new device->connect->no
- // ledger for our user->disconnect->new device!->...
- // Once a device become invisible (disconnected from the local network, shut
- // down, ...), we remove it from this set.
- std::set<std::string, convert::StringViewComparator> contacted_hosts_;
-
- component::ServiceProviderImpl network_service_provider_;
- std::string const host_name_;
- fuchsia::netconnector::NetConnectorPtr const net_connector_;
- std::unique_ptr<p2p_provider::UserIdProvider> const user_id_provider_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(P2PProviderImpl);
-};
-
-} // namespace p2p_provider
-
-#endif // PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_P2P_PROVIDER_IMPL_H_
diff --git a/bin/ledger/p2p_provider/impl/p2p_provider_impl_unittest.cc b/bin/ledger/p2p_provider/impl/p2p_provider_impl_unittest.cc
deleted file mode 100644
index 9ede9b2..0000000
--- a/bin/ledger/p2p_provider/impl/p2p_provider_impl_unittest.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_provider/impl/p2p_provider_impl.h"
-
-#include <algorithm>
-#include <ostream>
-#include <string>
-
-#include <lib/fit/function.h>
-
-// gtest matchers are in gmock.
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/p2p_provider/impl/static_user_id_provider.h"
-#include "peridot/bin/ledger/p2p_provider/public/user_id_provider.h"
-#include "peridot/bin/ledger/testing/netconnector/netconnector_factory.h"
-
-namespace p2p_provider {
-namespace {
-
-class RecordingClient : public P2PProvider::Client {
- public:
- struct DeviceChange {
- std::string device;
- DeviceChangeType change;
-
- bool operator==(const DeviceChange& b) const {
- return device == b.device && change == b.change;
- }
- };
-
- struct Message {
- std::string source;
- std::string data;
-
- bool operator==(const Message& b) const {
- return source == b.source && data == b.data;
- }
- };
-
- void OnDeviceChange(fxl::StringView device_name,
- DeviceChangeType change_type) override {
- device_changes.push_back(DeviceChange{device_name.ToString(), change_type});
- }
-
- void OnNewMessage(fxl::StringView device_name,
- fxl::StringView message) override {
- messages.push_back(Message{device_name.ToString(), message.ToString()});
- }
- std::vector<DeviceChange> device_changes;
- std::vector<Message> messages;
-};
-
-std::ostream& operator<<(std::ostream& os,
- const RecordingClient::DeviceChange& d) {
- return os << "DeviceChange{" << d.device << ", " << bool(d.change) << "}";
-}
-
-std::ostream& operator<<(std::ostream& os, const RecordingClient::Message& m) {
- return os << "Message{" << m.source << ", " << m.data << "}";
-}
-
-class P2PProviderImplTest : public gtest::TestLoopFixture {
- public:
- P2PProviderImplTest() {}
- ~P2PProviderImplTest() override {}
-
- std::unique_ptr<P2PProvider> GetProvider(std::string host_name,
- std::string user_name = "user") {
- fuchsia::netconnector::NetConnectorPtr netconnector;
- net_connector_factory_.AddBinding(host_name, netconnector.NewRequest());
- return std::make_unique<p2p_provider::P2PProviderImpl>(
- std::move(host_name), std::move(netconnector),
- std::make_unique<StaticUserIdProvider>(std::move(user_name)));
- }
-
- protected:
- void SetUp() override { ::testing::Test::SetUp(); }
-
- ledger::NetConnectorFactory net_connector_factory_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(P2PProviderImplTest);
-};
-
-TEST_F(P2PProviderImplTest, ThreeHosts_SameUser) {
- std::unique_ptr<P2PProvider> provider1 = GetProvider("host1");
- RecordingClient client1;
- provider1->Start(&client1);
- RunLoopUntilIdle();
- EXPECT_TRUE(client1.device_changes.empty());
-
- std::unique_ptr<P2PProvider> provider2 = GetProvider("host2");
- RecordingClient client2;
- provider2->Start(&client2);
- RunLoopUntilIdle();
-
- EXPECT_THAT(client1.device_changes,
- testing::UnorderedElementsAre(RecordingClient::DeviceChange{
- "host2", DeviceChangeType::NEW}));
- EXPECT_THAT(client2.device_changes,
- testing::UnorderedElementsAre(RecordingClient::DeviceChange{
- "host1", DeviceChangeType::NEW}));
-
- std::unique_ptr<P2PProvider> provider3 = GetProvider("host3");
- RecordingClient client3;
- provider3->Start(&client3);
- RunLoopUntilIdle();
-
- EXPECT_THAT(
- client1.device_changes,
- testing::ElementsAre(
- RecordingClient::DeviceChange{"host2", DeviceChangeType::NEW},
- RecordingClient::DeviceChange{"host3", DeviceChangeType::NEW}));
-
- EXPECT_THAT(
- client2.device_changes,
- testing::ElementsAre(
- RecordingClient::DeviceChange{"host1", DeviceChangeType::NEW},
- RecordingClient::DeviceChange{"host3", DeviceChangeType::NEW}));
-
- EXPECT_THAT(
- client3.device_changes,
- testing::UnorderedElementsAre(
- RecordingClient::DeviceChange{"host1", DeviceChangeType::NEW},
- RecordingClient::DeviceChange{"host2", DeviceChangeType::NEW}));
-
- // Disconnect one host, and verify disconnection notices are sent.
- provider2.reset();
- RunLoopUntilIdle();
-
- EXPECT_THAT(
- client1.device_changes,
- testing::ElementsAre(
- RecordingClient::DeviceChange{"host2", DeviceChangeType::NEW},
- RecordingClient::DeviceChange{"host3", DeviceChangeType::NEW},
- RecordingClient::DeviceChange{"host2", DeviceChangeType::DELETED}));
-
- EXPECT_THAT(
- client3.device_changes,
- testing::UnorderedElementsAre(
- RecordingClient::DeviceChange{"host1", DeviceChangeType::NEW},
- RecordingClient::DeviceChange{"host2", DeviceChangeType::NEW},
- RecordingClient::DeviceChange{"host2", DeviceChangeType::DELETED}));
-}
-
-TEST_F(P2PProviderImplTest, FourHosts_TwoUsers) {
- std::unique_ptr<P2PProvider> provider1 = GetProvider("host1", "user1");
- RecordingClient client1;
- provider1->Start(&client1);
- std::unique_ptr<P2PProvider> provider2 = GetProvider("host2", "user2");
- RecordingClient client2;
- provider2->Start(&client2);
- std::unique_ptr<P2PProvider> provider3 = GetProvider("host3", "user2");
- RecordingClient client3;
- provider3->Start(&client3);
- std::unique_ptr<P2PProvider> provider4 = GetProvider("host4", "user1");
- RecordingClient client4;
- provider4->Start(&client4);
- RunLoopUntilIdle();
-
- // Verify that only devices with the same user connect together.
- EXPECT_THAT(client1.device_changes,
- testing::ElementsAre(RecordingClient::DeviceChange{
- "host4", DeviceChangeType::NEW}));
- EXPECT_THAT(client2.device_changes,
- testing::ElementsAre(RecordingClient::DeviceChange{
- "host3", DeviceChangeType::NEW}));
- EXPECT_THAT(client3.device_changes,
- testing::ElementsAre(RecordingClient::DeviceChange{
- "host2", DeviceChangeType::NEW}));
- EXPECT_THAT(client4.device_changes,
- testing::ElementsAre(RecordingClient::DeviceChange{
- "host1", DeviceChangeType::NEW}));
-
- provider4.reset();
- RunLoopUntilIdle();
-
- EXPECT_THAT(
- client1.device_changes,
- testing::ElementsAre(
- RecordingClient::DeviceChange{"host4", DeviceChangeType::NEW},
- RecordingClient::DeviceChange{"host4", DeviceChangeType::DELETED}));
- EXPECT_THAT(client2.device_changes,
- testing::ElementsAre(RecordingClient::DeviceChange{
- "host3", DeviceChangeType::NEW}));
- EXPECT_THAT(client3.device_changes,
- testing::ElementsAre(RecordingClient::DeviceChange{
- "host2", DeviceChangeType::NEW}));
-}
-
-TEST_F(P2PProviderImplTest, TwoHosts_Messages) {
- std::unique_ptr<P2PProvider> provider1 = GetProvider("host1");
- RecordingClient client1;
- provider1->Start(&client1);
- std::unique_ptr<P2PProvider> provider2 = GetProvider("host2");
- RecordingClient client2;
- provider2->Start(&client2);
-
- RunLoopUntilIdle();
-
- EXPECT_TRUE(provider1->SendMessage("host2", "datagram"));
- RunLoopUntilIdle();
-
- EXPECT_THAT(client1.messages, testing::ElementsAre());
- EXPECT_THAT(client2.messages, testing::ElementsAre(RecordingClient::Message{
- "host1", "datagram"}));
-}
-} // namespace
-} // namespace p2p_provider
diff --git a/bin/ledger/p2p_provider/impl/remote_connection.cc b/bin/ledger/p2p_provider/impl/remote_connection.cc
deleted file mode 100644
index c612640..0000000
--- a/bin/ledger/p2p_provider/impl/remote_connection.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_provider/impl/remote_connection.h"
-
-#include <flatbuffers/flatbuffers.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/p2p_provider/impl/envelope_generated.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace p2p_provider {
-RemoteConnection::RemoteConnection(std::string local_name)
- : local_name_(std::move(local_name)) {
- message_relay_.SetChannelClosedCallback([this] { OnChannelClosed(); });
- message_relay_.SetMessageReceivedCallback(
- [this](std::vector<uint8_t> data) { OnNewMessage(std::move(data)); });
-}
-
-void RemoteConnection::Start(zx::channel channel) {
- FXL_DCHECK(!started_);
- started_ = true;
- message_relay_.SetChannel(std::move(channel));
-}
-
-void RemoteConnection::SendMessage(fxl::StringView data) {
- message_relay_.SendMessage(std::vector<uint8_t>(data.begin(), data.end()));
-}
-
-void RemoteConnection::Disconnect() {
- FXL_DCHECK(started_);
- message_relay_.SetChannelClosedCallback(nullptr);
- message_relay_.CloseChannel();
-
- if (on_empty_) {
- on_empty_();
- }
-}
-
-void RemoteConnection::set_on_empty(fit::closure on_empty) {
- on_empty_ = std::move(on_empty);
-}
-
-void RemoteConnection::set_on_close(fit::closure on_close) {
- on_close_ = std::move(on_close);
-}
-
-void RemoteConnection::set_on_message(
- fit::function<void(std::vector<uint8_t>)> on_message) {
- on_message_ = std::move(on_message);
-}
-
-void RemoteConnection::OnChannelClosed() {
- if (on_close_) {
- on_close_();
- }
- if (on_empty_) {
- auto on_empty = std::move(on_empty_);
- on_empty();
- }
-}
-
-void RemoteConnection::OnNewMessage(std::vector<uint8_t> data) {
- FXL_DCHECK(on_message_)
- << "No message handler has been set. We would be dropping messages.";
-
- if (on_message_) {
- on_message_(std::move(data));
- }
-}
-
-} // namespace p2p_provider
diff --git a/bin/ledger/p2p_provider/impl/remote_connection.h b/bin/ledger/p2p_provider/impl/remote_connection.h
deleted file mode 100644
index d33c59b..0000000
--- a/bin/ledger/p2p_provider/impl/remote_connection.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_REMOTE_CONNECTION_H_
-#define PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_REMOTE_CONNECTION_H_
-
-#include <string>
-
-#include <flatbuffers/flatbuffers.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/netconnector/cpp/message_relay.h>
-#include <lib/zx/channel.h>
-
-namespace p2p_provider {
-// RemoteConnection holds a connection with a single remote device.
-class RemoteConnection {
- public:
- explicit RemoteConnection(std::string local_name);
-
- // Starts listening on the provided channel for new messages.
- // |channel| is presumed to be sending/receiving messages from/to another
- // device.
- void Start(zx::channel channel);
-
- // Sends |data| to another device through the channel set in |Start|.
- void SendMessage(fxl::StringView data);
-
- // Disconnects.
- void Disconnect();
-
- // |on_empty| will be called when this connection is no longer valid, either
- // because we disconnected or because the other side disconnected.
- void set_on_empty(fit::closure on_empty);
-
- // |on_close| will be called when the other side closes the connection.
- void set_on_close(fit::closure on_close);
-
- // |on_message| will be called for every new message received.
- void set_on_message(fit::function<void(std::vector<uint8_t>)> on_message);
-
- private:
- void OnChannelClosed();
- void OnNewMessage(std::vector<uint8_t> data);
-
- bool started_ = false;
-
- const std::string local_name_;
- netconnector::MessageRelay message_relay_;
-
- fit::closure on_empty_;
- fit::closure on_close_;
- fit::function<void(std::vector<uint8_t>)> on_message_;
-};
-
-} // namespace p2p_provider
-
-#endif // PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_REMOTE_CONNECTION_H_
diff --git a/bin/ledger/p2p_provider/impl/static_user_id_provider.cc b/bin/ledger/p2p_provider/impl/static_user_id_provider.cc
deleted file mode 100644
index b0a2ee1..0000000
--- a/bin/ledger/p2p_provider/impl/static_user_id_provider.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_provider/impl/static_user_id_provider.h"
-
-namespace p2p_provider {
-
-StaticUserIdProvider::StaticUserIdProvider(std::string user_id)
- : user_id_(user_id) {}
-
-StaticUserIdProvider::~StaticUserIdProvider() = default;
-
-void StaticUserIdProvider::GetUserId(
- fit::function<void(Status, std::string)> callback) {
- callback(Status::OK, user_id_);
-}
-
-} // namespace p2p_provider
diff --git a/bin/ledger/p2p_provider/impl/static_user_id_provider.h b/bin/ledger/p2p_provider/impl/static_user_id_provider.h
deleted file mode 100644
index f3a575e..0000000
--- a/bin/ledger/p2p_provider/impl/static_user_id_provider.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_STATIC_USER_ID_PROVIDER_H_
-#define PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_STATIC_USER_ID_PROVIDER_H_
-
-#include <string>
-
-#include "peridot/bin/ledger/p2p_provider/public/user_id_provider.h"
-
-namespace p2p_provider {
-
-// Implementation of |UserIdProvider| that always returns a static value, passed
-// in the constructor.
-class StaticUserIdProvider : public UserIdProvider {
- public:
- StaticUserIdProvider(std::string user_id);
- ~StaticUserIdProvider() override;
-
- void GetUserId(fit::function<void(Status, std::string)> callback) override;
-
- private:
- const std::string user_id_;
-};
-
-} // namespace p2p_provider
-
-#endif // PERIDOT_BIN_LEDGER_P2P_PROVIDER_IMPL_STATIC_USER_ID_PROVIDER_H_
diff --git a/bin/ledger/p2p_provider/public/BUILD.gn b/bin/ledger/p2p_provider/public/BUILD.gn
deleted file mode 100644
index bffd88c..0000000
--- a/bin/ledger/p2p_provider/public/BUILD.gn
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("public") {
- sources = [
- "p2p_provider.h",
- "types.h",
- "user_id_provider.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- ]
-
- deps = []
-}
diff --git a/bin/ledger/p2p_provider/public/p2p_provider.h b/bin/ledger/p2p_provider/public/p2p_provider.h
deleted file mode 100644
index 18a53cb..0000000
--- a/bin/ledger/p2p_provider/public/p2p_provider.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_P2P_PROVIDER_H_
-#define PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_P2P_PROVIDER_H_
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/p2p_provider/public/types.h"
-
-namespace p2p_provider {
-// P2PProvider handles the peer-to-peer connections between devices.
-class P2PProvider {
- public:
- class Client {
- public:
- // OnDeviceChange is called for every new connection and
- // disconnection to devices from the mesh, including the ones already
- // participating in the mesh when we connect to it.
- virtual void OnDeviceChange(fxl::StringView device_name,
- DeviceChangeType change_type) = 0;
- // OnNewMessage is called for every message sent to this device.
- virtual void OnNewMessage(fxl::StringView device_name,
- fxl::StringView message) = 0;
- };
-
- P2PProvider() {}
- virtual ~P2PProvider() {}
-
- // Starts participating in the device mesh.
- // To stop participating, destroy this class instance.
- virtual void Start(Client* client) = 0;
- // Sends the provided message |data| to |destination|. Returns true if the
- // message was sent, false if the destination is not available.
- virtual bool SendMessage(fxl::StringView destination,
- fxl::StringView data) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(P2PProvider);
-};
-
-} // namespace p2p_provider
-
-#endif // PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_P2P_PROVIDER_H_
diff --git a/bin/ledger/p2p_provider/public/types.h b/bin/ledger/p2p_provider/public/types.h
deleted file mode 100644
index 852d37f..0000000
--- a/bin/ledger/p2p_provider/public/types.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_TYPES_H_
-#define PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_TYPES_H_
-
-namespace p2p_provider {
-// Type describing whether the change is a new device or a deleted one.
-enum class DeviceChangeType : bool { NEW, DELETED };
-
-} // namespace p2p_provider
-
-#endif // PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_TYPES_H_
diff --git a/bin/ledger/p2p_provider/public/user_id_provider.h b/bin/ledger/p2p_provider/public/user_id_provider.h
deleted file mode 100644
index 67c2b34..0000000
--- a/bin/ledger/p2p_provider/public/user_id_provider.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_USER_ID_PROVIDER_H_
-#define PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_USER_ID_PROVIDER_H_
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-namespace p2p_provider {
-// UserIdProvider abstracts the unique User ID shared accross all devices of a
-// user and used to establish a connection.
-class UserIdProvider {
- public:
- enum class Status {
- OK,
- ERROR,
- };
-
- UserIdProvider() {}
- virtual ~UserIdProvider() {}
-
- // GetUserId calls its callback with the user id.
- virtual void GetUserId(fit::function<void(Status, std::string)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(UserIdProvider);
-};
-
-} // namespace p2p_provider
-
-#endif // PERIDOT_BIN_LEDGER_P2P_PROVIDER_PUBLIC_USER_ID_PROVIDER_H_
diff --git a/bin/ledger/p2p_sync/impl/BUILD.gn b/bin/ledger/p2p_sync/impl/BUILD.gn
deleted file mode 100644
index 81fbf4e..0000000
--- a/bin/ledger/p2p_sync/impl/BUILD.gn
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("impl") {
- sources = [
- "commit_batch.cc",
- "commit_batch.h",
- "device_mesh.h",
- "flatbuffer_message_factory.cc",
- "flatbuffer_message_factory.h",
- "ledger_communicator_impl.cc",
- "ledger_communicator_impl.h",
- "message_holder.h",
- "page_communicator_impl.cc",
- "page_communicator_impl.h",
- "user_communicator_factory_impl.cc",
- "user_communicator_factory_impl.h",
- "user_communicator_impl.cc",
- "user_communicator_impl.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/environment",
- "//peridot/bin/ledger/p2p_provider/impl",
- "//peridot/bin/ledger/p2p_sync/public",
- "//peridot/bin/ledger/storage/public",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.modular.auth",
- ]
-
- deps = [
- ":message",
- "//garnet/public/lib/callback",
- "//peridot/lib/ledger_client:constants",
- ]
-}
-
-flatbuffer("message") {
- sources = [
- "message.fbs",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "page_communicator_impl_unittest.cc",
- "user_communicator_impl_unittest.cc",
- ]
-
- deps = [
- ":impl",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/p2p_provider/impl",
- "//peridot/bin/ledger/storage/fake:lib",
- "//peridot/bin/ledger/storage/testing",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/bin/ledger/testing/netconnector",
-
- # gtest matchers are in gmock.
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/p2p_sync/impl/commit_batch.cc b/bin/ledger/p2p_sync/impl/commit_batch.cc
deleted file mode 100644
index f2b565f..0000000
--- a/bin/ledger/p2p_sync/impl/commit_batch.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_sync/impl/commit_batch.h"
-
-#include <lib/callback/scoped_callback.h>
-
-namespace p2p_sync {
-
-CommitBatch::CommitBatch(std::string device, Delegate* delegate,
- storage::PageStorage* storage)
- : device_(std::move(device)),
- delegate_(delegate),
- storage_(storage),
- weak_factory_(this) {}
-
-void CommitBatch::set_on_empty(fit::closure on_empty) {
- on_empty_ = std::move(on_empty);
-}
-
-void CommitBatch::AddToBatch(
- std::vector<storage::PageStorage::CommitIdAndBytes> new_commits) {
- // New commits are supposed to be the parents of the already inserted ones. We
- // insert them before to ensure parents are processed before children.
- //
- // This insertion may be suboptimal in some cases, for instance when a merge
- // commit's parents are related to each other. In that case, we may request
- // (and insert) multiple times the same commit. A better way would be to sort
- // these commits by generation before inserting, but we don't have access to
- // this information here.
- commits_.insert(commits_.begin(),
- std::make_move_iterator(new_commits.begin()),
- std::make_move_iterator(new_commits.end()));
-
- std::vector<storage::PageStorage::CommitIdAndBytes> out;
- out.reserve(commits_.size());
- for (const auto& commit : commits_) {
- out.emplace_back(commit.id, commit.bytes);
- }
-
- storage_->AddCommitsFromSync(
- std::move(out), storage::ChangeSource::P2P,
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this](storage::Status status,
- std::vector<storage::CommitId> missing_ids) {
- if (status == storage::Status::OK) {
- if (on_empty_) {
- on_empty_();
- }
- return;
- }
- if (status == storage::Status::NOT_FOUND && !missing_ids.empty()) {
- delegate_->RequestCommits(device_, std::move(missing_ids));
- return;
- }
- FXL_LOG(ERROR) << "Error while adding commits, aborting batch: "
- << status;
- if (on_empty_) {
- on_empty_();
- }
- }));
-}
-
-} // namespace p2p_sync
diff --git a/bin/ledger/p2p_sync/impl/commit_batch.h b/bin/ledger/p2p_sync/impl/commit_batch.h
deleted file mode 100644
index 9c995e8..0000000
--- a/bin/ledger/p2p_sync/impl/commit_batch.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_COMMIT_BATCH_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_COMMIT_BATCH_H_
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace p2p_sync {
-
-// CommitBatch holds all commits that should be added together in PageStorage.
-class CommitBatch {
- public:
- // Delegate is used by |CommitBatch| to request missing commits.
- class Delegate {
- public:
- // Request missing commits from this batch. Commits will be added later
- // through CommitBatch::AddBatch.
- virtual void RequestCommits(fxl::StringView device,
- std::vector<storage::CommitId> ids) = 0;
- };
-
- CommitBatch(std::string device, Delegate* delegate,
- storage::PageStorage* storage);
- CommitBatch(const CommitBatch&) = delete;
- const CommitBatch& operator=(const CommitBatch&) = delete;
-
- // Registers a callback to be called when the batch processing is completed,
- // either through success or an unrecoverable error. Part of the
- // callback::AutoCleanable* client API.
- void set_on_empty(fit::closure on_empty);
-
- // Adds the provided commits to this batch.
- // This method will attempt to add the whole batch to |PageStorage|, and may
- // request additional commits through the |Delegate| if needed.
- void AddToBatch(
- std::vector<storage::PageStorage::CommitIdAndBytes> new_commits);
-
- private:
- std::string const device_;
- Delegate* const delegate_;
- storage::PageStorage* const storage_;
- std::list<storage::PageStorage::CommitIdAndBytes> commits_;
- fit::closure on_empty_;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<CommitBatch> weak_factory_;
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_COMMIT_BATCH_H_
diff --git a/bin/ledger/p2p_sync/impl/device_mesh.h b/bin/ledger/p2p_sync/impl/device_mesh.h
deleted file mode 100644
index f9dff68..0000000
--- a/bin/ledger/p2p_sync/impl/device_mesh.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_DEVICE_MESH_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_DEVICE_MESH_H_
-
-#include <memory>
-#include <set>
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace p2p_sync {
-// DeviceMesh is used by PageCommunicators to communicate with the device mesh.
-class DeviceMesh {
- public:
- using DeviceSet = std::set<std::string, convert::StringViewComparator>;
-
- DeviceMesh() {}
- virtual ~DeviceMesh() {}
-
- // Returns the current active device set.
- virtual DeviceSet GetDeviceList() = 0;
-
- // Sends the given buffer to a connected device.
- virtual void Send(fxl::StringView device_name,
- convert::ExtendedStringView data) = 0;
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_DEVICE_MESH_H_
diff --git a/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.cc b/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.cc
deleted file mode 100644
index 90f37ef..0000000
--- a/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.h"
-
-#include "peridot/lib/convert/convert.h"
-
-namespace p2p_sync {
-
-void CreateUnknownResponseMessage(flatbuffers::FlatBufferBuilder* buffer,
- fxl::StringView namespace_id,
- fxl::StringView page_id,
- ResponseStatus status) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id_offset =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id),
- convert::ToFlatBufferVector(buffer, page_id));
- flatbuffers::Offset<Response> response =
- CreateResponse(*buffer, status, namespace_page_id_offset);
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Response, response.Union());
- buffer->Finish(message);
-}
-} // namespace p2p_sync
diff --git a/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.h b/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.h
deleted file mode 100644
index 8daaa7d..0000000
--- a/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_FLATBUFFER_MESSAGE_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_FLATBUFFER_MESSAGE_FACTORY_H_
-
-#include <flatbuffers/flatbuffers.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/p2p_sync/impl/message_generated.h"
-
-namespace p2p_sync {
-
-void CreateUnknownResponseMessage(flatbuffers::FlatBufferBuilder* buffer,
- fxl::StringView namespace_id,
- fxl::StringView page_id,
- ResponseStatus status);
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_FLATBUFFER_MESSAGE_FACTORY_H_
diff --git a/bin/ledger/p2p_sync/impl/ledger_communicator_impl.cc b/bin/ledger/p2p_sync/impl/ledger_communicator_impl.cc
deleted file mode 100644
index dd00103..0000000
--- a/bin/ledger/p2p_sync/impl/ledger_communicator_impl.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_sync/impl/ledger_communicator_impl.h"
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.h"
-#include "peridot/bin/ledger/p2p_sync/impl/message_generated.h"
-#include "peridot/bin/ledger/p2p_sync/impl/page_communicator_impl.h"
-
-namespace p2p_sync {
-LedgerCommunicatorImpl::LedgerCommunicatorImpl(
- coroutine::CoroutineService* coroutine_service, std::string namespace_id,
- DeviceMesh* mesh)
- : coroutine_service_(coroutine_service),
- namespace_id_(std::move(namespace_id)),
- mesh_(mesh) {}
-
-LedgerCommunicatorImpl::~LedgerCommunicatorImpl() {
- FXL_DCHECK(pages_.empty());
- if (on_delete_) {
- on_delete_();
- }
-}
-
-void LedgerCommunicatorImpl::set_on_delete(fit::closure on_delete) {
- FXL_DCHECK(!on_delete_) << "on_delete() can only be called once.";
- on_delete_ = std::move(on_delete);
-}
-
-void LedgerCommunicatorImpl::OnDeviceChange(
- fxl::StringView remote_device, p2p_provider::DeviceChangeType change_type) {
- for (const auto& page : pages_) {
- page.second->OnDeviceChange(remote_device, change_type);
- }
-}
-
-void LedgerCommunicatorImpl::OnNewRequest(fxl::StringView source,
- fxl::StringView page_id,
- MessageHolder<Request> message) {
- const auto& it = pages_.find(page_id);
- if (it == pages_.end()) {
- // Send unknown page response.
- flatbuffers::FlatBufferBuilder buffer;
- CreateUnknownResponseMessage(&buffer, namespace_id_, page_id,
- ResponseStatus_UNKNOWN_PAGE);
- mesh_->Send(source, convert::ExtendedStringView(buffer));
- return;
- }
-
- it->second->OnNewRequest(source, std::move(message));
-}
-
-void LedgerCommunicatorImpl::OnNewResponse(fxl::StringView source,
- fxl::StringView page_id,
- MessageHolder<Response> message) {
- const auto& it = pages_.find(page_id);
- if (it == pages_.end()) {
- // Page has been deleted between request and response, just discard.
- return;
- }
-
- it->second->OnNewResponse(source, std::move(message));
-}
-
-std::unique_ptr<PageCommunicator> LedgerCommunicatorImpl::GetPageCommunicator(
- storage::PageStorage* storage, storage::PageSyncClient* sync_client) {
- storage::PageId page_id = storage->GetId();
-
- FXL_DCHECK(pages_.find(page_id) == pages_.end());
-
- std::unique_ptr<PageCommunicatorImpl> page =
- std::make_unique<PageCommunicatorImpl>(coroutine_service_, storage,
- sync_client, namespace_id_,
- page_id, mesh_);
- PageCommunicatorImpl* page_ptr = page.get();
- pages_.emplace(page_id, page_ptr);
- page->set_on_delete([this, page_id = std::move(page_id), page_ptr] {
- auto it = pages_.find(page_id);
- FXL_DCHECK(it != pages_.end());
- pages_.erase(it);
- });
- return page;
-}
-
-} // namespace p2p_sync
diff --git a/bin/ledger/p2p_sync/impl/ledger_communicator_impl.h b/bin/ledger/p2p_sync/impl/ledger_communicator_impl.h
deleted file mode 100644
index bd60ed8..0000000
--- a/bin/ledger/p2p_sync/impl/ledger_communicator_impl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_LEDGER_COMMUNICATOR_IMPL_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_LEDGER_COMMUNICATOR_IMPL_H_
-
-#import <map>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/p2p_provider/public/types.h"
-#include "peridot/bin/ledger/p2p_sync/impl/device_mesh.h"
-#include "peridot/bin/ledger/p2p_sync/impl/message_generated.h"
-#include "peridot/bin/ledger/p2p_sync/impl/message_holder.h"
-#include "peridot/bin/ledger/p2p_sync/public/ledger_communicator.h"
-#include "peridot/bin/ledger/p2p_sync/public/page_communicator.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace p2p_sync {
-class PageCommunicatorImpl;
-
-// Ledger-level P2P communicator.
-class LedgerCommunicatorImpl : public LedgerCommunicator {
- public:
- LedgerCommunicatorImpl(coroutine::CoroutineService* coroutine_service,
- std::string namespace_id, DeviceMesh* mesh);
- ~LedgerCommunicatorImpl() override;
-
- void set_on_delete(fit::closure on_delete);
-
- // OnDeviceChange is called each time a device connects or unconnects.
- void OnDeviceChange(fxl::StringView remote_device,
- p2p_provider::DeviceChangeType change_type);
-
- // Called when a new request arrived for this ledger from device |source|.
- void OnNewRequest(fxl::StringView source, fxl::StringView page_id,
- MessageHolder<Request> message);
-
- // Called when a new response arrived for this ledger from device |source|.
- void OnNewResponse(fxl::StringView source, fxl::StringView page_id,
- MessageHolder<Response> message);
-
- // LedgerCommunicator:
- std::unique_ptr<PageCommunicator> GetPageCommunicator(
- storage::PageStorage* storage,
- storage::PageSyncClient* sync_client) override;
-
- private:
- std::map<std::string, PageCommunicatorImpl*, convert::StringViewComparator>
- pages_;
-
- fit::closure on_delete_;
- coroutine::CoroutineService* const coroutine_service_;
- const std::string namespace_id_;
- DeviceMesh* const mesh_;
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_LEDGER_COMMUNICATOR_IMPL_H_
diff --git a/bin/ledger/p2p_sync/impl/message.fbs b/bin/ledger/p2p_sync/impl/message.fbs
deleted file mode 100644
index b97f8af..0000000
--- a/bin/ledger/p2p_sync/impl/message.fbs
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-namespace p2p_sync;
-
-// Handshake. Gives the host_name of the device. Will be the first message
-// once a connection is established.
-table Handshake {
- version: ushort;
- host_name: [ubyte];
-}
-
-table NamespacePageId {
- namespace_id: [ubyte];
- page_id: [ubyte];
-}
-
-// Request that the other side starts sending us new commits.
-// There is no guarantee that the other side actually sends data over, or at
-// which frequency (for instance, if low on battery).
-table WatchStartRequest {}
-
-// Request that the other side stops sending us new commits.
-table WatchStopRequest {}
-
-table Data {
- bytes: [ubyte];
-}
-
-table CommitId {
- id: [ubyte];
-}
-
-// Request commit data.
-table CommitRequest {
- commit_ids: [CommitId];
-}
-
-enum CommitStatus : ushort {
- OK,
- // No commit by this id is known.
- UNKNOWN_COMMIT,
-}
-
-table Commit {
- id: CommitId;
- status: CommitStatus;
- commit: Data;
-}
-
-table CommitResponse {
- commits: [Commit];
-}
-
-table ObjectId {
- key_index: uint;
- deletion_scope_id: uint;
- digest: [ubyte];
-}
-
-// Request some objects.
-table ObjectRequest {
- object_ids: [ObjectId];
-}
-
-enum ObjectStatus : ushort {
- OK,
- // No object by this id is known.
- UNKNOWN_OBJECT,
-}
-
-// Whether an object is known to be synced to the cloud.
-enum ObjectSyncStatus : ubyte {
- // The object is not known to be synced to the cloud.
- UNSYNCED,
- // The object is known to be synced to the cloud.
- SYNCED_TO_CLOUD,
-}
-
-table Object {
- id: ObjectId;
- status: ObjectStatus;
- data: Data;
- sync_status: ObjectSyncStatus;
-}
-
-table ObjectResponse {
- objects: [Object];
-}
-
-union RequestMessage {
- WatchStartRequest,
- WatchStopRequest,
- CommitRequest,
- ObjectRequest,
-}
-
-table Request {
- namespace_page: NamespacePageId;
- request: RequestMessage;
-}
-
-union ResponseMessage {
- CommitResponse,
- ObjectResponse,
-}
-
-enum ResponseStatus : ushort {
- OK,
- // No namespace by this name is known. Requesting side should stop sending
- // requests for this namespace.
- UNKNOWN_NAMESPACE,
- // No page by this name is known in this ledger. Requesting side should stop
- // sending requests for this page.
- UNKNOWN_PAGE,
-}
-
-table Response {
- status: ResponseStatus;
- namespace_page: NamespacePageId;
- response: ResponseMessage;
-}
-
-union MessageUnion {
- Request,
- Response,
-}
-
-// Message contains the business-logic messages sent between devices.
-table Message {
- message: MessageUnion;
-}
-
-root_type Message;
diff --git a/bin/ledger/p2p_sync/impl/message_holder.h b/bin/ledger/p2p_sync/impl/message_holder.h
deleted file mode 100644
index 1eff936..0000000
--- a/bin/ledger/p2p_sync/impl/message_holder.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_MESSAGE_HOLDER_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_MESSAGE_HOLDER_H_
-
-#include <functional>
-#include <utility>
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/strings/string_view.h>
-
-namespace p2p_sync {
-// MessageHolder is used to hold a parsed Flatbuffer message along with its
-// data.
-template <class M>
-class MessageHolder {
- public:
- // Create a new MessageHolder from the provided data and a parser.
- MessageHolder(fxl::StringView data,
- fit::function<const M*(const uint8_t*)> get_message)
- : data_(data.begin(), data.end()), message_(get_message(data_.data())) {}
-
- // Create a new MessageHolder from the provided data and a parser.
- MessageHolder(std::vector<uint8_t> data,
- fit::function<const M*(const uint8_t*)> get_message)
- : data_(std::move(data)), message_(get_message(data_.data())) {}
-
- // Create a new MessageHolder from the current object and a function to
- // specialize the message. The current message holder is destroyed in the
- // process. It can be used as follows:
- // MessageHolder<Message> message = ...;
- // MessageHolder<Request> request = std::move(message).TakeAndMap<Request>(
- // [](const Message* message) {
- // return static_cast<const Request*>(message->message());
- // });
- template <class T>
- MessageHolder<T> TakeAndMap(
- fit::function<const T*(const M*)> get_message) && {
- return MessageHolder<T>(std::move(*this), std::move(get_message));
- }
-
- // Allow moves.
- MessageHolder(MessageHolder&& other) noexcept = default;
- MessageHolder& operator=(MessageHolder&& other) noexcept = default;
-
- // Delete copy constructor and assignment. We cannot easily copy a
- // MessageHolder because of the need to re-parse the data and reapply the
- // chain of specializations to recreate the object.
- MessageHolder(const MessageHolder& other) = delete;
- MessageHolder& operator=(const MessageHolder<M>& other) = delete;
-
- // Allow MessageHolder<T> to be used as a T* for reading data.
- const M* operator->() const { return message_; }
- const M& operator*() const { return *message_; }
-
- private:
- template <typename U>
- friend class MessageHolder;
-
- // Equivalent constructor to the TakeAndMap factory. Using the factory allows
- // to explicitly declare template parameters, permitting the use of a lambda
- // directly.
- template <class T>
- MessageHolder(MessageHolder<T>&& other,
- fit::function<const M*(const T*)> get_message)
- : data_(std::move(other.data_)), message_(get_message(other.message_)) {
- other.message_ = nullptr;
- }
-
- std::vector<uint8_t> data_;
- const M* message_;
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_MESSAGE_HOLDER_H_
diff --git a/bin/ledger/p2p_sync/impl/page_communicator_impl.cc b/bin/ledger/p2p_sync/impl/page_communicator_impl.cc
deleted file mode 100644
index b1ec5a7..0000000
--- a/bin/ledger/p2p_sync/impl/page_communicator_impl.cc
+++ /dev/null
@@ -1,679 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_sync/impl/page_communicator_impl.h"
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine_waiter.h"
-#include "peridot/bin/ledger/p2p_sync/impl/message_generated.h"
-#include "peridot/bin/ledger/storage/public/read_data_source.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace p2p_sync {
-namespace {
-storage::ObjectIdentifier ToObjectIdentifier(const ObjectId* fb_object_id) {
- uint32_t key_index = fb_object_id->key_index();
- uint32_t deletion_scope_id = fb_object_id->deletion_scope_id();
- return storage::ObjectIdentifier{
- key_index, deletion_scope_id,
- storage::ObjectDigest(fb_object_id->digest())};
-}
-} // namespace
-
-// PendingObjectRequestHolder holds state for object requests that have been
-// sent to peers and for which we wait for an answer.
-class PageCommunicatorImpl::PendingObjectRequestHolder {
- public:
- explicit PendingObjectRequestHolder(
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback)
- : callback_(std::move(callback)) {}
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
-
- // Registers a new pending request to device |destination|.
- void AddNewPendingRequest(std::string destination) {
- requests_.emplace(std::move(destination));
- }
-
- // Processes the response from device |source|.
- void Complete(fxl::StringView source, const Object* object) {
- auto it = requests_.find(source);
- if (it == requests_.end()) {
- return;
- }
- if (object == nullptr || object->status() == ObjectStatus_UNKNOWN_OBJECT) {
- requests_.erase(it);
- if (!requests_.empty()) {
- return;
- }
- // All requests have returned and none is valid: return an error.
- callback_(storage::Status::NOT_FOUND, storage::ChangeSource::P2P,
- storage::IsObjectSynced::NO, nullptr);
- if (on_empty_) {
- on_empty_();
- }
- return;
- }
-
- std::unique_ptr<storage::DataSource::DataChunk> chunk =
- storage::DataSource::DataChunk::Create(
- convert::ToString(object->data()->bytes()));
- storage::IsObjectSynced is_object_synced;
- switch (object->sync_status()) {
- case ObjectSyncStatus_UNSYNCED:
- is_object_synced = storage::IsObjectSynced::NO;
- break;
- case ObjectSyncStatus_SYNCED_TO_CLOUD:
- is_object_synced = storage::IsObjectSynced::YES;
- break;
- }
- callback_(storage::Status::OK, storage::ChangeSource::P2P, is_object_synced,
- std::move(chunk));
- if (on_empty_) {
- on_empty_();
- }
- }
-
- private:
- fit::function<void(
- storage::Status, storage::ChangeSource, storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)> const callback_;
- // Set of devices for which we are waiting an answer.
- // We might be able to get rid of this list and just use a counter (or even
- // nothing at all) once we have a timeout on requests.
- std::set<std::string, convert::StringViewComparator> requests_;
- fit::closure on_empty_;
-};
-
-// ObjectResponseHolder holds temporary data we collect in order to build
-// ObjectResponses.
-// This is necessary as object data (from |storage::Object|) and synchronization
-// data come from different asynchronous calls.
-struct PageCommunicatorImpl::ObjectResponseHolder {
- storage::ObjectIdentifier identifier;
- std::unique_ptr<const storage::Object> object;
- bool is_synced = false;
-
- explicit ObjectResponseHolder(storage::ObjectIdentifier identifier)
- : identifier(std::move(identifier)) {}
-};
-
-PageCommunicatorImpl::PageCommunicatorImpl(
- coroutine::CoroutineService* coroutine_service,
- storage::PageStorage* storage, storage::PageSyncClient* sync_client,
- std::string namespace_id, std::string page_id, DeviceMesh* mesh)
- : coroutine_manager_(coroutine_service),
- namespace_id_(std::move(namespace_id)),
- page_id_(std::move(page_id)),
- mesh_(mesh),
- storage_(storage),
- sync_client_(sync_client),
- weak_factory_(this) {}
-
-PageCommunicatorImpl::~PageCommunicatorImpl() {
- FXL_DCHECK(!in_destructor_);
- in_destructor_ = true;
-
- flatbuffers::FlatBufferBuilder buffer;
- if (!started_) {
- if (on_delete_) {
- on_delete_();
- }
- return;
- }
-
- BuildWatchStopBuffer(&buffer);
- for (const auto& device : interested_devices_) {
- mesh_->Send(device, buffer);
- }
-
- if (on_delete_) {
- on_delete_();
- }
-}
-
-void PageCommunicatorImpl::Start() {
- FXL_DCHECK(!started_);
- started_ = true;
- sync_client_->SetSyncDelegate(this);
- storage_->AddCommitWatcher(this);
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer);
-
- for (const auto& device : mesh_->GetDeviceList()) {
- mesh_->Send(device, buffer);
- }
-}
-
-void PageCommunicatorImpl::set_on_delete(fit::closure on_delete) {
- FXL_DCHECK(!on_delete_) << "set_on_delete() can only be called once.";
- on_delete_ = std::move(on_delete);
-}
-
-void PageCommunicatorImpl::OnDeviceChange(
- fxl::StringView remote_device, p2p_provider::DeviceChangeType change_type) {
- if (!started_ || in_destructor_) {
- return;
- }
-
- if (change_type == p2p_provider::DeviceChangeType::DELETED) {
- const auto& it = interested_devices_.find(remote_device);
- if (it != interested_devices_.end()) {
- interested_devices_.erase(it);
- }
- const auto& it2 = not_interested_devices_.find(remote_device);
- if (it2 != not_interested_devices_.end()) {
- not_interested_devices_.erase(it2);
- }
- const auto& it3 = pending_commit_batches_.find(remote_device);
- if (it3 != pending_commit_batches_.end()) {
- pending_commit_batches_.erase(it3);
- }
- return;
- }
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer);
- mesh_->Send(remote_device, buffer);
-}
-
-void PageCommunicatorImpl::OnNewRequest(fxl::StringView source,
- MessageHolder<Request> message) {
- FXL_DCHECK(!in_destructor_);
- switch (message->request_type()) {
- case RequestMessage_WatchStartRequest: {
- MarkSyncedToPeer(
- [this, source = source.ToString()](storage::Status status) {
- if (status != storage::Status::OK) {
- // If we fail to mark the page storage as synced to a peer, we
- // might end up in a situation of deleting from disk a partially
- // synced page. Log an error and return.
- FXL_LOG(ERROR) << "Failed to mark PageStorage as synced to peer";
- return;
- }
- if (interested_devices_.find(source) == interested_devices_.end()) {
- interested_devices_.insert(source);
- }
- auto it = not_interested_devices_.find(source);
- if (it != not_interested_devices_.end()) {
- // The device used to be uninterested, but now wants updates.
- // Let's contact it again.
- not_interested_devices_.erase(it);
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer);
- mesh_->Send(source, buffer);
- }
- });
- break;
- }
- case RequestMessage_WatchStopRequest: {
- const auto& it = interested_devices_.find(source);
- if (it != interested_devices_.end()) {
- interested_devices_.erase(it);
- }
- // Device |source| disconnected, thus will not answer any request. We thus
- // mark all pending requests to |source| to be finished.
- std::vector<PendingObjectRequestHolder*> requests;
- requests.reserve(pending_object_requests_.size());
- for (auto& object_request : pending_object_requests_) {
- // We cannot call Complete here because it deletes the object, making
- // the iterator used in this for loop invalid.
- requests.push_back(&object_request.second);
- }
- for (PendingObjectRequestHolder* const request : requests) {
- request->Complete(source, nullptr);
- }
- break;
- }
- case RequestMessage_CommitRequest:
- ProcessCommitRequest(
- source.ToString(),
- std::move(message).TakeAndMap<CommitRequest>(
- [](const Request* request) {
- return static_cast<const CommitRequest*>(request->request());
- }));
- break;
- case RequestMessage_ObjectRequest:
- ProcessObjectRequest(
- source,
- std::move(message).TakeAndMap<ObjectRequest>(
- [](const Request* request) {
- return static_cast<const ObjectRequest*>(request->request());
- }));
- break;
- case RequestMessage_NONE:
- FXL_LOG(ERROR) << "The message received is malformed";
- break;
- }
-}
-
-void PageCommunicatorImpl::OnNewResponse(fxl::StringView source,
- MessageHolder<Response> message) {
- FXL_DCHECK(!in_destructor_);
- if (message->status() != ResponseStatus_OK) {
- // The namespace or page was unknown on the other side. We can probably do
- // something smart with this information (for instance, stop sending
- // requests over), but we just ignore it for now.
- not_interested_devices_.emplace(source.ToString());
- return;
- }
- switch (message->response_type()) {
- case ResponseMessage_ObjectResponse: {
- const ObjectResponse* object_response =
- static_cast<const ObjectResponse*>(message->response());
- for (const Object* object : *(object_response->objects())) {
- auto object_id = ToObjectIdentifier(object->id());
- auto pending_request = pending_object_requests_.find(object_id);
- if (pending_request == pending_object_requests_.end()) {
- continue;
- }
- pending_request->second.Complete(source, object);
- }
- break;
- }
- case ResponseMessage_CommitResponse: {
- const CommitResponse* commit_response =
- static_cast<const CommitResponse*>(message->response());
- std::vector<storage::PageStorage::CommitIdAndBytes> commits;
- for (const Commit* commit : *(commit_response->commits())) {
- if (commit->status() != CommitStatus_OK) {
- continue;
- }
- commits.emplace_back(convert::ToString(commit->id()->id()),
- convert::ToString(commit->commit()->bytes()));
- }
- auto it = pending_commit_batches_.find(source);
- if (it != pending_commit_batches_.end()) {
- it->second.AddToBatch(std::move(commits));
- } else {
- auto it_pair = pending_commit_batches_.emplace(
- std::piecewise_construct, std::forward_as_tuple(source.ToString()),
- std::forward_as_tuple(source.ToString(), this, storage_));
- it_pair.first->second.AddToBatch(std::move(commits));
- }
- break;
- }
-
- case ResponseMessage_NONE:
- FXL_LOG(ERROR) << "The message received is malformed";
- return;
- }
-}
-
-void PageCommunicatorImpl::GetObject(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) {
- flatbuffers::FlatBufferBuilder buffer;
-
- BuildObjectRequestBuffer(&buffer, object_identifier);
-
- auto request_holder = pending_object_requests_.emplace(
- std::move(object_identifier), std::move(callback));
-
- for (const auto& device : interested_devices_) {
- request_holder.first->second.AddNewPendingRequest(device);
- }
- for (const auto& device : interested_devices_) {
- mesh_->Send(device, buffer);
- }
-}
-
-void PageCommunicatorImpl::OnNewCommits(
- const std::vector<std::unique_ptr<const storage::Commit>>& commits,
- storage::ChangeSource source) {
- if (source != storage::ChangeSource::LOCAL) {
- // Don't propagate synced commits.
- return;
- }
- for (const auto& commit : commits) {
- commits_to_upload_.emplace_back(commit->Clone());
- }
- // We need to check if we need to merge first.
- storage_->GetHeadCommitIds(
- callback::MakeScoped(weak_factory_.GetWeakPtr(),
- [this](storage::Status status,
- std::vector<storage::CommitId> commit_ids) {
- if (status != storage::Status::OK) {
- return;
- }
- if (commit_ids.size() != 1) {
- // A merge needs to happen, let's wait until we
- // have one.
- return;
- }
- if (commits_to_upload_.empty()) {
- // Commits have already been sent. Let's stop
- // early.
- return;
- }
- flatbuffers::FlatBufferBuilder buffer;
- BuildCommitBuffer(&buffer, commits_to_upload_);
-
- for (const auto& device : interested_devices_) {
- mesh_->Send(device, buffer);
- }
- commits_to_upload_.clear();
- }));
-}
-
-void PageCommunicatorImpl::RequestCommits(fxl::StringView device,
- std::vector<storage::CommitId> ids) {
- flatbuffers::FlatBufferBuilder buffer;
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(buffer,
- convert::ToFlatBufferVector(&buffer, namespace_id_),
- convert::ToFlatBufferVector(&buffer, page_id_));
- std::vector<flatbuffers::Offset<CommitId>> commit_ids;
- for (const auto& id : ids) {
- flatbuffers::Offset<CommitId> commit_id =
- CreateCommitId(buffer, convert::ToFlatBufferVector(&buffer, id));
- commit_ids.push_back(commit_id);
- }
- flatbuffers::Offset<CommitRequest> commit_request =
- CreateCommitRequest(buffer, buffer.CreateVector(commit_ids));
- flatbuffers::Offset<Request> request =
- CreateRequest(buffer, namespace_page_id, RequestMessage_CommitRequest,
- commit_request.Union());
- flatbuffers::Offset<Message> message =
- CreateMessage(buffer, MessageUnion_Request, request.Union());
- buffer.Finish(message);
- mesh_->Send(device, buffer);
-}
-
-void PageCommunicatorImpl::BuildWatchStartBuffer(
- flatbuffers::FlatBufferBuilder* buffer) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id_),
- convert::ToFlatBufferVector(buffer, page_id_));
- flatbuffers::Offset<Request> request = CreateRequest(
- *buffer, namespace_page_id, RequestMessage_WatchStartRequest);
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Request, request.Union());
- buffer->Finish(message);
-}
-
-void PageCommunicatorImpl::BuildWatchStopBuffer(
- flatbuffers::FlatBufferBuilder* buffer) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id_),
- convert::ToFlatBufferVector(buffer, page_id_));
- flatbuffers::Offset<Request> request = CreateRequest(
- *buffer, namespace_page_id, RequestMessage_WatchStopRequest);
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Request, request.Union());
- buffer->Finish(message);
-}
-
-void PageCommunicatorImpl::BuildObjectRequestBuffer(
- flatbuffers::FlatBufferBuilder* buffer,
- storage::ObjectIdentifier object_identifier) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id_),
- convert::ToFlatBufferVector(buffer, page_id_));
- flatbuffers::Offset<ObjectId> object_id = CreateObjectId(
- *buffer, object_identifier.key_index(),
- object_identifier.deletion_scope_id(),
- convert::ToFlatBufferVector(
- buffer, object_identifier.object_digest().Serialize()));
- flatbuffers::Offset<ObjectRequest> object_request = CreateObjectRequest(
- *buffer, buffer->CreateVector(
- std::vector<flatbuffers::Offset<ObjectId>>({object_id})));
- flatbuffers::Offset<Request> request =
- CreateRequest(*buffer, namespace_page_id, RequestMessage_ObjectRequest,
- object_request.Union());
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Request, request.Union());
- buffer->Finish(message);
-}
-
-void PageCommunicatorImpl::BuildCommitBuffer(
- flatbuffers::FlatBufferBuilder* buffer,
- const std::vector<std::unique_ptr<const storage::Commit>>& commits) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id_),
- convert::ToFlatBufferVector(buffer, page_id_));
- std::vector<flatbuffers::Offset<Commit>> fb_commits;
- for (const auto& commit : commits) {
- flatbuffers::Offset<CommitId> fb_commit_id = CreateCommitId(
- *buffer, convert::ToFlatBufferVector(buffer, commit->GetId()));
- flatbuffers::Offset<Data> fb_commit_data = CreateData(
- *buffer,
- convert::ToFlatBufferVector(buffer, commit->GetStorageBytes()));
- fb_commits.emplace_back(
- CreateCommit(*buffer, fb_commit_id, CommitStatus_OK, fb_commit_data));
- }
-
- flatbuffers::Offset<CommitResponse> commit_response =
- CreateCommitResponse(*buffer, buffer->CreateVector(fb_commits));
- flatbuffers::Offset<Response> response =
- CreateResponse(*buffer, ResponseStatus_OK, namespace_page_id,
- ResponseMessage_CommitResponse, commit_response.Union());
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Response, response.Union());
- buffer->Finish(message);
-}
-
-void PageCommunicatorImpl::BuildCommitResponseBuffer(
- flatbuffers::FlatBufferBuilder* buffer,
- const std::vector<
- std::pair<storage::CommitId, std::unique_ptr<const storage::Commit>>>&
- commits) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id_),
- convert::ToFlatBufferVector(buffer, page_id_));
- std::vector<flatbuffers::Offset<Commit>> fb_commits;
- for (const auto& commit : commits) {
- flatbuffers::Offset<CommitId> fb_commit_id = CreateCommitId(
- *buffer, convert::ToFlatBufferVector(buffer, commit.first));
- if (commit.second) {
- flatbuffers::Offset<Data> fb_commit_data =
- CreateData(*buffer, convert::ToFlatBufferVector(
- buffer, commit.second->GetStorageBytes()));
- fb_commits.emplace_back(
- CreateCommit(*buffer, fb_commit_id, CommitStatus_OK, fb_commit_data));
- } else {
- fb_commits.emplace_back(
- CreateCommit(*buffer, fb_commit_id, CommitStatus_UNKNOWN_COMMIT));
- }
- }
-
- flatbuffers::Offset<CommitResponse> commit_response =
- CreateCommitResponse(*buffer, buffer->CreateVector(fb_commits));
- flatbuffers::Offset<Response> response =
- CreateResponse(*buffer, ResponseStatus_OK, namespace_page_id,
- ResponseMessage_CommitResponse, commit_response.Union());
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Response, response.Union());
- buffer->Finish(message);
-}
-
-void PageCommunicatorImpl::ProcessCommitRequest(
- std::string source, MessageHolder<CommitRequest> request) {
- coroutine_manager_.StartCoroutine([this, source = std::move(source),
- request = std::move(request)](
- coroutine::CoroutineHandler* handler) {
- auto commit_waiter = fxl::MakeRefCounted<callback::Waiter<
- storage::Status,
- std::pair<storage::CommitId, std::unique_ptr<const storage::Commit>>>>(
- storage::Status::OK);
- for (const CommitId* id : *request->commit_ids()) {
- storage_->GetCommit(
- id->id(), [commit_id = convert::ToString(id->id()),
- callback = commit_waiter->NewCallback()](
- storage::Status status,
- std::unique_ptr<const storage::Commit> commit) mutable {
- if (status == storage::Status::NOT_FOUND) {
- // Not finding an commit is okay in this context: we'll just
- // reply we don't have it. There is not need to abort
- // processing the request.
- callback(storage::Status::OK,
- std::make_pair(std::move(commit_id), nullptr));
- return;
- }
- callback(status,
- std::make_pair(std::move(commit_id), std::move(commit)));
- });
- }
- storage::Status status;
- std::vector<
- std::pair<storage::CommitId, std::unique_ptr<const storage::Commit>>>
- commits;
- if (coroutine::Wait(handler, std::move(commit_waiter), &status, &commits) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return;
- }
-
- if (status != storage::Status::OK) {
- return;
- }
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildCommitResponseBuffer(&buffer, commits);
- mesh_->Send(source, buffer);
- });
-}
-
-void PageCommunicatorImpl::ProcessObjectRequest(
- fxl::StringView source, MessageHolder<ObjectRequest> request) {
- coroutine_manager_.StartCoroutine(
- [this, source = source.ToString(),
- request = std::move(request)](coroutine::CoroutineHandler* handler) {
- // We use a std::list so that we can keep a reference to an element
- // while adding new items.
- std::list<ObjectResponseHolder> object_responses;
- auto response_waiter =
- fxl::MakeRefCounted<callback::StatusWaiter<storage::Status>>(
- storage::Status::OK);
- for (const ObjectId* object_id : *request->object_ids()) {
- storage::ObjectIdentifier identifier{
- object_id->key_index(), object_id->deletion_scope_id(),
- storage::ObjectDigest(object_id->digest())};
- object_responses.emplace_back(identifier);
- auto& response = object_responses.back();
- storage_->GetPiece(
- identifier,
- [callback = response_waiter->NewCallback(), &response](
- storage::Status status,
- std::unique_ptr<const storage::Object> object) mutable {
- if (status == storage::Status::NOT_FOUND) {
- // Not finding an object is okay in this context: we'll just
- // reply we don't have it. There is not need to abort
- // processing the request.
- callback(storage::Status::OK);
- return;
- }
- response.object = std::move(object);
- callback(status);
- });
- storage_->IsPieceSynced(
- std::move(identifier),
- [callback = response_waiter->NewCallback(), &response](
- storage::Status status, bool is_synced) {
- if (status == storage::Status::NOT_FOUND) {
- // Not finding an object is okay in this context: we'll just
- // reply we don't have it. There is not need to abort
- // processing the request.
- callback(storage::Status::OK);
- return;
- }
- response.is_synced = is_synced;
- callback(status);
- });
- }
-
- storage::Status status;
- if (coroutine::Wait(handler, response_waiter, &status) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return;
- }
-
- if (status != storage::Status::OK) {
- FXL_LOG(WARNING) << "Error while retrieving objects: " << status;
- return;
- }
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildObjectResponseBuffer(&buffer, std::move(object_responses));
-
- mesh_->Send(source, buffer);
- });
-}
-
-void PageCommunicatorImpl::BuildObjectResponseBuffer(
- flatbuffers::FlatBufferBuilder* buffer,
- std::list<ObjectResponseHolder> object_responses) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id_),
- convert::ToFlatBufferVector(buffer, page_id_));
- std::vector<flatbuffers::Offset<Object>> fb_objects;
- for (const ObjectResponseHolder& object_response : object_responses) {
- flatbuffers::Offset<ObjectId> fb_object_id = CreateObjectId(
- *buffer, object_response.identifier.key_index(),
- object_response.identifier.deletion_scope_id(),
- convert::ToFlatBufferVector(
- buffer, object_response.identifier.object_digest().Serialize()));
- if (object_response.object) {
- fxl::StringView data;
- storage::Status status = object_response.object->GetData(&data);
- if (status != storage::Status::OK) {
- FXL_LOG(ERROR) << "Unable to read object data, aborting: " << status;
- // We do getData first so that we can continue in case of error
- // without having written anything in the flatbuffer.
- continue;
- }
- flatbuffers::Offset<Data> fb_data =
- CreateData(*buffer, convert::ToFlatBufferVector(buffer, data));
- ObjectSyncStatus sync_status = object_response.is_synced
- ? ObjectSyncStatus_SYNCED_TO_CLOUD
- : ObjectSyncStatus_UNSYNCED;
- fb_objects.emplace_back(CreateObject(
- *buffer, fb_object_id, ObjectStatus_OK, fb_data, sync_status));
- } else {
- fb_objects.emplace_back(
- CreateObject(*buffer, fb_object_id, ObjectStatus_UNKNOWN_OBJECT));
- }
- }
- flatbuffers::Offset<ObjectResponse> object_response =
- CreateObjectResponse(*buffer, buffer->CreateVector(fb_objects));
- flatbuffers::Offset<Response> response =
- CreateResponse(*buffer, ResponseStatus_OK, namespace_page_id,
- ResponseMessage_ObjectResponse, object_response.Union());
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Response, response.Union());
- buffer->Finish(message);
-}
-
-void PageCommunicatorImpl::MarkSyncedToPeer(
- fit::function<void(storage::Status)> callback) {
- if (marked_as_synced_to_peer_) {
- callback(storage::Status::OK);
- return;
- }
- storage_->MarkSyncedToPeer(
- [this, callback = std::move(callback)](storage::Status status) {
- if (status == storage::Status::OK) {
- marked_as_synced_to_peer_ = true;
- }
- callback(status);
- });
-}
-
-} // namespace p2p_sync
diff --git a/bin/ledger/p2p_sync/impl/page_communicator_impl.h b/bin/ledger/p2p_sync/impl/page_communicator_impl.h
deleted file mode 100644
index 025c049..0000000
--- a/bin/ledger/p2p_sync/impl/page_communicator_impl.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_PAGE_COMMUNICATOR_IMPL_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_PAGE_COMMUNICATOR_IMPL_H_
-
-#include <flatbuffers/flatbuffers.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/callback/cancellable.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/coroutine/coroutine_manager.h"
-#include "peridot/bin/ledger/p2p_provider/public/types.h"
-#include "peridot/bin/ledger/p2p_sync/impl/commit_batch.h"
-#include "peridot/bin/ledger/p2p_sync/impl/device_mesh.h"
-#include "peridot/bin/ledger/p2p_sync/impl/message_generated.h"
-#include "peridot/bin/ledger/p2p_sync/impl/message_holder.h"
-#include "peridot/bin/ledger/p2p_sync/public/page_communicator.h"
-#include "peridot/bin/ledger/storage/public/commit_watcher.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/page_sync_client.h"
-#include "peridot/bin/ledger/storage/public/page_sync_delegate.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace p2p_sync {
-class PageCommunicatorImplInspectorForTest;
-
-class PageCommunicatorImpl : public PageCommunicator,
- public storage::PageSyncDelegate,
- public storage::CommitWatcher,
- public CommitBatch::Delegate {
- public:
- PageCommunicatorImpl(coroutine::CoroutineService* coroutine_service,
- storage::PageStorage* storage,
- storage::PageSyncClient* sync_client,
- std::string namespace_id, std::string page_id,
- DeviceMesh* mesh);
- ~PageCommunicatorImpl() override;
-
- void set_on_delete(fit::closure on_delete);
-
- // OnDeviceChange is called each time a device connects or unconnects.
- void OnDeviceChange(fxl::StringView remote_device,
- p2p_provider::DeviceChangeType change_type);
-
- // Called when a new request arrived for this page from device |source|.
- void OnNewRequest(fxl::StringView source, MessageHolder<Request> message);
-
- // Called when a new response arrived for this page from device |source|.
- void OnNewResponse(fxl::StringView source, MessageHolder<Response> message);
-
- // PageCommunicator:
- void Start() override;
-
- // storage::PageSyncDelegate:
- void GetObject(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) override;
-
- // storage::CommitWatcher:
- void OnNewCommits(
- const std::vector<std::unique_ptr<const storage::Commit>>& commits,
- storage::ChangeSource source) override;
-
- private:
- friend class PageCommunicatorImplInspectorForTest;
- class PendingObjectRequestHolder;
- struct ObjectResponseHolder;
-
- void RequestCommits(fxl::StringView device,
- std::vector<storage::CommitId> ids) override;
-
- // These methods build the flatbuffer message corresponding to their name.
- void BuildWatchStartBuffer(flatbuffers::FlatBufferBuilder* buffer);
- void BuildWatchStopBuffer(flatbuffers::FlatBufferBuilder* buffer);
- void BuildObjectRequestBuffer(flatbuffers::FlatBufferBuilder* buffer,
- storage::ObjectIdentifier object_identifier);
- void BuildCommitBuffer(
- flatbuffers::FlatBufferBuilder* buffer,
- const std::vector<std::unique_ptr<const storage::Commit>>& commits);
- void BuildObjectResponseBuffer(
- flatbuffers::FlatBufferBuilder* buffer,
- std::list<ObjectResponseHolder> object_responses);
-
- // Processes an incoming CommitRequest object from device |source|.
- void ProcessCommitRequest(std::string source,
- MessageHolder<CommitRequest> request);
-
- // Builds a CommitResponse buffer in response to an incoming CommitRequest.
- // This is different from |BuildCommitBuffer| which builds CommitResponse for
- // a remote watcher. In particular, |BuildCommitBuffer|'s commits always
- // exist. In this method, the pair's second element for a commit will be null
- // if the commit does not exist on this device.
- void BuildCommitResponseBuffer(
- flatbuffers::FlatBufferBuilder* buffer,
- const std::vector<
- std::pair<storage::CommitId, std::unique_ptr<const storage::Commit>>>&
- commits);
-
- // Processes an incoming ObjectRequest object.
- void ProcessObjectRequest(fxl::StringView source,
- MessageHolder<ObjectRequest> request);
-
- // Marks the PageStorage as synced to a peer. If successful, on the following
- // call to MarkSyncedToPeer, the given |callback| will be called immediately.
- void MarkSyncedToPeer(fit::function<void(storage::Status)> callback);
-
- // Map of pending requests for objects.
- callback::AutoCleanableMap<storage::ObjectIdentifier,
- PendingObjectRequestHolder>
- pending_object_requests_;
- // Map of pending commit batch insertions.
- callback::AutoCleanableMap<std::string, CommitBatch,
- convert::StringViewComparator>
- pending_commit_batches_;
- // List of devices we know are interested in this page.
- std::set<std::string, convert::StringViewComparator> interested_devices_;
- // List of devices we know are not interested in this page.
- std::set<std::string, convert::StringViewComparator> not_interested_devices_;
- fit::closure on_delete_;
- bool marked_as_synced_to_peer_ = false;
- bool started_ = false;
- bool in_destructor_ = false;
-
- // Commit upload: we queue commits to upload here while we check if a
- // conflict exists. If it exist, we wait until it is resolved before
- // uploading.
- std::vector<std::unique_ptr<const storage::Commit>> commits_to_upload_;
-
- coroutine::CoroutineManager coroutine_manager_;
- const std::string namespace_id_;
- const std::string page_id_;
- DeviceMesh* const mesh_;
- storage::PageStorage* const storage_;
- storage::PageSyncClient* const sync_client_;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<PageCommunicatorImpl> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageCommunicatorImpl);
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_PAGE_COMMUNICATOR_IMPL_H_
diff --git a/bin/ledger/p2p_sync/impl/page_communicator_impl_unittest.cc b/bin/ledger/p2p_sync/impl/page_communicator_impl_unittest.cc
deleted file mode 100644
index 0481681..0000000
--- a/bin/ledger/p2p_sync/impl/page_communicator_impl_unittest.cc
+++ /dev/null
@@ -1,1239 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_sync/impl/page_communicator_impl.h"
-
-#include <algorithm>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <lib/async/cpp/task.h>
-#include <lib/fit/function.h>
-
-// gtest matchers are in gmock and we cannot include the specific header file
-// directly as it is private to the library.
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include "gmock/gmock.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/p2p_sync/impl/device_mesh.h"
-#include "peridot/bin/ledger/storage/fake/fake_object.h"
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-#include "peridot/lib/convert/convert.h"
-
-using testing::IsEmpty;
-
-namespace p2p_sync {
-namespace {
-
-// Creates a dummy object identifier.
-// |object_digest| need not be valid (wrt. internal storage constraints) as it
-// is only used as an opaque identifier for p2p.
-storage::ObjectIdentifier MakeObjectIdentifier(std::string object_digest) {
- return storage::ObjectIdentifier(
- 0, 0, storage::ObjectDigest(std::move(object_digest)));
-}
-
-class FakeCommit : public storage::CommitEmptyImpl {
- public:
- FakeCommit(std::string id, std::string data,
- std::vector<storage::CommitId> parents = {})
- : id_(std::move(id)),
- data_(std::move(data)),
- parents_(std::move(parents)) {}
-
- const storage::CommitId& GetId() const override { return id_; }
-
- std::vector<storage::CommitIdView> GetParentIds() const override {
- std::vector<storage::CommitIdView> parent_ids;
- for (const storage::CommitId& id : parents_) {
- parent_ids.emplace_back(id);
- }
- return parent_ids;
- }
-
- fxl::StringView GetStorageBytes() const override { return data_; }
-
- std::unique_ptr<const storage::Commit> Clone() const override {
- return std::make_unique<FakeCommit>(id_, data_);
- }
-
- private:
- const std::string id_;
- const std::string data_;
- const std::vector<storage::CommitId> parents_;
-};
-
-class FakePageStorage : public storage::PageStorageEmptyImpl {
- public:
- explicit FakePageStorage(async_dispatcher_t* dispatcher, std::string page_id)
- : dispatcher_(dispatcher), page_id_(std::move(page_id)) {}
- ~FakePageStorage() override {}
-
- storage::PageId GetId() override { return page_id_; }
-
- void GetHeadCommitIds(
- fit::function<void(storage::Status, std::vector<storage::CommitId>)>
- callback) override {
- callback(storage::Status::OK, {"commit_id"});
- }
-
- const FakeCommit& AddCommit(std::string id, std::string data) {
- auto commit =
- commits_.emplace(std::piecewise_construct, std::forward_as_tuple(id),
- std::forward_as_tuple(id, std::move(data)));
- return commit.first->second;
- }
-
- void GetCommit(storage::CommitIdView commit_id,
- fit::function<void(storage::Status,
- std::unique_ptr<const storage::Commit>)>
- callback) override {
- auto it = commits_.find(commit_id);
- if (it == commits_.end()) {
- callback(storage::Status::NOT_FOUND, nullptr);
- return;
- }
- callback(storage::Status::OK, it->second.Clone());
- }
-
- void GetPiece(storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status,
- std::unique_ptr<const storage::Object>)>
- callback) override {
- async::PostTask(dispatcher_, [this, object_identifier,
- callback = std::move(callback)]() {
- const auto& it = objects_.find(object_identifier);
- if (it == objects_.end()) {
- callback(storage::Status::NOT_FOUND, nullptr);
- return;
- }
- callback(storage::Status::OK, std::make_unique<storage::fake::FakeObject>(
- object_identifier, it->second));
- });
- }
-
- void SetPiece(storage::ObjectIdentifier object_identifier,
- std::string contents, bool is_synced = false) {
- objects_[object_identifier] = std::move(contents);
- if (is_synced) {
- synced_objects_.insert(std::move(object_identifier));
- }
- }
-
- void IsPieceSynced(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status, bool)> callback) override {
- async::PostTask(dispatcher_, [this, object_identifier,
- callback = std::move(callback)]() {
- const auto& it = objects_.find(object_identifier);
- if (it == objects_.end()) {
- callback(storage::Status::NOT_FOUND, false);
- return;
- }
- callback(storage::Status::OK, synced_objects_.find(object_identifier) !=
- synced_objects_.end());
- });
- }
-
- void AddCommitsFromSync(
- std::vector<storage::PageStorage::CommitIdAndBytes> ids_and_bytes,
- const storage::ChangeSource /*source*/,
- fit::function<void(storage::Status, std::vector<storage::CommitId>)>
- callback) override {
- commits_from_sync_.emplace_back(
- std::piecewise_construct,
- std::forward_as_tuple(std::move(ids_and_bytes)),
- std::forward_as_tuple(std::move(callback)));
- }
-
- storage::Status AddCommitWatcher(storage::CommitWatcher* watcher) override {
- FXL_DCHECK(!watcher_);
- watcher_ = watcher;
- return storage::Status::OK;
- }
-
- void MarkSyncedToPeer(
- fit::function<void(storage::Status)> callback) override {
- callback(mark_synced_to_peer_status);
- }
-
- storage::CommitWatcher* watcher_ = nullptr;
- std::vector<std::pair<
- std::vector<storage::PageStorage::CommitIdAndBytes>,
- fit::function<void(storage::Status, std::vector<storage::CommitId>)>>>
- commits_from_sync_;
- storage::Status mark_synced_to_peer_status = storage::Status::OK;
-
- private:
- async_dispatcher_t* const dispatcher_;
- const std::string page_id_;
- std::map<storage::ObjectIdentifier, std::string> objects_;
- std::set<storage::ObjectIdentifier> synced_objects_;
- std::map<storage::CommitId, FakeCommit, convert::StringViewComparator>
- commits_;
-};
-
-class FakeDeviceMesh : public DeviceMesh {
- public:
- FakeDeviceMesh() {}
- ~FakeDeviceMesh() override {}
-
- DeviceSet GetDeviceList() override { return devices_; }
-
- void Send(fxl::StringView device_name,
- convert::ExtendedStringView data) override {
- messages_.emplace_back(
- std::forward_as_tuple(device_name.ToString(), data.ToString()));
- }
-
- DeviceSet devices_;
- std::vector<std::pair<std::string, std::string>> messages_;
-};
-
-void BuildWatchStartBuffer(flatbuffers::FlatBufferBuilder* buffer,
- fxl::StringView namespace_id,
- fxl::StringView page_id) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id),
- convert::ToFlatBufferVector(buffer, page_id));
- flatbuffers::Offset<Request> request = CreateRequest(
- *buffer, namespace_page_id, RequestMessage_WatchStartRequest);
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Request, request.Union());
- buffer->Finish(message);
-}
-
-void BuildWatchStopBuffer(flatbuffers::FlatBufferBuilder* buffer,
- fxl::StringView namespace_id,
- fxl::StringView page_id) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id),
- convert::ToFlatBufferVector(buffer, page_id));
- flatbuffers::Offset<Request> request = CreateRequest(
- *buffer, namespace_page_id, RequestMessage_WatchStopRequest);
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Request, request.Union());
- buffer->Finish(message);
-}
-
-void BuildObjectRequestBuffer(
- flatbuffers::FlatBufferBuilder* buffer, fxl::StringView namespace_id,
- fxl::StringView page_id,
- std::vector<storage::ObjectIdentifier> object_ids) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id),
- convert::ToFlatBufferVector(buffer, page_id));
- std::vector<flatbuffers::Offset<ObjectId>> fb_object_ids;
- fb_object_ids.reserve(object_ids.size());
- for (const storage::ObjectIdentifier& object_id : object_ids) {
- fb_object_ids.emplace_back(CreateObjectId(
- *buffer, object_id.key_index(), object_id.deletion_scope_id(),
- convert::ToFlatBufferVector(buffer,
- object_id.object_digest().Serialize())));
- }
- flatbuffers::Offset<ObjectRequest> object_request =
- CreateObjectRequest(*buffer, buffer->CreateVector(fb_object_ids));
- flatbuffers::Offset<Request> fb_request =
- CreateRequest(*buffer, namespace_page_id, RequestMessage_ObjectRequest,
- object_request.Union());
- flatbuffers::Offset<Message> fb_message =
- CreateMessage(*buffer, MessageUnion_Request, fb_request.Union());
- buffer->Finish(fb_message);
-}
-
-void BuildObjectResponseBuffer(
- flatbuffers::FlatBufferBuilder* buffer, fxl::StringView namespace_id,
- fxl::StringView page_id,
- std::vector<std::tuple<storage::ObjectIdentifier, std::string, bool>>
- data) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id),
- convert::ToFlatBufferVector(buffer, page_id));
- std::vector<flatbuffers::Offset<Object>> fb_objects;
- for (const auto& object_tuple : data) {
- const storage::ObjectIdentifier& object_identifier =
- std::get<0>(object_tuple);
- const std::string& data = std::get<1>(object_tuple);
- bool is_synced = std::get<2>(object_tuple);
-
- flatbuffers::Offset<ObjectId> fb_object_id = CreateObjectId(
- *buffer, object_identifier.key_index(),
- object_identifier.deletion_scope_id(),
- convert::ToFlatBufferVector(
- buffer, object_identifier.object_digest().Serialize()));
- if (!data.empty()) {
- flatbuffers::Offset<Data> fb_data =
- CreateData(*buffer, convert::ToFlatBufferVector(buffer, data));
- fb_objects.emplace_back(
- CreateObject(*buffer, fb_object_id, ObjectStatus_OK, fb_data,
- is_synced ? ObjectSyncStatus_SYNCED_TO_CLOUD
- : ObjectSyncStatus_UNSYNCED));
- } else {
- fb_objects.emplace_back(
- CreateObject(*buffer, fb_object_id, ObjectStatus_UNKNOWN_OBJECT));
- }
- }
- flatbuffers::Offset<ObjectResponse> object_response =
- CreateObjectResponse(*buffer, buffer->CreateVector(fb_objects));
- flatbuffers::Offset<Response> response =
- CreateResponse(*buffer, ResponseStatus_OK, namespace_page_id,
- ResponseMessage_ObjectResponse, object_response.Union());
- flatbuffers::Offset<Message> message =
- CreateMessage(*buffer, MessageUnion_Response, response.Union());
- buffer->Finish(message);
-}
-
-void BuildCommitRequestBuffer(flatbuffers::FlatBufferBuilder* buffer,
- fxl::StringView namespace_id,
- fxl::StringView page_id,
- std::vector<storage::CommitId> commit_ids) {
- flatbuffers::Offset<NamespacePageId> namespace_page_id =
- CreateNamespacePageId(*buffer,
- convert::ToFlatBufferVector(buffer, namespace_id),
- convert::ToFlatBufferVector(buffer, page_id));
- std::vector<flatbuffers::Offset<CommitId>> fb_commit_ids;
- fb_commit_ids.reserve(commit_ids.size());
- for (const storage::CommitId& commit_id : commit_ids) {
- fb_commit_ids.emplace_back(CreateCommitId(
- *buffer, convert::ToFlatBufferVector(buffer, commit_id)));
- }
- flatbuffers::Offset<CommitRequest> commit_request =
- CreateCommitRequest(*buffer, buffer->CreateVector(fb_commit_ids));
- flatbuffers::Offset<Request> fb_request =
- CreateRequest(*buffer, namespace_page_id, RequestMessage_CommitRequest,
- commit_request.Union());
- flatbuffers::Offset<Message> fb_message =
- CreateMessage(*buffer, MessageUnion_Request, fb_request.Union());
- buffer->Finish(fb_message);
-}
-
-class PageCommunicatorImplTest : public gtest::TestLoopFixture {
- public:
- PageCommunicatorImplTest() {}
- ~PageCommunicatorImplTest() override {}
-
- protected:
- void SetUp() override { ::testing::Test::SetUp(); }
-
- coroutine::CoroutineServiceImpl coroutine_service_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageCommunicatorImplTest);
-};
-
-TEST_F(PageCommunicatorImplTest, ConnectToExistingMesh) {
- FakeDeviceMesh mesh;
- mesh.devices_.emplace("device2");
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
-
- EXPECT_TRUE(mesh.messages_.empty());
-
- page_communicator.Start();
-
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[0].second.data()),
- mesh.messages_[0].second.size());
- if (!VerifyMessageBuffer(verifier)) {
- // Wrong serialization, abort.
- FXL_LOG(ERROR) << "The message received is malformed.";
- return;
- };
- const Message* message = GetMessage(mesh.messages_[0].second.data());
- ASSERT_EQ(MessageUnion_Request, message->message_type());
- const Request* request = static_cast<const Request*>(message->message());
- const NamespacePageId* namespace_page_id = request->namespace_page();
- EXPECT_EQ("ledger",
- convert::ExtendedStringView(namespace_page_id->namespace_id()));
- EXPECT_EQ("page", convert::ExtendedStringView(namespace_page_id->page_id()));
- EXPECT_EQ(RequestMessage_WatchStartRequest, request->request_type());
-}
-
-TEST_F(PageCommunicatorImplTest, ConnectToNewMeshParticipant) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- EXPECT_TRUE(mesh.messages_.empty());
-
- mesh.devices_.emplace("device2");
- page_communicator.OnDeviceChange("device2",
- p2p_provider::DeviceChangeType::NEW);
-
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[0].second.data()),
- mesh.messages_[0].second.size());
- if (!VerifyMessageBuffer(verifier)) {
- // Wrong serialization, abort.
- FXL_LOG(ERROR) << "The message received is malformed.";
- return;
- };
- const Message* message = GetMessage(mesh.messages_[0].second.data());
- ASSERT_EQ(MessageUnion_Request, message->message_type());
- const Request* request = static_cast<const Request*>(message->message());
- const NamespacePageId* namespace_page_id = request->namespace_page();
- EXPECT_EQ("ledger",
- convert::ExtendedStringView(namespace_page_id->namespace_id()));
- EXPECT_EQ("page", convert::ExtendedStringView(namespace_page_id->page_id()));
- EXPECT_EQ(RequestMessage_WatchStartRequest, request->request_type());
-}
-
-TEST_F(PageCommunicatorImplTest, GetObject) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> new_device_message(convert::ToStringView(buffer),
- &GetMessage);
- page_communicator.OnNewRequest(
- "device2", std::move(new_device_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data;
- page_communicator.GetObject(
- MakeObjectIdentifier("foo"),
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[0].second.data()),
- mesh.messages_[0].second.size());
- ASSERT_TRUE(VerifyMessageBuffer(verifier));
-
- // Verify the message sent to request the object.
- const Message* message = GetMessage(mesh.messages_[0].second.data());
- ASSERT_EQ(MessageUnion_Request, message->message_type());
- const Request* request = static_cast<const Request*>(message->message());
- const NamespacePageId* namespace_page_id = request->namespace_page();
- EXPECT_EQ("ledger",
- convert::ExtendedStringView(namespace_page_id->namespace_id()));
- EXPECT_EQ("page", convert::ExtendedStringView(namespace_page_id->page_id()));
- EXPECT_EQ(RequestMessage_ObjectRequest, request->request_type());
- const ObjectRequest* object_request =
- static_cast<const ObjectRequest*>(request->request());
- EXPECT_EQ(1u, object_request->object_ids()->size());
- EXPECT_EQ(0u, object_request->object_ids()->begin()->key_index());
- EXPECT_EQ(0u, object_request->object_ids()->begin()->deletion_scope_id());
- EXPECT_EQ("foo", convert::ExtendedStringView(
- object_request->object_ids()->begin()->digest()));
-}
-
-TEST_F(PageCommunicatorImplTest, DontGetObjectsIfMarkPageSyncedToPeerFailed) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> new_device_message(convert::ToStringView(buffer),
- &GetMessage);
- // If storage fails to mark the page as synced to a peer, the mesh should not
- // be updated.
- storage.mark_synced_to_peer_status = storage::Status::IO_ERROR;
- page_communicator.OnNewRequest(
- "device2", std::move(new_device_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data;
- page_communicator.GetObject(
- MakeObjectIdentifier("foo"),
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- EXPECT_THAT(mesh.messages_, IsEmpty());
-}
-
-TEST_F(PageCommunicatorImplTest, ObjectRequest) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- storage.SetPiece(MakeObjectIdentifier("object_digest"), "some data");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- // Send request to PageCommunicator. We request two objects: |object_digest|
- // and |object_digest2|. Only |object_digest| will be present in storage.
- flatbuffers::FlatBufferBuilder request_buffer;
- BuildObjectRequestBuffer(&request_buffer, "ledger", "page",
- {MakeObjectIdentifier("object_digest"),
- MakeObjectIdentifier("object_digest2")});
- MessageHolder<Message> request_message(convert::ToStringView(request_buffer),
- &GetMessage);
- page_communicator.OnNewRequest(
- "device2", std::move(request_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- RunLoopUntilIdle();
-
- // Verify the response.
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[0].second.data()),
- mesh.messages_[0].second.size());
- ASSERT_TRUE(VerifyMessageBuffer(verifier));
-
- const Message* reply_message = GetMessage(mesh.messages_[0].second.data());
- ASSERT_EQ(MessageUnion_Response, reply_message->message_type());
- const Response* response =
- static_cast<const Response*>(reply_message->message());
- const NamespacePageId* response_namespace_page_id =
- response->namespace_page();
- EXPECT_EQ("ledger", convert::ExtendedStringView(
- response_namespace_page_id->namespace_id()));
- EXPECT_EQ("page",
- convert::ExtendedStringView(response_namespace_page_id->page_id()));
- EXPECT_EQ(ResponseMessage_ObjectResponse, response->response_type());
- const ObjectResponse* object_response =
- static_cast<const ObjectResponse*>(response->response());
- ASSERT_EQ(2u, object_response->objects()->size());
- auto it = object_response->objects()->begin();
- EXPECT_EQ("object_digest", convert::ExtendedStringView(it->id()->digest()));
- EXPECT_EQ(ObjectStatus_OK, it->status());
- EXPECT_EQ("some data", convert::ExtendedStringView(it->data()->bytes()));
- EXPECT_EQ(ObjectSyncStatus_UNSYNCED, it->sync_status());
- it++;
- EXPECT_EQ("object_digest2", convert::ExtendedStringView(it->id()->digest()));
- EXPECT_EQ(ObjectStatus_UNKNOWN_OBJECT, it->status());
-}
-
-TEST_F(PageCommunicatorImplTest, ObjectRequestSynced) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- storage.SetPiece(MakeObjectIdentifier("object_digest"), "some data", true);
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- // Send request to PageCommunicator. We request two objects: |object_digest|
- // and |object_digest2|. Only |object_digest| will be present in storage.
- flatbuffers::FlatBufferBuilder request_buffer;
- BuildObjectRequestBuffer(&request_buffer, "ledger", "page",
- {MakeObjectIdentifier("object_digest")});
- MessageHolder<Message> request_message(convert::ToStringView(request_buffer),
- &GetMessage);
- page_communicator.OnNewRequest(
- "device2", std::move(request_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- RunLoopUntilIdle();
-
- // Verify the response.
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[0].second.data()),
- mesh.messages_[0].second.size());
- ASSERT_TRUE(VerifyMessageBuffer(verifier));
-
- const Message* reply_message = GetMessage(mesh.messages_[0].second.data());
- ASSERT_EQ(MessageUnion_Response, reply_message->message_type());
- const Response* response =
- static_cast<const Response*>(reply_message->message());
- const NamespacePageId* response_namespace_page_id =
- response->namespace_page();
- EXPECT_EQ("ledger", convert::ExtendedStringView(
- response_namespace_page_id->namespace_id()));
- EXPECT_EQ("page",
- convert::ExtendedStringView(response_namespace_page_id->page_id()));
- EXPECT_EQ(ResponseMessage_ObjectResponse, response->response_type());
- const ObjectResponse* object_response =
- static_cast<const ObjectResponse*>(response->response());
- ASSERT_EQ(1u, object_response->objects()->size());
- auto it = object_response->objects()->begin();
- EXPECT_EQ("object_digest", convert::ExtendedStringView(it->id()->digest()));
- EXPECT_EQ(ObjectStatus_OK, it->status());
- EXPECT_EQ("some data", convert::ExtendedStringView(it->data()->bytes()));
- EXPECT_EQ(ObjectSyncStatus_SYNCED_TO_CLOUD, it->sync_status());
-}
-
-TEST_F(PageCommunicatorImplTest, GetObjectProcessResponseSuccess) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> new_device_message(convert::ToStringView(buffer),
- &GetMessage);
- page_communicator.OnNewRequest(
- "device2", std::move(new_device_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data;
- page_communicator.GetObject(
- MakeObjectIdentifier("foo"),
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::FlatBufferBuilder response_buffer;
- BuildObjectResponseBuffer(
- &response_buffer, "ledger", "page",
- {std::make_tuple(MakeObjectIdentifier("foo"), "foo_data", false),
- std::make_tuple(MakeObjectIdentifier("bar"), "bar_data", false)});
- MessageHolder<Message> response_message(
- convert::ToStringView(response_buffer), &GetMessage);
- page_communicator.OnNewResponse(
- "device2", std::move(response_message)
- .TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- }));
-
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ("foo_data", data->Get());
- EXPECT_EQ(storage::IsObjectSynced::NO, is_object_synced);
-}
-
-TEST_F(PageCommunicatorImplTest, GetObjectProcessResponseSynced) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> new_device_message(convert::ToStringView(buffer),
- &GetMessage);
- page_communicator.OnNewRequest(
- "device2", std::move(new_device_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data;
- page_communicator.GetObject(
- MakeObjectIdentifier("foo"),
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::FlatBufferBuilder response_buffer;
- BuildObjectResponseBuffer(
- &response_buffer, "ledger", "page",
- {std::make_tuple(MakeObjectIdentifier("foo"), "foo_data", true)});
- MessageHolder<Message> response_message(
- convert::ToStringView(response_buffer), &GetMessage);
- page_communicator.OnNewResponse(
- "device2", std::move(response_message)
- .TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- }));
-
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ("foo_data", data->Get());
- EXPECT_EQ(storage::IsObjectSynced::YES, is_object_synced);
-}
-
-TEST_F(PageCommunicatorImplTest, GetObjectProcessResponseFail) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> message(convert::ToStringView(buffer), &GetMessage);
- page_communicator.OnNewRequest(
- "device2",
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data;
- page_communicator.GetObject(
- MakeObjectIdentifier("foo"),
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::FlatBufferBuilder response_buffer;
- BuildObjectResponseBuffer(
- &response_buffer, "ledger", "page",
- {std::make_tuple(MakeObjectIdentifier("foo"), "", false)});
- MessageHolder<Message> response_message(
- convert::ToStringView(response_buffer), &GetMessage);
- page_communicator.OnNewResponse(
- "device2", std::move(response_message)
- .TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- }));
-
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::NOT_FOUND, status);
- EXPECT_FALSE(data);
-}
-
-TEST_F(PageCommunicatorImplTest, GetObjectProcessResponseMultiDeviceSuccess) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> message(convert::ToStringView(buffer), &GetMessage);
- page_communicator.OnNewRequest(
- "device2",
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
- message = MessageHolder<Message>(convert::ToStringView(buffer), &GetMessage);
- page_communicator.OnNewRequest(
- "device3",
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data;
- page_communicator.GetObject(
- MakeObjectIdentifier("foo"),
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- EXPECT_EQ(2u, mesh.messages_.size());
-
- flatbuffers::FlatBufferBuilder response_buffer_1;
- BuildObjectResponseBuffer(
- &response_buffer_1, "ledger", "page",
- {std::make_tuple(MakeObjectIdentifier("foo"), "", false)});
- MessageHolder<Message> message_1(convert::ToStringView(response_buffer_1),
- &GetMessage);
- page_communicator.OnNewResponse(
- "device2",
- std::move(message_1).TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- }));
- EXPECT_FALSE(called);
-
- flatbuffers::FlatBufferBuilder response_buffer_2;
- BuildObjectResponseBuffer(
- &response_buffer_2, "ledger", "page",
- {std::make_tuple(MakeObjectIdentifier("foo"), "foo_data", false)});
- MessageHolder<Message> message_2(convert::ToStringView(response_buffer_2),
- &GetMessage);
- page_communicator.OnNewResponse(
- "device3",
- std::move(message_2).TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- }));
-
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::OK, status);
- EXPECT_EQ("foo_data", data->Get());
- EXPECT_EQ(storage::ChangeSource::P2P, source);
- EXPECT_EQ(storage::IsObjectSynced::NO, is_object_synced);
-}
-
-TEST_F(PageCommunicatorImplTest, GetObjectProcessResponseMultiDeviceFail) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> message(convert::ToStringView(buffer), &GetMessage);
- page_communicator.OnNewRequest(
- "device2",
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
- message = MessageHolder<Message>(convert::ToStringView(buffer), &GetMessage);
- page_communicator.OnNewRequest(
- "device3",
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- bool called;
- storage::Status status;
- storage::ChangeSource source;
- storage::IsObjectSynced is_object_synced;
- std::unique_ptr<storage::DataSource::DataChunk> data;
- page_communicator.GetObject(
- MakeObjectIdentifier("foo"),
- callback::Capture(callback::SetWhenCalled(&called), &status, &source,
- &is_object_synced, &data));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- EXPECT_EQ(2u, mesh.messages_.size());
-
- flatbuffers::FlatBufferBuilder response_buffer_1;
- BuildObjectResponseBuffer(
- &response_buffer_1, "ledger", "page",
- {std::make_tuple(MakeObjectIdentifier("foo"), "", false)});
- MessageHolder<Message> message_1(convert::ToStringView(response_buffer_1),
- &GetMessage);
- page_communicator.OnNewResponse(
- "device2",
- std::move(message_1).TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- }));
- EXPECT_FALSE(called);
-
- flatbuffers::FlatBufferBuilder response_buffer_2;
- BuildObjectResponseBuffer(
- &response_buffer_2, "ledger", "page",
- {std::make_tuple(MakeObjectIdentifier("foo"), "", false)});
- MessageHolder<Message> message_2(convert::ToStringView(response_buffer_2),
- &GetMessage);
- page_communicator.OnNewResponse(
- "device3",
- std::move(message_2).TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- }));
-
- EXPECT_TRUE(called);
- EXPECT_EQ(storage::Status::NOT_FOUND, status);
- EXPECT_FALSE(data);
-}
-
-TEST_F(PageCommunicatorImplTest, CommitUpdate) {
- FakeDeviceMesh mesh;
- FakePageStorage storage_1(dispatcher(), "page");
- PageCommunicatorImpl page_communicator_1(&coroutine_service_, &storage_1,
- &storage_1, "ledger", "page", &mesh);
- page_communicator_1.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> message(convert::ToStringView(buffer), &GetMessage);
- page_communicator_1.OnNewRequest(
- "device2",
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
- RunLoopUntilIdle();
-
- FakePageStorage storage_2(dispatcher(), "page");
- PageCommunicatorImpl page_communicator_2(&coroutine_service_, &storage_2,
- &storage_2, "ledger", "page", &mesh);
- page_communicator_2.Start();
-
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.emplace_back(std::make_unique<FakeCommit>("id 1", "data 1"));
- commits.emplace_back(std::make_unique<FakeCommit>("id 2", "data 2"));
- ASSERT_NE(nullptr, storage_1.watcher_);
- storage_1.watcher_->OnNewCommits(commits, storage::ChangeSource::CLOUD);
-
- RunLoopUntilIdle();
- // No new message is sent on commits from CLOUD.
- ASSERT_EQ(0u, mesh.messages_.size());
-
- storage_1.watcher_->OnNewCommits(commits, storage::ChangeSource::P2P);
-
- RunLoopUntilIdle();
- // No new message is sent on commits from P2P either.
- ASSERT_EQ(0u, mesh.messages_.size());
-
- storage_1.watcher_->OnNewCommits(commits, storage::ChangeSource::LOCAL);
- RunLoopUntilIdle();
-
- // Local commit: a message is sent.
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[0].second.data()),
- mesh.messages_[0].second.size());
- ASSERT_TRUE(VerifyMessageBuffer(verifier));
-
- MessageHolder<Message> reply_message(mesh.messages_[0].second, &GetMessage);
- ASSERT_EQ(MessageUnion_Response, reply_message->message_type());
- MessageHolder<Response> response =
- std::move(reply_message).TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- });
- const NamespacePageId* response_namespace_page_id =
- response->namespace_page();
- EXPECT_EQ("ledger", convert::ExtendedStringView(
- response_namespace_page_id->namespace_id()));
- EXPECT_EQ("page",
- convert::ExtendedStringView(response_namespace_page_id->page_id()));
- EXPECT_EQ(ResponseMessage_CommitResponse, response->response_type());
-
- // Send it to the other side.
- page_communicator_2.OnNewResponse("device1", std::move(response));
- RunLoopUntilIdle();
-
- // The other side's storage has the commit.
- ASSERT_EQ(1u, storage_2.commits_from_sync_.size());
- ASSERT_EQ(2u, storage_2.commits_from_sync_[0].first.size());
- EXPECT_EQ("id 1", storage_2.commits_from_sync_[0].first[0].id);
- EXPECT_EQ("data 1", storage_2.commits_from_sync_[0].first[0].bytes);
- EXPECT_EQ("id 2", storage_2.commits_from_sync_[0].first[1].id);
- EXPECT_EQ("data 2", storage_2.commits_from_sync_[0].first[1].bytes);
-
- // Verify we don't crash on response from storage
- storage_2.commits_from_sync_[0].second(storage::Status::OK, {});
- RunLoopUntilIdle();
-}
-
-TEST_F(PageCommunicatorImplTest, GetObjectDisconnect) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> message(convert::ToStringView(buffer), &GetMessage);
- page_communicator.OnNewRequest(
- "device2",
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- bool called1, called2, called3, called4;
- storage::Status status1, status2, status3, status4;
- storage::ChangeSource source1, source2, source3, source4;
- storage::IsObjectSynced is_object_synced1, is_object_synced2,
- is_object_synced3, is_object_synced4;
- std::unique_ptr<storage::DataSource::DataChunk> data1, data2, data3, data4;
- page_communicator.GetObject(
- MakeObjectIdentifier("foo1"),
- callback::Capture(callback::SetWhenCalled(&called1), &status1, &source1,
- &is_object_synced1, &data1));
- page_communicator.GetObject(
- MakeObjectIdentifier("foo2"),
- callback::Capture(callback::SetWhenCalled(&called2), &status2, &source2,
- &is_object_synced2, &data2));
- page_communicator.GetObject(
- MakeObjectIdentifier("foo3"),
- callback::Capture(callback::SetWhenCalled(&called3), &status3, &source3,
- &is_object_synced3, &data3));
- page_communicator.GetObject(
- MakeObjectIdentifier("foo4"),
- callback::Capture(callback::SetWhenCalled(&called4), &status4, &source4,
- &is_object_synced4, &data4));
- RunLoopUntilIdle();
- EXPECT_FALSE(called1);
- EXPECT_FALSE(called2);
- EXPECT_FALSE(called3);
- EXPECT_FALSE(called4);
- EXPECT_EQ(4u, mesh.messages_.size());
-
- flatbuffers::FlatBufferBuilder stop_buffer;
- BuildWatchStopBuffer(&stop_buffer, "ledger", "page");
- MessageHolder<Message> watch_stop_message(convert::ToStringView(stop_buffer),
- &GetMessage);
- page_communicator.OnNewRequest(
- "device2", std::move(watch_stop_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
- RunLoopUntilIdle();
-
- // All requests are terminated with a not found status.
- EXPECT_TRUE(called1);
- EXPECT_EQ(storage::Status::NOT_FOUND, status1);
- EXPECT_EQ(storage::ChangeSource::P2P, source1);
- EXPECT_FALSE(data1);
-
- EXPECT_TRUE(called2);
- EXPECT_EQ(storage::Status::NOT_FOUND, status2);
- EXPECT_EQ(storage::ChangeSource::P2P, source2);
- EXPECT_FALSE(data2);
-
- EXPECT_TRUE(called3);
- EXPECT_EQ(storage::Status::NOT_FOUND, status3);
- EXPECT_EQ(storage::ChangeSource::P2P, source3);
- EXPECT_FALSE(data3);
-
- EXPECT_TRUE(called4);
- EXPECT_EQ(storage::Status::NOT_FOUND, status4);
- EXPECT_EQ(storage::ChangeSource::P2P, source4);
- EXPECT_FALSE(data4);
-}
-
-TEST_F(PageCommunicatorImplTest, CommitRequest) {
- FakeDeviceMesh mesh;
- FakePageStorage storage(dispatcher(), "page");
- const storage::Commit& commit_1 = storage.AddCommit("commit1", "data1");
-
- PageCommunicatorImpl page_communicator(&coroutine_service_, &storage,
- &storage, "ledger", "page", &mesh);
- page_communicator.Start();
-
- // Send request to PageCommunicator. We request two objects: |object_digest|
- // and |object_digest2|. Only |object_digest| will be present in storage.
- flatbuffers::FlatBufferBuilder request_buffer;
- BuildCommitRequestBuffer(&request_buffer, "ledger", "page",
- {storage::CommitId(commit_1.GetId()),
- storage::CommitId("missing_commit")});
- MessageHolder<Message> request_message(convert::ToStringView(request_buffer),
- &GetMessage);
- page_communicator.OnNewRequest(
- "device2", std::move(request_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
-
- RunLoopUntilIdle();
-
- // Verify the response.
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[0].second.data()),
- mesh.messages_[0].second.size());
- ASSERT_TRUE(VerifyMessageBuffer(verifier));
-
- const Message* reply_message = GetMessage(mesh.messages_[0].second.data());
- ASSERT_EQ(MessageUnion_Response, reply_message->message_type());
- const Response* response =
- static_cast<const Response*>(reply_message->message());
- const NamespacePageId* response_namespace_page_id =
- response->namespace_page();
- EXPECT_EQ("ledger", convert::ExtendedStringView(
- response_namespace_page_id->namespace_id()));
- EXPECT_EQ("page",
- convert::ExtendedStringView(response_namespace_page_id->page_id()));
- EXPECT_EQ(ResponseMessage_CommitResponse, response->response_type());
- const CommitResponse* commit_response =
- static_cast<const CommitResponse*>(response->response());
- ASSERT_EQ(2u, commit_response->commits()->size());
- auto it = commit_response->commits()->begin();
- EXPECT_EQ("commit1", convert::ExtendedStringView(it->id()->id()));
- EXPECT_EQ(CommitStatus_OK, it->status());
- EXPECT_EQ("data1", convert::ExtendedStringView(it->commit()->bytes()));
- it++;
- EXPECT_EQ("missing_commit", convert::ExtendedStringView(it->id()->id()));
- EXPECT_EQ(CommitStatus_UNKNOWN_COMMIT, it->status());
-}
-
-// Sends an update for new commits that triggers a backlog sync.
-TEST_F(PageCommunicatorImplTest, CommitBatchUpdate) {
- FakeDeviceMesh mesh;
- FakePageStorage storage_1(dispatcher(), "page");
- storage_1.AddCommit("id 0", "data 0");
- PageCommunicatorImpl page_communicator_1(&coroutine_service_, &storage_1,
- &storage_1, "ledger", "page", &mesh);
- page_communicator_1.Start();
-
- flatbuffers::FlatBufferBuilder buffer;
- BuildWatchStartBuffer(&buffer, "ledger", "page");
- MessageHolder<Message> message(convert::ToStringView(buffer), &GetMessage);
- page_communicator_1.OnNewRequest(
- "device2",
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- }));
- RunLoopUntilIdle();
-
- FakePageStorage storage_2(dispatcher(), "page");
- PageCommunicatorImpl page_communicator_2(&coroutine_service_, &storage_2,
- &storage_2, "ledger", "page", &mesh);
- page_communicator_2.Start();
-
- std::vector<std::unique_ptr<const storage::Commit>> commits;
- commits.emplace_back(std::make_unique<FakeCommit>(
- "id 1", "data 1", std::vector<storage::CommitId>({"id 0"})));
- commits.emplace_back(std::make_unique<FakeCommit>(
- "id 2", "data 2", std::vector<storage::CommitId>({"id 1"})));
-
- storage_1.watcher_->OnNewCommits(commits, storage::ChangeSource::LOCAL);
- RunLoopUntilIdle();
-
- // Local commit: a message is sent.
- ASSERT_EQ(1u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[0].first);
-
- {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[0].second.data()),
- mesh.messages_[0].second.size());
- ASSERT_TRUE(VerifyMessageBuffer(verifier));
-
- MessageHolder<Message> reply_message(mesh.messages_[0].second, &GetMessage);
- ASSERT_EQ(MessageUnion_Response, reply_message->message_type());
- MessageHolder<Response> response =
- std::move(reply_message)
- .TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- });
- const NamespacePageId* response_namespace_page_id =
- response->namespace_page();
- EXPECT_EQ("ledger", convert::ExtendedStringView(
- response_namespace_page_id->namespace_id()));
- EXPECT_EQ("page", convert::ExtendedStringView(
- response_namespace_page_id->page_id()));
- EXPECT_EQ(ResponseMessage_CommitResponse, response->response_type());
-
- // Send it to the other side.
- page_communicator_2.OnNewResponse("device1", std::move(response));
- }
- RunLoopUntilIdle();
-
- // PageCommunicator should have tried to add the commit.
- ASSERT_EQ(1u, storage_2.commits_from_sync_.size());
- EXPECT_EQ(2u, storage_2.commits_from_sync_[0].first.size());
- // Return that we miss one commit
- storage_2.commits_from_sync_[0].second(storage::Status::NOT_FOUND, {"id 0"});
-
- // |page_communicator_2| should ask for the base, "id 0" commit.
- ASSERT_EQ(2u, mesh.messages_.size());
- EXPECT_EQ("device1", mesh.messages_[1].first);
-
- {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[1].second.data()),
- mesh.messages_[0].second.size());
- ASSERT_TRUE(VerifyMessageBuffer(verifier));
-
- MessageHolder<Message> request_message(mesh.messages_[1].second,
- &GetMessage);
- ASSERT_EQ(MessageUnion_Request, request_message->message_type());
- MessageHolder<Request> request =
- std::move(request_message)
- .TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- });
- const NamespacePageId* request_namespace_page_id =
- request->namespace_page();
- EXPECT_EQ("ledger", convert::ExtendedStringView(
- request_namespace_page_id->namespace_id()));
- EXPECT_EQ("page", convert::ExtendedStringView(
- request_namespace_page_id->page_id()));
- EXPECT_EQ(RequestMessage_CommitRequest, request->request_type());
-
- // Send it to the other side.
- page_communicator_1.OnNewRequest("device2", std::move(request));
- }
- RunLoopUntilIdle();
-
- // |page_communicator_1| sends commit "id 0" to device 2.
- ASSERT_EQ(3u, mesh.messages_.size());
- EXPECT_EQ("device2", mesh.messages_[2].first);
-
- {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(mesh.messages_[2].second.data()),
- mesh.messages_[0].second.size());
- ASSERT_TRUE(VerifyMessageBuffer(verifier));
-
- MessageHolder<Message> reply_message(mesh.messages_[2].second, &GetMessage);
- ASSERT_EQ(MessageUnion_Response, reply_message->message_type());
- MessageHolder<Response> response =
- std::move(reply_message)
- .TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- });
- const NamespacePageId* response_namespace_page_id =
- response->namespace_page();
- EXPECT_EQ("ledger", convert::ExtendedStringView(
- response_namespace_page_id->namespace_id()));
- EXPECT_EQ("page", convert::ExtendedStringView(
- response_namespace_page_id->page_id()));
- EXPECT_EQ(ResponseMessage_CommitResponse, response->response_type());
-
- // Send it to the other side.
- page_communicator_2.OnNewResponse("device1", std::move(response));
- }
- RunLoopUntilIdle();
-
- // Verify that we are truely adding the whole commit batch.
- ASSERT_EQ(2u, storage_2.commits_from_sync_.size());
- EXPECT_EQ(3u, storage_2.commits_from_sync_[1].first.size());
- EXPECT_EQ("id 0", storage_2.commits_from_sync_[1].first[0].id);
- EXPECT_EQ("data 0", storage_2.commits_from_sync_[1].first[0].bytes);
- EXPECT_EQ("id 1", storage_2.commits_from_sync_[1].first[1].id);
- EXPECT_EQ("data 1", storage_2.commits_from_sync_[1].first[1].bytes);
- EXPECT_EQ("id 2", storage_2.commits_from_sync_[1].first[2].id);
- EXPECT_EQ("data 2", storage_2.commits_from_sync_[1].first[2].bytes);
-
- // Verify we don't crash on response from storage
- storage_2.commits_from_sync_[1].second(storage::Status::OK, {});
-}
-} // namespace
-} // namespace p2p_sync
diff --git a/bin/ledger/p2p_sync/impl/user_communicator_factory_impl.cc b/bin/ledger/p2p_sync/impl/user_communicator_factory_impl.cc
deleted file mode 100644
index e84c1c9..0000000
--- a/bin/ledger/p2p_sync/impl/user_communicator_factory_impl.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_sync/impl/user_communicator_factory_impl.h"
-
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <fuchsia/netconnector/cpp/fidl.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/p2p_provider/impl/p2p_provider_impl.h"
-#include "peridot/bin/ledger/p2p_sync/impl/user_communicator_impl.h"
-
-namespace p2p_sync {
-UserCommunicatorFactoryImpl::UserCommunicatorFactoryImpl(
- ledger::Environment* environment)
- : environment_(environment) {}
-
-UserCommunicatorFactoryImpl::~UserCommunicatorFactoryImpl() {}
-
-std::unique_ptr<UserCommunicator>
-UserCommunicatorFactoryImpl::GetUserCommunicator(
- std::unique_ptr<p2p_provider::UserIdProvider> user_id_provider) {
- char host_name_buffer[HOST_NAME_MAX + 1];
- int result = gethostname(host_name_buffer, sizeof(host_name_buffer));
- if (result < 0) {
- FXL_LOG(ERROR) << "unable to get hostname. errno " << errno;
- return nullptr;
- }
-
- fuchsia::netconnector::NetConnectorPtr net_connector =
- environment_->startup_context()
- ->ConnectToEnvironmentService<fuchsia::netconnector::NetConnector>();
-
- return std::make_unique<p2p_sync::UserCommunicatorImpl>(
- std::make_unique<p2p_provider::P2PProviderImpl>(
- host_name_buffer, std::move(net_connector),
- std::move(user_id_provider)),
- environment_->coroutine_service());
-}
-
-} // namespace p2p_sync
diff --git a/bin/ledger/p2p_sync/impl/user_communicator_factory_impl.h b/bin/ledger/p2p_sync/impl/user_communicator_factory_impl.h
deleted file mode 100644
index 852d54f..0000000
--- a/bin/ledger/p2p_sync/impl/user_communicator_factory_impl.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_USER_COMMUNICATOR_FACTORY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_USER_COMMUNICATOR_FACTORY_IMPL_H_
-
-#include <memory>
-#include <string>
-
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/p2p_provider/public/user_id_provider.h"
-#include "peridot/bin/ledger/p2p_sync/public/user_communicator.h"
-#include "peridot/bin/ledger/p2p_sync/public/user_communicator_factory.h"
-
-namespace p2p_sync {
-// Factory for creating UserCommunicators with default configuration.
-class UserCommunicatorFactoryImpl : public UserCommunicatorFactory {
- public:
- UserCommunicatorFactoryImpl(ledger::Environment* environment);
- ~UserCommunicatorFactoryImpl() override;
-
- std::unique_ptr<UserCommunicator> GetUserCommunicator(
- std::unique_ptr<p2p_provider::UserIdProvider> user_id_provider) override;
-
- private:
- ledger::Environment* const environment_;
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_USER_COMMUNICATOR_FACTORY_IMPL_H_
diff --git a/bin/ledger/p2p_sync/impl/user_communicator_impl.cc b/bin/ledger/p2p_sync/impl/user_communicator_impl.cc
deleted file mode 100644
index e16a5c5..0000000
--- a/bin/ledger/p2p_sync/impl/user_communicator_impl.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_sync/impl/user_communicator_impl.h"
-
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/p2p_sync/impl/flatbuffer_message_factory.h"
-#include "peridot/bin/ledger/p2p_sync/impl/ledger_communicator_impl.h"
-#include "peridot/bin/ledger/p2p_sync/impl/message_generated.h"
-#include "peridot/bin/ledger/p2p_sync/impl/message_holder.h"
-#include "peridot/lib/ledger_client/constants.h"
-
-namespace p2p_sync {
-
-UserCommunicatorImpl::UserCommunicatorImpl(
- std::unique_ptr<p2p_provider::P2PProvider> provider,
- coroutine::CoroutineService* coroutine_service)
- : p2p_provider_(std::move(provider)),
- coroutine_service_(coroutine_service) {}
-
-UserCommunicatorImpl::~UserCommunicatorImpl() { FXL_DCHECK(ledgers_.empty()); }
-
-void UserCommunicatorImpl::Start() {
- FXL_DCHECK(!started_);
- started_ = true;
- p2p_provider_->Start(this);
-}
-
-std::unique_ptr<LedgerCommunicator> UserCommunicatorImpl::GetLedgerCommunicator(
- std::string namespace_id) {
- FXL_DCHECK(started_);
- FXL_DCHECK(ledgers_.find(namespace_id) == ledgers_.end())
- << "UserCommunicatorImpl::GetLedgerCommunicator should be called once "
- "per active namespace: "
- << namespace_id;
-
- std::unique_ptr<LedgerCommunicatorImpl> ledger =
- std::make_unique<LedgerCommunicatorImpl>(coroutine_service_, namespace_id,
- this);
- LedgerCommunicatorImpl* ledger_ptr = ledger.get();
- ledger->set_on_delete(
- [this, namespace_id]() mutable { ledgers_.erase(namespace_id); });
- ledgers_[std::move(namespace_id)] = ledger_ptr;
- return ledger;
-}
-
-void UserCommunicatorImpl::OnNewMessage(fxl::StringView source,
- fxl::StringView data) {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(data.data()), data.size());
- if (!VerifyMessageBuffer(verifier)) {
- // Wrong serialization, abort.
- FXL_LOG(ERROR) << "The message received is malformed.";
- return;
- };
- MessageHolder<Message> message(data, &GetMessage);
- const NamespacePageId* namespace_page_id;
- switch (message->message_type()) {
- case MessageUnion_NONE:
- FXL_LOG(ERROR) << "The message received is unexpected at this point.";
- return;
- break;
-
- case MessageUnion_Request: {
- MessageHolder<Request> request =
- std::move(message).TakeAndMap<Request>([](const Message* message) {
- return static_cast<const Request*>(message->message());
- });
- namespace_page_id = request->namespace_page();
-
- std::string namespace_id(namespace_page_id->namespace_id()->begin(),
- namespace_page_id->namespace_id()->end());
- std::string page_id(namespace_page_id->page_id()->begin(),
- namespace_page_id->page_id()->end());
-
- const auto& it = ledgers_.find(namespace_id);
- if (it == ledgers_.end()) {
- flatbuffers::FlatBufferBuilder buffer;
- CreateUnknownResponseMessage(&buffer, namespace_id, page_id,
- ResponseStatus_UNKNOWN_NAMESPACE);
- p2p_provider_->SendMessage(source, convert::ExtendedStringView(buffer));
- return;
- }
- it->second->OnNewRequest(source, page_id, std::move(request));
- break;
- }
-
- case MessageUnion_Response: {
- MessageHolder<Response> response =
- std::move(message).TakeAndMap<Response>([](const Message* message) {
- return static_cast<const Response*>(message->message());
- });
- namespace_page_id = response->namespace_page();
- std::string namespace_id(namespace_page_id->namespace_id()->begin(),
- namespace_page_id->namespace_id()->end());
- std::string page_id(namespace_page_id->page_id()->begin(),
- namespace_page_id->page_id()->end());
-
- const auto& it = ledgers_.find(namespace_id);
- if (it == ledgers_.end()) {
- // We are receiving a response for a ledger that no longer exists. This
- // can happen in normal operation, and we cannot do anything with this
- // message: we can't send it to a ledger, and we don't send responses to
- // responses. So we just drop it here.
- return;
- }
- it->second->OnNewResponse(source, page_id, std::move(response));
- break;
- }
- }
-}
-
-void UserCommunicatorImpl::OnDeviceChange(
- fxl::StringView remote_device, p2p_provider::DeviceChangeType change_type) {
- switch (change_type) {
- case p2p_provider::DeviceChangeType::NEW:
- devices_.insert(remote_device.ToString());
- break;
- case p2p_provider::DeviceChangeType::DELETED:
- devices_.erase(devices_.find(remote_device));
- break;
- }
- for (const auto& it : ledgers_) {
- it.second->OnDeviceChange(remote_device, change_type);
- }
-}
-
-DeviceMesh::DeviceSet UserCommunicatorImpl::GetDeviceList() { return devices_; }
-
-void UserCommunicatorImpl::Send(fxl::StringView device_name,
- convert::ExtendedStringView data) {
- p2p_provider_->SendMessage(device_name, data);
-}
-
-} // namespace p2p_sync
diff --git a/bin/ledger/p2p_sync/impl/user_communicator_impl.h b/bin/ledger/p2p_sync/impl/user_communicator_impl.h
deleted file mode 100644
index 4fd30f4..0000000
--- a/bin/ledger/p2p_sync/impl/user_communicator_impl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_USER_COMMUNICATOR_IMPL_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_USER_COMMUNICATOR_IMPL_H_
-
-#include <memory>
-#include <set>
-#include <string>
-
-#include <fuchsia/netconnector/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/netconnector/cpp/message_relay.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/p2p_provider/public/p2p_provider.h"
-#include "peridot/bin/ledger/p2p_provider/public/types.h"
-#include "peridot/bin/ledger/p2p_provider/public/user_id_provider.h"
-#include "peridot/bin/ledger/p2p_sync/impl/device_mesh.h"
-#include "peridot/bin/ledger/p2p_sync/public/user_communicator.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace p2p_sync {
-class LedgerCommunicatorImpl;
-
-class UserCommunicatorImpl : public UserCommunicator,
- public DeviceMesh,
- public p2p_provider::P2PProvider::Client {
- public:
- explicit UserCommunicatorImpl(
- std::unique_ptr<p2p_provider::P2PProvider> provider,
- coroutine::CoroutineService* coroutine_service);
- ~UserCommunicatorImpl() override;
-
- // UserCommunicator:
- void Start() override;
- std::unique_ptr<LedgerCommunicator> GetLedgerCommunicator(
- std::string namespace_id) override;
-
- // DeviceMesh:
- DeviceSet GetDeviceList() override;
- void Send(fxl::StringView device_name,
- convert::ExtendedStringView data) override;
-
- private:
- // P2PProvider::Client
- void OnDeviceChange(fxl::StringView remote_device,
- p2p_provider::DeviceChangeType change_type) override;
- void OnNewMessage(fxl::StringView source, fxl::StringView data) override;
-
- // Set of active ledgers.
- std::map<std::string, LedgerCommunicatorImpl*, convert::StringViewComparator>
- ledgers_;
- std::set<std::string, convert::StringViewComparator> devices_;
-
- bool started_ = false;
- std::string user_token_;
- std::unique_ptr<component::ServiceProviderImpl> network_service_provider_;
-
- std::unique_ptr<p2p_provider::P2PProvider> p2p_provider_;
- coroutine::CoroutineService* const coroutine_service_;
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_IMPL_USER_COMMUNICATOR_IMPL_H_
diff --git a/bin/ledger/p2p_sync/impl/user_communicator_impl_unittest.cc b/bin/ledger/p2p_sync/impl/user_communicator_impl_unittest.cc
deleted file mode 100644
index 3815b83..0000000
--- a/bin/ledger/p2p_sync/impl/user_communicator_impl_unittest.cc
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/p2p_sync/impl/user_communicator_impl.h"
-
-#include <algorithm>
-#include <string>
-
-#include <lib/fit/function.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-// gtest matchers are in gmock and we cannot include the specific header file
-// directly as it is private to the library.
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/p2p_provider/impl/p2p_provider_impl.h"
-#include "peridot/bin/ledger/p2p_provider/public/user_id_provider.h"
-#include "peridot/bin/ledger/p2p_sync/impl/page_communicator_impl.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-#include "peridot/bin/ledger/testing/netconnector/netconnector_factory.h"
-
-namespace p2p_sync {
-class PageCommunicatorImplInspectorForTest {
- public:
- static const std::set<std::string, convert::StringViewComparator>&
- GetInterestedDevices(const std::unique_ptr<PageCommunicator>& page) {
- return reinterpret_cast<PageCommunicatorImpl*>(page.get())
- ->interested_devices_;
- }
-};
-
-namespace {
-
-class FakePageStorage : public storage::PageStorageEmptyImpl {
- public:
- explicit FakePageStorage(std::string page_id)
- : page_id_(std::move(page_id)) {}
- ~FakePageStorage() override {}
-
- storage::PageId GetId() override { return page_id_; }
-
- void MarkSyncedToPeer(
- fit::function<void(storage::Status)> callback) override {
- callback(storage::Status::OK);
- }
-
- private:
- const std::string page_id_;
-};
-
-class FakeUserIdProvider : public p2p_provider::UserIdProvider {
- public:
- explicit FakeUserIdProvider(std::string user_id)
- : user_id_(std::move(user_id)) {}
-
- void GetUserId(fit::function<void(Status, std::string)> callback) override {
- callback(Status::OK, user_id_);
- };
-
- private:
- std::string user_id_;
-};
-
-class UserCommunicatorImplTest : public gtest::TestLoopFixture {
- public:
- UserCommunicatorImplTest() {}
- ~UserCommunicatorImplTest() override {}
-
- std::unique_ptr<UserCommunicator> GetUserCommunicator(
- std::string host_name, std::string user_name = "user") {
- fuchsia::netconnector::NetConnectorPtr netconnector;
- net_connector_factory_.AddBinding(host_name, netconnector.NewRequest());
- std::unique_ptr<p2p_provider::P2PProvider> provider =
- std::make_unique<p2p_provider::P2PProviderImpl>(
- std::move(host_name), std::move(netconnector),
- std::make_unique<FakeUserIdProvider>(std::move(user_name)));
- return std::make_unique<UserCommunicatorImpl>(std::move(provider),
- &coroutine_service_);
- }
-
- protected:
- void SetUp() override { ::testing::Test::SetUp(); }
-
- ledger::NetConnectorFactory net_connector_factory_;
-
- private:
- coroutine::CoroutineServiceImpl coroutine_service_;
- FXL_DISALLOW_COPY_AND_ASSIGN(UserCommunicatorImplTest);
-};
-
-TEST_F(UserCommunicatorImplTest, OneHost_NoCrash) {
- std::unique_ptr<UserCommunicator> user_communicator =
- GetUserCommunicator("host1");
- user_communicator->Start();
- std::unique_ptr<LedgerCommunicator> ledger =
- user_communicator->GetLedgerCommunicator("ledger1");
- FakePageStorage storage("page1");
- std::unique_ptr<PageCommunicator> page =
- ledger->GetPageCommunicator(&storage, &storage);
- page->Start();
- RunLoopUntilIdle();
-}
-
-TEST_F(UserCommunicatorImplTest, ThreeHosts_SamePage) {
- std::unique_ptr<UserCommunicator> user_communicator1 =
- GetUserCommunicator("host1");
- user_communicator1->Start();
- std::unique_ptr<LedgerCommunicator> ledger1 =
- user_communicator1->GetLedgerCommunicator("app");
- FakePageStorage storage1("page");
- std::unique_ptr<PageCommunicator> page1 =
- ledger1->GetPageCommunicator(&storage1, &storage1);
- page1->Start();
- RunLoopUntilIdle();
-
- std::unique_ptr<UserCommunicator> user_communicator2 =
- GetUserCommunicator("host2");
- user_communicator2->Start();
- std::unique_ptr<LedgerCommunicator> ledger2 =
- user_communicator2->GetLedgerCommunicator("app");
- FakePageStorage storage2("page");
- std::unique_ptr<PageCommunicator> page2 =
- ledger2->GetPageCommunicator(&storage2, &storage2);
- page2->Start();
- RunLoopUntilIdle();
-
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page1),
- testing::UnorderedElementsAre("host2"));
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page2),
- testing::UnorderedElementsAre("host1"));
-
- std::unique_ptr<UserCommunicator> user_communicator3 =
- GetUserCommunicator("host3");
- user_communicator3->Start();
- std::unique_ptr<LedgerCommunicator> ledger3 =
- user_communicator3->GetLedgerCommunicator("app");
- FakePageStorage storage3("page");
- std::unique_ptr<PageCommunicator> page3 =
- ledger3->GetPageCommunicator(&storage3, &storage3);
- page3->Start();
- RunLoopUntilIdle();
-
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page1),
- testing::UnorderedElementsAre("host2", "host3"));
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page2),
- testing::UnorderedElementsAre("host1", "host3"));
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page3),
- testing::UnorderedElementsAre("host1", "host2"));
-
- page2.reset();
- RunLoopUntilIdle();
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page1),
- testing::UnorderedElementsAre("host3"));
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page3),
- testing::UnorderedElementsAre("host1"));
-}
-
-TEST_F(UserCommunicatorImplTest, ThreeHosts_TwoPages) {
- std::unique_ptr<UserCommunicator> user_communicator1 =
- GetUserCommunicator("host1");
- user_communicator1->Start();
- std::unique_ptr<LedgerCommunicator> ledger1 =
- user_communicator1->GetLedgerCommunicator("app");
- FakePageStorage storage1_1("page1");
- std::unique_ptr<PageCommunicator> page1_1 =
- ledger1->GetPageCommunicator(&storage1_1, &storage1_1);
- page1_1->Start();
- FakePageStorage storage1_2("page2");
- std::unique_ptr<PageCommunicator> page1_2 =
- ledger1->GetPageCommunicator(&storage1_2, &storage1_2);
- page1_2->Start();
- RunLoopUntilIdle();
-
- std::unique_ptr<UserCommunicator> user_communicator2 =
- GetUserCommunicator("host2");
- user_communicator2->Start();
- std::unique_ptr<LedgerCommunicator> ledger2 =
- user_communicator2->GetLedgerCommunicator("app");
- FakePageStorage storage2_1("page1");
- std::unique_ptr<PageCommunicator> page2_1 =
- ledger2->GetPageCommunicator(&storage2_1, &storage2_1);
- page2_1->Start();
- RunLoopUntilIdle();
-
- std::unique_ptr<UserCommunicator> user_communicator3 =
- GetUserCommunicator("host3");
- user_communicator3->Start();
- std::unique_ptr<LedgerCommunicator> ledger3 =
- user_communicator3->GetLedgerCommunicator("app");
- FakePageStorage storage3_2("page2");
- std::unique_ptr<PageCommunicator> page3_2 =
- ledger3->GetPageCommunicator(&storage3_2, &storage3_2);
- page3_2->Start();
- RunLoopUntilIdle();
-
- EXPECT_THAT(
- PageCommunicatorImplInspectorForTest::GetInterestedDevices(page1_1),
- testing::UnorderedElementsAre("host2"));
- EXPECT_THAT(
- PageCommunicatorImplInspectorForTest::GetInterestedDevices(page1_2),
- testing::UnorderedElementsAre("host3"));
- EXPECT_THAT(
- PageCommunicatorImplInspectorForTest::GetInterestedDevices(page2_1),
- testing::UnorderedElementsAre("host1"));
- EXPECT_THAT(
- PageCommunicatorImplInspectorForTest::GetInterestedDevices(page3_2),
- testing::UnorderedElementsAre("host1"));
-}
-
-// This test adds some delay (ie. runs the loop until idle) between the time a
-// device becomes visible and the time the page we are interested in becomes
-// active. This ensure we correctly connect pages that become active after the
-// device is connected.
-TEST_F(UserCommunicatorImplTest, ThreeHosts_WaitBeforePageIsActive) {
- std::unique_ptr<UserCommunicator> user_communicator1 =
- GetUserCommunicator("host1");
- user_communicator1->Start();
- RunLoopUntilIdle();
- std::unique_ptr<LedgerCommunicator> ledger1 =
- user_communicator1->GetLedgerCommunicator("app");
- FakePageStorage storage1("page");
- std::unique_ptr<PageCommunicator> page1 =
- ledger1->GetPageCommunicator(&storage1, &storage1);
- page1->Start();
- RunLoopUntilIdle();
-
- std::unique_ptr<UserCommunicator> user_communicator2 =
- GetUserCommunicator("host2");
- user_communicator2->Start();
- RunLoopUntilIdle();
- std::unique_ptr<LedgerCommunicator> ledger2 =
- user_communicator2->GetLedgerCommunicator("app");
- FakePageStorage storage2("page");
- std::unique_ptr<PageCommunicator> page2 =
- ledger2->GetPageCommunicator(&storage2, &storage2);
- page2->Start();
- RunLoopUntilIdle();
-
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page1),
- testing::UnorderedElementsAre("host2"));
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page2),
- testing::UnorderedElementsAre("host1"));
-
- std::unique_ptr<UserCommunicator> user_communicator3 =
- GetUserCommunicator("host3");
- user_communicator3->Start();
- RunLoopUntilIdle();
- std::unique_ptr<LedgerCommunicator> ledger3 =
- user_communicator3->GetLedgerCommunicator("app");
- FakePageStorage storage3("page");
- std::unique_ptr<PageCommunicator> page3 =
- ledger3->GetPageCommunicator(&storage3, &storage3);
- page3->Start();
- RunLoopUntilIdle();
-
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page1),
- testing::UnorderedElementsAre("host2", "host3"));
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page2),
- testing::UnorderedElementsAre("host1", "host3"));
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page3),
- testing::UnorderedElementsAre("host1", "host2"));
-
- page2.reset();
- RunLoopUntilIdle();
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page1),
- testing::UnorderedElementsAre("host3"));
- EXPECT_THAT(PageCommunicatorImplInspectorForTest::GetInterestedDevices(page3),
- testing::UnorderedElementsAre("host1"));
-}
-
-} // namespace
-} // namespace p2p_sync
diff --git a/bin/ledger/p2p_sync/public/BUILD.gn b/bin/ledger/p2p_sync/public/BUILD.gn
deleted file mode 100644
index 0a718ee..0000000
--- a/bin/ledger/p2p_sync/public/BUILD.gn
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("public") {
- sources = [
- "ledger_communicator.h",
- "page_communicator.h",
- "user_communicator.h",
- "user_communicator_factory.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/p2p_provider/public",
- "//peridot/bin/ledger/storage/public",
- ]
-
- deps = []
-}
diff --git a/bin/ledger/p2p_sync/public/README.md b/bin/ledger/p2p_sync/public/README.md
deleted file mode 100644
index edf01ed..0000000
--- a/bin/ledger/p2p_sync/public/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Peer-to-peer communication
-
-The Ledger supports peer-to-peer synchronization between devices able to communicate directly.
-
-# Protocol
-The protocol used for P2P communication is based on message passing. Messages
-are defined in //peridot/bin/ledger/p2p_sync/impl/message.fbs. This is not an
-RPC-like system : most messages do not expect any response, and the protocol
-should be resilient to devices not answering.
diff --git a/bin/ledger/p2p_sync/public/ledger_communicator.h b/bin/ledger/p2p_sync/public/ledger_communicator.h
deleted file mode 100644
index 4e170c5..0000000
--- a/bin/ledger/p2p_sync/public/ledger_communicator.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_LEDGER_COMMUNICATOR_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_LEDGER_COMMUNICATOR_H_
-
-#include <memory>
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/p2p_sync/public/page_communicator.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace p2p_sync {
-// LedgerCommunicator handles ledger-level data transfer between peers.
-class LedgerCommunicator {
- public:
- LedgerCommunicator() {}
- virtual ~LedgerCommunicator() {}
-
- // Returns a page-specific communicator.
- // All |PageCommunicator| objects obtained through this method must be
- // destroyed before |LedgerCommunicator|.
- virtual std::unique_ptr<PageCommunicator> GetPageCommunicator(
- storage::PageStorage* storage, storage::PageSyncClient* sync_client) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerCommunicator);
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_LEDGER_COMMUNICATOR_H_
diff --git a/bin/ledger/p2p_sync/public/page_communicator.h b/bin/ledger/p2p_sync/public/page_communicator.h
deleted file mode 100644
index bde323d..0000000
--- a/bin/ledger/p2p_sync/public/page_communicator.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_PAGE_COMMUNICATOR_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_PAGE_COMMUNICATOR_H_
-
-#include "peridot/bin/ledger/p2p_sync/public/page_communicator.h"
-
-#include <memory>
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-namespace p2p_sync {
-// PageCommunicator handles page-level data transfer between peers.
-class PageCommunicator {
- public:
- PageCommunicator() {}
- virtual ~PageCommunicator() {}
-
- // Start should be called at most once. It signals that this page is active on
- // this device.
- virtual void Start() = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageCommunicator);
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_PAGE_COMMUNICATOR_H_
diff --git a/bin/ledger/p2p_sync/public/user_communicator.h b/bin/ledger/p2p_sync/public/user_communicator.h
deleted file mode 100644
index 725d4f5..0000000
--- a/bin/ledger/p2p_sync/public/user_communicator.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_USER_COMMUNICATOR_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_USER_COMMUNICATOR_H_
-
-#include <memory>
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/p2p_sync/public/ledger_communicator.h"
-
-namespace p2p_sync {
-// UserCommunicator is the user-level object handling peer-to-peer connections
-// with the mesh of devices of a user.
-class UserCommunicator {
- public:
- UserCommunicator() {}
- virtual ~UserCommunicator() {}
-
- // Connects this device to its device mesh. To be called exactly once before
- // any other method.
- virtual void Start() = 0;
- // Returns a ledger-specific communicator.
- // All |LedgerCommunicator| objects obtained through this method must be
- // destroyed before |UserCommunicator|.
- virtual std::unique_ptr<LedgerCommunicator> GetLedgerCommunicator(
- std::string repository_id) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(UserCommunicator);
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_USER_COMMUNICATOR_H_
diff --git a/bin/ledger/p2p_sync/public/user_communicator_factory.h b/bin/ledger/p2p_sync/public/user_communicator_factory.h
deleted file mode 100644
index 5293202..0000000
--- a/bin/ledger/p2p_sync/public/user_communicator_factory.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_USER_COMMUNICATOR_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_USER_COMMUNICATOR_FACTORY_H_
-
-#include <memory>
-
-#include "peridot/bin/ledger/p2p_provider/public/user_id_provider.h"
-#include "peridot/bin/ledger/p2p_sync/public/user_communicator.h"
-
-namespace p2p_sync {
-// Factory for creating UserCommunicators with default configuration.
-class UserCommunicatorFactory {
- public:
- UserCommunicatorFactory() {}
- virtual ~UserCommunicatorFactory() {}
-
- virtual std::unique_ptr<UserCommunicator> GetUserCommunicator(
- std::unique_ptr<p2p_provider::UserIdProvider> user_id_provider) = 0;
-};
-
-} // namespace p2p_sync
-
-#endif // PERIDOT_BIN_LEDGER_P2P_SYNC_PUBLIC_USER_COMMUNICATOR_FACTORY_H_
diff --git a/bin/ledger/storage/BUILD.gn b/bin/ledger/storage/BUILD.gn
deleted file mode 100644
index 69cb0ea..0000000
--- a/bin/ledger/storage/BUILD.gn
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("storage") {
- deps = [
- "//peridot/bin/ledger/storage/impl",
- "//peridot/bin/ledger/storage/public",
- ]
-}
diff --git a/bin/ledger/storage/fake/BUILD.gn b/bin/ledger/storage/fake/BUILD.gn
deleted file mode 100644
index d9c7d82..0000000
--- a/bin/ledger/storage/fake/BUILD.gn
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("fake") {
- testonly = true
-
- deps = [
- ":lib",
- ]
-}
-
-source_set("lib") {
- testonly = true
-
- sources = [
- "fake_commit.cc",
- "fake_commit.h",
- "fake_db.cc",
- "fake_db.h",
- "fake_db_factory.cc",
- "fake_db_factory.h",
- "fake_journal.cc",
- "fake_journal.h",
- "fake_journal_delegate.cc",
- "fake_journal_delegate.h",
- "fake_object.cc",
- "fake_object.h",
- "fake_page_storage.cc",
- "fake_page_storage.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/environment",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/storage/testing",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//peridot/bin/ledger/encryption/fake",
- "//peridot/bin/ledger/encryption/primitives",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/storage/fake/fake_commit.cc b/bin/ledger/storage/fake/fake_commit.cc
deleted file mode 100644
index 26b2c1c..0000000
--- a/bin/ledger/storage/fake/fake_commit.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/fake/fake_commit.h"
-
-#include <memory>
-#include <string>
-
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/fake/fake_journal_delegate.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/storage/public/iterator.h"
-
-namespace storage {
-namespace fake {
-
-FakeCommit::FakeCommit(FakeJournalDelegate* journal) : journal_(journal) {}
-FakeCommit::~FakeCommit() {}
-
-std::unique_ptr<const Commit> FakeCommit::Clone() const {
- return std::make_unique<FakeCommit>(journal_);
-}
-
-const CommitId& FakeCommit::GetId() const { return journal_->GetId(); }
-
-std::vector<CommitIdView> FakeCommit::GetParentIds() const {
- return journal_->GetParentIds();
-}
-
-zx::time_utc FakeCommit::GetTimestamp() const { return zx::time_utc(); }
-
-uint64_t FakeCommit::GetGeneration() const { return journal_->GetGeneration(); }
-
-ObjectIdentifier FakeCommit::GetRootIdentifier() const {
- // The object digest is fake here: using journal id is arbitrary.
- return encryption::MakeDefaultObjectIdentifier(
- ObjectDigest(journal_->GetId()));
-}
-
-fxl::StringView FakeCommit::GetStorageBytes() const {
- return fxl::StringView();
-}
-
-} // namespace fake
-} // namespace storage
diff --git a/bin/ledger/storage/fake/fake_commit.h b/bin/ledger/storage/fake/fake_commit.h
deleted file mode 100644
index 395e26c..0000000
--- a/bin/ledger/storage/fake/fake_commit.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_COMMIT_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_COMMIT_H_
-
-#include <memory>
-#include <string>
-
-#include "peridot/bin/ledger/storage/fake/fake_journal.h"
-#include "peridot/bin/ledger/storage/fake/fake_journal_delegate.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-
-namespace storage {
-namespace fake {
-
-// A |FakeCommit| is a commit based on a |FakeJournalDelegate|.
-class FakeCommit : public Commit {
- public:
- explicit FakeCommit(FakeJournalDelegate* journal);
- ~FakeCommit() override;
-
- // Commit:
- std::unique_ptr<const Commit> Clone() const override;
-
- const CommitId& GetId() const override;
-
- std::vector<CommitIdView> GetParentIds() const override;
-
- zx::time_utc GetTimestamp() const override;
-
- uint64_t GetGeneration() const override;
-
- ObjectIdentifier GetRootIdentifier() const override;
-
- fxl::StringView GetStorageBytes() const override;
-
- private:
- FakeJournalDelegate* journal_;
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeCommit);
-};
-
-} // namespace fake
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_COMMIT_H_
diff --git a/bin/ledger/storage/fake/fake_db.cc b/bin/ledger/storage/fake/fake_db.cc
deleted file mode 100644
index e6d40e8..0000000
--- a/bin/ledger/storage/fake/fake_db.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/fake/fake_db.h"
-
-#include <lib/async/cpp/task.h>
-
-#include "peridot/bin/ledger/storage/fake/fake_object.h"
-
-namespace storage {
-namespace fake {
-
-namespace {
-Status MakeEmptySyncCallAndCheck(async_dispatcher_t* dispatcher,
- coroutine::CoroutineHandler* handler) {
- if (coroutine::SyncCall(handler, [&dispatcher](fit::closure on_done) {
- async::PostTask(dispatcher, std::move(on_done));
- }) == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return Status::OK;
-}
-
-bool HasPrefix(const std::string& key, convert::ExtendedStringView prefix) {
- return key.size() >= prefix.size() &&
- key.compare(0, prefix.size(), prefix.ToString());
-}
-
-class FakeBatch : public Db::Batch {
- public:
- FakeBatch(async_dispatcher_t* dispatcher,
- std::map<std::string, std::string>* key_value_store)
- : dispatcher_(dispatcher), key_value_store_(key_value_store) {}
- ~FakeBatch() override {}
-
- Status Put(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key, fxl::StringView value) override {
- std::string key_str = key.ToString();
- entries_to_put_[key_str] = value.ToString();
-
- // Inserting an entry means that any previous |Delete| operations on that
- // key are cancelled: erase that key from |entries_to_delete_| if present.
- auto it = entries_to_delete_.find(key_str);
- if (it != entries_to_delete_.end()) {
- entries_to_delete_.erase(it);
- }
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
- }
-
- Status Delete(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key) override {
- std::string key_str = key.ToString();
- entries_to_delete_.insert(key_str);
-
- // Deleting an entry means that any previous |Put| operations on that key
- // is cancelled: erase that entry from |entries_to_put_| if present.
- auto it = entries_to_put_.find(key_str);
- if (it != entries_to_put_.end()) {
- entries_to_put_.erase(it);
- }
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
- }
-
- Status DeleteByPrefix(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView prefix) override {
- for (auto it = key_value_store_->lower_bound(prefix.ToString());
- it != key_value_store_->end() && HasPrefix(it->first, prefix); ++it) {
- Delete(handler, it->first);
- }
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
- }
-
- Status Execute(coroutine::CoroutineHandler* handler) override {
- for (const auto& entry : entries_to_put_) {
- (*key_value_store_)[entry.first] = entry.second;
- }
- for (const auto& key : entries_to_delete_) {
- auto it = key_value_store_->find(key);
- if (it != key_value_store_->end()) {
- key_value_store_->erase(it);
- }
- }
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
- }
-
- private:
- async_dispatcher_t* dispatcher_;
-
- std::map<std::string, std::string> entries_to_put_;
- std::set<std::string> entries_to_delete_;
-
- std::map<std::string, std::string>* key_value_store_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeBatch);
-};
-
-// A wrapper storage::Iterator for the elements of an std::map that start with a
-// given prefix.
-class PrefixIterator
- : public storage::Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>> {
- public:
- PrefixIterator(const std::map<std::string, std::string>& key_value_store,
- convert::ExtendedStringView prefix)
- : prefix_(prefix.ToString()),
- it_(key_value_store.lower_bound(prefix_)),
- end_(key_value_store.end()) {
- UpdateCurrentElement();
- }
-
- ~PrefixIterator() {}
-
- storage::Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>&
- Next() override {
- ++it_;
- UpdateCurrentElement();
- return *this;
- }
-
- bool Valid() const override {
- return current_.has_value() &&
- current_.value().first.substr(0, prefix_.size()) ==
- convert::ExtendedStringView(prefix_);
- }
-
- storage::Status GetStatus() const override { return storage::Status::OK; }
-
- const std::pair<convert::ExtendedStringView, convert::ExtendedStringView>&
- operator*() const override {
- FXL_DCHECK(current_.has_value());
- return current_.value();
- }
-
- const std::pair<convert::ExtendedStringView, convert::ExtendedStringView>*
- operator->() const override {
- FXL_DCHECK(current_.has_value());
- return ¤t_.value();
- }
-
- private:
- void UpdateCurrentElement() {
- if (it_ != end_) {
- current_ = {convert::ExtendedStringView(it_->first),
- convert::ExtendedStringView(it_->second)};
- } else {
- current_.reset();
- }
- }
-
- std::string prefix_;
- std::optional<
- std::pair<convert::ExtendedStringView, convert::ExtendedStringView>>
- current_;
- std::map<std::string, std::string>::const_iterator it_;
- std::map<std::string, std::string>::const_iterator end_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PrefixIterator);
-};
-
-} // namespace
-
-FakeDb::FakeDb(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {}
-FakeDb::~FakeDb() {}
-
-Status FakeDb::StartBatch(coroutine::CoroutineHandler* handler,
- std::unique_ptr<Batch>* batch) {
- *batch = std::make_unique<FakeBatch>(dispatcher_, &key_value_store_);
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status FakeDb::Get(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key, std::string* value) {
- auto it = key_value_store_.find(key.ToString());
- if (it == key_value_store_.end()) {
- return Status::NOT_FOUND;
- }
- *value = it->second;
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status FakeDb::HasKey(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key, bool* has_key) {
- auto it = key_value_store_.find(key.ToString());
- *has_key = it != key_value_store_.end();
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status FakeDb::GetObject(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) {
- auto it = key_value_store_.find(key.ToString());
- if (it == key_value_store_.end()) {
- return Status::NOT_FOUND;
- }
- *object = std::make_unique<FakeObject>(object_identifier, it->second);
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status FakeDb::GetByPrefix(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView prefix,
- std::vector<std::string>* key_suffixes) {
- std::vector<std::string> keys_with_prefix;
- auto it = key_value_store_.lower_bound(prefix.ToString());
- while (it != key_value_store_.end() && HasPrefix(it->first, prefix)) {
- keys_with_prefix.push_back(it->first.substr(prefix.size()));
- }
- key_suffixes->swap(keys_with_prefix);
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status FakeDb::GetEntriesByPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::vector<std::pair<std::string, std::string>>* entries) {
- std::vector<std::pair<std::string, std::string>> entries_with_prefix;
-
- auto it = key_value_store_.lower_bound(prefix.ToString());
- while (it != key_value_store_.end() && HasPrefix(it->first, prefix)) {
- entries_with_prefix.emplace_back(it->first, it->second);
- }
- entries->swap(entries_with_prefix);
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status FakeDb::GetIteratorAtPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::unique_ptr<Iterator<const std::pair<
- convert::ExtendedStringView, convert::ExtendedStringView>>>* iterator) {
- *iterator = std::make_unique<PrefixIterator>(key_value_store_, prefix);
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-} // namespace fake
-} // namespace storage
diff --git a/bin/ledger/storage/fake/fake_db.h b/bin/ledger/storage/fake/fake_db.h
deleted file mode 100644
index 85eef5f..0000000
--- a/bin/ledger/storage/fake/fake_db.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_DB_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_DB_H_
-
-#include <map>
-
-#include <lib/async/dispatcher.h>
-
-#include "peridot/bin/ledger/storage/public/db.h"
-
-namespace storage {
-namespace fake {
-
-class FakeDb : public Db {
- public:
- explicit FakeDb(async_dispatcher_t* dispatcher);
- ~FakeDb() override;
-
- // Db:
- Status StartBatch(coroutine::CoroutineHandler* handler,
- std::unique_ptr<Batch>* batch) override;
- Status Get(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key, std::string* value) override;
- Status HasKey(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key, bool* has_key) override;
- Status GetObject(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) override;
- Status GetByPrefix(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView prefix,
- std::vector<std::string>* key_suffixes) override;
- Status GetEntriesByPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::vector<std::pair<std::string, std::string>>* entries) override;
- Status GetIteratorAtPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::unique_ptr<Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>>*
- iterator) override;
-
- private:
- async_dispatcher_t* const dispatcher_;
-
- std::map<std::string, std::string> key_value_store_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeDb);
-};
-
-} // namespace fake
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_DB_H_
diff --git a/bin/ledger/storage/fake/fake_db_factory.cc b/bin/ledger/storage/fake/fake_db_factory.cc
deleted file mode 100644
index e23c58d..0000000
--- a/bin/ledger/storage/fake/fake_db_factory.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/fake/fake_db_factory.h"
-
-#include <lib/fxl/files/directory.h>
-
-#include "peridot/bin/ledger/storage/fake/fake_db.h"
-
-namespace storage {
-namespace fake {
-
-void FakeDbFactory::GetOrCreateDb(
- ledger::DetachedPath db_path, DbFactory::OnDbNotFound on_db_not_found,
- fit::function<void(Status, std::unique_ptr<Db>)> callback) {
- if (!files::IsDirectoryAt(db_path.root_fd(), db_path.path())) {
- if (on_db_not_found == DbFactory::OnDbNotFound::RETURN) {
- callback(Status::NOT_FOUND, nullptr);
- return;
- }
- // Create the path to fake the creation of the Db at the expected
- // destination.
- if (!files::CreateDirectoryAt(db_path.root_fd(), db_path.path())) {
- FXL_LOG(ERROR) << "Failed to create the storage directory in "
- << db_path.path();
- callback(Status::INTERNAL_IO_ERROR, nullptr);
- return;
- }
- }
- callback(Status::OK, std::make_unique<FakeDb>(dispatcher_));
-}
-
-} // namespace fake
-} // namespace storage
diff --git a/bin/ledger/storage/fake/fake_db_factory.h b/bin/ledger/storage/fake/fake_db_factory.h
deleted file mode 100644
index 7e56a89..0000000
--- a/bin/ledger/storage/fake/fake_db_factory.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_DB_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_DB_FACTORY_H_
-
-#include "peridot/bin/ledger/storage/public/db_factory.h"
-
-namespace storage {
-namespace fake {
-
-// A fake implementation of the DbFactory.
-class FakeDbFactory : public DbFactory {
- public:
- explicit FakeDbFactory(async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher) {}
-
- void GetOrCreateDb(
- ledger::DetachedPath db_path, DbFactory::OnDbNotFound on_db_not_found,
- fit::function<void(Status, std::unique_ptr<Db>)> callback) override;
-
- private:
- void CreateInitializedDb(
- fit::function<void(Status, std::unique_ptr<Db>)> callback);
-
- async_dispatcher_t* dispatcher_;
-};
-
-} // namespace fake
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_DB_FACTORY_H_
diff --git a/bin/ledger/storage/fake/fake_journal.cc b/bin/ledger/storage/fake/fake_journal.cc
deleted file mode 100644
index 257f6a7..0000000
--- a/bin/ledger/storage/fake/fake_journal.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/fake/fake_journal.h"
-
-#include <string>
-
-#include <lib/fit/function.h>
-
-namespace storage {
-namespace fake {
-
-FakeJournal::FakeJournal(FakeJournalDelegate* delegate) : delegate_(delegate) {}
-
-FakeJournal::~FakeJournal() {}
-
-void FakeJournal::Commit(
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- delegate_->Commit(std::move(callback));
-}
-
-Status FakeJournal::Rollback() { return delegate_->Rollback(); }
-
-void FakeJournal::Put(convert::ExtendedStringView key,
- ObjectIdentifier object_identifier, KeyPriority priority,
- fit::function<void(Status)> callback) {
- callback(delegate_->SetValue(key, std::move(object_identifier), priority));
-}
-
-void FakeJournal::Delete(convert::ExtendedStringView key,
- fit::function<void(Status)> callback) {
- callback(delegate_->Delete(key));
-}
-
-void FakeJournal::Clear(fit::function<void(Status)> callback) {
- callback(delegate_->Clear());
-}
-
-const JournalId& FakeJournal::GetId() const { return delegate_->GetId(); }
-
-} // namespace fake
-} // namespace storage
diff --git a/bin/ledger/storage/fake/fake_journal.h b/bin/ledger/storage/fake/fake_journal.h
deleted file mode 100644
index f0cbb3e..0000000
--- a/bin/ledger/storage/fake/fake_journal.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_JOURNAL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_JOURNAL_H_
-
-#include <memory>
-#include <string>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/storage/fake/fake_journal_delegate.h"
-#include "peridot/bin/ledger/storage/public/journal.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace fake {
-
-// A |FakeJournal| is an in-memory journal.
-class FakeJournal : public Journal {
- public:
- explicit FakeJournal(FakeJournalDelegate* delegate);
- ~FakeJournal() override;
-
- void Commit(
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback);
-
- Status Rollback();
-
- // Journal:
- void Put(convert::ExtendedStringView key, ObjectIdentifier object_identifier,
- KeyPriority priority, fit::function<void(Status)> callback) override;
- void Delete(convert::ExtendedStringView key,
- fit::function<void(Status)> callback) override;
- void Clear(fit::function<void(Status)> callback) override;
- const JournalId& GetId() const override;
-
- private:
- FakeJournalDelegate* delegate_;
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeJournal);
-};
-
-} // namespace fake
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_JOURNAL_H_
diff --git a/bin/ledger/storage/fake/fake_journal_delegate.cc b/bin/ledger/storage/fake/fake_journal_delegate.cc
deleted file mode 100644
index 3c80415..0000000
--- a/bin/ledger/storage/fake/fake_journal_delegate.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/fake/fake_journal_delegate.h"
-
-#include <utility>
-
-#include <lib/fit/function.h>
-#include <zircon/syscalls.h>
-
-#include "peridot/bin/ledger/storage/fake/fake_commit.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-namespace fake {
-namespace {
-
-storage::CommitId RandomCommitId(rng::Random* random) {
- storage::CommitId result;
- result.resize(kCommitIdSize);
- random->Draw(&result);
- return result;
-}
-
-} // namespace
-
-FakeJournalDelegate::FakeJournalDelegate(rng::Random* random, Data initial_data,
- CommitId parent_id, bool autocommit,
- uint64_t generation = 0)
- : autocommit_(autocommit),
- id_(RandomCommitId(random)),
- parent_id_(std::move(parent_id)),
- data_(std::move(initial_data)),
- generation_(generation) {}
-
-FakeJournalDelegate::FakeJournalDelegate(rng::Random* random, Data initial_data,
- CommitId parent_id, CommitId other_id,
- bool autocommit,
- uint64_t generation = 0)
- : autocommit_(autocommit),
- id_(RandomCommitId(random)),
- parent_id_(std::move(parent_id)),
- other_id_(std::move(other_id)),
- data_(std::move(initial_data)),
- generation_(generation) {}
-
-FakeJournalDelegate::~FakeJournalDelegate() {}
-
-Status FakeJournalDelegate::SetValue(convert::ExtendedStringView key,
- ObjectIdentifier value,
- KeyPriority priority) {
- if (is_committed_ || is_rolled_back_) {
- return Status::ILLEGAL_STATE;
- }
- data_.insert({key.ToString(), {key.ToString(), std::move(value), priority}});
- return Status::OK;
-}
-
-Status FakeJournalDelegate::Delete(convert::ExtendedStringView key) {
- if (is_committed_ || is_rolled_back_) {
- return Status::ILLEGAL_STATE;
- }
- auto it = data_.find(key);
- if (it != data_.end()) {
- data_.erase(it);
- }
- return Status::OK;
-}
-
-Status FakeJournalDelegate::Clear() {
- if (is_committed_ || is_rolled_back_) {
- return Status::ILLEGAL_STATE;
- }
- data_.clear();
- return Status::OK;
-}
-
-void FakeJournalDelegate::Commit(
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- if (is_committed_ || is_rolled_back_) {
- callback(Status::ILLEGAL_STATE, nullptr);
- return;
- }
-
- commit_callback_ = std::move(callback);
-
- if (autocommit_) {
- ResolvePendingCommit(Status::OK);
- }
-}
-
-bool FakeJournalDelegate::IsCommitted() const { return is_committed_; }
-
-Status FakeJournalDelegate::Rollback() {
- if (is_committed_ || is_rolled_back_) {
- return Status::ILLEGAL_STATE;
- }
- is_rolled_back_ = true;
- return Status::OK;
-}
-
-bool FakeJournalDelegate::IsRolledBack() const { return is_rolled_back_; }
-
-std::vector<CommitIdView> FakeJournalDelegate::GetParentIds() const {
- if (other_id_.empty()) {
- return {parent_id_};
- }
- return {parent_id_, other_id_};
-}
-
-bool FakeJournalDelegate::IsPendingCommit() {
- return static_cast<bool>(commit_callback_);
-}
-
-void FakeJournalDelegate::ResolvePendingCommit(Status /*status*/) {
- is_committed_ = true;
- auto callback = std::move(commit_callback_);
- commit_callback_ = nullptr;
- callback(Status::OK, std::make_unique<const FakeCommit>(this));
-}
-
-const FakeJournalDelegate::Data& FakeJournalDelegate::GetData() const {
- return data_;
-}
-
-} // namespace fake
-} // namespace storage
diff --git a/bin/ledger/storage/fake/fake_journal_delegate.h b/bin/ledger/storage/fake/fake_journal_delegate.h
deleted file mode 100644
index df51f51..0000000
--- a/bin/ledger/storage/fake/fake_journal_delegate.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_JOURNAL_DELEGATE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_JOURNAL_DELEGATE_H_
-
-#include <map>
-#include <string>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/random.h"
-
-namespace storage {
-namespace fake {
-
-// |FakeJournalDelegate| records the changes made through a journal. This
-// object is owned by |FakePageStorage| and outlives |FakeJournal|.
-class FakeJournalDelegate {
- public:
- using Data = std::map<std::string, Entry, convert::StringViewComparator>;
-
- // Regular commit.
- // |initial_data| must contain the content of the page when the transaction
- // starts.
- FakeJournalDelegate(rng::Random* random, Data initial_data,
- CommitId parent_id, bool autocommit, uint64_t generation);
- // Merge commit.
- // |initial_data| must contain the content of the page when the transaction
- // starts.
- FakeJournalDelegate(rng::Random* random, Data initial_data,
- CommitId parent_id, CommitId other_id, bool autocommit,
- uint64_t generation);
- ~FakeJournalDelegate();
-
- const CommitId& GetId() const { return id_; }
-
- Status SetValue(convert::ExtendedStringView key, ObjectIdentifier value,
- KeyPriority priority);
- Status Delete(convert::ExtendedStringView key);
- Status Clear();
-
- void Commit(
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback);
- bool IsCommitted() const;
-
- Status Rollback();
- bool IsRolledBack() const;
-
- uint64_t GetGeneration() const { return generation_; }
-
- std::vector<CommitIdView> GetParentIds() const;
-
- bool IsPendingCommit();
- void ResolvePendingCommit(Status status);
-
- const Data& GetData() const;
-
- private:
- bool autocommit_;
-
- const CommitId id_;
- const CommitId parent_id_;
- const CommitId other_id_;
- Data data_;
- uint64_t generation_;
-
- bool is_committed_ = false;
- bool is_rolled_back_ = false;
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- commit_callback_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeJournalDelegate);
-};
-
-} // namespace fake
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_JOURNAL_DELEGATE_H_
diff --git a/bin/ledger/storage/fake/fake_object.cc b/bin/ledger/storage/fake/fake_object.cc
deleted file mode 100644
index 3a12c26..0000000
--- a/bin/ledger/storage/fake/fake_object.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/fake/fake_object.h"
-
-namespace storage {
-namespace fake {
-
-FakeObject::FakeObject(ObjectIdentifier identifier, fxl::StringView content)
- : identifier_(std::move(identifier)), content_(content.ToString()) {}
-
-FakeObject::~FakeObject() {}
-
-ObjectIdentifier FakeObject::GetIdentifier() const { return identifier_; }
-
-Status FakeObject::GetData(fxl::StringView* data) const {
- *data = content_;
- return Status::OK;
-}
-
-} // namespace fake
-} // namespace storage
diff --git a/bin/ledger/storage/fake/fake_object.h b/bin/ledger/storage/fake/fake_object.h
deleted file mode 100644
index 3136f9a..0000000
--- a/bin/ledger/storage/fake/fake_object.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_OBJECT_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_OBJECT_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace fake {
-
-class FakeObject : public Object {
- public:
- FakeObject(ObjectIdentifier identifier, fxl::StringView content);
- ~FakeObject() override;
- ObjectIdentifier GetIdentifier() const override;
- Status GetData(fxl::StringView* data) const override;
-
- private:
- ObjectIdentifier identifier_;
- std::string content_;
-};
-
-} // namespace fake
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_OBJECT_H_
diff --git a/bin/ledger/storage/fake/fake_page_storage.cc b/bin/ledger/storage/fake/fake_page_storage.cc
deleted file mode 100644
index 7fba43e..0000000
--- a/bin/ledger/storage/fake/fake_page_storage.cc
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/concatenate.h>
-#include <lib/zx/time.h>
-
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/fake/fake_commit.h"
-#include "peridot/bin/ledger/storage/fake/fake_journal.h"
-#include "peridot/bin/ledger/storage/fake/fake_object.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-namespace fake {
-
-namespace {
-
-Status ToBuffer(convert::ExtendedStringView value, int64_t offset,
- int64_t max_size, fsl::SizedVmo* buffer) {
- size_t start = value.size();
- // Valid indices are between -N and N-1.
- if (offset >= -static_cast<int64_t>(value.size()) &&
- offset < static_cast<int64_t>(value.size())) {
- start = offset < 0 ? value.size() + offset : offset;
- }
- size_t length = max_size < 0 ? value.size() : max_size;
- bool result = fsl::VmoFromString(value.substr(start, length), buffer);
- return result ? Status::OK : Status::INTERNAL_IO_ERROR;
-}
-
-} // namespace
-
-FakePageStorage::FakePageStorage(ledger::Environment* environment,
- PageId page_id)
- : page_id_(std::move(page_id)),
- environment_(environment),
- encryption_service_(environment_->dispatcher()) {}
-
-FakePageStorage::~FakePageStorage() {}
-
-PageId FakePageStorage::GetId() { return page_id_; }
-
-void FakePageStorage::GetHeadCommitIds(
- fit::function<void(Status, std::vector<CommitId>)> callback) {
- std::vector<CommitId> commit_ids(heads_.begin(), heads_.end());
- if (commit_ids.empty()) {
- commit_ids.emplace_back();
- }
- callback(Status::OK, std::move(commit_ids));
-}
-
-void FakePageStorage::GetCommit(
- CommitIdView commit_id,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) {
- auto it = journals_.find(commit_id.ToString());
- if (it == journals_.end()) {
- callback(Status::NOT_FOUND, nullptr);
- return;
- }
-
- async::PostDelayedTask(
- environment_->dispatcher(),
- [this, commit_id = commit_id.ToString(), callback = std::move(callback)] {
- callback(Status::OK,
- std::make_unique<FakeCommit>(journals_[commit_id].get()));
- },
- kFakePageStorageDelay);
-}
-
-void FakePageStorage::StartCommit(
- const CommitId& commit_id, JournalType /*journal_type*/,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) {
- uint64_t next_generation = 0;
- FakeJournalDelegate::Data data;
- if (journals_.find(commit_id) != journals_.end()) {
- next_generation = journals_[commit_id].get()->GetGeneration() + 1;
- data = journals_[commit_id].get()->GetData();
- }
- auto delegate = std::make_unique<FakeJournalDelegate>(
- environment_->random(), std::move(data), commit_id, autocommit_,
- next_generation);
- auto journal = std::make_unique<FakeJournal>(delegate.get());
- journals_[delegate->GetId()] = std::move(delegate);
- callback(Status::OK, std::move(journal));
-}
-
-void FakePageStorage::StartMergeCommit(
- const CommitId& left, const CommitId& right,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) {
- auto delegate = std::make_unique<FakeJournalDelegate>(
- environment_->random(), journals_[left].get()->GetData(), left, right,
- autocommit_,
- 1 + std::max(journals_[left].get()->GetGeneration(),
- journals_[right].get()->GetGeneration()));
- auto journal = std::make_unique<FakeJournal>(delegate.get());
- journals_[delegate->GetId()] = std::move(delegate);
- callback(Status::OK, std::move(journal));
-}
-
-void FakePageStorage::CommitJournal(
- std::unique_ptr<Journal> journal,
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- static_cast<FakeJournal*>(journal.get())
- ->Commit([this, callback = std::move(callback)](
- Status status,
- std::unique_ptr<const storage::Commit> commit) {
- for (const storage::CommitIdView& parent_id : commit->GetParentIds()) {
- auto it = heads_.find(parent_id.ToString());
- if (it != heads_.end()) {
- heads_.erase(it);
- }
- }
- heads_.emplace(commit->GetId());
- if (!drop_commit_notifications_) {
- for (CommitWatcher* watcher : watchers_) {
- async::PostTask(
- environment_->dispatcher(),
- [watcher, commit = commit->Clone()]() mutable {
- std::vector<std::unique_ptr<const Commit>> commits;
- commits.push_back(std::move(commit));
- watcher->OnNewCommits(commits, ChangeSource::LOCAL);
- });
- }
- }
- callback(status, std::move(commit));
- });
-}
-
-void FakePageStorage::RollbackJournal(std::unique_ptr<Journal> journal,
- fit::function<void(Status)> callback) {
- callback(static_cast<FakeJournal*>(journal.get())->Rollback());
-}
-
-Status FakePageStorage::AddCommitWatcher(CommitWatcher* watcher) {
- watchers_.emplace(watcher);
- return Status::OK;
-}
-
-Status FakePageStorage::RemoveCommitWatcher(CommitWatcher* watcher) {
- auto it = watchers_.find(watcher);
- if (it != watchers_.end()) {
- watchers_.erase(it);
- }
- return Status::OK;
-}
-
-void FakePageStorage::IsSynced(fit::function<void(Status, bool)> callback) {
- callback(Status::OK, is_synced_);
-}
-
-void FakePageStorage::AddObjectFromLocal(
- ObjectType /*object_type*/, std::unique_ptr<DataSource> data_source,
- fit::function<void(Status, ObjectIdentifier)> callback) {
- auto value = std::make_unique<std::string>();
- auto data_source_ptr = data_source.get();
- data_source_ptr->Get([this, data_source = std::move(data_source),
- value = std::move(value),
- callback = std::move(callback)](
- std::unique_ptr<DataSource::DataChunk> chunk,
- DataSource::Status status) mutable {
- if (status == DataSource::Status::ERROR) {
- callback(Status::IO_ERROR, {});
- return;
- }
- auto view = chunk->Get();
- value->append(view.data(), view.size());
- if (status == DataSource::Status::DONE) {
- ObjectIdentifier object_identifier =
- encryption_service_.MakeObjectIdentifier(FakeDigest(*value));
- objects_[object_identifier] = std::move(*value);
- callback(Status::OK, std::move(object_identifier));
- }
- });
-}
-
-void FakePageStorage::GetObject(
- ObjectIdentifier object_identifier, Location /*location*/,
- fit::function<void(Status, std::unique_ptr<const Object>)> callback) {
- GetPiece(object_identifier, std::move(callback));
-}
-
-void FakePageStorage::GetObjectPart(
- ObjectIdentifier object_identifier, int64_t offset, int64_t max_size,
- Location location, fit::function<void(Status, fsl::SizedVmo)> callback) {
- GetPiece(object_identifier,
- [offset, max_size, callback = std::move(callback)](
- Status status, std::unique_ptr<const Object> piece) {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- fxl::StringView data;
- Status data_status = piece->GetData(&data);
- if (data_status != Status::OK) {
- callback(data_status, nullptr);
- return;
- }
- fsl::SizedVmo buffer;
- Status buffer_status = ToBuffer(data, offset, max_size, &buffer);
- if (buffer_status != Status::OK) {
- callback(buffer_status, nullptr);
- return;
- }
- callback(Status::OK, std::move(buffer));
- });
-}
-
-void FakePageStorage::GetPiece(
- ObjectIdentifier object_identifier,
- fit::function<void(Status, std::unique_ptr<const Object>)> callback) {
- object_requests_.emplace_back(
- [this, object_identifier = std::move(object_identifier),
- callback = std::move(callback)] {
- auto it = objects_.find(object_identifier);
- if (it == objects_.end()) {
- callback(Status::NOT_FOUND, nullptr);
- return;
- }
-
- callback(Status::OK,
- std::make_unique<FakeObject>(object_identifier, it->second));
- });
- async::PostDelayedTask(
- environment_->dispatcher(), [this] { SendNextObject(); },
- kFakePageStorageDelay);
-}
-
-void FakePageStorage::GetCommitContents(const Commit& commit,
- std::string min_key,
- fit::function<bool(Entry)> on_next,
- fit::function<void(Status)> on_done) {
- FakeJournalDelegate* journal = journals_[commit.GetId()].get();
- if (!journal) {
- on_done(Status::NOT_FOUND);
- return;
- }
-
- for (auto it = journal->GetData().lower_bound(min_key);
- it != journal->GetData().end(); ++it) {
- if (!on_next(it->second)) {
- break;
- }
- }
- on_done(Status::OK);
-}
-
-void FakePageStorage::GetEntryFromCommit(
- const Commit& commit, std::string key,
- fit::function<void(Status, Entry)> callback) {
- FakeJournalDelegate* journal = journals_[commit.GetId()].get();
- if (!journal) {
- callback(Status::NOT_FOUND, Entry());
- return;
- }
- const fake::FakeJournalDelegate::Data& data = journal->GetData();
- auto it = data.find(key);
- if (it == data.end()) {
- callback(Status::NOT_FOUND, Entry());
- return;
- }
- callback(Status::OK, it->second);
-}
-
-const std::map<std::string, std::unique_ptr<FakeJournalDelegate>>&
-FakePageStorage::GetJournals() const {
- return journals_;
-}
-
-const std::map<ObjectIdentifier, std::string>& FakePageStorage::GetObjects()
- const {
- return objects_;
-}
-
-ObjectDigest FakePageStorage::FakeDigest(fxl::StringView value) const {
- // Builds a fake ObjectDigest by computing the hash of |value|, and prefixes
- // it with 0xFACEFEED to intentionally make it longer than real object
- // digests, start with a 1 bit, and easy to spot in logs. This is incompatible
- // with real object digests, but is enough for a fake because all clients of
- // the fake should treat object digests as opaque blobs.
- return ObjectDigest(fxl::Concatenate(
- {"\xFA\xCE\xFE\xED", encryption::SHA256WithLengthHash(value)}));
-}
-
-void FakePageStorage::SendNextObject() {
- auto rng = environment_->random()->NewBitGenerator<uint64_t>();
- std::uniform_int_distribution<size_t> distribution(
- 0u, object_requests_.size() - 1);
- auto it = object_requests_.begin() + distribution(rng);
- auto closure = std::move(*it);
- object_requests_.erase(it);
- closure();
-}
-
-void FakePageStorage::DeleteObjectFromLocal(
- const ObjectIdentifier& object_identifier) {
- objects_.erase(object_identifier);
-}
-
-void FakePageStorage::SetDropCommitNotifications(bool drop) {
- drop_commit_notifications_ = drop;
-}
-
-} // namespace fake
-} // namespace storage
diff --git a/bin/ledger/storage/fake/fake_page_storage.h b/bin/ledger/storage/fake/fake_page_storage.h
deleted file mode 100644
index 836a413..0000000
--- a/bin/ledger/storage/fake/fake_page_storage.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_PAGE_STORAGE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_PAGE_STORAGE_H_
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/storage/fake/fake_journal_delegate.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-namespace storage {
-namespace fake {
-
-// The delay for which tasks are posted by the FakePageStorage methods
-// GetCommit() and GetPiece().
-constexpr zx::duration kFakePageStorageDelay = zx::msec(5);
-
-class FakePageStorage : public PageStorageEmptyImpl {
- public:
- FakePageStorage(ledger::Environment* environment, PageId page_id);
- ~FakePageStorage() override;
-
- // PageStorage:
- PageId GetId() override;
- void GetHeadCommitIds(
- fit::function<void(Status, std::vector<CommitId>)> callback) override;
- void GetCommit(CommitIdView commit_id,
- fit::function<void(Status, std::unique_ptr<const Commit>)>
- callback) override;
- void StartCommit(
- const CommitId& commit_id, JournalType journal_type,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) override;
- void StartMergeCommit(
- const CommitId& left, const CommitId& right,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) override;
- void CommitJournal(
- std::unique_ptr<Journal> journal,
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) override;
- void RollbackJournal(std::unique_ptr<Journal> journal,
- fit::function<void(Status)> callback) override;
- Status AddCommitWatcher(CommitWatcher* watcher) override;
- Status RemoveCommitWatcher(CommitWatcher* watcher) override;
- void IsSynced(fit::function<void(Status, bool)> callback) override;
- void AddObjectFromLocal(
- ObjectType object_type, std::unique_ptr<DataSource> data_source,
- fit::function<void(Status, ObjectIdentifier)> callback) override;
- void GetObjectPart(
- ObjectIdentifier object_identifier, int64_t offset, int64_t max_size,
- Location location,
- fit::function<void(Status, fsl::SizedVmo)> callback) override;
- void GetObject(ObjectIdentifier object_identifier, Location location,
- fit::function<void(Status, std::unique_ptr<const Object>)>
- callback) override;
- void GetPiece(ObjectIdentifier object_identifier,
- fit::function<void(Status, std::unique_ptr<const Object>)>
- callback) override;
- void GetCommitContents(const Commit& commit, std::string min_key,
- fit::function<bool(Entry)> on_next,
- fit::function<void(Status)> on_done) override;
- void GetEntryFromCommit(const Commit& commit, std::string key,
- fit::function<void(Status, Entry)> callback) override;
-
- // For testing:
- void set_autocommit(bool autocommit) { autocommit_ = autocommit; }
- void set_synced(bool is_synced) { is_synced_ = is_synced; }
-
- const std::map<std::string, std::unique_ptr<FakeJournalDelegate>>&
- GetJournals() const;
-
- const std::map<ObjectIdentifier, std::string>& GetObjects() const;
-
- // Deletes this object from the fake local storage, but keeps it in its
- // "network" storage.
- void DeleteObjectFromLocal(const ObjectIdentifier& object_identifier);
-
- // If set to true, no commit notification is sent to the commit watchers.
- void SetDropCommitNotifications(bool drop);
-
- protected:
- // Returns an ObjectDigest (for use in the object identifier returned by
- // AddObjectFromLocal).
- // By default, fake object digests are invalid to ensure external clients do
- // not rely implicitly on the internal encoding. Specific tests can override
- // this method if they need valid object digests instead.
- virtual ObjectDigest FakeDigest(fxl::StringView value) const;
-
- PageId page_id_;
-
- private:
- void SendNextObject();
-
- bool autocommit_ = true;
- bool drop_commit_notifications_ = false;
- bool is_synced_ = false;
-
- ledger::Environment* const environment_;
- std::map<std::string, std::unique_ptr<FakeJournalDelegate>> journals_;
- std::map<ObjectIdentifier, std::string> objects_;
- std::set<CommitId> heads_;
- std::set<CommitWatcher*> watchers_;
- std::vector<fit::closure> object_requests_;
- encryption::FakeEncryptionService encryption_service_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakePageStorage);
-};
-
-} // namespace fake
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_FAKE_FAKE_PAGE_STORAGE_H_
diff --git a/bin/ledger/storage/impl/BUILD.gn b/bin/ledger/storage/impl/BUILD.gn
deleted file mode 100644
index d903764..0000000
--- a/bin/ledger/storage/impl/BUILD.gn
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("impl") {
- deps = [
- ":lib",
- "//peridot/bin/ledger/storage/impl/btree",
- ]
-}
-
-flatbuffer("object_identifier") {
- sources = [
- "object_identifier.fbs",
- ]
-
- extra_configs = [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-flatbuffer("commit_storage") {
- sources = [
- "commit.fbs",
- ]
-
- public_deps = [
- ":object_identifier",
- ]
-
- extra_configs = [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-flatbuffer("file_index") {
- sources = [
- "file_index.fbs",
- ]
-
- extra_configs = [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("object_identifier_lib") {
- sources = [
- "constants.h",
- "object_digest.cc",
- "object_digest.h",
- "object_identifier_encoding.cc",
- "object_identifier_encoding.h",
- ]
-
- deps = [
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/encryption/public",
- ]
-
- public_deps = [
- ":object_identifier",
- "//peridot/bin/ledger/storage/public",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("lib") {
- sources = [
- "commit_impl.cc",
- "commit_impl.h",
- "data_serialization.h",
- "db_serialization.cc",
- "db_serialization.h",
- "file_index.cc",
- "file_index.h",
- "journal_impl.cc",
- "journal_impl.h",
- "ledger_storage_impl.cc",
- "ledger_storage_impl.h",
- "leveldb.cc",
- "leveldb.h",
- "leveldb_factory.cc",
- "leveldb_factory.h",
- "object_impl.cc",
- "object_impl.h",
- "page_db.h",
- "page_db_batch_impl.cc",
- "page_db_batch_impl.h",
- "page_db_impl.cc",
- "page_db_impl.h",
- "page_storage_impl.cc",
- "page_storage_impl.h",
- "split.cc",
- "split.h",
- ]
-
- deps = [
- ":commit_storage",
- ":file_index",
- ":object_identifier_lib",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/cobalt",
- "//peridot/bin/ledger/encryption/impl",
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/encryption/public",
- "//peridot/bin/ledger/environment",
- "//peridot/bin/ledger/filesystem",
- "//peridot/bin/ledger/lock",
- "//peridot/bin/ledger/storage/impl/btree:lib",
- "//peridot/bin/ledger/storage/public",
- "//peridot/lib/base64url",
- "//zircon/public/lib/trace",
- ]
-
- public_deps = [
- ":object_identifier_lib",
- "//peridot/bin/ledger/coroutine",
- "//peridot/lib/convert",
- "//peridot/third_party/bup",
- "//third_party/leveldb",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("test_utils") {
- testonly = true
-
- sources = [
- "storage_test_utils.cc",
- "storage_test_utils.h",
- ]
-
- deps = [
- ":lib",
- "//garnet/public/lib/callback",
- "//peridot/bin/ledger/encryption/fake",
- "//peridot/bin/ledger/encryption/primitives",
- ]
-
- public_deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/storage/impl/btree:lib",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/rng",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "commit_impl_unittest.cc",
- "commit_random_impl.cc",
- "commit_random_impl.h",
- "file_index_unittest.cc",
- "ledger_storage_unittest.cc",
- "leveldb_factory_unittest.cc",
- "object_digest_unittest.cc",
- "object_impl_unittest.cc",
- "page_db_empty_impl.cc",
- "page_db_empty_impl.h",
- "page_db_unittest.cc",
- "page_storage_unittest.cc",
- "split_unittest.cc",
- ]
-
- deps = [
- ":file_index",
- ":lib",
- ":test_utils",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/fxl/test",
- "//peridot/bin/ledger/cloud_sync/impl",
- "//peridot/bin/ledger/encryption/fake",
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/storage/fake:lib",
- "//peridot/bin/ledger/storage/impl/btree:lib",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/storage/testing",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/rng",
- "//peridot/lib/scoped_tmpfs",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/storage/impl/btree/BUILD.gn b/bin/ledger/storage/impl/btree/BUILD.gn
deleted file mode 100644
index 22070d1..0000000
--- a/bin/ledger/storage/impl/btree/BUILD.gn
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fuzzing/fuzzer.gni")
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("btree") {
- deps = [
- ":lib",
- ]
-}
-
-source_set("lib") {
- sources = [
- "builder.cc",
- "builder.h",
- "diff.cc",
- "diff.h",
- "encoding.cc",
- "encoding.h",
- "entry_change_iterator.h",
- "iterator.cc",
- "iterator.h",
- "synchronous_storage.cc",
- "synchronous_storage.h",
- "tree_node.cc",
- "tree_node.h",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/coroutine",
- ]
-
- deps = [
- ":internal",
- ":tree_node_storage",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/storage/impl:object_identifier_lib",
- "//peridot/bin/ledger/storage/public",
- "//peridot/lib/convert",
- "//third_party/murmurhash",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-flatbuffer("tree_node_storage") {
- sources = [
- "tree_node.fbs",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/storage/impl:object_identifier",
- ]
-
- extra_configs = [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("internal") {
- sources = [
- "internal_helper.cc",
- "internal_helper.h",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/storage/public",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "btree_utils_unittest.cc",
- "diff_unittest.cc",
- "encoding_unittest.cc",
- "tree_node_unittest.cc",
- ]
-
- deps = [
- ":lib",
- ":tree_node_storage",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/encryption/fake",
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/storage/fake:lib",
- "//peridot/bin/ledger/storage/impl:object_identifier_lib",
- "//peridot/bin/ledger/storage/impl:test_utils",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/storage/testing",
- "//peridot/bin/ledger/testing:lib",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-fuzz_target("encoding_fuzzer") {
- sources = [
- "encoding_fuzztest.cc",
- ]
- deps = [
- ":lib",
- "//peridot/bin/ledger/storage/public",
- ]
- corpora =
- [ "848002de6109d94118c57d79b2a8c0cfbd16ba8691bb390e3eb7437089ad99cc" ]
-}
diff --git a/bin/ledger/storage/impl/btree/btree_utils_unittest.cc b/bin/ledger/storage/impl/btree/btree_utils_unittest.cc
deleted file mode 100644
index 85a2e16..0000000
--- a/bin/ledger/storage/impl/btree/btree_utils_unittest.cc
+++ /dev/null
@@ -1,888 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <algorithm>
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/arraysize.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-#include "peridot/bin/ledger/storage/impl/btree/builder.h"
-#include "peridot/bin/ledger/storage/impl/btree/diff.h"
-#include "peridot/bin/ledger/storage/impl/btree/entry_change_iterator.h"
-#include "peridot/bin/ledger/storage/impl/btree/iterator.h"
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace btree {
-namespace {
-// Pre-determined node level function.
-uint8_t GetTestNodeLevel(convert::ExtendedStringView key) {
- if (key == "key03" || key == "key07" || key == "key30" || key == "key60" ||
- key == "key89") {
- return 1;
- }
-
- if (key == "key50" || key == "key75") {
- return 2;
- }
-
- return 0;
-}
-
-constexpr NodeLevelCalculator kTestNodeLevelCalculator = {&GetTestNodeLevel};
-
-class TrackGetObjectFakePageStorage : public fake::FakePageStorage {
- public:
- explicit TrackGetObjectFakePageStorage(ledger::Environment* environment,
- PageId id)
- : fake::FakePageStorage(environment, id) {}
- ~TrackGetObjectFakePageStorage() override {}
-
- void GetObject(ObjectIdentifier object_identifier, Location location,
- fit::function<void(Status, std::unique_ptr<const Object>)>
- callback) override {
- object_requests.insert(object_identifier);
- fake::FakePageStorage::GetObject(std::move(object_identifier), location,
- std::move(callback));
- }
-
- std::set<ObjectIdentifier> object_requests;
-
- protected:
- ObjectDigest FakeDigest(fxl::StringView content) const override {
- // BTree code needs storage to return valid digests.
- return MakeObjectDigest(content.ToString());
- }
-};
-
-class BTreeUtilsTest : public StorageTest {
- public:
- BTreeUtilsTest() : fake_storage_(&environment_, "page_id") {}
-
- ~BTreeUtilsTest() override {}
-
- // Test:
- void SetUp() override {
- ::testing::Test::SetUp();
- std::srand(0);
- }
-
- protected:
- PageStorage* GetStorage() override { return &fake_storage_; }
-
- ObjectIdentifier CreateTree(const std::vector<EntryChange>& entries) {
- ObjectIdentifier base_node_identifier;
- EXPECT_TRUE(GetEmptyNodeIdentifier(&base_node_identifier));
-
- ObjectIdentifier new_root_identifier;
- EXPECT_TRUE(CreateTreeFromChanges(base_node_identifier, entries,
- &new_root_identifier));
- return new_root_identifier;
- }
-
- std::vector<Entry> GetEntriesList(ObjectIdentifier root_identifier) {
- std::vector<Entry> entries;
- auto on_next = [&entries](EntryAndNodeIdentifier entry) {
- entries.push_back(entry.entry);
- return true;
- };
- auto on_done = [this](Status status) {
- EXPECT_EQ(Status::OK, status);
- QuitLoop();
- };
- ForEachEntry(environment_.coroutine_service(), &fake_storage_,
- root_identifier, "", std::move(on_next), std::move(on_done));
- RunLoopFor(kSufficientDelay);
- return entries;
- }
-
- TrackGetObjectFakePageStorage fake_storage_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(BTreeUtilsTest);
-};
-
-TEST_F(BTreeUtilsTest, GetNodeLevel) {
- size_t level_distribution[4];
- memset(level_distribution, 0, sizeof(level_distribution));
-
- for (size_t i = 0; i < 1000; ++i) {
- fxl::StringView key(reinterpret_cast<char*>(&i), sizeof(i));
- uint8_t node_level =
- std::min(arraysize(level_distribution) - 1,
- static_cast<size_t>(
- GetDefaultNodeLevelCalculator()->GetNodeLevel(key)));
- level_distribution[node_level]++;
- }
-
- EXPECT_TRUE(std::is_sorted(level_distribution,
- level_distribution + arraysize(level_distribution),
- [](int v1, int v2) { return v2 < v1; }));
- EXPECT_NE(0u, level_distribution[1]);
-}
-
-TEST_F(BTreeUtilsTest, ApplyChangesFromEmpty) {
- ObjectIdentifier root_identifier;
- ASSERT_TRUE(GetEmptyNodeIdentifier(&root_identifier));
- std::vector<EntryChange> changes;
- ASSERT_TRUE(CreateEntryChanges(3, &changes));
-
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- // Expected layout (X is key "keyX"):
- // [00, 01, 02]
- ApplyChanges(
- environment_.coroutine_service(), &fake_storage_, root_identifier,
- std::make_unique<EntryChangeIterator>(changes.begin(), changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(1u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(changes.size(), entries.size());
- for (size_t i = 0; i < entries.size(); ++i) {
- EXPECT_EQ(changes[i].entry, entries[i]);
- }
-}
-
-TEST_F(BTreeUtilsTest, ApplyChangeSingleLevel1Entry) {
- ObjectIdentifier root_identifier;
- ASSERT_TRUE(GetEmptyNodeIdentifier(&root_identifier));
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(std::vector<size_t>({3}), &golden_entries));
-
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- // Expected layout (XX is key "keyXX"):
- // [03]
-
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(golden_entries.begin(),
- golden_entries.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(1u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(golden_entries.size(), entries.size());
- for (size_t i = 0; i < golden_entries.size(); ++i) {
- EXPECT_EQ(golden_entries[i].entry, entries[i]);
- }
-}
-
-TEST_F(BTreeUtilsTest, ApplyChangesManyEntries) {
- ObjectIdentifier root_identifier;
- ASSERT_TRUE(GetEmptyNodeIdentifier(&root_identifier));
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(11, &golden_entries));
-
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01, 02] [04, 05, 06] [08, 09, 10]
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(golden_entries.begin(),
- golden_entries.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(4u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(golden_entries.size(), entries.size());
- for (size_t i = 0; i < golden_entries.size(); ++i) {
- EXPECT_EQ(golden_entries[i].entry, entries[i]);
- }
-
- Entry new_entry = {"key071", MakeObjectIdentifier("object_digest_071"),
- KeyPriority::EAGER};
- std::vector<EntryChange> new_change{EntryChange{new_entry, false}};
- // Insert key "071" between keys "07" and "08".
- golden_entries.insert(golden_entries.begin() + 8, new_change[0]);
-
- new_nodes.clear();
- ObjectIdentifier new_root_identifier2;
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01, 02] [04, 05, 06] [071, 08, 09, 10]
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- new_root_identifier,
- std::make_unique<EntryChangeIterator>(new_change.begin(),
- new_change.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier2, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_NE(new_root_identifier, new_root_identifier2);
- // The root and the 3rd child have changed.
- EXPECT_EQ(2u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier2) != new_nodes.end());
-
- entries = GetEntriesList(new_root_identifier2);
- ASSERT_EQ(golden_entries.size(), entries.size());
- for (size_t i = 0; i < golden_entries.size(); ++i) {
- EXPECT_EQ(golden_entries[i].entry, entries[i]);
- }
-}
-
-TEST_F(BTreeUtilsTest, UpdateValue) {
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01, 02] [04, 05, 06] [08, 09, 10, 11]
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(11, &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Update entry.
- std::vector<Entry> entries_to_update{golden_entries[2].entry};
- std::vector<EntryChange> update_changes;
- for (size_t i = 0; i < entries_to_update.size(); ++i) {
- std::unique_ptr<const Object> object;
- ASSERT_TRUE(
- AddObject(fxl::StringPrintf("new_object%02" PRIuMAX, i), &object));
- entries_to_update[i].object_identifier = object->GetIdentifier();
- update_changes.push_back(EntryChange{entries_to_update[i], false});
- }
-
- // Expected layout is unchanged.
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(update_changes.begin(),
- update_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_NE(root_identifier, new_root_identifier);
- // The root and the first child have changed.
- EXPECT_EQ(2u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(golden_entries.size(), entries.size());
- size_t updated_index = 0;
- for (size_t i = 0; i < golden_entries.size(); ++i) {
- if (updated_index < entries_to_update.size() &&
- golden_entries[i].entry.key == entries_to_update[updated_index].key) {
- EXPECT_EQ(entries_to_update[updated_index], entries[i]);
- // Skip the updated entries.
- updated_index++;
- continue;
- }
- EXPECT_EQ(golden_entries[i].entry, entries[i]);
- }
-}
-
-TEST_F(BTreeUtilsTest, UpdateValueLevel1) {
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01, 02] [04, 05, 06] [08, 09, 10, 11]
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(11, &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Update entry.
- std::vector<Entry> entries_to_update{golden_entries[3].entry};
- std::vector<EntryChange> update_changes;
- for (size_t i = 0; i < entries_to_update.size(); ++i) {
- std::unique_ptr<const Object> object;
- ASSERT_TRUE(
- AddObject(fxl::StringPrintf("new_object%02" PRIuMAX, i), &object));
- entries_to_update[i].object_identifier = object->GetIdentifier();
- update_changes.push_back(EntryChange{entries_to_update[i], false});
- }
-
- // Expected layout is unchanged.
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(update_changes.begin(),
- update_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_NE(root_identifier, new_root_identifier);
- // Only the root has changed.
- EXPECT_EQ(1u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(golden_entries.size(), entries.size());
- size_t updated_index = 0;
- for (size_t i = 0; i < golden_entries.size(); ++i) {
- if (updated_index < entries_to_update.size() &&
- golden_entries[i].entry.key == entries_to_update[updated_index].key) {
- EXPECT_EQ(entries_to_update[updated_index], entries[i]);
- // Skip the updated entries.
- updated_index++;
- continue;
- }
- EXPECT_EQ(golden_entries[i].entry, entries[i]);
- }
-}
-
-TEST_F(BTreeUtilsTest, UpdateValueSplitChange) {
- // Expected layout (XX is key "keyXX"):
- // [00, 04]
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(std::vector<size_t>({
- 0,
- 4,
- }),
- &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Add level 1 entry.
- std::vector<EntryChange> update_changes;
- ASSERT_TRUE(CreateEntryChanges(std::vector<size_t>({3}), &update_changes));
- // Expected layout (XX is key "keyXX"):
- // [03]
- // / \
- // [00] [04]
-
- // Apply update.
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(update_changes.begin(),
- update_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_NE(root_identifier, new_root_identifier);
- // The tree nodes are new.
- EXPECT_EQ(3u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(golden_entries.size() + update_changes.size(), entries.size());
- size_t updated_index = 0;
- for (size_t i = 0; i < entries.size(); ++i) {
- if (updated_index < update_changes.size() &&
- entries[i] == update_changes[updated_index].entry) {
- // Skip the updated entries.
- updated_index++;
- continue;
- }
- ASSERT_GT(golden_entries.size(), i - updated_index);
- EXPECT_EQ(golden_entries[i - updated_index].entry, entries[i]);
- }
-}
-
-TEST_F(BTreeUtilsTest, NoOpUpdateChange) {
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01, 02] [04, 05, 06] [08, 09, 10, 11]
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(11, &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Apply all entries again.
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(golden_entries.begin(),
- golden_entries.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(root_identifier, new_root_identifier);
- // The root and the first child have changed.
- EXPECT_EQ(0u, new_nodes.size());
-}
-
-TEST_F(BTreeUtilsTest, DeleteChanges) {
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01, 02] [04, 05, 06] [08, 09, 10, 11]
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(11, &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Delete entries.
- std::vector<EntryChange> delete_changes;
- ASSERT_TRUE(
- CreateEntryChanges(std::vector<size_t>({2, 4}), &delete_changes, true));
-
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01] [05, 06] [08, 09, 10, 11]
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(delete_changes.begin(),
- delete_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_NE(root_identifier, new_root_identifier);
- // The root and the first 2 children have changed.
- EXPECT_EQ(3u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(golden_entries.size() - delete_changes.size(), entries.size());
- size_t deleted_index = 0;
- for (size_t i = 0; i < golden_entries.size(); ++i) {
- if (deleted_index < delete_changes.size() &&
- golden_entries[i].entry.key ==
- delete_changes[deleted_index].entry.key) {
- // Skip the deleted entries.
- deleted_index++;
- continue;
- }
- ASSERT_LT(i - deleted_index, entries.size());
- EXPECT_EQ(golden_entries[i].entry, entries[i - deleted_index]);
- }
-}
-
-TEST_F(BTreeUtilsTest, DeleteLevel1Changes) {
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01, 02] [04, 05, 06] [08, 09, 10, 11]
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(11, &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Delete entry.
- std::vector<EntryChange> delete_changes;
- ASSERT_TRUE(
- CreateEntryChanges(std::vector<size_t>({3}), &delete_changes, true));
-
- // Expected layout (XX is key "keyXX"):
- // [07]
- // / \
- // [00, 01, 02, 04, 05, 06] [08, 09, 10, 11]
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(delete_changes.begin(),
- delete_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_NE(root_identifier, new_root_identifier);
- // The root and one child have changed.
- EXPECT_EQ(2u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(golden_entries.size() - delete_changes.size(), entries.size());
- size_t deleted_index = 0;
- for (size_t i = 0; i < golden_entries.size(); ++i) {
- if (deleted_index < delete_changes.size() &&
- golden_entries[i].entry.key ==
- delete_changes[deleted_index].entry.key) {
- // Skip the deleted entries.
- deleted_index++;
- continue;
- }
- ASSERT_LT(i - deleted_index, entries.size());
- EXPECT_EQ(golden_entries[i].entry, entries[i - deleted_index]);
- }
-}
-
-TEST_F(BTreeUtilsTest, NoOpDeleteChange) {
- // Expected layout (XX is key "keyXX"):
- // [03, 07]
- // / | \
- // [00, 01, 02] [04, 05, 06] [08, 09, 10, 11]
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(11, &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Delete entry.
- std::vector<EntryChange> delete_changes;
- ASSERT_TRUE(CreateEntryChanges(std::vector<size_t>({12, 13, 14}),
- &delete_changes, true));
-
- // Apply deletion.
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(delete_changes.begin(),
- delete_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(root_identifier, new_root_identifier);
- // The root and the first child have changed.
- EXPECT_EQ(0u, new_nodes.size());
-}
-
-TEST_F(BTreeUtilsTest, SplitMergeUpdate) {
- // Expected layout (XX is key "keyXX"):
- // [50]
- // / \
- // [03] [60, 89]
- // / | \
- // [55] [65, 74, 76] [99]
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(
- std::vector<size_t>({3, 50, 55, 60, 65, 74, 76, 89, 99}),
- &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Add level 2 entry.
- std::vector<EntryChange> update_changes;
- ASSERT_TRUE(CreateEntryChanges(std::vector<size_t>({75}), &update_changes));
- // Expected layout (XX is key "keyXX"):
- // [50, 75]
- // / | \
- // [03] [60] [89]
- // / \ / \
- // [55] [65, 74] [76] [99]
-
- // Apply update.
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(update_changes.begin(),
- update_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_NE(root_identifier, new_root_identifier);
- // The tree nodes are new.
- EXPECT_EQ(5u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-
- std::vector<Entry> entries = GetEntriesList(new_root_identifier);
- ASSERT_EQ(golden_entries.size() + update_changes.size(), entries.size());
- size_t updated_index = 0;
- for (size_t i = 0; i < entries.size(); ++i) {
- if (updated_index < update_changes.size() &&
- entries[i] == update_changes[updated_index].entry) {
- // Skip the updated entries.
- updated_index++;
- continue;
- }
- ASSERT_LT(i - updated_index, golden_entries.size());
- EXPECT_EQ(golden_entries[i - updated_index].entry, entries[i]);
- }
-
- // Remove the new entry.
- std::vector<EntryChange> delete_changes;
- ASSERT_TRUE(
- CreateEntryChanges(std::vector<size_t>({75}), &delete_changes, true));
-
- ObjectIdentifier final_node_identifier;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- new_root_identifier,
- std::make_unique<EntryChangeIterator>(delete_changes.begin(),
- delete_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &final_node_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(root_identifier, final_node_identifier);
-}
-
-TEST_F(BTreeUtilsTest, DeleteAll) {
- // Create an initial tree.
- std::vector<size_t> values({0, 1, 2, 3, 4, 5, 6, 7});
- std::vector<EntryChange> golden_entries;
- ASSERT_TRUE(CreateEntryChanges(values, &golden_entries));
- ObjectIdentifier root_identifier = CreateTree(golden_entries);
-
- // Delete everything.
- std::vector<EntryChange> delete_changes;
- ASSERT_TRUE(CreateEntryChanges(values, &delete_changes, true));
- // Apply update.
- bool called;
- Status status;
- ObjectIdentifier new_root_identifier;
- std::set<ObjectIdentifier> new_nodes;
- ApplyChanges(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- std::make_unique<EntryChangeIterator>(delete_changes.begin(),
- delete_changes.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_NE(root_identifier, new_root_identifier);
- EXPECT_TRUE(new_root_identifier.object_digest().IsValid());
- // The empty node is new.
- EXPECT_EQ(1u, new_nodes.size());
- EXPECT_TRUE(new_nodes.find(new_root_identifier) != new_nodes.end());
-}
-
-TEST_F(BTreeUtilsTest, GetObjectIdentifiersFromEmpty) {
- ObjectIdentifier root_identifier;
- ASSERT_TRUE(GetEmptyNodeIdentifier(&root_identifier));
- bool called;
- Status status;
- std::set<ObjectIdentifier> object_identifiers;
- GetObjectIdentifiers(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &object_identifiers));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(1u, object_identifiers.size());
- EXPECT_TRUE(object_identifiers.find(root_identifier) !=
- object_identifiers.end());
-}
-
-TEST_F(BTreeUtilsTest, GetObjectOneNodeTree) {
- std::vector<EntryChange> entries;
- ASSERT_TRUE(CreateEntryChanges(4, &entries));
- ObjectIdentifier root_identifier = CreateTree(entries);
-
- bool called;
- Status status;
- std::set<ObjectIdentifier> object_identifiers;
- GetObjectIdentifiers(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &object_identifiers));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(6u, object_identifiers.size());
- EXPECT_TRUE(object_identifiers.find(root_identifier) !=
- object_identifiers.end());
- for (EntryChange& e : entries) {
- EXPECT_TRUE(object_identifiers.find(e.entry.object_identifier) !=
- object_identifiers.end());
- }
-}
-
-TEST_F(BTreeUtilsTest, GetObjectIdentifiersBigTree) {
- std::vector<EntryChange> entries;
- ASSERT_TRUE(CreateEntryChanges(99, &entries));
- ObjectIdentifier root_identifier = CreateTree(entries);
-
- bool called;
- Status status;
- std::set<ObjectIdentifier> object_identifiers;
- GetObjectIdentifiers(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &object_identifiers));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(99u + 12, object_identifiers.size());
- EXPECT_TRUE(object_identifiers.find(root_identifier) !=
- object_identifiers.end());
- for (EntryChange& e : entries) {
- EXPECT_TRUE(object_identifiers.find(e.entry.object_identifier) !=
- object_identifiers.end());
- }
-}
-
-TEST_F(BTreeUtilsTest, GetObjectsFromSync) {
- std::vector<EntryChange> entries;
- ASSERT_TRUE(CreateEntryChanges(5, &entries));
- entries[3].entry.priority = KeyPriority::LAZY;
- ObjectIdentifier root_identifier = CreateTree(entries);
-
- fake_storage_.object_requests.clear();
- bool called;
- Status status;
- // Expected layout (XX is key "keyXX"):
- // [03]
- // / \
- // [00, 01, 02] [04]
- GetObjectsFromSync(
- environment_.coroutine_service(), &fake_storage_, root_identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-
- std::vector<ObjectIdentifier> object_requests;
- std::copy(fake_storage_.object_requests.begin(),
- fake_storage_.object_requests.end(),
- std::back_inserter(object_requests));
- // There are 8 objects: 3 nodes and 4 eager values and 1 lazy. Except from the
- // lazy object, all others should have been requested.
- EXPECT_EQ(3 + 4u, object_requests.size());
-
- std::set<ObjectIdentifier> object_identifiers;
- GetObjectIdentifiers(environment_.coroutine_service(), &fake_storage_,
- root_identifier,
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &object_identifiers));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- ASSERT_EQ(3 + 5u, object_identifiers.size());
- for (ObjectIdentifier& identifier : object_requests) {
- // entries[3] contains the lazy value.
- if (identifier != entries[3].entry.object_identifier) {
- EXPECT_TRUE(object_identifiers.find(identifier) !=
- object_identifiers.end());
- }
- }
-}
-
-TEST_F(BTreeUtilsTest, ForEachEmptyTree) {
- std::vector<EntryChange> entries = {};
- ObjectIdentifier root_identifier = CreateTree(entries);
- auto on_next = [](EntryAndNodeIdentifier e) {
- // Fail: There are no elements in the tree.
- EXPECT_TRUE(false);
- return false;
- };
- auto on_done = [this](Status status) {
- EXPECT_EQ(Status::OK, status);
- QuitLoop();
- };
- ForEachEntry(environment_.coroutine_service(), &fake_storage_,
- root_identifier, "", std::move(on_next), std::move(on_done));
- RunLoopFor(kSufficientDelay);
-}
-
-TEST_F(BTreeUtilsTest, ForEachAllEntries) {
- // Create a tree from entries with keys from 00-99.
- std::vector<EntryChange> entries;
- ASSERT_TRUE(CreateEntryChanges(100, &entries));
- ObjectIdentifier root_identifier = CreateTree(entries);
-
- int current_key = 0;
- auto on_next = [¤t_key](EntryAndNodeIdentifier e) {
- EXPECT_EQ(fxl::StringPrintf("key%02d", current_key), e.entry.key);
- current_key++;
- return true;
- };
- auto on_done = [this](Status status) {
- EXPECT_EQ(Status::OK, status);
- QuitLoop();
- };
- ForEachEntry(environment_.coroutine_service(), &fake_storage_,
- root_identifier, "", on_next, on_done);
- RunLoopFor(kSufficientDelay);
-}
-
-TEST_F(BTreeUtilsTest, ForEachEntryPrefix) {
- // Create a tree from entries with keys from 00-99.
- std::vector<EntryChange> entries;
- ASSERT_TRUE(CreateEntryChanges(100, &entries));
- ObjectIdentifier root_identifier = CreateTree(entries);
-
- // Find all entries with "key3" prefix in the key.
- std::string prefix = "key3";
- int current_key = 30;
- auto on_next = [¤t_key, &prefix](EntryAndNodeIdentifier e) {
- if (e.entry.key.substr(0, prefix.length()) != prefix) {
- return false;
- }
- EXPECT_EQ(fxl::StringPrintf("key%02d", current_key++), e.entry.key);
- return true;
- };
- auto on_done = [this, ¤t_key](Status status) {
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(40, current_key);
- QuitLoop();
- };
- ForEachEntry(environment_.coroutine_service(), &fake_storage_,
- root_identifier, prefix, on_next, on_done);
- RunLoopFor(kSufficientDelay);
-}
-
-} // namespace
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/builder.cc b/bin/ledger/storage/impl/btree/builder.cc
deleted file mode 100644
index 4874e79..0000000
--- a/bin/ledger/storage/impl/btree/builder.cc
+++ /dev/null
@@ -1,671 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/builder.h"
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine_waiter.h"
-#include "peridot/bin/ledger/storage/impl/btree/internal_helper.h"
-#include "peridot/bin/ledger/storage/impl/btree/synchronous_storage.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "third_party/murmurhash/murmurhash.h"
-
-namespace storage {
-namespace btree {
-namespace {
-
-constexpr uint32_t kMurmurHashSeed = 0xbeef;
-
-using HashResultType = decltype(murmurhash(nullptr, 0, 0));
-using HashSliceType = uint8_t;
-
-union Hash {
- HashResultType hash;
- HashSliceType slices[sizeof(HashResultType) / sizeof(HashSliceType)];
-};
-
-static_assert(sizeof(Hash::slices) == sizeof(Hash::hash),
- "Hash size is incorrect.");
-static_assert(sizeof(HashSliceType) < std::numeric_limits<uint8_t>::max(),
- "Hash size is too big.");
-
-Hash FastHash(convert::ExtendedStringView value) {
- return {.hash = murmurhash(value.data(), value.size(), kMurmurHashSeed)};
-}
-
-uint8_t GetNodeLevel(convert::ExtendedStringView key) {
- // Compute the level of a key by computing the hash of the key.
- // A key is at level k if the first k bytes of the hash of |key| are 0s. This
- // constructs a tree with an expected node size of |255|.
- Hash hash = FastHash(key);
- for (size_t l = 0; l < sizeof(Hash); ++l) {
- if (hash.slices[l]) {
- return l;
- }
- }
- return std::numeric_limits<uint8_t>::max();
-}
-
-constexpr NodeLevelCalculator kDefaultNodeLevelCalculator = {&GetNodeLevel};
-
-// Base class for tree nodes during construction. To apply mutations on a tree
-// node, one starts by creating an instance of NodeBuilder from the id of an
-// existing tree node, then applies mutation on it. Once all mutations are
-// applied, a call to Build will build a TreeNode in the storage.
-class NodeBuilder {
- public:
- // Creates a NodeBuilder from the id of a tree node.
- static Status FromIdentifier(SynchronousStorage* page_storage,
- ObjectIdentifier object_identifier,
- NodeBuilder* node_builder);
-
- // Creates a null builder.
- NodeBuilder() { FXL_DCHECK(Validate()); }
-
- NodeBuilder(NodeBuilder&&) = default;
-
- NodeBuilder& operator=(NodeBuilder&&) = default;
-
- // Returns whether the builder is null.
- explicit operator bool() const { return type_ != BuilderType::NULL_NODE; }
-
- // Apply the given mutation on |node_builder|.
- Status Apply(const NodeLevelCalculator* node_level_calculator,
- SynchronousStorage* page_storage, EntryChange change,
- bool* did_mutate);
-
- // Build the tree node represented by the builder |node_builder| in the
- // storage.
- Status Build(SynchronousStorage* page_storage,
- ObjectIdentifier* object_identifier,
- std::set<ObjectIdentifier>* new_identifiers);
-
- private:
- enum class BuilderType {
- EXISTING_NODE,
- NEW_NODE,
- NULL_NODE,
- };
-
- static NodeBuilder CreateExistingBuilder(uint8_t level,
- ObjectIdentifier object_identifier) {
- return NodeBuilder(BuilderType::EXISTING_NODE, level,
- std::move(object_identifier), {}, {});
- }
-
- static NodeBuilder CreateNewBuilder(uint8_t level, std::vector<Entry> entries,
- std::vector<NodeBuilder> children) {
- if (entries.empty() && !children[0]) {
- return NodeBuilder();
- }
- return NodeBuilder(BuilderType::NEW_NODE, level, {}, std::move(entries),
- std::move(children));
- }
-
- NodeBuilder(BuilderType type, uint8_t level,
- ObjectIdentifier object_identifier, std::vector<Entry> entries,
- std::vector<NodeBuilder> children)
- : type_(type),
- level_(level),
- object_identifier_(std::move(object_identifier)),
- entries_(std::move(entries)),
- children_(std::move(children)) {
- FXL_DCHECK(Validate());
- }
-
- // Ensures that the entries and children of this builder are computed.
- Status ComputeContent(SynchronousStorage* page_storage);
-
- // Delete the value with the given |key| from the builder. |key_level| must be
- // greater or equal then the node level.
- Status Delete(SynchronousStorage* page_storage, uint8_t key_level,
- std::string key, bool* did_mutate);
-
- // Update the tree by adding |entry| (or modifying the value associated to
- // |entry.key| with |entry.value| if |key| is already in the tree).
- // |change_level| must be greater or equal than the node level.
- Status Update(SynchronousStorage* page_storage, uint8_t change_level,
- Entry entry, bool* did_mutate);
-
- // Split the current tree in 2 according to |key|. This method expects that
- // |key| is not in the tree. After the call, the left tree will be in the
- // current builder, and the right tree in |right|.
- Status Split(SynchronousStorage* page_storage, std::string key,
- NodeBuilder* right);
-
- // Merge this tree with |other|. This expects all elements of |other| to be
- // greather than elements in |this|.
- Status Merge(SynchronousStorage* page_storage, NodeBuilder other);
-
- // Extract the entries and children from a TreeNode.
- static void ExtractContent(const TreeNode& node, std::vector<Entry>* entries,
- std::vector<NodeBuilder>* children);
-
- // Validate that the content of this builder follows the expected constraints.
- bool Validate() {
- if (type_ == BuilderType::NULL_NODE &&
- object_identifier_.object_digest().IsValid()) {
- return false;
- }
- if (type_ == BuilderType::EXISTING_NODE &&
- !object_identifier_.object_digest().IsValid()) {
- return false;
- }
- if (type_ == BuilderType::NEW_NODE && children_.empty()) {
- return false;
- }
- if ((!children_.empty() || !entries_.empty()) &&
- children_.size() != entries_.size() + 1) {
- return false;
- }
- if (type_ == BuilderType::NEW_NODE && entries_.empty() && !children_[0]) {
- return false;
- }
- return true;
- }
-
- // Add needed parent to |node| to produce a new tree of level |target_level|.
- NodeBuilder& ToLevel(uint8_t target_level) {
- if (!*this) {
- return *this;
- }
- FXL_DCHECK(target_level >= level_);
- while (level_ < target_level) {
- std::vector<NodeBuilder> children;
- children.push_back(std::move(*this));
- *this =
- NodeBuilder::CreateNewBuilder(level_ + 1, {}, std::move(children));
- }
- return *this;
- }
-
- // Collect the maximal set of nodes in the tree root at this builder than can
- // currently be built. A node can be built if and only if all its children are
- // already built. Add the buildable nodes to |output|. Return if at least a
- // node has been added to |output|.
- bool CollectNodesToBuild(std::vector<NodeBuilder*>* output) {
- if (type_ != BuilderType::NEW_NODE) {
- return false;
- }
- bool found_nodes_to_build = false;
- for (auto& child : children_) {
- found_nodes_to_build |= child.CollectNodesToBuild(output);
- }
- if (!found_nodes_to_build) {
- output->push_back(this);
- }
- return true;
- }
-
- BuilderType type_ = BuilderType::NULL_NODE;
- uint8_t level_;
- ObjectIdentifier object_identifier_;
- std::vector<Entry> entries_;
- std::vector<NodeBuilder> children_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(NodeBuilder);
-};
-
-Status NodeBuilder::FromIdentifier(SynchronousStorage* page_storage,
- ObjectIdentifier object_identifier,
- NodeBuilder* node_builder) {
- std::unique_ptr<const TreeNode> node;
- RETURN_ON_ERROR(
- page_storage->TreeNodeFromIdentifier(object_identifier, &node));
- FXL_DCHECK(node);
-
- std::vector<Entry> entries;
- std::vector<NodeBuilder> children;
- ExtractContent(*node, &entries, &children);
- *node_builder = NodeBuilder(BuilderType::EXISTING_NODE, node->level(),
- std::move(object_identifier), std::move(entries),
- std::move(children));
- return Status::OK;
-}
-
-Status NodeBuilder::Apply(const NodeLevelCalculator* node_level_calculator,
- SynchronousStorage* page_storage, EntryChange change,
- bool* did_mutate) {
- if (!*this) {
- // If the change is a deletion, and the tree is null, the result is still
- // null.
- if (change.deleted) {
- *did_mutate = false;
- return Status::OK;
- }
-
- // Otherwise, create a node of the right level that contains only entry.
- std::vector<Entry> entries;
- uint8_t level = node_level_calculator->GetNodeLevel(change.entry.key);
- entries.push_back(std::move(change.entry));
- *this = NodeBuilder::CreateNewBuilder(level, std::move(entries),
- std::vector<NodeBuilder>(2));
- *did_mutate = true;
- return Status::OK;
- }
-
- uint8_t change_level = node_level_calculator->GetNodeLevel(change.entry.key);
-
- if (change_level < level_) {
- // The change is at a lower level than the current node. Find the children
- // to apply the change, transform it and reconstruct the new node.
- RETURN_ON_ERROR(ComputeContent(page_storage));
-
- size_t index = GetEntryOrChildIndex(entries_, change.entry.key);
- FXL_DCHECK(index == entries_.size() ||
- entries_[index].key != change.entry.key);
-
- NodeBuilder& child = children_[index];
- RETURN_ON_ERROR(child.Apply(node_level_calculator, page_storage,
- std::move(change), did_mutate));
- // Suppress warning that |did_mutate| might not be initialized.
- if (!*did_mutate) { // NOLINT
- return Status::OK;
- }
-
- type_ = BuilderType::NEW_NODE;
- if (entries_.empty() && !children_[0]) {
- *this = NodeBuilder();
- } else {
- child.ToLevel(level_ - 1);
- }
- return Status::OK;
- }
-
- if (change.deleted) {
- return Delete(page_storage, change_level, std::move(change.entry.key),
- did_mutate);
- }
-
- return Update(page_storage, change_level, std::move(change.entry),
- did_mutate);
-}
-
-Status NodeBuilder::Build(SynchronousStorage* page_storage,
- ObjectIdentifier* object_identifier,
- std::set<ObjectIdentifier>* new_identifiers) {
- if (!*this) {
- RETURN_ON_ERROR(
- page_storage->TreeNodeFromEntries(0, {}, {}, &object_identifier_));
-
- *object_identifier = object_identifier_;
- new_identifiers->insert(object_identifier_);
- type_ = BuilderType::EXISTING_NODE;
- return Status::OK;
- }
- if (type_ == BuilderType::EXISTING_NODE) {
- *object_identifier = object_identifier_;
- return Status::OK;
- }
-
- std::vector<NodeBuilder*> to_build;
- while (CollectNodesToBuild(&to_build)) {
- auto waiter =
- fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- for (NodeBuilder* child : to_build) {
- std::map<size_t, ObjectIdentifier> children;
- for (size_t index = 0; index < child->children_.size(); ++index) {
- const auto& sub_child = child->children_[index];
- FXL_DCHECK(sub_child.type_ != BuilderType::NEW_NODE);
- if (sub_child) {
- children[index] = sub_child.object_identifier_;
- }
- }
- TreeNode::FromEntries(
- page_storage->page_storage(), child->level_, child->entries_,
- children,
- [new_identifiers, child, callback = waiter->NewCallback()](
- Status status, ObjectIdentifier object_identifier) {
- if (status == Status::OK) {
- child->type_ = BuilderType::EXISTING_NODE;
- child->object_identifier_ = object_identifier;
- new_identifiers->insert(child->object_identifier_);
- }
- callback(status);
- });
- }
- Status status;
-
- if (coroutine::Wait(page_storage->handler(), std::move(waiter), &status) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- if (status != Status::OK) {
- return status;
- }
- to_build.clear();
- }
-
- FXL_DCHECK(type_ == BuilderType::EXISTING_NODE);
- *object_identifier = object_identifier_;
-
- return Status::OK;
-}
-
-Status NodeBuilder::ComputeContent(SynchronousStorage* page_storage) {
- FXL_DCHECK(*this);
-
- if (!children_.empty()) {
- return Status::OK;
- }
-
- FXL_DCHECK(type_ == BuilderType::EXISTING_NODE);
-
- std::unique_ptr<const TreeNode> node;
- RETURN_ON_ERROR(
- page_storage->TreeNodeFromIdentifier(object_identifier_, &node));
- FXL_DCHECK(node);
-
- ExtractContent(*node, &entries_, &children_);
- return Status::OK;
-}
-
-Status NodeBuilder::Delete(SynchronousStorage* page_storage, uint8_t key_level,
- std::string key, bool* did_mutate) {
- FXL_DCHECK(*this);
- FXL_DCHECK(key_level >= level_);
-
- // If the change is at a higher level than this node, then it is a no-op.
- if (key_level > level_) {
- return Status::OK;
- }
-
- RETURN_ON_ERROR(ComputeContent(page_storage));
-
- size_t index = GetEntryOrChildIndex(entries_, key);
-
- // The key must be in the current node if it is in the tree.
- if (index == entries_.size() || entries_[index].key != key) {
- // The key is not found. Return the current node.
- *did_mutate = false;
- return Status::OK;
- }
-
- // Element at |index| must be removed.
- RETURN_ON_ERROR(
- children_[index].Merge(page_storage, std::move(children_[index + 1])));
-
- type_ = BuilderType::NEW_NODE;
- *did_mutate = true;
- entries_.erase(entries_.begin() + index);
- children_.erase(children_.begin() + index + 1);
-
- // Check if this makes this node null.
- if (entries_.empty() && !children_[0]) {
- *this = NodeBuilder();
- }
-
- return Status::OK;
-}
-
-Status NodeBuilder::Update(SynchronousStorage* page_storage,
- uint8_t change_level, Entry entry,
- bool* did_mutate) {
- FXL_DCHECK(*this);
- FXL_DCHECK(change_level >= level_);
-
- // If the change is at a greater level than the node level, the current node
- // must be splitted in 2, and the new root is composed of the new entry and
- // the 2 children.
- if (change_level > level_) {
- NodeBuilder right;
- RETURN_ON_ERROR(Split(page_storage, entry.key, &right));
-
- std::vector<Entry> entries;
- entries.push_back(std::move(entry));
- std::vector<NodeBuilder> children;
- children.push_back(std::move(this->ToLevel(change_level - 1)));
- children.push_back(std::move(right.ToLevel(change_level - 1)));
- *this = NodeBuilder::CreateNewBuilder(change_level, std::move(entries),
- std::move(children));
- *did_mutate = true;
- return Status::OK;
- }
-
- RETURN_ON_ERROR(ComputeContent(page_storage));
-
- // The change is at the current level. The entries must be splitted
- // according to the key of the change.
- size_t split_index = GetEntryOrChildIndex(entries_, entry.key);
-
- if (split_index < entries_.size() && entries_[split_index].key == entry.key) {
- // The key is already present in the current entries of the node. The
- // value must be replaced.
-
- // Entries are identical, the change is a no-op.
- if (entries_[split_index].object_identifier == entry.object_identifier &&
- entries_[split_index].priority == entry.priority) {
- *did_mutate = false;
- return Status::OK;
- }
-
- type_ = BuilderType::NEW_NODE;
- *did_mutate = true;
- entries_[split_index].object_identifier =
- std::move(entry.object_identifier);
- entries_[split_index].priority = entry.priority;
- return Status::OK;
- }
-
- type_ = BuilderType::NEW_NODE;
- *did_mutate = true;
-
- // Split the child that encompass |entry.key|.
- NodeBuilder right;
- RETURN_ON_ERROR(
- children_[split_index].Split(page_storage, entry.key, &right));
-
- // Add |entry| to the list of entries of the result node.
- entries_.insert(entries_.begin() + split_index, std::move(entry));
- // Append the right node to the list of children.
- children_.insert(children_.begin() + split_index + 1, std::move(right));
- return Status::OK;
-}
-
-Status NodeBuilder::Split(SynchronousStorage* page_storage, std::string key,
- NodeBuilder* right) {
- if (!*this) {
- *right = NodeBuilder();
- return Status::OK;
- }
-
- RETURN_ON_ERROR(ComputeContent(page_storage));
-
- // Find the index at which to split.
- size_t split_index = GetEntryOrChildIndex(entries_, key);
-
- // Ensure that |key| is not part of the entries.
- FXL_DCHECK(split_index == entries_.size() ||
- entries_[split_index].key != key);
-
- auto& child_to_split = children_[split_index];
-
- if (split_index == 0 && !child_to_split) {
- *right = std::move(*this);
- *this = NodeBuilder();
- return Status::OK;
- }
-
- if (split_index == entries_.size() && !child_to_split) {
- *right = NodeBuilder();
- return Status::OK;
- }
-
- type_ = BuilderType::NEW_NODE;
-
- // Recursively call |Split| on the child.
- NodeBuilder sub_right;
- RETURN_ON_ERROR(
- child_to_split.Split(page_storage, std::move(key), &sub_right));
-
- std::vector<Entry> right_entries;
-
- right_entries.reserve(entries_.size() - split_index);
- right_entries.insert(right_entries.end(),
- std::make_move_iterator(entries_.begin() + split_index),
- std::make_move_iterator(entries_.end()));
-
- std::vector<NodeBuilder> right_children;
- right_children.reserve(children_.size() - split_index);
- right_children.push_back(std::move(sub_right));
- right_children.insert(
- right_children.end(),
- std::make_move_iterator(children_.begin() + split_index + 1),
- std::make_move_iterator(children_.end()));
-
- *right = NodeBuilder::CreateNewBuilder(level_, std::move(right_entries),
- std::move(right_children));
-
- entries_.erase(entries_.begin() + split_index, entries_.end());
- children_.erase(children_.begin() + split_index + 1, children_.end());
-
- if (entries_.empty() && !children_[0]) {
- *this = NodeBuilder();
- }
- FXL_DCHECK(Validate());
-
- return Status::OK;
-}
-
-Status NodeBuilder::Merge(SynchronousStorage* page_storage, NodeBuilder other) {
- if (!other) {
- return Status::OK;
- }
-
- if (!*this) {
- *this = std::move(other);
- return Status::OK;
- }
-
- // |NULL_NODE|s do not have the level_ assigned. Only check the level if both
- // are non-null.
- FXL_DCHECK(level_ == other.level_);
-
- RETURN_ON_ERROR(ComputeContent(page_storage));
- RETURN_ON_ERROR(other.ComputeContent(page_storage));
-
- type_ = BuilderType::NEW_NODE;
-
- // Merge the right-most child from |left| with the left-most child
- // from |right|.
- RETURN_ON_ERROR(
- children_.back().Merge(page_storage, std::move(other.children_.front())));
-
- // Concatenate entries.
- entries_.insert(entries_.end(),
- std::make_move_iterator(other.entries_.begin()),
- std::make_move_iterator(other.entries_.end()));
-
- // Concatenate children, skipping the first child from other.
- children_.insert(children_.end(),
- std::make_move_iterator(other.children_.begin() + 1),
- std::make_move_iterator(other.children_.end()));
- return Status::OK;
-}
-
-void NodeBuilder::ExtractContent(const TreeNode& node,
- std::vector<Entry>* entries,
- std::vector<NodeBuilder>* children) {
- FXL_DCHECK(entries);
- FXL_DCHECK(children);
- *entries = std::vector<Entry>(node.entries().begin(), node.entries().end());
- children->clear();
- size_t next_index = 0;
- for (const auto& child : node.children_identifiers()) {
- for (; next_index < child.first; ++next_index) {
- children->push_back(NodeBuilder());
- }
- children->push_back(
- NodeBuilder::CreateExistingBuilder(node.level() - 1, child.second));
- ++next_index;
- }
- for (; next_index <= entries->size(); ++next_index) {
- children->push_back(NodeBuilder());
- }
-}
-
-// Apply |changes| on |root|. This is called recursively until |changes| is not
-// valid anymore. At this point, build is called on |root|.
-Status ApplyChangesOnRoot(const NodeLevelCalculator* node_level_calculator,
- SynchronousStorage* page_storage, NodeBuilder root,
- std::unique_ptr<Iterator<const EntryChange>> changes,
- ObjectIdentifier* object_identifier,
- std::set<ObjectIdentifier>* new_identifiers) {
- Status status;
- while (changes->Valid()) {
- EntryChange change = **changes;
- changes->Next();
-
- bool did_mutate;
- status = root.Apply(node_level_calculator, page_storage, std::move(change),
- &did_mutate);
- if (status != Status::OK) {
- return status;
- }
- }
-
- if (changes->GetStatus() != Status::OK) {
- return changes->GetStatus();
- }
- return root.Build(page_storage, object_identifier, new_identifiers);
-}
-
-} // namespace
-
-const NodeLevelCalculator* GetDefaultNodeLevelCalculator() {
- return &kDefaultNodeLevelCalculator;
-}
-
-void ApplyChanges(
- coroutine::CoroutineService* coroutine_service, PageStorage* page_storage,
- ObjectIdentifier root_identifier,
- std::unique_ptr<Iterator<const EntryChange>> changes,
- fit::function<void(Status, ObjectIdentifier, std::set<ObjectIdentifier>)>
- callback,
- const NodeLevelCalculator* node_level_calculator) {
- FXL_DCHECK(storage::IsDigestValid(root_identifier.object_digest()));
- coroutine_service->StartCoroutine(
- [page_storage, root_identifier = std::move(root_identifier),
- changes = std::move(changes), callback = std::move(callback),
- node_level_calculator](coroutine::CoroutineHandler* handler) mutable {
- SynchronousStorage storage(page_storage, handler);
-
- NodeBuilder root;
- Status status = NodeBuilder::FromIdentifier(
- &storage, std::move(root_identifier), &root);
- if (status != Status::OK) {
- callback(status, {}, {});
- return;
- }
- ObjectIdentifier object_identifier;
- std::set<ObjectIdentifier> new_identifiers;
- status = ApplyChangesOnRoot(node_level_calculator, &storage,
- std::move(root), std::move(changes),
- &object_identifier, &new_identifiers);
- if (status != Status::OK) {
- callback(status, {}, {});
- return;
- }
-
- if (object_identifier.object_digest().IsValid()) {
- callback(Status::OK, std::move(object_identifier),
- std::move(new_identifiers));
- return;
- }
-
- TreeNode::Empty(page_storage, [callback = std::move(callback)](
- Status status,
- ObjectIdentifier object_identifier) {
- std::set<ObjectIdentifier> new_identifiers({object_identifier});
- callback(status, std::move(object_identifier),
- std::move(new_identifiers));
- });
- });
-}
-
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/builder.h b/bin/ledger/storage/impl/btree/builder.h
deleted file mode 100644
index 9e64629..0000000
--- a/bin/ledger/storage/impl/btree/builder.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_BUILDER_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_BUILDER_H_
-
-#include <memory>
-#include <set>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/public/iterator.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace btree {
-
-struct NodeLevelCalculator {
- // Returns the level in the tree where a node containing |key| must be
- // located. The leaves are located on level 0.
- uint8_t (*GetNodeLevel)(convert::ExtendedStringView key);
-};
-
-// Returns the default algorithm to compute the node level.
-const NodeLevelCalculator* GetDefaultNodeLevelCalculator();
-
-// Applies changes provided by |changes| to the B-Tree starting at
-// |root_identifier|. |changes| must provide |EntryChange| objects sorted by
-// their key. The callback will provide the status of the operation, the id of
-// the new root and the list of ids of all new nodes created after the changes.
-void ApplyChanges(
- coroutine::CoroutineService* coroutine_service, PageStorage* page_storage,
- ObjectIdentifier root_identifier,
- std::unique_ptr<Iterator<const EntryChange>> changes,
- fit::function<void(Status, ObjectIdentifier, std::set<ObjectIdentifier>)>
- callback,
- const NodeLevelCalculator* node_level_calculator =
- GetDefaultNodeLevelCalculator());
-
-} // namespace btree
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_BUILDER_H_
diff --git a/bin/ledger/storage/impl/btree/diff.cc b/bin/ledger/storage/impl/btree/diff.cc
deleted file mode 100644
index c02fdde..0000000
--- a/bin/ledger/storage/impl/btree/diff.cc
+++ /dev/null
@@ -1,603 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/diff.h"
-
-#include <utility>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/storage/impl/btree/internal_helper.h"
-#include "peridot/bin/ledger/storage/impl/btree/iterator.h"
-#include "peridot/bin/ledger/storage/impl/btree/synchronous_storage.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-
-namespace storage {
-namespace btree {
-namespace {
-// Aggregates 2 |BTreeIterator|s and allows to walk through these concurrently
-// to compute the diff. |on_next| will be called for each diff entry.
-class IteratorPair {
- public:
- IteratorPair(
- SynchronousStorage* storage,
- fit::function<bool(std::unique_ptr<Entry>, std::unique_ptr<Entry>)>
- on_next)
- : on_next_(std::move(on_next)), left_(storage), right_(storage) {}
-
- // Initialize the pair with the ids of both roots.
- Status Init(ObjectIdentifier left_node_identifier,
- ObjectIdentifier right_node_identifier, fxl::StringView min_key) {
- RETURN_ON_ERROR(left_.Init(left_node_identifier));
- RETURN_ON_ERROR(right_.Init(right_node_identifier));
- if (!min_key.empty()) {
- RETURN_ON_ERROR(SkipIteratorsTo(min_key));
- }
- Normalize();
- if (!Finished() && !HasDiff()) {
- RETURN_ON_ERROR(Advance());
- }
-
- return Status::OK;
- }
-
- bool Finished() const {
- FXL_DCHECK(IsNormalized());
- return right_.Finished();
- }
-
- // Send the actual diff to the client. Returns |false| if the iteration must
- // be stopped.
- bool SendDiff() {
- FXL_DCHECK(HasDiff());
-
- // If the 2 iterators are on 2 equals values, nothing to do.
- if (left_.HasValue() && right_.HasValue() &&
- left_.CurrentEntry() == right_.CurrentEntry()) {
- return true;
- }
-
- if (HasSameNextChild()) {
- // If the 2 iterators are on the same child, send a diff for each
- // iterator that is currently on a value.
- if (right_.HasValue()) {
- if (!SendRight()) {
- return false;
- }
- }
- if (left_.HasValue() &&
- (!right_.HasValue() ||
- left_.CurrentEntry().key != right_.CurrentEntry().key)) {
- if (!SendLeft()) {
- return false;
- }
- }
- return true;
- }
-
- // Otherwise, just send the diff of the right node.
- return SendRight();
- }
-
- // Advance the iterator until there is potentially a diff to send.
- Status Advance() {
- FXL_DCHECK(!Finished());
- do {
- FXL_DCHECK(IsNormalized());
-
- // If the 2 next children are identical, skip these.
- if (HasSameNextChild()) {
- right_.SkipNextSubTree();
- left_.SkipNextSubTree();
- Normalize();
- continue;
- }
-
- // If both iterators are sitting on a value for the same key, both need
- // to be advanced.
- if (right_.HasValue() && left_.HasValue() &&
- right_.CurrentEntry().key == left_.CurrentEntry().key) {
- RETURN_ON_ERROR(right_.Advance());
- Swap();
- }
-
- RETURN_ON_ERROR(right_.Advance());
- Normalize();
- } while (!Finished() && !HasDiff());
- return Status::OK;
- }
-
- private:
- // Advances the two iterators so that they are both in the first entry that 1)
- // is greater than or equal to min_key and 2) might be different between the
- // two iterators. We consider that the two entries might be different, if they
- // are in btree nodes with different ids.
- Status SkipIteratorsTo(fxl::StringView min_key) {
- for (;;) {
- if (left_.SkipToIndex(min_key)) {
- right_.SkipTo(min_key);
- return Status::OK;
- }
- if (right_.SkipToIndex(min_key)) {
- left_.SkipToIndex(min_key);
- return Status::OK;
- }
-
- auto left_child = left_.GetNextChild();
- auto right_child = right_.GetNextChild();
- if (!left_child) {
- right_.SkipTo(min_key);
- return Status::OK;
- }
- if (!right_child) {
- left_.SkipTo(min_key);
- return Status::OK;
- }
- if (left_child == right_child) {
- return Status::OK;
- }
- // Same nodes might be in different depths of the btrees. Only descend in
- // each if their current level is the same as or greater than the other
- // one's.
- uint8_t level_left = left_.GetLevel();
- uint8_t level_right = right_.GetLevel();
- if (level_left >= level_right) {
- RETURN_ON_ERROR(left_.Advance());
- }
- if (level_right >= level_left) {
- RETURN_ON_ERROR(right_.Advance());
- }
- }
- }
-
- // Ensure that the representation of the pair of iterator is normalized
- // according to the following rules:
- // If only one iterator is finished, it is always the left one.
- // If only one iterator is on a value, it is always the left one.
- // If both iterator are on a value, the left one has a key greater or equals
- // to the right one, and if the keys are equals, the iterator are in
- // their original order.
- // If none of the iterators is on a value, the right one has a level
- // greather or equals to the left one.
- //
- // When the iterator is normalized, the different algorithms can cut the
- // number of case it needs to consider.
- void Normalize() {
- if (left_.Finished()) {
- return;
- }
- if (right_.Finished()) {
- Swap();
- return;
- }
-
- if (right_.HasValue() && left_.HasValue()) {
- if (left_.CurrentEntry().key < right_.CurrentEntry().key) {
- Swap();
- return;
- }
- if (left_.CurrentEntry().key == right_.CurrentEntry().key) {
- ResetSwap();
- }
- return;
- }
-
- if (left_.HasValue()) {
- return;
- }
- if (right_.HasValue()) {
- Swap();
- return;
- }
-
- if (left_.GetLevel() > right_.GetLevel()) {
- Swap();
- }
- }
-
- // Returns if the iterator is normalized. See |Normalize| for the
- // definition. This is only used in DCHECKs.
- bool IsNormalized() const {
- if (left_.Finished() || right_.Finished()) {
- return left_.Finished();
- }
-
- if (left_.HasValue()) {
- if (!right_.HasValue()) {
- return true;
- }
-
- if (right_.CurrentEntry().key > left_.CurrentEntry().key) {
- return false;
- }
-
- if (right_.CurrentEntry().key == left_.CurrentEntry().key) {
- if (!diff_from_left_to_right_)
- return diff_from_left_to_right_;
- }
-
- return true;
- }
-
- if (right_.HasValue()) {
- return false;
- }
-
- return right_.GetLevel() >= left_.GetLevel();
- }
-
- // Returns whether there is a potential diff to send at the current state.
- bool HasDiff() const {
- FXL_DCHECK(IsNormalized());
- return (right_.HasValue() && (left_.Finished() || left_.HasValue())) ||
- (left_.HasValue() && HasSameNextChild());
- }
-
- // Returns whether the 2 iterators have the same next child in the
- // iteration. This allows to skip part of the 2 btrees when they are
- // identicals.
- bool HasSameNextChild() const {
- if (left_.Finished()) {
- return false;
- }
- auto right_child = right_.GetNextChild();
- if (!right_child) {
- return false;
- }
- auto left_child = left_.GetNextChild();
- if (!left_child) {
- return false;
- }
- return *right_child == *left_child;
- }
-
- // Swaps the 2 iterators. This is useful to reduce the number of case to
- // consider during the iteration.
- void Swap() {
- std::swap(left_, right_);
- diff_from_left_to_right_ = !diff_from_left_to_right_;
- }
-
- // Reset the iterators so that they are back in the original order.
- void ResetSwap() {
- if (!diff_from_left_to_right_) {
- Swap();
- }
- }
-
- // Send a diff using the right iterator.
- bool SendRight() { return Send(&right_, &left_, !diff_from_left_to_right_); }
-
- // Send a diff using the left iterator.
- bool SendLeft() { return Send(&left_, &right_, diff_from_left_to_right_); }
-
- bool Send(BTreeIterator* it1, BTreeIterator* it2, bool it1_to_it2) {
- std::unique_ptr<Entry> it1_entry, it2_entry;
- it1_entry = std::make_unique<Entry>(it1->CurrentEntry());
- if (!it2->Finished() && it2->HasValue() &&
- it1->CurrentEntry().key == it2->CurrentEntry().key) {
- it2_entry = std::make_unique<Entry>(it2->CurrentEntry());
- }
-
- if (it1_to_it2) {
- return on_next_(std::move(it1_entry), std::move(it2_entry));
- }
- return on_next_(std::move(it2_entry), std::move(it1_entry));
- }
-
- fit::function<bool(std::unique_ptr<Entry>, std::unique_ptr<Entry>)> on_next_;
- BTreeIterator left_;
- BTreeIterator right_;
- // Keep track whether the change is from left to right, or right to left.
- // This allows to switch left and right during the algorithm to handle less
- // cases.
- bool diff_from_left_to_right_ = true;
-};
-
-// Iterator that does a three-way diff by using two IteratorPair objects in
-// parallel.
-// Here is an attempt to convey what this iterator should be doing:
-// - It creates an IteratorPair (IP thereafter) for each side of the diff
-// (base-to-left and base-to-right).
-// - At the initialization time, it advances each internal IP to their first
-// diff. Each IP (as viewed from here) is on one key: the key of the latest
-// diff it returned.
-// - We always advance the IP with the lowest key, or the one not finished yet.
-// If both are on the same key, we advance both.
-// - The current key considered by the ThreeWayIterator is the lowest key of the
-// latest left and right diffs. If one IP is finished, then the current key is
-// the key of the other IP's diff.
-// - When sending the ThreeWayIterator diff, we consider the current key (per
-// above). If both IPs are on the same key, the diff is easy (we just send
-// everything). However, if the IPs are on different keys, or one of them is
-// finished, we have to consider multiple cases:
-// - If the base entry is present, it means the key/value was present in the
-// base revision. Given that the other IP moved past this key, there is no
-// diff on that side and we copy the base entry to that side entry within
-// the tree-way diff change.
-// - If the base entry is not present, it means the key/value was not present
-// in the base revision and it is an addition.
-class ThreeWayIterator {
- public:
- explicit ThreeWayIterator(SynchronousStorage* storage) {
- base_left_iterators_ = std::make_unique<IteratorPair>(
- storage,
- [this](std::unique_ptr<Entry> base, std::unique_ptr<Entry> left) {
- left_advanced_ = true;
- base_left_.swap(base);
- left_.swap(left);
- return true;
- });
- base_right_iterators_ = std::make_unique<IteratorPair>(
- storage,
- [this](std::unique_ptr<Entry> base, std::unique_ptr<Entry> right) {
- right_advanced_ = true;
- base_right_.swap(base);
- right_.swap(right);
- return true;
- });
- }
-
- Status Init(ObjectIdentifier base_node_identifier,
- ObjectIdentifier left_node_identifier,
- ObjectIdentifier right_node_identifier, fxl::StringView min_key) {
- RETURN_ON_ERROR(base_left_iterators_->Init(base_node_identifier,
- left_node_identifier, min_key));
- RETURN_ON_ERROR(base_right_iterators_->Init(
- base_node_identifier, right_node_identifier, min_key));
- if (!Finished()) {
- RETURN_ON_ERROR(AdvanceLeft());
- RETURN_ON_ERROR(AdvanceRight());
- }
- return Status::OK;
- }
-
- bool Finished() const {
- return base_left_iterators_->Finished() &&
- base_right_iterators_->Finished() && !base_left_ && !left_ &&
- !base_right_ && !right_;
- }
-
- Status Advance() {
- FXL_DCHECK(!Finished());
- if (base_left_iterators_->Finished() && !base_left_ && !left_) {
- RETURN_ON_ERROR(AdvanceRight());
- } else if (base_right_iterators_->Finished() && !base_right_ && !right_) {
- RETURN_ON_ERROR(AdvanceLeft());
- } else if (GetLeftKey() < GetRightKey()) {
- RETURN_ON_ERROR(AdvanceLeft());
- } else if (GetLeftKey() > GetRightKey()) {
- RETURN_ON_ERROR(AdvanceRight());
- } else {
- RETURN_ON_ERROR(AdvanceLeft());
- RETURN_ON_ERROR(AdvanceRight());
- }
- return Status::OK;
- }
-
- ThreeWayChange GetCurrentDiff() {
- FXL_DCHECK(!Finished());
- ThreeWayChange change;
- change.base = GetBase();
- change.left = GetEntry(change.base, base_left_iterators_, left_, right_);
- change.right = GetEntry(change.base, base_right_iterators_, right_, left_);
- return change;
- }
-
- private:
- // GetLeftKey (resp. GetRightKey) should not be called if the left (resp.
- // right) IteratorPair is finished.
- const std::string& GetLeftKey() {
- FXL_DCHECK(base_left_ || left_);
- if (base_left_) {
- return base_left_->key;
- }
- return left_->key;
- }
-
- const std::string& GetRightKey() {
- FXL_DCHECK(base_right_ || right_);
- if (base_right_) {
- return base_right_->key;
- }
- return right_->key;
- }
-
- Status AdvanceLeft() {
- left_advanced_ = false;
- while (!base_left_iterators_->Finished() && !left_advanced_) {
- if (!base_left_iterators_->SendDiff()) {
- return Status::OK;
- }
- RETURN_ON_ERROR(base_left_iterators_->Advance());
- }
- if (!left_advanced_ && base_left_iterators_->Finished()) {
- base_left_.reset();
- left_.reset();
- }
- return Status::OK;
- }
-
- Status AdvanceRight() {
- right_advanced_ = false;
- while (!base_right_iterators_->Finished() && !right_advanced_) {
- if (!base_right_iterators_->SendDiff()) {
- return Status::OK;
- }
- RETURN_ON_ERROR(base_right_iterators_->Advance());
- }
- if (!right_advanced_ && base_right_iterators_->Finished()) {
- base_right_.reset();
- right_.reset();
- }
- return Status::OK;
- }
-
- std::unique_ptr<Entry> GetBase() {
- if (base_left_ && base_right_) {
- if (base_left_->key < base_right_->key) {
- return std::make_unique<Entry>(*base_left_);
- }
- return std::make_unique<Entry>(*base_right_);
- }
- if (!base_right_ && base_left_ &&
- (!right_ || base_left_->key < right_->key)) {
- return std::make_unique<Entry>(*base_left_);
- }
- if (!base_left_ && base_right_ &&
- (!left_ || base_right_->key < left_->key)) {
- return std::make_unique<Entry>(*base_right_);
- }
- return std::unique_ptr<Entry>();
- }
-
- std::unique_ptr<Entry> GetEntry(
- const std::unique_ptr<Entry>& base,
- const std::unique_ptr<IteratorPair>& this_iterator,
- const std::unique_ptr<Entry>& this_entry,
- const std::unique_ptr<Entry>& other_entry) {
- if (base) {
- if (this_entry && base->key == this_entry->key) {
- return std::make_unique<Entry>(*this_entry);
- }
- if (this_entry && base->key < this_entry->key) {
- return std::make_unique<Entry>(*base);
- }
- if (this_iterator->Finished()) {
- return std::make_unique<Entry>(*base);
- }
- return std::unique_ptr<Entry>();
- }
- if (!this_entry || (other_entry && other_entry->key < this_entry->key)) {
- return std::unique_ptr<Entry>();
- }
- return std::make_unique<Entry>(*this_entry);
- }
-
- bool left_advanced_ = false;
- bool right_advanced_ = false;
-
- std::unique_ptr<Entry> base_left_;
- std::unique_ptr<Entry> base_right_;
- std::unique_ptr<Entry> left_;
- std::unique_ptr<Entry> right_;
-
- std::unique_ptr<IteratorPair> base_left_iterators_;
- std::unique_ptr<IteratorPair> base_right_iterators_;
-};
-
-Status ForEachDiffInternal(SynchronousStorage* storage,
- ObjectIdentifier left_node_identifier,
- ObjectIdentifier right_node_identifier,
- std::string min_key,
- fit::function<bool(EntryChange)> on_next) {
- FXL_DCHECK(storage::IsDigestValid(left_node_identifier.object_digest()));
- FXL_DCHECK(storage::IsDigestValid(right_node_identifier.object_digest()));
-
- if (left_node_identifier == right_node_identifier) {
- return Status::OK;
- }
-
- auto wrapped_next = [on_next = std::move(on_next)](
- std::unique_ptr<Entry> base,
- std::unique_ptr<Entry> other) {
- if (other) {
- return on_next({std::move(*other), false});
- }
- return on_next({std::move(*base), true});
- };
-
- IteratorPair iterators(storage, std::move(wrapped_next));
- RETURN_ON_ERROR(
- iterators.Init(left_node_identifier, right_node_identifier, min_key));
-
- while (!iterators.Finished()) {
- if (!iterators.SendDiff()) {
- return Status::OK;
- }
- RETURN_ON_ERROR(iterators.Advance());
- }
-
- return Status::OK;
-} // namespace
-
-Status ForEachThreeWayDiffInternal(
- SynchronousStorage* storage, ObjectIdentifier base_node_identifier,
- ObjectIdentifier left_node_identifier,
- ObjectIdentifier right_node_identifier, std::string min_key,
- fit::function<bool(ThreeWayChange)> on_next) {
- FXL_DCHECK(IsDigestValid(base_node_identifier.object_digest()));
- FXL_DCHECK(IsDigestValid(left_node_identifier.object_digest()));
- FXL_DCHECK(IsDigestValid(right_node_identifier.object_digest()));
-
- if (left_node_identifier == right_node_identifier) {
- return Status::OK;
- }
-
- ThreeWayIterator iterator(storage);
- RETURN_ON_ERROR(iterator.Init(base_node_identifier, left_node_identifier,
- right_node_identifier, min_key));
-
- while (!iterator.Finished()) {
- if (!on_next(iterator.GetCurrentDiff())) {
- return Status::OK;
- }
- RETURN_ON_ERROR(iterator.Advance());
- }
-
- return Status::OK;
-}
-
-} // namespace
-
-void ForEachDiff(coroutine::CoroutineService* coroutine_service,
- PageStorage* page_storage,
- ObjectIdentifier base_root_identifier,
- ObjectIdentifier other_root_identifier, std::string min_key,
- fit::function<bool(EntryChange)> on_next,
- fit::function<void(Status)> on_done) {
- FXL_DCHECK(storage::IsDigestValid(base_root_identifier.object_digest()));
- FXL_DCHECK(storage::IsDigestValid(other_root_identifier.object_digest()));
- coroutine_service->StartCoroutine(
- [page_storage, base_root_identifier = std::move(base_root_identifier),
- other_root_identifier = std::move(other_root_identifier),
- on_next = std::move(on_next), min_key = std::move(min_key),
- on_done =
- std::move(on_done)](coroutine::CoroutineHandler* handler) mutable {
- SynchronousStorage storage(page_storage, handler);
-
- on_done(ForEachDiffInternal(&storage, base_root_identifier,
- other_root_identifier, std::move(min_key),
- std::move(on_next)));
- });
-}
-
-void ForEachThreeWayDiff(coroutine::CoroutineService* coroutine_service,
- PageStorage* page_storage,
- ObjectIdentifier base_root_identifier,
- ObjectIdentifier left_root_identifier,
- ObjectIdentifier right_root_identifier,
- std::string min_key,
- fit::function<bool(ThreeWayChange)> on_next,
- fit::function<void(Status)> on_done) {
- FXL_DCHECK(storage::IsDigestValid(base_root_identifier.object_digest()));
- FXL_DCHECK(storage::IsDigestValid(left_root_identifier.object_digest()));
- FXL_DCHECK(storage::IsDigestValid(right_root_identifier.object_digest()));
- coroutine_service->StartCoroutine(
- [page_storage, base_root_identifier = std::move(base_root_identifier),
- left_root_identifier = std::move(left_root_identifier),
- right_root_identifier = std::move(right_root_identifier),
- on_next = std::move(on_next), min_key = std::move(min_key),
- on_done =
- std::move(on_done)](coroutine::CoroutineHandler* handler) mutable {
- SynchronousStorage storage(page_storage, handler);
-
- on_done(ForEachThreeWayDiffInternal(
- &storage, base_root_identifier, left_root_identifier,
- right_root_identifier, std::move(min_key), std::move(on_next)));
- });
-}
-
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/diff.h b/bin/ledger/storage/impl/btree/diff.h
deleted file mode 100644
index c3e5aef..0000000
--- a/bin/ledger/storage/impl/btree/diff.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_DIFF_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_DIFF_H_
-
-#include <functional>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace btree {
-
-// Iterates through the differences between two trees given their root ids
-// |base_root_id| and |other_root_id| and calls |on_next| on found differences.
-// Returning false from |on_next| will immediately stop the iteration. |on_done|
-// is called once, upon successfull completion, i.e. when there are no more
-// differences or iteration was interrupted, or if an error occurs.
-void ForEachDiff(coroutine::CoroutineService* coroutine_service,
- PageStorage* page_storage,
- ObjectIdentifier base_root_identifier,
- ObjectIdentifier other_root_identifier, std::string min_key,
- fit::function<bool(EntryChange)> on_next,
- fit::function<void(Status)> on_done);
-
-// Iterates through the differences between three trees given their root ids and
-// calls |on_next| if any difference is found between any pair.
-// Returning false from |on_next| will immediately stop the iteration. |on_done|
-// is called once, upon successful completion, i.e. when there are no more
-// differences or iteration was interrupted, or if an error occurs.
-void ForEachThreeWayDiff(coroutine::CoroutineService* coroutine_service,
- PageStorage* page_storage,
- ObjectIdentifier base_root_identifier,
- ObjectIdentifier left_root_identifier,
- ObjectIdentifier right_root_identifier,
- std::string min_key,
- fit::function<bool(ThreeWayChange)> on_next,
- fit::function<void(Status)> on_done);
-
-} // namespace btree
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_DIFF_H_
diff --git a/bin/ledger/storage/impl/btree/diff_unittest.cc b/bin/ledger/storage/impl/btree/diff_unittest.cc
deleted file mode 100644
index 97630e0..0000000
--- a/bin/ledger/storage/impl/btree/diff_unittest.cc
+++ /dev/null
@@ -1,576 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/diff.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fxl/macros.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-#include "peridot/bin/ledger/storage/impl/btree/builder.h"
-#include "peridot/bin/ledger/storage/impl/btree/entry_change_iterator.h"
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace btree {
-namespace {
-std::unique_ptr<Entry> CreateEntryPtr(std::string key,
- ObjectIdentifier object_identifier,
- KeyPriority priority) {
- auto e = std::make_unique<Entry>();
- e->key = key;
- e->object_identifier = std::move(object_identifier);
- e->priority = priority;
- return e;
-}
-
-std::unique_ptr<Entry> CreateEntryPtr() { return std::unique_ptr<Entry>(); }
-
-class FakePageStorageValidDigest : public fake::FakePageStorage {
- public:
- using fake::FakePageStorage::FakePageStorage;
-
- protected:
- ObjectDigest FakeDigest(fxl::StringView content) const override {
- // BTree code needs storage to return valid digests.
- return MakeObjectDigest(content.ToString());
- }
-};
-
-class DiffTest : public StorageTest {
- public:
- DiffTest() : fake_storage_(&environment_, "page_id") {}
-
- ~DiffTest() override {}
-
- // Test:
- void SetUp() override {
- StorageTest::SetUp();
- std::srand(0);
- }
-
- protected:
- PageStorage* GetStorage() override { return &fake_storage_; }
-
- ObjectIdentifier CreateTree(const std::vector<EntryChange>& entries) {
- ObjectIdentifier root_identifier;
- EXPECT_TRUE(GetEmptyNodeIdentifier(&root_identifier));
-
- ObjectIdentifier identifier;
- EXPECT_TRUE(CreateTreeFromChanges(root_identifier, entries, &identifier));
- return identifier;
- }
-
- FakePageStorageValidDigest fake_storage_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(DiffTest);
-};
-
-TEST_F(DiffTest, ForEachDiff) {
- std::unique_ptr<const Object> object;
- ASSERT_TRUE(AddObject("change1", &object));
- ObjectIdentifier object_identifier = object->GetIdentifier();
-
- std::vector<EntryChange> base_changes;
- ASSERT_TRUE(CreateEntryChanges(50, &base_changes));
- ObjectIdentifier base_root_identifier = CreateTree(base_changes);
-
- std::vector<EntryChange> other_changes;
- // Update value for key1.
- other_changes.push_back(
- EntryChange{Entry{"key1", object_identifier, KeyPriority::LAZY}, false});
- // Add entry key255.
- other_changes.push_back(EntryChange{
- Entry{"key255", object_identifier, KeyPriority::LAZY}, false});
- // Remove entry key40.
- other_changes.push_back(
- EntryChange{Entry{"key40", {}, KeyPriority::LAZY}, true});
- ObjectIdentifier other_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, other_changes,
- &other_root_identifier));
-
- // ForEachDiff should return all changes just applied.
- bool called;
- Status status;
- size_t current_change = 0;
- ForEachDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- other_root_identifier, "",
- [&other_changes, ¤t_change](EntryChange e) {
- EXPECT_EQ(other_changes[current_change].deleted, e.deleted);
- if (e.deleted) {
- EXPECT_EQ(other_changes[current_change].entry.key, e.entry.key);
- } else {
- EXPECT_EQ(other_changes[current_change].entry, e.entry);
- }
- ++current_change;
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(other_changes.size(), current_change);
-}
-
-TEST_F(DiffTest, ForEachDiffWithMinKey) {
- // Expected base tree layout (XX is key "keyXX"):
- // [50]
- // / \
- // [03, 07, 30] [65, 76]
- // /
- // [01, 02]
- std::vector<EntryChange> base_entries;
- ASSERT_TRUE(CreateEntryChanges(
- std::vector<size_t>({1, 2, 3, 7, 30, 50, 65, 76}), &base_entries));
- // Expected other tree layout (XX is key "keyXX"):
- // [50, 75]
- // / | \
- // [03, 07, 30] [65] [76]
- // / /
- // [01, 02] [51]
- std::vector<EntryChange> changes;
- ASSERT_TRUE(CreateEntryChanges(std::vector<size_t>({51, 75}), &changes));
-
- bool called;
- Status status;
- ObjectIdentifier base_root_identifier = CreateTree(base_entries);
- ObjectIdentifier other_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, changes,
- &other_root_identifier));
-
- // ForEachDiff with a "key0" as min_key should return both changes.
- size_t current_change = 0;
- ForEachDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- other_root_identifier, "key0",
- [&changes, ¤t_change](EntryChange e) {
- EXPECT_EQ(changes[current_change++].entry, e.entry);
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(changes.size(), current_change);
-
- // With "key60" as min_key, only key75 should be returned.
- ForEachDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- other_root_identifier, "key60",
- [&changes](EntryChange e) {
- EXPECT_EQ(changes[1].entry, e.entry);
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-}
-
-TEST_F(DiffTest, ForEachDiffWithMinKeySkipNodes) {
- // Expected base tree layout (XX is key "keyXX"):
- // [03, 07, 30]
- // /
- // [01, 02]
- std::vector<EntryChange> base_entries;
- ASSERT_TRUE(
- CreateEntryChanges(std::vector<size_t>({1, 2, 3, 7, 30}), &base_entries));
- // Expected other tree layout (XX is key "keyXX"):
- // [50]
- // /
- // [03, 07, 30]
- // /
- // [01, 02]
- std::vector<EntryChange> changes;
- ASSERT_TRUE(CreateEntryChanges(std::vector<size_t>({50}), &changes));
-
- bool called;
- Status status;
- ObjectIdentifier base_root_identifier = CreateTree(base_entries);
- ObjectIdentifier other_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, changes,
- &other_root_identifier));
-
- ForEachDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- other_root_identifier, "key01",
- [&changes](EntryChange e) {
- EXPECT_EQ(changes[0].entry, e.entry);
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-}
-
-TEST_F(DiffTest, ForEachDiffPriorityChange) {
- std::vector<EntryChange> base_changes;
- ASSERT_TRUE(CreateEntryChanges(50, &base_changes));
- ObjectIdentifier base_root_identifier = CreateTree(base_changes);
- Entry base_entry = base_changes[10].entry;
-
- std::vector<EntryChange> other_changes;
- // Update priority for a key.
- other_changes.push_back(EntryChange{
- Entry{base_entry.key, base_entry.object_identifier, KeyPriority::LAZY},
- false});
-
- bool called;
- Status status;
- ObjectIdentifier other_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, other_changes,
- &other_root_identifier));
-
- // ForEachDiff should return all changes just applied.
- size_t change_count = 0;
- EntryChange actual_change;
- ForEachDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- other_root_identifier, "",
- [&actual_change, &change_count](EntryChange e) {
- actual_change = e;
- ++change_count;
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(1u, change_count);
- EXPECT_FALSE(actual_change.deleted);
- EXPECT_EQ(base_entry.key, actual_change.entry.key);
- EXPECT_EQ(base_entry.object_identifier,
- actual_change.entry.object_identifier);
- EXPECT_EQ(KeyPriority::LAZY, actual_change.entry.priority);
-}
-
-TEST_F(DiffTest, ForEachThreeWayDiff) {
- // Base tree.
- std::vector<EntryChange> base_changes;
- ASSERT_TRUE(CreateEntryChanges(50, &base_changes));
- ObjectIdentifier base_object01_identifier =
- base_changes[1].entry.object_identifier;
- ObjectIdentifier base_object02_identifier =
- base_changes[2].entry.object_identifier;
- ObjectIdentifier base_object40_identifier =
- base_changes[40].entry.object_identifier;
- ObjectIdentifier base_root_identifier = CreateTree(base_changes);
-
- std::unique_ptr<const Object> object;
- ASSERT_TRUE(AddObject("change1", &object));
- ObjectIdentifier object_identifier = object->GetIdentifier();
-
- // Left tree.
- std::vector<EntryChange> left_changes;
- // Update value for key1.
- left_changes.push_back(
- EntryChange{Entry{"key01", object_identifier, KeyPriority::LAZY}, false});
- // Add entry key255.
- left_changes.push_back(EntryChange{
- Entry{"key255", object_identifier, KeyPriority::LAZY}, false});
- // Remove entry key40.
- left_changes.push_back(
- EntryChange{Entry{"key40", {}, KeyPriority::LAZY}, true});
-
- ObjectIdentifier left_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, left_changes,
- &left_root_identifier));
-
- // Right tree.
- std::unique_ptr<const Object> object2;
- ASSERT_TRUE(AddObject("change2", &object2));
- ObjectIdentifier object_identifier2 = object2->GetIdentifier();
- std::vector<EntryChange> right_changes;
- // Update to same value for key1.
- right_changes.push_back(
- EntryChange{Entry{"key01", object_identifier, KeyPriority::LAZY}, false});
- // Update to different value for key2
- right_changes.push_back(EntryChange{
- Entry{"key02", object_identifier2, KeyPriority::LAZY}, false});
- // Add entry key258.
- right_changes.push_back(EntryChange{
- Entry{"key258", object_identifier, KeyPriority::LAZY}, false});
-
- ObjectIdentifier right_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, right_changes,
- &right_root_identifier));
-
- std::vector<ThreeWayChange> expected_three_way_changes;
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr("key01", base_object01_identifier, KeyPriority::EAGER),
- CreateEntryPtr("key01", object_identifier, KeyPriority::LAZY),
- CreateEntryPtr("key01", object_identifier, KeyPriority::LAZY)});
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr("key02", base_object02_identifier, KeyPriority::EAGER),
- CreateEntryPtr("key02", base_object02_identifier, KeyPriority::EAGER),
- CreateEntryPtr("key02", object_identifier2, KeyPriority::LAZY)});
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr(),
- CreateEntryPtr("key255", object_identifier, KeyPriority::LAZY),
- CreateEntryPtr()});
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr(), CreateEntryPtr(),
- CreateEntryPtr("key258", object_identifier, KeyPriority::LAZY)});
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr("key40", base_object40_identifier, KeyPriority::EAGER),
- CreateEntryPtr(),
- CreateEntryPtr("key40", base_object40_identifier, KeyPriority::EAGER)});
-
- bool called;
- Status status;
- unsigned int current_change = 0;
- ForEachThreeWayDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- left_root_identifier, right_root_identifier, "",
- [&expected_three_way_changes, ¤t_change](ThreeWayChange e) {
- EXPECT_LT(current_change, expected_three_way_changes.size());
- if (current_change >= expected_three_way_changes.size()) {
- return false;
- }
- EXPECT_EQ(expected_three_way_changes[current_change], e);
- current_change++;
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(current_change, expected_three_way_changes.size());
-}
-
-TEST_F(DiffTest, ForEachThreeWayDiffMinKey) {
- // Base tree.
- std::vector<EntryChange> base_changes;
- ASSERT_TRUE(CreateEntryChanges(50, &base_changes));
- ObjectIdentifier base_object01_identifier =
- base_changes[1].entry.object_identifier;
- ObjectIdentifier base_object02_identifier =
- base_changes[2].entry.object_identifier;
- ObjectIdentifier base_object40_identifier =
- base_changes[40].entry.object_identifier;
- ObjectIdentifier base_root_identifier = CreateTree(base_changes);
-
- std::unique_ptr<const Object> object;
- ASSERT_TRUE(AddObject("change1", &object));
- ObjectIdentifier object_identifier = object->GetIdentifier();
-
- // Left tree.
- std::vector<EntryChange> left_changes;
- // Update value for key1.
- left_changes.push_back(
- EntryChange{Entry{"key01", object_identifier, KeyPriority::LAZY}, false});
- // Add entry key255.
- left_changes.push_back(EntryChange{
- Entry{"key255", object_identifier, KeyPriority::LAZY}, false});
- // Remove entry key40.
- left_changes.push_back(
- EntryChange{Entry{"key40", {}, KeyPriority::LAZY}, true});
-
- ObjectIdentifier left_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, left_changes,
- &left_root_identifier));
-
- // Right tree.
- std::unique_ptr<const Object> object2;
- ASSERT_TRUE(AddObject("change2", &object2));
- ObjectIdentifier object_identifier2 = object2->GetIdentifier();
- std::vector<EntryChange> right_changes;
- // Update to same value for key1.
- right_changes.push_back(
- EntryChange{Entry{"key01", object_identifier, KeyPriority::LAZY}, false});
- // Update to different value for key2
- right_changes.push_back(EntryChange{
- Entry{"key02", object_identifier2, KeyPriority::LAZY}, false});
- // Add entry key258.
- right_changes.push_back(EntryChange{
- Entry{"key258", object_identifier, KeyPriority::LAZY}, false});
-
- ObjectIdentifier right_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, right_changes,
- &right_root_identifier));
-
- std::vector<ThreeWayChange> expected_three_way_changes;
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr(), CreateEntryPtr(),
- CreateEntryPtr("key258", object_identifier, KeyPriority::LAZY)});
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr("key40", base_object40_identifier, KeyPriority::EAGER),
- CreateEntryPtr(),
- CreateEntryPtr("key40", base_object40_identifier, KeyPriority::EAGER)});
-
- bool called;
- Status status;
- unsigned int current_change = 0;
- ForEachThreeWayDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- left_root_identifier, right_root_identifier, "key257",
- [&expected_three_way_changes, ¤t_change](ThreeWayChange e) {
- EXPECT_LT(current_change, expected_three_way_changes.size());
- if (current_change >= expected_three_way_changes.size()) {
- return false;
- }
- EXPECT_EQ(expected_three_way_changes[current_change], e);
- current_change++;
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(current_change, expected_three_way_changes.size());
-}
-
-TEST_F(DiffTest, ForEachThreeWayDiffNoDiff) {
- // Base tree.
- std::vector<EntryChange> base_changes;
- ASSERT_TRUE(CreateEntryChanges(50, &base_changes));
- ObjectIdentifier base_object01_identifier =
- base_changes[1].entry.object_identifier;
- ObjectIdentifier base_object02_identifier =
- base_changes[2].entry.object_identifier;
- ObjectIdentifier base_object40_identifier =
- base_changes[40].entry.object_identifier;
- ObjectIdentifier base_root_identifier = CreateTree(base_changes);
-
- std::unique_ptr<const Object> object;
- ASSERT_TRUE(AddObject("change1", &object));
- ObjectIdentifier object_identifier = object->GetIdentifier();
-
- // Left tree.
- std::vector<EntryChange> left_changes;
- // Update value for key1.
- left_changes.push_back(
- EntryChange{Entry{"key01", object_identifier, KeyPriority::LAZY}, false});
- // Add entry key255.
- left_changes.push_back(EntryChange{
- Entry{"key255", object_identifier, KeyPriority::LAZY}, false});
- // Remove entry key40.
- left_changes.push_back(
- EntryChange{Entry{"key40", {}, KeyPriority::LAZY}, true});
-
- ObjectIdentifier left_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, left_changes,
- &left_root_identifier));
-
- // Right tree.
- std::unique_ptr<const Object> object2;
- ASSERT_TRUE(AddObject("change2", &object2));
- ObjectIdentifier object_identifier2 = object2->GetIdentifier();
- std::vector<EntryChange> right_changes;
- // Update to same value for key1.
- right_changes.push_back(
- EntryChange{Entry{"key01", object_identifier, KeyPriority::LAZY}, false});
- // Update to different value for key2
- right_changes.push_back(EntryChange{
- Entry{"key02", object_identifier2, KeyPriority::LAZY}, false});
- // Add entry key258.
- right_changes.push_back(EntryChange{
- Entry{"key258", object_identifier, KeyPriority::LAZY}, false});
-
- ObjectIdentifier right_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, right_changes,
- &right_root_identifier));
-
- bool called;
- Status status;
- // No change is expected.
- ForEachThreeWayDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- left_root_identifier, right_root_identifier, "key5",
- [](ThreeWayChange e) {
- ADD_FAILURE();
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
-}
-
-TEST_F(DiffTest, ForEachThreeWayNoBaseChange) {
- // Base tree.
- std::vector<EntryChange> base_changes;
- ObjectIdentifier base_root_identifier = CreateTree(base_changes);
-
- std::unique_ptr<const Object> object1, object2, object3, object4;
- ASSERT_TRUE(AddObject("change1", &object1));
- ObjectIdentifier object1_identifier = object1->GetIdentifier();
- ASSERT_TRUE(AddObject("change2", &object2));
- ObjectIdentifier object2_identifier = object2->GetIdentifier();
- ASSERT_TRUE(AddObject("change3", &object3));
- ObjectIdentifier object3_identifier = object3->GetIdentifier();
- ASSERT_TRUE(AddObject("change4", &object4));
- ObjectIdentifier object4_identifier = object4->GetIdentifier();
-
- // Left tree.
- std::vector<EntryChange> left_changes;
- left_changes.push_back(EntryChange{
- Entry{"key01", object1_identifier, KeyPriority::EAGER}, false});
- left_changes.push_back(EntryChange{
- Entry{"key03", object3_identifier, KeyPriority::EAGER}, false});
-
- ObjectIdentifier left_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, left_changes,
- &left_root_identifier));
-
- // Right tree.
- std::vector<EntryChange> right_changes;
- right_changes.push_back(EntryChange{
- Entry{"key02", object2_identifier, KeyPriority::EAGER}, false});
- right_changes.push_back(EntryChange{
- Entry{"key04", object4_identifier, KeyPriority::EAGER}, false});
-
- ObjectIdentifier right_root_identifier;
- ASSERT_TRUE(CreateTreeFromChanges(base_root_identifier, right_changes,
- &right_root_identifier));
-
- std::vector<ThreeWayChange> expected_three_way_changes;
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr(),
- CreateEntryPtr("key01", object1_identifier, KeyPriority::EAGER),
- CreateEntryPtr()});
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr(), CreateEntryPtr(),
- CreateEntryPtr("key02", object2_identifier, KeyPriority::EAGER)});
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr(),
- CreateEntryPtr("key03", object3_identifier, KeyPriority::EAGER),
- CreateEntryPtr()});
- expected_three_way_changes.push_back(ThreeWayChange{
- CreateEntryPtr(), CreateEntryPtr(),
- CreateEntryPtr("key04", object4_identifier, KeyPriority::EAGER)});
-
- bool called;
- Status status;
- unsigned int current_change = 0;
- ForEachThreeWayDiff(
- environment_.coroutine_service(), &fake_storage_, base_root_identifier,
- left_root_identifier, right_root_identifier, "",
- [&expected_three_way_changes, ¤t_change](ThreeWayChange e) {
- EXPECT_LT(current_change, expected_three_way_changes.size());
- if (current_change >= expected_three_way_changes.size()) {
- return false;
- }
- EXPECT_EQ(expected_three_way_changes[current_change], e);
- current_change++;
- return true;
- },
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(current_change, expected_three_way_changes.size());
-}
-
-} // namespace
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/encoding.cc b/bin/ledger/storage/impl/btree/encoding.cc
deleted file mode 100644
index b5a1855..0000000
--- a/bin/ledger/storage/impl/btree/encoding.cc
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/encoding.h"
-
-#include <algorithm>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/storage/impl/btree/tree_node_generated.h"
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace storage {
-namespace btree {
-namespace {
-KeyPriority ToKeyPriority(KeyPriorityStorage priority_storage) {
- switch (priority_storage) {
- case KeyPriorityStorage_EAGER:
- return KeyPriority::EAGER;
- case KeyPriorityStorage_LAZY:
- return KeyPriority::LAZY;
- }
-}
-
-bool IsKeyPriorityStorageValid(KeyPriorityStorage priority_storage) {
- return priority_storage == KeyPriorityStorage_EAGER ||
- priority_storage == KeyPriorityStorage_LAZY;
-}
-
-KeyPriorityStorage ToKeyPriorityStorage(KeyPriority priority) {
- switch (priority) {
- case KeyPriority::EAGER:
- return KeyPriorityStorage_EAGER;
- case KeyPriority::LAZY:
- return KeyPriorityStorage_LAZY;
- }
-}
-
-bool IsTreeNodeEntryValid(const EntryStorage* entry) {
- return entry && entry->key() &&
- IsObjectIdentifierStorageValid(entry->object_id()) &&
- IsKeyPriorityStorageValid(entry->priority());
-}
-
-Entry ToEntry(const EntryStorage* entry_storage) {
- FXL_DCHECK(IsTreeNodeEntryValid(entry_storage));
- return Entry{convert::ToString(entry_storage->key()),
- ToObjectIdentifier(entry_storage->object_id()),
- ToKeyPriority(entry_storage->priority())};
-}
-} // namespace
-
-bool CheckValidTreeNodeSerialization(fxl::StringView data) {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(data.data()), data.size());
- if (!VerifyTreeNodeStorageBuffer(verifier)) {
- return false;
- }
-
- const TreeNodeStorage* tree_node =
- GetTreeNodeStorage(reinterpret_cast<const unsigned char*>(data.data()));
-
- if (!tree_node->children() || !tree_node->entries()) {
- return false;
- }
-
- if (tree_node->children()->size() > tree_node->entries()->size() + 1) {
- return false;
- }
-
- // Check that the indexes are strictly increasing.
- size_t expected_min_next_index = 0;
- for (const auto* child : *(tree_node->children())) {
- if (child->index() < expected_min_next_index) {
- return false;
- }
- if (!IsObjectIdentifierStorageValid(child->object_id())) {
- return false;
- }
- expected_min_next_index = child->index() + 1;
- }
-
- // Check that all index are in [0, tree_node->entries()->size()]
- if (expected_min_next_index > tree_node->entries()->size() + 1) {
- return false;
- }
-
- // Check that the first entry is correct.
- if (tree_node->entries()->size() > 0) {
- const auto* entry = *tree_node->entries()->begin();
- if (!IsTreeNodeEntryValid(entry)) {
- return false;
- }
- }
- // Check that the rest of the entries are correct and that the keys are in
- // order.
- auto it = std::adjacent_find(
- tree_node->entries()->begin(), tree_node->entries()->end(),
- [](const auto* e1, const auto* e2) {
- FXL_DCHECK(IsTreeNodeEntryValid(e1));
- if (!IsTreeNodeEntryValid(e2)) {
- return true;
- }
- return convert::ExtendedStringView(e1->key()) >=
- convert::ExtendedStringView(e2->key());
- });
- return it == tree_node->entries()->end();
-}
-
-std::string EncodeNode(uint8_t level, const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children) {
- flatbuffers::FlatBufferBuilder builder;
-
- auto entries_offsets = builder.CreateVector(
- entries.size(),
- static_cast<std::function<flatbuffers::Offset<EntryStorage>(size_t)>>(
- [&builder, &entries](size_t i) {
- const auto& entry = entries[i];
- return CreateEntryStorage(
- builder, convert::ToFlatBufferVector(&builder, entry.key),
- ToObjectIdentifierStorage(&builder, entry.object_identifier),
- ToKeyPriorityStorage(entry.priority));
- }));
-
- size_t children_count = children.size();
- auto current_children = children.begin();
- auto children_offsets = builder.CreateVector(
- children_count,
- static_cast<std::function<flatbuffers::Offset<ChildStorage>(size_t)>>(
- [&builder, ¤t_children](size_t i) {
- size_t index = current_children->first;
- auto object_identifier_storage =
- ToObjectIdentifierStorage(&builder, current_children->second);
- ++current_children;
- return CreateChildStorage(builder, index,
- object_identifier_storage);
- }));
-
- builder.Finish(
- CreateTreeNodeStorage(builder, entries_offsets, children_offsets, level));
-
- return std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
- builder.GetSize());
-}
-
-bool DecodeNode(fxl::StringView data, uint8_t* level,
- std::vector<Entry>* res_entries,
- std::map<size_t, ObjectIdentifier>* res_children) {
- if (!CheckValidTreeNodeSerialization(data)) {
- return false;
- }
-
- const TreeNodeStorage* tree_node =
- GetTreeNodeStorage(reinterpret_cast<const unsigned char*>(data.data()));
-
- *level = tree_node->level();
- res_entries->clear();
- res_entries->reserve(tree_node->entries()->size());
- for (const auto* entry_storage : *(tree_node->entries())) {
- res_entries->push_back(ToEntry(entry_storage));
- }
- res_children->clear();
- for (const auto* child_storage : *(tree_node->children())) {
- (*res_children)[child_storage->index()] =
- ToObjectIdentifier(child_storage->object_id());
- }
-
- return true;
-}
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/encoding.h b/bin/ledger/storage/impl/btree/encoding.h
deleted file mode 100644
index 355c781..0000000
--- a/bin/ledger/storage/impl/btree/encoding.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ENCODING_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ENCODING_H_
-
-#include <map>
-#include <string>
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace btree {
-
-bool CheckValidTreeNodeSerialization(fxl::StringView data);
-
-std::string EncodeNode(uint8_t level, const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children);
-
-bool DecodeNode(fxl::StringView data, uint8_t* level,
- std::vector<Entry>* res_entries,
- std::map<size_t, ObjectIdentifier>* res_children);
-
-} // namespace btree
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ENCODING_H_
diff --git a/bin/ledger/storage/impl/btree/encoding_fuzztest.cc b/bin/ledger/storage/impl/btree/encoding_fuzztest.cc
deleted file mode 100644
index 9f570e1..0000000
--- a/bin/ledger/storage/impl/btree/encoding_fuzztest.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/encoding.h"
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- std::string bytes(reinterpret_cast<const char *>(Data), Size);
-
- if (storage::btree::CheckValidTreeNodeSerialization(bytes)) {
- uint8_t res_level;
- std::vector<storage::Entry> res_entries;
- std::map<size_t, storage::ObjectIdentifier> res_children;
- storage::btree::DecodeNode(bytes, &res_level, &res_entries, &res_children);
- }
- return 0;
-}
diff --git a/bin/ledger/storage/impl/btree/encoding_unittest.cc b/bin/ledger/storage/impl/btree/encoding_unittest.cc
deleted file mode 100644
index 7595eec..0000000
--- a/bin/ledger/storage/impl/btree/encoding_unittest.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/encoding.h"
-
-#include <lib/fit/function.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/impl/btree/tree_node_generated.h"
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-namespace btree {
-namespace {
-
-// Allows to create correct std::strings with \0 bytes inside from C-style
-// string constants.
-std::string operator"" _s(const char* str, size_t size) {
- return std::string(str, size);
-}
-
-TEST(EncodingTest, EmptyData) {
- uint8_t level = 0u;
- std::vector<Entry> entries;
- std::map<size_t, ObjectIdentifier> children;
-
- std::string bytes = EncodeNode(level, entries, children);
-
- uint8_t res_level;
- std::vector<Entry> res_entries;
- std::map<size_t, ObjectIdentifier> res_children;
- EXPECT_TRUE(DecodeNode(bytes, &res_level, &res_entries, &res_children));
- EXPECT_EQ(level, res_level);
- EXPECT_EQ(entries, res_entries);
- EXPECT_EQ(children, res_children);
-}
-
-TEST(EncodingTest, SingleEntry) {
- uint8_t level = 1u;
- std::vector<Entry> entries = {
- {"key", MakeObjectIdentifier("object_digest"), KeyPriority::EAGER}};
- std::map<size_t, ObjectIdentifier> children = {
- {0u, MakeObjectIdentifier("child_1")},
- {1u, MakeObjectIdentifier("child_2")}};
-
- std::string bytes = EncodeNode(level, entries, children);
-
- uint8_t res_level;
- std::vector<Entry> res_entries;
- std::map<size_t, ObjectIdentifier> res_children;
- EXPECT_TRUE(DecodeNode(bytes, &res_level, &res_entries, &res_children));
- EXPECT_EQ(level, res_level);
- EXPECT_EQ(entries, res_entries);
- EXPECT_EQ(children, res_children);
-}
-
-TEST(EncodingTest, MoreEntries) {
- uint8_t level = 5;
- std::vector<Entry> entries = {
- {"key1", MakeObjectIdentifier("abc"), KeyPriority::EAGER},
- {"key2", MakeObjectIdentifier("def"), KeyPriority::LAZY},
- {"key3", MakeObjectIdentifier("geh"), KeyPriority::EAGER},
- {"key4", MakeObjectIdentifier("ijk"), KeyPriority::LAZY}};
- std::map<size_t, ObjectIdentifier> children = {
- {0, MakeObjectIdentifier("child_1")},
- {1, MakeObjectIdentifier("child_2")},
- {2, MakeObjectIdentifier("child_3")},
- {3, MakeObjectIdentifier("child_4")},
- {4, MakeObjectIdentifier("child_5")}};
-
- std::string bytes = EncodeNode(level, entries, children);
-
- uint8_t res_level;
- std::vector<Entry> res_entries;
- std::map<size_t, ObjectIdentifier> res_children;
- EXPECT_TRUE(DecodeNode(bytes, &res_level, &res_entries, &res_children));
- EXPECT_EQ(level, res_level);
- EXPECT_EQ(entries, res_entries);
- EXPECT_EQ(children, res_children);
-}
-
-TEST(EncodingTest, SparsedEntriesWithBeginAndEnd) {
- uint8_t level = 5;
- std::vector<Entry> entries = {
- {"key1", MakeObjectIdentifier("abc"), KeyPriority::EAGER},
- {"key2", MakeObjectIdentifier("def"), KeyPriority::LAZY},
- {"key3", MakeObjectIdentifier("geh"), KeyPriority::EAGER},
- {"key4", MakeObjectIdentifier("ijk"), KeyPriority::LAZY}};
- std::map<size_t, ObjectIdentifier> children = {
- {0, MakeObjectIdentifier("child_1")},
- {2, MakeObjectIdentifier("child_2")},
- {4, MakeObjectIdentifier("child_3")}};
-
- std::string bytes = EncodeNode(level, entries, children);
-
- uint8_t res_level;
- std::vector<Entry> res_entries;
- std::map<size_t, ObjectIdentifier> res_children;
- EXPECT_TRUE(DecodeNode(bytes, &res_level, &res_entries, &res_children));
- EXPECT_EQ(level, res_level);
- EXPECT_EQ(entries, res_entries);
- EXPECT_EQ(children, res_children);
-}
-
-TEST(EncodingTest, SparsedEntriesWithoutBeginAndEnd) {
- uint8_t level = 5;
- std::vector<Entry> entries = {
- {"key1", MakeObjectIdentifier("abc"), KeyPriority::EAGER},
- {"key2", MakeObjectIdentifier("def"), KeyPriority::LAZY},
- {"key3", MakeObjectIdentifier("geh"), KeyPriority::EAGER},
- {"key4", MakeObjectIdentifier("ijk"), KeyPriority::LAZY}};
- std::map<size_t, ObjectIdentifier> children = {
- {1, MakeObjectIdentifier("child_1")},
- {3, MakeObjectIdentifier("child_2")}};
-
- std::string bytes = EncodeNode(level, entries, children);
-
- uint8_t res_level;
- std::vector<Entry> res_entries;
- std::map<size_t, ObjectIdentifier> res_children;
- EXPECT_TRUE(DecodeNode(bytes, &res_level, &res_entries, &res_children));
- EXPECT_EQ(level, res_level);
- EXPECT_EQ(entries, res_entries);
- EXPECT_EQ(children, res_children);
-}
-
-TEST(EncodingTest, ZeroByte) {
- uint8_t level = 13;
- std::vector<Entry> entries = {
- {"k\0ey"_s, MakeObjectIdentifier("\0a\0\0"_s), KeyPriority::EAGER}};
- std::map<size_t, ObjectIdentifier> children = {
- {0u, MakeObjectIdentifier("ch\0ld_1"_s)},
- {1u, MakeObjectIdentifier("child_\0"_s)}};
-
- std::string bytes = EncodeNode(level, entries, children);
-
- uint8_t res_level;
- std::vector<Entry> res_entries;
- std::map<size_t, ObjectIdentifier> res_children;
- EXPECT_TRUE(DecodeNode(bytes, &res_level, &res_entries, &res_children));
- EXPECT_EQ(level, res_level);
- EXPECT_EQ(entries, res_entries);
- EXPECT_EQ(children, res_children);
-}
-
-std::string ToString(flatbuffers::FlatBufferBuilder* builder) {
- return std::string(reinterpret_cast<const char*>(builder->GetBufferPointer()),
- builder->GetSize());
-}
-
-TEST(EncodingTest, Errors) {
- flatbuffers::FlatBufferBuilder builder;
-
- auto create_children = [&builder](size_t size) {
- std::vector<flatbuffers::Offset<ChildStorage>> children;
-
- for (size_t i = 0; i < size; ++i) {
- children.push_back(CreateChildStorage(
- builder, 1,
- ToObjectIdentifierStorage(
- &builder, MakeObjectIdentifier(fxl::StringPrintf("c%lu", i)))));
- }
- return builder.CreateVector(children);
- };
-
- // An empty string is not a valid serialization.
- EXPECT_FALSE(CheckValidTreeNodeSerialization(""));
-
- // 2 children without entries is not a valid serialization.
- builder.Finish(CreateTreeNodeStorage(
- builder,
- builder.CreateVector(std::vector<flatbuffers::Offset<EntryStorage>>()),
- create_children(2)));
- EXPECT_FALSE(CheckValidTreeNodeSerialization(ToString(&builder)));
-
- // A single child with index 1 is not a valid serialization.
- builder.Clear();
- builder.Finish(CreateTreeNodeStorage(
- builder,
- builder.CreateVector(std::vector<flatbuffers::Offset<EntryStorage>>()),
- create_children(1)));
- EXPECT_FALSE(CheckValidTreeNodeSerialization(ToString(&builder)));
-
- // 2 children with the same index is not a valid serialization.
- builder.Clear();
- builder.Finish(CreateTreeNodeStorage(
- builder,
- builder.CreateVector(
- 1,
- static_cast<std::function<flatbuffers::Offset<EntryStorage>(size_t)>>(
- [&](size_t i) {
- return CreateEntryStorage(
- builder, convert::ToFlatBufferVector(&builder, "hello"),
- ToObjectIdentifierStorage(&builder,
- MakeObjectIdentifier("world")),
- KeyPriorityStorage::KeyPriorityStorage_EAGER);
- })),
- create_children(2)));
- EXPECT_FALSE(CheckValidTreeNodeSerialization(ToString(&builder)));
-
- // 2 entries not sorted.
- builder.Clear();
- builder.Finish(CreateTreeNodeStorage(
- builder,
- builder.CreateVector(
- 2,
- static_cast<std::function<flatbuffers::Offset<EntryStorage>(size_t)>>(
- [&](size_t i) {
- return CreateEntryStorage(
- builder, convert::ToFlatBufferVector(&builder, "hello"),
- ToObjectIdentifierStorage(&builder,
- MakeObjectIdentifier("world")),
- KeyPriorityStorage::KeyPriorityStorage_EAGER);
- })),
- create_children(0)));
- EXPECT_FALSE(CheckValidTreeNodeSerialization(ToString(&builder)));
-}
-
-} // namespace
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/entry_change_iterator.h b/bin/ledger/storage/impl/btree/entry_change_iterator.h
deleted file mode 100644
index 9fd55df..0000000
--- a/bin/ledger/storage/impl/btree/entry_change_iterator.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ENTRY_CHANGE_ITERATOR_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ENTRY_CHANGE_ITERATOR_H_
-
-#include <vector>
-
-#include "peridot/bin/ledger/storage/public/iterator.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace btree {
-
-class EntryChangeIterator : public Iterator<const storage::EntryChange> {
- public:
- EntryChangeIterator(std::vector<EntryChange>::const_iterator it,
- std::vector<EntryChange>::const_iterator end)
- : it_(it), end_(end) {}
-
- ~EntryChangeIterator() override {}
-
- Iterator<const storage::EntryChange>& Next() override {
- FXL_DCHECK(Valid()) << "Iterator::Next iterator not valid";
- ++it_;
- return *this;
- }
-
- bool Valid() const override { return it_ != end_; }
-
- Status GetStatus() const override { return Status::OK; }
-
- const storage::EntryChange& operator*() const override { return *it_; }
- const storage::EntryChange* operator->() const override { return &(*it_); }
-
- private:
- std::vector<EntryChange>::const_iterator it_;
- std::vector<EntryChange>::const_iterator end_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(EntryChangeIterator);
-};
-
-} // namespace btree
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ENTRY_CHANGE_ITERATOR_H_
diff --git a/bin/ledger/storage/impl/btree/internal_helper.cc b/bin/ledger/storage/impl/btree/internal_helper.cc
deleted file mode 100644
index aae70e0..0000000
--- a/bin/ledger/storage/impl/btree/internal_helper.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/internal_helper.h"
-
-#include <algorithm>
-
-namespace storage {
-namespace btree {
-
-// Returns the index of |entries| that contains |key|, or the first entry that
-// has key greather than |key|. In the second case, the key, if present, will
-// be found in the children at the returned index.
-size_t GetEntryOrChildIndex(const std::vector<Entry>& entries,
- fxl::StringView key) {
- auto lower = std::lower_bound(
- entries.begin(), entries.end(), key,
- [](const Entry& entry, fxl::StringView key) { return entry.key < key; });
- FXL_DCHECK(lower == entries.end() || lower->key >= key);
- return lower - entries.begin();
-}
-
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/internal_helper.h b/bin/ledger/storage/impl/btree/internal_helper.h
deleted file mode 100644
index 16f00b6..0000000
--- a/bin/ledger/storage/impl/btree/internal_helper.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_INTERNAL_HELPER_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_INTERNAL_HELPER_H_
-
-#include <vector>
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-#define RETURN_ON_ERROR(expr) \
- do { \
- Status status = (expr); \
- if (status != Status::OK) { \
- return status; \
- } \
- } while (0)
-
-namespace storage {
-namespace btree {
-
-// Returns the index of |entries| that contains |key|, or the first entry that
-// has a key greather than |key|. In the second case, the key, if present, will
-// be found in the children at the returned index.
-size_t GetEntryOrChildIndex(const std::vector<Entry>& entries,
- fxl::StringView key);
-
-} // namespace btree
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_INTERNAL_HELPER_H_
diff --git a/bin/ledger/storage/impl/btree/iterator.cc b/bin/ledger/storage/impl/btree/iterator.cc
deleted file mode 100644
index 0d48b4b..0000000
--- a/bin/ledger/storage/impl/btree/iterator.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/iterator.h"
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/storage/impl/btree/internal_helper.h"
-
-namespace storage {
-namespace btree {
-
-namespace {
-
-Status ForEachEntryInternal(
- SynchronousStorage* storage, ObjectIdentifier root_identifier,
- fxl::StringView min_key,
- fit::function<bool(EntryAndNodeIdentifier)> on_next) {
- BTreeIterator iterator(storage);
- RETURN_ON_ERROR(iterator.Init(root_identifier));
- RETURN_ON_ERROR(iterator.SkipTo(min_key));
- while (!iterator.Finished()) {
- RETURN_ON_ERROR(iterator.AdvanceToValue());
- if (iterator.HasValue()) {
- if (!on_next({iterator.CurrentEntry(), iterator.GetIdentifier()})) {
- return Status::OK;
- }
- RETURN_ON_ERROR(iterator.Advance());
- }
- }
- return Status::OK;
-}
-
-} // namespace
-
-BTreeIterator::BTreeIterator(SynchronousStorage* storage) : storage_(storage) {}
-
-BTreeIterator::BTreeIterator(BTreeIterator&& other) noexcept = default;
-
-BTreeIterator& BTreeIterator::operator=(BTreeIterator&& other) noexcept =
- default;
-
-Status BTreeIterator::Init(ObjectIdentifier node_identifier) {
- return Descend(node_identifier);
-}
-
-Status BTreeIterator::SkipTo(fxl::StringView min_key) {
- descending_ = true;
- for (;;) {
- if (SkipToIndex(min_key)) {
- return Status::OK;
- }
- auto next_child = GetNextChild();
- if (!next_child) {
- return Status::OK;
- }
- RETURN_ON_ERROR(Descend(*next_child));
- }
-}
-
-bool BTreeIterator::SkipToIndex(fxl::StringView key) {
- auto& entries = CurrentNode().entries();
- size_t skip_count = GetEntryOrChildIndex(entries, key);
- if (skip_count < CurrentIndex()) {
- return true;
- }
- CurrentIndex() = skip_count;
- if (CurrentIndex() < entries.size() && entries[CurrentIndex()].key == key) {
- descending_ = false;
- return true;
- }
- return false;
-}
-
-const ObjectIdentifier* BTreeIterator::GetNextChild() const {
- auto index = CurrentIndex();
- auto& children_identifiers = CurrentNode().children_identifiers();
- auto children_index = descending_ ? index : index + 1;
- auto it = children_identifiers.find(children_index);
- return it == children_identifiers.end() ? nullptr : &(it->second);
-}
-
-bool BTreeIterator::HasValue() const {
- return !stack_.empty() && !descending_ &&
- CurrentIndex() < CurrentNode().entries().size();
-}
-
-bool BTreeIterator::Finished() const { return stack_.empty(); }
-
-const Entry& BTreeIterator::CurrentEntry() const {
- FXL_DCHECK(HasValue());
- return CurrentNode().entries()[CurrentIndex()];
-}
-
-const ObjectIdentifier& BTreeIterator::GetIdentifier() const {
- return CurrentNode().GetIdentifier();
-}
-
-uint8_t BTreeIterator::GetLevel() const { return CurrentNode().level(); }
-
-Status BTreeIterator::Advance() {
- if (descending_) {
- auto child = GetNextChild();
- if (!child) {
- descending_ = false;
- return Status::OK;
- }
- return Descend(*child);
- }
-
- auto& index = CurrentIndex();
- ++index;
- if (index <= CurrentNode().entries().size()) {
- descending_ = true;
- } else {
- stack_.pop_back();
- }
-
- return Status::OK;
-}
-
-Status BTreeIterator::AdvanceToValue() {
- while (!Finished() && !HasValue()) {
- RETURN_ON_ERROR(Advance());
- }
- return Status::OK;
-}
-
-void BTreeIterator::SkipNextSubTree() {
- if (descending_) {
- descending_ = false;
- } else {
- ++CurrentIndex();
- }
-}
-
-size_t& BTreeIterator::CurrentIndex() { return stack_.back().second; }
-
-size_t BTreeIterator::CurrentIndex() const { return stack_.back().second; }
-
-const TreeNode& BTreeIterator::CurrentNode() const {
- return *stack_.back().first;
-}
-
-Status BTreeIterator::Descend(const ObjectIdentifier& node_identifier) {
- FXL_DCHECK(descending_);
- std::unique_ptr<const TreeNode> node;
- RETURN_ON_ERROR(storage_->TreeNodeFromIdentifier(node_identifier, &node));
- stack_.emplace_back(std::move(node), 0);
- return Status::OK;
-}
-
-void GetObjectIdentifiers(
- coroutine::CoroutineService* coroutine_service, PageStorage* page_storage,
- ObjectIdentifier root_identifier,
- fit::function<void(Status, std::set<ObjectIdentifier>)> callback) {
- FXL_DCHECK(root_identifier.object_digest().IsValid());
- auto object_digests = std::make_unique<std::set<ObjectIdentifier>>();
- object_digests->insert(root_identifier);
-
- auto on_next = [object_digests =
- object_digests.get()](EntryAndNodeIdentifier e) {
- object_digests->insert(e.entry.object_identifier);
- object_digests->insert(e.node_identifier);
- return true;
- };
- auto on_done = [object_digests = std::move(object_digests),
- callback = std::move(callback)](Status status) {
- if (status != Status::OK) {
- callback(status, std::set<ObjectIdentifier>());
- return;
- }
- callback(status, std::move(*object_digests));
- };
- ForEachEntry(coroutine_service, page_storage, root_identifier, "",
- std::move(on_next), std::move(on_done));
-}
-
-void GetObjectsFromSync(coroutine::CoroutineService* coroutine_service,
- PageStorage* page_storage,
- ObjectIdentifier root_identifier,
- fit::function<void(Status)> callback) {
- auto waiter = fxl::MakeRefCounted<
- callback::Waiter<Status, std::unique_ptr<const Object>>>(Status::OK);
- auto on_next = [page_storage, waiter](EntryAndNodeIdentifier e) {
- if (e.entry.priority == KeyPriority::EAGER) {
- page_storage->GetObject(e.entry.object_identifier,
- PageStorage::Location::NETWORK,
- waiter->NewCallback());
- }
- return true;
- };
- auto on_done = [callback = std::move(callback),
- waiter](Status status) mutable {
- if (status != Status::OK) {
- callback(status);
- return;
- }
- waiter->Finalize(
- [callback = std::move(callback)](
- Status s, std::vector<std::unique_ptr<const Object>> objects) {
- callback(s);
- });
- };
- ForEachEntry(coroutine_service, page_storage, root_identifier, "",
- std::move(on_next), std::move(on_done));
-}
-
-void ForEachEntry(coroutine::CoroutineService* coroutine_service,
- PageStorage* page_storage, ObjectIdentifier root_identifier,
- std::string min_key,
- fit::function<bool(EntryAndNodeIdentifier)> on_next,
- fit::function<void(Status)> on_done) {
- FXL_DCHECK(root_identifier.object_digest().IsValid());
- coroutine_service->StartCoroutine(
- [page_storage, root_identifier = std::move(root_identifier),
- min_key = std::move(min_key), on_next = std::move(on_next),
- on_done =
- std::move(on_done)](coroutine::CoroutineHandler* handler) mutable {
- SynchronousStorage storage(page_storage, handler);
-
- on_done(ForEachEntryInternal(&storage, root_identifier, min_key,
- std::move(on_next)));
- });
-}
-
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/iterator.h b/bin/ledger/storage/impl/btree/iterator.h
deleted file mode 100644
index 6e3e2a4..0000000
--- a/bin/ledger/storage/impl/btree/iterator.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ITERATOR_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ITERATOR_H_
-
-#include <functional>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/impl/btree/synchronous_storage.h"
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace btree {
-
-// An entry and the id of the tree node in which it is stored.
-struct EntryAndNodeIdentifier {
- const Entry& entry; // NOLINT
- const ObjectIdentifier& node_identifier; // NOLINT
-};
-
-// Iterator over a B-Tree. This iterator exposes the internal of the iteration
-// to allow to skip part of the tree.
-class BTreeIterator {
- public:
- explicit BTreeIterator(SynchronousStorage* storage);
-
- BTreeIterator(BTreeIterator&& other) noexcept;
- BTreeIterator& operator=(BTreeIterator&& other) noexcept;
-
- // Initializes the iterator with the root node of the tree.
- Status Init(ObjectIdentifier node_identifier);
-
- // Skips the iteration until the first key that is greater than or equal to
- // |min_key|.
- Status SkipTo(fxl::StringView min_key);
-
- // Skips to the index where key could be found, within the current node. The
- // current index will only be updated if the new index is after the current
- // one. Returns true if either the key was found in this node, or if it is
- // guaranteed not to be found in any of this nodes children; false otherwise.
- bool SkipToIndex(fxl::StringView key);
-
- // Returns the identifier of the next child that will be explored, or
- // |nullptr| if it doesn't exist.
- const ObjectIdentifier* GetNextChild() const;
-
- // Returns whether the iterator is currently on a value. The method
- // |CurrentEntry| is only valid when |HasValue| is true.
- bool HasValue() const;
-
- // Returns whether the iteration is finished.
- bool Finished() const;
-
- // Returns the current value of the iterator. It is only valid when
- // |HasValue| is true.
- const Entry& CurrentEntry() const;
-
- // Returns the identifier of the node at the top of the stack.
- const storage::ObjectIdentifier& GetIdentifier() const;
-
- // Returns the level of the node at the top of the stack.
- uint8_t GetLevel() const;
-
- // Advances the iterator by a single step.
- Status Advance();
-
- // Advances the iterator until it has a value or it finishes.
- Status AdvanceToValue();
-
- // Skips the next sub tree in the iteration.
- void SkipNextSubTree();
-
- private:
- size_t& CurrentIndex();
- size_t CurrentIndex() const;
- const TreeNode& CurrentNode() const;
- Status Descend(const ObjectIdentifier& node_identifier);
-
- SynchronousStorage* storage_;
- // Stack representing the current iteration state. Each level represents the
- // current node in the B-Tree, and the index currently looked at. If
- // |descending_| is |true|, the index is the child index, otherwise it is the
- // entry index.
- std::vector<std::pair<std::unique_ptr<const TreeNode>, size_t>> stack_;
- bool descending_ = true;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BTreeIterator);
-};
-
-// Retrieves the ids of all objects in the B-Tree, i.e tree nodes and values of
-// entries in the tree. After a successfull call, |callback| will be called
-// with the set of results.
-void GetObjectIdentifiers(
- coroutine::CoroutineService* coroutine_service, PageStorage* page_storage,
- ObjectIdentifier root_identifier,
- fit::function<void(Status, std::set<ObjectIdentifier>)> callback);
-
-// Tries to download all tree nodes and values with |EAGER| priority that are
-// not locally available from sync. To do this |PageStorage::GetObject| is
-// called for all corresponding objects.
-void GetObjectsFromSync(coroutine::CoroutineService* coroutine_service,
- PageStorage* page_storage,
- ObjectIdentifier root_identifier,
- fit::function<void(Status)> callback);
-
-// Iterates through the nodes of the tree with the given root and calls
-// |on_next| on found entries with a key equal to or greater than |min_key|. The
-// return value of |on_next| can be used to stop the iteration: returning false
-// will interrupt the iteration in progress and no more |on_next| calls will be
-// made. |on_done| is called once, upon successfull completion, i.e. when there
-// are no more elements or iteration was interrupted, or if an error occurs.
-void ForEachEntry(coroutine::CoroutineService* coroutine_service,
- PageStorage* page_storage, ObjectIdentifier root_identifier,
- std::string min_key,
- fit::function<bool(EntryAndNodeIdentifier)> on_next,
- fit::function<void(Status)> on_done);
-
-} // namespace btree
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_ITERATOR_H_
diff --git a/bin/ledger/storage/impl/btree/synchronous_storage.cc b/bin/ledger/storage/impl/btree/synchronous_storage.cc
deleted file mode 100644
index ecef403..0000000
--- a/bin/ledger/storage/impl/btree/synchronous_storage.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/synchronous_storage.h"
-
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine_waiter.h"
-
-namespace storage {
-namespace btree {
-
-SynchronousStorage::SynchronousStorage(PageStorage* page_storage,
- coroutine::CoroutineHandler* handler)
- : page_storage_(page_storage), handler_(handler) {}
-
-Status SynchronousStorage::TreeNodeFromIdentifier(
- ObjectIdentifier object_identifier,
- std::unique_ptr<const TreeNode>* result) {
- Status status;
- if (coroutine::SyncCall(
- handler_,
- [this, &object_identifier](
- fit::function<void(Status, std::unique_ptr<const TreeNode>)>
- callback) {
- TreeNode::FromIdentifier(page_storage_, object_identifier,
- std::move(callback));
- },
- &status, result) == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return status;
-}
-
-Status SynchronousStorage::TreeNodesFromIdentifiers(
- std::vector<ObjectIdentifier> object_identifiers,
- std::vector<std::unique_ptr<const TreeNode>>* result) {
- auto waiter = fxl::MakeRefCounted<
- callback::Waiter<Status, std::unique_ptr<const TreeNode>>>(Status::OK);
- for (const auto& object_identifier : object_identifiers) {
- TreeNode::FromIdentifier(page_storage_, object_identifier,
- waiter->NewCallback());
- }
- Status status;
- if (coroutine::Wait(handler_, std::move(waiter), &status, result) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return status;
-}
-
-Status SynchronousStorage::TreeNodeFromEntries(
- uint8_t level, const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children,
- ObjectIdentifier* result) {
- Status status;
- if (coroutine::SyncCall(
- handler_,
- [this, level, &entries,
- &children](fit::function<void(Status, ObjectIdentifier)> callback) {
- TreeNode::FromEntries(page_storage_, level, entries, children,
- std::move(callback));
- },
- &status, result) == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return status;
-}
-
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/synchronous_storage.h b/bin/ledger/storage/impl/btree/synchronous_storage.h
deleted file mode 100644
index 4a56646..0000000
--- a/bin/ledger/storage/impl/btree/synchronous_storage.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_SYNCHRONOUS_STORAGE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_SYNCHRONOUS_STORAGE_H_
-
-#include <memory>
-#include <vector>
-
-#include <lib/callback/waiter.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-namespace btree {
-
-// Wrapper for TreeNode and PageStorage that uses coroutines to make
-// asynchronous calls look like synchronous ones.
-class SynchronousStorage {
- public:
- SynchronousStorage(PageStorage* page_storage,
- coroutine::CoroutineHandler* handler);
-
- PageStorage* page_storage() { return page_storage_; }
- coroutine::CoroutineHandler* handler() { return handler_; }
-
- Status TreeNodeFromIdentifier(ObjectIdentifier object_identifier,
- std::unique_ptr<const TreeNode>* result);
-
- Status TreeNodesFromIdentifiers(
- std::vector<ObjectIdentifier> object_identifiers,
- std::vector<std::unique_ptr<const TreeNode>>* result);
-
- Status TreeNodeFromEntries(uint8_t level, const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children,
- ObjectIdentifier* result);
-
- private:
- PageStorage* page_storage_;
- coroutine::CoroutineHandler* handler_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SynchronousStorage);
-};
-
-} // namespace btree
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_SYNCHRONOUS_STORAGE_H_
diff --git a/bin/ledger/storage/impl/btree/tree_node.cc b/bin/ledger/storage/impl/btree/tree_node.cc
deleted file mode 100644
index 2c22f68..0000000
--- a/bin/ledger/storage/impl/btree/tree_node.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-
-#include <algorithm>
-#include <utility>
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_counted.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "peridot/bin/ledger/storage/impl/btree/encoding.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace storage {
-namespace btree {
-
-TreeNode::TreeNode(PageStorage* page_storage, ObjectIdentifier identifier,
- uint8_t level, std::vector<Entry> entries,
- std::map<size_t, ObjectIdentifier> children)
- : page_storage_(page_storage),
- identifier_(std::move(identifier)),
- level_(level),
- entries_(std::move(entries)),
- children_(std::move(children)) {
- FXL_DCHECK(children_.empty() || children_.cbegin()->first <= entries_.size());
-}
-
-TreeNode::~TreeNode() {}
-
-void TreeNode::FromIdentifier(
- PageStorage* page_storage, ObjectIdentifier identifier,
- fit::function<void(Status, std::unique_ptr<const TreeNode>)> callback) {
- page_storage->GetObject(
- identifier, PageStorage::Location::NETWORK,
- [page_storage, identifier, callback = std::move(callback)](
- Status status, std::unique_ptr<const Object> object) mutable {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- std::unique_ptr<const TreeNode> node;
- status = FromObject(page_storage, std::move(identifier),
- std::move(object), &node);
- callback(status, std::move(node));
- });
-}
-
-void TreeNode::Empty(PageStorage* page_storage,
- fit::function<void(Status, ObjectIdentifier)> callback) {
- FromEntries(page_storage, 0u, std::vector<Entry>(),
- std::map<size_t, ObjectIdentifier>(), std::move(callback));
-}
-
-void TreeNode::FromEntries(
- PageStorage* page_storage, uint8_t level, const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children,
- fit::function<void(Status, ObjectIdentifier)> callback) {
- FXL_DCHECK(children.begin() == children.end() ||
- children.cbegin()->first <= entries.size());
-#ifndef NDEBUG
- for (const auto& identifier : children) {
- FXL_DCHECK(storage::IsDigestValid(identifier.second.object_digest()));
- }
-#endif
- std::string encoding = EncodeNode(level, entries, children);
- page_storage->AddObjectFromLocal(
- ObjectType::TREE_NODE, storage::DataSource::Create(std::move(encoding)),
- std::move(callback));
-}
-
-int TreeNode::GetKeyCount() const { return entries_.size(); }
-
-Status TreeNode::GetEntry(int index, Entry* entry) const {
- FXL_DCHECK(index >= 0 && index < GetKeyCount());
- *entry = entries_[index];
- return Status::OK;
-}
-
-void TreeNode::GetChild(
- int index,
- fit::function<void(Status, std::unique_ptr<const TreeNode>)> callback)
- const {
- FXL_DCHECK(index >= 0 && index <= GetKeyCount());
- const auto it = children_.find(index);
- if (it == children_.end()) {
- callback(Status::NO_SUCH_CHILD, nullptr);
- return;
- }
- return FromIdentifier(page_storage_, it->second, std::move(callback));
-}
-
-Status TreeNode::FindKeyOrChild(convert::ExtendedStringView key,
- int* index) const {
- if (key.empty()) {
- *index = 0;
- return !entries_.empty() && entries_[0].key.empty() ? Status::OK
- : Status::NOT_FOUND;
- }
- auto it =
- std::lower_bound(entries_.begin(), entries_.end(), key,
- [](const Entry& entry, convert::ExtendedStringView key) {
- return entry.key < key;
- });
- if (it == entries_.end()) {
- *index = entries_.size();
- return Status::NOT_FOUND;
- }
- *index = it - entries_.begin();
- if (it->key == key) {
- return Status::OK;
- }
- return Status::NOT_FOUND;
-}
-
-const ObjectIdentifier& TreeNode::GetIdentifier() const { return identifier_; }
-
-Status TreeNode::FromObject(PageStorage* page_storage,
- ObjectIdentifier identifier,
- std::unique_ptr<const Object> object,
- std::unique_ptr<const TreeNode>* node) {
- fxl::StringView data;
- Status status = object->GetData(&data);
- if (status != Status::OK) {
- return status;
- }
- uint8_t level;
- std::vector<Entry> entries;
- std::map<size_t, ObjectIdentifier> children;
- if (!DecodeNode(data, &level, &entries, &children)) {
- return Status::FORMAT_ERROR;
- }
- node->reset(new TreeNode(page_storage, std::move(identifier), level,
- std::move(entries), std::move(children)));
- return Status::OK;
-}
-
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/btree/tree_node.fbs b/bin/ledger/storage/impl/btree/tree_node.fbs
deleted file mode 100644
index 83925aa..0000000
--- a/bin/ledger/storage/impl/btree/tree_node.fbs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-include "peridot/bin/ledger/storage/impl/object_identifier.fbs";
-
-namespace storage;
-
-enum KeyPriorityStorage : byte { EAGER = 0, LAZY = 1 }
-
-table EntryStorage {
- key: [ubyte];
- object_id: ObjectIdentifierStorage;
- priority: KeyPriorityStorage;
-}
-
-table ChildStorage {
- index: ushort (key);
- object_id: ObjectIdentifierStorage;
-}
-
-table TreeNodeStorage {
- entries: [EntryStorage];
- children: [ChildStorage];
- level: ubyte;
-}
-
-root_type TreeNodeStorage;
diff --git a/bin/ledger/storage/impl/btree/tree_node.h b/bin/ledger/storage/impl/btree/tree_node.h
deleted file mode 100644
index 399ca65..0000000
--- a/bin/ledger/storage/impl/btree/tree_node.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_TREE_NODE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_TREE_NODE_H_
-
-#include <memory>
-#include <vector>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace storage {
-namespace btree {
-
-// A node of the B-Tree holding the commit contents.
-class TreeNode {
- public:
- ~TreeNode();
-
- // Creates a |TreeNode| object for an existing node and calls the given
- // |callback| with the returned status and node.
- static void FromIdentifier(
- PageStorage* page_storage, ObjectIdentifier identifier,
- fit::function<void(Status, std::unique_ptr<const TreeNode>)> callback);
-
- // Creates a |TreeNode| object with the given entries and children. |children|
- // is a map from the index of the child to the identfiier of the child. It
- // only contains non-empty children. It is expected that all child index are
- // between |0| and |size(entries)| (included). The |callback| will be called
- // with the success or error status and the id of the new node.
- static void FromEntries(
- PageStorage* page_storage, uint8_t level,
- const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children,
- fit::function<void(Status, ObjectIdentifier)> callback);
-
- // Creates an empty node, i.e. a TreeNode with no entries and an empty child
- // at index 0 and calls the callback with the result.
- static void Empty(PageStorage* page_storage,
- fit::function<void(Status, ObjectIdentifier)> callback);
-
- // Returns the number of entries stored in this tree node.
- int GetKeyCount() const;
-
- // Finds the entry at position |index| and stores it in |entry|. |index| has
- // to be in [0, GetKeyCount() - 1].
- Status GetEntry(int index, Entry* entry) const;
-
- // Finds the child node at position |index| and calls the |callback| with the
- // result. |index| has to be in [0, GetKeyCount()]. If the child at the given
- // index is empty |NO_SUCH_CHILD| is returned and the value of |child| is not
- // updated.
- void GetChild(int index,
- fit::function<void(Status, std::unique_ptr<const TreeNode>)>
- callback) const;
-
- // Searches for the given |key| in this node. If it is found, |OK| is
- // returned and index contains the index of the entry. If not, |NOT_FOUND|
- // is returned and index stores the index of the child node where the key
- // might be found.
- Status FindKeyOrChild(convert::ExtendedStringView key, int* index) const;
-
- const ObjectIdentifier& GetIdentifier() const;
-
- uint8_t level() const { return level_; }
-
- const std::vector<Entry>& entries() const { return entries_; }
-
- const std::map<size_t, ObjectIdentifier>& children_identifiers() const {
- return children_;
- }
-
- private:
- TreeNode(PageStorage* page_storage, ObjectIdentifier identifier,
- uint8_t level, std::vector<Entry> entries,
- std::map<size_t, ObjectIdentifier> children);
-
- // Creates a |TreeNode| object for an existing |object| and stores it in the
- // given |node|.
- static Status FromObject(PageStorage* page_storage,
- ObjectIdentifier identifier,
- std::unique_ptr<const Object> object,
- std::unique_ptr<const TreeNode>* node);
-
- PageStorage* page_storage_;
- ObjectIdentifier identifier_;
- const uint8_t level_;
- const std::vector<Entry> entries_;
- const std::map<size_t, ObjectIdentifier> children_;
-};
-
-} // namespace btree
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_BTREE_TREE_NODE_H_
diff --git a/bin/ledger/storage/impl/btree/tree_node_unittest.cc b/bin/ledger/storage/impl/btree/tree_node_unittest.cc
deleted file mode 100644
index 93218fa..0000000
--- a/bin/ledger/storage/impl/btree/tree_node_unittest.cc
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fxl/logging.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-#include "peridot/bin/ledger/storage/impl/btree/encoding.h"
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-namespace btree {
-namespace {
-
-class FakePageStorageValidDigest : public fake::FakePageStorage {
- public:
- using fake::FakePageStorage::FakePageStorage;
-
- protected:
- ObjectDigest FakeDigest(fxl::StringView content) const override {
- // BTree code needs storage to return valid digests.
- return MakeObjectDigest(content.ToString());
- }
-};
-
-class TreeNodeTest : public StorageTest {
- public:
- TreeNodeTest() : fake_storage_(&environment_, "page_id") {}
-
- ~TreeNodeTest() override {}
-
- // Test:
- void SetUp() override {
- ::testing::Test::SetUp();
- std::srand(0);
- }
-
- protected:
- PageStorage* GetStorage() override { return &fake_storage_; }
-
- std::unique_ptr<const TreeNode> CreateEmptyNode() {
- ObjectIdentifier root_identifier;
- EXPECT_TRUE(GetEmptyNodeIdentifier(&root_identifier));
- std::unique_ptr<const TreeNode> node;
- EXPECT_TRUE(CreateNodeFromIdentifier(root_identifier, &node));
- return node;
- }
-
- Entry GetEntry(const TreeNode* node, int index) {
- Entry found_entry;
- EXPECT_EQ(Status::OK, node->GetEntry(index, &found_entry));
- return found_entry;
- }
-
- std::map<size_t, ObjectIdentifier> CreateChildren(int size) {
- std::map<size_t, ObjectIdentifier> children;
- for (int i = 0; i < size; ++i) {
- children[i] = CreateEmptyNode()->GetIdentifier();
- }
- return children;
- }
-
- FakePageStorageValidDigest fake_storage_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(TreeNodeTest);
-};
-
-TEST_F(TreeNodeTest, CreateGetTreeNode) {
- std::unique_ptr<const TreeNode> node = CreateEmptyNode();
-
- bool called;
- Status status;
- std::unique_ptr<const TreeNode> found_node;
- TreeNode::FromIdentifier(&fake_storage_, node->GetIdentifier(),
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &found_node));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, found_node);
-
- TreeNode::FromIdentifier(&fake_storage_,
- RandomObjectIdentifier(environment_.random()),
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &found_node));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
-}
-
-TEST_F(TreeNodeTest, GetEntryChild) {
- int size = 10;
- std::vector<Entry> entries;
- ASSERT_TRUE(CreateEntries(size, &entries));
- std::unique_ptr<const TreeNode> node;
- ASSERT_TRUE(CreateNodeFromEntries(entries, {}, &node));
- EXPECT_EQ(size, node->GetKeyCount());
- for (int i = 0; i < size; ++i) {
- EXPECT_EQ(entries[i], GetEntry(node.get(), i));
- }
-
- bool called;
- for (int i = 0; i <= size; ++i) {
- Status status;
- std::unique_ptr<const TreeNode> child;
- node->GetChild(i, callback::Capture(callback::SetWhenCalled(&called),
- &status, &child));
- RunLoopFor(kSufficientDelay);
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::NO_SUCH_CHILD, status);
- EXPECT_EQ(node->children_identifiers().find(i),
- node->children_identifiers().end());
- }
-}
-
-TEST_F(TreeNodeTest, FindKeyOrChild) {
- int size = 10;
- std::vector<Entry> entries;
- ASSERT_TRUE(CreateEntries(size, &entries));
- std::unique_ptr<const TreeNode> node;
- ASSERT_TRUE(CreateNodeFromEntries(entries, {}, &node));
-
- int index;
- EXPECT_EQ(Status::OK, node->FindKeyOrChild("key00", &index));
- EXPECT_EQ(0, index);
-
- EXPECT_EQ(Status::OK, node->FindKeyOrChild("key02", &index));
- EXPECT_EQ(2, index);
-
- EXPECT_EQ(Status::OK, node->FindKeyOrChild("key09", &index));
- EXPECT_EQ(9, index);
-
- EXPECT_EQ(Status::NOT_FOUND, node->FindKeyOrChild("0", &index));
- EXPECT_EQ(0, index);
-
- EXPECT_EQ(Status::NOT_FOUND, node->FindKeyOrChild("key001", &index));
- EXPECT_EQ(1, index);
-
- EXPECT_EQ(Status::NOT_FOUND, node->FindKeyOrChild("key020", &index));
- EXPECT_EQ(3, index);
-
- EXPECT_EQ(Status::NOT_FOUND, node->FindKeyOrChild("key999", &index));
- EXPECT_EQ(10, index);
-}
-
-TEST_F(TreeNodeTest, Serialization) {
- int size = 3;
- std::vector<Entry> entries;
- ASSERT_TRUE(CreateEntries(size, &entries));
- std::map<size_t, ObjectIdentifier> children = CreateChildren(size + 1);
- std::unique_ptr<const TreeNode> node;
- ASSERT_TRUE(CreateNodeFromEntries(entries, children, &node));
-
- bool called;
- Status status;
- std::unique_ptr<const Object> object;
- fake_storage_.GetObject(
- node->GetIdentifier(), PageStorage::Location::LOCAL,
- callback::Capture(callback::SetWhenCalled(&called), &status, &object));
- RunLoopFor(kSufficientDelay);
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- std::unique_ptr<const TreeNode> retrieved_node;
- EXPECT_EQ(node->GetIdentifier(), object->GetIdentifier());
- ASSERT_TRUE(CreateNodeFromIdentifier(node->GetIdentifier(), &retrieved_node));
-
- fxl::StringView data;
- EXPECT_EQ(Status::OK, object->GetData(&data));
- uint8_t level;
- std::vector<Entry> parsed_entries;
- std::map<size_t, ObjectIdentifier> parsed_children;
- EXPECT_TRUE(DecodeNode(data, &level, &parsed_entries, &parsed_children));
- EXPECT_EQ(entries, parsed_entries);
- EXPECT_EQ(children, parsed_children);
-}
-
-} // namespace
-} // namespace btree
-} // namespace storage
diff --git a/bin/ledger/storage/impl/commit.fbs b/bin/ledger/storage/impl/commit.fbs
deleted file mode 100644
index 8a496c3..0000000
--- a/bin/ledger/storage/impl/commit.fbs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-include "peridot/bin/ledger/storage/impl/object_identifier.fbs";
-
-namespace storage;
-
-struct IdStorage {
- b00: ubyte;
- b01: ubyte;
- b02: ubyte;
- b03: ubyte;
- b04: ubyte;
- b05: ubyte;
- b06: ubyte;
- b07: ubyte;
- b08: ubyte;
- b09: ubyte;
- b10: ubyte;
- b11: ubyte;
- b12: ubyte;
- b13: ubyte;
- b14: ubyte;
- b15: ubyte;
- b16: ubyte;
- b17: ubyte;
- b18: ubyte;
- b19: ubyte;
- b20: ubyte;
- b21: ubyte;
- b22: ubyte;
- b23: ubyte;
- b24: ubyte;
- b25: ubyte;
- b26: ubyte;
- b27: ubyte;
- b28: ubyte;
- b29: ubyte;
- b30: ubyte;
- b31: ubyte;
-}
-
-table CommitStorage {
- timestamp: long;
- generation: ulong;
- root_node_id: ObjectIdentifierStorage;
- parents: [storage.IdStorage];
-}
-
-root_type CommitStorage;
diff --git a/bin/ledger/storage/impl/commit_impl.cc b/bin/ledger/storage/impl/commit_impl.cc
deleted file mode 100644
index 47c81d9..0000000
--- a/bin/ledger/storage/impl/commit_impl.cc
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/commit_impl.h"
-
-#include <sys/time.h>
-#include <algorithm>
-#include <utility>
-
-#include <flatbuffers/flatbuffers.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/build_config.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_counted.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-#include "peridot/bin/ledger/storage/impl/commit_generated.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-#include "peridot/bin/ledger/storage/impl/object_identifier_generated.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-
-namespace {
-
-static_assert(sizeof(IdStorage) == kCommitIdSize,
- "storage size for id is incorrect");
-
-const IdStorage* ToIdStorage(CommitIdView id) {
- return reinterpret_cast<const IdStorage*>(id.data());
-}
-
-CommitIdView ToCommitIdView(const IdStorage* id_storage) {
- return CommitIdView(fxl::StringView(reinterpret_cast<const char*>(id_storage),
- sizeof(IdStorage)));
-}
-
-} // namespace
-
-class CommitImpl::SharedStorageBytes
- : public fxl::RefCountedThreadSafe<SharedStorageBytes> {
- public:
- const std::string& bytes() { return bytes_; }
-
- private:
- FRIEND_REF_COUNTED_THREAD_SAFE(SharedStorageBytes);
- FRIEND_MAKE_REF_COUNTED(SharedStorageBytes);
- explicit SharedStorageBytes(std::string bytes) : bytes_(std::move(bytes)) {}
- ~SharedStorageBytes() {}
-
- std::string bytes_;
-};
-
-namespace {
-// Checks whether the given |storage_bytes| are a valid serialization of a
-// commit.
-bool CheckValidSerialization(fxl::StringView storage_bytes) {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(storage_bytes.data()),
- storage_bytes.size());
-
- if (!VerifyCommitStorageBuffer(verifier)) {
- return false;
- };
-
- const CommitStorage* commit_storage = GetCommitStorage(storage_bytes.data());
- auto parents = commit_storage->parents();
- return parents && parents->size() >= 1 && parents->size() <= 2;
-}
-
-std::string SerializeCommit(
- uint64_t generation, zx::time_utc timestamp,
- const ObjectIdentifier& root_node_identifier,
- std::vector<std::unique_ptr<const Commit>> parent_commits) {
- flatbuffers::FlatBufferBuilder builder;
-
- auto parents_id = builder.CreateVectorOfStructs(
- parent_commits.size(),
- static_cast<std::function<void(size_t, IdStorage*)>>(
- [&parent_commits](size_t i, IdStorage* child_storage) {
- *child_storage = *ToIdStorage(parent_commits[i]->GetId());
- }));
-
- auto root_node_storage =
- ToObjectIdentifierStorage(&builder, root_node_identifier);
- auto storage = CreateCommitStorage(builder, timestamp.get(), generation,
- root_node_storage, parents_id);
- builder.Finish(storage);
- return std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
- builder.GetSize());
-}
-} // namespace
-
-CommitImpl::CommitImpl(Token /* token */, PageStorage* page_storage,
- CommitId id, zx::time_utc timestamp, uint64_t generation,
- ObjectIdentifier root_node_identifier,
- std::vector<CommitIdView> parent_ids,
- fxl::RefPtr<SharedStorageBytes> storage_bytes)
- : page_storage_(page_storage),
- id_(std::move(id)),
- timestamp_(timestamp),
- generation_(generation),
- root_node_identifier_(std::move(root_node_identifier)),
- parent_ids_(std::move(parent_ids)),
- storage_bytes_(std::move(storage_bytes)) {
- FXL_DCHECK(page_storage_ != nullptr);
- FXL_DCHECK(id_ == kFirstPageCommitId ||
- (!parent_ids_.empty() && parent_ids_.size() <= 2));
-}
-
-CommitImpl::~CommitImpl() {}
-
-Status CommitImpl::FromStorageBytes(PageStorage* page_storage, CommitId id,
- std::string storage_bytes,
- std::unique_ptr<const Commit>* commit) {
- FXL_DCHECK(id != kFirstPageCommitId);
-
- if (!CheckValidSerialization(storage_bytes)) {
- return Status::FORMAT_ERROR;
- }
-
- auto storage_ptr =
- fxl::MakeRefCounted<SharedStorageBytes>(std::move(storage_bytes));
-
- const CommitStorage* commit_storage =
- GetCommitStorage(storage_ptr->bytes().data());
-
- ObjectIdentifier root_node_identifier =
- ToObjectIdentifier(commit_storage->root_node_id());
- std::vector<CommitIdView> parent_ids;
-
- for (size_t i = 0; i < commit_storage->parents()->size(); ++i) {
- parent_ids.emplace_back(ToCommitIdView(commit_storage->parents()->Get(i)));
- }
- *commit = std::make_unique<CommitImpl>(
- Token(), page_storage, std::move(id),
- zx::time_utc(commit_storage->timestamp()), commit_storage->generation(),
- std::move(root_node_identifier), parent_ids, std::move(storage_ptr));
- return Status::OK;
-}
-
-std::unique_ptr<const Commit> CommitImpl::FromContentAndParents(
- timekeeper::Clock* clock, PageStorage* page_storage,
- ObjectIdentifier root_node_identifier,
- std::vector<std::unique_ptr<const Commit>> parent_commits) {
- FXL_DCHECK(parent_commits.size() == 1 || parent_commits.size() == 2);
-
- uint64_t parent_generation = 0;
- for (const auto& commit : parent_commits) {
- parent_generation = std::max(parent_generation, commit->GetGeneration());
- }
- uint64_t generation = parent_generation + 1;
-
- // Sort commit ids for uniqueness.
- std::sort(parent_commits.begin(), parent_commits.end(),
- [](const std::unique_ptr<const Commit>& c1,
- const std::unique_ptr<const Commit>& c2) {
- return c1->GetId() < c2->GetId();
- });
- // Compute timestamp.
- zx::time_utc timestamp;
- if (parent_commits.size() == 2) {
- timestamp = std::max(parent_commits[0]->GetTimestamp(),
- parent_commits[1]->GetTimestamp());
- } else {
- zx_status_t status = clock->Now(×tamp);
- FXL_CHECK(status == ZX_OK);
- }
-
- std::string storage_bytes = SerializeCommit(
- generation, timestamp, root_node_identifier, std::move(parent_commits));
-
- CommitId id = encryption::SHA256WithLengthHash(storage_bytes);
-
- std::unique_ptr<const Commit> commit;
- Status status = FromStorageBytes(page_storage, std::move(id),
- std::move(storage_bytes), &commit);
- FXL_DCHECK(status == Status::OK);
- return commit;
-}
-
-void CommitImpl::Empty(
- PageStorage* page_storage,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) {
- btree::TreeNode::Empty(
- page_storage, [page_storage, callback = std::move(callback)](
- Status s, ObjectIdentifier root_identifier) {
- if (s != Status::OK) {
- callback(s, nullptr);
- return;
- }
-
- FXL_DCHECK(IsDigestValid(root_identifier.object_digest()));
-
- auto storage_ptr = fxl::MakeRefCounted<SharedStorageBytes>("");
-
- auto ptr = std::make_unique<CommitImpl>(
- Token(), page_storage, kFirstPageCommitId.ToString(),
- zx::time_utc(), 0, std::move(root_identifier),
- std::vector<CommitIdView>(), std::move(storage_ptr));
- callback(Status::OK, std::move(ptr));
- });
-}
-
-std::unique_ptr<const Commit> CommitImpl::Clone() const {
- return std::make_unique<CommitImpl>(Token(), page_storage_, id_, timestamp_,
- generation_, root_node_identifier_,
- parent_ids_, storage_bytes_);
-}
-
-const CommitId& CommitImpl::GetId() const { return id_; }
-
-std::vector<CommitIdView> CommitImpl::GetParentIds() const {
- return parent_ids_;
-}
-
-zx::time_utc CommitImpl::GetTimestamp() const { return timestamp_; }
-
-uint64_t CommitImpl::GetGeneration() const { return generation_; }
-
-ObjectIdentifier CommitImpl::GetRootIdentifier() const {
- return root_node_identifier_;
-}
-
-fxl::StringView CommitImpl::GetStorageBytes() const {
- return storage_bytes_->bytes();
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/commit_impl.h b/bin/ledger/storage/impl/commit_impl.h
deleted file mode 100644
index eb35cb9..0000000
--- a/bin/ledger/storage/impl/commit_impl.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_COMMIT_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_COMMIT_IMPL_H_
-
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/timekeeper/clock.h>
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace storage {
-
-class CommitImpl : public Commit {
- private:
- // Passkey idiom to restrict access to the constructor to static factories.
- class Token;
- class SharedStorageBytes;
-
- public:
- // Creates a new |CommitImpl| object with the given contents.
- CommitImpl(Token token, PageStorage* page_storage, CommitId id,
- zx::time_utc timestamp, uint64_t generation,
- ObjectIdentifier root_node_identifier,
- std::vector<CommitIdView> parent_ids,
- fxl::RefPtr<SharedStorageBytes> storage_bytes);
-
- ~CommitImpl() override;
-
- // Factory method for creating a |CommitImpl| object given its storage
- // representation. If the format is incorrect, |nullptr| will be returned.
- static Status FromStorageBytes(PageStorage* page_storage, CommitId id,
- std::string storage_bytes,
- std::unique_ptr<const Commit>* commit);
-
- static std::unique_ptr<const Commit> FromContentAndParents(
- timekeeper::Clock* clock, PageStorage* page_storage,
- ObjectIdentifier root_node_identifier,
- std::vector<std::unique_ptr<const Commit>> parent_commits);
-
- // Factory method for creating an empty |CommitImpl| object, i.e. without
- // parents and with empty contents.
- static void Empty(
- PageStorage* page_storage,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback);
-
- // Commit:
- std::unique_ptr<const Commit> Clone() const override;
- const CommitId& GetId() const override;
- std::vector<CommitIdView> GetParentIds() const override;
- zx::time_utc GetTimestamp() const override;
- uint64_t GetGeneration() const override;
- ObjectIdentifier GetRootIdentifier() const override;
- fxl::StringView GetStorageBytes() const override;
-
- private:
- class Token {
- private:
- Token() {}
- friend CommitImpl;
- };
-
- PageStorage* page_storage_;
- const CommitId id_;
- const zx::time_utc timestamp_;
- const uint64_t generation_;
- const ObjectIdentifier root_node_identifier_;
- const std::vector<CommitIdView> parent_ids_;
- const fxl::RefPtr<SharedStorageBytes> storage_bytes_;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_COMMIT_IMPL_H_
diff --git a/bin/ledger/storage/impl/commit_impl_unittest.cc b/bin/ledger/storage/impl/commit_impl_unittest.cc
deleted file mode 100644
index 6bf2b34..0000000
--- a/bin/ledger/storage/impl/commit_impl_unittest.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/commit_impl.h"
-
-#include <tuple>
-
-#include <lib/fxl/macros.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/storage/fake/fake_page_storage.h"
-#include "peridot/bin/ledger/storage/impl/commit_random_impl.h"
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-namespace {
-
-class CommitImplTest : public StorageTest {
- public:
- CommitImplTest() : page_storage_(&environment_, "page_id") {}
-
- ~CommitImplTest() override {}
-
- protected:
- PageStorage* GetStorage() override { return &page_storage_; }
-
- bool CheckCommitEquals(const Commit& expected, const Commit& commit) {
- return std::forward_as_tuple(expected.GetId(), expected.GetTimestamp(),
- expected.GetParentIds(),
- expected.GetRootIdentifier()) ==
- std::forward_as_tuple(commit.GetId(), commit.GetTimestamp(),
- commit.GetParentIds(),
- commit.GetRootIdentifier());
- }
-
- bool CheckCommitStorageBytes(const std::unique_ptr<const Commit>& commit) {
- std::unique_ptr<const Commit> copy;
- Status status = CommitImpl::FromStorageBytes(
- &page_storage_, commit->GetId(), commit->GetStorageBytes().ToString(),
- ©);
- EXPECT_EQ(Status::OK, status);
-
- return CheckCommitEquals(*commit, *copy);
- }
-
- fake::FakePageStorage page_storage_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(CommitImplTest);
-};
-
-TEST_F(CommitImplTest, CommitStorageBytes) {
- ObjectIdentifier root_node_identifier =
- RandomObjectIdentifier(environment_.random());
-
- std::vector<std::unique_ptr<const Commit>> parents;
-
- // A commit with one parent.
- parents.emplace_back(
- std::make_unique<CommitRandomImpl>(environment_.random()));
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), &page_storage_, root_node_identifier,
- std::move(parents));
- EXPECT_TRUE(CheckCommitStorageBytes(commit));
-
- // A commit with two parents.
- parents = std::vector<std::unique_ptr<const Commit>>();
- parents.emplace_back(
- std::make_unique<CommitRandomImpl>(environment_.random()));
- parents.emplace_back(
- std::make_unique<CommitRandomImpl>(environment_.random()));
- std::unique_ptr<const Commit> commit2 = CommitImpl::FromContentAndParents(
- environment_.clock(), &page_storage_, root_node_identifier,
- std::move(parents));
- EXPECT_TRUE(CheckCommitStorageBytes(commit2));
-}
-
-TEST_F(CommitImplTest, CloneCommit) {
- ObjectIdentifier root_node_identifier =
- RandomObjectIdentifier(environment_.random());
-
- std::vector<std::unique_ptr<const Commit>> parents;
- parents.emplace_back(
- std::make_unique<CommitRandomImpl>(environment_.random()));
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), &page_storage_, root_node_identifier,
- std::move(parents));
- std::unique_ptr<const Commit> copy;
- Status status =
- CommitImpl::FromStorageBytes(&page_storage_, commit->GetId(),
- commit->GetStorageBytes().ToString(), ©);
- ASSERT_EQ(Status::OK, status);
- std::unique_ptr<const Commit> clone = commit->Clone();
- EXPECT_TRUE(CheckCommitEquals(*copy, *clone));
-}
-
-TEST_F(CommitImplTest, MergeCommitTimestamp) {
- ObjectIdentifier root_node_identifier =
- RandomObjectIdentifier(environment_.random());
-
- std::vector<std::unique_ptr<const Commit>> parents;
- parents.emplace_back(
- std::make_unique<CommitRandomImpl>(environment_.random()));
- parents.emplace_back(
- std::make_unique<CommitRandomImpl>(environment_.random()));
- EXPECT_NE(parents[0]->GetTimestamp(), parents[1]->GetTimestamp());
- auto max_timestamp =
- std::max(parents[0]->GetTimestamp(), parents[1]->GetTimestamp());
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), &page_storage_, root_node_identifier,
- std::move(parents));
-
- EXPECT_EQ(max_timestamp, commit->GetTimestamp());
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/impl/commit_random_impl.cc b/bin/ledger/storage/impl/commit_random_impl.cc
deleted file mode 100644
index 6a8c76c..0000000
--- a/bin/ledger/storage/impl/commit_random_impl.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/commit_random_impl.h"
-
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-
-CommitRandomImpl::CommitRandomImpl(rng::Random* random)
- : id_(RandomCommitId(random)),
- timestamp_(random->Draw<zx::time_utc>()),
- generation_(random->Draw<uint64_t>()),
- root_node_identifier_(RandomObjectIdentifier(random)),
- parent_ids_{RandomCommitId(random)},
- parent_ids_views_{parent_ids_[0]},
- storage_bytes_(RandomString(random, 64)) {}
-
-CommitRandomImpl::~CommitRandomImpl() = default;
-
-CommitRandomImpl::CommitRandomImpl(const CommitRandomImpl& other) {
- *this = other;
-}
-
-CommitRandomImpl& CommitRandomImpl::operator=(const CommitRandomImpl& other) {
- id_ = other.id_;
- timestamp_ = other.timestamp_;
- generation_ = other.generation_;
- root_node_identifier_ = other.root_node_identifier_;
- parent_ids_ = other.parent_ids_;
- storage_bytes_ = other.storage_bytes_;
- parent_ids_views_ = {parent_ids_[0]};
- return *this;
-}
-
-std::unique_ptr<const Commit> CommitRandomImpl::Clone() const {
- return std::make_unique<CommitRandomImpl>(*this);
-}
-
-const CommitId& CommitRandomImpl::GetId() const { return id_; }
-
-std::vector<CommitIdView> CommitRandomImpl::GetParentIds() const {
- return parent_ids_views_;
-}
-
-zx::time_utc CommitRandomImpl::GetTimestamp() const { return timestamp_; }
-
-uint64_t CommitRandomImpl::GetGeneration() const { return generation_; }
-
-ObjectIdentifier CommitRandomImpl::GetRootIdentifier() const {
- return root_node_identifier_;
-}
-
-fxl::StringView CommitRandomImpl::GetStorageBytes() const {
- return storage_bytes_;
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/commit_random_impl.h b/bin/ledger/storage/impl/commit_random_impl.h
deleted file mode 100644
index dd7afe5..0000000
--- a/bin/ledger/storage/impl/commit_random_impl.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_COMMIT_RANDOM_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_COMMIT_RANDOM_IMPL_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/lib/rng/random.h"
-
-namespace storage {
-
-// Implementaton of Commit returning random values (fixed for each instance).
-class CommitRandomImpl : public Commit {
- public:
- CommitRandomImpl(rng::Random* random);
- ~CommitRandomImpl() override;
- CommitRandomImpl(const CommitRandomImpl& other);
- CommitRandomImpl& operator=(const CommitRandomImpl& other);
-
- // Commit:
- std::unique_ptr<const Commit> Clone() const override;
-
- const CommitId& GetId() const override;
-
- std::vector<CommitIdView> GetParentIds() const override;
-
- zx::time_utc GetTimestamp() const override;
-
- uint64_t GetGeneration() const override;
-
- ObjectIdentifier GetRootIdentifier() const override;
-
- fxl::StringView GetStorageBytes() const override;
-
- private:
- CommitId id_;
- zx::time_utc timestamp_;
- uint64_t generation_;
- ObjectIdentifier root_node_identifier_;
- std::vector<CommitId> parent_ids_;
- std::vector<CommitIdView> parent_ids_views_;
- std::string storage_bytes_;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_COMMIT_RANDOM_IMPL_H_
diff --git a/bin/ledger/storage/impl/constants.h b/bin/ledger/storage/impl/constants.h
deleted file mode 100644
index cad4fa7..0000000
--- a/bin/ledger/storage/impl/constants.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_CONSTANTS_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_CONSTANTS_H_
-
-namespace storage {
-
-inline constexpr size_t kStorageHashSize = 32;
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_CONSTANTS_H_
diff --git a/bin/ledger/storage/impl/data_serialization.h b/bin/ledger/storage/impl/data_serialization.h
deleted file mode 100644
index 6370510..0000000
--- a/bin/ledger/storage/impl/data_serialization.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_DATA_SERIALIZATION_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_DATA_SERIALIZATION_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace storage {
-
-template <typename I>
-I DeserializeData(fxl::StringView value) {
- static_assert(std::is_trivially_copyable<I>::value,
- "The return type must be trivially copyable.");
- FXL_DCHECK(value.size() == sizeof(I));
- I result;
- memcpy(&result, value.data(), sizeof(I));
- return result;
-}
-
-template <typename I>
-fxl::StringView SerializeData(const I& value) {
- static_assert(std::is_trivially_copyable<I>::value,
- "The parameter type must be trivially copyable.");
- return fxl::StringView(reinterpret_cast<const char*>(&value), sizeof(I));
-}
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_DATA_SERIALIZATION_H_
diff --git a/bin/ledger/storage/impl/db_serialization.cc b/bin/ledger/storage/impl/db_serialization.cc
deleted file mode 100644
index 31395dc..0000000
--- a/bin/ledger/storage/impl/db_serialization.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/db_serialization.h"
-
-#include <lib/fxl/strings/concatenate.h>
-#include <lib/fxl/strings/string_view.h>
-#include <zircon/syscalls.h>
-
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-
-namespace storage {
-
-// HeadRow.
-
-constexpr fxl::StringView HeadRow::kPrefix;
-
-std::string HeadRow::GetKeyFor(CommitIdView head) {
- return fxl::Concatenate({kPrefix, head});
-}
-
-// CommitRow.
-
-constexpr fxl::StringView CommitRow::kPrefix;
-
-std::string CommitRow::GetKeyFor(CommitIdView commit_id) {
- return fxl::Concatenate({kPrefix, commit_id});
-}
-
-// ObjectRow.
-
-constexpr fxl::StringView ObjectRow::kPrefix;
-
-std::string ObjectRow::GetKeyFor(const ObjectDigest& object_digest) {
- return fxl::Concatenate({kPrefix, object_digest.Serialize()});
-}
-
-// UnsyncedCommitRow.
-
-constexpr fxl::StringView UnsyncedCommitRow::kPrefix;
-
-std::string UnsyncedCommitRow::GetKeyFor(const CommitId& commit_id) {
- return fxl::Concatenate({kPrefix, commit_id});
-}
-
-// ObjectStatusRow.
-
-constexpr fxl::StringView ObjectStatusRow::kTransientPrefix;
-constexpr fxl::StringView ObjectStatusRow::kLocalPrefix;
-constexpr fxl::StringView ObjectStatusRow::kSyncedPrefix;
-
-std::string ObjectStatusRow::GetKeyFor(
- PageDbObjectStatus object_status,
- const ObjectIdentifier& object_identifier) {
- return fxl::Concatenate(
- {GetPrefixFor(object_status), EncodeObjectIdentifier(object_identifier)});
-}
-
-fxl::StringView ObjectStatusRow::GetPrefixFor(
- PageDbObjectStatus object_status) {
- switch (object_status) {
- case PageDbObjectStatus::UNKNOWN:
- FXL_NOTREACHED();
- return "";
- case PageDbObjectStatus::TRANSIENT:
- return kTransientPrefix;
- case PageDbObjectStatus::LOCAL:
- return kLocalPrefix;
- case PageDbObjectStatus::SYNCED:
- return kSyncedPrefix;
- }
-}
-
-// ImplicitJournalMetadataRow.
-
-constexpr fxl::StringView ImplicitJournalMetadataRow::kPrefix;
-
-std::string ImplicitJournalMetadataRow::GetKeyFor(const JournalId& journal_id) {
- return fxl::Concatenate({kPrefix, journal_id});
-}
-
-// SyncMetadataRow.
-
-constexpr fxl::StringView SyncMetadataRow::kPrefix;
-
-std::string SyncMetadataRow::GetKeyFor(fxl::StringView key) {
- return fxl::Concatenate({kPrefix, key});
-}
-
-// JournalEntryRow.
-
-constexpr fxl::StringView JournalEntryRow::kPrefix;
-constexpr fxl::StringView JournalEntryRow::kJournalEntry;
-constexpr fxl::StringView JournalEntryRow::kDeletePrefix;
-constexpr char JournalEntryRow::kImplicitPrefix;
-constexpr char JournalEntryRow::kExplicitPrefix;
-constexpr char JournalEntryRow::kAddPrefix;
-constexpr char JournalEntryRow::kClear;
-
-std::string JournalEntryRow::NewJournalId(rng::Random* random,
- JournalType journal_type) {
- std::string id;
- id.resize(kJournalIdSize);
- id[0] = (journal_type == JournalType::IMPLICIT ? kImplicitPrefix
- : kExplicitPrefix);
- random->Draw(&id[1], kJournalIdSize - 1);
- return id;
-}
-
-std::string JournalEntryRow::GetPrefixFor(const JournalId& journal_id) {
- return fxl::Concatenate({kPrefix, journal_id, "/"});
-}
-
-std::string JournalEntryRow::GetEntriesPrefixFor(const JournalId& journal_id) {
- return fxl::Concatenate(
- {JournalEntryRow::GetPrefixFor(journal_id), kJournalEntry});
-}
-
-std::string JournalEntryRow::GetKeyFor(const JournalId& id,
- fxl::StringView key) {
- return fxl::Concatenate({JournalEntryRow::GetEntriesPrefixFor(id), key});
-}
-
-std::string JournalEntryRow::GetClearMarkerKey(const JournalId& id) {
- return fxl::Concatenate({JournalEntryRow::GetPrefixFor(id), {&kClear, 1}});
-}
-
-std::string JournalEntryRow::GetValueFor(
- const ObjectIdentifier& object_identifier, KeyPriority priority) {
- char priority_byte =
- (priority == KeyPriority::EAGER) ? kEagerPrefix : kLazyPrefix;
- return fxl::Concatenate({{&kAddPrefix, 1},
- {&priority_byte, 1},
- EncodeObjectIdentifier(object_identifier)});
-}
-
-Status JournalEntryRow::ExtractObjectIdentifier(
- fxl::StringView db_value, ObjectIdentifier* object_identifier) {
- if (db_value[0] == kDeletePrefix[0]) {
- return Status::NOT_FOUND;
- }
- if (!DecodeObjectIdentifier(db_value.substr(kAddPrefixSize),
- object_identifier)) {
- return Status::FORMAT_ERROR;
- }
- return Status::OK;
-}
-
-// PageIsOnlineRow.
-
-constexpr fxl::StringView PageIsOnlineRow::kKey;
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/db_serialization.h b/bin/ledger/storage/impl/db_serialization.h
deleted file mode 100644
index ee2c49e..0000000
--- a/bin/ledger/storage/impl/db_serialization.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_DB_SERIALIZATION_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_DB_SERIALIZATION_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/impl/page_db.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/lib/rng/random.h"
-
-namespace storage {
-
-class HeadRow {
- public:
- static constexpr fxl::StringView kPrefix = "heads/";
-
- static std::string GetKeyFor(CommitIdView head);
-};
-
-class CommitRow {
- public:
- static constexpr fxl::StringView kPrefix = "commits/";
-
- static std::string GetKeyFor(CommitIdView commit_id);
-};
-
-class ObjectRow {
- public:
- static constexpr fxl::StringView kPrefix = "objects/";
-
- static std::string GetKeyFor(const ObjectDigest& object_digest);
-};
-
-class UnsyncedCommitRow {
- public:
- static constexpr fxl::StringView kPrefix = "unsynced/commits/";
-
- static std::string GetKeyFor(const CommitId& commit_id);
-};
-
-class ObjectStatusRow {
- public:
- static constexpr fxl::StringView kTransientPrefix =
- "transient/object_digests/";
- static constexpr fxl::StringView kLocalPrefix = "local/object_digests/";
- static constexpr fxl::StringView kSyncedPrefix = "synced/object_digests/";
-
- static std::string GetKeyFor(PageDbObjectStatus object_status,
- const ObjectIdentifier& object_identifier);
-
- private:
- static fxl::StringView GetPrefixFor(PageDbObjectStatus object_status);
-};
-
-class ImplicitJournalMetadataRow {
- public:
- static constexpr fxl::StringView kPrefix = "journals/implicit_metadata/";
-
- static std::string GetKeyFor(const JournalId& journal_id);
-};
-
-class SyncMetadataRow {
- public:
- static constexpr fxl::StringView kPrefix = "sync_metadata/";
-
- static std::string GetKeyFor(fxl::StringView key);
-};
-
-class JournalEntryRow {
- public:
- // Journal keys
- static const size_t kJournalIdSize = 16;
- static constexpr fxl::StringView kPrefix = "journals/";
-
- static constexpr fxl::StringView kJournalEntry = "entry/";
- static constexpr char kImplicitPrefix = 'I';
- static constexpr char kExplicitPrefix = 'E';
- static const size_t kPrefixSize =
- kPrefix.size() + kJournalIdSize + 1 + kJournalEntry.size();
-
- // Journal values
- static constexpr char kClear = 'C';
- static constexpr char kAddPrefix = 'A';
- static constexpr fxl::StringView kDeletePrefix = "D";
- static const char kLazyPrefix = 'L';
- static const char kEagerPrefix = 'E';
- static const size_t kAddPrefixSize = 2;
-
- static std::string NewJournalId(rng::Random* random,
- JournalType journal_type);
-
- static std::string GetPrefixFor(const JournalId& journal_id);
-
- static std::string GetEntriesPrefixFor(const JournalId& journal_id);
-
- static std::string GetKeyFor(const JournalId& id, fxl::StringView key);
-
- static std::string GetValueFor(const ObjectIdentifier& object_identifier,
- KeyPriority priority);
-
- static std::string GetClearMarkerKey(const JournalId& id);
-
- static Status ExtractObjectIdentifier(fxl::StringView db_value,
- ObjectIdentifier* object_identifier);
-};
-
-class PageIsOnlineRow {
- public:
- static constexpr fxl::StringView kKey = "page_is_online";
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_DB_SERIALIZATION_H_
diff --git a/bin/ledger/storage/impl/file_index.cc b/bin/ledger/storage/impl/file_index.cc
deleted file mode 100644
index 85ed804..0000000
--- a/bin/ledger/storage/impl/file_index.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/file_index.h"
-
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-
-namespace storage {
-
-bool FileIndexSerialization::CheckValidFileIndexSerialization(
- fxl::StringView data) {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(data.data()), data.size());
- return VerifyFileIndexBuffer(verifier);
-}
-
-Status FileIndexSerialization::ParseFileIndex(fxl::StringView content,
- const FileIndex** file_index) {
- if (!CheckValidFileIndexSerialization(content)) {
- return Status::FORMAT_ERROR;
- }
- *file_index = GetFileIndex(content.data());
- return Status::OK;
-}
-
-void FileIndexSerialization::BuildFileIndex(
- const std::vector<ObjectIdentifierAndSize>& children,
- std::unique_ptr<DataSource::DataChunk>* output, size_t* total_size) {
- auto builder = std::make_unique<flatbuffers::FlatBufferBuilder>();
- size_t local_total_size = 0u;
-
- std::vector<flatbuffers::Offset<ObjectChild>> object_children;
- for (const auto& identifier_and_size : children) {
- local_total_size += identifier_and_size.size;
- object_children.push_back(
- CreateObjectChild(*builder, identifier_and_size.size,
- ToObjectIdentifierStorage(
- builder.get(), identifier_and_size.identifier)));
- }
- FinishFileIndexBuffer(
- *builder, CreateFileIndex(*builder, local_total_size,
- builder->CreateVector(object_children.data(),
- object_children.size())));
-
- *output = DataSource::DataChunk::Create(std::move(builder));
- *total_size = local_total_size;
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/file_index.fbs b/bin/ledger/storage/impl/file_index.fbs
deleted file mode 100644
index f851fc1..0000000
--- a/bin/ledger/storage/impl/file_index.fbs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-include "peridot/bin/ledger/storage/impl/object_identifier.fbs";
-
-namespace storage;
-
-// An entry for the identifier of a part of a file.
-table ObjectChild {
- size: ulong;
- object_identifier: ObjectIdentifierStorage;
-}
-
-// The index of a chunked file.
-table FileIndex {
- size: ulong;
- children: [ObjectChild];
-}
-
-root_type FileIndex;
diff --git a/bin/ledger/storage/impl/file_index.h b/bin/ledger/storage/impl/file_index.h
deleted file mode 100644
index bf6607f..0000000
--- a/bin/ledger/storage/impl/file_index.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_FILE_INDEX_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_FILE_INDEX_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/impl/file_index_generated.h"
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// Wrappers over flatbuffer serialization of FileIndex that ensures additional
-// validation.
-class FileIndexSerialization {
- public:
- struct ObjectIdentifierAndSize {
- ObjectIdentifier identifier;
- uint64_t size;
- };
-
- // Checks that |data| is a correct encoding for a |FileIndex|.
- static bool CheckValidFileIndexSerialization(fxl::StringView data);
-
- // Parses a |FileIndex| from |content|.
- static Status ParseFileIndex(fxl::StringView content,
- const FileIndex** file_index);
-
- // Builds the |FileIndex| representing the given children.
- static void BuildFileIndex(
- const std::vector<ObjectIdentifierAndSize>& children,
- std::unique_ptr<DataSource::DataChunk>* output, size_t* total_size);
-
- private:
- FileIndexSerialization() {}
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_FILE_INDEX_H_
diff --git a/bin/ledger/storage/impl/file_index_unittest.cc b/bin/ledger/storage/impl/file_index_unittest.cc
deleted file mode 100644
index 283cb96..0000000
--- a/bin/ledger/storage/impl/file_index_unittest.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/file_index.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-
-namespace storage {
-namespace {
-
-using FileIndexSerializationTest = ledger::TestWithEnvironment;
-
-TEST_F(FileIndexSerializationTest, CheckInvalid) {
- EXPECT_FALSE(FileIndexSerialization::CheckValidFileIndexSerialization(""));
-
- std::string ones(200, '\1');
- EXPECT_FALSE(FileIndexSerialization::CheckValidFileIndexSerialization(ones));
-}
-
-TEST_F(FileIndexSerializationTest, SerializationDeserialization) {
- const std::vector<FileIndexSerialization::ObjectIdentifierAndSize> elements =
- {
- {RandomObjectIdentifier(environment_.random()), 1},
- {RandomObjectIdentifier(environment_.random()), 2},
- {RandomObjectIdentifier(environment_.random()), 3},
- {RandomObjectIdentifier(environment_.random()), 4},
- {RandomObjectIdentifier(environment_.random()), 3},
- {RandomObjectIdentifier(environment_.random()), 2},
- {RandomObjectIdentifier(environment_.random()), 1},
- };
-
- constexpr size_t expected_total_size = 16;
-
- std::unique_ptr<DataSource::DataChunk> chunk;
- size_t total_size;
- FileIndexSerialization::BuildFileIndex(elements, &chunk, &total_size);
-
- EXPECT_EQ(expected_total_size, total_size);
-
- const FileIndex* file_index;
- Status status =
- FileIndexSerialization::ParseFileIndex(chunk->Get(), &file_index);
- ASSERT_EQ(Status::OK, status);
-
- EXPECT_EQ(expected_total_size, file_index->size());
- ASSERT_EQ(elements.size(), file_index->children()->size());
- const auto& children = *(file_index->children());
- for (size_t i = 0; i < elements.size(); ++i) {
- EXPECT_EQ(elements[i].size, children[i]->size());
- EXPECT_EQ(elements[i].identifier,
- ToObjectIdentifier(children[i]->object_identifier()));
- }
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/impl/journal_impl.cc b/bin/ledger/storage/impl/journal_impl.cc
deleted file mode 100644
index 3fe3451..0000000
--- a/bin/ledger/storage/impl/journal_impl.cc
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/journal_impl.h"
-
-#include <functional>
-#include <map>
-#include <string>
-#include <utility>
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/storage/impl/btree/builder.h"
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-#include "peridot/bin/ledger/storage/impl/commit_impl.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-
-namespace storage {
-
-JournalImpl::JournalImpl(Token /* token */, JournalType type,
- ledger::Environment* environment,
- PageStorageImpl* page_storage, JournalId id,
- CommitId base)
- : type_(type),
- environment_(environment),
- page_storage_(page_storage),
- id_(std::move(id)),
- base_(std::move(base)),
- valid_(true),
- failed_operation_(false) {}
-
-JournalImpl::~JournalImpl() {
- // Log a warning if the journal was not committed or rolled back.
- if (valid_) {
- FXL_LOG(WARNING) << "Journal not committed or rolled back.";
- }
-}
-
-std::unique_ptr<Journal> JournalImpl::Simple(JournalType type,
- ledger::Environment* environment,
- PageStorageImpl* page_storage,
- const JournalId& id,
- const CommitId& base) {
- return std::make_unique<JournalImpl>(Token(), type, environment, page_storage,
- id, base);
-}
-
-std::unique_ptr<Journal> JournalImpl::Merge(ledger::Environment* environment,
- PageStorageImpl* page_storage,
- const JournalId& id,
- const CommitId& base,
- const CommitId& other) {
- auto journal = std::make_unique<JournalImpl>(
- Token(), JournalType::EXPLICIT, environment, page_storage, id, base);
- journal->other_ = std::make_unique<CommitId>(other);
- return journal;
-}
-
-const JournalId& JournalImpl::GetId() const { return id_; }
-
-void JournalImpl::Commit(
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- serializer_.Serialize<Status, std::unique_ptr<const storage::Commit>>(
- std::move(callback),
- [this](fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- if (!StateAllowsMutation()) {
- callback(Status::ILLEGAL_STATE, nullptr);
- return;
- }
-
- GetParents([this, callback = std::move(callback)](
- Status status,
- std::vector<std::unique_ptr<const storage::Commit>>
- parents) mutable {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- page_storage_->GetJournalEntries(
- id_, [this, parents = std::move(parents),
- callback = std::move(callback)](
- Status status,
- std::unique_ptr<Iterator<const EntryChange>> changes,
- JournalContainsClearOperation
- contains_clear_operation) mutable {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- if (contains_clear_operation ==
- JournalContainsClearOperation::NO) {
- // The journal doesn't contain the clear operation. The
- // changes recorded on the journal need to be executed
- // over the content of the first parent.
- ObjectIdentifier root_identifier =
- parents[0]->GetRootIdentifier();
- CreateCommitFromChanges(
- std::move(parents), std::move(root_identifier),
- std::move(changes), std::move(callback));
- return;
- }
-
- // The journal contains the clear operation. The changes
- // recorded on the journal need to be executed over an empty
- // page.
- btree::TreeNode::Empty(
- page_storage_,
- [this, parents = std::move(parents),
- changes = std::move(changes),
- callback = std::move(callback)](
- Status status,
- ObjectIdentifier root_identifier) mutable {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- CreateCommitFromChanges(
- std::move(parents), std::move(root_identifier),
- std::move(changes), std::move(callback));
- });
- });
- });
- });
-}
-
-void JournalImpl::Rollback(fit::function<void(Status)> callback) {
- serializer_.Serialize<Status>(std::move(callback),
- [this](fit::function<void(Status)> callback) {
- RollbackInternal(std::move(callback));
- });
-}
-
-void JournalImpl::Put(convert::ExtendedStringView key,
- ObjectIdentifier object_identifier, KeyPriority priority,
- fit::function<void(Status)> callback) {
- serializer_.Serialize<Status>(
- std::move(callback),
- [this, key = key.ToString(),
- object_identifier = std::move(object_identifier),
- priority](fit::function<void(Status)> callback) mutable {
- if (!StateAllowsMutation()) {
- callback(Status::ILLEGAL_STATE);
- return;
- }
- page_storage_->AddJournalEntry(
- id_, key, std::move(object_identifier), priority,
- [this, callback = std::move(callback)](Status s) {
- if (s != Status::OK) {
- failed_operation_ = true;
- }
- callback(s);
- });
- });
-}
-
-void JournalImpl::Delete(convert::ExtendedStringView key,
- fit::function<void(Status)> callback) {
- serializer_.Serialize<Status>(
- std::move(callback),
- [this, key = key.ToString()](fit::function<void(Status)> callback) {
- if (!StateAllowsMutation()) {
- callback(Status::ILLEGAL_STATE);
- return;
- }
-
- page_storage_->RemoveJournalEntry(
- id_, key, [this, callback = std::move(callback)](Status s) {
- if (s != Status::OK) {
- failed_operation_ = true;
- }
- callback(s);
- });
- });
-}
-
-void JournalImpl::Clear(fit::function<void(Status)> callback) {
- serializer_.Serialize<Status>(
- std::move(callback), [this](fit::function<void(Status)> callback) {
- if (!StateAllowsMutation()) {
- callback(Status::ILLEGAL_STATE);
- return;
- }
-
- page_storage_->EmptyJournalAndMarkContainsClearOperation(
- id_, [this, callback = std::move(callback)](Status s) {
- if (s != Status::OK) {
- failed_operation_ = true;
- }
- callback(s);
- });
- });
-}
-
-void JournalImpl::GetParents(
- fit::function<void(Status,
- std::vector<std::unique_ptr<const storage::Commit>>)>
- callback) {
- auto waiter = fxl::MakeRefCounted<
- callback::Waiter<Status, std::unique_ptr<const storage::Commit>>>(
- Status::OK);
- page_storage_->GetCommit(base_, waiter->NewCallback());
- if (other_) {
- page_storage_->GetCommit(*other_, waiter->NewCallback());
- }
- waiter->Finalize(std::move(callback));
-}
-
-void JournalImpl::CreateCommitFromChanges(
- std::vector<std::unique_ptr<const storage::Commit>> parents,
- ObjectIdentifier root_identifier,
- std::unique_ptr<Iterator<const EntryChange>> changes,
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback) {
- btree::ApplyChanges(
- environment_->coroutine_service(), page_storage_,
- std::move(root_identifier), std::move(changes),
- [this, parents = std::move(parents), callback = std::move(callback)](
- Status status, ObjectIdentifier object_identifier,
- std::set<ObjectIdentifier> new_nodes) mutable {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- // If the commit is a no-op, return early.
- if (parents.size() == 1 &&
- parents.front()->GetRootIdentifier() == object_identifier) {
- // |new_nodes| can be ignored here. If a clear operation has been
- // executed and the state has then been restored to the one before the
- // transaction, |ApplyChanges| might have re-created some nodes that
- // already exist. Because they already exist in a pre-existing commit,
- // there is no need to update their state.
-
- // We are in an operation from the serializer: make sure not to sent
- // the rollback operation in the serializer as well, or a deadlock
- // will be created.
- RollbackInternal(
- [parent = std::move(parents.front()),
- callback = std::move(callback)](Status status) mutable {
- callback(status, std::move(parent));
- });
- return;
- }
- std::unique_ptr<const storage::Commit> commit =
- CommitImpl::FromContentAndParents(environment_->clock(),
- page_storage_, object_identifier,
- std::move(parents));
- GetObjectsToSync([this, new_nodes = std::move(new_nodes),
- commit = std::move(commit),
- callback = std::move(callback)](
- Status status, std::vector<ObjectIdentifier>
- objects_to_sync) mutable {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
-
- objects_to_sync.reserve(objects_to_sync.size() + new_nodes.size());
- // TODO(qsr): When using C++17, move data out of the set using
- // extract.
- objects_to_sync.insert(objects_to_sync.end(), new_nodes.begin(),
- new_nodes.end());
- page_storage_->AddCommitFromLocal(
- commit->Clone(), std::move(objects_to_sync),
- [this, commit = std::move(commit),
- callback = std::move(callback)](Status status) mutable {
- valid_ = false;
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- page_storage_->RemoveJournal(
- id_,
- [commit = std::move(commit),
- callback = std::move(callback)](Status status) mutable {
- if (status != Status::OK) {
- FXL_LOG(INFO)
- << "Commit created, but failed to delete journal.";
- }
- callback(Status::OK, std::move(commit));
- });
- });
- });
- });
-}
-
-void JournalImpl::GetObjectsToSync(
- fit::function<void(Status status,
- std::vector<ObjectIdentifier> objects_to_sync)>
- callback) {
- page_storage_->GetJournalEntries(
- id_, [this, callback = std::move(callback)](
- Status s, std::unique_ptr<Iterator<const EntryChange>> entries,
- JournalContainsClearOperation contains_clear_operation) mutable {
- if (s != Status::OK) {
- callback(s, {});
- return;
- }
- // Compute the key-value pairs added in this journal.
- std::map<std::string, ObjectIdentifier> key_values;
- while (entries->Valid()) {
- const Entry& entry = (*entries)->entry;
- if ((*entries)->deleted) {
- key_values.erase(entry.key);
- } else {
- key_values[entry.key] = entry.object_identifier;
- }
- entries->Next();
- }
- auto waiter =
- fxl::MakeRefCounted<callback::Waiter<Status, bool>>(Status::OK);
- for (const auto& key_value : key_values) {
- page_storage_->ObjectIsUntracked(key_value.second,
- waiter->NewCallback());
- }
- waiter->Finalize([key_values = std::move(key_values),
- callback = std::move(callback)](
- Status s, std::vector<bool> is_untracked) {
- if (s != Status::OK) {
- callback(s, {});
- return;
- }
- // Compute the set of values.
- std::set<ObjectIdentifier> result_set;
- size_t i = 0;
- for (const auto& key_value : key_values) {
- // Only untracked objects should be synced.
- if (is_untracked[i++]) {
- result_set.insert(key_value.second);
- }
- }
- std::vector<ObjectIdentifier> objects_to_sync;
- std::copy(result_set.begin(), result_set.end(),
- std::back_inserter(objects_to_sync));
- callback(Status::OK, std::move(objects_to_sync));
- });
- });
-}
-
-void JournalImpl::RollbackInternal(fit::function<void(Status)> callback) {
- if (!valid_) {
- callback(Status::ILLEGAL_STATE);
- return;
- }
- page_storage_->RemoveJournal(
- id_, [this, callback = std::move(callback)](Status s) {
- if (s == Status::OK) {
- valid_ = false;
- }
- callback(s);
- });
-}
-
-bool JournalImpl::StateAllowsMutation() {
- return valid_ && (type_ == JournalType::IMPLICIT || !failed_operation_);
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/journal_impl.h b/bin/ledger/storage/impl/journal_impl.h
deleted file mode 100644
index b00c49c..0000000
--- a/bin/ledger/storage/impl/journal_impl.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_JOURNAL_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_JOURNAL_IMPL_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-
-#include <lib/callback/operation_serializer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/impl/page_storage_impl.h"
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/journal.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// A |JournalImpl| represents a commit in progress.
-class JournalImpl : public Journal {
- private:
- // Passkey idiom to restrict access to the constructor to static factories.
- class Token;
-
- public:
- JournalImpl(Token token, JournalType type, ledger::Environment* environment,
- PageStorageImpl* page_storage, JournalId id, CommitId base);
- ~JournalImpl() override;
-
- // Creates a new Journal for a simple commit.
- static std::unique_ptr<Journal> Simple(JournalType type,
- ledger::Environment* environment,
- PageStorageImpl* page_storage,
- const JournalId& id,
- const CommitId& base);
-
- // Creates a new Journal for a merge commit.
- static std::unique_ptr<Journal> Merge(ledger::Environment* environment,
- PageStorageImpl* page_storage,
- const JournalId& id,
- const CommitId& base,
- const CommitId& other);
-
- // Commits the changes of this |Journal|. Trying to update entries or rollback
- // will fail after a successful commit. The callback will be called with the
- // returned status and the new commit. This Journal object should not be
- // deleted before |callback| is called.
- void Commit(
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback);
-
- // Rolls back all changes to this |Journal|. Trying to update entries or
- // commit will fail with an |ILLEGAL_STATE| after a successful rollback. This
- // Journal object should not be deleted before |callback| is called.
- void Rollback(fit::function<void(Status)> callback);
-
- // Journal:
- void Put(convert::ExtendedStringView key, ObjectIdentifier object_identifier,
- KeyPriority priority, fit::function<void(Status)> callback) override;
- void Delete(convert::ExtendedStringView key,
- fit::function<void(Status)> callback) override;
- void Clear(fit::function<void(Status)> callback) override;
- const JournalId& GetId() const override;
-
- private:
- class Token {
- private:
- Token() {}
- friend JournalImpl;
- };
-
- void GetParents(
- fit::function<void(Status,
- std::vector<std::unique_ptr<const storage::Commit>>)>
- callback);
-
- // Creates a new commit. The commit parents are |parents|. The content of the
- // commit is built by executing |changes| over the content pointed by
- // |root_identifier|.
- void CreateCommitFromChanges(
- std::vector<std::unique_ptr<const storage::Commit>> parents,
- ObjectIdentifier root_identifier,
- std::unique_ptr<Iterator<const EntryChange>> changes,
- fit::function<void(Status, std::unique_ptr<const storage::Commit>)>
- callback);
-
- void GetObjectsToSync(
- fit::function<void(Status status,
- std::vector<ObjectIdentifier> objects_to_sync)>
- callback);
-
- void RollbackInternal(fit::function<void(Status)> callback);
-
- // Returns whether the journal is in a state where it is legal to call |Put|,
- // |Delete| or |Clear|.
- bool StateAllowsMutation();
-
- const JournalType type_;
- ledger::Environment* const environment_;
- PageStorageImpl* const page_storage_;
- const JournalId id_;
- CommitId base_;
- std::unique_ptr<CommitId> other_;
- // A journal is no longer valid if either commit or rollback have been
- // executed.
- bool valid_;
- // |failed_operation_| is true if any of the Put or Delete methods in this
- // journal have failed. In this case, any operation on EXPLICIT journals
- // other than rolling back will fail. IMPLICIT journals can still be commited
- // even if some operations have failed.
- bool failed_operation_;
- // Serializes all update operations so that entries are inserted in the
- // journal in the order calls to put and delete were received.
- callback::OperationSerializer serializer_;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_JOURNAL_IMPL_H_
diff --git a/bin/ledger/storage/impl/ledger_storage_impl.cc b/bin/ledger/storage/impl/ledger_storage_impl.cc
deleted file mode 100644
index dca3246..0000000
--- a/bin/ledger/storage/impl/ledger_storage_impl.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/ledger_storage_impl.h"
-
-#include <string>
-
-#include <dirent.h>
-#include <algorithm>
-#include <iterator>
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/trace_callback.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/path.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/bin/ledger/filesystem/directory_reader.h"
-#include "peridot/bin/ledger/storage/impl/page_storage_impl.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/lib/base64url/base64url.h"
-
-namespace storage {
-
-namespace {
-
-constexpr fxl::StringView kStagingPathPrefix = "staging";
-
-// Encodes opaque bytes in a way that is usable as a directory name.
-std::string GetDirectoryName(fxl::StringView bytes) {
- return base64url::Base64UrlEncode(bytes);
-}
-
-// Decodes opaque bytes used as a directory names into an id. This is the
-// opposite transformation of GetDirectoryName.
-std::string GetId(fxl::StringView bytes) {
- std::string decoded;
- bool result = base64url::Base64UrlDecode(bytes, &decoded);
- FXL_DCHECK(result);
- return decoded;
-}
-
-} // namespace
-
-LedgerStorageImpl::LedgerStorageImpl(
- ledger::Environment* environment,
- encryption::EncryptionService* encryption_service, DbFactory* db_factory,
- ledger::DetachedPath content_dir)
- : environment_(environment),
- encryption_service_(encryption_service),
- db_factory_(db_factory),
- storage_dir_(std::move(content_dir)),
- weak_factory_(this) {}
-
-LedgerStorageImpl::~LedgerStorageImpl() {}
-
-Status LedgerStorageImpl::Init() {
- if (!files::CreateDirectoryAt(storage_dir_.root_fd(), storage_dir_.path())) {
- FXL_LOG(ERROR) << "Failed to create the storage directory in "
- << storage_dir_.path();
- return Status::INTERNAL_IO_ERROR;
- }
- return Status::OK;
-}
-
-void LedgerStorageImpl::CreatePageStorage(
- PageId page_id,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback) {
- auto timed_callback = TRACE_CALLBACK(std::move(callback), "ledger",
- "ledger_storage_create_page_storage");
- GetOrCreateDb(GetPathFor(page_id), std::move(page_id),
- DbFactory::OnDbNotFound::CREATE, std::move(timed_callback));
-}
-
-void LedgerStorageImpl::GetPageStorage(
- PageId page_id,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback) {
- auto timed_callback = TRACE_CALLBACK(std::move(callback), "ledger",
- "ledger_storage_get_page_storage");
- GetOrCreateDb(GetPathFor(page_id), std::move(page_id),
- DbFactory::OnDbNotFound::RETURN, std::move(timed_callback));
-}
-
-void LedgerStorageImpl::DeletePageStorage(
- PageIdView page_id, fit::function<void(Status)> callback) {
- ledger::DetachedPath path = GetPathFor(page_id);
- ledger::DetachedPath staging_path = GetStagingPathFor(page_id);
- // |final_callback| will be called from the I/O loop and call the original
- // |callback| in the main one. The main loop outlives the I/O one, so it's
- // safe to capture environment_->dispatcher() here.
- auto final_callback = [dispatcher = environment_->dispatcher(),
- callback =
- std::move(callback)](Status status) mutable {
- // Call the callback in the main thread.
- async::PostTask(dispatcher, [status, callback = std::move(callback)] {
- callback(status);
- });
- };
-
- async::PostTask(
- environment_->io_dispatcher(),
- [path = std::move(path), staging_path = std::move(staging_path),
- callback = std::move(final_callback)]() mutable {
- if (!files::IsDirectoryAt(path.root_fd(), path.path())) {
- callback(Status::NOT_FOUND);
- return;
- }
- files::ScopedTempDirAt tmp_directory(staging_path.root_fd(),
- staging_path.path());
- std::string destination = tmp_directory.path() + "/content";
-
- if (renameat(path.root_fd(), path.path().c_str(),
- tmp_directory.root_fd(), destination.c_str()) != 0) {
- FXL_LOG(ERROR) << "Unable to move local page storage to "
- << destination << ". Error: " << strerror(errno);
- callback(Status::IO_ERROR);
- return;
- }
-
- if (!files::DeletePathAt(tmp_directory.root_fd(), destination, true)) {
- FXL_LOG(ERROR) << "Unable to delete local staging storage at: "
- << destination;
- callback(Status::IO_ERROR);
- return;
- }
- callback(Status::OK);
- });
-}
-
-std::vector<PageId> LedgerStorageImpl::ListLocalPages() {
- std::vector<PageId> local_pages;
- ledger::GetDirectoryEntries(
- storage_dir_, [&local_pages](fxl::StringView encoded_page_id) {
- local_pages.emplace_back(GetId(encoded_page_id));
- return true;
- });
- return local_pages;
-}
-
-void LedgerStorageImpl::InitializePageStorage(
- PageId page_id, std::unique_ptr<Db> db,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback) {
- auto storage = std::make_unique<PageStorageImpl>(
- environment_, encryption_service_, std::move(db), std::move(page_id));
- PageStorageImpl* storage_ptr = storage.get();
- storage_ptr->Init([callback = std::move(callback),
- storage = std::move(storage)](Status status) mutable {
- if (status != Status::OK) {
- FXL_LOG(ERROR) << "Failed to initialize PageStorage. Status: " << status;
- callback(status, nullptr);
- return;
- }
- callback(Status::OK, std::move(storage));
- });
-}
-
-void LedgerStorageImpl::GetOrCreateDb(
- ledger::DetachedPath path, PageId page_id,
- DbFactory::OnDbNotFound on_db_not_found,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback) {
- db_factory_->GetOrCreateDb(
- std::move(path), on_db_not_found,
- callback::MakeScoped(
- weak_factory_.GetWeakPtr(),
- [this, page_id = std::move(page_id), callback = std::move(callback)](
- Status status, std::unique_ptr<Db> db) mutable {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
- InitializePageStorage(std::move(page_id), std::move(db),
- std::move(callback));
- }));
-}
-
-ledger::DetachedPath LedgerStorageImpl::GetPathFor(PageIdView page_id) {
- FXL_DCHECK(!page_id.empty());
- return storage_dir_.SubPath(GetDirectoryName(page_id));
-}
-
-ledger::DetachedPath LedgerStorageImpl::GetStagingPathFor(PageIdView page_id) {
- FXL_DCHECK(!page_id.empty());
- return storage_dir_.SubPath(
- fxl::Concatenate({kStagingPathPrefix, GetDirectoryName(page_id)}));
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/ledger_storage_impl.h b/bin/ledger/storage/impl/ledger_storage_impl.h
deleted file mode 100644
index b1f77aa..0000000
--- a/bin/ledger/storage/impl/ledger_storage_impl.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEDGER_STORAGE_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEDGER_STORAGE_IMPL_H_
-
-#include <lib/async/dispatcher.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/storage/public/db.h"
-#include "peridot/bin/ledger/storage/public/db_factory.h"
-#include "peridot/bin/ledger/storage/public/ledger_storage.h"
-
-namespace storage {
-
-class LedgerStorageImpl : public LedgerStorage {
- public:
- LedgerStorageImpl(ledger::Environment* environment,
- encryption::EncryptionService* encryption_service,
- storage::DbFactory* db_factory,
- ledger::DetachedPath content_dir);
- ~LedgerStorageImpl() override;
-
- // Initializes this LedgerStorageImpl by creating the |content_dir| directory
- // given in the constructor.
- Status Init();
-
- // LedgerStorage:
- void CreatePageStorage(
- PageId page_id,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback)
- override;
-
- void GetPageStorage(PageId page_id,
- fit::function<void(Status, std::unique_ptr<PageStorage>)>
- callback) override;
-
- void DeletePageStorage(PageIdView page_id,
- fit::function<void(Status)> callback) override;
-
- // For debugging only.
- std::vector<PageId> ListLocalPages();
-
- private:
- // Creates and returns through the callback, an initialized |PageStorageImpl|
- // object.
- void InitializePageStorage(
- PageId page_id, std::unique_ptr<Db> db,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback);
-
- // Gets or creates a new PageStorage at the given |path| for the page with the
- // given |page_id|.
- void GetOrCreateDb(
- ledger::DetachedPath path, PageId page_id,
- DbFactory::OnDbNotFound on_db_not_found,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback);
-
- ledger::DetachedPath GetPathFor(PageIdView page_id);
- ledger::DetachedPath GetDeprecatedPathFor(PageIdView page_id);
-
- // Returns the staging path for the given |page_id|.
- ledger::DetachedPath GetStagingPathFor(PageIdView page_id);
-
- ledger::Environment* const environment_;
- encryption::EncryptionService* const encryption_service_;
- storage::DbFactory* const db_factory_;
- ledger::DetachedPath storage_dir_;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<LedgerStorageImpl> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerStorageImpl);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEDGER_STORAGE_IMPL_H_
diff --git a/bin/ledger/storage/impl/ledger_storage_unittest.cc b/bin/ledger/storage/impl/ledger_storage_unittest.cc
deleted file mode 100644
index 59e2fa8..0000000
--- a/bin/ledger/storage/impl/ledger_storage_unittest.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/fake/fake_db_factory.h"
-#include "peridot/bin/ledger/storage/impl/ledger_storage_impl.h"
-#include "peridot/bin/ledger/storage/public/db_factory.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace storage {
-namespace {
-
-class LedgerStorageTest : public ledger::TestWithEnvironment {
- public:
- LedgerStorageTest()
- : encryption_service_(dispatcher()),
- db_factory_(dispatcher()),
- storage_(&environment_, &encryption_service_, &db_factory_,
- ledger::DetachedPath(tmpfs_.root_fd())) {}
-
- ~LedgerStorageTest() override {}
-
- // ledger::TestWithEnvironment:
- void SetUp() override {
- ledger::TestWithEnvironment::SetUp();
-
- ASSERT_EQ(Status::OK, storage_.Init());
- }
-
- private:
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- encryption::FakeEncryptionService encryption_service_;
-
- protected:
- fake::FakeDbFactory db_factory_;
- LedgerStorageImpl storage_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerStorageTest);
-};
-
-TEST_F(LedgerStorageTest, CreateGetCreatePageStorage) {
- PageId page_id = "1234";
- Status status;
- std::unique_ptr<PageStorage> page_storage;
- bool called;
- storage_.GetPageStorage(
- page_id, callback::Capture(callback::SetWhenCalled(&called), &status,
- &page_storage));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
- EXPECT_EQ(nullptr, page_storage);
-
- storage_.CreatePageStorage(
- page_id, callback::Capture(callback::SetWhenCalled(&called), &status,
- &page_storage));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(nullptr, page_storage);
- ASSERT_EQ(page_id, page_storage->GetId());
-
- page_storage.reset();
- storage_.GetPageStorage(
- page_id, callback::Capture(callback::SetWhenCalled(&called), &status,
- &page_storage));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, page_storage);
-}
-
-TEST_F(LedgerStorageTest, CreateDeletePageStorage) {
- PageId page_id = "1234";
- Status status;
- bool called;
- std::unique_ptr<PageStorage> page_storage;
- storage_.CreatePageStorage(
- page_id, callback::Capture(callback::SetWhenCalled(&called), &status,
- &page_storage));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- ASSERT_NE(nullptr, page_storage);
- ASSERT_EQ(page_id, page_storage->GetId());
- page_storage.reset();
-
- storage_.GetPageStorage(
- page_id, callback::Capture(callback::SetWhenCalled(&called), &status,
- &page_storage));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, page_storage);
-
- storage_.DeletePageStorage(
- page_id, callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- storage_.GetPageStorage(
- page_id, callback::Capture(callback::SetWhenCalled(&called), &status,
- &page_storage));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
- EXPECT_EQ(nullptr, page_storage);
-}
-
-TEST_F(LedgerStorageTest, DeletePageStorageNotFound) {
- PageId page_id = "1234";
- Status status;
- bool called;
-
- storage_.DeletePageStorage(
- page_id, callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/impl/leveldb.cc b/bin/ledger/storage/impl/leveldb.cc
deleted file mode 100644
index 95ae61d..0000000
--- a/bin/ledger/storage/impl/leveldb.cc
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/leveldb.h"
-
-#include <utility>
-
-#include <lib/async/cpp/task.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/path.h>
-#include <lib/fxl/logging.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/cobalt/cobalt.h"
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/impl/object_impl.h"
-#include "util/env_fuchsia.h"
-
-namespace storage {
-
-using coroutine::CoroutineHandler;
-
-namespace {
-
-Status MakeEmptySyncCallAndCheck(async_dispatcher_t* dispatcher,
- coroutine::CoroutineHandler* handler) {
- if (coroutine::SyncCall(handler, [&dispatcher](fit::closure on_done) {
- async::PostTask(dispatcher, std::move(on_done));
- }) == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return Status::OK;
-}
-
-Status ConvertStatus(leveldb::Status s) {
- if (s.IsNotFound()) {
- return Status::NOT_FOUND;
- }
- if (!s.ok()) {
- FXL_LOG(ERROR) << "LevelDB error: " << s.ToString();
- return Status::INTERNAL_IO_ERROR;
- }
- return Status::OK;
-}
-
-class BatchImpl : public Db::Batch {
- public:
- // Creates a new Batch based on a leveldb batch. Once |Execute| is called,
- // |callback| will be called with the same batch, ready to be written in
- // leveldb. If the destructor is called without a previous execution of the
- // batch, |callback| will be called with a |nullptr|.
- BatchImpl(
- async_dispatcher_t* dispatcher,
- std::unique_ptr<leveldb::WriteBatch> batch, leveldb::DB* db,
- fit::function<Status(std::unique_ptr<leveldb::WriteBatch>)> callback)
- : dispatcher_(dispatcher),
- batch_(std::move(batch)),
- db_(db),
- callback_(std::move(callback)) {}
-
- ~BatchImpl() override {
- if (batch_)
- callback_(nullptr);
- }
-
- Status Put(CoroutineHandler* handler, convert::ExtendedStringView key,
- fxl::StringView value) override {
- FXL_DCHECK(batch_);
- if (MakeEmptySyncCallAndCheck(dispatcher_, handler) ==
- Status::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- batch_->Put(key, convert::ToSlice(value));
- return Status::OK;
- }
-
- Status Delete(CoroutineHandler* handler,
- convert::ExtendedStringView key) override {
- FXL_DCHECK(batch_);
- batch_->Delete(key);
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
- }
-
- Status DeleteByPrefix(CoroutineHandler* handler,
- convert::ExtendedStringView prefix) override {
- FXL_DCHECK(batch_);
- std::unique_ptr<leveldb::Iterator> it(db_->NewIterator(read_options_));
- for (it->Seek(prefix); it->Valid() && it->key().starts_with(prefix);
- it->Next()) {
- batch_->Delete(it->key());
- }
- if (MakeEmptySyncCallAndCheck(dispatcher_, handler) ==
- Status::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return ConvertStatus(it->status());
- }
-
- Status Execute(CoroutineHandler* handler) override {
- FXL_DCHECK(batch_);
- if (MakeEmptySyncCallAndCheck(dispatcher_, handler) ==
- Status::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return callback_(std::move(batch_));
- }
-
- private:
- async_dispatcher_t* const dispatcher_;
- std::unique_ptr<leveldb::WriteBatch> batch_;
-
- const leveldb::ReadOptions read_options_;
- leveldb::DB* db_;
-
- fit::function<Status(std::unique_ptr<leveldb::WriteBatch>)> callback_;
-};
-
-class RowIterator
- : public Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>> {
- public:
- RowIterator(std::unique_ptr<leveldb::Iterator> it, std::string prefix)
- : it_(std::move(it)), prefix_(std::move(prefix)) {
- PrepareEntry();
- }
-
- ~RowIterator() override {}
-
- Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>&
- Next() override {
- it_->Next();
- PrepareEntry();
- return *this;
- }
-
- bool Valid() const final {
- return it_->Valid() && it_->key().starts_with(prefix_);
- }
-
- Status GetStatus() const override {
- return it_->status().ok() ? Status::OK : Status::INTERNAL_IO_ERROR;
- }
-
- const std::pair<convert::ExtendedStringView, convert::ExtendedStringView>&
- operator*() const override {
- return *(row_.get());
- }
-
- const std::pair<convert::ExtendedStringView, convert::ExtendedStringView>*
- operator->() const override {
- return row_.get();
- }
-
- private:
- void PrepareEntry() {
- if (!Valid()) {
- row_.reset(nullptr);
- return;
- }
- row_ = std::make_unique<
- std::pair<convert::ExtendedStringView, convert::ExtendedStringView>>(
- it_->key(), it_->value());
- }
-
- std::unique_ptr<leveldb::Iterator> it_;
- const std::string prefix_;
-
- std::unique_ptr<
- std::pair<convert::ExtendedStringView, convert::ExtendedStringView>>
- row_;
-};
-
-} // namespace
-
-LevelDb::LevelDb(async_dispatcher_t* dispatcher, ledger::DetachedPath db_path)
- : dispatcher_(dispatcher), db_path_(std::move(db_path)) {}
-
-LevelDb::~LevelDb() {
- FXL_DCHECK(!active_batches_count_)
- << "Not all LevelDb batches have been executed or rolled back.";
-}
-
-Status LevelDb::Init() {
- TRACE_DURATION("ledger", "leveldb_init");
- if (!files::CreateDirectoryAt(db_path_.root_fd(), db_path_.path())) {
- FXL_LOG(ERROR) << "Failed to create directory under " << db_path_.path();
- return Status::INTERNAL_IO_ERROR;
- }
- fxl::UniqueFD unique_fd;
- ledger::DetachedPath db_path = db_path_;
- if (db_path_.path() != ".") {
- // Open a UniqueFD at the db path.
- unique_fd = db_path_.OpenFD(&db_path);
- if (!unique_fd.is_valid()) {
- FXL_LOG(ERROR) << "Unable to open directory at " << db_path_.path()
- << ". errno: " << errno;
- return Status::INTERNAL_IO_ERROR;
- }
- }
- env_ = leveldb::MakeFuchsiaEnv(db_path.root_fd());
- leveldb::Options options;
- options.env = env_.get();
- options.create_if_missing = true;
- leveldb::DB* db = nullptr;
- leveldb::Status status = leveldb::DB::Open(options, db_path.path(), &db);
- if (status.IsCorruption()) {
- FXL_LOG(ERROR) << "Ledger state corrupted at " << db_path_.path()
- << " with leveldb status: " << status.ToString();
- FXL_LOG(WARNING) << "Trying to recover by erasing the local state.";
- FXL_LOG(WARNING)
- << "***** ALL LOCAL CHANGES IN THIS PAGE WILL BE LOST *****";
- ledger::ReportEvent(ledger::CobaltEvent::LEDGER_LEVELDB_STATE_CORRUPTED);
-
- if (!files::DeletePathAt(db_path_.root_fd(), db_path_.path(), true)) {
- FXL_LOG(ERROR) << "Failed to delete corrupted ledger at "
- << db_path_.path();
- return Status::INTERNAL_IO_ERROR;
- }
- leveldb::Status status = leveldb::DB::Open(options, db_path.path(), &db);
- if (!status.ok()) {
- FXL_LOG(ERROR) << "Failed to create a new LevelDB at " << db_path_.path()
- << " with leveldb status: " << status.ToString();
- return Status::INTERNAL_IO_ERROR;
- }
- } else if (!status.ok()) {
- FXL_LOG(ERROR) << "Failed to open ledger at " << db_path_.path()
- << " with leveldb status: " << status.ToString();
- return Status::INTERNAL_IO_ERROR;
- }
- db_.reset(db);
- return Status::OK;
-}
-
-Status LevelDb::StartBatch(CoroutineHandler* handler,
- std::unique_ptr<Db::Batch>* batch) {
- auto db_batch = std::make_unique<leveldb::WriteBatch>();
- active_batches_count_++;
- *batch = std::make_unique<BatchImpl>(
- dispatcher_, std::move(db_batch), db_.get(),
- [this](std::unique_ptr<leveldb::WriteBatch> db_batch) {
- active_batches_count_--;
- if (db_batch) {
- leveldb::Status status = db_->Write(write_options_, db_batch.get());
- if (!status.ok()) {
- FXL_LOG(ERROR) << "Failed to execute batch with status: "
- << status.ToString();
- return Status::INTERNAL_IO_ERROR;
- }
- }
- return Status::OK;
- });
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status LevelDb::Get(CoroutineHandler* handler, convert::ExtendedStringView key,
- std::string* value) {
- if (MakeEmptySyncCallAndCheck(dispatcher_, handler) == Status::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return ConvertStatus(db_->Get(read_options_, key, value));
-}
-
-Status LevelDb::HasKey(CoroutineHandler* handler,
- convert::ExtendedStringView key, bool* has_key) {
- std::unique_ptr<leveldb::Iterator> iterator(db_->NewIterator(read_options_));
- iterator->Seek(key);
-
- *has_key = iterator->Valid() && iterator->key() == key;
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status LevelDb::GetObject(CoroutineHandler* handler,
- convert::ExtendedStringView key,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) {
- std::unique_ptr<leveldb::Iterator> iterator(db_->NewIterator(read_options_));
- iterator->Seek(key);
-
- if (!iterator->Valid() || iterator->key() != key) {
- return Status::NOT_FOUND;
- }
-
- if (object) {
- *object = std::make_unique<LevelDBObject>(std::move(object_identifier),
- std::move(iterator));
- }
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status LevelDb::GetByPrefix(CoroutineHandler* handler,
- convert::ExtendedStringView prefix,
- std::vector<std::string>* key_suffixes) {
- std::vector<std::string> result;
- std::unique_ptr<leveldb::Iterator> it(db_->NewIterator(read_options_));
- for (it->Seek(prefix); it->Valid() && it->key().starts_with(prefix);
- it->Next()) {
- leveldb::Slice key = it->key();
- key.remove_prefix(prefix.size());
- result.push_back(key.ToString());
- }
- if (!it->status().ok()) {
- return ConvertStatus(it->status());
- }
- key_suffixes->swap(result);
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status LevelDb::GetEntriesByPrefix(
- CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::vector<std::pair<std::string, std::string>>* entries) {
- std::vector<std::pair<std::string, std::string>> result;
- std::unique_ptr<leveldb::Iterator> it(db_->NewIterator(read_options_));
- for (it->Seek(prefix); it->Valid() && it->key().starts_with(prefix);
- it->Next()) {
- leveldb::Slice key = it->key();
- key.remove_prefix(prefix.size());
- result.emplace_back(key.ToString(), it->value().ToString());
- }
- if (!it->status().ok()) {
- return ConvertStatus(it->status());
- }
- entries->swap(result);
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-Status LevelDb::GetIteratorAtPrefix(
- CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::unique_ptr<Iterator<const std::pair<
- convert::ExtendedStringView, convert::ExtendedStringView>>>* iterator) {
- std::unique_ptr<leveldb::Iterator> local_iterator(
- db_->NewIterator(read_options_));
- local_iterator->Seek(prefix);
-
- if (iterator) {
- std::unique_ptr<Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>>
- row_iterator = std::make_unique<RowIterator>(std::move(local_iterator),
- prefix.ToString());
- iterator->swap(row_iterator);
- }
- return MakeEmptySyncCallAndCheck(dispatcher_, handler);
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/leveldb.h b/bin/ledger/storage/impl/leveldb.h
deleted file mode 100644
index 4fe2283..0000000
--- a/bin/ledger/storage/impl/leveldb.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEVELDB_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEVELDB_H_
-
-#include <utility>
-
-#include <lib/async/dispatcher.h>
-
-#include "leveldb/db.h"
-#include "leveldb/write_batch.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/storage/public/db.h"
-
-namespace storage {
-
-class LevelDb : public Db {
- public:
- explicit LevelDb(async_dispatcher_t* dispatcher,
- ledger::DetachedPath db_path);
-
- ~LevelDb() override;
-
- Status Init();
-
- // Db:
- Status StartBatch(coroutine::CoroutineHandler* handler,
- std::unique_ptr<Batch>* batch) override;
- Status Get(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key, std::string* value) override;
- Status HasKey(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key, bool* has_key) override;
- Status GetObject(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) override;
- Status GetByPrefix(coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView prefix,
- std::vector<std::string>* key_suffixes) override;
- Status GetEntriesByPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::vector<std::pair<std::string, std::string>>* entries) override;
- Status GetIteratorAtPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::unique_ptr<Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>>*
- iterator) override;
-
- private:
- async_dispatcher_t* const dispatcher_;
- const ledger::DetachedPath db_path_;
- std::unique_ptr<leveldb::Env> env_;
- std::unique_ptr<leveldb::DB> db_;
-
- const leveldb::WriteOptions write_options_;
- const leveldb::ReadOptions read_options_;
-
- uint64_t active_batches_count_ = 0;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LevelDb);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEVELDB_H_
diff --git a/bin/ledger/storage/impl/leveldb_factory.cc b/bin/ledger/storage/impl/leveldb_factory.cc
deleted file mode 100644
index 4434077..0000000
--- a/bin/ledger/storage/impl/leveldb_factory.cc
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/leveldb_factory.h"
-
-#include <mutex>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/callback/trace_callback.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/memory/ref_counted.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/fxl/synchronization/thread_annotations.h>
-
-#include "peridot/lib/convert/convert.h"
-
-// LevelDbFactory tries to keep an empty, initialized instance of LevelDb always
-// available. It stores this cached instance under cached_db/.
-//
-// On requests for new LevelDb instances (see |GetOrCreateDb|), if the cached
-// instance is ready, it is moved to the requested destination and then a new
-// LevelDb is prepared to be cached. If the cached instance is not yet
-// available, the request is queued, and will be handled when the cached db is
-// ready.
-//
-// Note that if multiple requests are received while waiting for the LevelDb
-// initialization, only the first one is queued up. The rest directly request a
-// new LevelDb instance at the final destination.
-
-namespace storage {
-namespace {
-
-// TODO(LE-635): We need to clean the staging path, so that we don't leave
-// unreachable storage on disk.
-constexpr fxl::StringView kStagingPath = "staging";
-constexpr fxl::StringView kCachedDbPath = "cached_db";
-
-constexpr size_t kRandomBytesCount = 16;
-
-// Returns whether the parent directory of |path| exists. If it is not possible
-// to access the parent directory, returns whether the given |path| exists.
-bool ParentDirectoryExists(ledger::DetachedPath path) {
- size_t last_slash = path.path().find_last_of('/');
- return files::IsDirectoryAt(path.root_fd(),
- last_slash == std::string::npos
- ? path.path()
- : path.path().substr(0, last_slash));
-}
-
-} // namespace
-
-enum class LevelDbFactory::CreateInStagingPath : bool {
- NO,
- YES,
-};
-
-// Holds the LevelDb object together with the information on its initialization
-// state, allowing the coordination between the main and the I/O thread for
-// the creation of new LevelDb objects.
-struct LevelDbFactory::DbWithInitializationState
- : public fxl::RefCountedThreadSafe<
- LevelDbFactory::DbWithInitializationState> {
- public:
- // The mutex used to avoid concurrency issues during initialization.
- std::mutex mutex;
-
- // Whether the initialization has been cancelled. This information is known on
- // the main thread, which is the only one that should update this field if
- // needed. The I/O thread should read |cancelled| to know whether to proceed
- // with completing the requested initialization.
- bool cancelled FXL_GUARDED_BY(mutex) = false;
-
- // The LevelDb object itself should only be initialized while holding the
- // mutex, to prevent a race condition when cancelling from the main thread.
- std::unique_ptr<LevelDb> db FXL_GUARDED_BY(mutex) = nullptr;
-
- private:
- FRIEND_REF_COUNTED_THREAD_SAFE(DbWithInitializationState);
- FRIEND_MAKE_REF_COUNTED(DbWithInitializationState);
-
- DbWithInitializationState() {}
- ~DbWithInitializationState() {}
-};
-
-LevelDbFactory::LevelDbFactory(ledger::Environment* environment,
- ledger::DetachedPath cache_path)
- : environment_(environment),
- staging_path_(cache_path.SubPath(kStagingPath)),
- cached_db_path_(cache_path.SubPath(kCachedDbPath)),
- coroutine_manager_(environment->coroutine_service()),
- weak_factory_(this) {}
-
-void LevelDbFactory::Init() {
- // If there is already a LevelDb instance in the cache directory, initialize
- // that one, instead of creating a new one.
- CreateInStagingPath create_in_staging_path = static_cast<CreateInStagingPath>(
- !files::IsDirectoryAt(cached_db_path_.root_fd(), cached_db_path_.path()));
- PrepareCachedDb(create_in_staging_path);
-}
-
-void LevelDbFactory::GetOrCreateDb(
- ledger::DetachedPath db_path, DbFactory::OnDbNotFound on_db_not_found,
- fit::function<void(Status, std::unique_ptr<Db>)> callback) {
- if (files::IsDirectoryAt(db_path.root_fd(), db_path.path())) {
- // If the path exists, there is a LevelDb instance already there. Open and
- // return it.
- GetOrCreateDbAtPath(std::move(db_path), CreateInStagingPath::NO,
- std::move(callback));
- return;
- }
- if (on_db_not_found == DbFactory::OnDbNotFound::RETURN) {
- callback(Status::NOT_FOUND, nullptr);
- return;
- }
- // If creating the pre-cached db failed at some point it will likely fail
- // again. Don't retry caching anymore.
- if (cached_db_status_ == Status::OK) {
- if (cached_db_is_ready_) {
- // A cached instance is available. Use that one for the given callback.
- ReturnPrecachedDb(std::move(db_path), std::move(callback));
- return;
- }
- if (!pending_request_) {
- // The cached instance is not ready yet, and there are no other pending
- // requests. Store this one as pending until the cached db is ready.
- pending_request_path_ = std::move(db_path);
- pending_request_ = std::move(callback);
- return;
- }
- }
- // Either creation of a cached db has failed or a previous request is already
- // waiting for the cached instance. Request a new LevelDb at the final
- // destination.
- GetOrCreateDbAtPath(std::move(db_path), CreateInStagingPath::YES,
- std::move(callback));
-}
-
-void LevelDbFactory::GetOrCreateDbAtPath(
- ledger::DetachedPath db_path, CreateInStagingPath create_in_staging_path,
- fit::function<void(Status, std::unique_ptr<Db>)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, db_path = std::move(db_path), create_in_staging_path](
- coroutine::CoroutineHandler* handler,
- fit::function<void(Status, std::unique_ptr<Db>)> callback) {
- auto db_with_initialization_state =
- fxl::MakeRefCounted<DbWithInitializationState>();
- Status status;
- if (coroutine::SyncCall(
- handler,
- [&](fit::function<void(Status)> callback) {
- async::PostTask(
- environment_->io_dispatcher(),
- [this, db_path = std::move(db_path),
- create_in_staging_path, db_with_initialization_state,
- callback = std::move(callback)]() mutable {
- GetOrCreateDbAtPathOnIOThread(
- std::move(db_path), create_in_staging_path,
- std::move(db_with_initialization_state),
- std::move(callback));
- });
- },
- &status) == coroutine::ContinuationStatus::OK) {
- // The coroutine returned normally, the initialization was done
- // completely on the I/O thread, return normally.
- std::lock_guard<std::mutex> guard(
- db_with_initialization_state->mutex);
- callback(status, std::move(db_with_initialization_state->db));
- return;
- }
- // The coroutine is interrupted, but the initialization has been posted
- // on the I/O thread. The lock must be acquired and |cancelled| must be
- // set to |true|.
- //
- // There are 3 cases to consider:
- // 1. The lock is acquired before |GetOrCreateDbAtPathOnIOThread| is
- // called. |cancelled| will be set to |true| and when
- // |GetOrCreateDbAtPathOnIOThread| is executed, it will return early.
- // 2. The lock is acquired after |GetOrCreateDbAtPathOnIOThread| is
- // executed. |GetOrCreateDbAtPathOnIOThread| will not be called
- // again, and there is no concurrency issue anymore.
- // 3. The lock is tentatively acquired while
- // |GetOrCreateDbAtPathOnIOThread| is run. Because
- // |GetOrCreateDbAtPathOnIOThread| is guarded by the same mutex, this
- // will block until |GetOrCreateDbAtPathOnIOThread| is executed, and
- // the case is the same as 2.
-
- std::lock_guard<std::mutex> guard(db_with_initialization_state->mutex);
- db_with_initialization_state->cancelled = true;
- db_with_initialization_state->db.reset();
- callback(Status::INTERRUPTED, nullptr);
- });
-}
-
-void LevelDbFactory::GetOrCreateDbAtPathOnIOThread(
- ledger::DetachedPath db_path, CreateInStagingPath create_in_staging_path,
- fxl::RefPtr<DbWithInitializationState> db_with_initialization_state,
- fit::function<void(Status)> callback) {
- std::lock_guard<std::mutex> guard(db_with_initialization_state->mutex);
- if (db_with_initialization_state->cancelled) {
- return;
- }
- Status status;
- if (create_in_staging_path == CreateInStagingPath::YES) {
- status = CreateDbThroughStagingPathOnIOThread(
- std::move(db_path), &db_with_initialization_state->db);
- } else {
- FXL_DCHECK(files::IsDirectoryAt(db_path.root_fd(), db_path.path()));
- db_with_initialization_state->db = std::make_unique<LevelDb>(
- environment_->dispatcher(), std::move(db_path));
- status = db_with_initialization_state->db->Init();
- }
- if (status != Status::OK) {
- // Don't return the created db instance if initialization failed.
- db_with_initialization_state->db.reset();
- }
- async::PostTask(
- environment_->dispatcher(),
- [status, callback = std::move(callback)]() mutable { callback(status); });
-}
-
-Status LevelDbFactory::CreateDbThroughStagingPathOnIOThread(
- ledger::DetachedPath db_path, std::unique_ptr<LevelDb>* db) {
- char name[kRandomBytesCount];
- environment_->random()->Draw(name, kRandomBytesCount);
- ledger::DetachedPath tmp_destination = staging_path_.SubPath(
- convert::ToHex(fxl::StringView(name, kRandomBytesCount)));
- // Create a LevelDb instance in a temporary path.
- auto result =
- std::make_unique<LevelDb>(environment_->dispatcher(), tmp_destination);
- Status status = result->Init();
- if (status != Status::OK) {
- return status;
- }
- // If the parent directory doesn't exist, renameat will fail.
- // Note that |cached_db_path_| will also be created throught the staging path
- // and thus, this code path will be reached. Its parent directory is lazily
- // created when result->Init() (see code above) is called:
- // - |staging_path_| and |cached_db_path_| share the same parent (the
- // |cache_path| given on the constructor), and
- // - in LevelDb initialization, the directories up to the db path are created.
- FXL_DCHECK(ParentDirectoryExists(db_path))
- << "Parent directory does not exit for path: " << db_path.path();
- // Move it to the final destination.
- if (renameat(tmp_destination.root_fd(), tmp_destination.path().c_str(),
- db_path.root_fd(), db_path.path().c_str()) != 0) {
- FXL_LOG(ERROR) << "Unable to move LevelDb from staging path to final "
- "destination: "
- << db_path.path() << ". Error: " << strerror(errno);
- return Status::IO_ERROR;
- }
- *db = std::move(result);
- return Status::OK;
-}
-
-void LevelDbFactory::PrepareCachedDb(
- CreateInStagingPath create_in_staging_path) {
- TRACE_ASYNC_BEGIN("ledger", "prepare_cached_db", 0);
- FXL_DCHECK(!cached_db_is_ready_);
- FXL_DCHECK(cached_db_ == nullptr);
- GetOrCreateDbAtPath(
- cached_db_path_, create_in_staging_path,
- callback::MakeScoped(weak_factory_.GetWeakPtr(),
- [this](Status status, std::unique_ptr<Db> db) {
- TRACE_ASYNC_END("ledger", "prepare_cached_db", 0);
- cached_db_status_ = status;
- cached_db_ = std::move(db);
- cached_db_is_ready_ = true;
- if (pending_request_) {
- auto path = std::move(pending_request_path_);
- auto callback = std::move(pending_request_);
- pending_request_ = nullptr;
- ReturnPrecachedDb(std::move(path),
- std::move(callback));
- }
- }));
-}
-
-void LevelDbFactory::ReturnPrecachedDb(
- ledger::DetachedPath db_path,
- fit::function<void(Status, std::unique_ptr<Db>)> callback) {
- FXL_DCHECK(cached_db_is_ready_);
-
- if (cached_db_status_ != Status::OK) {
- // If we failed to create a cached db instance, any future attempts will
- // likely fail as well: just return the status and don't update
- // |cached_db_is_ready_| or call |PrepareCachedDb|.
- callback(cached_db_status_, nullptr);
- return;
- }
- // Move the cached db to the final destination.
- if (renameat(cached_db_path_.root_fd(), cached_db_path_.path().c_str(),
- db_path.root_fd(), db_path.path().c_str()) != 0) {
- FXL_LOG(ERROR) << "Unable to move LevelDb from: " << cached_db_path_.path()
- << " to final destination: " << db_path.path()
- << ". Error: " << strerror(errno);
- // Moving to the final destination failed, but the cached db was created
- // succesfully: no need to update |cached_db_is_ready_|, |cached_db_status_|
- // or |cached_db_|.
- callback(Status::IO_ERROR, nullptr);
- return;
- }
-
- // We know the |cached_db_status_| is |OK| and the db is already in the final
- // destination. Asynchronously start preparing the next cached db and then
- // call the callback.
- auto cached_db = std::move(cached_db_);
- cached_db_is_ready_ = false;
- PrepareCachedDb(CreateInStagingPath::YES);
- callback(Status::OK, std::move(cached_db));
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/leveldb_factory.h b/bin/ledger/storage/impl/leveldb_factory.h
deleted file mode 100644
index 43aae40..0000000
--- a/bin/ledger/storage/impl/leveldb_factory.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEVELDB_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEVELDB_FACTORY_H_
-
-#include "peridot/bin/ledger/storage/public/db_factory.h"
-
-#include <memory>
-
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine_manager.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/storage/impl/leveldb.h"
-
-namespace storage {
-
-// A factory for LevelDb instances.
-//
-// This factory tries to always keep a new empty instance of LevelDb,
-// initialized and pre-cached, in order to immediately respond to requests for
-// new Db instances.
-//
-// When creating new LevelDb instances, using |GetOrCreateDb|, the caller should
-// make sure that there is no live LevelDb instance for the same path.
-class LevelDbFactory : public DbFactory {
- public:
- LevelDbFactory(ledger::Environment* environment,
- ledger::DetachedPath cache_path);
-
- // Initializes the LevelDbFactory by preparing the cached instance of LevelDb.
- void Init();
-
- // DbFactory:
- void GetOrCreateDb(
- ledger::DetachedPath db_path, DbFactory::OnDbNotFound on_db_not_found,
- fit::function<void(Status, std::unique_ptr<Db>)> callback) override;
-
- private:
- struct DbWithInitializationState;
- enum class CreateInStagingPath : bool;
-
- // Gets or creates a new LevelDb instance in the given |db_path|,
- // initializes it in the I/O thread and then returns it through the
- // |callback|.
- void GetOrCreateDbAtPath(
- ledger::DetachedPath db_path, CreateInStagingPath create_in_staging_path,
- fit::function<void(Status, std::unique_ptr<Db>)> callback);
-
- // Gets or creates a new LevelDb instance. This method should be
- // called from the I/O thread. When initialization is complete, it makes sure
- // to update the |db_with_initialization_state| with the created LevelDb
- // instance, and then call the |callback| from the main thread.
- void GetOrCreateDbAtPathOnIOThread(
- ledger::DetachedPath db_path, CreateInStagingPath create_in_staging_path,
- fxl::RefPtr<DbWithInitializationState> db_with_initialization_state,
- fit::function<void(Status)> callback);
-
- // Synchronously creates and initializes a new LevelDb instance in a two-step
- // process: the new instance is created in a temporary directory under the
- // staging path and, if successful, it is then moved to the given |db_path|.
- // This way, if initialization is interrupted, the potentially corrupted
- // database will be in the staging area.
- Status CreateDbThroughStagingPathOnIOThread(ledger::DetachedPath db_path,
- std::unique_ptr<LevelDb>* db);
-
- // Asynchronously creates and initializes a new LevelDb instance. Once done,
- // if there is a pending request, it responds to it.
- void PrepareCachedDb(CreateInStagingPath create_in_staging_path);
-
- // Uses the cached LevelDb instance to respond to the given request and
- // initializes a new LevelDb for the cache directory.
- void ReturnPrecachedDb(
- ledger::DetachedPath db_path,
- fit::function<void(Status, std::unique_ptr<Db>)> callback);
-
- // If the cached LevelDb instance is available, |cached_db_is_ready_| is set
- // to |true| and |cached_db_status_| and |cached_db_| are updated to hold the
- // returned values from the LevelDb creation.
- // If at any point there is failure in initializing cached db, i.e. when
- // |cached_db_status_| is not |OK|, LevelDbFactory stops trying to pre-cache
- // instances, and only tries to create them at the final destination.
- bool cached_db_is_ready_ = false;
- Status cached_db_status_ = Status::OK;
- std::unique_ptr<Db> cached_db_;
-
- // If a request is received before the cached db is ready, it is queued up, by
- // storing the requester's callback (|pending_request_|) and the path of the
- // final destination (|pending_request_path_|).
- fit::function<void(Status, std::unique_ptr<Db>)> pending_request_;
- ledger::DetachedPath pending_request_path_;
-
- ledger::Environment* environment_;
- // The path where new LevelDb instances are created, before they are moved to
- // their final destination, or the cached db path.
- const ledger::DetachedPath staging_path_;
- // The path that keeps the initialized cached instance of LevelDb.
- const ledger::DetachedPath cached_db_path_;
- coroutine::CoroutineManager coroutine_manager_;
-
- // This must be the last member of the class.
- fxl::WeakPtrFactory<LevelDbFactory> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LevelDbFactory);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_LEVELDB_FACTORY_H_
diff --git a/bin/ledger/storage/impl/leveldb_factory_unittest.cc b/bin/ledger/storage/impl/leveldb_factory_unittest.cc
deleted file mode 100644
index e93ec77..0000000
--- a/bin/ledger/storage/impl/leveldb_factory_unittest.cc
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/path.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/storage/impl/leveldb_factory.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace storage {
-namespace {
-
-class LevelDbFactoryTest : public ledger::TestWithEnvironment {
- public:
- LevelDbFactoryTest()
- : base_path_(tmpfs_.root_fd()),
- cache_path_(base_path_.SubPath("cache")),
- db_path_(base_path_.SubPath("databases")),
- db_factory_(&environment_, cache_path_) {}
-
- ~LevelDbFactoryTest() override {}
-
- // ledger::TestWithEnvironment:
- void SetUp() override {
- ledger::TestWithEnvironment::SetUp();
-
- ASSERT_TRUE(
- files::CreateDirectoryAt(cache_path_.root_fd(), cache_path_.path()));
- ASSERT_TRUE(files::CreateDirectoryAt(db_path_.root_fd(), db_path_.path()));
-
- db_factory_.Init();
- RunLoopUntilIdle();
- }
-
- private:
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- ledger::DetachedPath base_path_;
-
- protected:
- ledger::DetachedPath cache_path_;
- ledger::DetachedPath db_path_;
- LevelDbFactory db_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LevelDbFactoryTest);
-};
-
-TEST_F(LevelDbFactoryTest, GetOrCreateDb) {
- // Create a new instance.
- Status status;
- std::unique_ptr<Db> db;
- bool called;
- db_factory_.GetOrCreateDb(
- db_path_.SubPath("db"), DbFactory::OnDbNotFound::CREATE,
- callback::Capture(callback::SetWhenCalled(&called), &status, &db));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, db);
- // Write one key-value pair.
- RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
- std::unique_ptr<Db::Batch> batch;
- EXPECT_EQ(Status::OK, db->StartBatch(handler, &batch));
- EXPECT_EQ(Status::OK, batch->Put(handler, "key", "value"));
- EXPECT_EQ(Status::OK, batch->Execute(handler));
- });
-
- // Close the previous instance and open it again.
- db.reset();
- db_factory_.GetOrCreateDb(
- db_path_.SubPath("db"), DbFactory::OnDbNotFound::RETURN,
- callback::Capture(callback::SetWhenCalled(&called), &status, &db));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, db);
- // Expect to find the previously written key-value pair.
- RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
- std::string value;
- EXPECT_EQ(Status::OK, db->Get(handler, "key", &value));
- EXPECT_EQ("value", value);
- });
-}
-
-TEST_F(LevelDbFactoryTest, GetDbOnNotFound) {
- // Try to get a non existing Db and expect a |NOT_FOUND| status.
- Status status;
- std::unique_ptr<Db> db;
- bool called;
- db_factory_.GetOrCreateDb(
- db_path_.SubPath("db"), DbFactory::OnDbNotFound::RETURN,
- callback::Capture(callback::SetWhenCalled(&called), &status, &db));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
- EXPECT_EQ(nullptr, db);
-}
-
-TEST_F(LevelDbFactoryTest, CreateMultipleDbs) {
- int N = 5;
- Status status;
- std::unique_ptr<Db> db;
- bool called;
-
- // Create N LevelDb instances, one after the other. All of them will use the
- // existing cached instance and then, initialize the creation of a new one.
- for (int i = 0; i < N; ++i) {
- ledger::DetachedPath path = db_path_.SubPath(fxl::NumberToString(i));
- EXPECT_FALSE(files::IsDirectoryAt(path.root_fd(), path.path()));
-
- db_factory_.GetOrCreateDb(
- path, DbFactory::OnDbNotFound::CREATE,
- callback::Capture(callback::SetWhenCalled(&called), &status, &db));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, db);
- // Check that the directory was created.
- EXPECT_TRUE(files::IsDirectoryAt(path.root_fd(), path.path()));
- }
-}
-
-TEST_F(LevelDbFactoryTest, CreateMultipleDbsConcurrently) {
- int N = 5;
- Status statuses[N];
- std::unique_ptr<Db> dbs[N];
- bool called[N];
-
- // Create N LevelDb instances concurrently. The first one will use the cached
- // instance, the 2nd one will be queued up to get the cached one when it's
- // initialized, and all the others will be created directly at the destination
- // directory.
- for (int i = 0; i < N; ++i) {
- ledger::DetachedPath path = db_path_.SubPath(fxl::NumberToString(i));
- EXPECT_FALSE(files::IsDirectoryAt(path.root_fd(), path.path()));
-
- db_factory_.GetOrCreateDb(
- db_path_.SubPath(fxl::NumberToString(i)),
- DbFactory::OnDbNotFound::CREATE,
- callback::Capture(callback::SetWhenCalled(&called[i]), &statuses[i],
- &dbs[i]));
- }
- RunLoopUntilIdle();
-
- for (int i = 0; i < N; ++i) {
- ledger::DetachedPath path = db_path_.SubPath(fxl::NumberToString(i));
- EXPECT_TRUE(called[i]);
- EXPECT_EQ(Status::OK, statuses[i]);
- EXPECT_NE(nullptr, dbs[i]);
- // Check that the directory was created.
- EXPECT_TRUE(files::IsDirectoryAt(path.root_fd(), path.path()));
- }
-}
-
-TEST_F(LevelDbFactoryTest, GetOrCreateDbInCallback) {
- bool called1;
- ledger::DetachedPath path1 = db_path_.SubPath("1");
-
- bool called2;
- ledger::DetachedPath path2 = db_path_.SubPath("2");
- Status status2;
- std::unique_ptr<Db> db2;
-
- db_factory_.GetOrCreateDb(
- path1, DbFactory::OnDbNotFound::CREATE,
- [&](Status status1, std::unique_ptr<Db> db1) {
- called1 = true;
- EXPECT_EQ(Status::OK, status1);
- EXPECT_NE(nullptr, db1);
- db_factory_.GetOrCreateDb(
- path2, DbFactory::OnDbNotFound::CREATE,
- callback::Capture(callback::SetWhenCalled(&called2), &status2,
- &db2));
- });
- RunLoopUntilIdle();
- EXPECT_TRUE(called1);
- EXPECT_TRUE(called2);
- EXPECT_EQ(Status::OK, status2);
- EXPECT_NE(nullptr, db2);
-
- // Check that the directories were created.
- EXPECT_TRUE(files::IsDirectoryAt(path1.root_fd(), path1.path()));
- EXPECT_TRUE(files::IsDirectoryAt(path2.root_fd(), path2.path()));
-}
-
-TEST_F(LevelDbFactoryTest, InitWithCachedDbAvailable) {
- // When an empty LevelDb instance is already cached from a previous
- // LevelDbFactory execution, don't create a new instance, but use the existing
- // one directly.
- scoped_tmpfs::ScopedTmpFS tmpfs;
- ledger::DetachedPath cache_path(tmpfs.root_fd(), "cache");
- // Must be the same as |kCachedDbPath| in leveldb_factory.cc.
- ledger::DetachedPath cached_db_path = cache_path.SubPath("cached_db");
-
- auto db_factory = std::make_unique<LevelDbFactory>(&environment_, cache_path);
-
- // The cached db directory should not be created, yet.
- EXPECT_FALSE(
- files::IsDirectoryAt(cached_db_path.root_fd(), cached_db_path.path()));
-
- // Initialize and wait for the cached instance to be created.
- db_factory->Init();
- RunLoopUntilIdle();
-
- // Close the factory. This will not affect the created cached instance, which
- // was created under |cached_db_path|.
- db_factory.reset();
- EXPECT_TRUE(
- files::IsDirectoryAt(cached_db_path.root_fd(), cached_db_path.path()));
-
- // Reset and re-initialize the factory object. It should now use the
- // previously created instance.
- db_factory = std::make_unique<LevelDbFactory>(&environment_, cache_path);
- db_factory->Init();
- RunLoopUntilIdle();
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/impl/object_digest.cc b/bin/ledger/storage/impl/object_digest.cc
deleted file mode 100644
index fe0e65b..0000000
--- a/bin/ledger/storage/impl/object_digest.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <bitset>
-
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/impl/constants.h"
-
-namespace storage {
-
-namespace {
-
-static_assert(kStorageHashSize == encryption::kHashSize,
- "Unexpected kStorageHashSize value");
-
-// The first bit is 1 for inlined values and 0 otherwise.
-constexpr size_t kInlineBit = 0;
-
-// The second bit is 0 for CHUNK and 1 for INDEX.
-constexpr size_t kTypeBit = 1;
-
-// The third bit is 1 for a tree node and 0 otherwise.
-constexpr char kTreeNodeBit = 2;
-
-// Builds an object digest by concatenating |prefix| and |data|.
-ObjectDigest BuildDigest(std::bitset<8> prefix,
- convert::ExtendedStringView data) {
- std::string result;
- result.reserve(data.size() + 1);
- result.push_back(prefix.to_ulong());
- result.append(data.data(), data.size());
- return ObjectDigest(std::move(result));
-}
-
-} // namespace
-
-bool IsDigestValid(convert::ExtendedStringView object_digest) {
- // All object digests should have a prefix.
- if (object_digest.size() == 0) {
- FXL_LOG(INFO) << "Invalid object digest: empty.";
- return false;
- }
- std::bitset<8> prefix(object_digest[0]);
- // Check inline bit.
- if (prefix[kInlineBit] && object_digest.size() > kStorageHashSize + 1) {
- FXL_LOG(INFO) << "Invalid object digest: inline but size="
- << object_digest.size()
- << "; digest=" << convert::ToHex(object_digest);
- return false;
- }
- if (!prefix[kInlineBit] && object_digest.size() != kStorageHashSize + 1) {
- FXL_LOG(INFO) << "Invalid object digest: not inline but size="
- << object_digest.size()
- << "; digest=" << convert::ToHex(object_digest);
- return false;
- }
- // All bits must be zero except the ones we use for ObjectDigestInfo.
- prefix.reset(kInlineBit);
- prefix.reset(kTypeBit);
- prefix.reset(kTreeNodeBit);
- return prefix.none();
-}
-
-bool IsDigestValid(const ObjectDigest& object_digest) {
- return object_digest.IsValid() && IsDigestValid(object_digest.Serialize());
-}
-
-ObjectDigestInfo GetObjectDigestInfo(const ObjectDigest& object_digest) {
- FXL_DCHECK(IsDigestValid(object_digest));
-
- const std::string& digest = object_digest.Serialize();
- std::bitset<8> prefix(digest[0]);
- ObjectDigestInfo result;
- result.object_type =
- prefix[kTreeNodeBit] ? ObjectType::TREE_NODE : ObjectType::BLOB;
- result.piece_type = prefix[kTypeBit] ? PieceType::INDEX : PieceType::CHUNK;
- result.inlined = prefix[kInlineBit] ? InlinedPiece::YES : InlinedPiece::NO;
- return result;
-}
-
-fxl::StringView ExtractObjectDigestData(const ObjectDigest& object_digest) {
- FXL_DCHECK(IsDigestValid(object_digest));
-
- fxl::StringView digest = object_digest.Serialize();
- return digest.substr(1);
-}
-
-ObjectDigest ComputeObjectDigest(PieceType piece_type, ObjectType object_type,
- convert::ExtendedStringView content) {
- std::bitset<8> prefix;
- prefix[kTypeBit] = piece_type == PieceType::INDEX;
- prefix[kTreeNodeBit] = object_type == ObjectType::TREE_NODE;
- if (content.size() <= kStorageHashSize) {
- prefix[kInlineBit] = true;
- return BuildDigest(prefix, content);
- }
- return BuildDigest(prefix, encryption::SHA256WithLengthHash(content));
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/object_digest.h b/bin/ledger/storage/impl/object_digest.h
deleted file mode 100644
index fd63d21..0000000
--- a/bin/ledger/storage/impl/object_digest.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_DIGEST_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_DIGEST_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace storage {
-
-// The two types of pieces. When an object is split into multiple pieces, it
-// produces a tree made of:
-// - chunks, at the leaves, that hold the actual values to be concatenated to
-// reconstruct the object,
-// - indices, that reference other pieces.
-// Note that an object that is small enough might not need to be split into
-// multiple pieces (see split.h for the splitting algorithm). In that case, the
-// tree of pieces degenerates to the simple case of single chunk encoding the
-// whole object.
-enum class PieceType {
- CHUNK,
- INDEX,
-};
-
-// Whether the piece is stored inline. Inlined pieces are small-enough pieces
-// that are embedded directly in the |ObjectDigest| representing them. If a
-// piece is not inlined, it is stored as a separate blob object, and is
-// referenced by the |ObjectDigest|, which is a hash of its content.
-enum class InlinedPiece { NO, YES };
-
-// Details about the piece represented by an |ObjectDigest|.
-// This information is encoded in the first byte of the digest.
-struct ObjectDigestInfo {
- // The type of the object encoded by the piece. |object_type| is |TREE_NODE|,
- // if this piece refers to a tree node object that was not split into pieces,
- // or if it refers to the root-index of a chunked tree node object; |BLOB|
- // otherwise.
- // Consequently, there is no way to distinguish between a piece encoding a
- // blob object, and an internal piece of a split tree node; deduplication even
- // means that a single piece may represent both depending on context.
- ObjectType object_type;
-
- // The type of the piece.
- PieceType piece_type;
-
- // Whether the piece is stored inline.
- InlinedPiece inlined;
-
- bool is_inlined() { return inlined == InlinedPiece::YES; }
- bool is_chunk() { return piece_type == PieceType::CHUNK; }
-};
-
-// Returns whether the given digest is valid.
-bool IsDigestValid(convert::ExtendedStringView object_digest);
-
-// Returns whether the given digest is valid.
-bool IsDigestValid(const ObjectDigest& object_digest);
-
-// Returns the type of |object_digest|.
-ObjectDigestInfo GetObjectDigestInfo(const ObjectDigest& object_digest);
-
-// Extracts the data from |object_digest|. If |object_digest| type is |INLINE|,
-// the returned data is the content of the object, otherwise, it is the hash of
-// the object. The returned view is valid for as long as |object digest|.
-fxl::StringView ExtractObjectDigestData(const ObjectDigest& object_digest);
-
-// Computes the id of a piece with the given |piece_type|, |object_type| and
-// |content|. The inlined bit of ObjectDigestInfo does not need to be provided
-// because it is derived from |content|'s length.
-ObjectDigest ComputeObjectDigest(PieceType piece_type, ObjectType object_type,
- convert::ExtendedStringView content);
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_DIGEST_H_
diff --git a/bin/ledger/storage/impl/object_digest_unittest.cc b/bin/ledger/storage/impl/object_digest_unittest.cc
deleted file mode 100644
index acc6908..0000000
--- a/bin/ledger/storage/impl/object_digest_unittest.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-
-namespace storage {
-namespace {
-
-fxl::StringView operator"" _s(const char* str, size_t size) {
- return fxl::StringView(str, size);
-}
-
-// Test for object ids smaller than the inlining threshold.
-using ObjectDigestSmallTest = ::testing::TestWithParam<fxl::StringView>;
-
-TEST_P(ObjectDigestSmallTest, Index) {
- ObjectDigest object_digest =
- ComputeObjectDigest(PieceType::INDEX, ObjectType::BLOB, GetParam());
- ASSERT_TRUE(IsDigestValid(object_digest));
- ObjectDigestInfo info = GetObjectDigestInfo(object_digest);
- EXPECT_EQ(PieceType::INDEX, info.piece_type);
- EXPECT_EQ(ObjectType::BLOB, info.object_type);
- EXPECT_EQ(InlinedPiece::YES, info.inlined);
- EXPECT_EQ(GetParam(), ExtractObjectDigestData(object_digest));
-}
-
-TEST_P(ObjectDigestSmallTest, Value) {
- ObjectDigest object_digest =
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::TREE_NODE, GetParam());
- ASSERT_TRUE(IsDigestValid(object_digest));
- ObjectDigestInfo info = GetObjectDigestInfo(object_digest);
- EXPECT_EQ(PieceType::CHUNK, info.piece_type);
- EXPECT_EQ(InlinedPiece::YES, info.inlined);
- EXPECT_EQ(ObjectType::TREE_NODE, info.object_type);
- EXPECT_EQ(GetParam(), ExtractObjectDigestData(object_digest));
-}
-
-INSTANTIATE_TEST_CASE_P(ObjectDigestTest, ObjectDigestSmallTest,
- ::testing::Values("", "hello", "world\0withzero"_s,
- "01234567890123456789012345678901"));
-
-// Test for object ids bigger than the inlining threshold.
-using ObjectDigestBigTest = ::testing::TestWithParam<fxl::StringView>;
-
-TEST_P(ObjectDigestBigTest, Index) {
- ObjectDigest object_digest =
- ComputeObjectDigest(PieceType::INDEX, ObjectType::TREE_NODE, GetParam());
- ASSERT_TRUE(IsDigestValid(object_digest));
- ObjectDigestInfo info = GetObjectDigestInfo(object_digest);
- EXPECT_EQ(PieceType::INDEX, info.piece_type);
- EXPECT_EQ(ObjectType::TREE_NODE, info.object_type);
- EXPECT_EQ(InlinedPiece::NO, info.inlined);
- EXPECT_EQ(encryption::SHA256WithLengthHash(GetParam()),
- ExtractObjectDigestData(object_digest));
-}
-
-TEST_P(ObjectDigestBigTest, Value) {
- ObjectDigest object_digest =
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, GetParam());
- ASSERT_TRUE(IsDigestValid(object_digest));
- ObjectDigestInfo info = GetObjectDigestInfo(object_digest);
- EXPECT_EQ(PieceType::CHUNK, info.piece_type);
- EXPECT_EQ(ObjectType::BLOB, info.object_type);
- EXPECT_EQ(InlinedPiece::NO, info.inlined);
- EXPECT_EQ(encryption::SHA256WithLengthHash(GetParam()),
- ExtractObjectDigestData(object_digest));
-}
-
-INSTANTIATE_TEST_CASE_P(ObjectDigestTest, ObjectDigestBigTest,
- ::testing::Values("012345678901234567890123456789012",
- "012345678900123456789001234567890012"
- "345678900123456789001234567890012345"
- "67890"));
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/impl/object_identifier.fbs b/bin/ledger/storage/impl/object_identifier.fbs
deleted file mode 100644
index 762cc8f..0000000
--- a/bin/ledger/storage/impl/object_identifier.fbs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-namespace storage;
-
-// The identifier of an object. This contains the digest of the object, as well
-// as the information needed to hide its name and encrypt its content.
-table ObjectIdentifierStorage {
- key_index: uint;
- deletion_scope_id: uint;
- object_digest: [ubyte];
-}
-
-root_type ObjectIdentifierStorage;
diff --git a/bin/ledger/storage/impl/object_identifier_encoding.cc b/bin/ledger/storage/impl/object_identifier_encoding.cc
deleted file mode 100644
index 623f0e7..0000000
--- a/bin/ledger/storage/impl/object_identifier_encoding.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-
-#include <limits>
-
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-
-namespace storage {
-ObjectIdentifier ToObjectIdentifier(
- const ObjectIdentifierStorage* object_identifier_storage) {
- return {object_identifier_storage->key_index(),
- object_identifier_storage->deletion_scope_id(),
- ObjectDigest(object_identifier_storage->object_digest())};
-}
-
-flatbuffers::Offset<ObjectIdentifierStorage> ToObjectIdentifierStorage(
- flatbuffers::FlatBufferBuilder* builder,
- const ObjectIdentifier& object_identifier) {
- return CreateObjectIdentifierStorage(
- *builder, object_identifier.key_index(),
- object_identifier.deletion_scope_id(),
- convert::ToFlatBufferVector(
- builder, object_identifier.object_digest().Serialize()));
-}
-
-std::string EncodeObjectIdentifier(const ObjectIdentifier& object_identifier) {
- flatbuffers::FlatBufferBuilder builder;
- builder.Finish(ToObjectIdentifierStorage(&builder, object_identifier));
- return std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
- builder.GetSize());
-}
-
-bool DecodeObjectIdentifier(fxl::StringView data,
- ObjectIdentifier* object_identifier) {
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(data.data()), data.size());
- if (!VerifyObjectIdentifierStorageBuffer(verifier)) {
- return false;
- }
- const ObjectIdentifierStorage* storage = GetObjectIdentifierStorage(
- reinterpret_cast<const unsigned char*>(data.data()));
- if (!IsObjectIdentifierStorageValid(storage)) {
- return false;
- }
- *object_identifier = ToObjectIdentifier(storage);
- return true;
-}
-
-bool IsObjectIdentifierStorageValid(const ObjectIdentifierStorage* storage) {
- return storage && storage->object_digest() &&
- IsDigestValid(storage->object_digest());
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/object_identifier_encoding.h b/bin/ledger/storage/impl/object_identifier_encoding.h
deleted file mode 100644
index 51460bf..0000000
--- a/bin/ledger/storage/impl/object_identifier_encoding.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_IDENTIFIER_ENCODING_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_IDENTIFIER_ENCODING_H_
-
-#include "peridot/bin/ledger/storage/impl/object_identifier_generated.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "third_party/flatbuffers/include/flatbuffers/flatbuffers.h"
-
-namespace storage {
-
-// Converts a |ObjectIdentifierStorage| to an |ObjectIdentifier|.
-ObjectIdentifier ToObjectIdentifier(
- const ObjectIdentifierStorage* object_identifier_storage);
-
-// Converts a |ObjectIdentifier| to an |ObjectIdentifierStorage|.
-flatbuffers::Offset<ObjectIdentifierStorage> ToObjectIdentifierStorage(
- flatbuffers::FlatBufferBuilder* builder,
- const ObjectIdentifier& object_identifier);
-
-// Encode an ObjectIdentifier into a string.
-std::string EncodeObjectIdentifier(const ObjectIdentifier& object_identifier);
-
-// Decode an ObjectIdentifier from a string. Return |true| in case of success,
-// |false| otherwise.
-bool DecodeObjectIdentifier(fxl::StringView data,
- ObjectIdentifier* object_identifier);
-
-// Returns whether a |ObjectIdentifierStorage| obtained from flatbuffer is
-// valid.
-bool IsObjectIdentifierStorageValid(const ObjectIdentifierStorage* storage);
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_IDENTIFIER_ENCODING_H_
diff --git a/bin/ledger/storage/impl/object_impl.cc b/bin/ledger/storage/impl/object_impl.cc
deleted file mode 100644
index b29e3d0..0000000
--- a/bin/ledger/storage/impl/object_impl.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/object_impl.h"
-
-#include <utility>
-
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-
-namespace storage {
-
-namespace {
-uint64_t ToFullPages(uint64_t value) {
- return (value + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));
-}
-} // namespace
-
-InlinedObject::InlinedObject(ObjectIdentifier identifier)
- : identifier_(std::move(identifier)) {}
-InlinedObject::~InlinedObject() {}
-
-ObjectIdentifier InlinedObject::GetIdentifier() const { return identifier_; }
-
-Status InlinedObject::GetData(fxl::StringView* data) const {
- *data = ExtractObjectDigestData(identifier_.object_digest());
- return Status::OK;
-}
-
-StringObject::StringObject(ObjectIdentifier identifier, std::string content)
- : identifier_(std::move(identifier)), content_(std::move(content)) {}
-
-StringObject::~StringObject() {}
-
-ObjectIdentifier StringObject::GetIdentifier() const { return identifier_; }
-
-Status StringObject::GetData(fxl::StringView* data) const {
- *data = content_;
- return Status::OK;
-}
-
-LevelDBObject::LevelDBObject(ObjectIdentifier identifier,
- std::unique_ptr<leveldb::Iterator> iterator)
- : identifier_(std::move(identifier)), iterator_(std::move(iterator)) {}
-
-LevelDBObject::~LevelDBObject() {}
-
-ObjectIdentifier LevelDBObject::GetIdentifier() const { return identifier_; }
-
-Status LevelDBObject::GetData(fxl::StringView* data) const {
- *data = convert::ExtendedStringView(iterator_->value());
- return Status::OK;
-}
-
-VmoObject::VmoObject(ObjectIdentifier identifier, fsl::SizedVmo vmo)
- : identifier_(std::move(identifier)), vmo_(std::move(vmo)) {}
-
-VmoObject::~VmoObject() {
- if (vmar_) {
- vmar_.destroy();
- }
-}
-
-ObjectIdentifier VmoObject::GetIdentifier() const { return identifier_; }
-
-Status VmoObject::GetData(fxl::StringView* data) const {
- Status status = Initialize();
- if (status != Status::OK) {
- return status;
- }
- *data = data_;
- return Status::OK;
-}
-
-Status VmoObject::GetVmo(fsl::SizedVmo* vmo) const {
- Status status = Initialize();
- if (status != Status::OK) {
- return status;
- }
-
- zx_status_t zx_status =
- vmo_.Duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_READ | ZX_RIGHT_MAP, vmo);
- if (zx_status != ZX_OK) {
- FXL_LOG(ERROR) << "Unable to duplicate a vmo. Status: " << zx_status;
- return Status::INTERNAL_IO_ERROR;
- }
- return Status::OK;
-}
-
-Status VmoObject::Initialize() const {
- if (initialized_) {
- return Status::OK;
- }
-
- uintptr_t allocate_address;
- zx_status_t zx_status = zx::vmar::root_self()->allocate(
- 0, ToFullPages(vmo_.size()),
- ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC, &vmar_,
- &allocate_address);
- if (zx_status != ZX_OK) {
- FXL_LOG(ERROR) << "Unable to allocate VMAR. Error: " << zx_status;
- return Status::INTERNAL_IO_ERROR;
- }
-
- char* mapped_address;
- zx_status = vmar_.map(0, vmo_.vmo(), 0, vmo_.size(),
- ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC,
- reinterpret_cast<uintptr_t*>(&mapped_address));
- if (zx_status != ZX_OK) {
- FXL_LOG(ERROR) << "Unable to map VMO. Error: " << zx_status;
- vmar_.reset();
- return Status::INTERNAL_IO_ERROR;
- }
-
- data_ = fxl::StringView(mapped_address, vmo_.size());
- initialized_ = true;
-
- return Status::OK;
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/object_impl.h b/bin/ledger/storage/impl/object_impl.h
deleted file mode 100644
index 79a2e4d..0000000
--- a/bin/ledger/storage/impl/object_impl.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_IMPL_H_
-
-#include <memory>
-
-#include <lib/zx/vmar.h>
-
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/lib/convert/convert.h"
-#include "third_party/leveldb/include/leveldb/iterator.h"
-
-namespace storage {
-
-// Object whose data is equal to its id.
-class InlinedObject : public Object {
- public:
- explicit InlinedObject(ObjectIdentifier identifier);
- ~InlinedObject() override;
-
- // Object:
- ObjectIdentifier GetIdentifier() const override;
- Status GetData(fxl::StringView* data) const override;
-
- private:
- const ObjectIdentifier identifier_;
-};
-
-// Object whose data is backed by a string.
-class StringObject : public Object {
- public:
- StringObject(ObjectIdentifier identifier, std::string content);
- ~StringObject() override;
-
- // Object:
- ObjectIdentifier GetIdentifier() const override;
- Status GetData(fxl::StringView* data) const override;
-
- private:
- const ObjectIdentifier identifier_;
- std::string content_;
-};
-
-// Object whose data is backed by a value in LevelDB.
-class LevelDBObject : public Object {
- public:
- LevelDBObject(ObjectIdentifier identifier,
- std::unique_ptr<leveldb::Iterator> iterator);
- ~LevelDBObject() override;
-
- // Object:
- ObjectIdentifier GetIdentifier() const override;
- Status GetData(fxl::StringView* data) const override;
-
- private:
- const ObjectIdentifier identifier_;
- std::unique_ptr<leveldb::Iterator> iterator_;
-};
-
-// Object whose data is backed by a VMO.
-class VmoObject : public Object {
- public:
- VmoObject(ObjectIdentifier identifier, fsl::SizedVmo vmo);
- ~VmoObject() override;
-
- // Object:
- ObjectIdentifier GetIdentifier() const override;
- Status GetData(fxl::StringView* data) const override;
- Status GetVmo(fsl::SizedVmo* vmo) const override;
-
- private:
- Status Initialize() const;
-
- mutable bool initialized_ = false;
- const ObjectIdentifier identifier_;
- fsl::SizedVmo vmo_;
- mutable zx::vmar vmar_;
- mutable fxl::StringView data_;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_OBJECT_IMPL_H_
diff --git a/bin/ledger/storage/impl/object_impl_unittest.cc b/bin/ledger/storage/impl/object_impl_unittest.cc
deleted file mode 100644
index c66e120..0000000
--- a/bin/ledger/storage/impl/object_impl_unittest.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/object_impl.h"
-
-#include <lib/fsl/vmo/strings.h>
-#include <zircon/syscalls.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-#include "third_party/leveldb/include/leveldb/db.h"
-#include "util/env_fuchsia.h"
-
-namespace storage {
-namespace {
-
-ObjectIdentifier CreateObjectIdentifier(ObjectDigest digest) {
- return {1u, 2u, std::move(digest)};
-}
-
-::testing::AssertionResult CheckObjectValue(const Object& object,
- ObjectIdentifier identifier,
- fxl::StringView data) {
- if (object.GetIdentifier() != identifier) {
- return ::testing::AssertionFailure()
- << "Expected id: " << identifier
- << ", but got: " << object.GetIdentifier();
- }
-
- fxl::StringView found_data;
- Status status = object.GetData(&found_data);
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "Unable to call GetData on object, status: " << status;
- }
-
- if (data != found_data) {
- return ::testing::AssertionFailure()
- << "Expected data: " << convert::ToHex(data)
- << ", but got: " << convert::ToHex(found_data);
- }
-
- fsl::SizedVmo vmo;
- status = object.GetVmo(&vmo);
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "Unable to call GetVmo on object, status: " << status;
- }
-
- std::string found_data_in_vmo;
- if (!fsl::StringFromVmo(vmo, &found_data_in_vmo)) {
- return ::testing::AssertionFailure() << "Unable to read from VMO.";
- }
-
- if (data != found_data_in_vmo) {
- return ::testing::AssertionFailure()
- << "Expected data in vmo: " << convert::ToHex(data)
- << ", but got: " << convert::ToHex(found_data_in_vmo);
- }
-
- return ::testing::AssertionSuccess();
-}
-
-class ObjectImplTest : public ledger::TestWithEnvironment {
- public:
- std::string RandomString(size_t size) {
- std::string result;
- result.resize(size);
- environment_.random()->Draw(&result);
- return result;
- }
-};
-
-TEST_F(ObjectImplTest, InlinedObject) {
- std::string data = RandomString(12);
- ObjectIdentifier identifier = CreateObjectIdentifier(
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, data));
-
- InlinedObject object(identifier);
- EXPECT_TRUE(CheckObjectValue(object, identifier, data));
-}
-
-TEST_F(ObjectImplTest, StringObject) {
- std::string data = RandomString(256);
- ObjectIdentifier identifier = CreateObjectIdentifier(
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, data));
-
- StringObject object(identifier, data);
- EXPECT_TRUE(CheckObjectValue(object, identifier, data));
-}
-
-TEST_F(ObjectImplTest, LevelDBObject) {
- scoped_tmpfs::ScopedTmpFS tmpfs;
- auto env = leveldb::MakeFuchsiaEnv(tmpfs.root_fd());
-
- leveldb::DB* db = nullptr;
- leveldb::Options options;
- options.env = env.get();
- options.create_if_missing = true;
- leveldb::Status status = leveldb::DB::Open(options, "db", &db);
- ASSERT_TRUE(status.ok());
- std::unique_ptr<leveldb::DB> db_ptr(db);
-
- leveldb::WriteOptions write_options_;
- leveldb::ReadOptions read_options_;
-
- std::string data = RandomString(256);
- ObjectIdentifier identifier = CreateObjectIdentifier(
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, data));
-
- status = db_ptr->Put(write_options_, "", data);
- ASSERT_TRUE(status.ok());
- std::unique_ptr<leveldb::Iterator> iterator(
- db_ptr->NewIterator(read_options_));
- iterator->Seek("");
- ASSERT_TRUE(iterator->Valid());
- ASSERT_TRUE(iterator->key() == "");
-
- LevelDBObject object(identifier, std::move(iterator));
- EXPECT_TRUE(CheckObjectValue(object, identifier, data));
-}
-
-TEST_F(ObjectImplTest, VmoObject) {
- std::string data = RandomString(256);
- ObjectIdentifier identifier = CreateObjectIdentifier(
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, data));
-
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(data, &vmo));
-
- VmoObject object(identifier, std::move(vmo));
- EXPECT_TRUE(CheckObjectValue(object, identifier, data));
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/impl/page_db.h b/bin/ledger/storage/impl/page_db.h
deleted file mode 100644
index c840196..0000000
--- a/bin/ledger/storage/impl/page_db.h
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/zx/time.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/bin/ledger/storage/public/db.h"
-#include "peridot/bin/ledger/storage/public/iterator.h"
-#include "peridot/bin/ledger/storage/public/journal.h"
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-class PageStorageImpl;
-
-// Status of an object in the database.
-enum class PageDbObjectStatus {
- // The object is not in the database.
- UNKNOWN,
- // The object is in the database, but not in any commit.
- TRANSIENT,
- // The object is associated to a commit, but not yet synced.
- LOCAL,
- // The object is synced.
- SYNCED,
-};
-
-// |PageDbMutator| provides all update (insertion and deletion) operations
-// over |PageDb|.
-class PageDbMutator {
- public:
- PageDbMutator() {}
- virtual ~PageDbMutator() {}
-
- // Heads.
- // Adds the given |head| in the set of commit heads.
- FXL_WARN_UNUSED_RESULT virtual Status AddHead(
- coroutine::CoroutineHandler* handler, CommitIdView head,
- zx::time_utc timestamp) = 0;
-
- // Removes the given |head| from the head commits.
- FXL_WARN_UNUSED_RESULT virtual Status RemoveHead(
- coroutine::CoroutineHandler* handler, CommitIdView head) = 0;
-
- // Commits.
- // Adds the given |commit| in the database.
- FXL_WARN_UNUSED_RESULT virtual Status AddCommitStorageBytes(
- coroutine::CoroutineHandler* handler, const CommitId& commit_id,
- fxl::StringView storage_bytes) = 0;
-
- // Removes the commit with the given |commit_id| from the commits.
- FXL_WARN_UNUSED_RESULT virtual Status RemoveCommit(
- coroutine::CoroutineHandler* handler, const CommitId& commit_id) = 0;
-
- // Journals.
- // Creates a new id for a journal with the given type and base commit. In a
- // merge journal, the base commit is always the left one.
- FXL_WARN_UNUSED_RESULT virtual Status CreateJournalId(
- coroutine::CoroutineHandler* handler, JournalType journal_type,
- const CommitId& base, JournalId* journal_id) = 0;
-
- // Removes all information on explicit journals from the database.
- FXL_WARN_UNUSED_RESULT virtual Status RemoveExplicitJournals(
- coroutine::CoroutineHandler* handler) = 0;
-
- // Removes all information on the journal with the given |journal_id| from the
- // database.
- FXL_WARN_UNUSED_RESULT virtual Status RemoveJournal(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id) = 0;
-
- // Adds a new |key|-|value| pair with the given |priority| to the journal with
- // the given |journal_id|.
- FXL_WARN_UNUSED_RESULT virtual Status AddJournalEntry(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id,
- fxl::StringView key, const ObjectIdentifier& object_identifier,
- KeyPriority priority) = 0;
-
- // Removes the given key from the journal with the given |journal_id|.
- FXL_WARN_UNUSED_RESULT virtual Status RemoveJournalEntry(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id,
- convert::ExtendedStringView key) = 0;
-
- // Marks the journal with the given |journal_id| as containing a clear
- // operation and removes all entries.
- FXL_WARN_UNUSED_RESULT virtual Status
- EmptyJournalAndMarkContainsClearOperation(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id) = 0;
-
- // Object data.
- // Writes the content of the given object.
- FXL_WARN_UNUSED_RESULT virtual Status WriteObject(
- coroutine::CoroutineHandler* handler, ObjectIdentifier object_identifier,
- std::unique_ptr<DataSource::DataChunk> content,
- PageDbObjectStatus object_status) = 0;
-
- // Object sync metadata.
- // Sets the status of the object with the given id.
- FXL_WARN_UNUSED_RESULT virtual Status SetObjectStatus(
- coroutine::CoroutineHandler* handler, ObjectIdentifier object_identifier,
- PageDbObjectStatus object_status) = 0;
-
- // Commit sync metadata.
- // Marks the given |commit_id| as synced.
- FXL_WARN_UNUSED_RESULT virtual Status MarkCommitIdSynced(
- coroutine::CoroutineHandler* handler, const CommitId& commit_id) = 0;
-
- // Marks the given |commit_id| as unsynced.
- FXL_WARN_UNUSED_RESULT virtual Status MarkCommitIdUnsynced(
- coroutine::CoroutineHandler* handler, const CommitId& commit_id,
- uint64_t generation) = 0;
-
- // Sets the opaque sync metadata associated with this page for the given key.
- FXL_WARN_UNUSED_RESULT virtual Status SetSyncMetadata(
- coroutine::CoroutineHandler* handler, fxl::StringView key,
- fxl::StringView value) = 0;
-
- // Updates the online state of the page.
- FXL_WARN_UNUSED_RESULT virtual Status MarkPageOnline(
- coroutine::CoroutineHandler* handler) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageDbMutator);
-};
-
-// |PageDb| manages all Ledger related data that are locally stored. This
-// includes commit, value and tree node objects, information on head commits, as
-// well as metadata on which objects and commits are not yet synchronized to the
-// cloud.
-class PageDb : public PageDbMutator {
- public:
- // A |Batch| can be used to execute a number of updates in |PageDb|
- // atomically.
- class Batch : public PageDbMutator {
- public:
- Batch() {}
- ~Batch() override {}
-
- // Executes this batch. No further operations in this batch are supported
- // after a successful execution.
- FXL_WARN_UNUSED_RESULT virtual Status Execute(
- coroutine::CoroutineHandler* handler) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(Batch);
- };
-
- PageDb() {}
- ~PageDb() override {}
-
- // Starts a new batch. The batch will be written when Execute is called on the
- // returned object. The PageDb object must outlive the batch object. If the
- // coroutine is interrupted, |INTERRUPTED| status is returned.
- FXL_WARN_UNUSED_RESULT virtual Status StartBatch(
- coroutine::CoroutineHandler* handler, std::unique_ptr<Batch>* batch) = 0;
-
- // Heads.
- // Finds all head commits and replaces the contents of |heads| with their ids.
- // Returns |OK| on success or |IO_ERROR| in case of an error reading the
- // values. It is not an error if no heads are found. The resulting |heads| are
- // ordered by the timestamp given at their insertion and if identical, by
- // their id.
- FXL_WARN_UNUSED_RESULT virtual Status GetHeads(
- coroutine::CoroutineHandler* handler, std::vector<CommitId>* heads) = 0;
-
- // Commits.
- // Finds the commit with the given |commit_id| and stores its represenation in
- // storage bytes in the |storage_bytes| string.
- FXL_WARN_UNUSED_RESULT virtual Status GetCommitStorageBytes(
- coroutine::CoroutineHandler* handler, CommitIdView commit_id,
- std::string* storage_bytes) = 0;
-
- // Journals.
- // Finds all implicit journal ids and replaces the contents of |journal_ids|
- // with their ids.
- FXL_WARN_UNUSED_RESULT virtual Status GetImplicitJournalIds(
- coroutine::CoroutineHandler* handler,
- std::vector<JournalId>* journal_ids) = 0;
-
- // Stores the id of the base commit for the journal with the given |base|
- // parameter.
- FXL_WARN_UNUSED_RESULT virtual Status GetBaseCommitForJournal(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id,
- CommitId* base) = 0;
-
- // Finds all the entries of the journal with the given |journal_id| and stores
- // an interator over the results on |entires|. Also returns a flag indicating
- // if the journal contains a clear operation, in which case we need to delete
- // all pre-existing data from the page upon commit.
- FXL_WARN_UNUSED_RESULT virtual Status GetJournalEntries(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id,
- std::unique_ptr<Iterator<const EntryChange>>* entries,
- JournalContainsClearOperation* contains_clear_operation) = 0;
-
- // Object data.
- // Reads the content of the given object. To check whether an object is stored
- // in the PageDb without retrieving its value, |nullptr| can be given for the
- // |object| argument.
- FXL_WARN_UNUSED_RESULT virtual Status ReadObject(
- coroutine::CoroutineHandler* handler, ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) = 0;
-
- // Checks whether the object with the given |object_digest| is stored in the
- // database.
- FXL_WARN_UNUSED_RESULT virtual Status HasObject(
- coroutine::CoroutineHandler* handler, const ObjectDigest& object_digest,
- bool* has_object) = 0;
-
- // Returns the status of the object with the given id.
- FXL_WARN_UNUSED_RESULT virtual Status GetObjectStatus(
- coroutine::CoroutineHandler* handler, ObjectIdentifier object_identifier,
- PageDbObjectStatus* object_status) = 0;
-
- // Commit sync metadata.
- // Finds the set of unsynced commits and replaces the contents of |commit_ids|
- // with their ids. The result is ordered by the timestamps given when calling
- // |MarkCommitIdUnsynced|.
- FXL_WARN_UNUSED_RESULT virtual Status GetUnsyncedCommitIds(
- coroutine::CoroutineHandler* handler,
- std::vector<CommitId>* commit_ids) = 0;
-
- // Checks if the commit with the given |commit_id| is synced.
- FXL_WARN_UNUSED_RESULT virtual Status IsCommitSynced(
- coroutine::CoroutineHandler* handler, const CommitId& commit_id,
- bool* is_synced) = 0;
-
- // Object sync metadata.
- // Finds the set of unsynced pieces and replaces the contents of
- // |object_identifiers| with their identifiers.
- FXL_WARN_UNUSED_RESULT virtual Status GetUnsyncedPieces(
- coroutine::CoroutineHandler* handler,
- std::vector<ObjectIdentifier>* object_identifiers) = 0;
-
- // Sync metadata.
- // Retrieves the opaque sync metadata associated with this page for the given
- // key.
- FXL_WARN_UNUSED_RESULT virtual Status GetSyncMetadata(
- coroutine::CoroutineHandler* handler, fxl::StringView key,
- std::string* value) = 0;
-
- // Returns whether the page is online, i.e. has been synced to the cloud or a
- // peer at least once from this device. By default, the state of a page is
- // offline. Once the state is set to online, it cannot be unset.
- FXL_WARN_UNUSED_RESULT virtual Status IsPageOnline(
- coroutine::CoroutineHandler* handler, bool* page_is_online) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageDb);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_H_
diff --git a/bin/ledger/storage/impl/page_db_batch_impl.cc b/bin/ledger/storage/impl/page_db_batch_impl.cc
deleted file mode 100644
index 20a132c..0000000
--- a/bin/ledger/storage/impl/page_db_batch_impl.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/page_db_batch_impl.h"
-
-#include <memory>
-
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/bin/ledger/storage/impl/data_serialization.h"
-#include "peridot/bin/ledger/storage/impl/db_serialization.h"
-#include "peridot/bin/ledger/storage/impl/journal_impl.h"
-
-#define RETURN_ON_ERROR(expr) \
- do { \
- Status status = (expr); \
- if (status != Status::OK) { \
- return status; \
- } \
- } while (0)
-
-namespace storage {
-
-using coroutine::CoroutineHandler;
-
-PageDbBatchImpl::PageDbBatchImpl(rng::Random* random,
- std::unique_ptr<Db::Batch> batch, PageDb* db)
- : random_(random), batch_(std::move(batch)), db_(db) {}
-
-PageDbBatchImpl::~PageDbBatchImpl() {}
-
-Status PageDbBatchImpl::AddHead(CoroutineHandler* handler, CommitIdView head,
- zx::time_utc timestamp) {
- return batch_->Put(handler, HeadRow::GetKeyFor(head),
- SerializeData(timestamp));
-}
-
-Status PageDbBatchImpl::RemoveHead(CoroutineHandler* handler,
- CommitIdView head) {
- return batch_->Delete(handler, HeadRow::GetKeyFor(head));
-}
-
-Status PageDbBatchImpl::AddCommitStorageBytes(CoroutineHandler* handler,
- const CommitId& commit_id,
- fxl::StringView storage_bytes) {
- return batch_->Put(handler, CommitRow::GetKeyFor(commit_id), storage_bytes);
-}
-
-Status PageDbBatchImpl::RemoveCommit(CoroutineHandler* handler,
- const CommitId& commit_id) {
- return batch_->Delete(handler, CommitRow::GetKeyFor(commit_id));
-}
-
-Status PageDbBatchImpl::CreateJournalId(coroutine::CoroutineHandler* handler,
- JournalType journal_type,
- const CommitId& base,
- JournalId* journal_id) {
- JournalId id = JournalEntryRow::NewJournalId(random_, journal_type);
-
- Status status = Status::OK;
- if (journal_type == JournalType::IMPLICIT) {
- status =
- batch_->Put(handler, ImplicitJournalMetadataRow::GetKeyFor(id), base);
- }
-
- if (status == Status::OK) {
- journal_id->swap(id);
- }
- return status;
-}
-
-Status PageDbBatchImpl::RemoveExplicitJournals(CoroutineHandler* handler) {
- static std::string kExplicitJournalPrefix =
- fxl::Concatenate({JournalEntryRow::kPrefix,
- fxl::StringView(&JournalEntryRow::kExplicitPrefix, 1)});
- return batch_->DeleteByPrefix(handler, kExplicitJournalPrefix);
-}
-
-Status PageDbBatchImpl::RemoveJournal(CoroutineHandler* handler,
- const JournalId& journal_id) {
- if (journal_id[0] == JournalEntryRow::kImplicitPrefix) {
- RETURN_ON_ERROR(batch_->Delete(
- handler, ImplicitJournalMetadataRow::GetKeyFor(journal_id)));
- }
- return batch_->DeleteByPrefix(handler,
- JournalEntryRow::GetPrefixFor(journal_id));
-}
-
-Status PageDbBatchImpl::AddJournalEntry(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id,
- fxl::StringView key, const ObjectIdentifier& object_identifier,
- KeyPriority priority) {
- return batch_->Put(handler, JournalEntryRow::GetKeyFor(journal_id, key),
- JournalEntryRow::GetValueFor(object_identifier, priority));
-}
-
-Status PageDbBatchImpl::RemoveJournalEntry(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id,
- convert::ExtendedStringView key) {
- return batch_->Put(handler, JournalEntryRow::GetKeyFor(journal_id, key),
- JournalEntryRow::kDeletePrefix);
-}
-
-Status PageDbBatchImpl::EmptyJournalAndMarkContainsClearOperation(
- CoroutineHandler* handler, const JournalId& journal_id) {
- Status status = batch_->DeleteByPrefix(
- handler, JournalEntryRow::GetPrefixFor(journal_id));
- if (status != Status::OK) {
- return status;
- }
- return batch_->Put(handler, JournalEntryRow::GetClearMarkerKey(journal_id),
- "");
-}
-
-Status PageDbBatchImpl::WriteObject(
- CoroutineHandler* handler, ObjectIdentifier object_identifier,
- std::unique_ptr<DataSource::DataChunk> content,
- PageDbObjectStatus object_status) {
- FXL_DCHECK(object_status > PageDbObjectStatus::UNKNOWN);
-
- bool has_key;
- RETURN_ON_ERROR(
- db_->HasObject(handler, object_identifier.object_digest(), &has_key));
- if (has_key) {
- if (object_status == PageDbObjectStatus::TRANSIENT) {
- return Status::OK;
- }
- return SetObjectStatus(handler, std::move(object_identifier),
- object_status);
- }
-
- RETURN_ON_ERROR(batch_->Put(
- handler, ObjectRow::GetKeyFor(object_identifier.object_digest()),
- content->Get()));
- return batch_->Put(
- handler, ObjectStatusRow::GetKeyFor(object_status, object_identifier),
- "");
-}
-
-Status PageDbBatchImpl::SetObjectStatus(CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- PageDbObjectStatus object_status) {
- FXL_DCHECK(object_status >= PageDbObjectStatus::LOCAL);
- RETURN_ON_ERROR(DCheckHasObject(handler, object_identifier.object_digest()));
-
- PageDbObjectStatus previous_object_status;
- RETURN_ON_ERROR(db_->GetObjectStatus(handler, object_identifier,
- &previous_object_status));
- if (previous_object_status >= object_status) {
- return Status::OK;
- }
- RETURN_ON_ERROR(batch_->Delete(
- handler,
- ObjectStatusRow::GetKeyFor(previous_object_status, object_identifier)));
- return batch_->Put(
- handler, ObjectStatusRow::GetKeyFor(object_status, object_identifier),
- "");
-}
-
-Status PageDbBatchImpl::MarkCommitIdSynced(CoroutineHandler* handler,
- const CommitId& commit_id) {
- return batch_->Delete(handler, UnsyncedCommitRow::GetKeyFor(commit_id));
-}
-
-Status PageDbBatchImpl::MarkCommitIdUnsynced(CoroutineHandler* handler,
- const CommitId& commit_id,
- uint64_t generation) {
- return batch_->Put(handler, UnsyncedCommitRow::GetKeyFor(commit_id),
- SerializeData(generation));
-}
-
-Status PageDbBatchImpl::SetSyncMetadata(CoroutineHandler* handler,
- fxl::StringView key,
- fxl::StringView value) {
- return batch_->Put(handler, SyncMetadataRow::GetKeyFor(key), value);
-}
-
-Status PageDbBatchImpl::MarkPageOnline(coroutine::CoroutineHandler* handler) {
- return batch_->Put(handler, PageIsOnlineRow::kKey, "");
-}
-
-Status PageDbBatchImpl::Execute(CoroutineHandler* handler) {
- return batch_->Execute(handler);
-}
-
-Status PageDbBatchImpl::DCheckHasObject(CoroutineHandler* handler,
- const ObjectDigest& key) {
-#ifdef NDEBUG
- return Status::OK;
-#else
- bool result;
- Status status = db_->HasObject(handler, key, &result);
- if (status == Status::INTERRUPTED) {
- return status;
- }
- FXL_DCHECK(status == Status::OK && result);
- return Status::OK;
-#endif
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/page_db_batch_impl.h b/bin/ledger/storage/impl/page_db_batch_impl.h
deleted file mode 100644
index 5550959..0000000
--- a/bin/ledger/storage/impl/page_db_batch_impl.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_BATCH_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_BATCH_IMPL_H_
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/impl/page_db.h"
-#include "peridot/bin/ledger/storage/public/db.h"
-#include "peridot/lib/rng/random.h"
-
-namespace storage {
-
-class PageDbBatchImpl : public PageDb::Batch {
- public:
- explicit PageDbBatchImpl(rng::Random* random,
- std::unique_ptr<Db::Batch> batch, PageDb* db);
- ~PageDbBatchImpl() override;
-
- // Heads.
- Status AddHead(coroutine::CoroutineHandler* handler, CommitIdView head,
- zx::time_utc timestamp) override;
- Status RemoveHead(coroutine::CoroutineHandler* handler,
- CommitIdView head) override;
-
- // Commits.
- Status AddCommitStorageBytes(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id,
- fxl::StringView storage_bytes) override;
- Status RemoveCommit(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id) override;
-
- // Journals.
- Status CreateJournalId(coroutine::CoroutineHandler* handler,
- JournalType journal_type, const CommitId& base,
- JournalId* journal_id) override;
- Status RemoveExplicitJournals(coroutine::CoroutineHandler* handler) override;
- Status RemoveJournal(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id) override;
-
- // Journal entries.
- Status AddJournalEntry(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id, fxl::StringView key,
- const ObjectIdentifier& object_identifier,
- KeyPriority priority) override;
- Status RemoveJournalEntry(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id,
- convert::ExtendedStringView key) override;
- Status EmptyJournalAndMarkContainsClearOperation(
- coroutine::CoroutineHandler* handler,
- const JournalId& journal_id) override;
-
- // Object data.
- Status WriteObject(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- std::unique_ptr<DataSource::DataChunk> content,
- PageDbObjectStatus object_status) override;
- Status SetObjectStatus(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- PageDbObjectStatus object_status) override;
-
- // Commit sync metadata.
- Status MarkCommitIdSynced(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id) override;
- Status MarkCommitIdUnsynced(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id,
- uint64_t generation) override;
-
- // Object sync metadata.
- Status SetSyncMetadata(coroutine::CoroutineHandler* handler,
- fxl::StringView key, fxl::StringView value) override;
-
- // Page online state.
- Status MarkPageOnline(coroutine::CoroutineHandler* handler) override;
-
- Status Execute(coroutine::CoroutineHandler* handler) override;
-
- private:
- Status DCheckHasObject(coroutine::CoroutineHandler* handler,
- const ObjectDigest& key);
-
- rng::Random* const random_;
- std::unique_ptr<Db::Batch> batch_;
- PageDb* const db_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageDbBatchImpl);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_BATCH_IMPL_H_
diff --git a/bin/ledger/storage/impl/page_db_empty_impl.cc b/bin/ledger/storage/impl/page_db_empty_impl.cc
deleted file mode 100644
index 5c84ba8..0000000
--- a/bin/ledger/storage/impl/page_db_empty_impl.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/page_db_empty_impl.h"
-
-namespace storage {
-
-using coroutine::CoroutineHandler;
-
-Status PageDbEmptyImpl::StartBatch(CoroutineHandler* /*handler*/,
- std::unique_ptr<PageDb::Batch>* /*batch*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetHeads(CoroutineHandler* /*handler*/,
- std::vector<CommitId>* /*heads*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetCommitStorageBytes(CoroutineHandler* /*handler*/,
- CommitIdView /*commit_id*/,
- std::string* /*storage_bytes*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetImplicitJournalIds(
- CoroutineHandler* /*handler*/, std::vector<JournalId>* /*journal_ids*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetBaseCommitForJournal(CoroutineHandler* /*handler*/,
- const JournalId& /*journal_id*/,
- CommitId* /*base*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetJournalEntries(
- CoroutineHandler* /*handler*/, const JournalId& /*journal_id*/,
- std::unique_ptr<Iterator<const EntryChange>>* /*entries*/,
- JournalContainsClearOperation* /*contains_clear_operation*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::ReadObject(CoroutineHandler* /*handler*/,
- ObjectIdentifier /*object_identifier*/,
- std::unique_ptr<const Object>* /*object*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::HasObject(CoroutineHandler* /*handler*/,
- const ObjectDigest& /*object_digest*/,
- bool* /*has_object*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetObjectStatus(CoroutineHandler* /*handler*/,
- ObjectIdentifier /*object_identifier*/,
- PageDbObjectStatus* /*object_status*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetUnsyncedCommitIds(
- CoroutineHandler* /*handler*/, std::vector<CommitId>* /*commit_ids*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::IsCommitSynced(CoroutineHandler* /*handler*/,
- const CommitId& /*commit_id*/,
- bool* /*is_synced*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetUnsyncedPieces(
- CoroutineHandler* /*handler*/,
- std::vector<ObjectIdentifier>* /*object_identifiers*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::GetSyncMetadata(CoroutineHandler* /*handler*/,
- fxl::StringView /*key*/,
- std::string* /*value*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::IsPageOnline(coroutine::CoroutineHandler* /*handler*/,
- bool* /*page_is_online*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::AddHead(CoroutineHandler* /*handler*/,
- CommitIdView /*head*/,
- zx::time_utc /*timestamp*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::RemoveHead(CoroutineHandler* /*handler*/,
- CommitIdView /*head*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::AddCommitStorageBytes(
- CoroutineHandler* /*handler*/, const CommitId& /*commit_id*/,
- fxl::StringView /*storage_bytes*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::RemoveCommit(CoroutineHandler* /*handler*/,
- const CommitId& /*commit_id*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::CreateJournalId(CoroutineHandler* /*handler*/,
- JournalType /*journal_type*/,
- const CommitId& /*base*/,
- JournalId* /*journal*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::RemoveExplicitJournals(CoroutineHandler* /*handler*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::RemoveJournal(CoroutineHandler* /*handler*/,
- const JournalId& /*journal_id*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::AddJournalEntry(
- CoroutineHandler* /*handler*/, const JournalId& /*journal_id*/,
- fxl::StringView /*key*/, const ObjectIdentifier& /*object_identifier*/,
- KeyPriority /*priority*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::RemoveJournalEntry(
- CoroutineHandler* /*handler*/, const JournalId& /*journal_id*/,
- convert::ExtendedStringView /*key*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::EmptyJournalAndMarkContainsClearOperation(
- coroutine::CoroutineHandler* /*handler*/, const JournalId& /*journal_id*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::WriteObject(
- CoroutineHandler* /*handler*/, ObjectIdentifier /*object_identifier*/,
- std::unique_ptr<DataSource::DataChunk> /*content*/,
- PageDbObjectStatus /*object_status*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::SetObjectStatus(CoroutineHandler* /*handler*/,
- ObjectIdentifier /*object_identifier*/,
- PageDbObjectStatus /*object_status*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::MarkCommitIdSynced(CoroutineHandler* /*handler*/,
- const CommitId& /*commit_id*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::MarkCommitIdUnsynced(CoroutineHandler* /*handler*/,
- const CommitId& /*commit_id*/,
- uint64_t /*generation*/) {
- return Status::NOT_IMPLEMENTED;
-}
-Status PageDbEmptyImpl::SetSyncMetadata(CoroutineHandler* /*handler*/,
- fxl::StringView /*key*/,
- fxl::StringView /*value*/) {
- return Status::NOT_IMPLEMENTED;
-}
-
-Status PageDbEmptyImpl::MarkPageOnline(
- coroutine::CoroutineHandler* /*handlers*/) {
- return Status::NOT_IMPLEMENTED;
-}
-
-Status PageDbEmptyImpl::Execute(CoroutineHandler* /*handler*/) {
- return Status::NOT_IMPLEMENTED;
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/page_db_empty_impl.h b/bin/ledger/storage/impl/page_db_empty_impl.h
deleted file mode 100644
index bb7e48e..0000000
--- a/bin/ledger/storage/impl/page_db_empty_impl.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_EMPTY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_EMPTY_IMPL_H_
-
-#include "peridot/bin/ledger/storage/impl/page_db.h"
-
-namespace storage {
-
-class PageDbEmptyImpl : public PageDb, public PageDb::Batch {
- public:
- PageDbEmptyImpl() {}
- ~PageDbEmptyImpl() override {}
-
- // PageDb:
- Status StartBatch(coroutine::CoroutineHandler* handler,
- std::unique_ptr<PageDb::Batch>* batch) override;
- Status GetHeads(coroutine::CoroutineHandler* handler,
- std::vector<CommitId>* heads) override;
- Status GetCommitStorageBytes(coroutine::CoroutineHandler* handler,
- CommitIdView commit_id,
- std::string* storage_bytes) override;
- Status GetImplicitJournalIds(coroutine::CoroutineHandler* handler,
- std::vector<JournalId>* journal_ids) override;
- Status GetBaseCommitForJournal(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id,
- CommitId* base) override;
- Status GetJournalEntries(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id,
- std::unique_ptr<Iterator<const EntryChange>>* entries,
- JournalContainsClearOperation* contains_clear_operation) override;
-
- // PageDb and PageDb::Batch:
- Status ReadObject(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) override;
- Status HasObject(coroutine::CoroutineHandler* handler,
- const ObjectDigest& object_digest,
- bool* has_object) override;
- Status GetUnsyncedCommitIds(coroutine::CoroutineHandler* handler,
- std::vector<CommitId>* commit_ids) override;
- Status IsCommitSynced(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id, bool* is_synced) override;
- Status GetUnsyncedPieces(
- coroutine::CoroutineHandler* handler,
- std::vector<ObjectIdentifier>* object_identifiers) override;
- Status GetObjectStatus(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- PageDbObjectStatus* object_status) override;
- Status GetSyncMetadata(coroutine::CoroutineHandler* handler,
- fxl::StringView key, std::string* value) override;
-
- Status IsPageOnline(coroutine::CoroutineHandler* handler,
- bool* page_is_online) override;
-
- Status AddHead(coroutine::CoroutineHandler* handler, CommitIdView head,
- zx::time_utc timestamp) override;
- Status RemoveHead(coroutine::CoroutineHandler* handler,
- CommitIdView head) override;
- Status AddCommitStorageBytes(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id,
- fxl::StringView storage_bytes) override;
- Status RemoveCommit(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id) override;
- Status CreateJournalId(coroutine::CoroutineHandler* handler,
- JournalType journal_type, const CommitId& base,
- JournalId* journal) override;
- Status RemoveExplicitJournals(coroutine::CoroutineHandler* handler) override;
- Status RemoveJournal(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id) override;
- Status AddJournalEntry(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id, fxl::StringView key,
- const ObjectIdentifier& object_identifier,
- KeyPriority priority) override;
- Status RemoveJournalEntry(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id,
- convert::ExtendedStringView key) override;
- Status EmptyJournalAndMarkContainsClearOperation(
- coroutine::CoroutineHandler* handler,
- const JournalId& journal_id) override;
- Status WriteObject(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- std::unique_ptr<DataSource::DataChunk> content,
- PageDbObjectStatus object_status) override;
- Status MarkCommitIdSynced(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id) override;
- Status MarkCommitIdUnsynced(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id,
- uint64_t generation) override;
- Status SetObjectStatus(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- PageDbObjectStatus object_status) override;
- Status SetSyncMetadata(coroutine::CoroutineHandler* handler,
- fxl::StringView key, fxl::StringView value) override;
-
- Status MarkPageOnline(coroutine::CoroutineHandler* handler) override;
-
- // PageDb::Batch:
- Status Execute(coroutine::CoroutineHandler* handler) override;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_EMPTY_IMPL_H_
diff --git a/bin/ledger/storage/impl/page_db_impl.cc b/bin/ledger/storage/impl/page_db_impl.cc
deleted file mode 100644
index f425c04..0000000
--- a/bin/ledger/storage/impl/page_db_impl.cc
+++ /dev/null
@@ -1,423 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/page_db_impl.h"
-
-#include <algorithm>
-#include <string>
-
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/bin/ledger/storage/impl/data_serialization.h"
-#include "peridot/bin/ledger/storage/impl/db_serialization.h"
-#include "peridot/bin/ledger/storage/impl/journal_impl.h"
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-#include "peridot/bin/ledger/storage/impl/object_impl.h"
-#include "peridot/bin/ledger/storage/impl/page_db_batch_impl.h"
-#include "peridot/lib/convert/convert.h"
-
-#define RETURN_ON_ERROR(expr) \
- do { \
- Status status = (expr); \
- if (status != Status::OK) { \
- return status; \
- } \
- } while (0)
-
-namespace storage {
-
-using coroutine::CoroutineHandler;
-
-namespace {
-
-// Extracts a sorted list of commit its from |entries|. Entries must be a map
-// from commit ids to serialized |A|.
-template <typename A>
-void ExtractSortedCommitsIds(
- std::vector<std::pair<std::string, std::string>>* entries,
- std::vector<CommitId>* commit_ids) {
- std::sort(entries->begin(), entries->end(),
- [&](const std::pair<std::string, std::string>& p1,
- const std::pair<std::string, std::string>& p2) {
- auto t1 = DeserializeData<A>(p1.second);
- auto t2 = DeserializeData<A>(p2.second);
- if (t1 != t2) {
- return t1 < t2;
- }
- return p1.first < p2.first;
- });
- commit_ids->clear();
- commit_ids->reserve(entries->size());
- for (std::pair<std::string, std::string>& entry : *entries) {
- commit_ids->push_back(std::move(entry.first));
- }
-}
-
-class JournalEntryIterator final : public Iterator<const EntryChange> {
- public:
- explicit JournalEntryIterator(
- std::unique_ptr<Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>>
- it)
- : it_(std::move(it)) {
- PrepareEntry();
- }
-
- ~JournalEntryIterator() override {}
-
- Iterator<const EntryChange>& Next() override {
- it_->Next();
- PrepareEntry();
- return *this;
- }
-
- bool Valid() const override { return it_->Valid(); }
-
- Status GetStatus() const override { return it_->GetStatus(); }
-
- const EntryChange& operator*() const override { return *(change_.get()); }
- const EntryChange* operator->() const override { return change_.get(); }
-
- private:
- void PrepareEntry() {
- if (!JournalEntryIterator::Valid()) {
- change_.reset(nullptr);
- return;
- }
- change_ = std::make_unique<EntryChange>();
-
- const std::pair<convert::ExtendedStringView, convert::ExtendedStringView>&
- key_value = **it_;
- change_->entry.key =
- key_value.first.substr(JournalEntryRow::kPrefixSize).ToString();
-
- if (key_value.second[0] == JournalEntryRow::kAddPrefix) {
- Status status = JournalEntryRow::ExtractObjectIdentifier(
- key_value.second, &change_->entry.object_identifier);
- FXL_DCHECK(status == Status::OK);
- change_->deleted = false;
- change_->entry.priority =
- (key_value.second[1] == JournalEntryRow::kLazyPrefix)
- ? KeyPriority::LAZY
- : KeyPriority::EAGER;
- } else {
- change_->deleted = true;
- }
- }
-
- std::unique_ptr<Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>>
- it_;
-
- std::unique_ptr<EntryChange> change_;
-};
-
-} // namespace
-
-PageDbImpl::PageDbImpl(ledger::Environment* environment, std::unique_ptr<Db> db)
- : environment_(environment), db_(std::move(db)) {
- FXL_DCHECK(environment_);
- FXL_DCHECK(db_);
-}
-
-PageDbImpl::~PageDbImpl() {}
-
-Status PageDbImpl::StartBatch(coroutine::CoroutineHandler* handler,
- std::unique_ptr<Batch>* batch) {
- std::unique_ptr<Db::Batch> db_batch;
- RETURN_ON_ERROR(db_->StartBatch(handler, &db_batch));
- *batch = std::make_unique<PageDbBatchImpl>(environment_->random(),
- std::move(db_batch), this);
- return Status::OK;
-}
-
-Status PageDbImpl::GetHeads(CoroutineHandler* handler,
- std::vector<CommitId>* heads) {
- std::vector<std::pair<std::string, std::string>> entries;
- RETURN_ON_ERROR(db_->GetEntriesByPrefix(
- handler, convert::ToSlice(HeadRow::kPrefix), &entries));
- ExtractSortedCommitsIds<zx::time_utc>(&entries, heads);
- return Status::OK;
-}
-
-Status PageDbImpl::GetCommitStorageBytes(CoroutineHandler* handler,
- CommitIdView commit_id,
- std::string* storage_bytes) {
- return db_->Get(handler, CommitRow::GetKeyFor(commit_id), storage_bytes);
-}
-
-Status PageDbImpl::GetImplicitJournalIds(CoroutineHandler* handler,
- std::vector<JournalId>* journal_ids) {
- return db_->GetByPrefix(handler,
- convert::ToSlice(ImplicitJournalMetadataRow::kPrefix),
- journal_ids);
-}
-
-Status PageDbImpl::GetBaseCommitForJournal(CoroutineHandler* handler,
- const JournalId& journal_id,
- CommitId* base) {
- FXL_DCHECK(journal_id.size() == JournalEntryRow::kJournalIdSize);
- FXL_DCHECK(journal_id[0] == JournalEntryRow::kImplicitPrefix);
- return db_->Get(handler, ImplicitJournalMetadataRow::GetKeyFor(journal_id),
- base);
-}
-
-Status PageDbImpl::GetJournalEntries(
- CoroutineHandler* handler, const JournalId& journal_id,
- std::unique_ptr<Iterator<const EntryChange>>* entries,
- JournalContainsClearOperation* contains_clear_operation) {
- std::unique_ptr<Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>>
- it;
- RETURN_ON_ERROR(db_->GetIteratorAtPrefix(
- handler, JournalEntryRow::GetEntriesPrefixFor(journal_id), &it));
- bool contains_clear_operation_key;
- RETURN_ON_ERROR(db_->HasKey(handler,
- JournalEntryRow::GetClearMarkerKey(journal_id),
- &contains_clear_operation_key));
-
- *entries = std::make_unique<JournalEntryIterator>(std::move(it));
- *contains_clear_operation = contains_clear_operation_key
- ? JournalContainsClearOperation::YES
- : JournalContainsClearOperation::NO;
- return Status::OK;
-}
-
-Status PageDbImpl::ReadObject(CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) {
- return db_->GetObject(handler,
- ObjectRow::GetKeyFor(object_identifier.object_digest()),
- object_identifier, object);
-}
-
-Status PageDbImpl::HasObject(CoroutineHandler* handler,
- const ObjectDigest& object_digest,
- bool* has_object) {
- return db_->HasKey(handler, ObjectRow::GetKeyFor(object_digest), has_object);
-}
-
-Status PageDbImpl::GetObjectStatus(CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- PageDbObjectStatus* object_status) {
- // Check must be done in ascending order of status, so that a change of status
- // between 2 reads does not create the case where no key is found.
- // That said, the most common expected status is SYNCED, so for performance
- // reasons, it is better to check it first.
- // By checking it first and then checking all statuses in ascending order we
- // both ensure correctness and performant lookup.
- // The only case that would generate a spurious lookup is when the status is
- // changed concurrently, which is a rare occurence.
- for (PageDbObjectStatus possible_status :
- {PageDbObjectStatus::SYNCED, PageDbObjectStatus::TRANSIENT,
- PageDbObjectStatus::LOCAL, PageDbObjectStatus::SYNCED}) {
- bool has_key;
- RETURN_ON_ERROR(db_->HasKey(
- handler, ObjectStatusRow::GetKeyFor(possible_status, object_identifier),
- &has_key));
- if (has_key) {
- *object_status = possible_status;
- return Status::OK;
- }
- }
-
- *object_status = PageDbObjectStatus::UNKNOWN;
- return Status::OK;
-}
-
-Status PageDbImpl::GetUnsyncedCommitIds(CoroutineHandler* handler,
- std::vector<CommitId>* commit_ids) {
- std::vector<std::pair<std::string, std::string>> entries;
- RETURN_ON_ERROR(db_->GetEntriesByPrefix(
- handler, convert::ToSlice(UnsyncedCommitRow::kPrefix), &entries));
- // Unsynced commit row values are the commit's generation.
- ExtractSortedCommitsIds<uint64_t>(&entries, commit_ids);
- return Status::OK;
-}
-
-Status PageDbImpl::IsCommitSynced(CoroutineHandler* handler,
- const CommitId& commit_id, bool* is_synced) {
- bool has_key;
- RETURN_ON_ERROR(
- db_->HasKey(handler, UnsyncedCommitRow::GetKeyFor(commit_id), &has_key));
- *is_synced = !has_key;
- return Status::OK;
-}
-
-Status PageDbImpl::GetUnsyncedPieces(
- CoroutineHandler* handler,
- std::vector<ObjectIdentifier>* object_identifiers) {
- std::vector<std::string> encoded_identifiers;
- Status status =
- db_->GetByPrefix(handler, convert::ToSlice(ObjectStatusRow::kLocalPrefix),
- &encoded_identifiers);
- if (status != Status::OK) {
- return status;
- }
-
- object_identifiers->clear();
- ObjectIdentifier object_identifier;
- for (auto& encoded_identifier : encoded_identifiers) {
- if (!DecodeObjectIdentifier(encoded_identifier, &object_identifier)) {
- return Status::FORMAT_ERROR;
- }
- object_identifiers->emplace_back(std::move(object_identifier));
- }
-
- return Status::OK;
-}
-
-Status PageDbImpl::GetSyncMetadata(CoroutineHandler* handler,
- fxl::StringView key, std::string* value) {
- return db_->Get(handler, SyncMetadataRow::GetKeyFor(key), value);
-}
-
-Status PageDbImpl::IsPageOnline(coroutine::CoroutineHandler* handler,
- bool* page_is_online) {
- return db_->HasKey(handler, PageIsOnlineRow::kKey, page_is_online);
-}
-
-Status PageDbImpl::AddHead(CoroutineHandler* handler, CommitIdView head,
- zx::time_utc timestamp) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->AddHead(handler, head, timestamp));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::RemoveHead(CoroutineHandler* handler, CommitIdView head) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->RemoveHead(handler, head));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::AddCommitStorageBytes(CoroutineHandler* handler,
- const CommitId& commit_id,
- fxl::StringView storage_bytes) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(
- batch->AddCommitStorageBytes(handler, commit_id, storage_bytes));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::RemoveCommit(CoroutineHandler* handler,
- const CommitId& commit_id) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->RemoveCommit(handler, commit_id));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::CreateJournalId(CoroutineHandler* handler,
- JournalType journal_type,
- const CommitId& base,
- JournalId* journal_id) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(
- batch->CreateJournalId(handler, journal_type, base, journal_id));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::RemoveExplicitJournals(CoroutineHandler* handler) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->RemoveExplicitJournals(handler));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::RemoveJournal(CoroutineHandler* handler,
- const JournalId& journal_id) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->RemoveJournal(handler, journal_id));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::AddJournalEntry(CoroutineHandler* handler,
- const JournalId& journal_id,
- fxl::StringView key,
- const ObjectIdentifier& object_identifier,
- KeyPriority priority) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->AddJournalEntry(handler, journal_id, key,
- object_identifier, priority));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::RemoveJournalEntry(CoroutineHandler* handler,
- const JournalId& journal_id,
- convert::ExtendedStringView key) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->RemoveJournalEntry(handler, journal_id, key));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::EmptyJournalAndMarkContainsClearOperation(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(
- batch->EmptyJournalAndMarkContainsClearOperation(handler, journal_id));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::WriteObject(CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- std::unique_ptr<DataSource::DataChunk> content,
- PageDbObjectStatus object_status) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->WriteObject(handler, object_identifier,
- std::move(content), object_status));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::SetObjectStatus(CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- PageDbObjectStatus object_status) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(
- batch->SetObjectStatus(handler, object_identifier, object_status));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::MarkCommitIdSynced(CoroutineHandler* handler,
- const CommitId& commit_id) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->MarkCommitIdSynced(handler, commit_id));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::MarkCommitIdUnsynced(CoroutineHandler* handler,
- const CommitId& commit_id,
- uint64_t generation) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->MarkCommitIdUnsynced(handler, commit_id, generation));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::SetSyncMetadata(CoroutineHandler* handler,
- fxl::StringView key, fxl::StringView value) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->SetSyncMetadata(handler, key, value));
- return batch->Execute(handler);
-}
-
-Status PageDbImpl::MarkPageOnline(coroutine::CoroutineHandler* handler) {
- std::unique_ptr<Batch> batch;
- RETURN_ON_ERROR(StartBatch(handler, &batch));
- RETURN_ON_ERROR(batch->MarkPageOnline(handler));
- return batch->Execute(handler);
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/page_db_impl.h b/bin/ledger/storage/impl/page_db_impl.h
deleted file mode 100644
index 79016c0..0000000
--- a/bin/ledger/storage/impl/page_db_impl.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_IMPL_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/storage/impl/page_db.h"
-#include "peridot/bin/ledger/storage/public/db.h"
-
-namespace storage {
-
-class PageStorageImpl;
-
-// TODO(qsr): LE-250 There must be a mechanism to clean the database from
-// TRANSIENT objects.
-class PageDbImpl : public PageDb {
- public:
- PageDbImpl(ledger::Environment* environment, std::unique_ptr<Db> db);
- ~PageDbImpl() override;
-
- Status StartBatch(coroutine::CoroutineHandler* handler,
- std::unique_ptr<PageDb::Batch>* batch) override;
- Status GetHeads(coroutine::CoroutineHandler* handler,
- std::vector<CommitId>* heads) override;
- Status GetCommitStorageBytes(coroutine::CoroutineHandler* handler,
- CommitIdView commit_id,
- std::string* storage_bytes) override;
- Status GetImplicitJournalIds(coroutine::CoroutineHandler* handler,
- std::vector<JournalId>* journal_ids) override;
- Status GetBaseCommitForJournal(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id,
- CommitId* base) override;
- Status GetJournalEntries(
- coroutine::CoroutineHandler* handler, const JournalId& journal_id,
- std::unique_ptr<Iterator<const EntryChange>>* entries,
- JournalContainsClearOperation* contains_clear_operation) override;
- Status ReadObject(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) override;
- Status HasObject(coroutine::CoroutineHandler* handler,
- const ObjectDigest& object_digest,
- bool* has_object) override;
- Status GetUnsyncedCommitIds(coroutine::CoroutineHandler* handler,
- std::vector<CommitId>* commit_ids) override;
- Status IsCommitSynced(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id, bool* is_synced) override;
- Status GetUnsyncedPieces(
- coroutine::CoroutineHandler* handler,
- std::vector<ObjectIdentifier>* object_identifiers) override;
- Status GetObjectStatus(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- PageDbObjectStatus* object_status) override;
- Status GetSyncMetadata(coroutine::CoroutineHandler* handler,
- fxl::StringView key, std::string* value) override;
- Status IsPageOnline(coroutine::CoroutineHandler* handler,
- bool* page_is_online) override;
-
- Status AddHead(coroutine::CoroutineHandler* handler, CommitIdView head,
- zx::time_utc timestamp) override;
- Status RemoveHead(coroutine::CoroutineHandler* handler,
- CommitIdView head) override;
- Status AddCommitStorageBytes(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id,
- fxl::StringView storage_bytes) override;
- Status RemoveCommit(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id) override;
- Status CreateJournalId(coroutine::CoroutineHandler* handler,
- JournalType journal_type, const CommitId& base,
- JournalId* journal_id) override;
- Status RemoveExplicitJournals(coroutine::CoroutineHandler* handler) override;
- Status RemoveJournal(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id) override;
- Status AddJournalEntry(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id, fxl::StringView key,
- const ObjectIdentifier& object_identifier,
- KeyPriority priority) override;
- Status RemoveJournalEntry(coroutine::CoroutineHandler* handler,
- const JournalId& journal_id,
- convert::ExtendedStringView key) override;
- Status EmptyJournalAndMarkContainsClearOperation(
- coroutine::CoroutineHandler* handler,
- const JournalId& journal_id) override;
- Status WriteObject(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- std::unique_ptr<DataSource::DataChunk> content,
- PageDbObjectStatus object_status) override;
- Status MarkCommitIdSynced(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id) override;
- Status MarkCommitIdUnsynced(coroutine::CoroutineHandler* handler,
- const CommitId& commit_id,
- uint64_t generation) override;
- Status SetObjectStatus(coroutine::CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- PageDbObjectStatus object_status) override;
- Status SetSyncMetadata(coroutine::CoroutineHandler* handler,
- fxl::StringView key, fxl::StringView value) override;
- Status MarkPageOnline(coroutine::CoroutineHandler* handler) override;
-
- private:
- ledger::Environment* environment_;
- std::unique_ptr<Db> db_;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_DB_IMPL_H_
diff --git a/bin/ledger/storage/impl/page_db_unittest.cc b/bin/ledger/storage/impl/page_db_unittest.cc
deleted file mode 100644
index b920b08..0000000
--- a/bin/ledger/storage/impl/page_db_unittest.cc
+++ /dev/null
@@ -1,562 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/page_db.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fxl/macros.h>
-#include <lib/zx/time.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/impl/commit_impl.h"
-#include "peridot/bin/ledger/storage/impl/commit_random_impl.h"
-#include "peridot/bin/ledger/storage/impl/journal_impl.h"
-#include "peridot/bin/ledger/storage/impl/leveldb.h"
-#include "peridot/bin/ledger/storage/impl/page_db_impl.h"
-#include "peridot/bin/ledger/storage/impl/page_storage_impl.h"
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace storage {
-namespace {
-
-using coroutine::CoroutineHandler;
-
-void ExpectChangesEqual(const EntryChange& expected, const EntryChange& found) {
- EXPECT_EQ(expected.deleted, found.deleted);
- EXPECT_EQ(expected.entry.key, found.entry.key);
- if (!expected.deleted) {
- // If the entry is deleted, object_identifier and priority are not valid.
- EXPECT_EQ(expected.entry, found.entry);
- }
-}
-
-std::unique_ptr<LevelDb> GetLevelDb(async_dispatcher_t* dispatcher,
- ledger::DetachedPath db_path) {
- auto db = std::make_unique<LevelDb>(dispatcher, std::move(db_path));
- EXPECT_EQ(Status::OK, db->Init());
- return db;
-}
-
-class PageDbTest : public ledger::TestWithEnvironment {
- public:
- PageDbTest()
- : encryption_service_(dispatcher()),
- base_path(tmpfs_.root_fd()),
- page_storage_(&environment_, &encryption_service_,
- GetLevelDb(dispatcher(), base_path.SubPath("storage")),
- "page_id"),
- page_db_(&environment_,
- GetLevelDb(dispatcher(), base_path.SubPath("page_db"))) {}
-
- ~PageDbTest() override {}
-
- // Test:
- void SetUp() override {
- std::srand(0);
-
- Status status;
- bool called;
- page_storage_.Init(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- }
-
- protected:
- scoped_tmpfs::ScopedTmpFS tmpfs_;
- encryption::FakeEncryptionService encryption_service_;
- ledger::DetachedPath base_path;
- PageStorageImpl page_storage_;
- PageDbImpl page_db_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageDbTest);
-};
-
-TEST_F(PageDbTest, HeadCommits) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- std::vector<CommitId> heads;
- EXPECT_EQ(Status::OK, page_db_.GetHeads(handler, &heads));
- EXPECT_TRUE(heads.empty());
-
- CommitId cid = RandomCommitId(environment_.random());
- EXPECT_EQ(Status::OK,
- page_db_.AddHead(handler, cid,
- environment_.random()->Draw<zx::time_utc>()));
- EXPECT_EQ(Status::OK, page_db_.GetHeads(handler, &heads));
- EXPECT_EQ(1u, heads.size());
- EXPECT_EQ(cid, heads[0]);
-
- EXPECT_EQ(Status::OK, page_db_.RemoveHead(handler, cid));
- EXPECT_EQ(Status::OK, page_db_.GetHeads(handler, &heads));
- EXPECT_TRUE(heads.empty());
- });
-}
-
-TEST_F(PageDbTest, OrderHeadCommitsByTimestamp) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- std::vector<zx::time_utc> timestamps = {zx::time_utc::infinite_past(),
- zx::time_utc::infinite(),
- zx::time_utc()};
-
- for (size_t i = 0; i < 10; ++i) {
- zx::time_utc ts;
- do {
- ts = environment_.random()->Draw<zx::time_utc>();
- } while (std::find(timestamps.begin(), timestamps.end(), ts) !=
- timestamps.end());
- timestamps.push_back(ts);
- }
-
- auto sorted_timestamps = timestamps;
- std::sort(sorted_timestamps.begin(), sorted_timestamps.end());
- auto random_ordered_timestamps = timestamps;
- auto rng = environment_.random()->NewBitGenerator<uint64_t>();
- std::shuffle(random_ordered_timestamps.begin(),
- random_ordered_timestamps.end(), rng);
-
- std::map<zx::time_utc, CommitId> commits;
- for (auto ts : random_ordered_timestamps) {
- commits[ts] = RandomCommitId(environment_.random());
- EXPECT_EQ(Status::OK, page_db_.AddHead(handler, commits[ts], ts));
- }
-
- std::vector<CommitId> heads;
- EXPECT_EQ(Status::OK, page_db_.GetHeads(handler, &heads));
- EXPECT_EQ(timestamps.size(), heads.size());
-
- for (size_t i = 0; i < heads.size(); ++i) {
- EXPECT_EQ(commits[sorted_timestamps[i]], heads[i]);
- }
- });
-}
-
-TEST_F(PageDbTest, Commits) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- std::vector<std::unique_ptr<const Commit>> parents;
- parents.emplace_back(
- std::make_unique<CommitRandomImpl>(environment_.random()));
-
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), &page_storage_,
- RandomObjectIdentifier(environment_.random()), std::move(parents));
-
- std::string storage_bytes;
- EXPECT_EQ(Status::NOT_FOUND, page_db_.GetCommitStorageBytes(
- handler, commit->GetId(), &storage_bytes));
-
- EXPECT_EQ(Status::OK,
- page_db_.AddCommitStorageBytes(handler, commit->GetId(),
- commit->GetStorageBytes()));
- EXPECT_EQ(Status::OK, page_db_.GetCommitStorageBytes(
- handler, commit->GetId(), &storage_bytes));
- EXPECT_EQ(storage_bytes, commit->GetStorageBytes());
-
- EXPECT_EQ(Status::OK, page_db_.RemoveCommit(handler, commit->GetId()));
- EXPECT_EQ(Status::NOT_FOUND, page_db_.GetCommitStorageBytes(
- handler, commit->GetId(), &storage_bytes));
- });
-}
-
-TEST_F(PageDbTest, Journals) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- CommitId commit_id = RandomCommitId(environment_.random());
-
- JournalId implicit_journal_id;
- JournalId explicit_journal_id;
- std::unique_ptr<Journal> explicit_journal;
- EXPECT_EQ(Status::OK,
- page_db_.CreateJournalId(handler, JournalType::IMPLICIT,
- commit_id, &implicit_journal_id));
- EXPECT_EQ(Status::OK,
- page_db_.CreateJournalId(handler, JournalType::EXPLICIT,
- commit_id, &explicit_journal_id));
-
- EXPECT_EQ(Status::OK, page_db_.RemoveExplicitJournals(handler));
-
- // Removing explicit journals should not affect the implicit ones.
- std::vector<JournalId> journal_ids;
- EXPECT_EQ(Status::OK,
- page_db_.GetImplicitJournalIds(handler, &journal_ids));
- ASSERT_EQ(1u, journal_ids.size());
- EXPECT_EQ(implicit_journal_id, journal_ids[0]);
-
- CommitId found_base_id;
- EXPECT_EQ(Status::OK, page_db_.GetBaseCommitForJournal(
- handler, journal_ids[0], &found_base_id));
- EXPECT_EQ(commit_id, found_base_id);
- EXPECT_EQ(Status::OK, page_db_.RemoveJournal(handler, journal_ids[0]));
- EXPECT_EQ(Status::NOT_FOUND, page_db_.GetBaseCommitForJournal(
- handler, journal_ids[0], &found_base_id));
- EXPECT_EQ(Status::OK,
- page_db_.GetImplicitJournalIds(handler, &journal_ids));
- EXPECT_EQ(0u, journal_ids.size());
- });
-}
-
-TEST_F(PageDbTest, JournalEntries) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- CommitId commit_id = RandomCommitId(environment_.random());
-
- JournalId journal_id;
- EXPECT_EQ(Status::OK,
- page_db_.CreateJournalId(handler, JournalType::IMPLICIT,
- commit_id, &journal_id));
- EXPECT_EQ(Status::OK,
- page_db_.AddJournalEntry(handler, journal_id, "add-key-1",
- MakeObjectIdentifier("value1"),
- KeyPriority::LAZY));
- EXPECT_EQ(Status::OK,
- page_db_.AddJournalEntry(handler, journal_id, "add-key-2",
- MakeObjectIdentifier("value2"),
- KeyPriority::EAGER));
- EXPECT_EQ(Status::OK,
- page_db_.AddJournalEntry(handler, journal_id, "add-key-1",
- MakeObjectIdentifier("value3"),
- KeyPriority::LAZY));
- EXPECT_EQ(Status::OK,
- page_db_.RemoveJournalEntry(handler, journal_id, "remove-key"));
-
- EntryChange expected_changes[] = {
- NewEntryChange("add-key-1", "value3", KeyPriority::LAZY),
- NewEntryChange("add-key-2", "value2", KeyPriority::EAGER),
- NewRemoveEntryChange("remove-key"),
- };
- std::unique_ptr<Iterator<const EntryChange>> entries;
- JournalContainsClearOperation contains_clear_operation;
- EXPECT_EQ(Status::OK,
- page_db_.GetJournalEntries(handler, journal_id, &entries,
- &contains_clear_operation));
- for (const auto& expected_change : expected_changes) {
- EXPECT_TRUE(entries->Valid());
- ExpectChangesEqual(expected_change, **entries);
- entries->Next();
- }
- EXPECT_FALSE(entries->Valid());
- EXPECT_EQ(JournalContainsClearOperation::NO, contains_clear_operation);
- EXPECT_EQ(Status::OK, entries->GetStatus());
- });
-}
-
-TEST_F(PageDbTest, JournalEntriesWithClear) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- CommitId commit_id = RandomCommitId(environment_.random());
-
- JournalId journal_id;
- EXPECT_EQ(Status::OK,
- page_db_.CreateJournalId(handler, JournalType::IMPLICIT,
- commit_id, &journal_id));
- EXPECT_EQ(Status::OK,
- page_db_.AddJournalEntry(handler, journal_id, "add-key-1",
- MakeObjectIdentifier("value1"),
- KeyPriority::LAZY));
- EXPECT_EQ(Status::OK, page_db_.EmptyJournalAndMarkContainsClearOperation(
- handler, journal_id));
- EXPECT_EQ(Status::OK,
- page_db_.AddJournalEntry(handler, journal_id, "add-key-2",
- MakeObjectIdentifier("value2"),
- KeyPriority::EAGER));
- EXPECT_EQ(Status::OK,
- page_db_.RemoveJournalEntry(handler, journal_id, "remove-key"));
-
- EntryChange expected_changes[] = {
- NewEntryChange("add-key-2", "value2", KeyPriority::EAGER),
- NewRemoveEntryChange("remove-key"),
- };
- std::unique_ptr<Iterator<const EntryChange>> entries;
- JournalContainsClearOperation contains_clear_operation;
- EXPECT_EQ(Status::OK,
- page_db_.GetJournalEntries(handler, journal_id, &entries,
- &contains_clear_operation));
- for (const auto& expected_change : expected_changes) {
- EXPECT_TRUE(entries->Valid());
- ExpectChangesEqual(expected_change, **entries);
- entries->Next();
- }
- EXPECT_FALSE(entries->Valid());
- EXPECT_EQ(JournalContainsClearOperation::YES, contains_clear_operation);
- EXPECT_EQ(Status::OK, entries->GetStatus());
- });
-}
-
-TEST_F(PageDbTest, ObjectStorage) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- ObjectIdentifier object_identifier =
- RandomObjectIdentifier(environment_.random());
- std::string content = RandomString(environment_.random(), 32 * 1024);
- std::unique_ptr<const Object> object;
- PageDbObjectStatus object_status;
-
- EXPECT_EQ(Status::NOT_FOUND,
- page_db_.ReadObject(handler, object_identifier, &object));
- ASSERT_EQ(Status::OK,
- page_db_.WriteObject(handler, object_identifier,
- DataSource::DataChunk::Create(content),
- PageDbObjectStatus::TRANSIENT));
- page_db_.GetObjectStatus(handler, object_identifier, &object_status);
- EXPECT_EQ(PageDbObjectStatus::TRANSIENT, object_status);
- ASSERT_EQ(Status::OK,
- page_db_.ReadObject(handler, object_identifier, &object));
- fxl::StringView object_content;
- EXPECT_EQ(Status::OK, object->GetData(&object_content));
- EXPECT_EQ(content, object_content);
- // Update the object to LOCAL. The new content should be ignored.
- std::string new_content = RandomString(environment_.random(), 32 * 1024);
- ASSERT_EQ(Status::OK,
- page_db_.WriteObject(handler, object_identifier,
- DataSource::DataChunk::Create(new_content),
- PageDbObjectStatus::LOCAL));
- page_db_.GetObjectStatus(handler, object_identifier, &object_status);
- EXPECT_EQ(PageDbObjectStatus::LOCAL, object_status);
- EXPECT_EQ(Status::OK, object->GetData(&object_content));
- EXPECT_EQ(content, object_content);
- EXPECT_NE(new_content, object_content);
- });
-}
-
-TEST_F(PageDbTest, UnsyncedCommits) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- CommitId commit_id = RandomCommitId(environment_.random());
- std::vector<CommitId> commit_ids;
- EXPECT_EQ(Status::OK, page_db_.GetUnsyncedCommitIds(handler, &commit_ids));
- EXPECT_TRUE(commit_ids.empty());
-
- EXPECT_EQ(Status::OK, page_db_.MarkCommitIdUnsynced(handler, commit_id, 0));
- EXPECT_EQ(Status::OK, page_db_.GetUnsyncedCommitIds(handler, &commit_ids));
- EXPECT_EQ(1u, commit_ids.size());
- EXPECT_EQ(commit_id, commit_ids[0]);
- bool is_synced;
- EXPECT_EQ(Status::OK,
- page_db_.IsCommitSynced(handler, commit_id, &is_synced));
- EXPECT_FALSE(is_synced);
-
- EXPECT_EQ(Status::OK, page_db_.MarkCommitIdSynced(handler, commit_id));
- EXPECT_EQ(Status::OK, page_db_.GetUnsyncedCommitIds(handler, &commit_ids));
- EXPECT_TRUE(commit_ids.empty());
- EXPECT_EQ(Status::OK,
- page_db_.IsCommitSynced(handler, commit_id, &is_synced));
- EXPECT_TRUE(is_synced);
- });
-}
-
-TEST_F(PageDbTest, OrderUnsyncedCommitsByTimestamp) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- CommitId commit_ids[] = {RandomCommitId(environment_.random()),
- RandomCommitId(environment_.random()),
- RandomCommitId(environment_.random())};
- // Add three unsynced commits with timestamps 200, 300 and 100.
- EXPECT_EQ(Status::OK,
- page_db_.MarkCommitIdUnsynced(handler, commit_ids[0], 200));
- EXPECT_EQ(Status::OK,
- page_db_.MarkCommitIdUnsynced(handler, commit_ids[1], 300));
- EXPECT_EQ(Status::OK,
- page_db_.MarkCommitIdUnsynced(handler, commit_ids[2], 100));
-
- // The result should be ordered by the given timestamps.
- std::vector<CommitId> found_ids;
- EXPECT_EQ(Status::OK, page_db_.GetUnsyncedCommitIds(handler, &found_ids));
- EXPECT_EQ(3u, found_ids.size());
- EXPECT_EQ(found_ids[0], commit_ids[2]);
- EXPECT_EQ(found_ids[1], commit_ids[0]);
- EXPECT_EQ(found_ids[2], commit_ids[1]);
- });
-}
-
-TEST_F(PageDbTest, UnsyncedPieces) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- auto object_identifier = RandomObjectIdentifier(environment_.random());
- std::vector<ObjectIdentifier> object_identifiers;
- EXPECT_EQ(Status::OK,
- page_db_.GetUnsyncedPieces(handler, &object_identifiers));
- EXPECT_TRUE(object_identifiers.empty());
-
- EXPECT_EQ(Status::OK,
- page_db_.WriteObject(handler, object_identifier,
- DataSource::DataChunk::Create(""),
- PageDbObjectStatus::LOCAL));
- EXPECT_EQ(Status::OK, page_db_.SetObjectStatus(handler, object_identifier,
- PageDbObjectStatus::LOCAL));
- EXPECT_EQ(Status::OK,
- page_db_.GetUnsyncedPieces(handler, &object_identifiers));
- EXPECT_EQ(1u, object_identifiers.size());
- EXPECT_EQ(object_identifier, object_identifiers[0]);
- PageDbObjectStatus object_status;
- EXPECT_EQ(Status::OK, page_db_.GetObjectStatus(handler, object_identifier,
- &object_status));
- EXPECT_EQ(PageDbObjectStatus::LOCAL, object_status);
-
- EXPECT_EQ(Status::OK, page_db_.SetObjectStatus(handler, object_identifier,
- PageDbObjectStatus::SYNCED));
- EXPECT_EQ(Status::OK,
- page_db_.GetUnsyncedPieces(handler, &object_identifiers));
- EXPECT_TRUE(object_identifiers.empty());
- EXPECT_EQ(Status::OK, page_db_.GetObjectStatus(handler, object_identifier,
- &object_status));
- EXPECT_EQ(PageDbObjectStatus::SYNCED, object_status);
- });
-}
-
-TEST_F(PageDbTest, Batch) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- std::unique_ptr<PageDb::Batch> batch;
- ASSERT_EQ(Status::OK, page_db_.StartBatch(handler, &batch));
- ASSERT_TRUE(batch);
-
- auto object_identifier = RandomObjectIdentifier(environment_.random());
- EXPECT_EQ(Status::OK, batch->WriteObject(handler, object_identifier,
- DataSource::DataChunk::Create(""),
- PageDbObjectStatus::LOCAL));
-
- std::vector<ObjectIdentifier> object_identifiers;
- EXPECT_EQ(Status::OK,
- page_db_.GetUnsyncedPieces(handler, &object_identifiers));
- EXPECT_TRUE(object_identifiers.empty());
-
- EXPECT_EQ(Status::OK, batch->Execute(handler));
-
- EXPECT_EQ(Status::OK,
- page_db_.GetUnsyncedPieces(handler, &object_identifiers));
- EXPECT_EQ(1u, object_identifiers.size());
- EXPECT_EQ(object_identifier, object_identifiers[0]);
- });
-}
-
-TEST_F(PageDbTest, PageDbObjectStatus) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- PageDbObjectStatus initial_statuses[] = {PageDbObjectStatus::TRANSIENT,
- PageDbObjectStatus::LOCAL,
- PageDbObjectStatus::SYNCED};
- PageDbObjectStatus next_statuses[] = {PageDbObjectStatus::LOCAL,
- PageDbObjectStatus::SYNCED};
- for (auto initial_status : initial_statuses) {
- for (auto next_status : next_statuses) {
- auto object_identifier = RandomObjectIdentifier(environment_.random());
- PageDbObjectStatus object_status;
- ASSERT_EQ(Status::OK, page_db_.GetObjectStatus(
- handler, object_identifier, &object_status));
- EXPECT_EQ(PageDbObjectStatus::UNKNOWN, object_status);
- ASSERT_EQ(Status::OK,
- page_db_.WriteObject(handler, object_identifier,
- DataSource::DataChunk::Create(""),
- initial_status));
- ASSERT_EQ(Status::OK, page_db_.GetObjectStatus(
- handler, object_identifier, &object_status));
- EXPECT_EQ(initial_status, object_status);
- ASSERT_EQ(Status::OK, page_db_.SetObjectStatus(
- handler, object_identifier, next_status));
-
- PageDbObjectStatus expected_status =
- std::max(initial_status, next_status);
- ASSERT_EQ(Status::OK, page_db_.GetObjectStatus(
- handler, object_identifier, &object_status));
- EXPECT_EQ(expected_status, object_status);
- }
- }
- });
-}
-
-TEST_F(PageDbTest, SyncMetadata) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- std::vector<std::pair<fxl::StringView, fxl::StringView>> keys_and_values = {
- {"foo1", "foo2"}, {"bar1", " bar2 "}};
- for (const auto& key_and_value : keys_and_values) {
- auto key = key_and_value.first;
- auto value = key_and_value.second;
- std::string returned_value;
- EXPECT_EQ(Status::NOT_FOUND,
- page_db_.GetSyncMetadata(handler, key, &returned_value));
-
- EXPECT_EQ(Status::OK, page_db_.SetSyncMetadata(handler, key, value));
- EXPECT_EQ(Status::OK,
- page_db_.GetSyncMetadata(handler, key, &returned_value));
- EXPECT_EQ(value, returned_value);
- }
- });
-}
-
-TEST_F(PageDbTest, PageIsOnline) {
- RunInCoroutine([&](CoroutineHandler* handler) {
- bool page_is_online;
-
- // Check that the initial state is not online.
- page_db_.IsPageOnline(handler, &page_is_online);
- EXPECT_FALSE(page_is_online);
-
- // Mark page as online and check it was updated.
- EXPECT_EQ(Status::OK, page_db_.MarkPageOnline(handler));
- page_db_.IsPageOnline(handler, &page_is_online);
- EXPECT_TRUE(page_is_online);
- });
-}
-
-// This test reproduces the crash of LE-451. The crash is due to a subtle
-// ordering of coroutine execution that is exactly reproduced here.
-TEST_F(PageDbTest, LE_451_ReproductionTest) {
- auto id = RandomObjectIdentifier(environment_.random());
- RunInCoroutine([&](CoroutineHandler* handler) {
- EXPECT_EQ(Status::OK, page_db_.WriteObject(
- handler, id, DataSource::DataChunk::Create(""),
- PageDbObjectStatus::LOCAL));
- });
- CoroutineHandler* handler1 = nullptr;
- CoroutineHandler* handler2 = nullptr;
- environment_.coroutine_service()->StartCoroutine(
- [&](CoroutineHandler* handler) {
- handler1 = handler;
- std::unique_ptr<PageDb::Batch> batch;
- EXPECT_EQ(Status::OK, page_db_.StartBatch(handler, &batch));
- EXPECT_EQ(Status::OK, batch->SetObjectStatus(
- handler, id, PageDbObjectStatus::SYNCED));
- if (handler->Yield() == coroutine::ContinuationStatus::INTERRUPTED) {
- return;
- }
- EXPECT_EQ(Status::OK, batch->Execute(handler));
- handler1 = nullptr;
- });
- environment_.coroutine_service()->StartCoroutine(
- [&](CoroutineHandler* handler) {
- handler2 = handler;
- std::unique_ptr<PageDb::Batch> batch;
- EXPECT_EQ(Status::OK, page_db_.StartBatch(handler, &batch));
- if (handler->Yield() == coroutine::ContinuationStatus::INTERRUPTED) {
- return;
- }
- EXPECT_EQ(Status::OK, batch->SetObjectStatus(
- handler, id, PageDbObjectStatus::LOCAL));
- EXPECT_EQ(Status::OK, batch->Execute(handler));
- handler2 = nullptr;
- });
- ASSERT_TRUE(handler1);
- ASSERT_TRUE(handler2);
-
- // Reach the 2 yield points.
- RunLoopUntilIdle();
-
- // Posting a task at this level ensures that the right interleaving between
- // reading and writing object status happens.
- async::PostTask(dispatcher(),
- [&] { handler1->Resume(coroutine::ContinuationStatus::OK); });
- handler2->Resume(coroutine::ContinuationStatus::OK);
-
- // Finish the test.
- RunLoopUntilIdle();
-
- // Ensures both coroutines are terminated.
- ASSERT_FALSE(handler1);
- ASSERT_FALSE(handler2);
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/impl/page_storage_impl.cc b/bin/ledger/storage/impl/page_storage_impl.cc
deleted file mode 100644
index fe3d9d7..0000000
--- a/bin/ledger/storage/impl/page_storage_impl.cc
+++ /dev/null
@@ -1,1541 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/page_storage_impl.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <algorithm>
-#include <iterator>
-#include <map>
-#include <set>
-#include <utility>
-
-#include <lib/callback/trace_callback.h>
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/arraysize.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/file_descriptor.h>
-#include <lib/fxl/files/path.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/fxl/strings/concatenate.h>
-#include <lib/zx/vmar.h>
-#include <lib/zx/vmo.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/cobalt/cobalt.h"
-#include "peridot/bin/ledger/coroutine/coroutine_waiter.h"
-#include "peridot/bin/ledger/lock/lock.h"
-#include "peridot/bin/ledger/storage/impl/btree/diff.h"
-#include "peridot/bin/ledger/storage/impl/btree/iterator.h"
-#include "peridot/bin/ledger/storage/impl/commit_impl.h"
-#include "peridot/bin/ledger/storage/impl/constants.h"
-#include "peridot/bin/ledger/storage/impl/file_index.h"
-#include "peridot/bin/ledger/storage/impl/file_index_generated.h"
-#include "peridot/bin/ledger/storage/impl/journal_impl.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-#include "peridot/bin/ledger/storage/impl/object_impl.h"
-#include "peridot/bin/ledger/storage/impl/split.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-
-using coroutine::CoroutineHandler;
-
-namespace {
-
-struct StringPointerComparator {
- using is_transparent = std::true_type;
-
- bool operator()(const std::string* str1, const std::string* str2) const {
- return *str1 < *str2;
- }
-
- bool operator()(const std::string* str1, const CommitIdView* str2) const {
- return *str1 < *str2;
- }
-
- bool operator()(const CommitIdView* str1, const std::string* str2) const {
- return *str1 < *str2;
- }
-};
-
-size_t GetObjectPartStart(int64_t offset, size_t object_size) {
- size_t start = object_size;
- // Valid indices are between -N and N-1.
- if (offset >= -static_cast<int64_t>(object_size) &&
- offset < static_cast<int64_t>(object_size)) {
- start = offset < 0 ? object_size + offset : offset;
- }
- return start;
-}
-
-size_t GetObjectPartLength(int64_t max_size, size_t object_size, size_t start) {
- size_t adjusted_max_size = max_size < 0 ? object_size : max_size;
- return start > object_size ? 0
- : std::min(adjusted_max_size, object_size - start);
-}
-
-} // namespace
-
-PageStorageImpl::PageStorageImpl(
- ledger::Environment* environment,
- encryption::EncryptionService* encryption_service, std::unique_ptr<Db> db,
- PageId page_id)
- : PageStorageImpl(environment, encryption_service,
- std::make_unique<PageDbImpl>(environment, std::move(db)),
- std::move(page_id)) {}
-
-PageStorageImpl::PageStorageImpl(
- ledger::Environment* environment,
- encryption::EncryptionService* encryption_service,
- std::unique_ptr<PageDb> page_db, PageId page_id)
- : environment_(environment),
- encryption_service_(encryption_service),
- page_id_(std::move(page_id)),
- db_(std::move(page_db)),
- page_sync_(nullptr),
- coroutine_manager_(environment->coroutine_service()) {}
-
-PageStorageImpl::~PageStorageImpl() {}
-
-void PageStorageImpl::Init(fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this](CoroutineHandler* handler, fit::function<void(Status)> callback) {
- callback(SynchronousInit(handler));
- });
-}
-
-PageId PageStorageImpl::GetId() { return page_id_; }
-
-void PageStorageImpl::SetSyncDelegate(PageSyncDelegate* page_sync) {
- page_sync_ = page_sync;
-}
-
-void PageStorageImpl::GetHeadCommitIds(
- fit::function<void(Status, std::vector<CommitId>)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this](CoroutineHandler* handler,
- fit::function<void(Status, std::vector<CommitId>)> callback) {
- std::vector<CommitId> commit_ids;
- Status status = db_->GetHeads(handler, &commit_ids);
- callback(status, std::move(commit_ids));
- });
-}
-
-void PageStorageImpl::GetCommit(
- CommitIdView commit_id,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) {
- FXL_DCHECK(commit_id.size());
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, commit_id = commit_id.ToString()](
- CoroutineHandler* handler,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) {
- std::unique_ptr<const Commit> commit;
- Status status = SynchronousGetCommit(handler, commit_id, &commit);
- callback(status, std::move(commit));
- });
-}
-
-void PageStorageImpl::AddCommitFromLocal(
- std::unique_ptr<const Commit> commit,
- std::vector<ObjectIdentifier> new_objects,
- fit::function<void(Status)> callback) {
- FXL_DCHECK(IsDigestValid(commit->GetRootIdentifier().object_digest()));
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, commit = std::move(commit), new_objects = std::move(new_objects)](
- CoroutineHandler* handler,
- fit::function<void(Status)> callback) mutable {
- callback(SynchronousAddCommitFromLocal(handler, std::move(commit),
- std::move(new_objects)));
- });
-}
-
-void PageStorageImpl::AddCommitsFromSync(
- std::vector<CommitIdAndBytes> ids_and_bytes, ChangeSource source,
- fit::function<void(Status, std::vector<CommitId>)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, ids_and_bytes = std::move(ids_and_bytes), source](
- CoroutineHandler* handler,
- fit::function<void(Status, std::vector<CommitId>)> callback) mutable {
- std::vector<CommitId> missing_ids;
- Status status = SynchronousAddCommitsFromSync(
- handler, std::move(ids_and_bytes), source, &missing_ids);
- callback(status, std::move(missing_ids));
- });
-}
-
-void PageStorageImpl::StartCommit(
- const CommitId& commit_id, JournalType journal_type,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, commit_id, journal_type](
- CoroutineHandler* handler,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) {
- JournalId journal_id;
- Status status =
- db_->CreateJournalId(handler, journal_type, commit_id, &journal_id);
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
-
- std::unique_ptr<Journal> journal = JournalImpl::Simple(
- journal_type, environment_, this, journal_id, commit_id);
- callback(Status::OK, std::move(journal));
- });
-}
-
-void PageStorageImpl::StartMergeCommit(
- const CommitId& left, const CommitId& right,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, left, right](
- CoroutineHandler* handler,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) {
- JournalId journal_id;
- Status status = db_->CreateJournalId(handler, JournalType::EXPLICIT,
- left, &journal_id);
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
-
- std::unique_ptr<Journal> journal =
- JournalImpl::Merge(environment_, this, journal_id, left, right);
- callback(Status::OK, std::move(journal));
- });
-}
-
-void PageStorageImpl::CommitJournal(
- std::unique_ptr<Journal> journal,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) {
- FXL_DCHECK(journal);
-
- auto managed_journal = managed_container_.Manage(std::move(journal));
- JournalImpl* journal_ptr = static_cast<JournalImpl*>(managed_journal->get());
-
- journal_ptr->Commit(
- [journal_ptr, managed_journal = std::move(managed_journal),
- callback = std::move(callback)](
- Status status, std::unique_ptr<const Commit> commit) mutable {
- if (status != Status::OK) {
- // Commit failed, roll the journal back.
- journal_ptr->Rollback(
- [status, managed_journal = std::move(managed_journal),
- callback = std::move(callback)](Status /*rollback_status*/) {
- callback(status, nullptr);
- });
- return;
- }
- callback(Status::OK, std::move(commit));
- });
-}
-
-void PageStorageImpl::RollbackJournal(std::unique_ptr<Journal> journal,
- fit::function<void(Status)> callback) {
- FXL_DCHECK(journal);
-
- auto managed_journal = managed_container_.Manage(std::move(journal));
- JournalImpl* journal_ptr = static_cast<JournalImpl*>(managed_journal->get());
-
- journal_ptr->Rollback(
- [managed_journal = std::move(managed_journal),
- callback = std::move(callback)](Status status) { callback(status); });
-}
-
-Status PageStorageImpl::AddCommitWatcher(CommitWatcher* watcher) {
- watchers_.push_back(watcher);
- return Status::OK;
-}
-
-Status PageStorageImpl::RemoveCommitWatcher(CommitWatcher* watcher) {
- auto watcher_it =
- std::find_if(watchers_.begin(), watchers_.end(),
- [watcher](CommitWatcher* w) { return w == watcher; });
- if (watcher_it == watchers_.end()) {
- return Status::NOT_FOUND;
- }
- watchers_.erase(watcher_it);
- return Status::OK;
-}
-
-void PageStorageImpl::IsSynced(fit::function<void(Status, bool)> callback) {
- auto waiter = fxl::MakeRefCounted<callback::Waiter<Status, bool>>(Status::OK);
- // Check for unsynced commits.
- coroutine_manager_.StartCoroutine(
- waiter->NewCallback(),
- [this](CoroutineHandler* handler,
- fit::function<void(Status, bool)> callback) {
- std::vector<CommitId> commit_ids;
- Status status = db_->GetUnsyncedCommitIds(handler, &commit_ids);
- if (status != Status::OK) {
- callback(status, false);
- } else {
- callback(Status::OK, commit_ids.empty());
- }
- });
-
- // Check for unsynced pieces.
- GetUnsyncedPieces([pieces_callback = waiter->NewCallback()](
- Status status, std::vector<ObjectIdentifier> pieces) {
- if (status != Status::OK) {
- pieces_callback(status, false);
- } else {
- pieces_callback(Status::OK, pieces.empty());
- }
- });
-
- waiter->Finalize([callback = std::move(callback)](
- Status status, std::vector<bool> is_synced) {
- if (status != Status::OK) {
- callback(status, false);
- return;
- }
- FXL_DCHECK(is_synced.size() == 2);
- callback(Status::OK, is_synced[0] && is_synced[1]);
- });
-}
-
-bool PageStorageImpl::IsOnline() { return page_is_online_; }
-
-void PageStorageImpl::IsEmpty(fit::function<void(Status, bool)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback), [this](CoroutineHandler* handler,
- fit::function<void(Status, bool)> callback) {
- // Check there is a single head.
- std::vector<CommitId> commit_ids;
- Status status = db_->GetHeads(handler, &commit_ids);
- if (status != Status::OK) {
- callback(status, false);
- return;
- }
- FXL_DCHECK(!commit_ids.empty());
- if (commit_ids.size() > 1) {
- // A page is not empty if there is more than one head commit.
- callback(Status::OK, false);
- return;
- }
- // Compare the root node of the head commit to that of the empty node.
- std::unique_ptr<const Commit> commit;
- status = SynchronousGetCommit(handler, commit_ids[0], &commit);
- ObjectIdentifier* empty_node_id;
- status = SynchronousGetEmptyNodeIdentifier(handler, &empty_node_id);
- if (status != Status::OK) {
- callback(status, false);
- return;
- }
- callback(Status::OK, commit->GetRootIdentifier() == *empty_node_id);
- });
-}
-
-void PageStorageImpl::GetUnsyncedCommits(
- fit::function<void(Status, std::vector<std::unique_ptr<const Commit>>)>
- callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this](CoroutineHandler* handler,
- fit::function<void(Status,
- std::vector<std::unique_ptr<const Commit>>)>
- callback) {
- std::vector<std::unique_ptr<const Commit>> unsynced_commits;
- Status s = SynchronousGetUnsyncedCommits(handler, &unsynced_commits);
- callback(s, std::move(unsynced_commits));
- });
-}
-
-void PageStorageImpl::MarkCommitSynced(const CommitId& commit_id,
- fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, commit_id](CoroutineHandler* handler,
- fit::function<void(Status)> callback) {
- callback(SynchronousMarkCommitSynced(handler, commit_id));
- });
-}
-
-void PageStorageImpl::GetUnsyncedPieces(
- fit::function<void(Status, std::vector<ObjectIdentifier>)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this](
- CoroutineHandler* handler,
- fit::function<void(Status, std::vector<ObjectIdentifier>)> callback) {
- std::vector<ObjectIdentifier> unsynced_object_identifiers;
- Status s =
- db_->GetUnsyncedPieces(handler, &unsynced_object_identifiers);
- callback(s, unsynced_object_identifiers);
- });
-}
-
-void PageStorageImpl::MarkPieceSynced(ObjectIdentifier object_identifier,
- fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, object_identifier = std::move(object_identifier)](
- CoroutineHandler* handler, fit::function<void(Status)> callback) {
- callback(db_->SetObjectStatus(handler, object_identifier,
- PageDbObjectStatus::SYNCED));
- });
-}
-
-void PageStorageImpl::IsPieceSynced(
- ObjectIdentifier object_identifier,
- fit::function<void(Status, bool)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, object_identifier = std::move(object_identifier)](
- CoroutineHandler* handler,
- fit::function<void(Status, bool)> callback) {
- PageDbObjectStatus object_status;
- Status status =
- db_->GetObjectStatus(handler, object_identifier, &object_status);
- callback(status, object_status == PageDbObjectStatus::SYNCED);
- });
-}
-
-void PageStorageImpl::MarkSyncedToPeer(fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- [this, callback = std::move(callback)](CoroutineHandler* handler) {
- std::unique_ptr<PageDb::Batch> batch;
- Status status = db_->StartBatch(handler, &batch);
- if (status != Status::OK) {
- callback(status);
- return;
- }
- status = SynchronousMarkPageOnline(handler, batch.get());
- if (status != Status::OK) {
- callback(status);
- return;
- }
- callback(batch->Execute(handler));
- });
-}
-
-void PageStorageImpl::AddObjectFromLocal(
- ObjectType object_type, std::unique_ptr<DataSource> data_source,
- fit::function<void(Status, ObjectIdentifier)> callback) {
- auto traced_callback =
- TRACE_CALLBACK(std::move(callback), "ledger", "page_storage_add_object");
-
- auto managed_data_source = managed_container_.Manage(std::move(data_source));
- auto managed_data_source_ptr = managed_data_source->get();
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- SplitDataSource(
- managed_data_source_ptr, object_type,
- [this](ObjectDigest object_digest) {
- FXL_DCHECK(IsDigestValid(object_digest));
- return encryption_service_->MakeObjectIdentifier(
- std::move(object_digest));
- },
- [this, waiter, managed_data_source = std::move(managed_data_source),
- callback = std::move(traced_callback)](
- IterationStatus status, ObjectIdentifier identifier,
- std::unique_ptr<DataSource::DataChunk> chunk) mutable {
- if (status == IterationStatus::ERROR) {
- callback(Status::IO_ERROR, ObjectIdentifier());
- return;
- }
-
- FXL_DCHECK(chunk != nullptr);
-
- if (!GetObjectDigestInfo(identifier.object_digest()).is_inlined()) {
- AddPiece(identifier, ChangeSource::LOCAL, IsObjectSynced::NO,
- std::move(chunk), waiter->NewCallback());
- }
- if (status == IterationStatus::IN_PROGRESS)
- return;
-
- FXL_DCHECK(status == IterationStatus::DONE);
- waiter->Finalize(
- [identifier = std::move(identifier),
- callback = std::move(callback)](Status status) mutable {
- callback(status, std::move(identifier));
- });
- });
-}
-
-void PageStorageImpl::GetObjectPart(
- ObjectIdentifier object_identifier, int64_t offset, int64_t max_size,
- Location location, fit::function<void(Status, fsl::SizedVmo)> callback) {
- FXL_DCHECK(IsDigestValid(object_identifier.object_digest()));
- GetPiece(
- object_identifier,
- [this, object_identifier, offset, max_size, location,
- callback = std::move(callback)](
- Status status, std::unique_ptr<const Object> object) mutable {
- if (status == Status::NOT_FOUND) {
- if (location == Location::NETWORK) {
- GetObjectPartFromSync(object_identifier, offset, max_size,
- std::move(callback));
- } else {
- callback(Status::NOT_FOUND, nullptr);
- }
- return;
- }
-
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
-
- FXL_DCHECK(object);
- ObjectDigestInfo digest_info =
- GetObjectDigestInfo(object_identifier.object_digest());
- fxl::StringView data;
- Status get_data_status = object->GetData(&data);
- if (get_data_status != Status::OK) {
- callback(get_data_status, nullptr);
- return;
- }
-
- if (digest_info.is_inlined() || digest_info.is_chunk()) {
- fsl::SizedVmo buffer;
- size_t start = GetObjectPartStart(offset, data.size());
- size_t length = GetObjectPartLength(max_size, data.size(), start);
-
- if (!fsl::VmoFromString(data.substr(start, length), &buffer)) {
- callback(Status::INTERNAL_IO_ERROR, nullptr);
- return;
- }
- callback(Status::OK, std::move(buffer));
- return;
- }
-
- FXL_DCHECK(digest_info.piece_type == PieceType::INDEX);
- const FileIndex* file_index;
- status = FileIndexSerialization::ParseFileIndex(data, &file_index);
- if (status != Status::OK) {
- callback(Status::FORMAT_ERROR, nullptr);
- return;
- }
- size_t start = GetObjectPartStart(offset, file_index->size());
- size_t length =
- GetObjectPartLength(max_size, file_index->size(), start);
-
- zx::vmo raw_vmo;
- zx_status_t zx_status = zx::vmo::create(length, 0, &raw_vmo);
- if (zx_status != ZX_OK) {
- FXL_LOG(WARNING) << "Unable to create VMO of size: " << length;
- callback(Status::INTERNAL_IO_ERROR, nullptr);
- return;
- }
- fsl::SizedVmo vmo(std::move(raw_vmo), length);
-
- if (length == 0) {
- callback(Status::OK, std::move(vmo));
- }
-
- fsl::SizedVmo vmo_copy;
- zx_status = vmo.Duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_WRITE, &vmo_copy);
- if (zx_status != ZX_OK) {
- FXL_LOG(ERROR) << "Unable to duplicate vmo. Status: " << zx_status;
- callback(Status::INTERNAL_IO_ERROR, nullptr);
- return;
- }
- FillBufferWithObjectContent(
- std::move(object), std::move(vmo_copy), start, length, 0,
- file_index->size(),
- [vmo = std::move(vmo), callback = std::move(callback)](
- Status status) mutable { callback(status, std::move(vmo)); });
- });
-}
-
-void PageStorageImpl::GetObject(
- ObjectIdentifier object_identifier, Location location,
- fit::function<void(Status, std::unique_ptr<const Object>)> callback) {
- GetObjectPart(object_identifier, 0, -1, location,
- [object_identifier = std::move(object_identifier),
- callback = std::move(callback)](Status status,
- fsl::SizedVmo vmo) mutable {
- callback(status,
- std::make_unique<VmoObject>(
- std::move(object_identifier), std::move(vmo)));
- });
-}
-
-void PageStorageImpl::GetPiece(
- ObjectIdentifier object_identifier,
- fit::function<void(Status, std::unique_ptr<const Object>)> callback) {
- ObjectDigestInfo digest_info =
- GetObjectDigestInfo(object_identifier.object_digest());
- if (digest_info.is_inlined()) {
- callback(Status::OK,
- std::make_unique<InlinedObject>(std::move(object_identifier)));
- return;
- }
-
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, object_identifier = std::move(object_identifier)](
- CoroutineHandler* handler,
- fit::function<void(Status, std::unique_ptr<const Object>)>
- callback) mutable {
- std::unique_ptr<const Object> object;
- Status status =
- db_->ReadObject(handler, std::move(object_identifier), &object);
- callback(status, std::move(object));
- });
-}
-
-void PageStorageImpl::SetSyncMetadata(fxl::StringView key,
- fxl::StringView value,
- fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, key = key.ToString(), value = value.ToString()](
- CoroutineHandler* handler, fit::function<void(Status)> callback) {
- callback(db_->SetSyncMetadata(handler, key, value));
- });
-}
-
-void PageStorageImpl::GetSyncMetadata(
- fxl::StringView key, fit::function<void(Status, std::string)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, key = key.ToString()](
- CoroutineHandler* handler,
- fit::function<void(Status, std::string)> callback) {
- std::string value;
- Status status = db_->GetSyncMetadata(handler, key, &value);
- callback(status, std::move(value));
- });
-}
-
-void PageStorageImpl::GetCommitContents(const Commit& commit,
- std::string min_key,
- fit::function<bool(Entry)> on_next,
- fit::function<void(Status)> on_done) {
- btree::ForEachEntry(
- environment_->coroutine_service(), this, commit.GetRootIdentifier(),
- min_key,
- [on_next = std::move(on_next)](btree::EntryAndNodeIdentifier next) {
- return on_next(next.entry);
- },
- std::move(on_done));
-}
-
-void PageStorageImpl::GetEntryFromCommit(
- const Commit& commit, std::string key,
- fit::function<void(Status, Entry)> callback) {
- std::unique_ptr<bool> key_found = std::make_unique<bool>(false);
- auto on_next = [key, key_found = key_found.get(),
- callback =
- callback.share()](btree::EntryAndNodeIdentifier next) {
- if (next.entry.key == key) {
- *key_found = true;
- callback(Status::OK, next.entry);
- }
- return false;
- };
-
- auto on_done = [key_found = std::move(key_found),
- callback = std::move(callback)](Status s) {
- if (*key_found) {
- return;
- }
- if (s == Status::OK) {
- callback(Status::NOT_FOUND, Entry());
- return;
- }
- callback(s, Entry());
- };
- btree::ForEachEntry(environment_->coroutine_service(), this,
- commit.GetRootIdentifier(), std::move(key),
- std::move(on_next), std::move(on_done));
-}
-
-void PageStorageImpl::GetCommitContentsDiff(
- const Commit& base_commit, const Commit& other_commit, std::string min_key,
- fit::function<bool(EntryChange)> on_next_diff,
- fit::function<void(Status)> on_done) {
- btree::ForEachDiff(environment_->coroutine_service(), this,
- base_commit.GetRootIdentifier(),
- other_commit.GetRootIdentifier(), std::move(min_key),
- std::move(on_next_diff), std::move(on_done));
-}
-
-void PageStorageImpl::GetThreeWayContentsDiff(
- const Commit& base_commit, const Commit& left_commit,
- const Commit& right_commit, std::string min_key,
- fit::function<bool(ThreeWayChange)> on_next_diff,
- fit::function<void(Status)> on_done) {
- btree::ForEachThreeWayDiff(
- environment_->coroutine_service(), this, base_commit.GetRootIdentifier(),
- left_commit.GetRootIdentifier(), right_commit.GetRootIdentifier(),
- std::move(min_key), std::move(on_next_diff), std::move(on_done));
-}
-
-void PageStorageImpl::GetJournalEntries(
- const JournalId& journal_id,
- fit::function<void(Status, std::unique_ptr<Iterator<const EntryChange>>,
- JournalContainsClearOperation contains_clear_operation)>
- callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, journal_id](
- CoroutineHandler* handler,
- fit::function<void(
- Status, std::unique_ptr<Iterator<const EntryChange>>,
- JournalContainsClearOperation contains_clear_operation)>
- callback) {
- std::unique_ptr<Iterator<const EntryChange>> entries;
- JournalContainsClearOperation contains_clear_operation;
- Status s = db_->GetJournalEntries(handler, journal_id, &entries,
- &contains_clear_operation);
- callback(s, std::move(entries), contains_clear_operation);
- });
-}
-
-void PageStorageImpl::AddJournalEntry(const JournalId& journal_id,
- fxl::StringView key,
- ObjectIdentifier object_identifier,
- KeyPriority priority,
- fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, journal_id, key = key.ToString(),
- object_identifier = std::move(object_identifier), priority](
- CoroutineHandler* handler, fit::function<void(Status)> callback) {
- callback(db_->AddJournalEntry(handler, journal_id, key,
- object_identifier, priority));
- });
-}
-
-void PageStorageImpl::RemoveJournalEntry(const JournalId& journal_id,
- convert::ExtendedStringView key,
- fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, journal_id, key = key.ToString()](
- CoroutineHandler* handler, fit::function<void(Status)> callback) {
- callback(db_->RemoveJournalEntry(handler, journal_id, key));
- });
-}
-
-void PageStorageImpl::EmptyJournalAndMarkContainsClearOperation(
- const JournalId& journal_id, fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, journal_id](CoroutineHandler* handler,
- fit::function<void(Status)> callback) {
- callback(db_->EmptyJournalAndMarkContainsClearOperation(handler,
- journal_id));
- });
-}
-
-void PageStorageImpl::RemoveJournal(const JournalId& journal_id,
- fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, journal_id](CoroutineHandler* handler,
- fit::function<void(Status)> callback) {
- callback(db_->RemoveJournal(handler, journal_id));
- });
-}
-
-void PageStorageImpl::NotifyWatchersOfNewCommits(
- const std::vector<std::unique_ptr<const Commit>>& new_commits,
- ChangeSource source) {
- for (CommitWatcher* watcher : watchers_) {
- watcher->OnNewCommits(new_commits, source);
- }
-}
-
-Status PageStorageImpl::MarkAllPiecesLocal(
- CoroutineHandler* handler, PageDb::Batch* batch,
- std::vector<ObjectIdentifier> object_identifiers) {
- std::set<ObjectIdentifier> seen_identifiers;
- while (!object_identifiers.empty()) {
- auto it = seen_identifiers.insert(std::move(object_identifiers.back()));
- object_identifiers.pop_back();
- const ObjectIdentifier& object_identifier = *(it.first);
- FXL_DCHECK(
- !GetObjectDigestInfo(object_identifier.object_digest()).is_inlined());
- Status status = batch->SetObjectStatus(handler, object_identifier,
- PageDbObjectStatus::LOCAL);
- if (status != Status::OK) {
- return status;
- }
- if (GetObjectDigestInfo(object_identifier.object_digest()).piece_type ==
- PieceType::INDEX) {
- std::unique_ptr<const Object> object;
- status = db_->ReadObject(handler, object_identifier, &object);
- if (status != Status::OK) {
- return status;
- }
-
- fxl::StringView content;
- status = object->GetData(&content);
- if (status != Status::OK) {
- return status;
- }
-
- const FileIndex* file_index;
- status = FileIndexSerialization::ParseFileIndex(content, &file_index);
- if (status != Status::OK) {
- return status;
- }
-
- object_identifiers.reserve(object_identifiers.size() +
- file_index->children()->size());
- for (const auto* child : *file_index->children()) {
- ObjectIdentifier new_object_identifier =
- ToObjectIdentifier(child->object_identifier());
- if (!GetObjectDigestInfo(new_object_identifier.object_digest())
- .is_inlined()) {
- if (!seen_identifiers.count(new_object_identifier)) {
- object_identifiers.push_back(std::move(new_object_identifier));
- }
- }
- }
- }
- }
- return Status::OK;
-}
-
-Status PageStorageImpl::ContainsCommit(CoroutineHandler* handler,
- CommitIdView id) {
- if (IsFirstCommit(id)) {
- return Status::OK;
- }
- std::string bytes;
- return db_->GetCommitStorageBytes(handler, id, &bytes);
-}
-
-bool PageStorageImpl::IsFirstCommit(CommitIdView id) {
- return id == kFirstPageCommitId;
-}
-
-void PageStorageImpl::AddPiece(ObjectIdentifier object_identifier,
- ChangeSource source,
- IsObjectSynced is_object_synced,
- std::unique_ptr<DataSource::DataChunk> data,
- fit::function<void(Status)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, object_identifier = std::move(object_identifier),
- data = std::move(data), source,
- is_object_synced](CoroutineHandler* handler,
- fit::function<void(Status)> callback) mutable {
- callback(SynchronousAddPiece(handler, std::move(object_identifier),
- source, is_object_synced,
- std::move(data)));
- });
-}
-
-void PageStorageImpl::DownloadFullObject(ObjectIdentifier object_identifier,
- fit::function<void(Status)> callback) {
- FXL_DCHECK(page_sync_);
- FXL_DCHECK(
- !GetObjectDigestInfo(object_identifier.object_digest()).is_inlined());
-
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, object_identifier = std::move(object_identifier)](
- CoroutineHandler* handler,
- fit::function<void(Status)> callback) mutable {
- Status status;
- ChangeSource source;
- IsObjectSynced is_object_synced;
- std::unique_ptr<DataSource::DataChunk> chunk;
-
- if (coroutine::SyncCall(
- handler,
- [this, object_identifier](
- fit::function<void(Status, ChangeSource, IsObjectSynced,
- std::unique_ptr<DataSource::DataChunk>)>
- callback) mutable {
- page_sync_->GetObject(std::move(object_identifier),
- std::move(callback));
- },
- &status, &source, &is_object_synced,
- &chunk) == coroutine::ContinuationStatus::INTERRUPTED) {
- callback(Status::INTERRUPTED);
- return;
- }
-
- if (status != Status::OK) {
- callback(status);
- return;
- }
- auto digest_info =
- GetObjectDigestInfo(object_identifier.object_digest());
- FXL_DCHECK(!digest_info.is_inlined());
-
- if (object_identifier.object_digest() !=
- ComputeObjectDigest(digest_info.piece_type, digest_info.object_type,
- chunk->Get())) {
- callback(Status::OBJECT_DIGEST_MISMATCH);
- return;
- }
-
- if (digest_info.is_chunk()) {
- callback(SynchronousAddPiece(handler, std::move(object_identifier),
- source, is_object_synced,
- std::move(chunk)));
- return;
- }
-
- auto waiter =
- fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- status = ForEachPiece(chunk->Get(), [&](ObjectIdentifier identifier) {
- if (GetObjectDigestInfo(identifier.object_digest()).is_inlined()) {
- return Status::OK;
- }
-
- Status status = db_->ReadObject(handler, identifier, nullptr);
- if (status == Status::NOT_FOUND) {
- DownloadFullObject(std::move(identifier), waiter->NewCallback());
- return Status::OK;
- }
- return status;
- });
- if (status != Status::OK) {
- callback(status);
- return;
- }
-
- if (coroutine::Wait(handler, std::move(waiter), &status) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- callback(Status::INTERRUPTED);
- return;
- }
-
- if (status != Status::OK) {
- callback(status);
- return;
- }
-
- callback(SynchronousAddPiece(handler, std::move(object_identifier),
- source, is_object_synced,
- std::move(chunk)));
- });
-}
-
-void PageStorageImpl::GetObjectPartFromSync(
- ObjectIdentifier object_identifier, size_t offset, size_t size,
- fit::function<void(Status, fsl::SizedVmo)> callback) {
- if (!page_sync_) {
- callback(Status::NOT_CONNECTED_ERROR, nullptr);
- return;
- }
-
- // TODO(LE-239): download only the needed part.
- DownloadFullObject(object_identifier,
- [this, object_identifier, offset, size,
- callback = std::move(callback)](Status status) mutable {
- if (status != Status::OK) {
- callback(status, nullptr);
- return;
- }
-
- GetObjectPart(object_identifier, offset, size,
- Location::LOCAL, std::move(callback));
- });
-}
-
-void PageStorageImpl::ObjectIsUntracked(
- ObjectIdentifier object_identifier,
- fit::function<void(Status, bool)> callback) {
- coroutine_manager_.StartCoroutine(
- std::move(callback),
- [this, object_identifier = std::move(object_identifier)](
- CoroutineHandler* handler,
- fit::function<void(Status, bool)> callback) mutable {
- if (GetObjectDigestInfo(object_identifier.object_digest())
- .is_inlined()) {
- callback(Status::OK, false);
- return;
- }
-
- PageDbObjectStatus object_status;
- Status status =
- db_->GetObjectStatus(handler, object_identifier, &object_status);
- callback(status, object_status == PageDbObjectStatus::TRANSIENT);
- });
-}
-
-void PageStorageImpl::FillBufferWithObjectContent(
- ObjectIdentifier object_identifier, fsl::SizedVmo vmo,
- int64_t global_offset, size_t global_size, int64_t current_position,
- size_t object_size, fit::function<void(Status)> callback) {
- GetPiece(object_identifier,
- [this, vmo = std::move(vmo), global_offset, global_size,
- current_position, object_size, callback = std::move(callback)](
- Status status, std::unique_ptr<const Object> object) mutable {
- if (status != Status::OK) {
- callback(status);
- return;
- }
-
- FXL_DCHECK(object);
- FillBufferWithObjectContent(
- std::move(object), std::move(vmo), global_offset, global_size,
- current_position, object_size, std::move(callback));
- });
-}
-
-void PageStorageImpl::FillBufferWithObjectContent(
- std::unique_ptr<const Object> object, fsl::SizedVmo vmo,
- int64_t global_offset, size_t global_size, int64_t current_position,
- size_t object_size, fit::function<void(Status)> callback) {
- fxl::StringView content;
- Status status = object->GetData(&content);
- if (status != Status::OK) {
- callback(status);
- return;
- }
- ObjectDigestInfo digest_info =
- GetObjectDigestInfo(object->GetIdentifier().object_digest());
- if (digest_info.is_inlined() || digest_info.is_chunk()) {
- if (object_size != content.size()) {
- FXL_LOG(ERROR) << "Error in serialization format. Expecting object: "
- << object->GetIdentifier()
- << " to have size: " << object_size
- << ", but found an object of size: " << content.size();
- callback(Status::FORMAT_ERROR);
- return;
- }
- // Distance is negative if the offset is ahead and positive if behind.
- int64_t distance_from_global_offset = current_position - global_offset;
- // Read offset can be non-zero on first read; in that case, we need to skip
- // bytes coming before global offset.
- size_t read_offset = std::max(-distance_from_global_offset, 0L);
- // Write offset is zero on the first write; otherwise we need to skip number
- // of bytes corresponding to what we have already written.
- size_t write_offset = std::max(distance_from_global_offset, 0L);
- // Read and write until reaching either size of the object, or global size.
- size_t read_write_size =
- std::min(content.size() - read_offset, global_size - write_offset);
- FXL_DCHECK(read_write_size > 0);
- fxl::StringView read_substr = content.substr(read_offset, read_write_size);
- zx_status_t zx_status =
- vmo.vmo().write(read_substr.data(), write_offset, read_write_size);
- if (zx_status != ZX_OK) {
- FXL_LOG(ERROR) << "Unable to write to vmo. Status: " << zx_status;
- callback(Status::INTERNAL_IO_ERROR);
- return;
- }
- callback(Status::OK);
- return;
- }
-
- const FileIndex* file_index;
- status = FileIndexSerialization::ParseFileIndex(content, &file_index);
- if (status != Status::OK) {
- callback(Status::FORMAT_ERROR);
- return;
- }
- if (file_index->size() != object_size) {
- FXL_LOG(ERROR) << "Error in serialization format. Expecting object: "
- << object->GetIdentifier() << " to have size " << object_size
- << ", but found an index object of size: "
- << file_index->size();
- callback(Status::FORMAT_ERROR);
- return;
- }
-
- int64_t sub_offset = 0;
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- for (const auto* child : *file_index->children()) {
- if (sub_offset + child->size() > file_index->size()) {
- callback(Status::FORMAT_ERROR);
- return;
- }
- int64_t child_position = current_position + sub_offset;
- ObjectIdentifier child_identifier =
- ToObjectIdentifier(child->object_identifier());
- if (child_position + static_cast<int64_t>(child->size()) < global_offset) {
- sub_offset += child->size();
- continue;
- }
- if (global_offset + static_cast<int64_t>(global_size) < child_position) {
- break;
- }
- fsl::SizedVmo vmo_copy;
- zx_status_t zx_status =
- vmo.Duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_WRITE, &vmo_copy);
- if (zx_status != ZX_OK) {
- FXL_LOG(ERROR) << "Unable to duplicate vmo. Status: " << zx_status;
- callback(Status::INTERNAL_IO_ERROR);
- return;
- }
- FillBufferWithObjectContent(child_identifier, std::move(vmo_copy),
- global_offset, global_size, child_position,
- child->size(), waiter->NewCallback());
- sub_offset += child->size();
- }
- waiter->Finalize(std::move(callback));
-}
-
-Status PageStorageImpl::SynchronousInit(CoroutineHandler* handler) {
- // Add the default page head if this page is empty.
- std::vector<CommitId> heads;
- Status s = db_->GetHeads(handler, &heads);
- if (s != Status::OK) {
- return s;
- }
- if (heads.empty()) {
- s = db_->AddHead(handler, kFirstPageCommitId, zx::time_utc());
- if (s != Status::OK) {
- return s;
- }
- }
-
- // Cache whether this page is online or not.
- s = db_->IsPageOnline(handler, &page_is_online_);
- if (s != Status::OK) {
- return s;
- }
-
- // Remove uncommited explicit journals.
- if (db_->RemoveExplicitJournals(handler) == Status::INTERRUPTED) {
- // Only fail if the handler is invalidated. Otherwise, failure to remove
- // explicit journals should not block the initalization.
- return Status::INTERRUPTED;
- }
-
- // Commit uncommited implicit journals.
- std::vector<JournalId> journal_ids;
- s = db_->GetImplicitJournalIds(handler, &journal_ids);
- if (s != Status::OK) {
- return s;
- }
-
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- for (JournalId& id : journal_ids) {
- CommitId base;
- s = db_->GetBaseCommitForJournal(handler, id, &base);
- if (s != Status::OK) {
- FXL_LOG(ERROR) << "Failed to get implicit journal with status " << s
- << ". journal id: " << id;
- return s;
- }
- std::unique_ptr<Journal> journal = JournalImpl::Simple(
- JournalType::IMPLICIT, environment_, this, id, base);
-
- CommitJournal(
- std::move(journal), [status_callback = waiter->NewCallback()](
- Status status, std::unique_ptr<const Commit>) {
- if (status != Status::OK) {
- FXL_LOG(ERROR) << "Failed to commit implicit journal created in "
- "previous Ledger execution.";
- }
- status_callback(status);
- });
- }
-
- if (coroutine::Wait(handler, std::move(waiter), &s) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return s;
-}
-
-Status PageStorageImpl::SynchronousGetCommit(
- CoroutineHandler* handler, CommitId commit_id,
- std::unique_ptr<const Commit>* commit) {
- if (IsFirstCommit(commit_id)) {
- Status s;
- if (coroutine::SyncCall(
- handler,
- [this](fit::function<void(Status, std::unique_ptr<const Commit>)>
- callback) {
- CommitImpl::Empty(this, std::move(callback));
- },
- &s, commit) == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- return s;
- }
- std::string bytes;
- Status s = db_->GetCommitStorageBytes(handler, commit_id, &bytes);
- if (s != Status::OK) {
- return s;
- }
- return CommitImpl::FromStorageBytes(this, commit_id, std::move(bytes),
- commit);
-}
-
-Status PageStorageImpl::SynchronousAddCommitFromLocal(
- CoroutineHandler* handler, std::unique_ptr<const Commit> commit,
- std::vector<ObjectIdentifier> new_objects) {
- std::vector<std::unique_ptr<const Commit>> commits;
- commits.reserve(1);
- commits.push_back(std::move(commit));
-
- return SynchronousAddCommits(handler, std::move(commits), ChangeSource::LOCAL,
- std::move(new_objects), nullptr);
-}
-
-Status PageStorageImpl::SynchronousAddCommitsFromSync(
- CoroutineHandler* handler, std::vector<CommitIdAndBytes> ids_and_bytes,
- ChangeSource source, std::vector<CommitId>* missing_ids) {
- std::vector<std::unique_ptr<const Commit>> commits;
-
- std::map<const CommitId*, const Commit*, StringPointerComparator> leaves;
- commits.reserve(ids_and_bytes.size());
-
- // The locked section below contains asynchronous operations reading the
- // database, and branches depending on those reads. This section is thus a
- // critical section and we need to ensure it is not executed concurrently by
- // several coroutines. The locked sections (and only those) are thus executed
- // serially.
- std::unique_ptr<lock::Lock> lock;
- if (lock::AcquireLock(handler, &commit_serializer_, &lock) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
-
- for (auto& id_and_bytes : ids_and_bytes) {
- CommitId id = std::move(id_and_bytes.id);
- std::string storage_bytes = std::move(id_and_bytes.bytes);
- Status status = ContainsCommit(handler, id);
- if (status == Status::OK) {
- // We only mark cloud-sourced commits as synced.
- if (source == ChangeSource::CLOUD) {
- Status status = SynchronousMarkCommitSynced(handler, id);
- if (status != Status::OK) {
- return status;
- }
- }
- continue;
- }
-
- if (status != Status::NOT_FOUND) {
- return status;
- }
-
- std::unique_ptr<const Commit> commit;
- status = CommitImpl::FromStorageBytes(this, id, std::move(storage_bytes),
- &commit);
- if (status != Status::OK) {
- FXL_LOG(ERROR) << "Unable to add commit. Id: " << convert::ToHex(id);
- return status;
- }
-
- // Remove parents from leaves.
- for (const auto& parent_id : commit->GetParentIds()) {
- auto it = leaves.find(&parent_id);
- if (it != leaves.end()) {
- leaves.erase(it);
- }
- }
- leaves[&commit->GetId()] = commit.get();
- commits.push_back(std::move(commit));
- }
-
- if (commits.empty()) {
- return Status::OK;
- }
-
- lock.reset();
-
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- // Get all objects from sync and then add the commit objects.
- for (const auto& leaf : leaves) {
- btree::GetObjectsFromSync(environment_->coroutine_service(), this,
- leaf.second->GetRootIdentifier(),
- waiter->NewCallback());
- }
-
- Status waiter_status;
- if (coroutine::Wait(handler, std::move(waiter), &waiter_status) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- if (waiter_status != Status::OK) {
- return waiter_status;
- }
-
- return SynchronousAddCommits(handler, std::move(commits), source,
- std::vector<ObjectIdentifier>(), missing_ids);
-}
-
-Status PageStorageImpl::SynchronousGetUnsyncedCommits(
- CoroutineHandler* handler,
- std::vector<std::unique_ptr<const Commit>>* unsynced_commits) {
- std::vector<CommitId> commit_ids;
- Status s = db_->GetUnsyncedCommitIds(handler, &commit_ids);
- if (s != Status::OK) {
- return s;
- }
-
- auto waiter = fxl::MakeRefCounted<
- callback::Waiter<Status, std::unique_ptr<const Commit>>>(Status::OK);
- for (const auto& commit_id : commit_ids) {
- GetCommit(commit_id, waiter->NewCallback());
- }
-
- std::vector<std::unique_ptr<const Commit>> result;
- if (coroutine::Wait(handler, std::move(waiter), &s, &result) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- if (s != Status::OK) {
- return s;
- }
- unsynced_commits->swap(result);
- return Status::OK;
-}
-
-Status PageStorageImpl::SynchronousMarkCommitSynced(CoroutineHandler* handler,
- const CommitId& commit_id) {
- std::unique_ptr<PageDb::Batch> batch;
- Status status = db_->StartBatch(handler, &batch);
- if (status != Status::OK) {
- return status;
- }
- status = SynchronousMarkCommitSyncedInBatch(handler, batch.get(), commit_id);
- if (status != Status::OK) {
- return status;
- }
- return batch->Execute(handler);
-}
-
-Status PageStorageImpl::SynchronousMarkCommitSyncedInBatch(
- CoroutineHandler* handler, PageDb::Batch* batch,
- const CommitId& commit_id) {
- Status status = SynchronousMarkPageOnline(handler, batch);
- if (status != Status::OK) {
- return status;
- }
- return batch->MarkCommitIdSynced(handler, commit_id);
-}
-
-Status PageStorageImpl::SynchronousAddCommits(
- CoroutineHandler* handler,
- std::vector<std::unique_ptr<const Commit>> commits, ChangeSource source,
- std::vector<ObjectIdentifier> new_objects,
- std::vector<CommitId>* missing_ids) {
- // Make sure that only one AddCommits operation is executed at a time.
- // Otherwise, if db_ operations are asynchronous, ContainsCommit (below) may
- // return NOT_FOUND while another commit is added, and batch->Execute() will
- // break the invariants of this system (in particular, that synced commits
- // cannot become unsynced).
- std::unique_ptr<lock::Lock> lock;
- if (lock::AcquireLock(handler, &commit_serializer_, &lock) ==
- coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
-
- // Apply all changes atomically.
- std::unique_ptr<PageDb::Batch> batch;
- Status status = db_->StartBatch(handler, &batch);
- if (status != Status::OK) {
- return status;
- }
- std::set<const CommitId*, StringPointerComparator> added_commits;
- std::vector<std::unique_ptr<const Commit>> commits_to_send;
-
- std::map<CommitId, zx::time_utc> heads_to_add;
-
- int orphaned_commits = 0;
- for (auto& commit : commits) {
- // We need to check if we are adding an already present remote commit here
- // because we might both download and locally commit the same commit at
- // roughly the same time. As commit writing is asynchronous, the previous
- // check in AddCommitsFromSync may have not matched any commit, while a
- // commit got added in between.
- Status s = ContainsCommit(handler, commit->GetId());
- if (s == Status::OK) {
- if (source == ChangeSource::CLOUD) {
- s = SynchronousMarkCommitSyncedInBatch(handler, batch.get(),
- commit->GetId());
- if (s != Status::OK) {
- return s;
- }
- }
- // The commit is already here. We can safely skip it.
- continue;
- }
- if (s != Status::NOT_FOUND) {
- return s;
- }
- // Now, we know we are adding a new commit.
-
- // Commits should arrive in order. Check that the parents are either
- // present in PageDb or in the list of already processed commits.
- // If the commit arrive out of order, print an error, but skip it
- // temporarly so that the Ledger can recover if all the needed commits
- // are received in a single batch.
- bool orphaned_commit = false;
- for (const CommitIdView& parent_id : commit->GetParentIds()) {
- if (added_commits.find(&parent_id) == added_commits.end()) {
- s = ContainsCommit(handler, parent_id);
- if (s != Status::OK) {
- FXL_LOG(ERROR) << "Failed to find parent commit \""
- << ToHex(parent_id) << "\" of commit \""
- << convert::ToHex(commit->GetId()) << "\".";
- if (s == Status::NOT_FOUND) {
- if (missing_ids) {
- missing_ids->push_back(parent_id.ToString());
- }
- orphaned_commit = true;
- continue;
- }
- return Status::INTERNAL_IO_ERROR;
- }
- }
- // Remove the parent from the list of heads.
- if (!heads_to_add.erase(parent_id.ToString())) {
- // parent_id was not added in the batch: remove it from heads in Db.
- s = batch->RemoveHead(handler, parent_id);
- if (s != Status::OK) {
- return s;
- }
- }
- }
-
- // The commit could not be added. Skip it.
- if (orphaned_commit) {
- orphaned_commits++;
- continue;
- }
-
- s = batch->AddCommitStorageBytes(handler, commit->GetId(),
- commit->GetStorageBytes());
- if (s != Status::OK) {
- return s;
- }
-
- if (source != ChangeSource::CLOUD) {
- s = batch->MarkCommitIdUnsynced(handler, commit->GetId(),
- commit->GetGeneration());
- if (s != Status::OK) {
- return s;
- }
- }
-
- // Update heads_to_add.
- heads_to_add[commit->GetId()] = commit->GetTimestamp();
-
- added_commits.insert(&commit->GetId());
- commits_to_send.push_back(std::move(commit));
- }
-
- if (orphaned_commits > 0) {
- if (source != ChangeSource::P2P) {
- ledger::ReportEvent(
- ledger::CobaltEvent::COMMITS_RECEIVED_OUT_OF_ORDER_NOT_RECOVERED);
- FXL_LOG(ERROR)
- << "Failed adding commits. Found " << orphaned_commits
- << " orphaned commits (one of their parent was not found).";
- }
- return Status::NOT_FOUND;
- }
-
- // Update heads in Db.
- for (const auto& head_timestamp : heads_to_add) {
- Status s =
- batch->AddHead(handler, head_timestamp.first, head_timestamp.second);
- if (s != Status::OK) {
- return s;
- }
- }
-
- // If adding local commits, mark all new pieces as local.
- Status s = MarkAllPiecesLocal(handler, batch.get(), std::move(new_objects));
- if (s != Status::OK) {
- return s;
- }
-
- s = batch->Execute(handler);
-
- NotifyWatchersOfNewCommits(commits_to_send, source);
-
- return s;
-}
-
-Status PageStorageImpl::SynchronousAddPiece(
- CoroutineHandler* handler, ObjectIdentifier object_identifier,
- ChangeSource source, IsObjectSynced is_object_synced,
- std::unique_ptr<DataSource::DataChunk> data) {
- FXL_DCHECK(
- !GetObjectDigestInfo(object_identifier.object_digest()).is_inlined());
- FXL_DCHECK(
- object_identifier.object_digest() ==
- ComputeObjectDigest(
- GetObjectDigestInfo(object_identifier.object_digest()).piece_type,
- GetObjectDigestInfo(object_identifier.object_digest()).object_type,
- data->Get()));
-
- std::unique_ptr<const Object> object;
- Status status = db_->ReadObject(handler, object_identifier, &object);
- if (status == Status::NOT_FOUND) {
- PageDbObjectStatus object_status;
- switch (is_object_synced) {
- case IsObjectSynced::NO:
- object_status =
- (source == ChangeSource::LOCAL ? PageDbObjectStatus::TRANSIENT
- : PageDbObjectStatus::LOCAL);
- break;
- case IsObjectSynced::YES:
- object_status = PageDbObjectStatus::SYNCED;
- break;
- }
- return db_->WriteObject(handler, object_identifier, std::move(data),
- object_status);
- }
- return status;
-}
-
-Status PageStorageImpl::SynchronousMarkPageOnline(
- coroutine::CoroutineHandler* handler, PageDb::Batch* batch) {
- if (page_is_online_) {
- return Status::OK;
- }
- Status status = batch->MarkPageOnline(handler);
- if (status == Status::OK) {
- page_is_online_ = true;
- }
- return status;
-}
-
-FXL_WARN_UNUSED_RESULT Status
-PageStorageImpl::SynchronousGetEmptyNodeIdentifier(
- coroutine::CoroutineHandler* handler, ObjectIdentifier** empty_node_id) {
- if (!empty_node_id_) {
- // Get the empty node identifier and cache it.
- Status status;
- ObjectIdentifier object_identifier;
- if (coroutine::SyncCall(
- handler,
- [this](fit::function<void(Status, ObjectIdentifier)> callback) {
- btree::TreeNode::Empty(this, std::move(callback));
- },
- &status,
- &object_identifier) == coroutine::ContinuationStatus::INTERRUPTED) {
- return Status::INTERRUPTED;
- }
- if (status != Status::OK) {
- return status;
- }
- empty_node_id_ =
- std::make_unique<ObjectIdentifier>(std::move(object_identifier));
- }
- *empty_node_id = empty_node_id_.get();
- return Status::OK;
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/page_storage_impl.h b/bin/ledger/storage/impl/page_storage_impl.h
deleted file mode 100644
index 1210757..0000000
--- a/bin/ledger/storage/impl/page_storage_impl.h
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_STORAGE_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_STORAGE_IMPL_H_
-
-#include <vector>
-
-#include <lib/async/dispatcher.h>
-#include <lib/callback/managed_container.h>
-#include <lib/callback/operation_serializer.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/coroutine/coroutine_manager.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/environment/environment.h"
-#include "peridot/bin/ledger/storage/impl/page_db_impl.h"
-#include "peridot/bin/ledger/storage/public/db.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/page_sync_delegate.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace storage {
-
-class PageStorageImpl : public PageStorage {
- public:
- PageStorageImpl(ledger::Environment* environment,
- encryption::EncryptionService* encryption_service,
- std::unique_ptr<Db> db, PageId page_id);
- PageStorageImpl(ledger::Environment* environment,
- encryption::EncryptionService* encryption_service,
- std::unique_ptr<PageDb> page_db, PageId page_id);
-
- ~PageStorageImpl() override;
-
- // Initializes this PageStorageImpl. This includes initializing the underlying
- // database, adding the default page head if the page is empty, removing
- // uncommitted explicit and committing implicit journals.
- void Init(fit::function<void(Status)> callback);
-
- // Adds the given locally created |commit| in this |PageStorage|.
- void AddCommitFromLocal(std::unique_ptr<const Commit> commit,
- std::vector<ObjectIdentifier> new_objects,
- fit::function<void(Status)> callback);
-
- // Checks whether the given |object_identifier| is untracked, i.e. has been
- // created using |AddObjectFromLocal()|, but is not yet part of any commit.
- // Untracked objects are invalid after the PageStorageImpl object is
- // destroyed.
- void ObjectIsUntracked(ObjectIdentifier object_identifier,
- fit::function<void(Status, bool)> callback);
-
- // PageStorage:
- PageId GetId() override;
- void SetSyncDelegate(PageSyncDelegate* page_sync) override;
- void GetHeadCommitIds(
- fit::function<void(Status, std::vector<CommitId>)> callback) override;
- void GetCommit(CommitIdView commit_id,
- fit::function<void(Status, std::unique_ptr<const Commit>)>
- callback) override;
- void AddCommitsFromSync(
- std::vector<CommitIdAndBytes> ids_and_bytes, ChangeSource source,
- fit::function<void(Status, std::vector<CommitId>)> callback) override;
- void StartCommit(
- const CommitId& commit_id, JournalType journal_type,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) override;
- void StartMergeCommit(
- const CommitId& left, const CommitId& right,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) override;
- void CommitJournal(std::unique_ptr<Journal> journal,
- fit::function<void(Status, std::unique_ptr<const Commit>)>
- callback) override;
- void RollbackJournal(std::unique_ptr<Journal> journal,
- fit::function<void(Status)> callback) override;
- Status AddCommitWatcher(CommitWatcher* watcher) override;
- Status RemoveCommitWatcher(CommitWatcher* watcher) override;
- void IsSynced(fit::function<void(Status, bool)> callback) override;
- bool IsOnline() override;
- void IsEmpty(fit::function<void(Status, bool)> callback) override;
- void GetUnsyncedCommits(
- fit::function<void(Status, std::vector<std::unique_ptr<const Commit>>)>
- callback) override;
- void MarkCommitSynced(const CommitId& commit_id,
- fit::function<void(Status)> callback) override;
- void GetUnsyncedPieces(
- fit::function<void(Status, std::vector<ObjectIdentifier>)> callback)
- override;
- void MarkPieceSynced(ObjectIdentifier object_identifier,
- fit::function<void(Status)> callback) override;
- void IsPieceSynced(ObjectIdentifier object_identifier,
- fit::function<void(Status, bool)> callback) override;
- void MarkSyncedToPeer(fit::function<void(Status)> callback) override;
- void AddObjectFromLocal(
- ObjectType object_type, std::unique_ptr<DataSource> data_source,
- fit::function<void(Status, ObjectIdentifier)> callback) override;
- void GetObjectPart(
- ObjectIdentifier object_identifier, int64_t offset, int64_t max_size,
- Location location,
- fit::function<void(Status, fsl::SizedVmo)> callback) override;
- void GetObject(ObjectIdentifier object_identifier, Location location,
- fit::function<void(Status, std::unique_ptr<const Object>)>
- callback) override;
- void GetPiece(ObjectIdentifier object_identifier,
- fit::function<void(Status, std::unique_ptr<const Object>)>
- callback) override;
- void SetSyncMetadata(fxl::StringView key, fxl::StringView value,
- fit::function<void(Status)> callback) override;
- void GetSyncMetadata(
- fxl::StringView key,
- fit::function<void(Status, std::string)> callback) override;
-
- // Methods to be used by JournalImpl.
- void GetJournalEntries(
- const JournalId& journal_id,
- fit::function<
- void(Status, std::unique_ptr<Iterator<const EntryChange>>,
- JournalContainsClearOperation contains_clear_operation)>
- callback);
-
- void AddJournalEntry(const JournalId& journal_id, fxl::StringView key,
- ObjectIdentifier object_identifier, KeyPriority priority,
- fit::function<void(Status)> callback);
-
- void RemoveJournalEntry(const JournalId& journal_id,
- convert::ExtendedStringView key,
- fit::function<void(Status)> callback);
-
- void EmptyJournalAndMarkContainsClearOperation(
- const JournalId& journal_id, fit::function<void(Status)> callback);
-
- void RemoveJournal(const JournalId& journal_id,
- fit::function<void(Status)> callback);
-
- // Commit contents.
- void GetCommitContents(const Commit& commit, std::string min_key,
- fit::function<bool(Entry)> on_next,
- fit::function<void(Status)> on_done) override;
- void GetEntryFromCommit(const Commit& commit, std::string key,
- fit::function<void(Status, Entry)> callback) override;
- void GetCommitContentsDiff(const Commit& base_commit,
- const Commit& other_commit, std::string min_key,
- fit::function<bool(EntryChange)> on_next_diff,
- fit::function<void(Status)> on_done) override;
- void GetThreeWayContentsDiff(const Commit& base_commit,
- const Commit& left_commit,
- const Commit& right_commit, std::string min_key,
- fit::function<bool(ThreeWayChange)> on_next_diff,
- fit::function<void(Status)> on_done) override;
-
- private:
- friend class PageStorageImplAccessorForTest;
-
- // Marks all pieces needed for the given objects as local.
- FXL_WARN_UNUSED_RESULT Status
- MarkAllPiecesLocal(coroutine::CoroutineHandler* handler, PageDb::Batch* batch,
- std::vector<ObjectIdentifier> object_identifiers);
-
- FXL_WARN_UNUSED_RESULT Status
- ContainsCommit(coroutine::CoroutineHandler* handler, CommitIdView id);
-
- bool IsFirstCommit(CommitIdView id);
-
- // Adds the given synced object. |object_identifier| is expected to match the
- // given |data|.
- void AddPiece(ObjectIdentifier object_identifier, ChangeSource source,
- IsObjectSynced is_object_synced,
- std::unique_ptr<DataSource::DataChunk> data,
- fit::function<void(Status)> callback);
-
- // Download all the chunks of the object with the given id.
- void DownloadFullObject(ObjectIdentifier object_identifier,
- fit::function<void(Status)> callback);
-
- void GetObjectPartFromSync(
- ObjectIdentifier object_identifier, size_t offset, size_t size,
- fit::function<void(Status, fsl::SizedVmo)> callback);
-
- // Reads the content of an object into a provided VMO. Takes into
- // account the global offset and size in order to be able to read only the
- // requested part of an object.
- // |global_offset| is the offset from the beginning of the full object in
- // bytes. |global_size| is the maximum size requested to be read into the vmo.
- // |current_position| is the position of the currently read piece (defined by
- // |object_identifier|) in the full object. |object_size| is the size of the
- // currently read piece.
- void FillBufferWithObjectContent(ObjectIdentifier object_identifier,
- fsl::SizedVmo vmo, int64_t global_offset,
- size_t global_size, int64_t current_position,
- size_t object_size,
- fit::function<void(Status)> callback);
- void FillBufferWithObjectContent(std::unique_ptr<const Object> object,
- fsl::SizedVmo vmo, int64_t global_offset,
- size_t global_size, int64_t current_position,
- size_t object_size,
- fit::function<void(Status)> callback);
-
- // Notifies the registered watchers of |new_commits|.
- void NotifyWatchersOfNewCommits(
-
- const std::vector<std::unique_ptr<const Commit>>& new_commits,
- ChangeSource source);
-
- // Synchronous versions of API methods using coroutines.
- FXL_WARN_UNUSED_RESULT Status
- SynchronousInit(coroutine::CoroutineHandler* handler);
-
- FXL_WARN_UNUSED_RESULT Status
- SynchronousGetCommit(coroutine::CoroutineHandler* handler, CommitId commit_id,
- std::unique_ptr<const Commit>* commit);
-
- FXL_WARN_UNUSED_RESULT Status
- SynchronousAddCommitFromLocal(coroutine::CoroutineHandler* handler,
- std::unique_ptr<const Commit> commit,
- std::vector<ObjectIdentifier> new_objects);
-
- FXL_WARN_UNUSED_RESULT Status SynchronousAddCommitsFromSync(
- coroutine::CoroutineHandler* handler,
- std::vector<CommitIdAndBytes> ids_and_bytes, ChangeSource source,
- std::vector<CommitId>* missing_ids);
-
- FXL_WARN_UNUSED_RESULT Status SynchronousGetUnsyncedCommits(
- coroutine::CoroutineHandler* handler,
- std::vector<std::unique_ptr<const Commit>>* unsynced_commits);
-
- FXL_WARN_UNUSED_RESULT Status SynchronousMarkCommitSynced(
- coroutine::CoroutineHandler* handler, const CommitId& commit_id);
-
- FXL_WARN_UNUSED_RESULT Status SynchronousMarkCommitSyncedInBatch(
- coroutine::CoroutineHandler* handler, PageDb::Batch* batch,
- const CommitId& commit_id);
-
- FXL_WARN_UNUSED_RESULT Status SynchronousAddCommits(
- coroutine::CoroutineHandler* handler,
- std::vector<std::unique_ptr<const Commit>> commits, ChangeSource source,
- std::vector<ObjectIdentifier> new_objects,
- std::vector<CommitId>* missing_ids);
-
- FXL_WARN_UNUSED_RESULT Status SynchronousAddPiece(
- coroutine::CoroutineHandler* handler, ObjectIdentifier object_identifier,
- ChangeSource source, IsObjectSynced is_object_synced,
- std::unique_ptr<DataSource::DataChunk> data);
-
- // Synchronous helper methods.
-
- // Marks this page as online.
- FXL_WARN_UNUSED_RESULT Status SynchronousMarkPageOnline(
- coroutine::CoroutineHandler* handler, PageDb::Batch* batch);
-
- // Updates the given |empty_node_id| to point to the empty node's
- // ObjectIdentifier.
- FXL_WARN_UNUSED_RESULT Status SynchronousGetEmptyNodeIdentifier(
- coroutine::CoroutineHandler* handler, ObjectIdentifier** empty_node_id);
-
- ledger::Environment* environment_;
- encryption::EncryptionService* const encryption_service_;
- const PageId page_id_;
- std::unique_ptr<PageDb> db_;
- std::vector<CommitWatcher*> watchers_;
- callback::ManagedContainer managed_container_;
- PageSyncDelegate* page_sync_;
- bool page_is_online_ = false;
- std::unique_ptr<ObjectIdentifier> empty_node_id_ = nullptr;
-
- callback::OperationSerializer commit_serializer_;
- coroutine::CoroutineManager coroutine_manager_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageStorageImpl);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_PAGE_STORAGE_IMPL_H_
diff --git a/bin/ledger/storage/impl/page_storage_unittest.cc b/bin/ledger/storage/impl/page_storage_unittest.cc
deleted file mode 100644
index a4384b2..0000000
--- a/bin/ledger/storage/impl/page_storage_unittest.cc
+++ /dev/null
@@ -1,2319 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <dirent.h>
-#include <chrono>
-#include <memory>
-#include <queue>
-#include <set>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/arraysize.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/path.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/impl/btree/encoding.h"
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-#include "peridot/bin/ledger/storage/impl/commit_impl.h"
-#include "peridot/bin/ledger/storage/impl/commit_random_impl.h"
-#include "peridot/bin/ledger/storage/impl/constants.h"
-#include "peridot/bin/ledger/storage/impl/journal_impl.h"
-#include "peridot/bin/ledger/storage/impl/leveldb.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/storage/impl/page_db_empty_impl.h"
-#include "peridot/bin/ledger/storage/impl/page_storage_impl.h"
-#include "peridot/bin/ledger/storage/impl/split.h"
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-#include "peridot/bin/ledger/storage/public/commit_watcher.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-using testing::ElementsAre;
-
-namespace storage {
-
-class PageStorageImplAccessorForTest {
- public:
- static void AddPiece(const std::unique_ptr<PageStorageImpl>& storage,
- ObjectIdentifier object_identifier, ChangeSource source,
- IsObjectSynced is_object_synced,
- std::unique_ptr<DataSource::DataChunk> chunk,
- fit::function<void(Status)> callback) {
- storage->AddPiece(std::move(object_identifier), source, is_object_synced,
- std::move(chunk), std::move(callback));
- }
-
- static PageDb& GetDb(const std::unique_ptr<PageStorageImpl>& storage) {
- return *(storage->db_);
- }
-};
-
-namespace {
-
-using coroutine::CoroutineHandler;
-
-std::vector<PageStorage::CommitIdAndBytes> CommitAndBytesFromCommit(
- const Commit& commit) {
- std::vector<PageStorage::CommitIdAndBytes> result;
- result.emplace_back(commit.GetId(), commit.GetStorageBytes().ToString());
- return result;
-}
-
-// DataSource that returns an error on the callback to Get().
-class FakeErrorDataSource : public DataSource {
- public:
- explicit FakeErrorDataSource(async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher) {}
-
- uint64_t GetSize() override { return 1; }
-
- void Get(fit::function<void(std::unique_ptr<DataChunk>, Status)> callback)
- override {
- async::PostTask(dispatcher_, [callback = std::move(callback)] {
- callback(nullptr, DataSource::Status::ERROR);
- });
- }
-
- async_dispatcher_t* const dispatcher_;
-};
-
-class FakeCommitWatcher : public CommitWatcher {
- public:
- FakeCommitWatcher() {}
-
- void OnNewCommits(const std::vector<std::unique_ptr<const Commit>>& commits,
- ChangeSource source) override {
- ++commit_count;
- last_commit_id = commits.back()->GetId();
- last_source = source;
- }
-
- int commit_count = 0;
- CommitId last_commit_id;
- ChangeSource last_source;
-};
-
-class DelayingFakeSyncDelegate : public PageSyncDelegate {
- public:
- explicit DelayingFakeSyncDelegate(
- fit::function<void(fit::closure)> on_get_object)
- : on_get_object_(std::move(on_get_object)) {}
-
- void AddObject(ObjectIdentifier object_identifier, const std::string& value) {
- digest_to_value_[std::move(object_identifier)] = value;
- }
-
- void GetObject(ObjectIdentifier object_identifier,
- fit::function<void(Status, ChangeSource, IsObjectSynced,
- std::unique_ptr<DataSource::DataChunk>)>
- callback) override {
- std::string& value = digest_to_value_[object_identifier];
- object_requests.insert(std::move(object_identifier));
- on_get_object_([callback = std::move(callback), value] {
- callback(Status::OK, ChangeSource::CLOUD, IsObjectSynced::YES,
- DataSource::DataChunk::Create(value));
- });
- }
-
- std::set<ObjectIdentifier> object_requests;
-
- private:
- fit::function<void(fit::closure)> on_get_object_;
- std::map<ObjectIdentifier, std::string> digest_to_value_;
-};
-
-class FakeSyncDelegate : public DelayingFakeSyncDelegate {
- public:
- FakeSyncDelegate()
- : DelayingFakeSyncDelegate([](fit::closure callback) { callback(); }) {}
-};
-
-// Implements |Init()|, |CreateJournalId() and |StartBatch()| and fails with a
-// |NOT_IMPLEMENTED| error in all other cases.
-class FakePageDbImpl : public PageDbEmptyImpl {
- public:
- FakePageDbImpl(rng::Random* random) : random_(random) {}
-
- Status CreateJournalId(CoroutineHandler* /*handler*/,
- JournalType /*journal_type*/, const CommitId& /*base*/,
- JournalId* journal_id) override {
- *journal_id = RandomString(random_, 10);
- return Status::OK;
- }
-
- Status StartBatch(CoroutineHandler* /*handler*/,
- std::unique_ptr<PageDb::Batch>* batch) override {
- *batch = std::make_unique<FakePageDbImpl>(random_);
- return Status::OK;
- }
-
- private:
- rng::Random* const random_;
-};
-
-class PageStorageTest : public ledger::TestWithEnvironment {
- public:
- PageStorageTest() : encryption_service_(dispatcher()) {}
-
- ~PageStorageTest() override {}
-
- // Test:
- void SetUp() override { ResetStorage(); }
-
- void ResetStorage() {
- if (storage_) {
- storage_->SetSyncDelegate(nullptr);
- storage_.reset();
- }
- tmpfs_ = std::make_unique<scoped_tmpfs::ScopedTmpFS>();
- PageId id = RandomString(environment_.random(), 10);
- auto db = std::make_unique<LevelDb>(
- dispatcher(), ledger::DetachedPath(tmpfs_->root_fd()));
- ASSERT_EQ(Status::OK, db->Init());
- storage_ = std::make_unique<PageStorageImpl>(
- &environment_, &encryption_service_, std::move(db), id);
-
- bool called;
- Status status;
- storage_->Init(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(id, storage_->GetId());
- }
-
- protected:
- PageStorage* GetStorage() { return storage_.get(); }
-
- std::vector<CommitId> GetHeads() {
- bool called;
- Status status;
- std::vector<CommitId> ids;
- storage_->GetHeadCommitIds(
- callback::Capture(callback::SetWhenCalled(&called), &status, &ids));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- return ids;
- }
-
- std::unique_ptr<const Commit> GetFirstHead() {
- std::vector<CommitId> ids = GetHeads();
- EXPECT_FALSE(ids.empty());
- return GetCommit(ids[0]);
- }
-
- std::unique_ptr<const Commit> GetCommit(const CommitId& id) {
- bool called;
- Status status;
- std::unique_ptr<const Commit> commit;
- storage_->GetCommit(id, callback::Capture(callback::SetWhenCalled(&called),
- &status, &commit));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- return commit;
- }
-
- ::testing::AssertionResult PutInJournal(Journal* journal,
- const std::string& key,
- ObjectIdentifier object_identifier,
- KeyPriority priority) {
- bool called;
- Status status;
- journal->Put(key, std::move(object_identifier), priority,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
-
- if (!called) {
- return ::testing::AssertionFailure()
- << "Journal::Put for key " << key << " didn't return.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure() << "Journal::Put for key " << key
- << " returned status: " << status;
- }
- return ::testing::AssertionSuccess();
- }
-
- ::testing::AssertionResult DeleteFromJournal(Journal* journal,
- const std::string& key) {
- bool called;
- Status status;
- journal->Delete(
- key, callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
-
- if (!called) {
- return ::testing::AssertionFailure()
- << "Journal::Delete for key " << key << " didn't return.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure() << "Journal::Delete for key " << key
- << " returned status: " << status;
- }
- return ::testing::AssertionSuccess();
- }
-
- std::unique_ptr<const Commit> TryCommitFromSync() {
- ObjectIdentifier root_identifier;
- EXPECT_TRUE(GetEmptyNodeIdentifier(&root_identifier));
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- std::unique_ptr<const Commit> commit =
- CommitImpl::FromContentAndParents(environment_.clock(), storage_.get(),
- root_identifier, std::move(parent));
-
- bool called;
- Status status;
- std::vector<CommitId> missing_ids;
- storage_->AddCommitsFromSync(
- CommitAndBytesFromCommit(*commit), ChangeSource::CLOUD,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &missing_ids));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- return commit;
- }
-
- // Returns an empty pointer if |CommitJournal| times out.
- FXL_WARN_UNUSED_RESULT std::unique_ptr<const Commit> TryCommitJournal(
- std::unique_ptr<Journal> journal, Status expected_status) {
- bool called;
- Status status;
- std::unique_ptr<const Commit> commit;
- storage_->CommitJournal(
- std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
-
- RunLoopUntilIdle();
- EXPECT_EQ(expected_status, status);
- if (!called) {
- return std::unique_ptr<const Commit>();
- }
- return commit;
- }
-
- // Returns an empty pointer if |TryCommitJournal| failed.
- FXL_WARN_UNUSED_RESULT std::unique_ptr<const Commit> TryCommitFromLocal(
- JournalType type, int keys, size_t min_key_size = 0) {
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- storage_->StartCommit(
- GetFirstHead()->GetId(), type,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, journal);
-
- for (int i = 0; i < keys; ++i) {
- auto key = fxl::StringPrintf("key%05d", i);
- if (key.size() < min_key_size) {
- key.resize(min_key_size);
- }
- EXPECT_TRUE(PutInJournal(journal.get(), key,
- RandomObjectIdentifier(environment_.random()),
- KeyPriority::EAGER));
- }
-
- EXPECT_TRUE(DeleteFromJournal(journal.get(), "key_does_not_exist"));
-
- std::unique_ptr<const Commit> commit =
- TryCommitJournal(std::move(journal), Status::OK);
- if (!commit) {
- return commit;
- }
-
- // Check the contents.
- std::vector<Entry> entries = GetCommitContents(*commit);
- EXPECT_EQ(static_cast<size_t>(keys), entries.size());
- for (int i = 0; i < keys; ++i) {
- auto key = fxl::StringPrintf("key%05d", i);
- if (key.size() < min_key_size) {
- key.resize(min_key_size);
- }
- EXPECT_EQ(key, entries[i].key);
- }
-
- return commit;
- }
-
- void TryAddFromLocal(std::string content,
- const ObjectIdentifier& expected_identifier) {
- bool called;
- Status status;
- ObjectIdentifier object_identifier;
- storage_->AddObjectFromLocal(
- ObjectType::BLOB, DataSource::Create(std::move(content)),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(expected_identifier, object_identifier);
- }
-
- std::unique_ptr<const Object> TryGetObject(
- const ObjectIdentifier& object_identifier, PageStorage::Location location,
- Status expected_status = Status::OK) {
- bool called;
- Status status;
- std::unique_ptr<const Object> object;
- storage_->GetObject(
- object_identifier, location,
- callback::Capture(callback::SetWhenCalled(&called), &status, &object));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(expected_status, status);
- return object;
- }
-
- fsl::SizedVmo TryGetObjectPart(const ObjectIdentifier& object_identifier,
- size_t offset, size_t max_size,
- PageStorage::Location location,
- Status expected_status = Status::OK) {
- bool called;
- Status status;
- fsl::SizedVmo vmo;
- storage_->GetObjectPart(
- object_identifier, offset, max_size, location,
- callback::Capture(callback::SetWhenCalled(&called), &status, &vmo));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(expected_status, status);
- return vmo;
- }
-
- std::unique_ptr<const Object> TryGetPiece(
- const ObjectIdentifier& object_identifier,
- Status expected_status = Status::OK) {
- bool called;
- Status status;
- std::unique_ptr<const Object> object;
- storage_->GetPiece(
- object_identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status, &object));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(expected_status, status);
- return object;
- }
-
- std::vector<Entry> GetCommitContents(const Commit& commit) {
- bool called;
- Status status;
- std::vector<Entry> result;
- auto on_next = [&result](Entry e) {
- result.push_back(e);
- return true;
- };
- storage_->GetCommitContents(
- commit, "", std::move(on_next),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- return result;
- }
-
- std::vector<std::unique_ptr<const Commit>> GetUnsyncedCommits() {
- bool called;
- Status status;
- std::vector<std::unique_ptr<const Commit>> commits;
- storage_->GetUnsyncedCommits(
- callback::Capture(callback::SetWhenCalled(&called), &status, &commits));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- return commits;
- }
-
- Status WriteObject(
- CoroutineHandler* handler, ObjectData* data,
- PageDbObjectStatus object_status = PageDbObjectStatus::TRANSIENT) {
- return PageStorageImplAccessorForTest::GetDb(storage_).WriteObject(
- handler, data->object_identifier, data->ToChunk(), object_status);
- }
-
- Status ReadObject(CoroutineHandler* handler,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) {
- return PageStorageImplAccessorForTest::GetDb(storage_).ReadObject(
- handler, object_identifier, object);
- }
-
- ::testing::AssertionResult ObjectIsUntracked(
- ObjectIdentifier object_identifier, bool expected_untracked) {
- bool called;
- Status status;
- bool is_untracked;
- storage_->ObjectIsUntracked(
- object_identifier, callback::Capture(callback::SetWhenCalled(&called),
- &status, &is_untracked));
- RunLoopUntilIdle();
-
- if (!called) {
- return ::testing::AssertionFailure()
- << "ObjectIsUntracked for id " << object_identifier
- << " didn't return.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "ObjectIsUntracked for id " << object_identifier
- << " returned status " << status;
- }
- if (is_untracked != expected_untracked) {
- return ::testing::AssertionFailure()
- << "For id " << object_identifier
- << " expected to find the object " << (is_untracked ? "un" : "")
- << "tracked, but was " << (expected_untracked ? "un" : "")
- << "tracked, instead.";
- }
- return ::testing::AssertionSuccess();
- }
-
- ::testing::AssertionResult IsPieceSynced(ObjectIdentifier object_identifier,
- bool expected_synced) {
- bool called;
- Status status;
- bool is_synced;
- storage_->IsPieceSynced(object_identifier,
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &is_synced));
- RunLoopUntilIdle();
-
- if (!called) {
- return ::testing::AssertionFailure()
- << "IsPieceSynced for id " << object_identifier
- << " didn't return.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "IsPieceSynced for id " << object_identifier
- << " returned status " << status;
- }
- if (is_synced != expected_synced) {
- return ::testing::AssertionFailure()
- << "For id " << object_identifier
- << " expected to find the object " << (is_synced ? "un" : "")
- << "synced, but was " << (expected_synced ? "un" : "")
- << "synced, instead.";
- }
- return ::testing::AssertionSuccess();
- }
-
- ::testing::AssertionResult CreateNodeFromIdentifier(
- ObjectIdentifier identifier,
- std::unique_ptr<const btree::TreeNode>* node) {
- bool called;
- Status status;
- std::unique_ptr<const btree::TreeNode> result;
- btree::TreeNode::FromIdentifier(
- GetStorage(), std::move(identifier),
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- RunLoopUntilIdle();
-
- if (!called) {
- return ::testing::AssertionFailure()
- << "TreeNode::FromIdentifier callback was not executed.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "TreeNode::FromIdentifier failed with status " << status;
- }
- node->swap(result);
- return ::testing::AssertionSuccess();
- }
-
- ::testing::AssertionResult CreateNodeFromEntries(
- const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children,
- std::unique_ptr<const btree::TreeNode>* node) {
- bool called;
- Status status;
- ObjectIdentifier identifier;
- btree::TreeNode::FromEntries(
- GetStorage(), 0u, entries, children,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &identifier));
- RunLoopUntilIdle();
- if (!called) {
- return ::testing::AssertionFailure()
- << "TreeNode::FromEntries callback was not executed.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "TreeNode::FromEntries failed with status " << status;
- }
- return CreateNodeFromIdentifier(identifier, node);
- }
-
- ::testing::AssertionResult GetEmptyNodeIdentifier(
- ObjectIdentifier* empty_node_identifier) {
- bool called;
- Status status;
- btree::TreeNode::Empty(GetStorage(),
- callback::Capture(callback::SetWhenCalled(&called),
- &status, empty_node_identifier));
- RunLoopUntilIdle();
- if (!called) {
- return ::testing::AssertionFailure()
- << "TreeNode::Empty callback was not executed.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "TreeNode::Empty failed with status " << status;
- }
- return ::testing::AssertionSuccess();
- }
-
- std::unique_ptr<scoped_tmpfs::ScopedTmpFS> tmpfs_;
- encryption::FakeEncryptionService encryption_service_;
- std::unique_ptr<PageStorageImpl> storage_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageStorageTest);
-};
-
-TEST_F(PageStorageTest, AddGetLocalCommits) {
- // Search for a commit id that doesn't exist and see the error.
- bool called;
- Status status;
- std::unique_ptr<const Commit> lookup_commit;
- storage_->GetCommit(RandomCommitId(environment_.random()),
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &lookup_commit));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
- EXPECT_FALSE(lookup_commit);
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(),
- RandomObjectIdentifier(environment_.random()), std::move(parent));
- CommitId id = commit->GetId();
- std::string storage_bytes = commit->GetStorageBytes().ToString();
-
- // Search for a commit that exist and check the content.
- storage_->AddCommitFromLocal(
- std::move(commit), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::unique_ptr<const Commit> found = GetCommit(id);
- EXPECT_EQ(storage_bytes, found->GetStorageBytes());
-}
-
-TEST_F(PageStorageTest, AddCommitFromLocalDoNotMarkUnsynedAlreadySyncedCommit) {
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(),
- RandomObjectIdentifier(environment_.random()), std::move(parent));
- CommitId id = commit->GetId();
- std::string storage_bytes = commit->GetStorageBytes().ToString();
-
- bool called;
- Status status;
- storage_->AddCommitFromLocal(
- commit->Clone(), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- auto commits = GetUnsyncedCommits();
- EXPECT_EQ(1u, commits.size());
- EXPECT_EQ(id, commits[0]->GetId());
-
- storage_->MarkCommitSynced(
- id, callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- // Add the commit again.
- storage_->AddCommitFromLocal(
- commit->Clone(), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- // Check that the commit is not marked unsynced.
- commits = GetUnsyncedCommits();
- EXPECT_EQ(0u, commits.size());
-}
-
-TEST_F(PageStorageTest, AddCommitBeforeParentsError) {
- // Try to add a commit before its parent and see the error.
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(
- std::make_unique<CommitRandomImpl>(environment_.random()));
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(),
- RandomObjectIdentifier(environment_.random()), std::move(parent));
-
- bool called;
- Status status;
- storage_->AddCommitFromLocal(
- std::move(commit), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
-}
-
-TEST_F(PageStorageTest, AddCommitsOutOfOrderError) {
- std::unique_ptr<const btree::TreeNode> node;
- ASSERT_TRUE(CreateNodeFromEntries({}, {}, &node));
- ObjectIdentifier root_identifier = node->GetIdentifier();
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- auto commit1 = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), root_identifier, std::move(parent));
- parent.clear();
- parent.push_back(commit1->Clone());
- auto commit2 = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), root_identifier, std::move(parent));
-
- std::vector<PageStorage::CommitIdAndBytes> commits_and_bytes;
- commits_and_bytes.emplace_back(commit2->GetId(),
- commit2->GetStorageBytes().ToString());
- commits_and_bytes.emplace_back(commit1->GetId(),
- commit1->GetStorageBytes().ToString());
-
- bool called;
- Status status;
- std::vector<CommitId> missing_ids;
- storage_->AddCommitsFromSync(
- std::move(commits_and_bytes), ChangeSource::CLOUD,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &missing_ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
-}
-
-TEST_F(PageStorageTest, AddGetSyncedCommits) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- FakeSyncDelegate sync;
- storage_->SetSyncDelegate(&sync);
-
- // Create a node with 2 values.
- ObjectData lazy_value("Some data", InlineBehavior::PREVENT);
- ObjectData eager_value("More data", InlineBehavior::PREVENT);
- std::vector<Entry> entries = {
- Entry{"key0", lazy_value.object_identifier, KeyPriority::LAZY},
- Entry{"key1", eager_value.object_identifier, KeyPriority::EAGER},
- };
- std::unique_ptr<const btree::TreeNode> node;
- ASSERT_TRUE(CreateNodeFromEntries(entries, {}, &node));
- ObjectIdentifier root_identifier = node->GetIdentifier();
-
- // Add the three objects to FakeSyncDelegate.
- sync.AddObject(lazy_value.object_identifier, lazy_value.value);
- sync.AddObject(eager_value.object_identifier, eager_value.value);
-
- {
- // Ensure root_object is not kept, as the storage it depends on will be
- // deleted.
- std::unique_ptr<const Object> root_object =
- TryGetObject(root_identifier, PageStorage::Location::NETWORK);
-
- fxl::StringView root_data;
- ASSERT_EQ(Status::OK, root_object->GetData(&root_data));
- sync.AddObject(root_identifier, root_data.ToString());
- }
-
- // Reset and clear the storage.
- ResetStorage();
- storage_->SetSyncDelegate(&sync);
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- std::unique_ptr<const Commit> commit =
- CommitImpl::FromContentAndParents(environment_.clock(), storage_.get(),
- root_identifier, std::move(parent));
- CommitId id = commit->GetId();
-
- // Adding the commit should only request the tree node and the eager value.
- sync.object_requests.clear();
- bool called;
- Status status;
- std::vector<CommitId> missing_ids;
- storage_->AddCommitsFromSync(
- CommitAndBytesFromCommit(*commit), ChangeSource::CLOUD,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &missing_ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(2u, sync.object_requests.size());
- EXPECT_TRUE(sync.object_requests.find(root_identifier) !=
- sync.object_requests.end());
- EXPECT_TRUE(sync.object_requests.find(eager_value.object_identifier) !=
- sync.object_requests.end());
-
- // Adding the same commit twice should not request any objects from sync.
- sync.object_requests.clear();
- storage_->AddCommitsFromSync(
- CommitAndBytesFromCommit(*commit), ChangeSource::CLOUD,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &missing_ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(sync.object_requests.empty());
-
- std::unique_ptr<const Commit> found = GetCommit(id);
- EXPECT_EQ(commit->GetStorageBytes(), found->GetStorageBytes());
-
- // Check that the commit is not marked as unsynced.
- std::vector<std::unique_ptr<const Commit>> commits = GetUnsyncedCommits();
- EXPECT_TRUE(commits.empty());
- });
-}
-
-// Check that receiving a remote commit that is already present locally but not
-// synced will mark the commit as synced.
-TEST_F(PageStorageTest, MarkRemoteCommitSynced) {
- FakeSyncDelegate sync;
- storage_->SetSyncDelegate(&sync);
-
- std::unique_ptr<const btree::TreeNode> node;
- ASSERT_TRUE(CreateNodeFromEntries({}, {}, &node));
- ObjectIdentifier root_identifier = node->GetIdentifier();
-
- std::unique_ptr<const Object> root_object =
- TryGetObject(root_identifier, PageStorage::Location::NETWORK);
-
- fxl::StringView root_data;
- ASSERT_EQ(Status::OK, root_object->GetData(&root_data));
- sync.AddObject(root_identifier, root_data.ToString());
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), root_identifier, std::move(parent));
- CommitId id = commit->GetId();
-
- bool called;
- Status status;
- storage_->AddCommitFromLocal(
- std::move(commit), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_EQ(1u, GetUnsyncedCommits().size());
- storage_->GetCommit(id, callback::Capture(callback::SetWhenCalled(&called),
- &status, &commit));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::vector<PageStorage::CommitIdAndBytes> commits_and_bytes;
- commits_and_bytes.emplace_back(commit->GetId(),
- commit->GetStorageBytes().ToString());
- std::vector<CommitId> missing_ids;
- storage_->AddCommitsFromSync(
- std::move(commits_and_bytes), ChangeSource::CLOUD,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &missing_ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- EXPECT_EQ(0u, GetUnsyncedCommits().size());
-}
-
-TEST_F(PageStorageTest, SyncCommits) {
- std::vector<std::unique_ptr<const Commit>> commits = GetUnsyncedCommits();
-
- // Initially there should be no unsynced commits.
- EXPECT_TRUE(commits.empty());
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- // After adding a commit it should marked as unsynced.
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(),
- RandomObjectIdentifier(environment_.random()), std::move(parent));
- CommitId id = commit->GetId();
- std::string storage_bytes = commit->GetStorageBytes().ToString();
-
- bool called;
- Status status;
- storage_->AddCommitFromLocal(
- std::move(commit), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- commits = GetUnsyncedCommits();
- EXPECT_EQ(1u, commits.size());
- EXPECT_EQ(storage_bytes, commits[0]->GetStorageBytes());
-
- // Mark it as synced.
- storage_->MarkCommitSynced(
- id, callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- commits = GetUnsyncedCommits();
- EXPECT_TRUE(commits.empty());
-}
-
-TEST_F(PageStorageTest, HeadCommits) {
- // Every page should have one initial head commit.
- std::vector<CommitId> heads = GetHeads();
- EXPECT_EQ(1u, heads.size());
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- // Adding a new commit with the previous head as its parent should replace the
- // old head.
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(),
- RandomObjectIdentifier(environment_.random()), std::move(parent));
- CommitId id = commit->GetId();
-
- bool called;
- Status status;
- storage_->AddCommitFromLocal(
- std::move(commit), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- heads = GetHeads();
- ASSERT_EQ(1u, heads.size());
- EXPECT_EQ(id, heads[0]);
-}
-
-TEST_F(PageStorageTest, CreateJournals) {
- // Explicit journal.
- auto left_commit = TryCommitFromLocal(JournalType::EXPLICIT, 5);
- ASSERT_TRUE(left_commit);
- auto right_commit = TryCommitFromLocal(JournalType::IMPLICIT, 10);
- ASSERT_TRUE(right_commit);
-
- // Journal for merge commit.
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- storage_->StartMergeCommit(
- left_commit->GetId(), right_commit->GetId(),
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, journal);
-
- storage_->RollbackJournal(
- std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-}
-
-TEST_F(PageStorageTest, CreateJournalHugeNode) {
- std::unique_ptr<const Commit> commit =
- TryCommitFromLocal(JournalType::EXPLICIT, 500, 1024);
- ASSERT_TRUE(commit);
- std::vector<Entry> entries = GetCommitContents(*commit);
-
- EXPECT_EQ(500u, entries.size());
- for (const auto& entry : entries) {
- EXPECT_EQ(1024u, entry.key.size());
- }
-
- // Check that all node's parts are marked as unsynced.
- bool called;
- Status status;
- std::vector<ObjectIdentifier> object_identifiers;
- storage_->GetUnsyncedPieces(callback::Capture(
- callback::SetWhenCalled(&called), &status, &object_identifiers));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- bool found_index = false;
- std::set<ObjectIdentifier> unsynced_identifiers(object_identifiers.begin(),
- object_identifiers.end());
- for (const auto& identifier : unsynced_identifiers) {
- EXPECT_FALSE(GetObjectDigestInfo(identifier.object_digest()).is_inlined());
-
- if (GetObjectDigestInfo(identifier.object_digest()).piece_type ==
- PieceType::INDEX) {
- found_index = true;
- std::set<ObjectIdentifier> sub_identifiers;
- IterationStatus iteration_status = IterationStatus::ERROR;
- CollectPieces(
- identifier,
- [this](ObjectIdentifier identifier,
- fit::function<void(Status, fxl::StringView)> callback) {
- storage_->GetPiece(
- std::move(identifier),
- [callback = std::move(callback)](
- Status status, std::unique_ptr<const Object> object) {
- if (status != Status::OK) {
- callback(status, "");
- return;
- }
- fxl::StringView data;
- status = object->GetData(&data);
- callback(status, data);
- });
- },
- [&iteration_status, &sub_identifiers](IterationStatus status,
- ObjectIdentifier identifier) {
- iteration_status = status;
- if (status == IterationStatus::IN_PROGRESS) {
- EXPECT_TRUE(sub_identifiers.insert(identifier).second);
- }
- return true;
- });
- RunLoopUntilIdle();
- EXPECT_EQ(IterationStatus::DONE, iteration_status);
- for (const auto& identifier : sub_identifiers) {
- EXPECT_EQ(1u, unsynced_identifiers.count(identifier));
- }
- }
- }
- EXPECT_TRUE(found_index);
-}
-
-TEST_F(PageStorageTest, JournalCommitFailsAfterFailedOperation) {
- // Using FakePageDbImpl will cause all PageDb operations that have to do
- // with journal entry update, to fail with a NOT_IMPLEMENTED error.
- auto test_storage = std::make_unique<PageStorageImpl>(
- &environment_, &encryption_service_,
- std::make_unique<FakePageDbImpl>(environment_.random()),
- RandomString(environment_.random(), 10));
-
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- // Explicit journals.
- // The first call will fail because FakePageDbImpl::AddJournalEntry()
- // returns an error. After a failed call all other Put/Delete/Commit
- // operations should fail with ILLEGAL_STATE.
- test_storage->StartCommit(
- RandomCommitId(environment_.random()), JournalType::EXPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- ObjectIdentifier random_identifier =
- RandomObjectIdentifier(environment_.random());
-
- journal->Put("key", random_identifier, KeyPriority::EAGER,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_NE(Status::OK, status);
-
- journal->Put("key", random_identifier, KeyPriority::EAGER,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::ILLEGAL_STATE, status);
-
- journal->Delete("key",
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::ILLEGAL_STATE, status);
-
- journal->Clear(callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::ILLEGAL_STATE, status);
-
- ASSERT_FALSE(TryCommitJournal(std::move(journal), Status::ILLEGAL_STATE));
-
- // Implicit journals.
- // All calls will fail because of FakePageDbImpl implementation, not because
- // of an ILLEGAL_STATE error.
- test_storage->StartCommit(
- RandomCommitId(environment_.random()), JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- journal->Put("key", random_identifier, KeyPriority::EAGER,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_NE(Status::OK, status);
-
- journal->Put("key", random_identifier, KeyPriority::EAGER,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_NE(Status::ILLEGAL_STATE, status);
-
- journal->Delete("key",
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_NE(Status::ILLEGAL_STATE, status);
-
- journal->Clear(callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_NE(Status::ILLEGAL_STATE, status);
-
- std::unique_ptr<const Commit> commit;
- test_storage->CommitJournal(
- std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_NE(Status::ILLEGAL_STATE, status);
-}
-
-TEST_F(PageStorageTest, DestroyUncommittedJournal) {
- // It is not an error if a journal is not committed or rolled back.
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- storage_->StartCommit(
- GetFirstHead()->GetId(), JournalType::EXPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_NE(nullptr, journal);
- EXPECT_TRUE(PutInJournal(journal.get(), "key",
- RandomObjectIdentifier(environment_.random()),
- KeyPriority::EAGER));
-}
-
-TEST_F(PageStorageTest, AddObjectFromLocal) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("Some data", InlineBehavior::PREVENT);
-
- bool called;
- Status status;
- ObjectIdentifier object_identifier;
- storage_->AddObjectFromLocal(
- ObjectType::BLOB, data.ToDataSource(),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(data.object_identifier, object_identifier);
-
- std::unique_ptr<const Object> object;
- ASSERT_EQ(Status::OK, ReadObject(handler, object_identifier, &object));
- fxl::StringView content;
- ASSERT_EQ(Status::OK, object->GetData(&content));
- EXPECT_EQ(data.value, content);
- EXPECT_TRUE(ObjectIsUntracked(object_identifier, true));
- EXPECT_TRUE(IsPieceSynced(object_identifier, false));
- });
-}
-
-TEST_F(PageStorageTest, AddSmallObjectFromLocal) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("Some data");
-
- bool called;
- Status status;
- ObjectIdentifier object_identifier;
- storage_->AddObjectFromLocal(
- ObjectType::BLOB, data.ToDataSource(),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(data.object_identifier, object_identifier);
- EXPECT_EQ(data.value,
- ExtractObjectDigestData(object_identifier.object_digest()));
-
- std::unique_ptr<const Object> object;
- EXPECT_EQ(Status::NOT_FOUND,
- ReadObject(handler, object_identifier, &object));
- // Inline objects do not need to ever be tracked.
- EXPECT_TRUE(ObjectIsUntracked(object_identifier, false));
- });
-}
-
-TEST_F(PageStorageTest, InterruptAddObjectFromLocal) {
- ObjectData data("Some data");
-
- storage_->AddObjectFromLocal(
- ObjectType::BLOB, data.ToDataSource(),
- [](Status returned_status, ObjectIdentifier object_identifier) {});
-
- // Checking that we do not crash when deleting the storage while an AddObject
- // call is in progress.
- storage_.reset();
-}
-
-TEST_F(PageStorageTest, AddObjectFromLocalError) {
- auto data_source = std::make_unique<FakeErrorDataSource>(dispatcher());
- bool called;
- Status status;
- ObjectIdentifier object_identifier;
- storage_->AddObjectFromLocal(
- ObjectType::BLOB, std::move(data_source),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::IO_ERROR, status);
-}
-
-TEST_F(PageStorageTest, AddLocalPiece) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("Some data", InlineBehavior::PREVENT);
-
- bool called;
- Status status;
- PageStorageImplAccessorForTest::AddPiece(
- storage_, data.object_identifier, ChangeSource::LOCAL,
- IsObjectSynced::NO, data.ToChunk(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::unique_ptr<const Object> object;
- ASSERT_EQ(Status::OK, ReadObject(handler, data.object_identifier, &object));
- fxl::StringView content;
- ASSERT_EQ(Status::OK, object->GetData(&content));
- EXPECT_EQ(data.value, content);
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, true));
- EXPECT_TRUE(IsPieceSynced(data.object_identifier, false));
- });
-}
-
-TEST_F(PageStorageTest, AddSyncPiece) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("Some data", InlineBehavior::PREVENT);
-
- bool called;
- Status status;
- PageStorageImplAccessorForTest::AddPiece(
- storage_, data.object_identifier, ChangeSource::CLOUD,
- IsObjectSynced::YES, data.ToChunk(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::unique_ptr<const Object> object;
- ASSERT_EQ(Status::OK, ReadObject(handler, data.object_identifier, &object));
- fxl::StringView content;
- ASSERT_EQ(Status::OK, object->GetData(&content));
- EXPECT_EQ(data.value, content);
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, false));
- EXPECT_TRUE(IsPieceSynced(data.object_identifier, true));
- });
-}
-
-TEST_F(PageStorageTest, AddP2PPiece) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("Some data", InlineBehavior::PREVENT);
-
- bool called;
- Status status;
- PageStorageImplAccessorForTest::AddPiece(
- storage_, data.object_identifier, ChangeSource::P2P, IsObjectSynced::NO,
- data.ToChunk(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::unique_ptr<const Object> object;
- ASSERT_EQ(Status::OK, ReadObject(handler, data.object_identifier, &object));
- fxl::StringView content;
- ASSERT_EQ(Status::OK, object->GetData(&content));
- EXPECT_EQ(data.value, content);
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, false));
- EXPECT_TRUE(IsPieceSynced(data.object_identifier, false));
- });
-}
-
-TEST_F(PageStorageTest, GetObject) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("Some data");
- ASSERT_EQ(Status::OK, WriteObject(handler, &data));
-
- std::unique_ptr<const Object> object =
- TryGetObject(data.object_identifier, PageStorage::Location::LOCAL);
- EXPECT_EQ(data.object_identifier, object->GetIdentifier());
- fxl::StringView object_data;
- ASSERT_EQ(Status::OK, object->GetData(&object_data));
- EXPECT_EQ(data.value, convert::ToString(object_data));
- });
-}
-
-TEST_F(PageStorageTest, GetObjectPart) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("_Some data_");
- ASSERT_EQ(Status::OK, WriteObject(handler, &data));
-
- fsl::SizedVmo object_part = TryGetObjectPart(
- data.object_identifier, 1, data.size - 2, PageStorage::Location::LOCAL);
- std::string object_part_data;
- ASSERT_TRUE(fsl::StringFromVmo(object_part, &object_part_data));
- EXPECT_EQ(data.value.substr(1, data.size - 2),
- convert::ToString(object_part_data));
- });
-}
-
-TEST_F(PageStorageTest, GetObjectPartLargeOffset) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("_Some data_");
- ASSERT_EQ(Status::OK, WriteObject(handler, &data));
-
- fsl::SizedVmo object_part =
- TryGetObjectPart(data.object_identifier, data.size * 2, data.size,
- PageStorage::Location::LOCAL);
- std::string object_part_data;
- ASSERT_TRUE(fsl::StringFromVmo(object_part, &object_part_data));
- EXPECT_EQ("", convert::ToString(object_part_data));
- });
-}
-
-TEST_F(PageStorageTest, GetObjectPartLargeMaxSize) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("_Some data_");
- ASSERT_EQ(Status::OK, WriteObject(handler, &data));
-
- fsl::SizedVmo object_part = TryGetObjectPart(
- data.object_identifier, 0, data.size * 2, PageStorage::Location::LOCAL);
- std::string object_part_data;
- ASSERT_TRUE(fsl::StringFromVmo(object_part, &object_part_data));
- EXPECT_EQ(data.value, convert::ToString(object_part_data));
- });
-}
-
-TEST_F(PageStorageTest, GetObjectPartNegativeArgs) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- ObjectData data("_Some data_");
- ASSERT_EQ(Status::OK, WriteObject(handler, &data));
-
- fsl::SizedVmo object_part =
- TryGetObjectPart(data.object_identifier, -data.size + 1, -1,
- PageStorage::Location::LOCAL);
- std::string object_part_data;
- ASSERT_TRUE(fsl::StringFromVmo(object_part, &object_part_data));
- EXPECT_EQ(data.value.substr(1, data.size - 1),
- convert::ToString(object_part_data));
- });
-}
-
-TEST_F(PageStorageTest, GetLargeObjectPart) {
- std::string data_str = RandomString(environment_.random(), 65536);
- size_t offset = 6144;
- size_t size = 49152;
-
- ObjectData data(std::move(data_str), ObjectType::TREE_NODE,
- InlineBehavior::PREVENT);
-
- ASSERT_EQ(
- PieceType::INDEX,
- GetObjectDigestInfo(data.object_identifier.object_digest()).piece_type);
-
- bool called;
- Status status;
- ObjectIdentifier object_identifier;
- storage_->AddObjectFromLocal(
- ObjectType::TREE_NODE, data.ToDataSource(),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(data.object_identifier, object_identifier);
-
- fsl::SizedVmo object_part = TryGetObjectPart(object_identifier, offset, size,
- PageStorage::Location::LOCAL);
- std::string object_part_data;
- ASSERT_TRUE(fsl::StringFromVmo(object_part, &object_part_data));
- std::string result_str = convert::ToString(object_part_data);
- EXPECT_EQ(size, result_str.size());
- EXPECT_EQ(data.value.substr(offset, size), result_str);
-}
-
-TEST_F(PageStorageTest, GetObjectPartFromSync) {
- ObjectData data("_Some data_", InlineBehavior::PREVENT);
- FakeSyncDelegate sync;
- sync.AddObject(data.object_identifier, data.value);
- storage_->SetSyncDelegate(&sync);
-
- fsl::SizedVmo object_part = TryGetObjectPart(
- data.object_identifier, 1, data.size - 2, PageStorage::Location::NETWORK);
- std::string object_part_data;
- ASSERT_TRUE(fsl::StringFromVmo(object_part, &object_part_data));
- EXPECT_EQ(data.value.substr(1, data.size - 2),
- convert::ToString(object_part_data));
-
- storage_->SetSyncDelegate(nullptr);
- ObjectData other_data("_Some other data_", InlineBehavior::PREVENT);
- TryGetObjectPart(other_data.object_identifier, 1, other_data.size - 2,
- PageStorage::Location::LOCAL, Status::NOT_FOUND);
- TryGetObjectPart(other_data.object_identifier, 1, other_data.size - 2,
- PageStorage::Location::NETWORK, Status::NOT_CONNECTED_ERROR);
-}
-
-TEST_F(PageStorageTest, GetObjectFromSync) {
- ObjectData data("Some data", InlineBehavior::PREVENT);
- FakeSyncDelegate sync;
- sync.AddObject(data.object_identifier, data.value);
- storage_->SetSyncDelegate(&sync);
-
- std::unique_ptr<const Object> object =
- TryGetObject(data.object_identifier, PageStorage::Location::NETWORK);
- EXPECT_EQ(data.object_identifier, object->GetIdentifier());
- fxl::StringView object_data;
- ASSERT_EQ(Status::OK, object->GetData(&object_data));
- EXPECT_EQ(data.value, convert::ToString(object_data));
-
- storage_->SetSyncDelegate(nullptr);
- ObjectData other_data("Some other data", InlineBehavior::PREVENT);
- TryGetObject(other_data.object_identifier, PageStorage::Location::LOCAL,
- Status::NOT_FOUND);
- TryGetObject(other_data.object_identifier, PageStorage::Location::NETWORK,
- Status::NOT_CONNECTED_ERROR);
-}
-
-TEST_F(PageStorageTest, GetObjectFromSyncWrongId) {
- ObjectData data("Some data", InlineBehavior::PREVENT);
- ObjectData data2("Some data2", InlineBehavior::PREVENT);
- FakeSyncDelegate sync;
- sync.AddObject(data.object_identifier, data2.value);
- storage_->SetSyncDelegate(&sync);
-
- TryGetObject(data.object_identifier, PageStorage::Location::NETWORK,
- Status::OBJECT_DIGEST_MISMATCH);
-}
-
-TEST_F(PageStorageTest, AddAndGetHugeTreenodeFromLocal) {
- std::string data_str = RandomString(environment_.random(), 65536);
-
- ObjectData data(std::move(data_str), ObjectType::TREE_NODE,
- InlineBehavior::PREVENT);
- ASSERT_EQ(
- ObjectType::TREE_NODE,
- GetObjectDigestInfo(data.object_identifier.object_digest()).object_type);
- ASSERT_EQ(
- PieceType::INDEX,
- GetObjectDigestInfo(data.object_identifier.object_digest()).piece_type);
- ASSERT_EQ(
- InlinedPiece::NO,
- GetObjectDigestInfo(data.object_identifier.object_digest()).inlined);
-
- bool called;
- Status status;
- ObjectIdentifier object_identifier;
- storage_->AddObjectFromLocal(
- ObjectType::TREE_NODE, data.ToDataSource(),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(data.object_identifier, object_identifier);
-
- std::unique_ptr<const Object> object =
- TryGetObject(object_identifier, PageStorage::Location::LOCAL);
- fxl::StringView content;
- ASSERT_EQ(Status::OK, object->GetData(&content));
- EXPECT_EQ(data.value, content);
- EXPECT_TRUE(ObjectIsUntracked(object_identifier, true));
- EXPECT_TRUE(IsPieceSynced(object_identifier, false));
-
- // Check that the object is encoded with an index, and is different than the
- // piece obtained at |object_identifier|.
- std::unique_ptr<const Object> piece = TryGetPiece(object_identifier);
- fxl::StringView piece_content;
- ASSERT_EQ(Status::OK, piece->GetData(&piece_content));
- EXPECT_NE(content, piece_content);
-}
-
-TEST_F(PageStorageTest, UnsyncedPieces) {
- ObjectData data_array[] = {
- ObjectData("Some data", InlineBehavior::PREVENT),
- ObjectData("Some more data", InlineBehavior::PREVENT),
- ObjectData("Even more data", InlineBehavior::PREVENT),
- };
- constexpr size_t size = arraysize(data_array);
- for (auto& data : data_array) {
- TryAddFromLocal(data.value, data.object_identifier);
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, true));
- EXPECT_TRUE(IsPieceSynced(data.object_identifier, false));
- }
-
- std::vector<CommitId> commits;
-
- // Add one key-value pair per commit.
- for (size_t i = 0; i < size; ++i) {
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- storage_->StartCommit(
- GetFirstHead()->GetId(), JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_TRUE(PutInJournal(journal.get(), fxl::StringPrintf("key%lu", i),
- data_array[i].object_identifier,
- KeyPriority::LAZY));
- EXPECT_TRUE(TryCommitJournal(std::move(journal), Status::OK));
- commits.push_back(GetFirstHead()->GetId());
- }
-
- // GetUnsyncedPieces should return the ids of all objects: 3 values and
- // the 3 root nodes of the 3 commits.
- bool called;
- Status status;
- std::vector<ObjectIdentifier> object_identifiers;
- storage_->GetUnsyncedPieces(callback::Capture(
- callback::SetWhenCalled(&called), &status, &object_identifiers));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(6u, object_identifiers.size());
- for (size_t i = 0; i < size; ++i) {
- std::unique_ptr<const Commit> commit = GetCommit(commits[i]);
- EXPECT_TRUE(std::find_if(object_identifiers.begin(),
- object_identifiers.end(),
- [&](const auto& identifier) {
- return identifier == commit->GetRootIdentifier();
- }) != object_identifiers.end());
- }
- for (auto& data : data_array) {
- EXPECT_TRUE(std::find(object_identifiers.begin(), object_identifiers.end(),
- data.object_identifier) != object_identifiers.end());
- }
-
- // Mark the 2nd object as synced. We now expect to still find the 2 unsynced
- // values and the (also unsynced) root node.
- storage_->MarkPieceSynced(
- data_array[1].object_identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- std::vector<ObjectIdentifier> objects;
- storage_->GetUnsyncedPieces(
- callback::Capture(callback::SetWhenCalled(&called), &status, &objects));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(5u, objects.size());
- std::unique_ptr<const Commit> commit = GetCommit(commits[2]);
- EXPECT_TRUE(std::find(objects.begin(), objects.end(),
- commit->GetRootIdentifier()) != objects.end());
- EXPECT_TRUE(std::find(objects.begin(), objects.end(),
- data_array[0].object_identifier) != objects.end());
- EXPECT_TRUE(std::find(objects.begin(), objects.end(),
- data_array[2].object_identifier) != objects.end());
-}
-
-TEST_F(PageStorageTest, PageIsSynced) {
- ObjectData data_array[] = {
- ObjectData("Some data", InlineBehavior::PREVENT),
- ObjectData("Some more data", InlineBehavior::PREVENT),
- ObjectData("Even more data", InlineBehavior::PREVENT),
- };
- constexpr size_t size = arraysize(data_array);
- for (auto& data : data_array) {
- TryAddFromLocal(data.value, data.object_identifier);
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, true));
- EXPECT_TRUE(IsPieceSynced(data.object_identifier, false));
- }
-
- // The objects have not been added in a commit: there is nothing to sync and
- // the page is considered synced.
- bool called;
- Status status;
- bool is_synced;
- storage_->IsSynced(
- callback::Capture(callback::SetWhenCalled(&called), &status, &is_synced));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(true, is_synced);
-
- // Add all objects in one commit.
- called = false;
- std::unique_ptr<Journal> journal;
- storage_->StartCommit(
- GetFirstHead()->GetId(), JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- for (size_t i = 0; i < size; ++i) {
- EXPECT_TRUE(PutInJournal(journal.get(), fxl::StringPrintf("key%lu", i),
- data_array[i].object_identifier,
- KeyPriority::LAZY));
- }
- EXPECT_TRUE(TryCommitJournal(std::move(journal), Status::OK));
- CommitId commit_id = GetFirstHead()->GetId();
-
- // After commiting, the page is unsynced.
- called = false;
- storage_->IsSynced(
- callback::Capture(callback::SetWhenCalled(&called), &status, &is_synced));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(is_synced);
- // Mark objects (and the root tree node) as synced and expect that the page is
- // still unsynced.
- for (const auto& data : data_array) {
- called = false;
- storage_->MarkPieceSynced(
- data.object_identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- }
-
- called = false;
- storage_->MarkPieceSynced(
- GetFirstHead()->GetRootIdentifier(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- called = false;
- storage_->IsSynced(
- callback::Capture(callback::SetWhenCalled(&called), &status, &is_synced));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(is_synced);
-
- // Mark the commit as synced and expect that the page is synced.
- called = false;
- storage_->MarkCommitSynced(
- commit_id, callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- called = false;
- storage_->IsSynced(
- callback::Capture(callback::SetWhenCalled(&called), &status, &is_synced));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(is_synced);
-
- // All objects should be synced now.
- for (auto& data : data_array) {
- EXPECT_TRUE(IsPieceSynced(data.object_identifier, true));
- }
-}
-
-TEST_F(PageStorageTest, PageIsMarkedOnlineAfterCloudSync) {
- // Check that the page is initially not marked as online.
- EXPECT_FALSE(storage_->IsOnline());
-
- // Create a local commit: the page is still not online.
- int size = 10;
- std::unique_ptr<const Commit> commit =
- TryCommitFromLocal(JournalType::EXPLICIT, size);
- EXPECT_FALSE(storage_->IsOnline());
-
- // Mark all objects as synced. The page is still not online: other devices
- // will only see these objects if the corresponding commit is also synced to
- // the cloud.
- bool called;
- Status status;
- std::vector<ObjectIdentifier> object_identifiers;
- storage_->GetUnsyncedPieces(callback::Capture(
- callback::SetWhenCalled(&called), &status, &object_identifiers));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- for (ObjectIdentifier& object_identifier : object_identifiers) {
- storage_->MarkPieceSynced(
- object_identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- }
- EXPECT_FALSE(storage_->IsOnline());
-
- // Mark the commit as synced. The page should now be marked as online.
- storage_->MarkCommitSynced(
- commit->GetId(),
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(storage_->IsOnline());
-}
-
-TEST_F(PageStorageTest, PageIsMarkedOnlineSyncWithPeer) {
- // Check that the page is initially not marked as online.
- EXPECT_FALSE(storage_->IsOnline());
-
- // Mark the page as synced to peer and expect that it is marked as online.
- bool called;
- Status status;
- storage_->MarkSyncedToPeer(
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(storage_->IsOnline());
-}
-
-TEST_F(PageStorageTest, PageIsEmpty) {
- ObjectData value("Some value", InlineBehavior::PREVENT);
- bool called;
- Status status;
- bool is_empty;
-
- // Initially the page is empty.
- storage_->IsEmpty(
- callback::Capture(callback::SetWhenCalled(&called), &status, &is_empty));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(is_empty);
-
- // Add an entry and expect that the page is not empty any more.
- std::unique_ptr<Journal> journal;
- storage_->StartCommit(
- GetFirstHead()->GetId(), JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(PutInJournal(journal.get(), "key", value.object_identifier,
- KeyPriority::LAZY));
- EXPECT_TRUE(TryCommitJournal(std::move(journal), Status::OK));
-
- storage_->IsEmpty(
- callback::Capture(callback::SetWhenCalled(&called), &status, &is_empty));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_FALSE(is_empty);
-
- // Clear the page and expect it to be empty again.
- storage_->StartCommit(
- GetFirstHead()->GetId(), JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(DeleteFromJournal(journal.get(), "key"));
- EXPECT_TRUE(TryCommitJournal(std::move(journal), Status::OK));
-
- storage_->IsEmpty(
- callback::Capture(callback::SetWhenCalled(&called), &status, &is_empty));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(is_empty);
-}
-
-TEST_F(PageStorageTest, UntrackedObjectsSimple) {
- ObjectData data("Some data", InlineBehavior::PREVENT);
-
- // The object is not yet created and its id should not be marked as untracked.
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, false));
-
- // After creating the object it should be marked as untracked.
- TryAddFromLocal(data.value, data.object_identifier);
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, true));
-
- // After adding the object in a commit it should not be untracked any more.
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- storage_->StartCommit(
- GetFirstHead()->GetId(), JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(PutInJournal(journal.get(), "key", data.object_identifier,
- KeyPriority::EAGER));
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, true));
- ASSERT_TRUE(TryCommitJournal(std::move(journal), Status::OK));
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, false));
-}
-
-TEST_F(PageStorageTest, UntrackedObjectsComplex) {
- ObjectData data_array[] = {
- ObjectData("Some data", InlineBehavior::PREVENT),
- ObjectData("Some more data", InlineBehavior::PREVENT),
- ObjectData("Even more data", InlineBehavior::PREVENT),
- };
- for (auto& data : data_array) {
- TryAddFromLocal(data.value, data.object_identifier);
- EXPECT_TRUE(ObjectIsUntracked(data.object_identifier, true));
- }
-
- // Add a first commit containing data_array[0].
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- storage_->StartCommit(
- GetFirstHead()->GetId(), JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(PutInJournal(journal.get(), "key0",
- data_array[0].object_identifier, KeyPriority::LAZY));
- EXPECT_TRUE(ObjectIsUntracked(data_array[0].object_identifier, true));
- ASSERT_TRUE(TryCommitJournal(std::move(journal), Status::OK));
- EXPECT_TRUE(ObjectIsUntracked(data_array[0].object_identifier, false));
- EXPECT_TRUE(ObjectIsUntracked(data_array[1].object_identifier, true));
- EXPECT_TRUE(ObjectIsUntracked(data_array[2].object_identifier, true));
-
- // Create a second commit. After calling Put for "key1" for the second time
- // data_array[1] is no longer part of this commit: it should remain
- // untracked after committing.
- journal.reset();
- storage_->StartCommit(
- GetFirstHead()->GetId(), JournalType::IMPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(PutInJournal(journal.get(), "key1",
- data_array[1].object_identifier, KeyPriority::LAZY));
- EXPECT_TRUE(PutInJournal(journal.get(), "key2",
- data_array[2].object_identifier, KeyPriority::LAZY));
- EXPECT_TRUE(PutInJournal(journal.get(), "key1",
- data_array[2].object_identifier, KeyPriority::LAZY));
- EXPECT_TRUE(PutInJournal(journal.get(), "key3",
- data_array[0].object_identifier, KeyPriority::LAZY));
- ASSERT_TRUE(TryCommitJournal(std::move(journal), Status::OK));
- EXPECT_TRUE(ObjectIsUntracked(data_array[0].object_identifier, false));
- EXPECT_TRUE(ObjectIsUntracked(data_array[1].object_identifier, true));
- EXPECT_TRUE(ObjectIsUntracked(data_array[2].object_identifier, false));
-}
-
-TEST_F(PageStorageTest, CommitWatchers) {
- FakeCommitWatcher watcher;
- storage_->AddCommitWatcher(&watcher);
-
- // Add a watcher and receive the commit.
- auto expected = TryCommitFromLocal(JournalType::EXPLICIT, 10);
- ASSERT_TRUE(expected);
- EXPECT_EQ(1, watcher.commit_count);
- EXPECT_EQ(expected->GetId(), watcher.last_commit_id);
- EXPECT_EQ(ChangeSource::LOCAL, watcher.last_source);
-
- // Add a second watcher.
- FakeCommitWatcher watcher2;
- storage_->AddCommitWatcher(&watcher2);
- expected = TryCommitFromLocal(JournalType::IMPLICIT, 10);
- ASSERT_TRUE(expected);
- EXPECT_EQ(2, watcher.commit_count);
- EXPECT_EQ(expected->GetId(), watcher.last_commit_id);
- EXPECT_EQ(ChangeSource::LOCAL, watcher.last_source);
- EXPECT_EQ(1, watcher2.commit_count);
- EXPECT_EQ(expected->GetId(), watcher2.last_commit_id);
- EXPECT_EQ(ChangeSource::LOCAL, watcher2.last_source);
-
- // Remove one watcher.
- storage_->RemoveCommitWatcher(&watcher2);
- expected = TryCommitFromSync();
- EXPECT_EQ(3, watcher.commit_count);
- EXPECT_EQ(expected->GetId(), watcher.last_commit_id);
- EXPECT_EQ(ChangeSource::CLOUD, watcher.last_source);
- EXPECT_EQ(1, watcher2.commit_count);
-}
-
-TEST_F(PageStorageTest, SyncMetadata) {
- std::vector<std::pair<fxl::StringView, fxl::StringView>> keys_and_values = {
- {"foo1", "foo2"}, {"bar1", " bar2 "}};
- for (const auto& key_and_value : keys_and_values) {
- auto key = key_and_value.first;
- auto value = key_and_value.second;
- bool called;
- Status status;
- std::string returned_value;
- storage_->GetSyncMetadata(
- key, callback::Capture(callback::SetWhenCalled(&called), &status,
- &returned_value));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
-
- storage_->SetSyncMetadata(
- key, value,
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- storage_->GetSyncMetadata(
- key, callback::Capture(callback::SetWhenCalled(&called), &status,
- &returned_value));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(value, returned_value);
- }
-}
-
-TEST_F(PageStorageTest, AddMultipleCommitsFromSync) {
- RunInCoroutine([this](CoroutineHandler* handler) {
- FakeSyncDelegate sync;
- storage_->SetSyncDelegate(&sync);
-
- // Build the commit Tree with:
- // 0
- // |
- // 1 2
- std::vector<ObjectIdentifier> object_identifiers;
- object_identifiers.resize(3);
- for (size_t i = 0; i < object_identifiers.size(); ++i) {
- ObjectData value("value" + std::to_string(i), InlineBehavior::PREVENT);
- std::vector<Entry> entries = {Entry{"key" + std::to_string(i),
- value.object_identifier,
- KeyPriority::EAGER}};
- std::unique_ptr<const btree::TreeNode> node;
- ASSERT_TRUE(CreateNodeFromEntries(entries, {}, &node));
- object_identifiers[i] = node->GetIdentifier();
- sync.AddObject(value.object_identifier, value.value);
- std::unique_ptr<const Object> root_object =
- TryGetObject(object_identifiers[i], PageStorage::Location::NETWORK);
- fxl::StringView root_data;
- ASSERT_EQ(Status::OK, root_object->GetData(&root_data));
- sync.AddObject(object_identifiers[i], root_data.ToString());
- }
-
- // Reset and clear the storage.
- ResetStorage();
- storage_->SetSyncDelegate(&sync);
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- std::unique_ptr<const Commit> commit0 = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), object_identifiers[0],
- std::move(parent));
- parent.clear();
-
- parent.emplace_back(GetFirstHead());
- std::unique_ptr<const Commit> commit1 = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), object_identifiers[1],
- std::move(parent));
- parent.clear();
-
- parent.emplace_back(commit1->Clone());
- std::unique_ptr<const Commit> commit2 = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), object_identifiers[2],
- std::move(parent));
-
- std::vector<PageStorage::CommitIdAndBytes> commits_and_bytes;
- commits_and_bytes.emplace_back(commit0->GetId(),
- commit0->GetStorageBytes().ToString());
- commits_and_bytes.emplace_back(commit1->GetId(),
- commit1->GetStorageBytes().ToString());
- commits_and_bytes.emplace_back(commit2->GetId(),
- commit2->GetStorageBytes().ToString());
-
- bool called;
- Status status;
- std::vector<CommitId> missing_ids;
- storage_->AddCommitsFromSync(
- std::move(commits_and_bytes), ChangeSource::CLOUD,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &missing_ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_EQ(4u, sync.object_requests.size());
- EXPECT_NE(sync.object_requests.find(object_identifiers[0]),
- sync.object_requests.end());
- EXPECT_EQ(sync.object_requests.find(object_identifiers[1]),
- sync.object_requests.end());
- EXPECT_NE(sync.object_requests.find(object_identifiers[2]),
- sync.object_requests.end());
- });
-}
-
-TEST_F(PageStorageTest, Generation) {
- std::unique_ptr<const Commit> commit1 =
- TryCommitFromLocal(JournalType::EXPLICIT, 3);
- ASSERT_TRUE(commit1);
- EXPECT_EQ(1u, commit1->GetGeneration());
-
- std::unique_ptr<const Commit> commit2 =
- TryCommitFromLocal(JournalType::EXPLICIT, 3);
- ASSERT_TRUE(commit2);
- EXPECT_EQ(2u, commit2->GetGeneration());
-
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- storage_->StartMergeCommit(
- commit1->GetId(), commit2->GetId(),
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::unique_ptr<const Commit> commit3 =
- TryCommitJournal(std::move(journal), Status::OK);
- ASSERT_TRUE(commit3);
- EXPECT_EQ(3u, commit3->GetGeneration());
-}
-
-TEST_F(PageStorageTest, GetEntryFromCommit) {
- int size = 10;
- std::unique_ptr<const Commit> commit =
- TryCommitFromLocal(JournalType::EXPLICIT, size);
- ASSERT_TRUE(commit);
-
- bool called;
- Status status;
- Entry entry;
- storage_->GetEntryFromCommit(
- *commit, "key not found",
- callback::Capture(callback::SetWhenCalled(&called), &status, &entry));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::NOT_FOUND, status);
-
- for (int i = 0; i < size; ++i) {
- std::string expected_key = fxl::StringPrintf("key%05d", i);
- storage_->GetEntryFromCommit(
- *commit, expected_key,
- callback::Capture(callback::SetWhenCalled(&called), &status, &entry));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::OK, status);
- EXPECT_EQ(expected_key, entry.key);
- }
-}
-
-TEST_F(PageStorageTest, WatcherForReEntrantCommits) {
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
-
- std::unique_ptr<const Commit> commit1 = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(),
- RandomObjectIdentifier(environment_.random()), std::move(parent));
- CommitId id1 = commit1->GetId();
-
- parent.clear();
- parent.emplace_back(commit1->Clone());
-
- std::unique_ptr<const Commit> commit2 = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(),
- RandomObjectIdentifier(environment_.random()), std::move(parent));
- CommitId id2 = commit2->GetId();
-
- FakeCommitWatcher watcher;
- storage_->AddCommitWatcher(&watcher);
-
- bool called;
- Status status;
- storage_->AddCommitFromLocal(
- std::move(commit1), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- storage_->AddCommitFromLocal(
- std::move(commit2), {},
- callback::Capture(callback::SetWhenCalled(&called), &status));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_EQ(2, watcher.commit_count);
- EXPECT_EQ(id2, watcher.last_commit_id);
-}
-
-TEST_F(PageStorageTest, NoOpCommit) {
- std::vector<CommitId> heads = GetHeads();
- ASSERT_FALSE(heads.empty());
-
- bool called;
- Status status;
- std::unique_ptr<Journal> journal;
- storage_->StartCommit(
- heads[0], JournalType::EXPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- // Create a key, and delete it.
- EXPECT_TRUE(PutInJournal(journal.get(), "key",
- RandomObjectIdentifier(environment_.random()),
- KeyPriority::EAGER));
- EXPECT_TRUE(DeleteFromJournal(journal.get(), "key"));
-
- // Commit the journal.
- std::unique_ptr<const Commit> commit;
- storage_->CommitJournal(
- std::move(journal),
- callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
-
- ASSERT_EQ(Status::OK, status);
- ASSERT_TRUE(commit);
- // Expect that the commit id is the same as the original one.
- EXPECT_EQ(heads[0], commit->GetId());
-}
-
-// Check that receiving a remote commit and commiting locally at the same time
-// do not prevent the commit to be marked as unsynced.
-TEST_F(PageStorageTest, MarkRemoteCommitSyncedRace) {
- bool sync_delegate_called;
- fit::closure sync_delegate_call;
- DelayingFakeSyncDelegate sync(callback::Capture(
- callback::SetWhenCalled(&sync_delegate_called), &sync_delegate_call));
- storage_->SetSyncDelegate(&sync);
-
- // We need to create new nodes for the storage to be asynchronous. The empty
- // node is already there, so we create two (child, which is empty, and root,
- // which contains child).
- std::string child_data = btree::EncodeNode(0u, std::vector<Entry>(), {});
- ObjectIdentifier child_identifier = encryption_service_.MakeObjectIdentifier(
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::TREE_NODE, child_data));
- sync.AddObject(child_identifier, child_data);
-
- std::string root_data =
- btree::EncodeNode(0u, std::vector<Entry>(), {{0u, child_identifier}});
- ObjectIdentifier root_identifier = encryption_service_.MakeObjectIdentifier(
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::TREE_NODE, root_data));
- sync.AddObject(root_identifier, root_data);
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
-
- std::unique_ptr<const Commit> commit = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), root_identifier, std::move(parent));
- CommitId id = commit->GetId();
-
- // Start adding the remote commit.
- bool commits_from_sync_called;
- Status commits_from_sync_status;
- std::vector<PageStorage::CommitIdAndBytes> commits_and_bytes;
- commits_and_bytes.emplace_back(commit->GetId(),
- commit->GetStorageBytes().ToString());
- std::vector<CommitId> missing_ids;
- storage_->AddCommitsFromSync(
- std::move(commits_and_bytes), ChangeSource::CLOUD,
- callback::Capture(callback::SetWhenCalled(&commits_from_sync_called),
- &commits_from_sync_status, &missing_ids));
-
- // Make the loop run until GetObject is called in sync, and before
- // AddCommitsFromSync finishes.
- RunLoopUntilIdle();
- EXPECT_TRUE(sync_delegate_called);
- EXPECT_FALSE(commits_from_sync_called);
-
- // Add the local commit.
- bool commits_from_local_called;
- Status commits_from_local_status;
- storage_->AddCommitFromLocal(
- std::move(commit), {},
- callback::Capture(callback::SetWhenCalled(&commits_from_local_called),
- &commits_from_local_status));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(commits_from_sync_called);
- // The local commit should be commited.
- EXPECT_TRUE(commits_from_local_called);
- ASSERT_TRUE(sync_delegate_call);
- sync_delegate_call();
-
- // Let the two AddCommit finish.
- RunLoopUntilIdle();
- EXPECT_TRUE(commits_from_sync_called);
- EXPECT_TRUE(commits_from_local_called);
- EXPECT_EQ(Status::OK, commits_from_sync_status);
- EXPECT_EQ(Status::OK, commits_from_local_status);
-
- // Verify that the commit is added correctly.
- bool called;
- Status status;
- storage_->GetCommit(id, callback::Capture(callback::SetWhenCalled(&called),
- &status, &commit));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- // The commit should be marked as synced.
- EXPECT_EQ(0u, GetUnsyncedCommits().size());
-}
-
-// Verifies that GetUnsyncedCommits() returns commits ordered by their
-// generation, and not by the timestamp.
-//
-// In this test the commits have the following structure:
-// (root)
-// / | \
-// (A) (B) (C)
-// \ /
-// (merge)
-// C is the last commit to be created. The test verifies that the unsynced
-// commits are returned in the generation order, with the merge commit being the
-// last despite not being the most recent.
-TEST_F(PageStorageTest, GetUnsyncedCommits) {
- const CommitId root_id = GetFirstHead()->GetId();
-
- bool called;
- Status status;
- std::unique_ptr<Journal> journal_a;
- storage_->StartCommit(
- root_id, JournalType::EXPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal_a));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(PutInJournal(journal_a.get(), "a",
- RandomObjectIdentifier(environment_.random()),
- KeyPriority::EAGER));
- std::unique_ptr<const Commit> commit_a =
- TryCommitJournal(std::move(journal_a), Status::OK);
- ASSERT_TRUE(commit_a);
- EXPECT_EQ(1u, commit_a->GetGeneration());
-
- std::unique_ptr<Journal> journal_b;
- storage_->StartCommit(
- root_id, JournalType::EXPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal_b));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(PutInJournal(journal_b.get(), "b",
- RandomObjectIdentifier(environment_.random()),
- KeyPriority::EAGER));
- std::unique_ptr<const Commit> commit_b =
- TryCommitJournal(std::move(journal_b), Status::OK);
- ASSERT_TRUE(commit_b);
- EXPECT_EQ(1u, commit_b->GetGeneration());
-
- std::unique_ptr<Journal> journal_merge;
- storage_->StartMergeCommit(commit_a->GetId(), commit_b->GetId(),
- callback::Capture(callback::SetWhenCalled(&called),
- &status, &journal_merge));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
-
- std::unique_ptr<const Commit> commit_merge =
- TryCommitJournal(std::move(journal_merge), Status::OK);
- ASSERT_TRUE(commit_merge);
- EXPECT_EQ(2u, commit_merge->GetGeneration());
-
- std::unique_ptr<Journal> journal_c;
- storage_->StartCommit(
- root_id, JournalType::EXPLICIT,
- callback::Capture(callback::SetWhenCalled(&called), &status, &journal_c));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_TRUE(PutInJournal(journal_c.get(), "c",
- RandomObjectIdentifier(environment_.random()),
- KeyPriority::EAGER));
- std::unique_ptr<const Commit> commit_c =
- TryCommitJournal(std::move(journal_c), Status::OK);
- ASSERT_TRUE(commit_c);
- EXPECT_EQ(1u, commit_c->GetGeneration());
-
- // Verify that the merge commit is returned as last, even though commit C is
- // older.
- std::vector<std::unique_ptr<const Commit>> unsynced_commits =
- GetUnsyncedCommits();
- EXPECT_EQ(4u, unsynced_commits.size());
- EXPECT_EQ(commit_merge->GetId(), unsynced_commits.back()->GetId());
- EXPECT_LT(commit_merge->GetTimestamp(), commit_c->GetTimestamp());
-}
-
-// Add a commit for which we don't have its parent. Verify that an error is
-// returned, along with the id of the missing parent.
-TEST_F(PageStorageTest, AddCommitsMissingParent) {
- std::unique_ptr<const btree::TreeNode> node;
- ASSERT_TRUE(CreateNodeFromEntries({}, {}, &node));
- ObjectIdentifier root_identifier = node->GetIdentifier();
-
- std::vector<std::unique_ptr<const Commit>> parent;
- parent.emplace_back(GetFirstHead());
- auto commit_parent = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), root_identifier, std::move(parent));
- parent.clear();
- parent.push_back(commit_parent->Clone());
- auto commit_child = CommitImpl::FromContentAndParents(
- environment_.clock(), storage_.get(), root_identifier, std::move(parent));
-
- std::vector<PageStorage::CommitIdAndBytes> commits_and_bytes;
- commits_and_bytes.emplace_back(commit_child->GetId(),
- commit_child->GetStorageBytes().ToString());
-
- bool called;
- Status status;
- std::vector<CommitId> missing_ids;
- storage_->AddCommitsFromSync(
- std::move(commits_and_bytes), ChangeSource::P2P,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &missing_ids));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::NOT_FOUND, status);
- EXPECT_THAT(missing_ids, ElementsAre(commit_parent->GetId()));
-}
-
-} // namespace
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/split.cc b/bin/ledger/storage/impl/split.cc
deleted file mode 100644
index dedcaa9..0000000
--- a/bin/ledger/storage/impl/split.cc
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/split.h"
-
-#include <limits>
-#include <sstream>
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/storage/impl/constants.h"
-#include "peridot/bin/ledger/storage/impl/file_index.h"
-#include "peridot/bin/ledger/storage/impl/file_index_generated.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/storage/impl/object_identifier_encoding.h"
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/third_party/bup/bupsplit.h"
-
-namespace storage {
-
-namespace {
-constexpr size_t kMinChunkSize = 4 * 1024;
-constexpr size_t kMaxChunkSize = std::numeric_limits<uint16_t>::max();
-constexpr size_t kBitsPerLevel = 4;
-// Empiric maximal size for an identifier in an index file. This should be the
-// smallest possible number that allow the Split tests to pass.
-constexpr size_t kMaxIdentifierSize = 77;
-// The max number of identifiers that an index can contain so that the file size
-// is less than |kMaxChunkSize|.
-constexpr size_t kMaxIdentifiersPerIndex = kMaxChunkSize / kMaxIdentifierSize;
-
-using ObjectIdentifierAndSize = FileIndexSerialization::ObjectIdentifierAndSize;
-
-struct ChunkAndSize {
- std::unique_ptr<DataSource::DataChunk> chunk;
- uint64_t size;
-};
-
-// Handles the successive callbacks from the DataSource.
-//
-// Algorithm:
-// This class keeps track of a list of identifiers per level. For each level,
-// the list must be aggregated into an index file, or if alone at the highest
-// level when the algorithm ends, sent to the client.
-// The algorithm reads data from the source and feeds it to the rolling hash.
-// For each chunk cut by the rolling hash, the identifier of the chunk is added
-// at level 0. The rolling hash algorithm also returns the number of index files
-// that need to be built. An index file is also built as soon as a level
-// contains |kMaxIdentifiersPerIndex| identifiers.
-// When the algorithm builds the index at level |n| it does the following:
-// For all levels from 0 to |n|:
-// - Build the index file at the given level. As a special case, if there is
-// a single object at the given level, just move it to the next level and
-// continue.
-// - Send the index file to the client.
-// - Add the identifier of the index file at the next level.
-class SplitContext {
- public:
- explicit SplitContext(
- fit::function<ObjectIdentifier(ObjectDigest)> make_object_identifier,
- fit::function<void(IterationStatus, ObjectIdentifier,
- std::unique_ptr<DataSource::DataChunk>)>
- callback,
- ObjectType object_type)
- : make_object_identifier_(std::move(make_object_identifier)),
- callback_(std::move(callback)),
- object_type_(object_type),
- roll_sum_split_(kMinChunkSize, kMaxChunkSize) {}
- SplitContext(SplitContext&& other) = default;
- ~SplitContext() {}
-
- void AddChunk(std::unique_ptr<DataSource::DataChunk> chunk,
- DataSource::Status status) {
- if (status == DataSource::Status::ERROR) {
- callback_(IterationStatus::ERROR, ObjectIdentifier(), nullptr);
- return;
- }
-
- FXL_DCHECK(chunk || status == DataSource::Status::DONE);
-
- if (chunk) {
- ProcessChunk(std::move(chunk));
- }
-
- if (status != DataSource::Status::DONE) {
- return;
- }
-
- if (!current_chunks_.empty()) {
- // The remaining data needs to be sent even if it is not chunked at an
- // expected cut point.
- BuildAndSendNextChunk(views_.back().size());
- }
-
- // No data remains.
- FXL_DCHECK(current_chunks_.empty());
-
- // The final id to send exists.
- FXL_DCHECK(!current_identifiers_per_level_.back().empty());
-
- // This traverses the stack of indices, sending each level until a single
- // top level index is produced.
- for (size_t i = 0; i < current_identifiers_per_level_.size(); ++i) {
- if (current_identifiers_per_level_[i].empty()) {
- continue;
- }
-
- // At the top of the stack with a single element, the algorithm is
- // finished. The top-level object_identifier is the unique element.
- if (i == current_identifiers_per_level_.size() - 1 &&
- current_identifiers_per_level_[i].size() == 1) {
- // This identifier may be recomputed by SendDone, so this is not
- // necessarily the final value that we are going to send, but we check
- // that we last called |SendInProgress| on it for consistency.
- FXL_DCHECK(current_identifiers_per_level_[i][0].identifier ==
- latest_identifier_);
- SendDone();
- return;
- }
-
- BuildIndexAtLevel(i);
- }
- FXL_NOTREACHED();
- }
-
- private:
- // Returns the object identifier for |data| of the given |type|, and invokes
- // |callback_| with IN_PROGRESS status. Actually defers sending the object
- // until the next call of this method, because the last object needs to be
- // treated differently in |SendDone|.
- ObjectIdentifier SendInProgress(PieceType type,
- std::unique_ptr<DataSource::DataChunk> data) {
- if (latest_piece_) {
- callback_(IterationStatus::IN_PROGRESS, latest_identifier_,
- std::move(latest_piece_));
- }
- auto data_view = data->Get();
- // object_type for inner (IN_PROGRESS) pieces is always BLOB, regardless of
- // the overall |object_type_|. It may need to be TREE_NODE if this is the
- // very last piece (DONE), but we do not know it at this stage. We account
- // for this by recomputing the object digest in |SendDone|. It does not
- // matter if we return a wrong identifier here, because it will not be used
- // at all if we are at the root piece.
- ObjectDigest object_digest =
- ComputeObjectDigest(type, ObjectType::BLOB, data_view);
- auto identifier = make_object_identifier_(object_digest);
- latest_identifier_ = identifier;
- latest_piece_ = std::move(data);
- return identifier;
- }
-
- // Recomputes the object identifier for the last object to send: since it is
- // the root of the piece hierarchy, it needs to have the |tree_node| bit set
- // if we are splitting a TreeNode. Then sends this object identifier as DONE.
- void SendDone() {
- FXL_DCHECK(latest_piece_);
- auto data_view = latest_piece_->Get();
- ObjectDigest object_digest = ComputeObjectDigest(
- GetObjectDigestInfo(latest_identifier_.object_digest()).piece_type,
- object_type_, data_view);
- latest_identifier_ = make_object_identifier_(object_digest);
- callback_(IterationStatus::DONE, latest_identifier_,
- std::move(latest_piece_));
- }
-
- std::vector<ObjectIdentifierAndSize>& GetCurrentIdentifiersAtLevel(
- size_t level) {
- if (level >= current_identifiers_per_level_.size()) {
- FXL_DCHECK(level == current_identifiers_per_level_.size());
- current_identifiers_per_level_.resize(level + 1);
- }
- return current_identifiers_per_level_[level];
- }
-
- // Appends the given chunk to the unprocessed data and processes as much data
- // as possible using the rolling hash to determine where to cut the stream in
- // pieces.
- void ProcessChunk(std::unique_ptr<DataSource::DataChunk> chunk) {
- views_.push_back(chunk->Get());
- current_chunks_.push_back(std::move(chunk));
-
- while (!views_.empty()) {
- size_t bits;
- size_t split_index = roll_sum_split_.Feed(views_.back(), &bits);
-
- if (split_index == 0) {
- return;
- }
-
- BuildAndSendNextChunk(split_index);
-
- size_t level = GetLevel(bits);
- for (size_t i = 0; i < level; ++i) {
- FXL_DCHECK(!current_identifiers_per_level_[i].empty());
- BuildIndexAtLevel(i);
- }
- }
- }
-
- void BuildAndSendNextChunk(size_t split_index) {
- auto data = BuildNextChunk(split_index);
- auto size = data->Get().size();
- auto identifier = SendInProgress(PieceType::CHUNK, std::move(data));
- AddIdentifierAtLevel(0, {std::move(identifier), size});
- }
-
- void AddIdentifierAtLevel(size_t level, ObjectIdentifierAndSize data) {
- GetCurrentIdentifiersAtLevel(level).push_back(std::move(data));
-
- if (current_identifiers_per_level_[level].size() <
- kMaxIdentifiersPerIndex) {
- // The level is not full, more identifiers can be added.
- return;
- }
-
- FXL_DCHECK(current_identifiers_per_level_[level].size() ==
- kMaxIdentifiersPerIndex);
- // The level contains the max number of identifiers. Creating the index
- // file.
-
- AddIdentifierAtLevel(
- level + 1,
- BuildAndSendIndex(std::move(current_identifiers_per_level_[level])));
- current_identifiers_per_level_[level].clear();
- }
-
- void BuildIndexAtLevel(size_t level) {
- auto objects = std::move(current_identifiers_per_level_[level]);
- current_identifiers_per_level_[level].clear();
-
- if (objects.size() == 1) {
- AddIdentifierAtLevel(level + 1, std::move(objects.front()));
- } else {
- auto id_and_size = BuildAndSendIndex(std::move(objects));
- AddIdentifierAtLevel(level + 1, std::move(id_and_size));
- }
- }
-
- ObjectIdentifierAndSize BuildAndSendIndex(
- std::vector<ObjectIdentifierAndSize> identifiers_and_sizes) {
- FXL_DCHECK(identifiers_and_sizes.size() > 1);
- FXL_DCHECK(identifiers_and_sizes.size() <= kMaxIdentifiersPerIndex);
-
- std::unique_ptr<DataSource::DataChunk> chunk;
- size_t total_size;
- FileIndexSerialization::BuildFileIndex(identifiers_and_sizes, &chunk,
- &total_size);
-
- FXL_DCHECK(chunk->Get().size() <= kMaxChunkSize)
- << "Expected maximum of: " << kMaxChunkSize
- << ", but got: " << chunk->Get().size();
- auto identifier = SendInProgress(PieceType::INDEX, std::move(chunk));
- return {std::move(identifier), total_size};
- }
-
- static size_t GetLevel(size_t bits) {
- FXL_DCHECK(bits >= bup::kBlobBits);
- return (bits - bup::kBlobBits) / kBitsPerLevel;
- }
-
- std::unique_ptr<DataSource::DataChunk> BuildNextChunk(size_t index) {
- FXL_DCHECK(current_chunks_.size() == views_.size());
- FXL_DCHECK(!current_chunks_.empty());
- FXL_DCHECK(views_.back().size() >= index);
-
- if (views_.size() == 1 && views_.front().size() == index &&
- views_.front().size() == current_chunks_.front()->Get().size()) {
- std::unique_ptr<DataSource::DataChunk> result =
- std::move(current_chunks_.front());
- views_.clear();
- current_chunks_.clear();
- return result;
- }
-
- std::string data;
- size_t total_size = index;
-
- for (size_t i = 0; i + 1 < views_.size(); ++i) {
- total_size += views_[i].size();
- }
- data.reserve(total_size);
- for (size_t i = 0; i + 1 < views_.size(); ++i) {
- data.append(views_[i].data(), views_[i].size());
- }
-
- fxl::StringView last = views_.back();
- data.append(last.data(), index);
-
- if (index < last.size()) {
- views_.clear();
- if (current_chunks_.size() > 1) {
- std::swap(current_chunks_.front(), current_chunks_.back());
- current_chunks_.resize(1);
- }
- views_.push_back(last.substr(index));
- } else {
- current_chunks_.clear();
- views_.clear();
- }
-
- FXL_DCHECK(current_chunks_.size() == views_.size());
- return DataSource::DataChunk::Create(std::move(data));
- }
-
- fit::function<ObjectIdentifier(ObjectDigest)> make_object_identifier_;
- fit::function<void(IterationStatus, ObjectIdentifier,
- std::unique_ptr<DataSource::DataChunk>)>
- callback_;
- // The object encoded by DataSource.
- const ObjectType object_type_;
- bup::RollSumSplit roll_sum_split_;
- // The list of chunks from the initial source that are not yet entirely
- // consumed.
- std::vector<std::unique_ptr<DataSource::DataChunk>> current_chunks_;
- // The list of data that has not yet been consumed. For all indexes, the view
- // at the given index is a view to the chunk at the same index.
- std::vector<fxl::StringView> views_;
- // List of unsent indices per level.
- std::vector<std::vector<ObjectIdentifierAndSize>>
- current_identifiers_per_level_;
- // The most recent piece of data (chunk or index) that is entirely consumed
- // but not yet sent to |callback_|.
- std::unique_ptr<DataSource::DataChunk> latest_piece_;
- // The identifier of |latest_piece_|.
- ObjectIdentifier latest_identifier_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SplitContext);
-};
-
-class CollectPiecesState
- : public fxl::RefCountedThreadSafe<CollectPiecesState> {
- public:
- fit::function<void(ObjectIdentifier,
- fit::function<void(Status, fxl::StringView)>)>
- data_accessor;
- fit::function<bool(IterationStatus, ObjectIdentifier)> callback;
- bool running = true;
-};
-
-void CollectPiecesInternal(ObjectIdentifier root,
- fxl::RefPtr<CollectPiecesState> state,
- fit::closure on_done) {
- if (!state->callback(IterationStatus::IN_PROGRESS, root)) {
- on_done();
- return;
- }
-
- if (GetObjectDigestInfo(root.object_digest()).piece_type !=
- PieceType::INDEX) {
- on_done();
- return;
- }
-
- state->data_accessor(root, [state, on_done = std::move(on_done)](
- Status status, fxl::StringView data) mutable {
- if (!state->running) {
- on_done();
- return;
- }
-
- if (status != Status::OK) {
- FXL_LOG(WARNING) << "Unable to read object content.";
- state->running = false;
- on_done();
- return;
- }
-
- auto waiter = fxl::MakeRefCounted<callback::CompletionWaiter>();
- status = ForEachPiece(data, [&](ObjectIdentifier identifier) {
- CollectPiecesInternal(std::move(identifier), state,
- waiter->NewCallback());
- return Status::OK;
- });
- if (status != Status::OK) {
- state->running = false;
- on_done();
- return;
- }
-
- waiter->Finalize(std::move(on_done));
- });
-}
-
-} // namespace
-
-void SplitDataSource(
- DataSource* source, ObjectType object_type,
- fit::function<ObjectIdentifier(ObjectDigest)> make_object_identifier,
- fit::function<void(IterationStatus, ObjectIdentifier,
- std::unique_ptr<DataSource::DataChunk>)>
- callback) {
- SplitContext context(std::move(make_object_identifier), std::move(callback),
- object_type);
- source->Get([context = std::move(context)](
- std::unique_ptr<DataSource::DataChunk> chunk,
- DataSource::Status status) mutable {
- context.AddChunk(std::move(chunk), status);
- });
-}
-
-Status ForEachPiece(fxl::StringView index_content,
- fit::function<Status(ObjectIdentifier)> callback) {
- const FileIndex* file_index;
- Status status =
- FileIndexSerialization::ParseFileIndex(index_content, &file_index);
- if (status != Status::OK) {
- return status;
- }
-
- for (const auto* child : *file_index->children()) {
- Status status = callback(ToObjectIdentifier(child->object_identifier()));
- if (status != Status::OK) {
- return status;
- }
- }
-
- return Status::OK;
-}
-
-void CollectPieces(
- ObjectIdentifier root,
- fit::function<void(ObjectIdentifier,
- fit::function<void(Status, fxl::StringView)>)>
- data_accessor,
- fit::function<bool(IterationStatus, ObjectIdentifier)> callback) {
- auto state = fxl::MakeRefCounted<CollectPiecesState>();
- state->data_accessor = std::move(data_accessor);
- state->callback = std::move(callback);
-
- CollectPiecesInternal(root, state, [state] {
- IterationStatus final_status =
- state->running ? IterationStatus::DONE : IterationStatus::ERROR;
- state->callback(final_status, {});
- });
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/split.h b/bin/ledger/storage/impl/split.h
deleted file mode 100644
index b34f66a..0000000
--- a/bin/ledger/storage/impl/split.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_SPLIT_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_SPLIT_H_
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// Status for the |SplitDataSource| and |CollectXXXPieces| callbacks.
-enum class IterationStatus {
- DONE,
- IN_PROGRESS,
- ERROR,
-};
-
-// Splits the data from |source| representing an object of some |type| and
-// builds a multi-level index from the content. The |source| is consumed and
-// split using a rolling hash. Each chunk and each index file is returned. On
-// each iteration, |make_object_identifier| is called first and must return the
-// |ObjectIdentifier| to use to reference the given content id. This identifier
-// is then passed to |callback|, along with the content itself and a status of
-// |IN_PROGRESS|, except for the last chunk which has a status of |DONE|.
-// |callback| is not called anymore once |source| is deleted.
-void SplitDataSource(
- DataSource* source, ObjectType type,
- fit::function<ObjectIdentifier(ObjectDigest)> make_object_identifier,
- fit::function<void(IterationStatus, ObjectIdentifier,
- std::unique_ptr<DataSource::DataChunk>)>
- callback);
-
-// Iterates over the pieces of an index object.
-Status ForEachPiece(fxl::StringView index_content,
- fit::function<Status(ObjectIdentifier)> callback);
-
-// Collects all pieces ids needed to build the object with id |root|. This
-// returns the id of the object itself, and recurse inside any index if the
-// |callback| returned true for the given id.
-void CollectPieces(
- ObjectIdentifier root,
- fit::function<void(ObjectIdentifier,
- fit::function<void(Status, fxl::StringView)>)>
- data_accessor,
- fit::function<bool(IterationStatus, ObjectIdentifier)> callback);
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_SPLIT_H_
diff --git a/bin/ledger/storage/impl/split_unittest.cc b/bin/ledger/storage/impl/split_unittest.cc
deleted file mode 100644
index 8b79d6b..0000000
--- a/bin/ledger/storage/impl/split_unittest.cc
+++ /dev/null
@@ -1,366 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/split.h"
-
-#include <string.h>
-
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/encryption/primitives/hash.h"
-#include "peridot/bin/ledger/storage/impl/constants.h"
-#include "peridot/bin/ledger/storage/impl/file_index.h"
-#include "peridot/bin/ledger/storage/impl/file_index_generated.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/storage/public/data_source.h"
-
-namespace storage {
-namespace {
-
-constexpr size_t kMinChunkSize = 4 * 1024;
-constexpr size_t kMaxChunkSize = std::numeric_limits<uint16_t>::max();
-
-// DataSource that produces 0.
-class PathologicalDataSource : public DataSource {
- public:
- explicit PathologicalDataSource(size_t size) : size_(size) {}
-
- uint64_t GetSize() override { return size_; }
- void Get(fit::function<void(std::unique_ptr<DataChunk>, Status)> callback)
- override {
- size_t remaining = size_;
- while (remaining) {
- size_t to_send = std::min<size_t>(remaining, 1024u);
- remaining -= to_send;
- callback(DataChunk::Create(std::string(to_send, '\0')),
- Status::TO_BE_CONTINUED);
- }
- callback(nullptr, Status::DONE);
- }
-
- private:
- size_t size_;
-};
-
-// DataSource that returns an error.
-class ErrorDataSource : public DataSource {
- public:
- ErrorDataSource() {}
-
- uint64_t GetSize() override { return 1; }
- void Get(fit::function<void(std::unique_ptr<DataChunk>, Status)> callback)
- override {
- callback(nullptr, Status::ERROR);
- }
-};
-
-std::string NewString(size_t size) {
- std::string content;
- content.resize(size);
- size_t i;
- for (i = 0; i + sizeof(size_t) < content.size(); i += sizeof(size_t)) {
- memcpy(&content[0] + i, &i, sizeof(i));
- }
- memcpy(&content[0] + i, &i, size % sizeof(size_t));
- return content;
-}
-
-struct Call {
- IterationStatus status;
- ObjectDigest digest;
-};
-
-struct SplitResult {
- std::vector<Call> calls;
- std::map<ObjectDigest, std::unique_ptr<DataSource::DataChunk>> data;
-};
-
-void DoSplit(DataSource* source, ObjectType object_type,
- fit::function<void(SplitResult)> callback) {
- auto result = std::make_unique<SplitResult>();
- SplitDataSource(
- source, object_type,
- [](ObjectDigest digest) {
- return encryption::MakeDefaultObjectIdentifier(std::move(digest));
- },
- [result = std::move(result), callback = std::move(callback)](
- IterationStatus status, ObjectIdentifier identifier,
- std::unique_ptr<DataSource::DataChunk> data) mutable {
- EXPECT_TRUE(result);
- auto digest = identifier.object_digest();
- if (status != IterationStatus::ERROR) {
- EXPECT_LE(data->Get().size(), kMaxChunkSize);
- if (result->data.count(digest) != 0) {
- EXPECT_EQ(result->data[digest]->Get(), data->Get());
- } else {
- result->data[digest] = std::move(data);
- }
- }
- result->calls.push_back({status, digest});
- if (status != IterationStatus::IN_PROGRESS) {
- auto to_send = std::move(*result);
- result.reset();
- callback(std::move(to_send));
- }
- });
-}
-
-::testing::AssertionResult ReadFile(
- const ObjectDigest& digest,
- const std::map<ObjectDigest, std::unique_ptr<DataSource::DataChunk>>& data,
- std::string* result, size_t expected_size) {
- size_t start_size = result->size();
- ObjectDigestInfo digest_info = GetObjectDigestInfo(digest);
- if (digest_info.is_inlined()) {
- auto content = ExtractObjectDigestData(digest);
- result->append(content.data(), content.size());
- } else if (digest_info.is_chunk()) {
- if (data.count(digest) == 0) {
- return ::testing::AssertionFailure() << "Unknown object.";
- }
- auto content = data.at(digest)->Get();
- result->append(content.data(), content.size());
- } else {
- FXL_DCHECK(digest_info.piece_type == PieceType::INDEX);
- if (data.count(digest) == 0) {
- return ::testing::AssertionFailure() << "Unknown object.";
- }
- auto content = data.at(digest)->Get();
- const FileIndex* file_index = GetFileIndex(content.data());
- for (const auto* child : *file_index->children()) {
- auto r =
- ReadFile(ObjectDigest(child->object_identifier()->object_digest()),
- data, result, child->size());
- if (!r) {
- return r;
- }
- }
- }
- if (result->size() - start_size != expected_size) {
- return ::testing::AssertionFailure()
- << "Expected an object of size: " << expected_size
- << " but found an object of size: " << (result->size() - start_size);
- }
- return ::testing::AssertionSuccess();
-}
-
-// The first paramater is the size of the value, the second its type.
-using SplitSmallValueTest =
- ::testing::TestWithParam<std::tuple<size_t, ObjectType>>;
-using SplitBigValueTest =
- ::testing::TestWithParam<std::tuple<size_t, ObjectType>>;
-
-TEST_P(SplitSmallValueTest, SmallValue) {
- const std::string content = NewString(std::get<0>(GetParam()));
- const ObjectType object_type = std::get<1>(GetParam());
- auto source = DataSource::Create(content);
- SplitResult split_result;
- DoSplit(source.get(), object_type,
- [&split_result](SplitResult c) { split_result = std::move(c); });
-
- ASSERT_EQ(1u, split_result.calls.size());
- EXPECT_EQ(IterationStatus::DONE, split_result.calls[0].status);
- ASSERT_EQ(1u, split_result.data.size());
- EXPECT_EQ(content, split_result.data.begin()->second->Get());
- EXPECT_EQ(split_result.calls[0].digest,
- ComputeObjectDigest(PieceType::CHUNK, object_type, content));
-
- std::string found_content;
- ASSERT_TRUE(ReadFile(split_result.calls.back().digest, split_result.data,
- &found_content, content.size()));
- EXPECT_EQ(content, found_content);
-}
-
-TEST_P(SplitBigValueTest, BigValues) {
- const std::string content = NewString(std::get<0>(GetParam()));
- const ObjectType object_type = std::get<1>(GetParam());
- auto source = DataSource::Create(content);
- SplitResult split_result;
- DoSplit(source.get(), object_type,
- [&split_result](SplitResult c) { split_result = std::move(c); });
-
- EXPECT_EQ(IterationStatus::DONE, split_result.calls.back().status);
- // There is at least 3 calls:
- // 1 index
- // 2 contents (including 1 termination)
- ASSERT_GE(split_result.calls.size(), 3u);
-
- fxl::StringView current = content;
- for (const auto& call : split_result.calls) {
- if (call.status == IterationStatus::IN_PROGRESS &&
- GetObjectDigestInfo(call.digest).is_chunk()) {
- EXPECT_EQ(current.substr(0, split_result.data[call.digest]->Get().size()),
- split_result.data[call.digest]->Get());
- // Check that object digest is always computed with object_type BLOB for
- // inner pieces (and in particular for chunks here). Only the root must
- // have it set to |object_type|.
- EXPECT_EQ(call.digest,
- ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB,
- split_result.data[call.digest]->Get()));
- current = current.substr(split_result.data[call.digest]->Get().size());
- }
- if (call.status == IterationStatus::DONE) {
- EXPECT_EQ(GetObjectDigestInfo(call.digest).piece_type, PieceType::INDEX);
- EXPECT_EQ(GetObjectDigestInfo(call.digest).object_type, object_type);
- }
- }
-
- EXPECT_EQ(0u, current.size());
-
- std::string found_content;
- ASSERT_TRUE(ReadFile(split_result.calls.back().digest, split_result.data,
- &found_content, content.size()));
- EXPECT_EQ(content, found_content);
-}
-
-INSTANTIATE_TEST_CASE_P(
- SplitTest, SplitSmallValueTest,
- ::testing::Combine(
- ::testing::Values(0, 12, kStorageHashSize, kStorageHashSize + 1, 100,
- 1024, kMinChunkSize),
- ::testing::Values(ObjectType::TREE_NODE, ObjectType::BLOB)));
-
-INSTANTIATE_TEST_CASE_P(
- SplitTest, SplitBigValueTest,
- ::testing::Combine(::testing::Values(kMaxChunkSize + 1, 32 * kMaxChunkSize),
- ::testing::Values(ObjectType::TREE_NODE,
- ObjectType::BLOB)));
-
-// A stream of 0s is only cut at the maximal size.
-TEST(SplitTest, PathologicalCase) {
- constexpr size_t kDataSize = 1024 * 1024 * 128;
- auto source = std::make_unique<PathologicalDataSource>(kDataSize);
- SplitResult split_result;
- DoSplit(source.get(), ObjectType::TREE_NODE,
- [&split_result](SplitResult c) { split_result = std::move(c); });
-
- ASSERT_EQ(IterationStatus::DONE, split_result.calls.back().status);
-
- size_t total_size = 0u;
- for (const auto& call : split_result.calls) {
- if (call.status == IterationStatus::IN_PROGRESS &&
- GetObjectDigestInfo(call.digest).is_chunk()) {
- total_size += split_result.data[call.digest]->Get().size();
- EXPECT_EQ(std::string(split_result.data[call.digest]->Get().size(), '\0'),
- split_result.data[call.digest]->Get());
- }
- }
-
- EXPECT_EQ(kDataSize, total_size);
-}
-
-TEST(SplitTest, Error) {
- auto source = std::make_unique<ErrorDataSource>();
- SplitResult split_result;
- DoSplit(source.get(), ObjectType::TREE_NODE,
- [&split_result](SplitResult c) { split_result = std::move(c); });
-
- ASSERT_EQ(1u, split_result.calls.size());
- ASSERT_EQ(IterationStatus::ERROR, split_result.calls.back().status);
-}
-
-ObjectIdentifier MakeIndexId(size_t i) {
- std::string value;
- value.resize(sizeof(i));
- memcpy(&value[0], &i, sizeof(i));
- return encryption::MakeDefaultObjectIdentifier(
- ComputeObjectDigest(PieceType::INDEX, ObjectType::BLOB, value));
-}
-
-TEST(SplitTest, CollectPieces) {
- // Define indexed files. Each index represents an index file. The content is
- // itself a of index in |parts| that represent the children of the entry.
- std::vector<std::vector<size_t>> parts = {
- // clang-format off
- {1, 2, 3},
- {4, 5},
- {4, 6, 7},
- {7, 8, 9},
- {10, 11},
- {},
- {},
- {},
- {},
- {},
- {},
- {}
- // clang-format on
- };
-
- for (const auto& children : parts) {
- for (size_t child : children) {
- EXPECT_LT(child, parts.size());
- }
- }
-
- std::map<ObjectIdentifier, std::unique_ptr<DataSource::DataChunk>> objects;
-
- for (size_t i = 0; i < parts.size(); ++i) {
- std::vector<FileIndexSerialization::ObjectIdentifierAndSize> children;
- for (size_t child : parts[i]) {
- children.push_back({MakeIndexId(child), 1});
- }
- size_t total_size;
- FileIndexSerialization::BuildFileIndex(children, &objects[MakeIndexId(i)],
- &total_size);
- }
- IterationStatus status;
- std::set<ObjectIdentifier> identifiers;
- CollectPieces(
- MakeIndexId(0),
- [&objects](ObjectIdentifier object_identifier,
- fit::function<void(Status, fxl::StringView)> callback) {
- callback(Status::OK, objects[object_identifier]->Get());
- },
- [&status, &identifiers](IterationStatus received_status,
- ObjectIdentifier identifier) {
- status = received_status;
- if (status == IterationStatus::IN_PROGRESS) {
- identifiers.insert(identifier);
- }
- return true;
- });
-
- ASSERT_EQ(IterationStatus::DONE, status);
- ASSERT_EQ(objects.size(), identifiers.size());
- for (const auto& identifier : identifiers) {
- EXPECT_EQ(1u, objects.count(identifier)) << "Unknown id: " << identifier;
- }
-}
-
-// Test behavior of CollectPieces when the data accessor function returns an
-// error in the middle of the iteration.
-TEST(SplitTest, CollectPiecesError) {
- const size_t nb_successfull_called = 128;
- IterationStatus status;
- size_t called = 0;
- CollectPieces(
- MakeIndexId(0),
- [&called](ObjectIdentifier identifier,
- fit::function<void(Status, fxl::StringView)> callback) {
- if (called >= nb_successfull_called) {
- callback(Status::INTERNAL_IO_ERROR, "");
- return;
- }
- ++called;
- std::vector<FileIndexSerialization::ObjectIdentifierAndSize> children;
- children.push_back({MakeIndexId(2 * called), 1});
- children.push_back({MakeIndexId(2 * called + 1), 1});
- std::unique_ptr<DataSource::DataChunk> data;
- size_t total_size;
- FileIndexSerialization::BuildFileIndex(children, &data, &total_size);
- callback(Status::OK, data->Get());
- },
- [&status](IterationStatus received_status, ObjectIdentifier identifier) {
- status = received_status;
- return true;
- });
- EXPECT_GE(called, nb_successfull_called);
- ASSERT_EQ(IterationStatus::ERROR, status);
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/impl/storage_test_utils.cc b/bin/ledger/storage/impl/storage_test_utils.cc
deleted file mode 100644
index fff8c8e..0000000
--- a/bin/ledger/storage/impl/storage_test_utils.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/impl/storage_test_utils.h"
-
-#include <inttypes.h>
-#include <numeric>
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fxl/strings/string_printf.h>
-#include <zircon/syscalls.h>
-
-#include "peridot/bin/ledger/encryption/fake/fake_encryption_service.h"
-#include "peridot/bin/ledger/storage/impl/btree/builder.h"
-#include "peridot/bin/ledger/storage/impl/btree/entry_change_iterator.h"
-#include "peridot/bin/ledger/storage/impl/constants.h"
-#include "peridot/bin/ledger/storage/impl/object_digest.h"
-#include "peridot/bin/ledger/storage/impl/split.h"
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-namespace storage {
-
-namespace {
-
-std::vector<size_t> GetEnumeration(size_t size) {
- FXL_CHECK(size <= 100);
-
- std::vector<size_t> values(size);
- std::iota(values.begin(), values.end(), 0u);
-
- return values;
-}
-
-std::string ResizeForBehavior(std::string value,
- InlineBehavior inline_behavior) {
- if (inline_behavior == InlineBehavior::PREVENT &&
- value.size() <= kStorageHashSize) {
- value.resize(kStorageHashSize + 1);
- }
- return value;
-}
-
-ObjectIdentifier GetObjectIdentifier(std::string value,
- ObjectType object_type) {
- ObjectDigest result;
- auto data_source = DataSource::Create(std::move(value));
- SplitDataSource(
- data_source.get(), object_type,
- [](ObjectDigest object_digest) {
- return encryption::MakeDefaultObjectIdentifier(
- std::move(object_digest));
- },
- [&result](IterationStatus status, ObjectIdentifier object_identifier,
- std::unique_ptr<DataSource::DataChunk> chunk) {
- if (status == IterationStatus::DONE) {
- result = object_identifier.object_digest();
- }
- });
- return encryption::MakeDefaultObjectIdentifier(std::move(result));
-}
-
-// Pre-determined node level function.
-uint8_t GetTestNodeLevel(convert::ExtendedStringView key) {
- if (key == "key03" || key == "key07" || key == "key30" || key == "key60" ||
- key == "key89") {
- return 1;
- }
-
- if (key == "key50" || key == "key75") {
- return 2;
- }
-
- return 0;
-}
-
-constexpr btree::NodeLevelCalculator kTestNodeLevelCalculator = {
- &GetTestNodeLevel};
-
-} // namespace
-
-ObjectData::ObjectData(std::string value, ObjectType object_type,
- InlineBehavior inline_behavior)
- : value(ResizeForBehavior(std::move(value), inline_behavior)),
- size(this->value.size()),
- object_identifier(GetObjectIdentifier(this->value, object_type)) {}
-
-std::unique_ptr<DataSource> ObjectData::ToDataSource() {
- return DataSource::Create(value);
-}
-
-std::unique_ptr<DataSource::DataChunk> ObjectData::ToChunk() {
- return DataSource::DataChunk::Create(value);
-}
-
-ObjectDigest MakeObjectDigest(std::string content,
- InlineBehavior inline_behavior) {
- return MakeObjectIdentifier(std::move(content), inline_behavior)
- .object_digest();
-}
-
-ObjectIdentifier MakeObjectIdentifier(std::string content,
- InlineBehavior inline_behavior) {
- ObjectData data(std::move(content), inline_behavior);
- return data.object_identifier;
-}
-
-std::string RandomString(rng::Random* random, size_t size) {
- std::string value;
- value.resize(size);
- random->Draw(&value);
- return value;
-}
-
-CommitId RandomCommitId(rng::Random* random) {
- return RandomString(random, kCommitIdSize);
-}
-
-ObjectDigest RandomObjectDigest(rng::Random* random) {
- ObjectData data(RandomString(random, 16), InlineBehavior::PREVENT);
- return data.object_identifier.object_digest();
-}
-
-ObjectIdentifier RandomObjectIdentifier(rng::Random* random) {
- return encryption::MakeDefaultObjectIdentifier(RandomObjectDigest(random));
-}
-
-EntryChange NewEntryChange(std::string key, std::string object_digest,
- KeyPriority priority) {
- return EntryChange{
- Entry{std::move(key), MakeObjectIdentifier(std::move(object_digest)),
- priority},
- false};
-}
-
-EntryChange NewRemoveEntryChange(std::string key) {
- return EntryChange{
- Entry{std::move(key), MakeObjectIdentifier(""), KeyPriority::EAGER},
- true};
-}
-
-StorageTest::StorageTest() {}
-
-StorageTest::~StorageTest() {}
-
-::testing::AssertionResult StorageTest::AddObject(
- std::string value, std::unique_ptr<const Object>* object) {
- bool called;
- Status status;
- ObjectIdentifier object_identifier;
- GetStorage()->AddObjectFromLocal(
- ObjectType::BLOB, DataSource::Create(value),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &object_identifier));
- RunLoopFor(kSufficientDelay);
- if (!called) {
- return ::testing::AssertionFailure()
- << "AddObjectFromLocal callback wasn't called.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "AddObjectFromLocal failed with status " << status
- << ". value: " << value;
- }
-
- std::unique_ptr<const Object> result;
- GetStorage()->GetObject(
- object_identifier, PageStorage::Location::LOCAL,
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- RunLoopFor(kSufficientDelay);
- if (!called) {
- return ::testing::AssertionFailure() << "GetObject callback wasn't called.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "GetObject failed with status " << status << ". value: " << value
- << ", object_identifier: " << object_identifier;
- }
- object->swap(result);
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult StorageTest::CreateEntries(
- size_t size, std::vector<Entry>* entries) {
- return CreateEntries(GetEnumeration(size), entries);
-}
-
-::testing::AssertionResult StorageTest::CreateEntries(
- std::vector<size_t> values, std::vector<Entry>* entries) {
- std::vector<Entry> result;
- for (auto i : values) {
- FXL_DCHECK(i < 100);
- std::unique_ptr<const Object> object;
- ::testing::AssertionResult assertion_result =
- AddObject(fxl::StringPrintf("object%02" PRIuMAX, i), &object);
- if (!assertion_result) {
- return assertion_result;
- }
- result.push_back(Entry{fxl::StringPrintf("key%02" PRIuMAX, i),
- object->GetIdentifier(), KeyPriority::EAGER});
- }
- entries->swap(result);
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult StorageTest::CreateEntryChanges(
- size_t size, std::vector<EntryChange>* changes) {
- return CreateEntryChanges(GetEnumeration(size), changes, false);
-}
-
-::testing::AssertionResult StorageTest::CreateEntryChanges(
- std::vector<size_t> values, std::vector<EntryChange>* changes,
- bool deletion) {
- std::vector<Entry> entries;
- ::testing::AssertionResult assertion_result =
- CreateEntries(std::move(values), &entries);
- if (!assertion_result) {
- return assertion_result;
- }
- std::vector<EntryChange> result;
-
- result.reserve(entries.size());
- for (auto& entry : entries) {
- result.push_back(EntryChange{std::move(entry), deletion});
- }
- changes->swap(result);
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult StorageTest::GetEmptyNodeIdentifier(
- ObjectIdentifier* empty_node_identifier) {
- bool called;
- Status status;
- btree::TreeNode::Empty(
- GetStorage(), callback::Capture(callback::SetWhenCalled(&called), &status,
- empty_node_identifier));
- RunLoopFor(kSufficientDelay);
- if (!called) {
- return ::testing::AssertionFailure()
- << "TreeNode::Empty callback wasn't called.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "TreeNode::Empty failed with status " << status;
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult StorageTest::CreateNodeFromIdentifier(
- ObjectIdentifier identifier, std::unique_ptr<const btree::TreeNode>* node) {
- bool called;
- Status status;
- std::unique_ptr<const btree::TreeNode> result;
- btree::TreeNode::FromIdentifier(
- GetStorage(), identifier,
- callback::Capture(callback::SetWhenCalled(&called), &status, &result));
- RunLoopFor(kSufficientDelay);
- if (!called) {
- return ::testing::AssertionFailure()
- << "TreeNode::FromIdentifier callback wasn't called.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "TreeNode::FromIdentifier failed with status " << status;
- }
- node->swap(result);
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult StorageTest::CreateNodeFromEntries(
- const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children,
- std::unique_ptr<const btree::TreeNode>* node) {
- bool called;
- Status status;
- ObjectIdentifier identifier;
- btree::TreeNode::FromEntries(
- GetStorage(), 0u, entries, children,
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &identifier));
-
- RunLoopFor(kSufficientDelay);
- if (!called) {
- return ::testing::AssertionFailure()
- << "TreeNode::FromEntries callback wasn't called.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "TreeNode::FromEntries failed with status " << status;
- }
- return CreateNodeFromIdentifier(std::move(identifier), node);
-}
-
-::testing::AssertionResult StorageTest::CreateTreeFromChanges(
- const ObjectIdentifier& base_node_identifier,
- const std::vector<EntryChange>& entries,
- ObjectIdentifier* new_root_identifier) {
- bool called;
- Status status;
- std::set<ObjectIdentifier> new_nodes;
- btree::ApplyChanges(
- environment_.coroutine_service(), GetStorage(), base_node_identifier,
- std::make_unique<btree::EntryChangeIterator>(entries.begin(),
- entries.end()),
- callback::Capture(callback::SetWhenCalled(&called), &status,
- new_root_identifier, &new_nodes),
- &kTestNodeLevelCalculator);
- RunLoopFor(kSufficientDelay);
- if (!called) {
- return ::testing::AssertionFailure()
- << "btree::ApplyChanges callback wasn't called.";
- }
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "btree::ApplyChanges failed with status " << status;
- }
- return ::testing::AssertionSuccess();
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/impl/storage_test_utils.h b/bin/ledger/storage/impl/storage_test_utils.h
deleted file mode 100644
index 51c23e9..0000000
--- a/bin/ledger/storage/impl/storage_test_utils.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_IMPL_STORAGE_TEST_UTILS_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_IMPL_STORAGE_TEST_UTILS_H_
-
-#include <string>
-
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/functional/closure.h>
-
-#include "peridot/bin/ledger/storage/impl/btree/tree_node.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-#include "peridot/lib/rng/random.h"
-
-namespace storage {
-
-// A sufficiently large delay, such that if a storagemethod posts a delayed
-// task, the task will be due after associated amount of time.
-inline constexpr zx::duration kSufficientDelay = zx::hour(1);
-
-// Enum describing the expected behavior for identifier, allowing or preventing
-// to be inlined values.
-enum class InlineBehavior {
- ALLOW,
- PREVENT,
-};
-
-// This class stores an object, computes its identifier and
-// provides accessor to transform into a data source and data chunks.
-class ObjectData {
- public:
- explicit ObjectData(std::string value)
- : ObjectData(value, InlineBehavior::ALLOW) {}
- explicit ObjectData(std::string value, InlineBehavior inline_behavior)
- : ObjectData(value, ObjectType::BLOB, inline_behavior) {}
- explicit ObjectData(std::string value, ObjectType object_type,
- InlineBehavior inline_behavior);
- std::unique_ptr<DataSource> ToDataSource();
- std::unique_ptr<DataSource::DataChunk> ToChunk();
-
- const std::string value;
- const size_t size;
- const ObjectIdentifier object_identifier;
-};
-
-// Builder the object digest for the given content. If |inline_behavior| is
-// InlineBehavior::PREVENT, resize |content| so that it cannot be inlined.
-ObjectDigest MakeObjectDigest(
- std::string content,
- InlineBehavior inline_behavior = InlineBehavior::ALLOW);
-
-// Builder the object identifier for the given content. If |inline_behavior| is
-// InlineBehavior::PREVENT, resize |content| so that it cannot be inlined.
-ObjectIdentifier MakeObjectIdentifier(
- std::string content,
- InlineBehavior inline_behavior = InlineBehavior::ALLOW);
-
-// Returns a random string of the given length.
-std::string RandomString(rng::Random* random, size_t size);
-
-// Create a new random commit id.
-CommitId RandomCommitId(rng::Random* random);
-
-// Create a new random object digest.
-ObjectDigest RandomObjectDigest(rng::Random* random);
-
-// Create a new random object identifier.
-ObjectIdentifier RandomObjectIdentifier(rng::Random* random);
-
-// Creates and returns a new EntryChange adding or updating the entry with the
-// given information.
-EntryChange NewEntryChange(std::string key, std::string object_digest,
- KeyPriority priority);
-
-// Creates and returns a new EntryChange removing the entry with the given key.
-EntryChange NewRemoveEntryChange(std::string key);
-
-// A TestLoopFixture providing some additional utility functions on PageStorage.
-//
-// All utility functions in this class return an |AssertionResult| meaning that
-// they can be used in an EXPECT/ASSERT_TRUE: E.g.
-// ASSERT_TRUE(AddObject("value", &object));
-// or an EXPECT/ASSERT_FALSE if the function is expected to fail.
-// ASSERT_FALSE(AddObject("value", &object));
-class StorageTest : public ledger::TestWithEnvironment {
- protected:
- StorageTest();
-
- ~StorageTest() override;
-
- virtual PageStorage* GetStorage() = 0;
-
- // Adds a new BLOB object with the given value in the page storage and updates
- // |object| with the new value.
- ::testing::AssertionResult AddObject(std::string value,
- std::unique_ptr<const Object>* object);
-
- // Creates a vector of entries, each of which has a key from "key00" to
- // "keyXX" where XX is |size-1|. A new value is created for each entry and the
- // corresponding object_digest is set on the entry. |entries| vector will be
- // swapped with the result.
- ::testing::AssertionResult CreateEntries(size_t size,
- std::vector<Entry>* entries);
-
- // Creates a vector of entries, each of which has a key "keyXX", were "XX" is
- // taken from the |values| vector. A new value is created for each entry and
- // the corresponding object_digest is set on the entry. |entries| vector will
- // be swapped with the result.
- ::testing::AssertionResult CreateEntries(std::vector<size_t> values,
- std::vector<Entry>* entries);
-
- // Creates a vector of entry changes adding or updating the given number of
- // entries. See |CreateEntries| for information on the created entries.
- // |changes| vector will be swapped with the result.
- ::testing::AssertionResult CreateEntryChanges(
- size_t size, std::vector<EntryChange>* changes);
-
- // Creates a vector of entry changes adding or updating the given number of
- // entries. See |CreateEntries| for information on the created entries.
- // |changes| vector will be swapped with the result. If |deletion| is true,
- // the changes will be deletions, otherwise the changes will be updates.
- ::testing::AssertionResult CreateEntryChanges(
- std::vector<size_t> values, std::vector<EntryChange>* changes,
- bool deletion = false);
-
- // Creates an empty tree node and updates |empty_node_identifier| with the
- // result.
- ::testing::AssertionResult GetEmptyNodeIdentifier(
- ObjectIdentifier* empty_node_identifier);
-
- // Returns the tree node corresponding to the given id.
- ::testing::AssertionResult CreateNodeFromIdentifier(
- ObjectIdentifier identifier,
- std::unique_ptr<const btree::TreeNode>* node);
-
- // Creates a new tree node from the given entries and children and updates
- // |node| with the result.
- ::testing::AssertionResult CreateNodeFromEntries(
- const std::vector<Entry>& entries,
- const std::map<size_t, ObjectIdentifier>& children,
- std::unique_ptr<const btree::TreeNode>* node);
-
- // Creates a BTree applying changes from the base node and gives back the
- // digest of its new root node.
- ::testing::AssertionResult CreateTreeFromChanges(
- const ObjectIdentifier& base_node_identifier,
- const std::vector<EntryChange>& entries,
- ObjectIdentifier* new_root_identifier);
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(StorageTest);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_IMPL_STORAGE_TEST_UTILS_H_
diff --git a/bin/ledger/storage/public/BUILD.gn b/bin/ledger/storage/public/BUILD.gn
deleted file mode 100644
index 4761f5c..0000000
--- a/bin/ledger/storage/public/BUILD.gn
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("public") {
- sources = [
- "commit.h",
- "commit_watcher.h",
- "constants.cc",
- "constants.h",
- "data_source.cc",
- "data_source.h",
- "db.h",
- "db_factory.h",
- "iterator.h",
- "journal.h",
- "ledger_storage.h",
- "object.cc",
- "object.h",
- "page_storage.cc",
- "page_storage.h",
- "page_sync_client.h",
- "page_sync_delegate.h",
- "read_data_source.cc",
- "read_data_source.h",
- "types.cc",
- "types.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/coroutine",
- "//peridot/bin/ledger/filesystem",
- "//peridot/lib/convert",
- "//peridot/lib/util:ptr",
- "//third_party/flatbuffers",
- "//zircon/public/lib/zx",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "data_source_unittest.cc",
- "object_unittest.cc",
- "read_data_source_unittest.cc",
- ]
-
- deps = [
- ":public",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/socket",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/storage/public/commit.h b/bin/ledger/storage/public/commit.h
deleted file mode 100644
index 7a10523..0000000
--- a/bin/ledger/storage/public/commit.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_COMMIT_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_COMMIT_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <lib/fxl/macros.h>
-#include <zx/time.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-class Commit {
- public:
- Commit() {}
- virtual ~Commit() {}
-
- // Returns a copy of the commit.
- virtual std::unique_ptr<const Commit> Clone() const = 0;
-
- // Returns the id of this commit.
- virtual const CommitId& GetId() const = 0;
-
- // Returns the ids of this commit's parents.
- virtual std::vector<CommitIdView> GetParentIds() const = 0;
-
- // Returns the creation timestamp of this commit in nanoseconds since epoch.
- virtual zx::time_utc GetTimestamp() const = 0;
-
- // Returns the generation of this commit (ie. the number of commits to the
- // root).
- virtual uint64_t GetGeneration() const = 0;
-
- // Returns the id of the root node of this commit.
- virtual ObjectIdentifier GetRootIdentifier() const = 0;
-
- // Returns the byte representation of this |Commit| as they will be synced to
- // the cloud.
- virtual fxl::StringView GetStorageBytes() const = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(Commit);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_COMMIT_H_
diff --git a/bin/ledger/storage/public/commit_watcher.h b/bin/ledger/storage/public/commit_watcher.h
deleted file mode 100644
index d5a1111..0000000
--- a/bin/ledger/storage/public/commit_watcher.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_COMMIT_WATCHER_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_COMMIT_WATCHER_H_
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-class CommitWatcher {
- public:
- CommitWatcher() {}
- virtual ~CommitWatcher() {}
-
- // Called when new commits have been created.
- virtual void OnNewCommits(
- const std::vector<std::unique_ptr<const Commit>>& commits,
- ChangeSource source) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(CommitWatcher);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_COMMIT_WATCHER_H_
diff --git a/bin/ledger/storage/public/constants.cc b/bin/ledger/storage/public/constants.cc
deleted file mode 100644
index 81e4ec9..0000000
--- a/bin/ledger/storage/public/constants.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/constants.h"
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace storage {
-
-namespace {
-constexpr char kFirstPageCommitIdArray[kCommitIdSize] = {};
-} // namespace
-
-constexpr fxl::StringView kFirstPageCommitId(kFirstPageCommitIdArray,
- kCommitIdSize);
-} // namespace storage
diff --git a/bin/ledger/storage/public/constants.h b/bin/ledger/storage/public/constants.h
deleted file mode 100644
index 925823b..0000000
--- a/bin/ledger/storage/public/constants.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_CONSTANTS_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_CONSTANTS_H_
-
-#include <stdint.h>
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace storage {
-
-// The size of a commit id in number of bytes.
-inline constexpr uint64_t kCommitIdSize = 32;
-
-// The ID of the first commit of a page.
-extern const fxl::StringView kFirstPageCommitId;
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_CONSTANTS_H_
diff --git a/bin/ledger/storage/public/data_source.cc b/bin/ledger/storage/public/data_source.cc
deleted file mode 100644
index 405624a..0000000
--- a/bin/ledger/storage/public/data_source.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/data_source.h"
-
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/socket_drainer.h>
-#include <lib/zx/vmar.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace storage {
-
-namespace {
-
-template <typename S>
-class StringLikeDataChunk : public DataSource::DataChunk {
- public:
- explicit StringLikeDataChunk(S value) : value_(std::move(value)) {}
-
- private:
- fxl::StringView Get() override { return convert::ExtendedStringView(value_); }
-
- S value_;
-};
-
-template <typename S>
-class StringLikeDataSource : public DataSource {
- public:
- explicit StringLikeDataSource(S value)
- : value_(std::move(value)), size_(value_.size()) {}
-
- private:
- uint64_t GetSize() override { return size_; }
-
- void Get(fit::function<void(std::unique_ptr<DataChunk>, Status)> callback)
- override {
-#ifndef NDEBUG
- FXL_DCHECK(!called_);
- called_ = true;
-#endif
- callback(std::make_unique<StringLikeDataChunk<S>>(std::move(value_)),
- Status::DONE);
- }
-
- S value_;
- uint64_t size_;
-#ifndef NDEBUG
- bool called_ = false;
-#endif
-};
-
-class VmoDataChunk : public DataSource::DataChunk {
- public:
- explicit VmoDataChunk(fsl::SizedVmo vmo) : vmo_(std::move(vmo)) {}
-
- zx_status_t Init() {
- uintptr_t allocate_address;
- zx_status_t status = zx::vmar::root_self()->allocate(
- 0, ToFullPages(vmo_.size()), ZX_VM_CAN_MAP_READ, &vmar_,
- &allocate_address);
- if (status != ZX_OK) {
- return status;
- }
-
- return vmar_.map(0, vmo_.vmo(), 0, vmo_.size(), ZX_VM_PERM_READ,
- &mapped_address_);
- }
-
- private:
- uint64_t ToFullPages(uint64_t value) {
- return (value + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));
- }
-
- fxl::StringView Get() override {
- return fxl::StringView(reinterpret_cast<char*>(mapped_address_),
- vmo_.size());
- }
-
- fsl::SizedVmo vmo_;
- zx::vmar vmar_;
- uintptr_t mapped_address_;
-};
-
-class VmoDataSource : public DataSource {
- public:
- explicit VmoDataSource(fsl::SizedVmo vmo) : vmo_(std::move(vmo)) {
- FXL_DCHECK(vmo_);
- }
-
- private:
- uint64_t GetSize() override { return vmo_.size(); }
-
- void Get(fit::function<void(std::unique_ptr<DataChunk>, Status)> callback)
- override {
-#ifndef NDEBUG
- FXL_DCHECK(!called_);
- called_ = true;
-#endif
- if (!vmo_) {
- callback(nullptr, Status::ERROR);
- return;
- }
- auto data = std::make_unique<VmoDataChunk>(std::move(vmo_));
- if (data->Init() != ZX_OK) {
- callback(nullptr, Status::ERROR);
- return;
- }
- callback(std::move(data), Status::DONE);
- }
-
- fsl::SizedVmo vmo_;
-#ifndef NDEBUG
- bool called_ = false;
-#endif
-};
-
-class SocketDataSource : public DataSource, public fsl::SocketDrainer::Client {
- public:
- SocketDataSource(zx::socket socket, uint64_t expected_size)
- : socket_(std::move(socket)),
- expected_size_(expected_size),
- remaining_bytes_(expected_size) {
- FXL_DCHECK(socket_);
- }
-
- private:
- uint64_t GetSize() override { return expected_size_; }
-
- void Get(fit::function<void(std::unique_ptr<DataChunk>, Status)> callback)
- override {
- FXL_DCHECK(socket_);
- callback_ = std::move(callback);
- socket_drainer_ = std::make_unique<fsl::SocketDrainer>(this);
- socket_drainer_->Start(std::move(socket_));
- socket_.reset();
- }
-
- void OnDataAvailable(const void* data, size_t num_bytes) override {
- if (num_bytes > remaining_bytes_) {
- FXL_LOG(ERROR) << "Received incorrect number of bytes. Expected: "
- << expected_size_ << ", but received at least "
- << (num_bytes - remaining_bytes_) << " more.";
- socket_drainer_.reset();
- callback_(nullptr, Status::ERROR);
- return;
- }
-
- remaining_bytes_ -= num_bytes;
- callback_(std::make_unique<StringLikeDataChunk<std::string>>(
- std::string(reinterpret_cast<const char*>(data), num_bytes)),
- Status::TO_BE_CONTINUED);
- }
-
- void OnDataComplete() override {
- socket_drainer_.reset();
- if (remaining_bytes_ != 0) {
- FXL_LOG(ERROR) << "Received incorrect number of bytes. Expected: "
- << expected_size_ << ", but received "
- << (expected_size_ - remaining_bytes_);
- callback_(nullptr, Status::ERROR);
- return;
- }
-
- callback_(std::make_unique<StringLikeDataChunk<std::string>>(std::string()),
- Status::DONE);
- }
-
- zx::socket socket_;
- uint64_t expected_size_;
- uint64_t remaining_bytes_;
- std::unique_ptr<fsl::SocketDrainer> socket_drainer_;
- fit::function<void(std::unique_ptr<DataChunk>, Status)> callback_;
-};
-
-class FlatBufferDataChunk : public DataSource::DataChunk {
- public:
- explicit FlatBufferDataChunk(
- std::unique_ptr<flatbuffers::FlatBufferBuilder> value)
- : value_(std::move(value)) {}
-
- private:
- fxl::StringView Get() override {
- return fxl::StringView(reinterpret_cast<char*>(value_->GetBufferPointer()),
- value_->GetSize());
- }
-
- std::unique_ptr<flatbuffers::FlatBufferBuilder> value_;
-};
-
-} // namespace
-
-std::unique_ptr<DataSource::DataChunk> DataSource::DataChunk::Create(
- std::string value) {
- return std::make_unique<StringLikeDataChunk<std::string>>(std::move(value));
-}
-
-std::unique_ptr<DataSource::DataChunk> DataSource::DataChunk::Create(
- std::unique_ptr<flatbuffers::FlatBufferBuilder> builder) {
- return std::make_unique<FlatBufferDataChunk>(std::move(builder));
-}
-
-std::unique_ptr<DataSource> DataSource::Create(std::string value) {
- return std::make_unique<StringLikeDataSource<std::string>>(std::move(value));
-}
-
-std::unique_ptr<DataSource> DataSource::Create(std::vector<uint8_t> value) {
- return std::make_unique<StringLikeDataSource<std::vector<uint8_t>>>(
- std::move(value));
-}
-
-std::unique_ptr<DataSource> DataSource::Create(fsl::SizedVmo vmo) {
- return std::make_unique<VmoDataSource>(std::move(vmo));
-}
-
-std::unique_ptr<DataSource> DataSource::Create(zx::socket socket,
- uint64_t size) {
- return std::make_unique<SocketDataSource>(std::move(socket), size);
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/public/data_source.h b/bin/ledger/storage/public/data_source.h
deleted file mode 100644
index 616c89d..0000000
--- a/bin/ledger/storage/public/data_source.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DATA_SOURCE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DATA_SOURCE_H_
-
-#include <stdint.h>
-#include <functional>
-#include <memory>
-
-#include <lib/fidl/cpp/array.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/zx/socket.h>
-
-#include "third_party/flatbuffers/include/flatbuffers/flatbuffers.h"
-
-namespace storage {
-
-// Represents a source of Data that can be read asynchronously.
-class DataSource {
- public:
- // A chunk of Data returned by the DataSource. Ownership is given to the
- // recipient.
- class DataChunk {
- public:
- DataChunk() {}
- virtual ~DataChunk() {}
-
- virtual fxl::StringView Get() = 0;
-
- // Factory methods.
- static std::unique_ptr<DataChunk> Create(std::string value);
- static std::unique_ptr<DataChunk> Create(
- std::unique_ptr<flatbuffers::FlatBufferBuilder> builder);
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(DataChunk);
- };
-
- enum Status {
- DONE,
- TO_BE_CONTINUED,
- ERROR,
- };
-
- // Factory methods.
- static std::unique_ptr<DataSource> Create(std::string value);
- static std::unique_ptr<DataSource> Create(std::vector<uint8_t> value);
- static std::unique_ptr<DataSource> Create(fsl::SizedVmo vmo);
- static std::unique_ptr<DataSource> Create(zx::socket socket, uint64_t size);
-
- DataSource() {}
- virtual ~DataSource() {}
-
- // Returns the total size of the data in the DataSource.
- virtual uint64_t GetSize() = 0;
- // Fetches the data. This must only be called once. |callback| will later be
- // called one or more times with subsequent chunks of data. If |Status| is
- // |TO_BE_CONTINUED|, |callback| will be called again with the next chunk of
- // data. If |Status| is |DONE|, all the data has been received. In case of
- // error, |callback| will be called with an |ERROR| status and a null |Data|.
- virtual void Get(
- fit::function<void(std::unique_ptr<DataChunk>, Status)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(DataSource);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DATA_SOURCE_H_
diff --git a/bin/ledger/storage/public/data_source_unittest.cc b/bin/ledger/storage/public/data_source_unittest.cc
deleted file mode 100644
index 96c467d..0000000
--- a/bin/ledger/storage/public/data_source_unittest.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/data_source.h"
-
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/socket/socket_pair.h"
-
-namespace storage {
-namespace {
-
-class DataSourceTest : public gtest::TestLoopFixture {
- protected:
- ::testing::AssertionResult TestDataSource(
- std::string expected, std::unique_ptr<DataSource> source) {
- std::string result;
- DataSource::Status status;
-
- source->Get([&result, &status](std::unique_ptr<DataSource::DataChunk> data,
- DataSource::Status received_status) {
- status = received_status;
- if (received_status == DataSource::Status::ERROR) {
- return;
- }
- result += data->Get().ToString();
- });
-
- RunLoopUntilIdle();
-
- if (status != DataSource::Status::DONE) {
- return ::testing::AssertionFailure()
- << "Expected: " << DataSource::Status::DONE
- << ", but got: " << status;
- }
-
- if (expected != result) {
- return ::testing::AssertionFailure()
- << "Expected: " << expected << ", but got: " << result;
- }
-
- return ::testing::AssertionSuccess();
- }
-};
-
-TEST_F(DataSourceTest, String) {
- std::string value = "Hello World";
-
- EXPECT_TRUE(TestDataSource(value, DataSource::Create(value)));
-}
-
-TEST_F(DataSourceTest, Array) {
- std::string value = "Hello World";
-
- fidl::VectorPtr<uint8_t> array;
- array.resize(value.size());
- memcpy(&array->at(0), value.data(), value.size());
-
- EXPECT_TRUE(TestDataSource(value, DataSource::Create(std::move(array))));
-}
-
-TEST_F(DataSourceTest, Vmo) {
- std::string value = "Hello World";
-
- fsl::SizedVmo vmo;
- EXPECT_TRUE(fsl::VmoFromString(value, &vmo));
-
- EXPECT_TRUE(TestDataSource(value, DataSource::Create(std::move(vmo))));
-}
-
-TEST_F(DataSourceTest, Socket) {
- std::string value = "Hello World";
-
- EXPECT_TRUE(TestDataSource(
- value,
- DataSource::Create(fsl::WriteStringToSocket(value), value.size())));
-}
-
-TEST_F(DataSourceTest, SocketWrongSize) {
- std::string value = "Hello World";
-
- EXPECT_FALSE(TestDataSource(
- value,
- DataSource::Create(fsl::WriteStringToSocket(value), value.size() - 1)));
- EXPECT_FALSE(TestDataSource(
- value,
- DataSource::Create(fsl::WriteStringToSocket(value), value.size() + 1)));
-}
-
-TEST_F(DataSourceTest, SocketMultipleChunk) {
- const size_t nb_iterations = 2;
- std::string value = "Hello World";
- std::vector<std::string> chunks;
- DataSource::Status status;
-
- socket::SocketPair socket_pair;
- auto data_source = DataSource::Create(std::move(socket_pair.socket2),
- nb_iterations * value.size());
-
- data_source->Get(
- [&chunks, &status](std::unique_ptr<DataSource::DataChunk> chunk,
- DataSource::Status new_status) {
- EXPECT_NE(DataSource::Status::ERROR, new_status);
- if (new_status == DataSource::Status::TO_BE_CONTINUED) {
- chunks.push_back(chunk->Get().ToString());
- }
- status = new_status;
- });
-
- for (size_t i = 0; i < nb_iterations; ++i) {
- EXPECT_EQ(i, chunks.size());
-
- size_t actual = 0;
- EXPECT_EQ(ZX_OK, socket_pair.socket1.write(0, value.c_str(), value.size(),
- &actual));
- EXPECT_EQ(value.size(), actual);
-
- RunLoopUntilIdle();
- }
-
- socket_pair.socket1.reset();
- RunLoopUntilIdle();
- EXPECT_EQ(DataSource::Status::DONE, status);
-
- EXPECT_EQ(nb_iterations, chunks.size());
- for (const auto& string : chunks) {
- EXPECT_EQ(value, string);
- }
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/public/db.h b/bin/ledger/storage/public/db.h
deleted file mode 100644
index 1f9a0f4..0000000
--- a/bin/ledger/storage/public/db.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DB_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DB_H_
-
-#include "peridot/bin/ledger/coroutine/coroutine.h"
-#include "peridot/bin/ledger/storage/public/iterator.h"
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-class Db {
- public:
- class Batch {
- public:
- // A |Batch| can be used to execute a number of updates in |Db| atomically.
- Batch() {}
- virtual ~Batch() {}
-
- // Inserts the given key-value pair in the database.
- FXL_WARN_UNUSED_RESULT virtual Status Put(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView key,
- fxl::StringView value) = 0;
-
- // Deletes the entry in the database with the given |key|.
- FXL_WARN_UNUSED_RESULT virtual Status Delete(
- coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView key) = 0;
-
- // Deletes all entries whose keys match the given |prefix|.
- FXL_WARN_UNUSED_RESULT virtual Status DeleteByPrefix(
- coroutine::CoroutineHandler* handler,
- convert::ExtendedStringView prefix) = 0;
-
- // Executes this batch. No further operations in this batch are supported
- // after a successful execution.
- FXL_WARN_UNUSED_RESULT virtual Status Execute(
- coroutine::CoroutineHandler* handler) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(Batch);
- };
-
- Db() {}
- virtual ~Db() {}
-
- // Starts a new batch. The batch will be written when Execute is called on the
- // returned object. The Db object must outlive the batch object.
- // The handler (and the corresponding coroutine) only need to remain active
- // until the result is returned. If the coroutine is interrupted,
- // |INTERRUPTED| status is returned.
- FXL_WARN_UNUSED_RESULT virtual Status StartBatch(
- coroutine::CoroutineHandler* handler, std::unique_ptr<Batch>* batch) = 0;
-
- // Retrieves the value corresponding to |key|.
- FXL_WARN_UNUSED_RESULT virtual Status Get(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView key,
- std::string* value) = 0;
-
- // Checks whether |key| is stored in this database.
- FXL_WARN_UNUSED_RESULT virtual Status HasKey(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView key,
- bool* has_key) = 0;
-
- // Retrieves the value for the given |key| as an Object with the provided
- // |object_identifier|.
- FXL_WARN_UNUSED_RESULT virtual Status GetObject(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView key,
- ObjectIdentifier object_identifier,
- std::unique_ptr<const Object>* object) = 0;
-
- // Retrieves all keys matching the given |prefix|. |key_suffixes| will be
- // updated to contain the suffixes of corresponding keys.
- FXL_WARN_UNUSED_RESULT virtual Status GetByPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::vector<std::string>* key_suffixes) = 0;
-
- // Retrieves all entries matching the given |prefix|. The keys of the
- // returned entries will be updated not to contain the |prefix|.
- FXL_WARN_UNUSED_RESULT virtual Status GetEntriesByPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::vector<std::pair<std::string, std::string>>* entries) = 0;
-
- // Retrieves an entry iterator over the entries whose keys start with
- // |prefix|.
- FXL_WARN_UNUSED_RESULT virtual Status GetIteratorAtPrefix(
- coroutine::CoroutineHandler* handler, convert::ExtendedStringView prefix,
- std::unique_ptr<Iterator<const std::pair<convert::ExtendedStringView,
- convert::ExtendedStringView>>>*
- iterator) = 0;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DB_H_
diff --git a/bin/ledger/storage/public/db_factory.h b/bin/ledger/storage/public/db_factory.h
deleted file mode 100644
index 423b4de..0000000
--- a/bin/ledger/storage/public/db_factory.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DB_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DB_FACTORY_H_
-
-#include <memory>
-
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/storage/public/db.h"
-
-namespace storage {
-
-// A factory for Db instances.
-class DbFactory {
- public:
- // Defines the action to be taken if |GetOrCreate| is called for a path that
- // doesn't already contain a Db.
- enum class OnDbNotFound {
- // |GetOrCreateDb| should return with a |NOT_FOUND| status.
- RETURN,
- // |GetOrCreateDb| should create a new Db instance.
- CREATE
- };
-
- DbFactory() {}
- virtual ~DbFactory() {}
-
- // Opens and returns an initialized instance of Db in the given |db_path|.
- // Depending on the value of |on_db_not_found|, if the Db doesn't already
- // exist, it either returns with NOT_FOUND status, or creates a new one.
- virtual void GetOrCreateDb(
- ledger::DetachedPath db_path, OnDbNotFound on_db_not_found,
- fit::function<void(Status, std::unique_ptr<Db>)> callback) = 0;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_DB_FACTORY_H_
diff --git a/bin/ledger/storage/public/iterator.h b/bin/ledger/storage/public/iterator.h
deleted file mode 100644
index 918c618..0000000
--- a/bin/ledger/storage/public/iterator.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_ITERATOR_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_ITERATOR_H_
-
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// A non-copyable iterator over a collection of elements of type T.
-template <class T>
-class Iterator {
- public:
- Iterator() {}
- virtual ~Iterator() {}
-
- // Advances to the next element in the collection. Should only be called on a
- // valid iterator.
- virtual Iterator<T>& Next() = 0;
- // Returns false if no elements are available in the collection, or an error
- // occurred. It is invalid to dereference this iterator or to call |Next()| if
- // Valid() returns false.
- virtual bool Valid() const = 0;
- // Returns the current status of the iterator. It returns the error status if
- // an error occurred, Status::OK otherwise. Reaching the end of the iterator
- // is not an error.
- virtual Status GetStatus() const = 0;
-
- virtual T& operator*() const = 0;
- virtual T* operator->() const = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(Iterator);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_ITERATOR_H_
diff --git a/bin/ledger/storage/public/journal.h b/bin/ledger/storage/public/journal.h
deleted file mode 100644
index 124f7a5..0000000
--- a/bin/ledger/storage/public/journal.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_JOURNAL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_JOURNAL_H_
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace storage {
-
-// A |Journal| represents a commit in progress.
-class Journal {
- public:
- Journal() {}
- virtual ~Journal() {}
-
- // Returns the ID of this journal.
- virtual const JournalId& GetId() const = 0;
-
- // Adds an entry with the given |key| and |object_identifier| to this
- // |Journal|. Returns |OK| on success or the error code otherwise.
- virtual void Put(convert::ExtendedStringView key,
- ObjectIdentifier object_identifier, KeyPriority priority,
- fit::function<void(Status)> callback) = 0;
-
- // Deletes the entry with the given |key| from this |Journal|. Returns |OK|
- // on success or the error code otherwise.
- virtual void Delete(convert::ExtendedStringView key,
- fit::function<void(Status)> callback) = 0;
-
- // Deletes all entries from this Journal, as well as any entries already
- // present on the page. This doesn't prevent subsequent calls to update the
- // contents of this Journal (|Put|, |Delete| or |Clear|).
- virtual void Clear(fit::function<void(Status)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(Journal);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_JOURNAL_H_
diff --git a/bin/ledger/storage/public/ledger_storage.h b/bin/ledger/storage/public/ledger_storage.h
deleted file mode 100644
index bb57987..0000000
--- a/bin/ledger/storage/public/ledger_storage.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_LEDGER_STORAGE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_LEDGER_STORAGE_H_
-
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// Manages storage for a single Ledger instance.
-class LedgerStorage {
- public:
- LedgerStorage() {}
- virtual ~LedgerStorage() {}
-
- // Creates a new |PageStorage| for the Page with the given |page_id|.
- virtual void CreatePageStorage(
- PageId page_id,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback) = 0;
-
- // Finds the |PageStorage| corresponding to the page with the given |page_id|.
- // The result will be returned through the given |callback|. If the storage
- // for the given page isn't found locally, nullptr will be returned instead.
- virtual void GetPageStorage(
- PageId page_id,
- fit::function<void(Status, std::unique_ptr<PageStorage>)> callback) = 0;
-
- // Deletes the storage related to the page with |page_id|. This includes the
- // local copy of the page storage with all commits, tree nodes and values.
- // This method can fail with a |NOT_FOUND| error if the page is not present in
- // the local storage, or with an |IO_ERROR| if deletion fails.
- virtual void DeletePageStorage(PageIdView page_id,
- fit::function<void(Status)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerStorage);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_LEDGER_STORAGE_H_
diff --git a/bin/ledger/storage/public/object.cc b/bin/ledger/storage/public/object.cc
deleted file mode 100644
index 803d5dc..0000000
--- a/bin/ledger/storage/public/object.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/object.h"
-
-#include <lib/fsl/vmo/strings.h>
-
-namespace storage {
-
-Status Object::GetVmo(fsl::SizedVmo* vmo) const {
- fxl::StringView data;
- Status status = GetData(&data);
- if (status != Status::OK) {
- return status;
- }
-
- if (!fsl::VmoFromString(data, vmo)) {
- FXL_LOG(WARNING) << "Unable to produce VMO for data.";
- return Status::INTERNAL_IO_ERROR;
- }
-
- return Status::OK;
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/public/object.h b/bin/ledger/storage/public/object.h
deleted file mode 100644
index ec1fa8b..0000000
--- a/bin/ledger/storage/public/object.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_OBJECT_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_OBJECT_H_
-
-#include <vector>
-
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-class Object {
- public:
- Object() {}
- virtual ~Object() {}
-
- // Returns the identifier of this storage object.
- virtual ObjectIdentifier GetIdentifier() const = 0;
-
- // Returns the data of this object. The returned view is valid as long as this
- // object is not deleted.
- virtual Status GetData(fxl::StringView* data) const = 0;
-
- // Returns a vmo containing the data.
- virtual Status GetVmo(fsl::SizedVmo* vmo) const;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(Object);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_OBJECT_H_
diff --git a/bin/ledger/storage/public/object_unittest.cc b/bin/ledger/storage/public/object_unittest.cc
deleted file mode 100644
index 130622f..0000000
--- a/bin/ledger/storage/public/object_unittest.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/object.h"
-
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-
-namespace storage {
-namespace {
-
-class StringObject : public Object {
- public:
- explicit StringObject(std::string value) : value_(std::move(value)) {}
- ~StringObject() override {}
-
- ObjectIdentifier GetIdentifier() const override {
- return {1u, 2u, ObjectDigest("digest")};
- }
-
- Status GetData(fxl::StringView* data) const override {
- *data = value_;
- return Status::OK;
- }
-
- private:
- std::string value_;
-};
-
-TEST(ObjectTest, GetVmo) {
- std::string content = "content";
- StringObject object(content);
-
- fsl::SizedVmo vmo;
- ASSERT_EQ(Status::OK, object.GetVmo(&vmo));
- std::string vmo_content;
- ASSERT_TRUE(fsl::StringFromVmo(vmo, &vmo_content));
- EXPECT_EQ(content, vmo_content);
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/public/page_storage.cc b/bin/ledger/storage/public/page_storage.cc
deleted file mode 100644
index d05aa7f..0000000
--- a/bin/ledger/storage/public/page_storage.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace storage {
-
-PageStorage::CommitIdAndBytes::CommitIdAndBytes() {}
-
-PageStorage::CommitIdAndBytes::CommitIdAndBytes(CommitId id, std::string bytes)
- : id(std::move(id)), bytes(std::move(bytes)) {}
-
-PageStorage::CommitIdAndBytes::CommitIdAndBytes(
- CommitIdAndBytes&& other) noexcept = default;
-
-PageStorage::CommitIdAndBytes& PageStorage::CommitIdAndBytes::operator=(
- CommitIdAndBytes&& other) noexcept = default;
-
-} // namespace storage
diff --git a/bin/ledger/storage/public/page_storage.h b/bin/ledger/storage/public/page_storage.h
deleted file mode 100644
index cd083d5..0000000
--- a/bin/ledger/storage/public/page_storage.h
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_STORAGE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_STORAGE_H_
-
-#include <functional>
-#include <memory>
-#include <utility>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-#include "peridot/bin/ledger/storage/public/commit_watcher.h"
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/bin/ledger/storage/public/journal.h"
-#include "peridot/bin/ledger/storage/public/object.h"
-#include "peridot/bin/ledger/storage/public/page_sync_client.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// |PageStorage| manages the local storage of a single page.
-class PageStorage : public PageSyncClient {
- public:
- struct CommitIdAndBytes {
- CommitIdAndBytes();
- CommitIdAndBytes(CommitId id, std::string bytes);
- CommitIdAndBytes(CommitIdAndBytes&& other) noexcept;
-
- CommitIdAndBytes& operator=(CommitIdAndBytes&& other) noexcept;
-
- CommitId id;
- std::string bytes;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(CommitIdAndBytes);
- };
-
- // Location where to search an object. See |GetObject| call for usage.
- enum Location { LOCAL, NETWORK };
-
- PageStorage() {}
- ~PageStorage() override {}
-
- // Returns the id of this page.
- virtual PageId GetId() = 0;
-
- // Finds the ids of all head commits. It is guaranteed that valid pages have
- // at least one head commit, even if they are empty.
- virtual void GetHeadCommitIds(
- fit::function<void(Status, std::vector<CommitId>)> callback) = 0;
- // Finds the commit with the given |commit_id| and calls the given |callback|
- // with the result.
- virtual void GetCommit(
- CommitIdView commit_id,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) = 0;
-
- // Adds a list of commits with the given ids and bytes to storage. The
- // callback is called when the storage has finished processing the commits. If
- // the status passed to the callback is OK, this indicates that storage
- // fetched all referenced objects and is ready to accept subsequent commits.
- // In case of error due to missing commits, |callback| will be passed a list
- // of the missing commit IDs.
- virtual void AddCommitsFromSync(
- std::vector<CommitIdAndBytes> ids_and_bytes, ChangeSource source,
- fit::function<void(Status, std::vector<CommitId>)> callback) = 0;
- // Starts a new journal based on the commit with the given |commit_id|. The
- // base commit must be one of the head commits. If |journal_type| is
- // |EXPLICIT|, all changes will be lost after a crash. Otherwise, changes to
- // implicit journals will be committed on system restart.
- virtual void StartCommit(
- const CommitId& commit_id, JournalType journal_type,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) = 0;
- // Starts a new journal for a merge commit, based on the given commits.
- // |left| and |right| must both be in the set of head commits. All
- // modifications to the journal consider the |left| as the base of the new
- // commit. Merge commits are always explicit, that is in case of a crash all
- // changes to the journal will be lost.
- virtual void StartMergeCommit(
- const CommitId& left, const CommitId& right,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) = 0;
-
- // Commits the given |journal| and when finished, returns the success/failure
- // status and the created Commit object through the given |callback|.
- virtual void CommitJournal(
- std::unique_ptr<Journal> journal,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) = 0;
- // Rolls back all changes to the given |Journal|.
- virtual void RollbackJournal(std::unique_ptr<Journal> journal,
- fit::function<void(Status)> callback) = 0;
- // Registers the given |CommitWatcher| which will be notified on new commits.
- virtual Status AddCommitWatcher(CommitWatcher* watcher) = 0;
- // Unregisters the given CommitWatcher.
- virtual Status RemoveCommitWatcher(CommitWatcher* watcher) = 0;
-
- // Checks whether there are any unsynced commits or pieces in this page. Note
- // that since the result is computed asynchronously, the caller must have
- // exclusive access to the page to ensure a correct result.
- virtual void IsSynced(fit::function<void(Status, bool)> callback) = 0;
-
- // Checks whether this page storage is empty. A page is not empty if there is
- // more than one head commits. Note that since the result is computed
- // asynchronously, the caller must have exclusive access to the page to ensure
- // a correct result.
- virtual void IsEmpty(fit::function<void(Status, bool)> callback) = 0;
-
- // Checks whether this page is online, i.e. has been synced to the cloud or a
- // peer. The page is marked as online if any of these has occured: a local
- // commit has been synced to the cloud, commits from the cloud have been
- // downloaded, or the page has been synced to a peer. Note that the result of
- // this method might be incorrect if there are other asynchronous operations
- // in progress. To ensure a correct result, the caller must have exclusive
- // access to the page.
- virtual bool IsOnline() = 0;
-
- // Finds the commits that have not yet been synced.
- //
- // The commits passed in the callback are sorted in a non-decreasing order of
- // their generations.
- virtual void GetUnsyncedCommits(
- fit::function<void(Status, std::vector<std::unique_ptr<const Commit>>)>
- callback) = 0;
-
- // Marks the given commit as synced.
- virtual void MarkCommitSynced(const CommitId& commit_id,
- fit::function<void(Status)> callback) = 0;
-
- // Finds all objects in the storage that are not yet synced, and calls
- // |callback| with the operation status and the corresponding
- // |ObjectIdentifier|s vector.
- virtual void GetUnsyncedPieces(
- fit::function<void(Status, std::vector<ObjectIdentifier>)> callback) = 0;
- // Marks the object with the given |object_identifier| as synced.
- virtual void MarkPieceSynced(ObjectIdentifier object_identifier,
- fit::function<void(Status)> callback) = 0;
- // Returns true if the object is known to be synced to the cloud, false
- // otherwise.
- virtual void IsPieceSynced(ObjectIdentifier object_identifier,
- fit::function<void(Status, bool)> callback) = 0;
-
- // Marks this page as synced to a peer.
- virtual void MarkSyncedToPeer(fit::function<void(Status)> callback) = 0;
-
- // Adds the given local object and passes the new object's id to the callback.
- virtual void AddObjectFromLocal(
- ObjectType object_type, std::unique_ptr<DataSource> data_source,
- fit::function<void(Status, ObjectIdentifier)> callback) = 0;
- // Finds the Object associated with the given |object_identifier|. The result
- // or an an error will be returned through the given |callback|. If |location|
- // is LOCAL, only local storage will be checked. If |location| is NETWORK,
- // then a network request may be made if the requested object is not present
- // locally.
- virtual void GetObject(
- ObjectIdentifier object_identifier, Location location,
- fit::function<void(Status, std::unique_ptr<const Object>)> callback) = 0;
-
- // Retrieve a part of an object starting at |offset| with a maximum size of
- // |max_size| and map it to a VMO.
- // If |offset| is less than 0, starts from |-offset| from the end of the
- // value. If |max_size| is less than 0, retrieves everything untill the end of
- // an object.
- virtual void GetObjectPart(
- ObjectIdentifier object_identifier, int64_t offset, int64_t max_size,
- Location location,
- fit::function<void(Status, fsl::SizedVmo)> callback) = 0;
-
- // Finds the piece associated with the given |object_identifier|. The result
- // or an error will be returned through the given |callback|. Only local
- // storage is checked, and if the object is an index, is it returned as is,
- // and not expanded.
- virtual void GetPiece(
- ObjectIdentifier object_identifier,
- fit::function<void(Status, std::unique_ptr<const Object>)> callback) = 0;
-
- // Sets the opaque sync metadata associated with this page associated with the
- // given |key|. This state is persisted through restarts and can be retrieved
- // using |GetSyncMetadata()|.
- virtual void SetSyncMetadata(fxl::StringView key, fxl::StringView value,
- fit::function<void(Status)> callback) = 0;
-
- // Retrieves the opaque sync metadata associated with this page and the given
- // |key|.
- virtual void GetSyncMetadata(
- fxl::StringView key,
- fit::function<void(Status, std::string)> callback) = 0;
-
- // Commit contents.
-
- // Iterates over the entries of the given |commit| and calls |on_next| on
- // found entries with a key equal to or greater than |min_key|. Returning
- // false from |on_next| will immediately stop the iteration. |on_done| is
- // called once, upon successfull completion, i.e. when there are no more
- // elements or iteration was interrupted, or if an error occurs.
- virtual void GetCommitContents(const Commit& commit, std::string min_key,
- fit::function<bool(Entry)> on_next,
- fit::function<void(Status)> on_done) = 0;
-
- // Retrieves the entry with the given |key| and calls |on_done| with the
- // result. The status of |on_done| will be |OK| on success, |NOT_FOUND| if
- // there is no such key in the given commit or an error status on failure.
- virtual void GetEntryFromCommit(
- const Commit& commit, std::string key,
- fit::function<void(Status, Entry)> on_done) = 0;
-
- // Iterates over the difference between the contents of two commits and calls
- // |on_next_diff| on found changed entries. Returning false from
- // |on_next_diff| will immediately stop the iteration. |on_done| is called
- // once, upon successfull completion, i.e. when there are no more differences
- // or iteration was interrupted, or if an error occurs.
- virtual void GetCommitContentsDiff(
- const Commit& base_commit, const Commit& other_commit,
- std::string min_key, fit::function<bool(EntryChange)> on_next_diff,
- fit::function<void(Status)> on_done) = 0;
-
- // Computes the 3-way diff between a base commit and two other commits. Calls
- // |on_next_diff| on found changed entries. Returning false from
- // |on_next_diff| will immediately stop the iteration. |on_done| is called
- // once, upon successfull completion, i.e. when there are no more differences
- // or iteration was interrupted, or if an error occurs.
- virtual void GetThreeWayContentsDiff(
- const Commit& base_commit, const Commit& left_commit,
- const Commit& right_commit, std::string min_key,
- fit::function<bool(ThreeWayChange)> on_next_diff,
- fit::function<void(Status)> on_done) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageStorage);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_STORAGE_H_
diff --git a/bin/ledger/storage/public/page_sync_client.h b/bin/ledger/storage/public/page_sync_client.h
deleted file mode 100644
index b119bc4..0000000
--- a/bin/ledger/storage/public/page_sync_client.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_SYNC_CLIENT_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_SYNC_CLIENT_H_
-
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/storage/public/page_sync_delegate.h"
-
-namespace storage {
-
-// |PageSyncClient| represents the communication interface between storage and
-// the synchronization objects.
-class PageSyncClient {
- public:
- PageSyncClient() {}
- virtual ~PageSyncClient() {}
-
- // Sets the PageSyncDelegate for this page. A nullptr can be passed to unset a
- // previously set value.
- virtual void SetSyncDelegate(PageSyncDelegate* page_sync) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageSyncClient);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_SYNC_CLIENT_H_
diff --git a/bin/ledger/storage/public/page_sync_delegate.h b/bin/ledger/storage/public/page_sync_delegate.h
deleted file mode 100644
index e4fd857..0000000
--- a/bin/ledger/storage/public/page_sync_delegate.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_SYNC_DELEGATE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_SYNC_DELEGATE_H_
-
-#include <functional>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// Delegate interface for PageStorage responsible for retrieving on-demand
-// storage objects from the cloud.
-class PageSyncDelegate {
- public:
- PageSyncDelegate() {}
- virtual ~PageSyncDelegate() {}
-
- // Retrieves the object of the given id from the cloud.
- virtual void GetObject(
- ObjectIdentifier object_identifier,
- fit::function<void(Status status, ChangeSource source,
- IsObjectSynced is_object_synced,
- std::unique_ptr<DataSource::DataChunk>)>
- callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageSyncDelegate);
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_PAGE_SYNC_DELEGATE_H_
diff --git a/bin/ledger/storage/public/read_data_source.cc b/bin/ledger/storage/public/read_data_source.cc
deleted file mode 100644
index a9453eb..0000000
--- a/bin/ledger/storage/public/read_data_source.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/read_data_source.h"
-
-#include <lib/fit/function.h>
-
-namespace storage {
-
-void ReadDataSource(
- callback::ManagedContainer* managed_container,
- std::unique_ptr<DataSource> data_source,
- fit::function<void(Status, std::unique_ptr<DataSource::DataChunk>)>
- callback) {
- auto managed_data_source = managed_container->Manage(std::move(data_source));
- auto chunks = std::vector<std::unique_ptr<DataSource::DataChunk>>();
- (*managed_data_source)
- ->Get([managed_data_source = std::move(managed_data_source),
- chunks = std::move(chunks), callback = std::move(callback)](
- std::unique_ptr<DataSource::DataChunk> chunk,
- DataSource::Status status) mutable {
- if (status == DataSource::Status::ERROR) {
- FXL_LOG(WARNING) << "Error while reading data source content.";
- callback(Status::INTERNAL_IO_ERROR, nullptr);
- return;
- }
-
- if (chunk) {
- chunks.push_back(std::move(chunk));
- }
-
- if (status == DataSource::Status::TO_BE_CONTINUED) {
- return;
- }
-
- FXL_DCHECK(status == DataSource::Status::DONE);
-
- if (chunks.empty()) {
- callback(Status::OK, DataSource::DataChunk::Create(""));
- return;
- }
-
- if (chunks.size() == 1) {
- callback(Status::OK, std::move(chunks.front()));
- return;
- }
- size_t final_size = 0;
- for (const auto& chunk : chunks) {
- final_size += chunk->Get().size();
- }
- std::string final_content;
- final_content.reserve(final_size);
- for (const auto& chunk : chunks) {
- final_content.append(chunk->Get().data(), chunk->Get().size());
- }
- callback(Status::OK,
- DataSource::DataChunk::Create(std::move(final_content)));
- });
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/public/read_data_source.h b/bin/ledger/storage/public/read_data_source.h
deleted file mode 100644
index a0f7319..0000000
--- a/bin/ledger/storage/public/read_data_source.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_READ_DATA_SOURCE_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_READ_DATA_SOURCE_H_
-
-#include <memory>
-
-#include <lib/callback/managed_container.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/storage/public/data_source.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// Reads the given data source, and returns a single data chunk containing its
-// content. This method will not call its |callback| if |managed_container| is
-// deleted.
-void ReadDataSource(
- callback::ManagedContainer* managed_container,
- std::unique_ptr<DataSource> data_source,
- fit::function<void(Status, std::unique_ptr<DataSource::DataChunk>)>
- callback);
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_READ_DATA_SOURCE_H_
diff --git a/bin/ledger/storage/public/read_data_source_unittest.cc b/bin/ledger/storage/public/read_data_source_unittest.cc
deleted file mode 100644
index 6f34288..0000000
--- a/bin/ledger/storage/public/read_data_source_unittest.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/read_data_source.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fit/function.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-
-namespace storage {
-namespace {
-
-// Data source which returns the given content byte-by-byte in separate chunks.
-class SplittingDataSource : public DataSource {
- public:
- SplittingDataSource(async_dispatcher_t* dispatcher, std::string content)
- : content_(std::move(content)), index_(0), task_runner_(dispatcher) {}
-
- uint64_t GetSize() override { return content_.size(); };
-
- void Get(fit::function<void(std::unique_ptr<DataChunk>, Status)> callback)
- override {
- if (index_ >= content_.size()) {
- callback(nullptr, Status::DONE);
- return;
- }
- callback(DataChunk::Create(content_.substr(index_, 1)),
- Status::TO_BE_CONTINUED);
- ++index_;
- task_runner_.PostTask([this, callback = std::move(callback)]() mutable {
- Get(std::move(callback));
- });
- };
-
- private:
- const std::string content_;
- size_t index_;
-
- callback::ScopedTaskRunner task_runner_;
-};
-
-using ReadDataSourceTest = gtest::TestLoopFixture;
-
-TEST_F(ReadDataSourceTest, ReadDataSource) {
- std::string expected_content = "Hello World";
- callback::ManagedContainer container;
-
- bool called;
- Status status;
- std::unique_ptr<DataSource::DataChunk> content;
- ReadDataSource(
- &container,
- std::make_unique<SplittingDataSource>(dispatcher(), expected_content),
- callback::Capture(callback::SetWhenCalled(&called), &status, &content));
- RunLoopUntilIdle();
- ASSERT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(expected_content, content->Get());
-}
-
-TEST_F(ReadDataSourceTest, DeleteContainerWhileReading) {
- std::string expected_content = "Hello World";
-
- bool called;
- Status status;
- std::unique_ptr<DataSource::DataChunk> content;
- {
- callback::ManagedContainer container;
- ReadDataSource(
- &container,
- std::make_unique<SplittingDataSource>(dispatcher(), expected_content),
- callback::Capture(callback::SetWhenCalled(&called), &status, &content));
- }
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/storage/public/types.cc b/bin/ledger/storage/public/types.cc
deleted file mode 100644
index eed285e..0000000
--- a/bin/ledger/storage/public/types.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/util/ptr.h"
-
-namespace storage {
-namespace {
-template <typename T>
-std::ostream& operator<<(std::ostream& os, const std::unique_ptr<T>& ptr) {
- if (ptr) {
- return os << *ptr;
- }
- return os;
-}
-} // namespace
-
-ObjectDigest::ObjectDigest() = default;
-ObjectDigest::ObjectDigest(std::string digest) : digest_(std::move(digest)) {}
-ObjectDigest::ObjectDigest(const flatbuffers::Vector<uint8_t>* digest)
- : ObjectDigest::ObjectDigest(convert::ToString(digest)) {}
-
-ObjectDigest::ObjectDigest(const ObjectDigest&) = default;
-ObjectDigest& ObjectDigest::operator=(const ObjectDigest&) = default;
-ObjectDigest::ObjectDigest(ObjectDigest&&) = default;
-ObjectDigest& ObjectDigest::operator=(ObjectDigest&&) = default;
-
-bool ObjectDigest::IsValid() const { return digest_.has_value(); }
-const std::string& ObjectDigest::Serialize() const {
- FXL_DCHECK(IsValid());
- return digest_.value();
-}
-
-bool operator==(const ObjectDigest& lhs, const ObjectDigest& rhs) {
- return lhs.digest_ == rhs.digest_;
-}
-bool operator!=(const ObjectDigest& lhs, const ObjectDigest& rhs) {
- return !(lhs == rhs);
-}
-bool operator<(const ObjectDigest& lhs, const ObjectDigest& rhs) {
- return lhs.digest_ < rhs.digest_;
-}
-
-std::ostream& operator<<(std::ostream& os, const ObjectDigest& e) {
- return os << (e.IsValid() ? convert::ToHex(e.Serialize()) : "invalid-digest");
-}
-
-ObjectIdentifier::ObjectIdentifier()
- : key_index_(0), deletion_scope_id_(0), object_digest_(ObjectDigest()) {}
-
-ObjectIdentifier::ObjectIdentifier(uint32_t key_index,
- uint32_t deletion_scope_id,
- ObjectDigest object_digest)
- : key_index_(key_index),
- deletion_scope_id_(deletion_scope_id),
- object_digest_(std::move(object_digest)) {}
-
-ObjectIdentifier::ObjectIdentifier(const ObjectIdentifier&) = default;
-ObjectIdentifier::ObjectIdentifier(ObjectIdentifier&&) = default;
-ObjectIdentifier& ObjectIdentifier::operator=(const ObjectIdentifier&) =
- default;
-ObjectIdentifier& ObjectIdentifier::operator=(ObjectIdentifier&&) = default;
-
-bool operator==(const ObjectIdentifier& lhs, const ObjectIdentifier& rhs) {
- return std::tie(lhs.key_index_, lhs.deletion_scope_id_, lhs.object_digest_) ==
- std::tie(rhs.key_index_, rhs.deletion_scope_id_, rhs.object_digest_);
-}
-
-bool operator!=(const ObjectIdentifier& lhs, const ObjectIdentifier& rhs) {
- return !(lhs == rhs);
-}
-
-bool operator<(const ObjectIdentifier& lhs, const ObjectIdentifier& rhs) {
- return std::tie(lhs.key_index_, lhs.deletion_scope_id_, lhs.object_digest_) <
- std::tie(rhs.key_index_, rhs.deletion_scope_id_, rhs.object_digest_);
-}
-
-std::ostream& operator<<(std::ostream& os, const ObjectIdentifier& e) {
- return os << "ObjectIdentifier{key_index: " << e.key_index()
- << ", deletion_scope_id: " << e.deletion_scope_id()
- << ", object_digest: " << e.object_digest() << "}";
-}
-
-bool operator==(const Entry& lhs, const Entry& rhs) {
- return std::tie(lhs.key, lhs.object_identifier, lhs.priority) ==
- std::tie(rhs.key, rhs.object_identifier, rhs.priority);
-}
-
-bool operator!=(const Entry& lhs, const Entry& rhs) { return !(lhs == rhs); }
-
-std::ostream& operator<<(std::ostream& os, const Entry& e) {
- return os << "Entry{key: " << e.key << ", value: " << e.object_identifier
- << ", priority: "
- << (e.priority == KeyPriority::EAGER ? "EAGER" : "LAZY") << "}";
-}
-
-bool operator==(const EntryChange& lhs, const EntryChange& rhs) {
- return lhs.deleted == rhs.deleted &&
- (lhs.deleted ? lhs.entry.key == rhs.entry.key
- : lhs.entry == rhs.entry);
-}
-
-bool operator!=(const EntryChange& lhs, const EntryChange& rhs) {
- return !(lhs == rhs);
-}
-
-std::ostream& operator<<(std::ostream& os, const EntryChange& e) {
- return os << "EntryChange{entry: " << e.entry << ", deleted: " << e.deleted
- << "}";
-}
-
-bool operator==(const ThreeWayChange& lhs, const ThreeWayChange& rhs) {
- return util::EqualPtr(lhs.base, rhs.base) &&
- util::EqualPtr(lhs.left, rhs.left) &&
- util::EqualPtr(lhs.right, rhs.right);
-}
-
-bool operator!=(const ThreeWayChange& lhs, const ThreeWayChange& rhs) {
- return !(lhs == rhs);
-}
-
-std::ostream& operator<<(std::ostream& os, const ThreeWayChange& e) {
- return os << "ThreeWayChange{base: " << e.base << ", left: " << e.left
- << ", right: " << e.right << "}";
-}
-
-fxl::StringView StatusToString(Status status) {
- switch (status) {
- case Status::OK:
- return "OK";
- case Status::IO_ERROR:
- return "IO_ERROR";
- case Status::NOT_FOUND:
- return "NOT_FOUND";
- case Status::FORMAT_ERROR:
- return "FORMAT_ERROR";
- case Status::ILLEGAL_STATE:
- return "ILLEGAL_STATE";
- case Status::INTERNAL_IO_ERROR:
- return "INTERNAL_IO_ERROR";
- case Status::INTERRUPTED:
- return "INTERRUPTED";
- case Status::NOT_CONNECTED_ERROR:
- return "NOT_CONNECTED_ERROR";
- case Status::NO_SUCH_CHILD:
- return "NO_SUCH_CHILD";
- case Status::OBJECT_DIGEST_MISMATCH:
- return "OBJECT_DIGEST_MISMATCH";
- case Status::NOT_IMPLEMENTED:
- return "NOT_IMPLEMENTED";
- }
-}
-
-std::ostream& operator<<(std::ostream& os, Status status) {
- return os << StatusToString(status);
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/public/types.h b/bin/ledger/storage/public/types.h
deleted file mode 100644
index 994f637..0000000
--- a/bin/ledger/storage/public/types.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_TYPES_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_TYPES_H_
-
-#include <ostream>
-#include <string>
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace storage {
-
-using PageId = std::string;
-using PageIdView = convert::ExtendedStringView;
-using CommitId = std::string;
-using CommitIdView = convert::ExtendedStringView;
-using JournalId = std::string;
-using JournalIdView = convert::ExtendedStringView;
-
-// The type of object.
-// Ledger stores user created content on BTrees, where the nodes (TREE_NODE
-// objects) store the user-created keys and references to the user-created
-// values. The content of the values is (usually) stored into separate BLOB
-// objects.
-// See ledger/storage/impl/btree for more details.
-enum class ObjectType {
- // A |TreeNode| object.
- TREE_NODE,
- // An opaque sequence of bytes. Currently used to store values.
- BLOB,
-};
-
-// The digest of an object.
-// This class is a container for an object digest, treated as an opaque blob. It
-// is not responsible for computing or validating the digest; see
-// storage/impl/object_digest.h for such functions.
-class ObjectDigest {
- public:
- // Builds an invalid object digest. Useful, eg., when returning a default
- // object upon error (with a failed status).
- ObjectDigest();
-
- // Builds a valid object digest whose value is equal to |digest|.
- explicit ObjectDigest(std::string digest);
- explicit ObjectDigest(const flatbuffers::Vector<uint8_t>* digest);
-
- ObjectDigest(const ObjectDigest&);
- ObjectDigest& operator=(const ObjectDigest&);
- ObjectDigest(ObjectDigest&&);
- ObjectDigest& operator=(ObjectDigest&&);
-
- // Returns whether this object represents a valid object digest.
- bool IsValid() const;
-
- // Returns the content of the object digest.
- // The reference is valid as long as this object. Must only be called if the
- // object is valid.
- const std::string& Serialize() const;
-
- private:
- friend bool operator==(const ObjectDigest& lhs, const ObjectDigest& rhs);
- friend bool operator<(const ObjectDigest& lhs, const ObjectDigest& rhs);
-
- std::optional<std::string> digest_;
-};
-
-bool operator==(const ObjectDigest& lhs, const ObjectDigest& rhs);
-bool operator!=(const ObjectDigest& lhs, const ObjectDigest& rhs);
-bool operator<(const ObjectDigest& lhs, const ObjectDigest& rhs);
-std::ostream& operator<<(std::ostream& os, const ObjectDigest& e);
-
-// The priority at which the key value is downloaded, and the cache policy.
-enum class KeyPriority {
- EAGER,
- LAZY,
-};
-
-// The identifier of an object. This contains the digest of the object, as well
-// as the information needed to hide its name and encrypt its content.
-class ObjectIdentifier {
- public:
- ObjectIdentifier();
- ObjectIdentifier(uint32_t key_index, uint32_t deletion_scope_id,
- ObjectDigest object_digest);
-
- ObjectIdentifier(const ObjectIdentifier&);
- ObjectIdentifier& operator=(const ObjectIdentifier&);
- ObjectIdentifier(ObjectIdentifier&&);
- ObjectIdentifier& operator=(ObjectIdentifier&&);
-
- uint32_t key_index() const { return key_index_; }
- uint32_t deletion_scope_id() const { return deletion_scope_id_; }
- const ObjectDigest& object_digest() const { return object_digest_; }
-
- private:
- friend bool operator==(const ObjectIdentifier&, const ObjectIdentifier&);
- friend bool operator<(const ObjectIdentifier&, const ObjectIdentifier&);
-
- uint32_t key_index_;
- uint32_t deletion_scope_id_;
- ObjectDigest object_digest_;
-};
-
-bool operator==(const ObjectIdentifier& lhs, const ObjectIdentifier& rhs);
-bool operator!=(const ObjectIdentifier& lhs, const ObjectIdentifier& rhs);
-bool operator<(const ObjectIdentifier& lhs, const ObjectIdentifier& rhs);
-std::ostream& operator<<(std::ostream& os, const ObjectIdentifier& e);
-
-// An entry in a commit.
-struct Entry {
- std::string key;
- ObjectIdentifier object_identifier;
- KeyPriority priority;
-};
-
-bool operator==(const Entry& lhs, const Entry& rhs);
-bool operator!=(const Entry& lhs, const Entry& rhs);
-std::ostream& operator<<(std::ostream& os, const Entry& e);
-
-// A change between two commit contents.
-struct EntryChange {
- Entry entry;
- bool deleted;
-};
-
-bool operator==(const EntryChange& lhs, const EntryChange& rhs);
-bool operator!=(const EntryChange& lhs, const EntryChange& rhs);
-std::ostream& operator<<(std::ostream& os, const EntryChange& e);
-
-// A change between 3 commit contents.
-struct ThreeWayChange {
- std::unique_ptr<Entry> base;
- std::unique_ptr<Entry> left;
- std::unique_ptr<Entry> right;
-};
-
-bool operator==(const ThreeWayChange& lhs, const ThreeWayChange& rhs);
-bool operator!=(const ThreeWayChange& lhs, const ThreeWayChange& rhs);
-std::ostream& operator<<(std::ostream& os, const ThreeWayChange& e);
-
-enum class ChangeSource { LOCAL, P2P, CLOUD };
-enum class IsObjectSynced : bool { NO, YES };
-
-enum class JournalType { IMPLICIT, EXPLICIT };
-
-enum class JournalContainsClearOperation { NO, YES };
-
-enum class Status {
- // User visible status.
- OK,
- IO_ERROR,
- NOT_FOUND,
-
- // Internal status.
- FORMAT_ERROR,
- ILLEGAL_STATE,
- INTERNAL_IO_ERROR,
- INTERRUPTED,
- NOT_CONNECTED_ERROR,
- NO_SUCH_CHILD,
- OBJECT_DIGEST_MISMATCH,
-
- // Temporary status or status for tests.
- NOT_IMPLEMENTED,
-};
-
-fxl::StringView StatusToString(Status status);
-std::ostream& operator<<(std::ostream& os, Status status);
-
-} // namespace storage
-#endif // PERIDOT_BIN_LEDGER_STORAGE_PUBLIC_TYPES_H_
diff --git a/bin/ledger/storage/testing/BUILD.gn b/bin/ledger/storage/testing/BUILD.gn
deleted file mode 100644
index 088235d..0000000
--- a/bin/ledger/storage/testing/BUILD.gn
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "commit_empty_impl.cc",
- "commit_empty_impl.h",
- "page_storage_empty_impl.cc",
- "page_storage_empty_impl.h",
- "storage_matcher.cc",
- "storage_matcher.h",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/storage/public",
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- ]
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/encryption/primitives",
- "//peridot/bin/ledger/storage/impl/btree:lib",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/socket",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "storage_matcher_unittest.cc",
- ]
-
- deps = [
- ":testing",
- "//peridot/bin/ledger/storage/public",
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/storage/testing/commit_empty_impl.cc b/bin/ledger/storage/testing/commit_empty_impl.cc
deleted file mode 100644
index 5f28be1..0000000
--- a/bin/ledger/storage/testing/commit_empty_impl.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/testing/commit_empty_impl.h"
-
-#include <lib/fxl/logging.h>
-
-namespace storage {
-
-std::unique_ptr<const Commit> CommitEmptyImpl::Clone() const {
- FXL_NOTIMPLEMENTED();
- return nullptr;
-}
-
-const CommitId& CommitEmptyImpl::GetId() const {
- static std::string id = "NOT_IMPLEMENTED";
- FXL_NOTIMPLEMENTED();
- return id;
-}
-
-std::vector<CommitIdView> CommitEmptyImpl::GetParentIds() const {
- FXL_NOTIMPLEMENTED();
- return {};
-}
-
-zx::time_utc CommitEmptyImpl::GetTimestamp() const {
- FXL_NOTIMPLEMENTED();
- return zx::time_utc();
-}
-
-uint64_t CommitEmptyImpl::GetGeneration() const {
- FXL_NOTIMPLEMENTED();
- return 0;
-}
-
-ObjectIdentifier CommitEmptyImpl::GetRootIdentifier() const {
- FXL_NOTIMPLEMENTED();
- return {0u, 0u, ObjectDigest()};
-}
-
-fxl::StringView CommitEmptyImpl::GetStorageBytes() const {
- FXL_NOTIMPLEMENTED();
- return "NOT_IMPLEMENTED";
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/testing/commit_empty_impl.h b/bin/ledger/storage/testing/commit_empty_impl.h
deleted file mode 100644
index 5cea3c6..0000000
--- a/bin/ledger/storage/testing/commit_empty_impl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_TESTING_COMMIT_EMPTY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_TESTING_COMMIT_EMPTY_IMPL_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "peridot/bin/ledger/storage/public/commit.h"
-
-namespace storage {
-
-// Empty implementaton of Commit. All methods do nothing and return dummy or
-// empty responses.
-class CommitEmptyImpl : public Commit {
- public:
- CommitEmptyImpl() = default;
- ~CommitEmptyImpl() override = default;
-
- // Commit:
- std::unique_ptr<const Commit> Clone() const override;
-
- const CommitId& GetId() const override;
-
- std::vector<CommitIdView> GetParentIds() const override;
-
- zx::time_utc GetTimestamp() const override;
-
- uint64_t GetGeneration() const override;
-
- ObjectIdentifier GetRootIdentifier() const override;
-
- fxl::StringView GetStorageBytes() const override;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_TESTING_COMMIT_EMPTY_IMPL_H_
diff --git a/bin/ledger/storage/testing/page_storage_empty_impl.cc b/bin/ledger/storage/testing/page_storage_empty_impl.cc
deleted file mode 100644
index dfe4ec4..0000000
--- a/bin/ledger/storage/testing/page_storage_empty_impl.cc
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/testing/page_storage_empty_impl.h"
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-namespace storage {
-
-PageId PageStorageEmptyImpl::GetId() {
- FXL_NOTIMPLEMENTED();
- return "NOT_IMPLEMENTED";
-}
-
-void PageStorageEmptyImpl::SetSyncDelegate(PageSyncDelegate* /*page_sync*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-void PageStorageEmptyImpl::GetHeadCommitIds(
- fit::function<void(Status, std::vector<CommitId>)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, std::vector<CommitId>());
-}
-
-void PageStorageEmptyImpl::GetCommit(
- CommitIdView /*commit_id*/,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, nullptr);
-}
-
-void PageStorageEmptyImpl::AddCommitsFromSync(
- std::vector<CommitIdAndBytes> /*ids_and_bytes*/, ChangeSource /*source*/,
- fit::function<void(Status, std::vector<CommitId>)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, {});
-}
-
-void PageStorageEmptyImpl::StartCommit(
- const CommitId& /*commit_id*/, JournalType /*journal_type*/,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, nullptr);
-}
-
-void PageStorageEmptyImpl::StartMergeCommit(
- const CommitId& /*left*/, const CommitId& /*right*/,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, nullptr);
-}
-
-void PageStorageEmptyImpl::CommitJournal(
- std::unique_ptr<Journal> /*journal*/,
- fit::function<void(Status, std::unique_ptr<const Commit>)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, nullptr);
-}
-
-void PageStorageEmptyImpl::RollbackJournal(
- std::unique_ptr<Journal> /*journal*/,
- fit::function<void(Status)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED);
-}
-
-Status PageStorageEmptyImpl::AddCommitWatcher(CommitWatcher* /*watcher*/) {
- FXL_NOTIMPLEMENTED();
- return Status::NOT_IMPLEMENTED;
-}
-
-Status PageStorageEmptyImpl::RemoveCommitWatcher(CommitWatcher* /*watcher*/) {
- FXL_NOTIMPLEMENTED();
- return Status::NOT_IMPLEMENTED;
-}
-
-void PageStorageEmptyImpl::IsSynced(
- fit::function<void(Status, bool)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, false);
-}
-
-bool PageStorageEmptyImpl::IsOnline() {
- FXL_NOTIMPLEMENTED();
- return false;
-}
-
-void PageStorageEmptyImpl::IsEmpty(fit::function<void(Status, bool)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, false);
-}
-
-void PageStorageEmptyImpl::GetUnsyncedCommits(
- fit::function<void(Status, std::vector<std::unique_ptr<const Commit>>)>
- callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, {});
-}
-
-void PageStorageEmptyImpl::MarkCommitSynced(
- const CommitId& /*commit_id*/, fit::function<void(Status)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED);
-}
-
-void PageStorageEmptyImpl::GetUnsyncedPieces(
- fit::function<void(Status, std::vector<ObjectIdentifier>)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, std::vector<ObjectIdentifier>());
-}
-
-void PageStorageEmptyImpl::MarkPieceSynced(
- ObjectIdentifier /*object_identifier*/,
- fit::function<void(Status)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED);
-}
-
-void PageStorageEmptyImpl::IsPieceSynced(
- ObjectIdentifier /*object_identifier*/,
- fit::function<void(Status, bool)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, false);
-}
-
-void PageStorageEmptyImpl::MarkSyncedToPeer(
- fit::function<void(Status)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED);
-}
-
-void PageStorageEmptyImpl::AddObjectFromLocal(
- ObjectType /*object_type*/, std::unique_ptr<DataSource> /*data_source*/,
- fit::function<void(Status, ObjectIdentifier)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, {});
-}
-
-void PageStorageEmptyImpl::GetObjectPart(
- ObjectIdentifier object_identifier, int64_t offset, int64_t max_size,
- Location location, fit::function<void(Status, fsl::SizedVmo)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, nullptr);
-}
-
-void PageStorageEmptyImpl::GetObject(
- ObjectIdentifier /*object_identifier*/, Location /*location*/,
- fit::function<void(Status, std::unique_ptr<const Object>)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, nullptr);
-}
-
-void PageStorageEmptyImpl::GetPiece(
- ObjectIdentifier /*object_identifier*/,
- fit::function<void(Status, std::unique_ptr<const Object>)> callback) {
- callback(Status::NOT_IMPLEMENTED, nullptr);
-}
-
-void PageStorageEmptyImpl::SetSyncMetadata(
- fxl::StringView /*key*/, fxl::StringView /*value*/,
- fit::function<void(Status)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED);
-}
-
-void PageStorageEmptyImpl::GetSyncMetadata(
- fxl::StringView /*key*/,
- fit::function<void(Status, std::string)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, "");
-}
-
-void PageStorageEmptyImpl::GetCommitContents(
- const Commit& /*commit*/, std::string /*min_key*/,
- fit::function<bool(Entry)> /*on_next*/,
- fit::function<void(Status)> on_done) {
- FXL_NOTIMPLEMENTED();
- on_done(Status::NOT_IMPLEMENTED);
-}
-
-void PageStorageEmptyImpl::GetEntryFromCommit(
- const Commit& /*commit*/, std::string /*key*/,
- fit::function<void(Status, Entry)> callback) {
- FXL_NOTIMPLEMENTED();
- callback(Status::NOT_IMPLEMENTED, Entry());
-}
-
-void PageStorageEmptyImpl::GetCommitContentsDiff(
- const Commit& /*base_commit*/, const Commit& /*other_commit*/,
- std::string /*min_key*/, fit::function<bool(EntryChange)> /*on_next_diff*/,
- fit::function<void(Status)> on_done) {
- FXL_NOTIMPLEMENTED();
- on_done(Status::NOT_IMPLEMENTED);
-}
-
-void PageStorageEmptyImpl::GetThreeWayContentsDiff(
- const Commit& /*base_commit*/, const Commit& /*left_commit*/,
- const Commit& /*right_commit*/, std::string /*min_key*/,
- fit::function<bool(ThreeWayChange)> /*on_next_diff*/,
- fit::function<void(Status)> on_done) {
- FXL_NOTIMPLEMENTED();
- on_done(Status::NOT_IMPLEMENTED);
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/testing/page_storage_empty_impl.h b/bin/ledger/storage/testing/page_storage_empty_impl.h
deleted file mode 100644
index 5136d11..0000000
--- a/bin/ledger/storage/testing/page_storage_empty_impl.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_TESTING_PAGE_STORAGE_EMPTY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_TESTING_PAGE_STORAGE_EMPTY_IMPL_H_
-
-#include <functional>
-#include <memory>
-#include <vector>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-
-namespace storage {
-
-// Empty implementaton of PageStorage. All methods do nothing and return dummy
-// or empty responses.
-class PageStorageEmptyImpl : public PageStorage {
- public:
- PageStorageEmptyImpl() = default;
- ~PageStorageEmptyImpl() override = default;
-
- // PageStorage:
- PageId GetId() override;
-
- void SetSyncDelegate(PageSyncDelegate* page_sync) override;
-
- void GetHeadCommitIds(
- fit::function<void(Status, std::vector<CommitId>)> callback) override;
-
- void GetCommit(CommitIdView commit_id,
- fit::function<void(Status, std::unique_ptr<const Commit>)>
- callback) override;
-
- void AddCommitsFromSync(
- std::vector<CommitIdAndBytes> ids_and_bytes, ChangeSource source,
- fit::function<void(Status, std::vector<CommitId>)> callback) override;
-
- void StartCommit(
- const CommitId& commit_id, JournalType journal_type,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) override;
-
- void StartMergeCommit(
- const CommitId& left, const CommitId& right,
- fit::function<void(Status, std::unique_ptr<Journal>)> callback) override;
-
- void CommitJournal(std::unique_ptr<Journal> journal,
- fit::function<void(Status, std::unique_ptr<const Commit>)>
- callback) override;
-
- void RollbackJournal(std::unique_ptr<Journal> journal,
- fit::function<void(Status)> callback) override;
-
- Status AddCommitWatcher(CommitWatcher* watcher) override;
-
- Status RemoveCommitWatcher(CommitWatcher* watcher) override;
-
- void IsSynced(fit::function<void(Status, bool)> callback) override;
-
- bool IsOnline() override;
-
- void IsEmpty(fit::function<void(Status, bool)> callback) override;
-
- void GetUnsyncedCommits(
- fit::function<void(Status, std::vector<std::unique_ptr<const Commit>>)>
- callback) override;
-
- void MarkCommitSynced(const CommitId& commit_id,
- fit::function<void(Status)> callback) override;
-
- void GetUnsyncedPieces(
- fit::function<void(Status, std::vector<ObjectIdentifier>)> callback)
- override;
-
- void MarkPieceSynced(ObjectIdentifier object_identifier,
- fit::function<void(Status)> callback) override;
-
- void IsPieceSynced(ObjectIdentifier object_identifier,
- fit::function<void(Status, bool)> callback) override;
-
- void MarkSyncedToPeer(fit::function<void(Status)> callback) override;
-
- void AddObjectFromLocal(
- ObjectType object_type, std::unique_ptr<DataSource> data_source,
- fit::function<void(Status, ObjectIdentifier)> callback) override;
-
- void GetObjectPart(
- ObjectIdentifier object_identifier, int64_t offset, int64_t max_size,
- Location location,
- fit::function<void(Status, fsl::SizedVmo)> callback) override;
-
- void GetObject(ObjectIdentifier object_identifier, Location location,
- fit::function<void(Status, std::unique_ptr<const Object>)>
- callback) override;
-
- void GetPiece(ObjectIdentifier object_identifier,
- fit::function<void(Status, std::unique_ptr<const Object>)>
- callback) override;
-
- void SetSyncMetadata(fxl::StringView key, fxl::StringView value,
- fit::function<void(Status)> callback) override;
-
- void GetSyncMetadata(
- fxl::StringView key,
- fit::function<void(Status, std::string)> callback) override;
-
- void GetCommitContents(const Commit& commit, std::string min_key,
- fit::function<bool(Entry)> on_next,
- fit::function<void(Status)> on_done) override;
-
- void GetEntryFromCommit(const Commit& commit, std::string key,
- fit::function<void(Status, Entry)> callback) override;
-
- void GetCommitContentsDiff(const Commit& base_commit,
- const Commit& other_commit, std::string min_key,
- fit::function<bool(EntryChange)> on_next_diff,
- fit::function<void(Status)> on_done) override;
-
- void GetThreeWayContentsDiff(const Commit& base_commit,
- const Commit& left_commit,
- const Commit& right_commit, std::string min_key,
- fit::function<bool(ThreeWayChange)> on_next_diff,
- fit::function<void(Status)> on_done) override;
-};
-
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_TESTING_PAGE_STORAGE_EMPTY_IMPL_H_
diff --git a/bin/ledger/storage/testing/storage_matcher.cc b/bin/ledger/storage/testing/storage_matcher.cc
deleted file mode 100644
index 262a7a9..0000000
--- a/bin/ledger/storage/testing/storage_matcher.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/testing/storage_matcher.h"
-
-using testing::_;
-using testing::AllOf;
-using testing::Field;
-
-namespace storage {
-
-testing::Matcher<ObjectIdentifier> MatchesDigest(
- testing::Matcher<std::string> matcher) {
- return Property(&ObjectIdentifier::object_digest,
- Property(&ObjectDigest::Serialize, matcher));
-}
-
-testing::Matcher<ObjectIdentifier> MatchesDigest(
- testing::Matcher<ObjectDigest> matcher) {
- return Property(&ObjectIdentifier::object_digest, matcher);
-}
-
-testing::Matcher<Entry> MatchesEntry(
- std::pair<testing::Matcher<std::string>, testing::Matcher<ObjectIdentifier>>
- matcher) {
- return MatchesEntry({matcher.first, matcher.second, _});
-}
-
-testing::Matcher<Entry> MatchesEntry(
- std::tuple<testing::Matcher<std::string>,
- testing::Matcher<ObjectIdentifier>,
- testing::Matcher<KeyPriority>>
- matcher) {
- return AllOf(Field(&Entry::key, std::get<0>(matcher)),
- Field(&Entry::object_identifier, std::get<1>(matcher)),
- Field(&Entry::priority, std::get<2>(matcher)));
-}
-
-} // namespace storage
diff --git a/bin/ledger/storage/testing/storage_matcher.h b/bin/ledger/storage/testing/storage_matcher.h
deleted file mode 100644
index b301c13..0000000
--- a/bin/ledger/storage/testing/storage_matcher.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_STORAGE_TESTING_STORAGE_MATCHER_H_
-#define PERIDOT_BIN_LEDGER_STORAGE_TESTING_STORAGE_MATCHER_H_
-
-#include <gmock/gmock.h>
-#include <tuple>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace storage {
-
-// Matcher that matches an ObjectIdentifier against a matcher for its digest.
-// Its key_index and deletion_scoped_id are ignored.
-testing::Matcher<ObjectIdentifier> MatchesDigest(
- testing::Matcher<std::string> matcher);
-testing::Matcher<ObjectIdentifier> MatchesDigest(
- testing::Matcher<ObjectDigest> matcher);
-
-// Matcher that matches a Ledger entry against a pair of matchers on the entry's
-// key and object_identifier. The entry's priority is not considered in this
-// Matcher.
-testing::Matcher<Entry> MatchesEntry(
- std::pair<testing::Matcher<std::string>, testing::Matcher<ObjectIdentifier>>
- matcher);
-
-// Matcher that matches a Ledger entry against a tuple of matchers on the
-// entry's key, object_identifier and priority.
-testing::Matcher<Entry> MatchesEntry(
- std::tuple<testing::Matcher<std::string>,
- testing::Matcher<ObjectIdentifier>,
- testing::Matcher<KeyPriority>>
- matcher);
-} // namespace storage
-
-#endif // PERIDOT_BIN_LEDGER_STORAGE_TESTING_STORAGE_MATCHER_H_
diff --git a/bin/ledger/storage/testing/storage_matcher_unittest.cc b/bin/ledger/storage/testing/storage_matcher_unittest.cc
deleted file mode 100644
index 2658bbf..0000000
--- a/bin/ledger/storage/testing/storage_matcher_unittest.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/storage/testing/storage_matcher.h"
-
-#include "gtest/gtest.h"
-
-namespace storage {
-namespace {
-
-TEST(StorageMatcher, MatchesDigest) {
- ObjectIdentifier id = {0, 1, ObjectDigest("hello")};
- EXPECT_THAT(id, MatchesDigest("hello"));
- EXPECT_THAT(id, Not(MatchesDigest("hexllo")));
-
- ObjectDigest digest = ObjectDigest("hello");
- EXPECT_THAT(id, MatchesDigest(digest));
-}
-
-TEST(StorageMatcher, MatchesEntry2Parameters) {
- ObjectIdentifier id = {0, 1, ObjectDigest("hello")};
- Entry entry = {"key", id, KeyPriority::EAGER};
-
- EXPECT_THAT(entry, MatchesEntry({"key", MatchesDigest("hello")}));
- EXPECT_THAT(entry, MatchesEntry({"key", id}));
- EXPECT_THAT(entry, Not(MatchesEntry({"key", MatchesDigest("helo")})));
- EXPECT_THAT(entry, Not(MatchesEntry({"ky", MatchesDigest("hello")})));
-}
-
-TEST(StorageMatcher, MatchesEntry3Parameters) {
- Entry entry = {"key", {0, 1, ObjectDigest("hello")}, KeyPriority::EAGER};
-
- EXPECT_THAT(
- entry, MatchesEntry({"key", MatchesDigest("hello"), KeyPriority::EAGER}));
- EXPECT_THAT(
- entry,
- Not(MatchesEntry({"key", MatchesDigest("hello"), KeyPriority::LAZY})));
-}
-
-} // namespace
-} // namespace storage
diff --git a/bin/ledger/sync_coordinator/impl/BUILD.gn b/bin/ledger/sync_coordinator/impl/BUILD.gn
deleted file mode 100644
index e0bc7bf..0000000
--- a/bin/ledger/sync_coordinator/impl/BUILD.gn
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("impl") {
- sources = [
- "ledger_sync_impl.cc",
- "ledger_sync_impl.h",
- "page_sync_impl.cc",
- "page_sync_impl.h",
- "sync_watcher_converter.cc",
- "sync_watcher_converter.h",
- "user_sync_impl.cc",
- "user_sync_impl.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/sync_coordinator/public",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/sync_coordinator/impl/ledger_sync_impl.cc b/bin/ledger/sync_coordinator/impl/ledger_sync_impl.cc
deleted file mode 100644
index 24ef304..0000000
--- a/bin/ledger/sync_coordinator/impl/ledger_sync_impl.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/sync_coordinator/impl/ledger_sync_impl.h"
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/sync_coordinator/impl/page_sync_impl.h"
-
-namespace sync_coordinator {
-
-LedgerSyncImpl::LedgerSyncImpl(
- std::unique_ptr<cloud_sync::LedgerSync> cloud_sync,
- std::unique_ptr<p2p_sync::LedgerCommunicator> p2p_sync)
- : cloud_sync_(std::move(cloud_sync)), p2p_sync_(std::move(p2p_sync)) {}
-
-LedgerSyncImpl::~LedgerSyncImpl() {}
-
-std::unique_ptr<PageSync> LedgerSyncImpl::CreatePageSync(
- storage::PageStorage* page_storage,
- storage::PageSyncClient* page_sync_client) {
- auto combined_sync =
- std::make_unique<PageSyncImpl>(page_storage, page_sync_client);
-
- if (cloud_sync_) {
- auto cloud_page_sync = cloud_sync_->CreatePageSync(
- page_storage, combined_sync->CreateCloudSyncClient());
- combined_sync->SetCloudSync(std::move(cloud_page_sync));
- }
-
- if (p2p_sync_) {
- auto p2p_page_sync = p2p_sync_->GetPageCommunicator(
- page_storage, combined_sync->CreateP2PSyncClient());
- combined_sync->SetP2PSync(std::move(p2p_page_sync));
- }
-
- return combined_sync;
-}
-
-} // namespace sync_coordinator
diff --git a/bin/ledger/sync_coordinator/impl/ledger_sync_impl.h b/bin/ledger/sync_coordinator/impl/ledger_sync_impl.h
deleted file mode 100644
index ed243af..0000000
--- a/bin/ledger/sync_coordinator/impl/ledger_sync_impl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_LEDGER_SYNC_IMPL_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_LEDGER_SYNC_IMPL_H_
-
-#include <functional>
-#include <memory>
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/ledger_sync.h"
-#include "peridot/bin/ledger/p2p_sync/public/ledger_communicator.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/sync_coordinator/public/ledger_sync.h"
-#include "peridot/bin/ledger/sync_coordinator/public/page_sync.h"
-
-namespace sync_coordinator {
-
-class LedgerSyncImpl : public LedgerSync {
- public:
- LedgerSyncImpl(std::unique_ptr<cloud_sync::LedgerSync> cloud_sync,
- std::unique_ptr<p2p_sync::LedgerCommunicator> p2p_sync);
- ~LedgerSyncImpl() override;
-
- // LedgerSync:
- std::unique_ptr<PageSync> CreatePageSync(
- storage::PageStorage* page_storage,
- storage::PageSyncClient* page_sync_client) override;
-
- private:
- std::unique_ptr<cloud_sync::LedgerSync> const cloud_sync_;
- std::unique_ptr<p2p_sync::LedgerCommunicator> const p2p_sync_;
-};
-
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_LEDGER_SYNC_IMPL_H_
diff --git a/bin/ledger/sync_coordinator/impl/page_sync_impl.cc b/bin/ledger/sync_coordinator/impl/page_sync_impl.cc
deleted file mode 100644
index 8ddb8c1..0000000
--- a/bin/ledger/sync_coordinator/impl/page_sync_impl.cc
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/sync_coordinator/impl/page_sync_impl.h"
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-namespace sync_coordinator {
-namespace {
-// Holder for a synchronization provider (cloud or peer-to-peer).
-//
-// This object handles communication between storage and the page synchronizer.
-class SyncProviderHolderBase : public storage::PageSyncClient,
- public storage::PageSyncDelegate {
- public:
- SyncProviderHolderBase();
- ~SyncProviderHolderBase() override;
-
- // storage::PageSyncClient:
- void SetSyncDelegate(storage::PageSyncDelegate* page_sync) override;
-
- // PageSyncDelegate:
- void GetObject(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status status,
- storage::ChangeSource change_source,
- storage::IsObjectSynced is_object_synced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) override;
-
- private:
- storage::PageSyncDelegate* page_sync_delegate_;
-};
-
-SyncProviderHolderBase::SyncProviderHolderBase() {}
-
-SyncProviderHolderBase::~SyncProviderHolderBase() {}
-
-void SyncProviderHolderBase::SetSyncDelegate(
- storage::PageSyncDelegate* page_sync) {
- page_sync_delegate_ = page_sync;
-}
-
-void SyncProviderHolderBase::GetObject(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status status,
- storage::ChangeSource change_source,
- storage::IsObjectSynced is_object_synced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) {
- page_sync_delegate_->GetObject(std::move(object_identifier),
- std::move(callback));
-}
-} // namespace
-
-class PageSyncImpl::CloudSyncHolder : public SyncProviderHolderBase {
- public:
- CloudSyncHolder();
- ~CloudSyncHolder() override;
-
- void SetCloudSync(std::unique_ptr<cloud_sync::PageSync> cloud_sync);
- cloud_sync::PageSync* GetCloudSync();
-
- private:
- std::unique_ptr<cloud_sync::PageSync> cloud_sync_;
-};
-
-PageSyncImpl::CloudSyncHolder::CloudSyncHolder() {}
-
-PageSyncImpl::CloudSyncHolder::~CloudSyncHolder() {}
-
-void PageSyncImpl::CloudSyncHolder::SetCloudSync(
- std::unique_ptr<cloud_sync::PageSync> cloud_sync) {
- FXL_DCHECK(!cloud_sync_);
- cloud_sync_ = std::move(cloud_sync);
-}
-
-cloud_sync::PageSync* PageSyncImpl::CloudSyncHolder::GetCloudSync() {
- FXL_DCHECK(cloud_sync_);
- return cloud_sync_.get();
-}
-
-class PageSyncImpl::P2PSyncHolder : public SyncProviderHolderBase {
- public:
- P2PSyncHolder();
- ~P2PSyncHolder() override;
-
- void SetP2PSync(std::unique_ptr<p2p_sync::PageCommunicator> p2p_sync);
- p2p_sync::PageCommunicator* GetP2PSync();
-
- private:
- std::unique_ptr<p2p_sync::PageCommunicator> p2p_sync_;
-};
-
-PageSyncImpl::P2PSyncHolder::P2PSyncHolder() {}
-
-PageSyncImpl::P2PSyncHolder::~P2PSyncHolder() {}
-
-void PageSyncImpl::P2PSyncHolder::SetP2PSync(
- std::unique_ptr<p2p_sync::PageCommunicator> p2p_sync) {
- FXL_DCHECK(!p2p_sync_);
- p2p_sync_ = std::move(p2p_sync);
-}
-
-p2p_sync::PageCommunicator* PageSyncImpl::P2PSyncHolder::GetP2PSync() {
- FXL_DCHECK(p2p_sync_);
- return p2p_sync_.get();
-}
-
-PageSyncImpl::PageSyncImpl(storage::PageStorage* storage,
- storage::PageSyncClient* sync_client)
- : storage_(storage), sync_client_(sync_client) {
- FXL_DCHECK(storage_);
- FXL_DCHECK(sync_client_);
-}
-
-PageSyncImpl::~PageSyncImpl() {}
-
-storage::PageSyncClient* PageSyncImpl::CreateCloudSyncClient() {
- FXL_DCHECK(!cloud_sync_);
- cloud_sync_ = std::make_unique<CloudSyncHolder>();
- return cloud_sync_.get();
-}
-
-void PageSyncImpl::SetCloudSync(
- std::unique_ptr<cloud_sync::PageSync> cloud_sync) {
- FXL_DCHECK(cloud_sync_);
- if (!cloud_sync) {
- // Cloud sync failed to produce an initialized |cloud_sync| instance - e.g.
- // because cloud provider is disconnected. Unset the entire cloud sync
- // holder to disable the cloud sync logic.
- cloud_sync_.reset();
- return;
- }
-
- cloud_sync->SetOnUnrecoverableError([this] {
- FXL_LOG(WARNING) << "Shutting down page cloud sync.";
- // TODO(ppi): handle recovery from cloud provider disconnection, LE-567.
- cloud_sync_.reset();
- });
- cloud_sync_->SetCloudSync(std::move(cloud_sync));
-}
-
-storage::PageSyncClient* PageSyncImpl::CreateP2PSyncClient() {
- FXL_DCHECK(!p2p_sync_);
- p2p_sync_ = std::make_unique<P2PSyncHolder>();
- return p2p_sync_.get();
-}
-
-void PageSyncImpl::SetP2PSync(
- std::unique_ptr<p2p_sync::PageCommunicator> p2p_sync) {
- FXL_DCHECK(p2p_sync_);
- p2p_sync_->SetP2PSync(std::move(p2p_sync));
-}
-
-void PageSyncImpl::Start() {
- sync_client_->SetSyncDelegate(this);
- if (cloud_sync_) {
- cloud_sync_->GetCloudSync()->Start();
- }
- if (p2p_sync_) {
- p2p_sync_->GetP2PSync()->Start();
- }
-}
-
-void PageSyncImpl::SetOnIdle(fit::closure on_idle) {
- // Only handle cloud sync for now.
- if (cloud_sync_) {
- cloud_sync_->GetCloudSync()->SetOnIdle(std::move(on_idle));
- }
-}
-
-bool PageSyncImpl::IsIdle() {
- if (cloud_sync_) {
- return cloud_sync_->GetCloudSync()->IsIdle();
- }
- return true;
-}
-
-void PageSyncImpl::SetOnBacklogDownloaded(fit::closure on_backlog_downloaded) {
- if (cloud_sync_) {
- cloud_sync_->GetCloudSync()->SetOnBacklogDownloaded(
- std::move(on_backlog_downloaded));
- }
-}
-
-void PageSyncImpl::SetSyncWatcher(SyncStateWatcher* watcher) {
- watcher_ = std::make_unique<SyncWatcherConverter>(watcher);
- if (cloud_sync_) {
- cloud_sync_->GetCloudSync()->SetSyncWatcher(watcher_.get());
- }
-}
-
-void PageSyncImpl::GetObject(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status, storage::ChangeSource,
- storage::IsObjectSynced is_object_synced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) {
- // AnyWaiter returns the first successful value to its Finalize callback. For
- // example, if P2P returns before cloud with a NOT_FOUND status, then we will
- // wait for Cloud to return; if P2P returns with an OK status, we will pass
- // the P2P-returned value immediately.
- auto waiter = fxl::MakeRefCounted<callback::AnyWaiter<
- storage::Status,
- std::tuple<storage::ChangeSource, storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>>>>(
- storage::Status::OK, storage::Status::NOT_FOUND,
- std::tuple<storage::ChangeSource, storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>>());
- if (cloud_sync_) {
- cloud_sync_->GetObject(
- object_identifier,
- [callback = waiter->NewCallback()](
- storage::Status status, storage::ChangeSource source,
- storage::IsObjectSynced is_object_synced,
- std::unique_ptr<storage::DataSource::DataChunk> data) {
- callback(status,
- std::make_tuple(source, is_object_synced, std::move(data)));
- });
- }
- if (p2p_sync_) {
- p2p_sync_->GetObject(
- std::move(object_identifier),
- [callback = waiter->NewCallback()](
- storage::Status status, storage::ChangeSource source,
- storage::IsObjectSynced is_object_synced,
- std::unique_ptr<storage::DataSource::DataChunk> data) {
- callback(status,
- std::make_tuple(source, is_object_synced, std::move(data)));
- });
- }
- waiter->Finalize(
- [callback = std::move(callback)](
- storage::Status status,
- std::tuple<storage::ChangeSource, storage::IsObjectSynced,
- std::unique_ptr<storage::DataSource::DataChunk>>
- data) {
- callback(status, std::get<0>(data), std::get<1>(data),
- std::move(std::get<2>(data)));
- });
-}
-
-} // namespace sync_coordinator
diff --git a/bin/ledger/sync_coordinator/impl/page_sync_impl.h b/bin/ledger/sync_coordinator/impl/page_sync_impl.h
deleted file mode 100644
index bcc9f84..0000000
--- a/bin/ledger/sync_coordinator/impl/page_sync_impl.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_PAGE_SYNC_IMPL_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_PAGE_SYNC_IMPL_H_
-
-#include <functional>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/page_sync.h"
-#include "peridot/bin/ledger/p2p_sync/public/page_communicator.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/storage/public/page_sync_client.h"
-#include "peridot/bin/ledger/storage/public/page_sync_delegate.h"
-#include "peridot/bin/ledger/sync_coordinator/impl/sync_watcher_converter.h"
-#include "peridot/bin/ledger/sync_coordinator/public/page_sync.h"
-
-namespace sync_coordinator {
-
-class PageSyncImpl : public PageSync, public storage::PageSyncDelegate {
- public:
- PageSyncImpl(storage::PageStorage* storage,
- storage::PageSyncClient* sync_client);
- ~PageSyncImpl() override;
-
- // Creates a PageSyncClient for cloud synchronization. This method should be
- // called at most once.
- storage::PageSyncClient* CreateCloudSyncClient();
- // Sets the PageSync for cloud synchronization. A Cloud sync client should
- // have been created first.
- void SetCloudSync(std::unique_ptr<cloud_sync::PageSync> cloud_sync);
-
- // Creates a PageSyncClient for p2p synchronization. This method should be
- // called at most once.
- storage::PageSyncClient* CreateP2PSyncClient();
- // Sets the PageSync for p2p synchronization. A P2P sync client should have
- // been created first.
- void SetP2PSync(std::unique_ptr<p2p_sync::PageCommunicator> p2p_sync);
-
- // PageSync:
- void Start() override;
- void SetOnIdle(fit::closure on_idle) override;
- bool IsIdle() override;
- void SetOnBacklogDownloaded(fit::closure on_backlog_downloaded) override;
- void SetSyncWatcher(SyncStateWatcher* watcher) override;
-
- // PageSyncDelegate:
- void GetObject(
- storage::ObjectIdentifier object_identifier,
- fit::function<void(storage::Status status,
- storage::ChangeSource change_source,
- storage::IsObjectSynced is_object_synced,
- std::unique_ptr<storage::DataSource::DataChunk>)>
- callback) override;
-
- private:
- class CloudSyncHolder;
- class P2PSyncHolder;
-
- std::unique_ptr<SyncWatcherConverter> watcher_;
- std::unique_ptr<CloudSyncHolder> cloud_sync_;
- std::unique_ptr<P2PSyncHolder> p2p_sync_;
-
- storage::PageStorage* const storage_;
- storage::PageSyncClient* const sync_client_;
-};
-
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_PAGE_SYNC_IMPL_H_
diff --git a/bin/ledger/sync_coordinator/impl/sync_watcher_converter.cc b/bin/ledger/sync_coordinator/impl/sync_watcher_converter.cc
deleted file mode 100644
index 5cd6431..0000000
--- a/bin/ledger/sync_coordinator/impl/sync_watcher_converter.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/sync_coordinator/impl/sync_watcher_converter.h"
-
-#include <utility>
-
-namespace sync_coordinator {
-namespace {
-DownloadSyncState ConvertToDownloadSyncState(
- cloud_sync::DownloadSyncState download) {
- switch (download) {
- case cloud_sync::DOWNLOAD_NOT_STARTED:
- return DownloadSyncState::DOWNLOAD_PENDING;
- case cloud_sync::DOWNLOAD_BACKLOG:
- return DownloadSyncState::DOWNLOAD_IN_PROGRESS;
- case cloud_sync::DOWNLOAD_TEMPORARY_ERROR:
- return DownloadSyncState::DOWNLOAD_PENDING;
- case cloud_sync::DOWNLOAD_SETTING_REMOTE_WATCHER:
- return DownloadSyncState::DOWNLOAD_IN_PROGRESS;
- case cloud_sync::DOWNLOAD_IDLE:
- return DownloadSyncState::DOWNLOAD_IDLE;
- case cloud_sync::DOWNLOAD_IN_PROGRESS:
- return DownloadSyncState::DOWNLOAD_IN_PROGRESS;
- case cloud_sync::DOWNLOAD_PERMANENT_ERROR:
- return DownloadSyncState::DOWNLOAD_ERROR;
- }
-}
-
-UploadSyncState ConvertToUploadSyncState(cloud_sync::UploadSyncState upload) {
- switch (upload) {
- case cloud_sync::UPLOAD_NOT_STARTED:
- return UploadSyncState::UPLOAD_PENDING;
- case cloud_sync::UPLOAD_SETUP:
- return UploadSyncState::UPLOAD_PENDING;
- case cloud_sync::UPLOAD_IDLE:
- return UploadSyncState::UPLOAD_IDLE;
- case cloud_sync::UPLOAD_PENDING:
- return UploadSyncState::UPLOAD_PENDING;
- case cloud_sync::UPLOAD_WAIT_TOO_MANY_LOCAL_HEADS:
- return UploadSyncState::UPLOAD_PENDING;
- case cloud_sync::UPLOAD_WAIT_REMOTE_DOWNLOAD:
- return UploadSyncState::UPLOAD_PENDING;
- case cloud_sync::UPLOAD_TEMPORARY_ERROR:
- return UploadSyncState::UPLOAD_PENDING;
- case cloud_sync::UPLOAD_IN_PROGRESS:
- return UploadSyncState::UPLOAD_IN_PROGRESS;
- case cloud_sync::UPLOAD_PERMANENT_ERROR:
- return UploadSyncState::UPLOAD_ERROR;
- }
-}
-
-sync_coordinator::SyncStateWatcher::SyncStateContainer ConvertToSyncState(
- cloud_sync::SyncStateWatcher::SyncStateContainer state) {
- return {ConvertToDownloadSyncState(state.download),
- ConvertToUploadSyncState(state.upload)};
-}
-
-} // namespace
-
-SyncWatcherConverter::SyncWatcherConverter(
- sync_coordinator::SyncStateWatcher* watcher)
- : watcher_(watcher) {}
-SyncWatcherConverter::~SyncWatcherConverter() {}
-
-void SyncWatcherConverter::Notify(SyncStateContainer sync_state) {
- watcher_->Notify(ConvertToSyncState(sync_state));
-}
-} // namespace sync_coordinator
diff --git a/bin/ledger/sync_coordinator/impl/sync_watcher_converter.h b/bin/ledger/sync_coordinator/impl/sync_watcher_converter.h
deleted file mode 100644
index 33bb71a..0000000
--- a/bin/ledger/sync_coordinator/impl/sync_watcher_converter.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_SYNC_WATCHER_CONVERTER_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_SYNC_WATCHER_CONVERTER_H_
-
-#include "peridot/bin/ledger/cloud_sync/public/sync_state_watcher.h"
-#include "peridot/bin/ledger/sync_coordinator/public/sync_state_watcher.h"
-
-namespace sync_coordinator {
-
-// Watcher interface for the current state of data synchronization.
-class SyncWatcherConverter : public cloud_sync::SyncStateWatcher {
- public:
- explicit SyncWatcherConverter(sync_coordinator::SyncStateWatcher* watcher);
- ~SyncWatcherConverter() override;
-
- // Notifies the watcher of a new state.
- void Notify(SyncStateContainer sync_state) override;
-
- private:
- sync_coordinator::SyncStateWatcher* const watcher_;
-};
-
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_SYNC_WATCHER_CONVERTER_H_
diff --git a/bin/ledger/sync_coordinator/impl/user_sync_impl.cc b/bin/ledger/sync_coordinator/impl/user_sync_impl.cc
deleted file mode 100644
index a809dd3..0000000
--- a/bin/ledger/sync_coordinator/impl/user_sync_impl.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/sync_coordinator/impl/user_sync_impl.h"
-
-#include "peridot/bin/ledger/sync_coordinator/impl/ledger_sync_impl.h"
-
-namespace sync_coordinator {
-
-UserSyncImpl::UserSyncImpl(std::unique_ptr<cloud_sync::UserSync> cloud_sync,
- std::unique_ptr<p2p_sync::UserCommunicator> p2p_sync)
- : cloud_sync_(std::move(cloud_sync)), p2p_sync_(std::move(p2p_sync)) {}
-
-UserSyncImpl::~UserSyncImpl() {}
-
-void UserSyncImpl::Start() {
- FXL_DCHECK(!started_);
- started_ = true;
- if (cloud_sync_) {
- cloud_sync_->Start();
- }
- if (p2p_sync_) {
- p2p_sync_->Start();
- }
-}
-void UserSyncImpl::SetWatcher(SyncStateWatcher* watcher) {
- watcher_ = std::make_unique<SyncWatcherConverter>(watcher);
- cloud_sync_->SetSyncWatcher(watcher_.get());
-}
-
-std::unique_ptr<LedgerSync> UserSyncImpl::CreateLedgerSync(
- fxl::StringView app_id, encryption::EncryptionService* encryption_service) {
- FXL_DCHECK(started_);
- std::unique_ptr<cloud_sync::LedgerSync> cloud_ledger_sync;
- if (cloud_sync_) {
- cloud_ledger_sync =
- cloud_sync_->CreateLedgerSync(app_id, encryption_service);
- }
- std::unique_ptr<p2p_sync::LedgerCommunicator> p2p_ledger_sync;
- if (p2p_sync_) {
- // FIXME(etiennej): fix the API
- p2p_ledger_sync = p2p_sync_->GetLedgerCommunicator(app_id.ToString());
- }
- auto combined_sync = std::make_unique<LedgerSyncImpl>(
- std::move(cloud_ledger_sync), std::move(p2p_ledger_sync));
- return combined_sync;
-}
-
-} // namespace sync_coordinator
diff --git a/bin/ledger/sync_coordinator/impl/user_sync_impl.h b/bin/ledger/sync_coordinator/impl/user_sync_impl.h
deleted file mode 100644
index fb93653..0000000
--- a/bin/ledger/sync_coordinator/impl/user_sync_impl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_USER_SYNC_IMPL_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_USER_SYNC_IMPL_H_
-
-#include <memory>
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/user_sync.h"
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/p2p_sync/public/user_communicator.h"
-#include "peridot/bin/ledger/sync_coordinator/impl/sync_watcher_converter.h"
-#include "peridot/bin/ledger/sync_coordinator/public/ledger_sync.h"
-#include "peridot/bin/ledger/sync_coordinator/public/user_sync.h"
-
-namespace sync_coordinator {
-
-class UserSyncImpl : public UserSync {
- public:
- UserSyncImpl(std::unique_ptr<cloud_sync::UserSync> cloud_sync,
- std::unique_ptr<p2p_sync::UserCommunicator> p2p_sync);
- ~UserSyncImpl() override;
-
- // UserSync:
- void Start() override;
- void SetWatcher(SyncStateWatcher* watcher) override;
- std::unique_ptr<LedgerSync> CreateLedgerSync(
- fxl::StringView app_id,
- encryption::EncryptionService* encryption_service) override;
-
- private:
- std::unique_ptr<SyncWatcherConverter> watcher_;
- bool started_ = false;
-
- std::unique_ptr<cloud_sync::UserSync> const cloud_sync_;
- std::unique_ptr<p2p_sync::UserCommunicator> const p2p_sync_;
-};
-
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_IMPL_USER_SYNC_IMPL_H_
diff --git a/bin/ledger/sync_coordinator/public/BUILD.gn b/bin/ledger/sync_coordinator/public/BUILD.gn
deleted file mode 100644
index 6a76ee8..0000000
--- a/bin/ledger/sync_coordinator/public/BUILD.gn
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("public") {
- sources = [
- "ledger_sync.h",
- "page_sync.h",
- "sync_state_watcher.h",
- "user_sync.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/cloud_sync/public",
- "//peridot/bin/ledger/p2p_sync/public",
- "//peridot/bin/ledger/storage/public",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/sync_coordinator/public/ledger_sync.h b/bin/ledger/sync_coordinator/public/ledger_sync.h
deleted file mode 100644
index a2c13f4..0000000
--- a/bin/ledger/sync_coordinator/public/ledger_sync.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_LEDGER_SYNC_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_LEDGER_SYNC_H_
-
-#include <functional>
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/cloud_sync/public/ledger_sync.h"
-#include "peridot/bin/ledger/p2p_sync/public/ledger_communicator.h"
-#include "peridot/bin/ledger/storage/public/page_storage.h"
-#include "peridot/bin/ledger/sync_coordinator/public/page_sync.h"
-
-namespace sync_coordinator {
-
-// Manages synchronization for a ledger.
-class LedgerSync {
- public:
- LedgerSync() {}
- virtual ~LedgerSync() {}
-
- // Creates a new page sync for the given page.
- virtual std::unique_ptr<PageSync> CreatePageSync(
- storage::PageStorage* page_storage,
- storage::PageSyncClient* page_sync_client) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerSync);
-};
-
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_LEDGER_SYNC_H_
diff --git a/bin/ledger/sync_coordinator/public/page_sync.h b/bin/ledger/sync_coordinator/public/page_sync.h
deleted file mode 100644
index d594e9b..0000000
--- a/bin/ledger/sync_coordinator/public/page_sync.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_PAGE_SYNC_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_PAGE_SYNC_H_
-
-#include <functional>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/sync_coordinator/public/sync_state_watcher.h"
-
-namespace sync_coordinator {
-
-// Manages synchronization of a single page.
-//
-// PageSync is responsible for uploading locally created artifacts (commits and
-// objects) of the page and for fetching remote artifacts of the same page and
-// putting them in storage. It manages coordination between upload/download
-// throught the cloud and through local peers.
-class PageSync {
- public:
- PageSync() {}
- virtual ~PageSync() {}
-
- // Starts syncing. Upon connection drop, the sync will restart automatically,
- // the client doesn't need to call Start() again.
- virtual void Start() = 0;
-
- // Sets a callback that will be called after Start() every time when PageSync
- // becomes idle, that is: finished uploading all unsynced local artifacts and
- // not downloading any remote artifacts. Can be set at most once and only
- // before calling Start().
- virtual void SetOnIdle(fit::closure on_idle) = 0;
-
- // Returns true iff PageSync is idle, that is with no pending upload or
- // download work.
- virtual bool IsIdle() = 0;
-
- // Sets a callback that will be called at most once after Start(), when all
- // remote commits added to the cloud between the last sync and starting the
- // current sync are added to storage. This can be used by the client to delay
- // exposing the local page until it catches up with the cloud. Can be set at
- // most once and only before calling Start().
- virtual void SetOnBacklogDownloaded(fit::closure on_backlog_downloaded) = 0;
-
- // Sets a watcher for the synchronization state of this page.
- virtual void SetSyncWatcher(SyncStateWatcher* watcher) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageSync);
-};
-
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_PAGE_SYNC_H_
diff --git a/bin/ledger/sync_coordinator/public/sync_state_watcher.h b/bin/ledger/sync_coordinator/public/sync_state_watcher.h
deleted file mode 100644
index 54d0296..0000000
--- a/bin/ledger/sync_coordinator/public/sync_state_watcher.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_SYNC_STATE_WATCHER_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_SYNC_STATE_WATCHER_H_
-
-namespace sync_coordinator {
-// Detail of the download part of the synchronization state.
-enum DownloadSyncState {
- DOWNLOAD_IDLE = 0,
- DOWNLOAD_PENDING,
- DOWNLOAD_IN_PROGRESS,
- DOWNLOAD_ERROR,
-};
-
-// Detail of the upload part of the synchronization state.
-enum UploadSyncState {
- UPLOAD_IDLE = 0,
- UPLOAD_PENDING,
- UPLOAD_IN_PROGRESS,
- UPLOAD_ERROR,
-};
-
-// Watcher interface for the current state of data synchronization
-class SyncStateWatcher {
- public:
- // Container for the synchronization state, containing both download and
- // upload components.
- struct SyncStateContainer {
- DownloadSyncState download = DOWNLOAD_IDLE;
- UploadSyncState upload = UPLOAD_IDLE;
- };
-
- virtual ~SyncStateWatcher() {}
-
- // Notifies the watcher of a new state.
- virtual void Notify(SyncStateContainer sync_state) = 0;
-};
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_SYNC_STATE_WATCHER_H_
diff --git a/bin/ledger/sync_coordinator/public/user_sync.h b/bin/ledger/sync_coordinator/public/user_sync.h
deleted file mode 100644
index 8293633..0000000
--- a/bin/ledger/sync_coordinator/public/user_sync.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_USER_SYNC_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_USER_SYNC_H_
-
-#include <memory>
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/encryption/public/encryption_service.h"
-#include "peridot/bin/ledger/sync_coordinator/public/ledger_sync.h"
-
-namespace sync_coordinator {
-
-// Top level factory for every object sync related for a given user.
-class UserSync {
- public:
- UserSync() {}
- virtual ~UserSync() {}
-
- // Starts the user-level synchronization.
- virtual void Start() = 0;
-
- // Sets a watcher aggregating the synchronization state of all operations
- // under this user. Set to nullptr for unregistering.
- virtual void SetWatcher(SyncStateWatcher* watcher) = 0;
-
- // Returns the Ledger-level synchronization object. The user-level
- // synchronization must be started before calling this method.
- virtual std::unique_ptr<LedgerSync> CreateLedgerSync(
- fxl::StringView app_id,
- encryption::EncryptionService* encryption_service) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(UserSync);
-};
-
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_PUBLIC_USER_SYNC_H_
diff --git a/bin/ledger/sync_coordinator/testing/BUILD.gn b/bin/ledger/sync_coordinator/testing/BUILD.gn
deleted file mode 100644
index 3004996..0000000
--- a/bin/ledger/sync_coordinator/testing/BUILD.gn
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "page_sync_empty_impl.cc",
- "page_sync_empty_impl.h",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/sync_coordinator/public",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/sync_coordinator/testing/page_sync_empty_impl.cc b/bin/ledger/sync_coordinator/testing/page_sync_empty_impl.cc
deleted file mode 100644
index 79ecf04..0000000
--- a/bin/ledger/sync_coordinator/testing/page_sync_empty_impl.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/sync_coordinator/testing/page_sync_empty_impl.h"
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-namespace sync_coordinator {
-
-void PageSyncEmptyImpl::Start() { FXL_NOTIMPLEMENTED(); }
-
-void PageSyncEmptyImpl::SetOnIdle(fit::closure /*on_idle_callback*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-bool PageSyncEmptyImpl::IsIdle() {
- FXL_NOTIMPLEMENTED();
- return true;
-}
-
-void PageSyncEmptyImpl::SetOnBacklogDownloaded(
- fit::closure /*on_backlog_downloaded_callback*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-void PageSyncEmptyImpl::SetSyncWatcher(SyncStateWatcher* /*watcher*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-} // namespace sync_coordinator
diff --git a/bin/ledger/sync_coordinator/testing/page_sync_empty_impl.h b/bin/ledger/sync_coordinator/testing/page_sync_empty_impl.h
deleted file mode 100644
index 29725f1..0000000
--- a/bin/ledger/sync_coordinator/testing/page_sync_empty_impl.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_TESTING_PAGE_SYNC_EMPTY_IMPL_H_
-#define PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_TESTING_PAGE_SYNC_EMPTY_IMPL_H_
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/sync_coordinator/public/page_sync.h"
-
-namespace sync_coordinator {
-
-class PageSyncEmptyImpl : public PageSync {
- public:
- // PageSync:
- void Start() override;
- void SetOnIdle(fit::closure on_idle_callback) override;
- bool IsIdle() override;
- void SetOnBacklogDownloaded(
- fit::closure on_backlog_downloaded_callback) override;
- void SetSyncWatcher(SyncStateWatcher* watcher) override;
-};
-
-} // namespace sync_coordinator
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_COORDINATOR_TESTING_PAGE_SYNC_EMPTY_IMPL_H_
diff --git a/bin/ledger/sync_helper/BUILD.gn b/bin/ledger/sync_helper/BUILD.gn
deleted file mode 100644
index dfbb3f1..0000000
--- a/bin/ledger/sync_helper/BUILD.gn
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("sync_helper") {
- sources = [
- "mutable.h",
- "sync_helper.cc",
- "sync_helper.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "mutable_unittest.cc",
- "sync_helper_unittest.cc",
- ]
-
- deps = [
- ":sync_helper",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/sync_helper/mutable.h b/bin/ledger/sync_helper/mutable.h
deleted file mode 100644
index c198c7a..0000000
--- a/bin/ledger/sync_helper/mutable.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_HELPER_MUTABLE_H_
-#define PERIDOT_BIN_LEDGER_SYNC_HELPER_MUTABLE_H_
-
-#include <utility>
-
-namespace ledger {
-
-// This class wraps a type A so that a const instance of Mutable<A> can still
-// mutate the internal A object.
-// It is used to capture a mutable variable in a non mutable lambda:
-// [b = Mutable(false)] {
-// *b = true;
-// }
-template <typename A>
-class Mutable {
- public:
- explicit Mutable(A value) : value_(std::move(value)) {}
- Mutable(Mutable&&) = default;
- Mutable<A>& operator=(Mutable&&) = default;
-
- A& operator*() const { return value_; }
-
- A* operator->() const { return &value_; }
-
- private:
- mutable A value_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_HELPER_MUTABLE_H_
diff --git a/bin/ledger/sync_helper/mutable_unittest.cc b/bin/ledger/sync_helper/mutable_unittest.cc
deleted file mode 100644
index 3f0664f..0000000
--- a/bin/ledger/sync_helper/mutable_unittest.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/sync_helper/mutable.h"
-
-#include "gtest/gtest.h"
-
-namespace ledger {
-namespace {
-
-TEST(MutableTest, ConstIsMutable) {
- const auto foo = Mutable(false);
- EXPECT_FALSE(*foo);
- *foo = true;
- EXPECT_TRUE(*foo);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/sync_helper/sync_helper.cc b/bin/ledger/sync_helper/sync_helper.cc
deleted file mode 100644
index 9220ea3..0000000
--- a/bin/ledger/sync_helper/sync_helper.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/sync_helper/sync_helper.h"
-
-namespace ledger {
-
-SyncHelper::SyncHelper() : current_sync_point_(0), weak_ptr_factory_(this) {}
-
-void SyncHelper::RegisterSynchronizationCallback(
- fit::function<void()> callback) {
- if (in_flight_operation_counts_per_sync_point_.empty()) {
- callback();
- return;
- }
-
- sync_callback_per_sync_points_[current_sync_point_] = std::move(callback);
- ++current_sync_point_;
- in_flight_operation_counts_per_sync_point_[current_sync_point_] = 0;
-}
-
-void SyncHelper::CallSynchronizationCallbacks() {
- for (auto it = in_flight_operation_counts_per_sync_point_.begin();
- it != in_flight_operation_counts_per_sync_point_.end() &&
- it->second == 0;
- it = in_flight_operation_counts_per_sync_point_.erase(it)) {
- auto sync_point_it = sync_callback_per_sync_points_.find(it->first);
- if (sync_point_it != sync_callback_per_sync_points_.end()) {
- sync_point_it->second();
- sync_callback_per_sync_points_.erase(sync_point_it);
- }
- }
- if (empty() && on_empty_callback_) {
- on_empty_callback_();
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/sync_helper/sync_helper.h b/bin/ledger/sync_helper/sync_helper.h
deleted file mode 100644
index c646931..0000000
--- a/bin/ledger/sync_helper/sync_helper.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_SYNC_HELPER_SYNC_HELPER_H_
-#define PERIDOT_BIN_LEDGER_SYNC_HELPER_SYNC_HELPER_H_
-
-#include <map>
-#include <utility>
-
-#include <lib/callback/scoped_callback.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/ledger/sync_helper/mutable.h"
-
-namespace ledger {
-
-// This class allows to register operations and synchronization callback.
-// Operation are registered by wrapping the callback that they are expected to
-// call when they are finished.
-// A synchronization callback is an callback that takes no parameter and that
-// will be called by this class when all operations registered before the
-// synchronization callback have finished.
-class SyncHelper {
- public:
- SyncHelper();
- SyncHelper(const SyncHelper&) = delete;
- SyncHelper& operator=(const SyncHelper&) = delete;
-
- // Sets the callback to be called every time the SyncHelper is empty.
- // SyncHelper is empty when no operation is currently in progress.
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- // Returns whether there is currently no running operation.
- bool empty() { return in_flight_operation_counts_per_sync_point_.empty(); }
-
- // Registers a synchronization callback. |callback| will be called when all
- // operation wrapped by |WrapOperation| before the call to
- // |RegisterSynchronizationCallback| have finished.
- void RegisterSynchronizationCallback(fit::function<void()> callback);
-
- // Wraps |callback| and marks it as a live operation. No callback registered
- // through |RegisterSynchronizationCallback| after this call will be called
- // until the returned callback has been called at least once.
- template <typename A>
- auto WrapOperation(A callback) {
- auto sync_point = current_sync_point_;
- in_flight_operation_counts_per_sync_point_[sync_point]++;
- auto on_first_call = fit::defer(callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(), [this, sync_point] {
- if (--in_flight_operation_counts_per_sync_point_[sync_point] == 0) {
- CallSynchronizationCallbacks();
- }
- }));
- // The lambda is not marked mutable, because the original callback might
- // have a const operator, and this should not force the receiver to use
- // only non-const operator.
- // Because of this:
- // - on_first_callcallback| must be wrap into a Mutable because calling it
- // is not a const operation.
- // - |callback| must be wrap into a Mutable because it might not have a
- // const operator().
- return
- [callback = Mutable(std::move(callback)),
- on_first_call = Mutable(std::move(on_first_call))](auto&&... params) {
- (*callback)(std::forward<decltype(params)>(params)...);
- on_first_call->call();
- };
- }
-
- private:
- // Calls all synchronization callbacks that are currently due.
- void CallSynchronizationCallbacks();
-
- // This class operates with a virtual timestamp.
- // - Each time an operation is registered, it increases the number of
- // operation at the current timestamp.
- // - Each time a synchronization callback is registered, it is either
- // immediately called if no operation is in progress, or it is associated
- // with the current timestamp, and after this, the current timestamp is
- // incremented.
- // - Each time an operation terminates, it decrements the number of operations
- // at the current timestamp. Then the algorithm looks at all timestamp in
- // increasing order. Until it finds one for which there is still operation
- // in progress, it calls the associated synchronization callback.
-
- // The current timestamp.
- int64_t current_sync_point_;
- // The synchronization callbacks associated to their respective timestamp.
- std::map<int64_t, fit::function<void()>> sync_callback_per_sync_points_;
- // The number of operation in progress for each timestamp.
- std::map<int64_t, int64_t> in_flight_operation_counts_per_sync_point_;
-
- fit::closure on_empty_callback_;
-
- // This must be the last member.
- fxl::WeakPtrFactory<SyncHelper> weak_ptr_factory_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_SYNC_HELPER_SYNC_HELPER_H_
diff --git a/bin/ledger/sync_helper/sync_helper_unittest.cc b/bin/ledger/sync_helper/sync_helper_unittest.cc
deleted file mode 100644
index 6505d23..0000000
--- a/bin/ledger/sync_helper/sync_helper_unittest.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/sync_helper/sync_helper.h"
-
-#include "garnet/public/lib/callback/set_when_called.h"
-#include "gtest/gtest.h"
-
-namespace ledger {
-namespace {
-
-TEST(SyncHelper, NoOperation) {
- SyncHelper sync_helper;
- bool called = false;
- sync_helper.RegisterSynchronizationCallback(callback::SetWhenCalled(&called));
- EXPECT_TRUE(called);
-}
-
-TEST(SyncHelper, OneOperation) {
- SyncHelper sync_helper;
- auto operation = sync_helper.WrapOperation([] {});
- bool called = false;
- sync_helper.RegisterSynchronizationCallback(callback::SetWhenCalled(&called));
- EXPECT_FALSE(called);
- operation();
- EXPECT_TRUE(called);
-}
-
-TEST(SyncHelper, TwoSyncCallbacks) {
- SyncHelper sync_helper;
- auto operation = sync_helper.WrapOperation([] {});
- bool called1 = false;
- bool called2 = false;
- sync_helper.RegisterSynchronizationCallback(
- callback::SetWhenCalled(&called1));
- sync_helper.RegisterSynchronizationCallback(
- callback::SetWhenCalled(&called2));
- EXPECT_FALSE(called1);
- EXPECT_FALSE(called2);
- operation();
- EXPECT_TRUE(called1);
- EXPECT_TRUE(called2);
-}
-
-TEST(SyncHelper, TwoOperation) {
- SyncHelper sync_helper;
- auto operation1 = sync_helper.WrapOperation([] {});
- auto operation2 = sync_helper.WrapOperation([] {});
- bool called = false;
- sync_helper.RegisterSynchronizationCallback(callback::SetWhenCalled(&called));
-
- EXPECT_FALSE(called);
- operation1();
- EXPECT_FALSE(called);
- operation2();
- EXPECT_TRUE(called);
-}
-
-TEST(SyncHelper, TwoOperationReversed) {
- SyncHelper sync_helper;
- auto operation1 = sync_helper.WrapOperation([] {});
- auto operation2 = sync_helper.WrapOperation([] {});
- bool called = false;
- sync_helper.RegisterSynchronizationCallback(callback::SetWhenCalled(&called));
-
- EXPECT_FALSE(called);
- operation2();
- EXPECT_FALSE(called);
- operation1();
- EXPECT_TRUE(called);
-}
-
-TEST(SyncHelper, TwoOperationTwoCallbacks) {
- SyncHelper sync_helper;
- auto operation1 = sync_helper.WrapOperation([] {});
- bool called1 = false;
- sync_helper.RegisterSynchronizationCallback(
- callback::SetWhenCalled(&called1));
- auto operation2 = sync_helper.WrapOperation([] {});
- bool called2 = false;
- sync_helper.RegisterSynchronizationCallback(
- callback::SetWhenCalled(&called2));
-
- EXPECT_FALSE(called1);
- EXPECT_FALSE(called2);
- operation1();
- EXPECT_TRUE(called1);
- EXPECT_FALSE(called2);
- operation2();
- EXPECT_TRUE(called1);
- EXPECT_TRUE(called2);
-}
-
-TEST(SyncHelper, CallOperationTwice) {
- SyncHelper sync_helper;
- int operation_count = 0;
- auto operation = sync_helper.WrapOperation([&] { ++operation_count; });
- int called_count = 0;
- sync_helper.RegisterSynchronizationCallback([&] { ++called_count; });
-
- EXPECT_EQ(0, operation_count);
- EXPECT_EQ(0, called_count);
- operation();
- EXPECT_EQ(1, operation_count);
- EXPECT_EQ(1, called_count);
- operation();
- EXPECT_EQ(2, operation_count);
- EXPECT_EQ(1, called_count);
-}
-
-TEST(SyncHelper, WrapMutableLambda) {
- SyncHelper sync_helper;
- bool called = false;
- sync_helper.WrapOperation([&called]() mutable { called = true; })();
- EXPECT_TRUE(called);
-}
-
-TEST(SyncHelper, StoreConstWrappedOperation) {
- SyncHelper sync_helper;
- bool called = false;
- const auto operation =
- sync_helper.WrapOperation(callback::SetWhenCalled(&called));
- EXPECT_FALSE(called);
- operation();
- EXPECT_TRUE(called);
-}
-
-TEST(SyncHelper, OnEmptyCallback) {
- SyncHelper sync_helper;
- bool on_empty_called;
- sync_helper.set_on_empty(callback::SetWhenCalled(&on_empty_called));
- EXPECT_TRUE(sync_helper.empty());
- const auto operation = sync_helper.WrapOperation([] {});
- EXPECT_FALSE(on_empty_called);
- EXPECT_FALSE(sync_helper.empty());
- operation();
- EXPECT_TRUE(on_empty_called);
- EXPECT_TRUE(sync_helper.empty());
-}
-
-TEST(SyncHelper, SyncWithDeletedOperation) {
- SyncHelper sync_helper;
- bool called;
- fit::closure operation = sync_helper.WrapOperation([] {});
- sync_helper.RegisterSynchronizationCallback(callback::SetWhenCalled(&called));
- EXPECT_FALSE(called);
- operation = nullptr;
- EXPECT_TRUE(called);
-}
-
-TEST(SyncHelper, OnEmptyWithDeletedOperation) {
- SyncHelper sync_helper;
- bool on_empty_called;
- sync_helper.set_on_empty(callback::SetWhenCalled(&on_empty_called));
- fit::closure operation = sync_helper.WrapOperation([] {});
- EXPECT_FALSE(on_empty_called);
- operation = nullptr;
- EXPECT_TRUE(on_empty_called);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/testing/BUILD.gn b/bin/ledger/testing/BUILD.gn
deleted file mode 100644
index 6a4508b..0000000
--- a/bin/ledger/testing/BUILD.gn
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- "//peridot/bin/ledger/*",
- "//peridot/bin/cloud_provider_firestore/validation",
-]
-
-source_set("lib") {
- testonly = true
-
- sources = [
- "data_generator.cc",
- "data_generator.h",
- "fake_disk_cleanup_manager.h",
- "get_page_ensure_initialized.cc",
- "get_page_ensure_initialized.h",
- "inspect.cc",
- "inspect.h",
- "ledger_matcher.cc",
- "ledger_matcher.h",
- "page_data_generator.cc",
- "page_data_generator.h",
- "quit_on_error.cc",
- "quit_on_error.h",
- "run_with_tracing.cc",
- "run_with_tracing.h",
- "sync_params.cc",
- "sync_params.h",
- "test_with_environment.cc",
- "test_with_environment.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp/testing",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//garnet/public/lib/timekeeper:testing",
- "//peridot/bin/ledger/app:lib",
- "//peridot/bin/ledger/environment",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/storage/public:public",
- "//peridot/lib/convert",
- "//peridot/lib/firebase_auth/testing:service_account",
- "//peridot/lib/rng:testing",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- "//third_party/rapidjson",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.net.oldhttp",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/coroutine",
- "//peridot/bin/ledger/fidl",
- "//peridot/lib/firebase_auth/testing",
- "//peridot/lib/firebase_auth/testing:json_schema",
- "//peridot/lib/firebase_auth/testing:service_account",
- "//third_party/boringssl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("ledger_instance_factory") {
- testonly = true
-
- sources = [
- "blocking_callback_waiter.cc",
- "blocking_callback_waiter.h",
- "ledger_app_instance_factory.cc",
- "ledger_app_instance_factory.h",
- "loop_controller.h",
- "loop_controller_real_loop.cc",
- "loop_controller_real_loop.h",
- "loop_controller_test_loop.cc",
- "loop_controller_test_loop.h",
- ]
-
- public_deps = [
- ":lib",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/fidl_helpers",
- "//peridot/lib/scoped_tmpfs",
- "//peridot/public/fidl/fuchsia.ledger",
- ]
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fsl",
- "//peridot/lib/convert",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-# TODO(https://fuchsia.atlassian.net/projects/LE/issues/LE-607): Consider moving to benchmarks/.
-source_set("get_ledger") {
- testonly = true
-
- sources = [
- "get_ledger.cc",
- "get_ledger.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/bin/ledger/filesystem",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//zircon/public/lib/fit",
- ]
-
- deps = [
- "//garnet/public/lib/callback",
- "//peridot/bin/ledger/fidl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "blocking_callback_waiter_unittest.cc",
- "ledger_matcher_unittest.cc",
- ]
-
- deps = [
- ":ledger_instance_factory",
- ":lib",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- "//zircon/public/lib/async-loop-cpp",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/testing/blocking_callback_waiter.cc b/bin/ledger/testing/blocking_callback_waiter.cc
deleted file mode 100644
index 44e0407..0000000
--- a/bin/ledger/testing/blocking_callback_waiter.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/blocking_callback_waiter.h"
-
-#include <lib/fit/defer.h>
-
-namespace ledger {
-
-BlockingCallbackWaiter::BlockingCallbackWaiter(LoopController* loop_controller)
- : loop_controller_(loop_controller) {}
-
-BlockingCallbackWaiter::~BlockingCallbackWaiter() {}
-
-fit::function<void()> BlockingCallbackWaiter::GetCallback() {
- live_callbacks_count_++;
- auto on_callback_deletion = fit::defer([this] {
- live_callbacks_count_--;
- if (live_callbacks_count_ == 0 && running_) {
- // All callbacks have went out of scope while |RunUntilCalled|: no other
- // callback can stop the loop, exit immediately.
- loop_controller_->StopLoop();
- }
- });
- return [this, on_callback_deletion = std::move(on_callback_deletion)] {
- ++callback_called_count_;
- if (running_) {
- // Called during |RunUntilCalled|: exit from the loop.
- loop_controller_->StopLoop();
- }
- };
-}
-
-bool BlockingCallbackWaiter::RunUntilCalled() {
- FXL_DCHECK(!running_);
- running_ = true;
- auto cleanup = fit::defer([this] { running_ = false; });
- while (NotCalledYet()) {
- if (live_callbacks_count_ == 0) {
- // Do not start the loop if no callback is available to stop it.
- return false;
- }
- loop_controller_->RunLoop();
- }
- ++run_until_called_count_;
- return true;
-}
-
-bool BlockingCallbackWaiter::NotCalledYet() {
- return callback_called_count_ <= run_until_called_count_;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/blocking_callback_waiter.h b/bin/ledger/testing/blocking_callback_waiter.h
deleted file mode 100644
index 11303cd..0000000
--- a/bin/ledger/testing/blocking_callback_waiter.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_BLOCKING_CALLBACK_WAITER_H_
-#define PERIDOT_BIN_LEDGER_TESTING_BLOCKING_CALLBACK_WAITER_H_
-
-#include "peridot/bin/ledger/testing/loop_controller.h"
-
-namespace ledger {
-
-// An implementation of |CallbackWaiter| that will block indefinitely until its
-// callback is called.
-class BlockingCallbackWaiter : public CallbackWaiter {
- public:
- explicit BlockingCallbackWaiter(LoopController* loop_controller);
- BlockingCallbackWaiter(const BlockingCallbackWaiter&) = delete;
- BlockingCallbackWaiter& operator=(const BlockingCallbackWaiter&) = delete;
- ~BlockingCallbackWaiter() override;
-
- fit::function<void()> GetCallback() override;
- bool RunUntilCalled() override;
- bool NotCalledYet() override;
-
- private:
- LoopController* loop_controller_;
- size_t callback_called_count_ = 0;
- size_t run_until_called_count_ = 0;
- size_t live_callbacks_count_ = 0;
- // Whether the waiter is currently in the |RunUntilCalled| method.
- bool running_ = false;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_BLOCKING_CALLBACK_WAITER_H_
diff --git a/bin/ledger/testing/blocking_callback_waiter_unittest.cc b/bin/ledger/testing/blocking_callback_waiter_unittest.cc
deleted file mode 100644
index 0e6c45f..0000000
--- a/bin/ledger/testing/blocking_callback_waiter_unittest.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/blocking_callback_waiter.h"
-
-#include <memory>
-
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-
-namespace ledger {
-namespace {
-
-class FakeLoopController : public LoopController {
- public:
- FakeLoopController(fit::function<void()> on_run,
- fit::function<void()> on_stop)
- : on_run_(std::move(on_run)), on_stop_(std::move(on_stop)) {}
- FakeLoopController(const FakeLoopController&) = delete;
- FakeLoopController& operator=(const FakeLoopController&) = delete;
-
- void RunLoop() override { on_run_(); };
-
- void StopLoop() override { on_stop_(); };
-
- std::unique_ptr<SubLoop> StartNewLoop() override {
- FXL_NOTREACHED();
- return nullptr;
- }
-
- std::unique_ptr<CallbackWaiter> NewWaiter() override {
- return std::make_unique<BlockingCallbackWaiter>(this);
- }
-
- async_dispatcher_t* dispatcher() override {
- FXL_NOTREACHED();
- return nullptr;
- }
-
- bool RunLoopUntil(fit::function<bool()> /* condition */) override {
- FXL_NOTREACHED();
- return false;
- }
-
- void RunLoopFor(zx::duration /* duration */) override { FXL_NOTREACHED(); }
-
- private:
- fit::function<void()> on_run_;
- fit::function<void()> on_stop_;
-};
-
-TEST(BlockingCallbackWaiterTest, PreCall) {
- size_t nb_run = 0;
- size_t nb_stop = 0;
- FakeLoopController loop_controller([&] { ++nb_run; }, [&] { ++nb_stop; });
-
- auto waiter = loop_controller.NewWaiter();
- auto callback = waiter->GetCallback();
-
- callback();
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- EXPECT_EQ(0u, nb_run);
- EXPECT_EQ(0u, nb_stop);
-}
-
-TEST(BlockingCallbackWaiterTest, MultipleGetCallback) {
- size_t nb_run = 0;
- size_t nb_stop = 0;
- FakeLoopController loop_controller([&] { ++nb_run; }, [&] { ++nb_stop; });
-
- auto waiter = loop_controller.NewWaiter();
-
- waiter->GetCallback()();
- waiter->GetCallback()();
-
- ASSERT_TRUE(waiter->RunUntilCalled());
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- EXPECT_EQ(0u, nb_run);
- EXPECT_EQ(0u, nb_stop);
-}
-
-TEST(BlockingCallbackWaiterTest, PostCall) {
- size_t nb_run = 0;
- size_t nb_stop = 0;
- std::unique_ptr<fit::closure> callback;
- FakeLoopController loop_controller(
- [&] {
- ++nb_run;
- if (callback) {
- (*callback)();
- }
- },
- [&] { ++nb_stop; });
-
- auto waiter = loop_controller.NewWaiter();
- callback = std::make_unique<fit::closure>(waiter->GetCallback());
-
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(1u, nb_run);
- EXPECT_EQ(1u, nb_stop);
-
- // loop_controller must outlive the waiter.
- callback.reset();
-}
-
-TEST(BlockingCallbackWaiterTest, MultipleRunUntilCalled) {
- size_t nb_run = 0;
- size_t nb_stop = 0;
- std::unique_ptr<fit::closure> callback;
- FakeLoopController loop_controller(
- [&] {
- ++nb_run;
- if (callback) {
- (*callback)();
- }
- },
- [&] { ++nb_stop; });
-
- auto waiter = loop_controller.NewWaiter();
- callback = std::make_unique<fit::closure>(waiter->GetCallback());
-
- ASSERT_TRUE(waiter->RunUntilCalled());
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(2u, nb_run);
- EXPECT_EQ(2u, nb_stop);
-
- // loop_controller must outlive the waiter.
- callback.reset();
-}
-
-TEST(BlockingCallbackWaiterTest, InterleaveRunUntilCalledAndCall) {
- size_t nb_run = 0;
- size_t nb_stop = 0;
- std::unique_ptr<fit::closure> callback;
- FakeLoopController loop_controller(
- [&] {
- ++nb_run;
- if (callback) {
- (*callback)();
- }
- },
- [&] { ++nb_stop; });
-
- auto waiter = loop_controller.NewWaiter();
- callback = std::make_unique<fit::closure>(waiter->GetCallback());
-
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(1u, nb_run);
- EXPECT_EQ(1u, nb_stop);
-
- (*callback)();
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(1u, nb_run);
- EXPECT_EQ(1u, nb_stop);
-
- // loop_controller must outlive the waiter.
- callback.reset();
-}
-
-TEST(BlockingCallbackWaiterTest, NotCalledYet) {
- FakeLoopController loop_controller([] {}, [] {});
- auto waiter = loop_controller.NewWaiter();
- auto callback = waiter->GetCallback();
-
- EXPECT_TRUE(waiter->NotCalledYet());
-
- callback();
- EXPECT_FALSE(waiter->NotCalledYet());
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_TRUE(waiter->NotCalledYet());
-
- callback();
- callback();
- EXPECT_FALSE(waiter->NotCalledYet());
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_FALSE(waiter->NotCalledYet());
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_TRUE(waiter->NotCalledYet());
-}
-
-TEST(BlockingCallbackWaiterTest, FailedWhenNoCallbackIsAlive) {
- std::unique_ptr<fit::closure> on_run_callback;
- FakeLoopController loop_controller(
- [&] {
- if (on_run_callback) {
- (*on_run_callback)();
- }
- },
- [] {});
- auto waiter = loop_controller.NewWaiter();
-
- EXPECT_FALSE(waiter->RunUntilCalled());
-
- fit::closure callback = waiter->GetCallback();
- callback = nullptr;
- EXPECT_FALSE(waiter->RunUntilCalled());
-
- callback = waiter->GetCallback();
- on_run_callback = std::make_unique<fit::closure>([&] { callback = nullptr; });
- EXPECT_FALSE(waiter->RunUntilCalled());
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/testing/cloud_provider/BUILD.gn b/bin/ledger/testing/cloud_provider/BUILD.gn
deleted file mode 100644
index 9b56236..0000000
--- a/bin/ledger/testing/cloud_provider/BUILD.gn
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("cloud_provider") {
- testonly = true
-
- sources = [
- "fake_cloud_provider.cc",
- "fake_cloud_provider.h",
- "fake_device_set.cc",
- "fake_device_set.h",
- "fake_page_cloud.cc",
- "fake_page_cloud.h",
- "types.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl/include",
- "//peridot/lib/commit_pack",
- ]
-
- deps = [
- "//peridot/bin/ledger/fidl_helpers",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//third_party/murmurhash",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/testing/cloud_provider/fake_cloud_provider.cc b/bin/ledger/testing/cloud_provider/fake_cloud_provider.cc
deleted file mode 100644
index c4da516..0000000
--- a/bin/ledger/testing/cloud_provider/fake_cloud_provider.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/cloud_provider/fake_cloud_provider.h"
-
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-FakeCloudProvider::Builder::Builder() = default;
-
-FakeCloudProvider::Builder::~Builder() = default;
-
-FakeCloudProvider::Builder& FakeCloudProvider::Builder::SetInjectNetworkError(
- InjectNetworkError inject_network_error) {
- inject_network_error_ = inject_network_error;
- return *this;
-}
-
-FakeCloudProvider::Builder& FakeCloudProvider::Builder::SetCloudEraseOnCheck(
- CloudEraseOnCheck cloud_erase_on_check) {
- cloud_erase_on_check_ = cloud_erase_on_check;
- return *this;
-}
-
-FakeCloudProvider::Builder&
-FakeCloudProvider::Builder::SetCloudEraseFromWatcher(
- CloudEraseFromWatcher cloud_erase_from_watcher) {
- cloud_erase_from_watcher_ = cloud_erase_from_watcher;
- return *this;
-}
-
-std::unique_ptr<FakeCloudProvider> FakeCloudProvider::Builder::Build() {
- return std::make_unique<FakeCloudProvider>(*this);
-}
-
-FakeCloudProvider::FakeCloudProvider(const Builder& builder)
- : device_set_(builder.cloud_erase_on_check_,
- builder.cloud_erase_from_watcher_),
- inject_network_error_(builder.inject_network_error_) {}
-
-FakeCloudProvider::FakeCloudProvider() : FakeCloudProvider(Builder()) {}
-
-FakeCloudProvider::~FakeCloudProvider() {}
-
-void FakeCloudProvider::GetDeviceSet(
- fidl::InterfaceRequest<cloud_provider::DeviceSet> device_set,
- GetDeviceSetCallback callback) {
- device_set_.AddBinding(std::move(device_set));
- callback(cloud_provider::Status::OK);
-}
-
-void FakeCloudProvider::GetPageCloud(
- std::vector<uint8_t> app_id, std::vector<uint8_t> page_id,
- fidl::InterfaceRequest<cloud_provider::PageCloud> page_cloud,
- GetPageCloudCallback callback) {
- const std::string key =
- convert::ToString(app_id) + "_" + convert::ToString(page_id);
- auto it = page_clouds_.find(key);
- if (it != page_clouds_.end()) {
- it->second.Bind(std::move(page_cloud));
- callback(cloud_provider::Status::OK);
- return;
- }
-
- auto ret =
- page_clouds_.emplace(std::piecewise_construct, std::forward_as_tuple(key),
- std::forward_as_tuple(inject_network_error_));
- ret.first->second.Bind(std::move(page_cloud));
- callback(cloud_provider::Status::OK);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/cloud_provider/fake_cloud_provider.h b/bin/ledger/testing/cloud_provider/fake_cloud_provider.h
deleted file mode 100644
index f9e0dee..0000000
--- a/bin/ledger/testing/cloud_provider/fake_cloud_provider.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_CLOUD_PROVIDER_H_
-#define PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_CLOUD_PROVIDER_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl_helpers/bound_interface_set.h"
-#include "peridot/bin/ledger/testing/cloud_provider/fake_device_set.h"
-#include "peridot/bin/ledger/testing/cloud_provider/fake_page_cloud.h"
-#include "peridot/bin/ledger/testing/cloud_provider/types.h"
-
-namespace ledger {
-
-class FakeCloudProvider : public cloud_provider::CloudProvider {
- public:
- class Builder {
- public:
- Builder();
- ~Builder();
-
- Builder& SetInjectNetworkError(InjectNetworkError inject_network_error);
- Builder& SetCloudEraseOnCheck(CloudEraseOnCheck cloud_erase_on_check);
- Builder& SetCloudEraseFromWatcher(
- CloudEraseFromWatcher cloud_erase_from_watcher);
-
- std::unique_ptr<FakeCloudProvider> Build();
-
- private:
- friend FakeCloudProvider;
-
- InjectNetworkError inject_network_error_ = InjectNetworkError::NO;
- CloudEraseOnCheck cloud_erase_on_check_ = CloudEraseOnCheck::NO;
- CloudEraseFromWatcher cloud_erase_from_watcher_ = CloudEraseFromWatcher::NO;
- };
-
- FakeCloudProvider();
- explicit FakeCloudProvider(const Builder& builder);
- ~FakeCloudProvider() override;
-
- private:
- void GetDeviceSet(
- fidl::InterfaceRequest<cloud_provider::DeviceSet> device_set,
- GetDeviceSetCallback callback) override;
-
- void GetPageCloud(
- std::vector<uint8_t> app_id, std::vector<uint8_t> page_id,
- fidl::InterfaceRequest<cloud_provider::PageCloud> page_cloud,
- GetPageCloudCallback callback) override;
-
- fidl_helpers::BoundInterfaceSet<cloud_provider::DeviceSet, FakeDeviceSet>
- device_set_;
-
- callback::AutoCleanableMap<std::string, FakePageCloud> page_clouds_;
-
- InjectNetworkError inject_network_error_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeCloudProvider);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_CLOUD_PROVIDER_H_
diff --git a/bin/ledger/testing/cloud_provider/fake_device_set.cc b/bin/ledger/testing/cloud_provider/fake_device_set.cc
deleted file mode 100644
index dfd9d55..0000000
--- a/bin/ledger/testing/cloud_provider/fake_device_set.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/cloud_provider/fake_device_set.h"
-
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-FakeDeviceSet::FakeDeviceSet(CloudEraseOnCheck cloud_erase_on_check,
- CloudEraseFromWatcher cloud_erase_from_watcher)
- : cloud_erase_on_check_(cloud_erase_on_check),
- cloud_erase_from_watcher_(cloud_erase_from_watcher) {}
-
-FakeDeviceSet::~FakeDeviceSet() {}
-
-void FakeDeviceSet::CheckFingerprint(std::vector<uint8_t> fingerprint,
- CheckFingerprintCallback callback) {
- if (cloud_erase_on_check_ == CloudEraseOnCheck::YES ||
- !fingerprints_.count(convert::ToString(fingerprint))) {
- callback(cloud_provider::Status::NOT_FOUND);
- return;
- }
-
- callback(cloud_provider::Status::OK);
-}
-
-void FakeDeviceSet::SetFingerprint(std::vector<uint8_t> fingerprint,
- SetFingerprintCallback callback) {
- fingerprints_.insert(convert::ToString(fingerprint));
- callback(cloud_provider::Status::OK);
-}
-
-void FakeDeviceSet::SetWatcher(
- std::vector<uint8_t> /*fingerprint*/,
- fidl::InterfaceHandle<cloud_provider::DeviceSetWatcher> watcher,
- SetWatcherCallback callback) {
- watcher_ = watcher.Bind();
- callback(cloud_provider::Status::OK);
-
- if (cloud_erase_from_watcher_ == CloudEraseFromWatcher::YES) {
- watcher_->OnCloudErased();
- }
-}
-
-void FakeDeviceSet::Erase(EraseCallback callback) {
- fingerprints_.clear();
- if (watcher_.is_bound()) {
- watcher_->OnCloudErased();
- }
- callback(cloud_provider::Status::OK);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/cloud_provider/fake_device_set.h b/bin/ledger/testing/cloud_provider/fake_device_set.h
deleted file mode 100644
index 90a3787..0000000
--- a/bin/ledger/testing/cloud_provider/fake_device_set.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_DEVICE_SET_H_
-#define PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_DEVICE_SET_H_
-
-#include <set>
-#include <string>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/cloud_provider/types.h"
-
-namespace ledger {
-
-class FakeDeviceSet : public cloud_provider::DeviceSet {
- public:
- FakeDeviceSet(CloudEraseOnCheck cloud_erase_on_check,
- CloudEraseFromWatcher cloud_erase_from_watcher);
- ~FakeDeviceSet() override;
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
-
- private:
- void CheckFingerprint(std::vector<uint8_t> fingerprint,
- CheckFingerprintCallback callback) override;
-
- void SetFingerprint(std::vector<uint8_t> fingerprint,
- SetFingerprintCallback callback) override;
-
- void SetWatcher(
- std::vector<uint8_t> fingerprint,
- fidl::InterfaceHandle<cloud_provider::DeviceSetWatcher> watcher,
- SetWatcherCallback callback) override;
-
- void Erase(EraseCallback callback) override;
-
- const CloudEraseOnCheck cloud_erase_on_check_ = CloudEraseOnCheck::NO;
-
- const CloudEraseFromWatcher cloud_erase_from_watcher_ =
- CloudEraseFromWatcher::NO;
-
- fit::closure on_empty_;
-
- std::set<std::string> fingerprints_;
-
- // Watcher set by the client.
- cloud_provider::DeviceSetWatcherPtr watcher_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeDeviceSet);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_DEVICE_SET_H_
diff --git a/bin/ledger/testing/cloud_provider/fake_page_cloud.cc b/bin/ledger/testing/cloud_provider/fake_page_cloud.cc
deleted file mode 100644
index 589a9f2..0000000
--- a/bin/ledger/testing/cloud_provider/fake_page_cloud.cc
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/cloud_provider/fake_page_cloud.h"
-
-#include <functional>
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/lib/convert/convert.h"
-#include "third_party/murmurhash/murmurhash.h"
-
-namespace ledger {
-
-namespace {
-
-// Number of errors to inject before allowing a request to succeed when
-// configured to inject network errors.
-constexpr size_t kInitialRemainingErrorsToInject = 2;
-
-// Seed for the murmur hash algorithm to ensure different request signatures.
-constexpr uint32_t kAddCommitsSeed = 1u;
-constexpr uint32_t kGetCommitsSeed = 2u;
-constexpr uint32_t kAddObjectSeed = 3u;
-constexpr uint32_t kGetObjectSeed = 4u;
-
-cloud_provider::Token PositionToToken(size_t position) {
- std::string bytes(
- std::string(reinterpret_cast<char*>(&position), sizeof(position)));
- cloud_provider::Token result;
- result.opaque_id = convert::ToArray(bytes);
- return result;
-}
-
-bool TokenToPosition(const std::unique_ptr<cloud_provider::Token>& token,
- size_t* result) {
- if (!token) {
- *result = 0u;
- return true;
- }
-
- if (token->opaque_id.size() != sizeof(*result)) {
- return false;
- }
-
- memcpy(result, token->opaque_id.data(), sizeof(*result));
- return true;
-}
-
-uint64_t GetVectorSignature(const std::vector<uint8_t>& vector,
- uint32_t seed) {
- return murmurhash(reinterpret_cast<const char*>(vector.data()),
- vector.size(), seed);
-}
-
-uint64_t GetCommitsSignature(
- const std::vector<cloud_provider::CommitPackEntry>& commits) {
- uint64_t result = 0;
- for (const auto& commit : commits) {
- result = result ^
- GetVectorSignature(convert::ToArray(commit.id), kAddCommitsSeed);
- }
- return result;
-}
-
-} // namespace
-
-class FakePageCloud::WatcherContainer {
- public:
- WatcherContainer(cloud_provider::PageCloudWatcherPtr watcher,
- size_t next_commit_index);
-
- void SendCommits(std::vector<cloud_provider::CommitPackEntry> commits,
- size_t next_commit_index, fit::closure on_ack);
-
- size_t NextCommitIndex() { return next_commit_index_; }
-
- bool WaitingForWatcherAck() { return waiting_for_watcher_ack_; }
-
- void set_on_empty(fit::closure on_empty) {
- watcher_.set_error_handler(
- [on_empty = std::move(on_empty)](zx_status_t status) { on_empty(); });
- }
-
- private:
- cloud_provider::PageCloudWatcherPtr watcher_;
- // Whether we're still waiting for the watcher to ack the previous commit
- // notification.
- bool waiting_for_watcher_ack_ = false;
-
- // Index of the first commit to be sent to the watcher.
- size_t next_commit_index_ = 0;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(WatcherContainer);
-};
-
-FakePageCloud::WatcherContainer::WatcherContainer(
- cloud_provider::PageCloudWatcherPtr watcher, size_t next_commit_index)
- : watcher_(std::move(watcher)), next_commit_index_(next_commit_index) {}
-
-void FakePageCloud::WatcherContainer::SendCommits(
- std::vector<cloud_provider::CommitPackEntry> commits,
- size_t next_commit_index, fit::closure on_ack) {
- FXL_DCHECK(watcher_.is_bound());
- FXL_DCHECK(!waiting_for_watcher_ack_);
- FXL_DCHECK(!commits.empty());
-
- waiting_for_watcher_ack_ = true;
- next_commit_index_ = next_commit_index;
- cloud_provider::CommitPack commit_pack;
- if (!cloud_provider::EncodeCommitPack(commits, &commit_pack)) {
- watcher_->OnError(cloud_provider::Status::INTERNAL_ERROR);
- return;
- }
- watcher_->OnNewCommits(std::move(commit_pack),
- PositionToToken(next_commit_index),
- [this, on_ack = std::move(on_ack)] {
- waiting_for_watcher_ack_ = false;
- on_ack();
- });
-}
-
-FakePageCloud::FakePageCloud(InjectNetworkError inject_network_error)
- : inject_network_error_(inject_network_error) {
- bindings_.set_empty_set_handler([this] {
- if (on_empty_) {
- on_empty_();
- }
- });
-}
-
-FakePageCloud::~FakePageCloud() {}
-
-void FakePageCloud::Bind(
- fidl::InterfaceRequest<cloud_provider::PageCloud> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void FakePageCloud::SendPendingCommits() {
- for (auto& container : containers_) {
- if (container.WaitingForWatcherAck() ||
- container.NextCommitIndex() >= commits_.size()) {
- continue;
- }
-
- std::vector<cloud_provider::CommitPackEntry> commits;
- for (size_t i = container.NextCommitIndex(); i < commits_.size(); i++) {
- commits.push_back(commits_[i]);
- }
-
- container.SendCommits(std::move(commits), commits_.size(),
- [this] { SendPendingCommits(); });
- }
-}
-
-bool FakePageCloud::MustReturnError(uint64_t request_signature) {
- switch (inject_network_error_) {
- case InjectNetworkError::NO:
- return false;
- case InjectNetworkError::YES:
- auto it = remaining_errors_to_inject_.find(request_signature);
- if (it == remaining_errors_to_inject_.end()) {
- remaining_errors_to_inject_[request_signature] =
- kInitialRemainingErrorsToInject;
- it = remaining_errors_to_inject_.find(request_signature);
- }
- if (it->second) {
- it->second--;
- return true;
- }
- remaining_errors_to_inject_.erase(it);
- return false;
- }
-}
-
-void FakePageCloud::AddCommits(cloud_provider::CommitPack commits,
- AddCommitsCallback callback) {
- std::vector<cloud_provider::CommitPackEntry> commit_entries;
- if (!cloud_provider::DecodeCommitPack(commits, &commit_entries)) {
- callback(cloud_provider::Status::INTERNAL_ERROR);
- return;
- }
-
- if (MustReturnError(GetCommitsSignature(commit_entries))) {
- callback(cloud_provider::Status::NETWORK_ERROR);
- return;
- }
- std::move(commit_entries.begin(), commit_entries.end(),
- std::back_inserter(commits_));
- SendPendingCommits();
- callback(cloud_provider::Status::OK);
-}
-
-void FakePageCloud::GetCommits(
- std::unique_ptr<cloud_provider::Token> min_position_token,
- GetCommitsCallback callback) {
- if (MustReturnError(GetVectorSignature(
- min_position_token ? min_position_token->opaque_id : std::vector<uint8_t>(),
- kGetCommitsSeed))) {
- callback(cloud_provider::Status::NETWORK_ERROR, nullptr, nullptr);
- return;
- }
- std::vector<cloud_provider::CommitPackEntry> result;
- size_t start = 0u;
- if (!TokenToPosition(min_position_token, &start)) {
- callback(cloud_provider::Status::ARGUMENT_ERROR, nullptr, nullptr);
- return;
- }
-
- for (size_t i = start; i < commits_.size(); i++) {
- result.push_back(commits_[i]);
- }
- std::unique_ptr<cloud_provider::Token> token;
- if (!result.empty()) {
- // This will cause the last commit to be delivered again when the token is
- // used for the next GetCommits() call. This is allowed by the FIDL contract
- // and should be handled correctly by the client.
- token = fidl::MakeOptional(PositionToToken(commits_.size() - 1));
- }
- cloud_provider::CommitPack commit_pack;
- if (!cloud_provider::EncodeCommitPack(result, &commit_pack)) {
- callback(cloud_provider::Status::INTERNAL_ERROR, nullptr, nullptr);
- return;
- }
- callback(cloud_provider::Status::OK,
- fidl::MakeOptional(std::move(commit_pack)), std::move(token));
-}
-
-void FakePageCloud::AddObject(std::vector<uint8_t> id,
- fuchsia::mem::Buffer data,
- AddObjectCallback callback) {
- if (MustReturnError(GetVectorSignature(id, kAddObjectSeed))) {
- callback(cloud_provider::Status::NETWORK_ERROR);
- return;
- }
- std::string bytes;
- if (!fsl::StringFromVmo(data, &bytes)) {
- callback(cloud_provider::Status::INTERNAL_ERROR);
- return;
- }
-
- objects_[convert::ToString(id)] = bytes;
- callback(cloud_provider::Status::OK);
-}
-
-void FakePageCloud::GetObject(std::vector<uint8_t> id,
- GetObjectCallback callback) {
- if (MustReturnError(GetVectorSignature(id, kGetObjectSeed))) {
- callback(cloud_provider::Status::NETWORK_ERROR, nullptr);
- return;
- }
- std::string id_str = convert::ToString(id);
- if (!objects_.count(id_str)) {
- callback(cloud_provider::Status::NOT_FOUND, nullptr);
- return;
- }
- ::fuchsia::mem::Buffer buffer;
- if (!fsl::VmoFromString(objects_[id_str], &buffer)) {
- callback(cloud_provider::Status::INTERNAL_ERROR, nullptr);
- return;
- }
- callback(cloud_provider::Status::OK, fidl::MakeOptional(std::move(buffer)));
-}
-
-void FakePageCloud::SetWatcher(
- std::unique_ptr<cloud_provider::Token> min_position_token,
- fidl::InterfaceHandle<cloud_provider::PageCloudWatcher> watcher,
- SetWatcherCallback callback) {
- // TODO(qsr): Inject errors here when LE-438 is fixed.
- auto watcher_ptr = watcher.Bind();
-
- size_t first_pending_commit_index;
- if (!TokenToPosition(min_position_token, &first_pending_commit_index)) {
- callback(cloud_provider::Status::ARGUMENT_ERROR);
- return;
- }
- containers_.emplace(std::move(watcher_ptr), first_pending_commit_index);
- SendPendingCommits();
- callback(cloud_provider::Status::OK);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/cloud_provider/fake_page_cloud.h b/bin/ledger/testing/cloud_provider/fake_page_cloud.h
deleted file mode 100644
index 6a54106..0000000
--- a/bin/ledger/testing/cloud_provider/fake_page_cloud.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_PAGE_CLOUD_H_
-#define PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_PAGE_CLOUD_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/cloud_provider/types.h"
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-namespace ledger {
-
-class FakePageCloud : public cloud_provider::PageCloud {
- public:
- explicit FakePageCloud(InjectNetworkError inject_network_error);
- ~FakePageCloud() override;
-
- void set_on_empty(fit::closure on_empty) { on_empty_ = std::move(on_empty); }
-
- void Bind(fidl::InterfaceRequest<cloud_provider::PageCloud> request);
-
- private:
- void SendPendingCommits();
- bool MustReturnError(uint64_t request_signature);
-
- // cloud_provider::PageCloud:
- void AddCommits(cloud_provider::CommitPack commits,
- AddCommitsCallback callback) override;
- void GetCommits(std::unique_ptr<cloud_provider::Token> min_position_token,
- GetCommitsCallback callback) override;
- void AddObject(std::vector<uint8_t> id, fuchsia::mem::Buffer data,
- AddObjectCallback callback) override;
- void GetObject(std::vector<uint8_t> id,
- GetObjectCallback callback) override;
- void SetWatcher(
- std::unique_ptr<cloud_provider::Token> min_position_token,
- fidl::InterfaceHandle<cloud_provider::PageCloudWatcher> watcher,
- SetWatcherCallback callback) override;
-
- InjectNetworkError inject_network_error_;
- std::map<uint64_t, size_t> remaining_errors_to_inject_;
-
- fidl::BindingSet<cloud_provider::PageCloud> bindings_;
- fit::closure on_empty_;
-
- std::vector<cloud_provider::CommitPackEntry> commits_;
- std::map<std::string, std::string> objects_;
-
- // Watchers set by the client.
- class WatcherContainer;
- callback::AutoCleanableSet<WatcherContainer> containers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakePageCloud);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_FAKE_PAGE_CLOUD_H_
diff --git a/bin/ledger/testing/cloud_provider/types.h b/bin/ledger/testing/cloud_provider/types.h
deleted file mode 100644
index 30c8061..0000000
--- a/bin/ledger/testing/cloud_provider/types.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_TYPES_H_
-#define PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_TYPES_H_
-
-namespace ledger {
-
-enum class CloudEraseOnCheck { YES, NO };
-enum class CloudEraseFromWatcher { YES, NO };
-enum class InjectNetworkError { YES, NO };
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_CLOUD_PROVIDER_TYPES_H_
diff --git a/bin/ledger/testing/data_generator.cc b/bin/ledger/testing/data_generator.cc
deleted file mode 100644
index 82d1b98..0000000
--- a/bin/ledger/testing/data_generator.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/data_generator.h"
-
-#include <algorithm>
-#include <functional>
-#include <string>
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/concatenate.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kKeyIdSeparator = "-";
-
-} // namespace
-
-DataGenerator::DataGenerator(rng::Random* random)
- : generator_(random->NewBitGenerator<uint64_t>()) {}
-
-DataGenerator::~DataGenerator() {}
-
-std::vector<uint8_t> DataGenerator::MakeKey(int i, size_t size) {
- std::string i_str = std::to_string(i);
- FXL_DCHECK(i_str.size() + kKeyIdSeparator.size() <= size);
- auto rand_bytes = MakeValue(size - i_str.size() - kKeyIdSeparator.size());
-
- return convert::ToArray(fxl::Concatenate(
- {convert::ExtendedStringView(rand_bytes), kKeyIdSeparator, i_str}));
-}
-
-PageId DataGenerator::MakePageId() {
- PageId value;
- std::generate(value.id.begin(), value.id.end(), std::ref(generator_));
- return value;
-}
-
-fidl::VectorPtr<uint8_t> DataGenerator::MakeValue(size_t size) {
- auto data = fidl::VectorPtr<uint8_t>::New(size);
- std::generate(data->begin(), data->end(), std::ref(generator_));
- return data;
-}
-
-std::vector<std::vector<uint8_t>> DataGenerator::MakeKeys(
- size_t key_count, size_t key_size, size_t unique_key_count) {
- FXL_DCHECK(unique_key_count <= key_count);
- std::vector<std::vector<uint8_t>> keys(key_count);
- for (size_t i = 0; i < unique_key_count; i++) {
- keys[i] = MakeKey(i, key_size);
- }
- for (size_t i = unique_key_count; i < key_count; i++) {
- keys[i] = keys[i - unique_key_count];
- }
- return keys;
-}
-
-size_t DataGenerator::GetKeyId(const std::vector<uint8_t>& key) {
- std::string key_str = convert::ToString(key);
- size_t split_index = key_str.find_last_of(kKeyIdSeparator.ToString());
- FXL_CHECK(split_index != std::string::npos &&
- split_index + kKeyIdSeparator.size() < key_str.size());
- return std::stoul(key_str.substr(split_index + kKeyIdSeparator.size()));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/data_generator.h b/bin/ledger/testing/data_generator.h
deleted file mode 100644
index 8dbf326..0000000
--- a/bin/ledger/testing/data_generator.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_DATA_GENERATOR_H_
-#define PERIDOT_BIN_LEDGER_TESTING_DATA_GENERATOR_H_
-
-#include <climits>
-#include <random>
-#include <vector>
-
-#include <lib/fidl/cpp/vector.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/lib/rng/random.h"
-
-namespace ledger {
-
-class DataGenerator {
- public:
- explicit DataGenerator(rng::Random* random);
-
- ~DataGenerator();
-
- // Builds a key of the given |size| as "<random data>-<i>". The id (|i|) of
- // the result can be retrieved by calling |GetKeyId|.
- std::vector<uint8_t> MakeKey(int i, size_t size);
-
- // Builds a random value that can be used as a page id.
- PageId MakePageId();
-
- // Builds a random value of the given length.
- fidl::VectorPtr<uint8_t> MakeValue(size_t size);
-
- // Builds a vector of length |key_count| containing keys of size |key_size|,
- // |unique_key_count| of which are unique.
- std::vector<std::vector<uint8_t>> MakeKeys(size_t key_count, size_t key_size,
- size_t unique_key_count);
-
- // Returns the id of |key|. |key| is assumed to have been created by this
- // DataGenerator, using either |MakeKey| or |MakeKeys|.
- size_t GetKeyId(const std::vector<uint8_t>& key);
-
- private:
- std::independent_bits_engine<rng::Random::BitGenerator<uint64_t>, CHAR_BIT,
- uint8_t>
- generator_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_DATA_GENERATOR_H_
diff --git a/bin/ledger/testing/fake_disk_cleanup_manager.h b/bin/ledger/testing/fake_disk_cleanup_manager.h
deleted file mode 100644
index 731b1b6..0000000
--- a/bin/ledger/testing/fake_disk_cleanup_manager.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_FAKE_DISK_CLEANUP_MANAGER_H_
-#define PERIDOT_BIN_LEDGER_TESTING_FAKE_DISK_CLEANUP_MANAGER_H_
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/app/disk_cleanup_manager.h"
-#include "peridot/bin/ledger/app/page_usage_listener.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-
-namespace ledger {
-
-class FakeDiskCleanupManager : public DiskCleanupManager,
- public PageUsageListener {
- public:
- FakeDiskCleanupManager() {}
- ~FakeDiskCleanupManager() override {}
-
- void set_on_empty(fit::closure on_empty_callback) override {}
-
- bool IsEmpty() override { return true; }
-
- void TryCleanUp(fit::function<void(Status)> callback) override {
- // Do not call the callback directly.
- cleanup_callback = std::move(callback);
- }
- void OnPageOpened(fxl::StringView /*ledger_name*/,
- storage::PageIdView /*page_id*/) override {
- ++page_opened_count;
- }
-
- void OnPageClosed(fxl::StringView /*ledger_name*/,
- storage::PageIdView /*page_id*/) override {
- ++page_closed_count;
- }
-
- void OnPageUnused(fxl::StringView /*ledger_name*/,
- storage::PageIdView /*page_id*/) override {
- ++page_unused_count;
- }
-
- int page_opened_count = 0;
- int page_closed_count = 0;
- int page_unused_count = 0;
- fit::function<void(Status)> cleanup_callback;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeDiskCleanupManager);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_FAKE_DISK_CLEANUP_MANAGER_H_
diff --git a/bin/ledger/testing/get_ledger.cc b/bin/ledger/testing/get_ledger.cc
deleted file mode 100644
index 5115a76..0000000
--- a/bin/ledger/testing/get_ledger.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/get_ledger.h"
-
-#include <fcntl.h>
-#include <utility>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/callback/capture.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/io/fd.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/logging.h>
-#include <lib/svc/cpp/services.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-// Converts a status returned by Ledger via FIDL to a ledger::Status.
-// The convention is that kernel errors (zx_status_t) are negative, while
-// positive values are reserved for user-space.
-Status ToLedgerStatus(zx_status_t status) {
- if (status == ZX_OK) {
- return Status::OK;
- }
- if (status > 0) {
- return static_cast<Status>(status);
- }
- return Status::INTERNAL_ERROR;
-}
-} // namespace
-
-Status GetLedger(component::StartupContext* context,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController>
- controller_request,
- cloud_provider::CloudProviderPtr cloud_provider,
- std::string user_id, std::string ledger_name,
- const DetachedPath& ledger_repository_path,
- fit::function<void()> error_handler, LedgerPtr* ledger) {
- fxl::UniqueFD dir(openat(ledger_repository_path.root_fd(),
- ledger_repository_path.path().c_str(), O_PATH));
- if (!dir.is_valid()) {
- FXL_LOG(ERROR) << "Unable to open directory at "
- << ledger_repository_path.path() << ". errno: " << errno;
- return Status::IO_ERROR;
- }
-
- ledger_internal::LedgerRepositoryFactoryPtr repository_factory;
-
- component::Services child_services;
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = "fuchsia-pkg://fuchsia.com/ledger#meta/ledger.cmx";
- launch_info.directory_request = child_services.NewRequest();
- launch_info.arguments.push_back("--disable_reporting");
- context->launcher()->CreateComponent(std::move(launch_info),
- std::move(controller_request));
- child_services.ConnectToService(repository_factory.NewRequest());
-
- fuchsia::ledger::internal::LedgerRepositorySyncPtr repository;
-
- repository_factory->GetRepository(
- fsl::CloneChannelFromFileDescriptor(dir.get()), std::move(cloud_provider),
- std::move(user_id), repository.NewRequest());
-
- (*ledger).set_error_handler(
- [error_handler = std::move(error_handler)](zx_status_t status) {
- FXL_LOG(ERROR) << "The ledger connection was closed, quitting.";
- error_handler();
- });
- repository->GetLedger(convert::ToArray(ledger_name), ledger->NewRequest());
- return ToLedgerStatus(repository->Sync());
-}
-
-void KillLedgerProcess(fuchsia::sys::ComponentControllerPtr* controller) {
- (*controller)->Kill();
- auto channel = controller->Unbind().TakeChannel();
- zx_signals_t observed;
- channel.wait_one(ZX_CHANNEL_PEER_CLOSED, zx::deadline_after(zx::sec(5)),
- &observed);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/get_ledger.h b/bin/ledger/testing/get_ledger.h
deleted file mode 100644
index 3ae1324..0000000
--- a/bin/ledger/testing/get_ledger.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_GET_LEDGER_H_
-#define PERIDOT_BIN_LEDGER_TESTING_GET_LEDGER_H_
-
-#include <functional>
-#include <string>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-
-namespace ledger {
-
-// Creates a new Ledger application instance and returns a LedgerPtr connection
-// to it. This method will call |Sync| on the Repository to ensure that the
-// Ledger is ready to be used for performance benchmark.
-Status GetLedger(component::StartupContext* context,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController>
- controller_request,
- cloud_provider::CloudProviderPtr cloud_provider,
- std::string user_id, std::string ledger_name,
- const DetachedPath& ledger_repository_path,
- fit::function<void()> error_handler, LedgerPtr* ledger);
-
-// Kills the remote ledger process controlled by |controller|.
-void KillLedgerProcess(fuchsia::sys::ComponentControllerPtr* controller);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_GET_LEDGER_H_
diff --git a/bin/ledger/testing/get_page_ensure_initialized.cc b/bin/ledger/testing/get_page_ensure_initialized.cc
deleted file mode 100644
index b31710c..0000000
--- a/bin/ledger/testing/get_page_ensure_initialized.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace ledger {
-namespace {
-// The delay before returning the page, after a successful initialization.
-constexpr zx::duration kDelay = zx::msec(500);
-} // namespace
-
-void GetPageEnsureInitialized(
- LedgerPtr* ledger, PageIdPtr requested_id, DelayCallback delay_callback,
- fit::function<void()> error_handler,
- fit::function<void(Status, PagePtr, PageId)> callback) {
- auto page = std::make_unique<PagePtr>();
- auto request = page->NewRequest();
- (*ledger)->GetPage(
- std::move(requested_id), std::move(request),
- [delay_callback, page = std::move(page),
- error_handler = std::move(error_handler),
- callback = std::move(callback)](Status status) mutable {
- if (status != Status::OK) {
- FXL_LOG(ERROR) << "Failure while getting a page.";
- callback(status, nullptr, {});
- return;
- }
-
- page->set_error_handler(
- [error_handler = std::move(error_handler)](zx_status_t status) {
- FXL_LOG(ERROR) << "The page connection was closed, quitting.";
- error_handler();
- });
-
- auto page_ptr = (*page).get();
- page_ptr->GetId([delay_callback, page = std::move(page),
- callback = std::move(callback)](PageId page_id) {
- if (delay_callback == DelayCallback::YES) {
- zx_nanosleep(zx_deadline_after(kDelay.get()));
- }
- callback(Status::OK, std::move(*page), page_id);
- });
- });
-}
-} // namespace ledger
diff --git a/bin/ledger/testing/get_page_ensure_initialized.h b/bin/ledger/testing/get_page_ensure_initialized.h
deleted file mode 100644
index f2e861d..0000000
--- a/bin/ledger/testing/get_page_ensure_initialized.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_GET_PAGE_ENSURE_INITIALIZED_H_
-#define PERIDOT_BIN_LEDGER_TESTING_GET_PAGE_ENSURE_INITIALIZED_H_
-
-#include <lib/fit/function.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace ledger {
-// Determines whether calling the |GetPageEnsureInitialized| callback should be
-// done after some delay. This can be used in benchmarks, to make sure that all
-// backround I/O operations have finished before measurements start.
-enum DelayCallback : bool { NO, YES };
-
-// Retrieves the requested page of the given Ledger instance amd returns after
-// ensuring that it is initialized. If |id| is nullptr, a new page with a unique
-// id is created.
-void GetPageEnsureInitialized(
- LedgerPtr* ledger, PageIdPtr requested_id, DelayCallback delay_callback,
- fit::function<void()> error_handler,
- fit::function<void(Status, PagePtr, PageId)> callback);
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_GET_PAGE_ENSURE_INITIALIZED_H_
diff --git a/bin/ledger/testing/inspect.cc b/bin/ledger/testing/inspect.cc
deleted file mode 100644
index c85c22a..0000000
--- a/bin/ledger/testing/inspect.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/inspect.h"
-
-#include <fuchsia/inspect/cpp/fidl.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-
-namespace ledger {
-
-// TODO(crjohns, nathaniel): Migrate this to a testing::Matcher.
-void ExpectRequestsMetric(fuchsia::inspect::Object* object,
- unsigned long expected_value) {
- bool requests_found = false;
- unsigned long extra_requests_found = 0UL;
- unsigned long requests = 0UL;
- for (auto& index : *object->metrics) {
- if (index.key == kRequestsInspectPathComponent) {
- if (!requests_found) {
- requests_found = true;
- requests = index.value.uint_value();
- } else {
- extra_requests_found++;
- }
- }
- }
- EXPECT_TRUE(requests_found);
- EXPECT_EQ(expected_value, requests);
- EXPECT_EQ(0UL, extra_requests_found);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/inspect.h b/bin/ledger/testing/inspect.h
deleted file mode 100644
index 7df672c..0000000
--- a/bin/ledger/testing/inspect.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_INSPECT_H_
-#define PERIDOT_BIN_LEDGER_TESTING_INSPECT_H_
-
-#include <fuchsia/inspect/cpp/fidl.h>
-
-namespace ledger {
-
-// TODO(crjohns, nathaniel): Move to an "Inspect API testing helpers" library,
-// parameterizing by the metric name rather than having "requests" hard-coded.
-// EXPECTs that |object| has a metric named "requests" and that the value of
-// the "requests" metric is |expected_value|.
-void ExpectRequestsMetric(fuchsia::inspect::Object* object,
- unsigned long expected_value);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_INSPECT_H_
diff --git a/bin/ledger/testing/ledger_app_instance_factory.cc b/bin/ledger/testing/ledger_app_instance_factory.cc
deleted file mode 100644
index 8cf1b1b..0000000
--- a/bin/ledger/testing/ledger_app_instance_factory.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/ledger_app_instance_factory.h"
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fsl/io/fd.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "garnet/public/lib/callback/capture.h"
-#include "gtest/gtest.h"
-
-namespace ledger {
-
-LedgerAppInstanceFactory::LedgerAppInstance::LedgerAppInstance(
- LoopController* loop_controller, std::vector<uint8_t> test_ledger_name,
- ledger_internal::LedgerRepositoryFactoryPtr ledger_repository_factory)
- : loop_controller_(loop_controller),
- test_ledger_name_(std::move(test_ledger_name)),
- ledger_repository_factory_(std::move(ledger_repository_factory)) {
- ledger_repository_factory_.set_error_handler([](zx_status_t status) {
- if (status != ZX_ERR_PEER_CLOSED) {
- ADD_FAILURE() << "|LedgerRepositoryFactory| failed with an error: "
- << status;
- }
- });
-}
-
-LedgerAppInstanceFactory::LedgerAppInstance::~LedgerAppInstance() {}
-
-ledger_internal::LedgerRepositoryFactory*
-LedgerAppInstanceFactory::LedgerAppInstance::ledger_repository_factory() {
- return ledger_repository_factory_.get();
-}
-
-ledger_internal::LedgerRepositoryPtr
-LedgerAppInstanceFactory::LedgerAppInstance::GetTestLedgerRepository() {
- ledger_internal::LedgerRepositoryPtr repository;
- repository.set_error_handler([](zx_status_t status) {
- if (status != ZX_ERR_PEER_CLOSED) {
- ADD_FAILURE() << "|LedgerRepository| failed with an error: " << status;
- }
- });
- ledger_repository_factory_->GetRepository(
- fsl::CloneChannelFromFileDescriptor(tmpfs_.root_fd()),
- MakeCloudProvider(), GetUserId(), repository.NewRequest());
- return repository;
-}
-
-LedgerPtr LedgerAppInstanceFactory::LedgerAppInstance::GetTestLedger() {
- LedgerPtr ledger;
- ledger.set_error_handler([](zx_status_t status) {
- if (status != ZX_ERR_PEER_CLOSED) {
- ADD_FAILURE() << "|Ledger| failed with an error: " << status;
- }
- });
-
- auto repository = GetTestLedgerRepository();
- repository->GetLedger(fidl::Clone(test_ledger_name_), ledger.NewRequest());
- auto waiter = loop_controller_->NewWaiter();
- repository->Sync(waiter->GetCallback());
- if (!waiter->RunUntilCalled()) {
- ADD_FAILURE() << "|GetLedger| failed to call back.";
- return nullptr;
- }
- return ledger;
-}
-
-PagePtr LedgerAppInstanceFactory::LedgerAppInstance::GetTestPage() {
- fidl::InterfaceHandle<Page> page;
- Status status;
- LedgerPtr ledger = GetTestLedger();
- auto waiter = loop_controller_->NewWaiter();
- ledger->GetPage(nullptr, page.NewRequest(),
- callback::Capture(waiter->GetCallback(), &status));
- if (!waiter->RunUntilCalled()) {
- ADD_FAILURE() << "|GetPage| failed to call back.";
- return nullptr;
- }
- EXPECT_EQ(Status::OK, status);
-
- return page.Bind();
-}
-
-PagePtr LedgerAppInstanceFactory::LedgerAppInstance::GetPage(
- const PageIdPtr& page_id, Status expected_status) {
- PagePtr page_ptr;
- Status status;
- LedgerPtr ledger = GetTestLedger();
- auto waiter = loop_controller_->NewWaiter();
- ledger->GetPage(fidl::Clone(page_id), page_ptr.NewRequest(),
- callback::Capture(waiter->GetCallback(), &status));
- if (!waiter->RunUntilCalled()) {
- ADD_FAILURE() << "|GetPage| failed to call back.";
- return nullptr;
- }
- EXPECT_EQ(expected_status, status);
-
- return page_ptr;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/ledger_app_instance_factory.h b/bin/ledger/testing/ledger_app_instance_factory.h
deleted file mode 100644
index 68f4187..0000000
--- a/bin/ledger/testing/ledger_app_instance_factory.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_LEDGER_APP_INSTANCE_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_TESTING_LEDGER_APP_INSTANCE_FACTORY_H_
-
-#include <functional>
-#include <memory>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/testing/loop_controller.h"
-#include "peridot/lib/rng/random.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-
-class LedgerAppInstanceFactory;
-
-// Class that creates instances of |LedgerAppInstanceFactory|.
-class LedgerAppInstanceFactoryBuilder {
- public:
- virtual ~LedgerAppInstanceFactoryBuilder(){};
- // Returns a new LedgerAppInstanceFactory.
- virtual std::unique_ptr<LedgerAppInstanceFactory> NewFactory() const = 0;
-};
-
-// Base class for client tests.
-//
-// Client tests are tests that act as clients to the Ledger as a whole. These
-// are integration tests or end-to-end tests (apptests).
-class LedgerAppInstanceFactory {
- public:
- // A Ledger app instance
- class LedgerAppInstance {
- public:
- LedgerAppInstance(
- LoopController* loop_controller,
- std::vector<uint8_t> test_ledger_name,
- ledger_internal::LedgerRepositoryFactoryPtr ledger_repository_factory);
- virtual ~LedgerAppInstance();
-
- // Returns the LedgerRepositoryFactory associated with this application
- // instance.
- ledger_internal::LedgerRepositoryFactory* ledger_repository_factory();
- // Builds and returns a new connection to the default LedgerRepository
- // object.
- ledger_internal::LedgerRepositoryPtr GetTestLedgerRepository();
- // Builds and returns a new connection to the default Ledger object.
- LedgerPtr GetTestLedger();
- // Builds and returns a new connection to a new random page on the default
- // Ledger object.
- PagePtr GetTestPage();
- // Returns a connection to the given page on the default Ledger object.
- PagePtr GetPage(const PageIdPtr& page_id, Status expected_status);
-
- private:
- virtual cloud_provider::CloudProviderPtr MakeCloudProvider() = 0;
- virtual std::string GetUserId() = 0;
-
- LoopController* loop_controller_;
- std::vector<uint8_t> test_ledger_name_;
- ledger_internal::LedgerRepositoryFactoryPtr ledger_repository_factory_;
-
- scoped_tmpfs::ScopedTmpFS tmpfs_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerAppInstance);
- };
-
- virtual ~LedgerAppInstanceFactory() {}
-
- // Starts a new instance of the Ledger. The |loop_controller| must allow to
- // control the loop that is used to access the LedgerAppInstance.
- virtual std::unique_ptr<LedgerAppInstance> NewLedgerAppInstance() = 0;
-
- // Returns the Loop controller controlling the loops of the LedgerAppInstances
- // created by this.
- virtual LoopController* GetLoopController() = 0;
-
- // Returns a random instance to control the randomness of the test.
- virtual rng::Random* GetRandom() = 0;
-};
-
-// Returns the list of LedgerAppInstanceFactoryBuilder to be passed as
-// parameters to the tests. The implementation of this function changes
-// depending on whether the tests are ran as integration tests, or end to end
-// tests.
-std::vector<const LedgerAppInstanceFactoryBuilder*>
-GetLedgerAppInstanceFactoryBuilders();
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_LEDGER_APP_INSTANCE_FACTORY_H_
diff --git a/bin/ledger/testing/ledger_matcher.cc b/bin/ledger/testing/ledger_matcher.cc
deleted file mode 100644
index 8fd475b..0000000
--- a/bin/ledger/testing/ledger_matcher.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/ledger_matcher.h"
-
-#include <lib/fsl/vmo/strings.h>
-
-using testing::AllOf;
-using testing::Field;
-using testing::TypedEq;
-
-namespace ledger {
-
-namespace {
-MATCHER_P(InternalViewMatcher, sub_matcher, "") { // NOLINT
- return ExplainMatchResult(sub_matcher, arg.ToString(), result_listener);
-}
-
-MATCHER_P(InternalBufferMatcher, sub_matcher, "") { // NOLINT
- std::string vmo_content;
- if (!TypedEq<bool>(true).MatchAndExplain(
- fsl::StringFromVmo(arg, &vmo_content), result_listener)) {
- return false;
- }
-
- return ExplainMatchResult(sub_matcher, vmo_content, result_listener);
-}
-
-MATCHER(PointWiseMatchesEntry, "") { // NOLINT
- auto& a = std::get<0>(arg);
- auto& b = std::get<1>(arg);
- return ExplainMatchResult(MatchesEntry(b), a, result_listener);
-}
-
-} // namespace
-
-testing::Matcher<convert::ExtendedStringView> MatchesView(
- testing::Matcher<std::string> matcher) {
- return InternalViewMatcher(std::move(matcher));
-}
-
-testing::Matcher<const fuchsia::mem::Buffer&> MatchesBuffer(
- testing::Matcher<std::string> matcher) {
- return InternalBufferMatcher(std::move(matcher));
-}
-
-testing::Matcher<const Entry&> MatchesEntry(
- std::pair<testing::Matcher<std::string>, testing::Matcher<std::string>>
- matcher) {
- return AllOf(Field(&Entry::key, MatchesView(matcher.first)),
- Field(&Entry::value, Pointee(MatchesBuffer(matcher.second))));
-}
-
-testing::Matcher<const std::vector<Entry>&> MatchEntries(
- std::map<std::string, testing::Matcher<std::string>> matchers) {
- return Pointwise(PointWiseMatchesEntry(), matchers);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/ledger_matcher.h b/bin/ledger/testing/ledger_matcher.h
deleted file mode 100644
index 06a2a09..0000000
--- a/bin/ledger/testing/ledger_matcher.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_LEDGER_MATCHER_H_
-#define PERIDOT_BIN_LEDGER_TESTING_LEDGER_MATCHER_H_
-
-#include <fuchsia/mem/cpp/fidl.h>
-#include <gmock/gmock.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-// Matcher that matches a convert::ExtendedStringView against a string-like.
-testing::Matcher<convert::ExtendedStringView> MatchesView(
- testing::Matcher<std::string> matcher);
-
-// Matcher that matches a mem::Buffer against a string.
-testing::Matcher<const fuchsia::mem::Buffer&> MatchesBuffer(
- testing::Matcher<std::string> matcher);
-
-// Matcher that matches a Ledger entry against a pair of matchers on the entry's
-// key and value. The entry's priority is not considered in this Matcher.
-testing::Matcher<const Entry&> MatchesEntry(
- std::pair<testing::Matcher<std::string>, testing::Matcher<std::string>>
- matcher);
-
-// Matcher that matches a list of ledger entries against a map from key to
-// matchers on the entries' values. The entries' priorities are not considered
-// in this Matcher.
-testing::Matcher<const std::vector<Entry>&> MatchEntries(
- std::map<std::string, testing::Matcher<std::string>> matchers);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_LEDGER_MATCHER_H_
diff --git a/bin/ledger/testing/ledger_matcher_unittest.cc b/bin/ledger/testing/ledger_matcher_unittest.cc
deleted file mode 100644
index cb13635..0000000
--- a/bin/ledger/testing/ledger_matcher_unittest.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/ledger_matcher.h"
-
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-
-using testing::HasSubstr;
-using testing::Not;
-
-namespace ledger {
-namespace {
-
-TEST(LedgerMatcher, ExtendedStringViewMatcher) {
- std::string foo = "hello";
- convert::ExtendedStringView view(foo);
-
- EXPECT_THAT(view, MatchesView("hello"));
- EXPECT_THAT(view, MatchesView(HasSubstr("ll")));
- EXPECT_THAT(view, Not(MatchesView("hello2")));
-}
-
-TEST(LedgerMatcher, BufferMatcher) {
- fsl::SizedVmo size_vmo;
- ASSERT_TRUE(fsl::VmoFromString("hello", &size_vmo));
- fuchsia::mem::Buffer buffer = std::move(size_vmo).ToTransport();
-
- EXPECT_THAT(buffer, MatchesBuffer("hello"));
- EXPECT_THAT(buffer, MatchesBuffer(HasSubstr("ll")));
- EXPECT_THAT(buffer, Not(MatchesBuffer("hello2")));
-}
-
-TEST(LedgerMatcher, EntryMatcher) {
- fsl::SizedVmo size_vmo;
- ASSERT_TRUE(fsl::VmoFromString("hello", &size_vmo));
- fuchsia::mem::Buffer buffer = std::move(size_vmo).ToTransport();
-
- Entry entry{convert::ToArray("key"), fidl::MakeOptional(std::move(buffer))};
-
- EXPECT_THAT(entry, MatchesEntry({"key", "hello"}));
- EXPECT_THAT(entry, MatchesEntry({Not("key2"), HasSubstr("ll")}));
-}
-
-TEST(LedgerMatcher, EntriesMatcher) {
- fsl::SizedVmo size_vmo;
- ASSERT_TRUE(fsl::VmoFromString("hello", &size_vmo));
- fuchsia::mem::Buffer buffer = std::move(size_vmo).ToTransport();
-
- Entry entry1{convert::ToArray("key1"), fidl::MakeOptional(std::move(buffer))};
-
- ASSERT_TRUE(fsl::VmoFromString("hello2", &size_vmo));
- buffer = std::move(size_vmo).ToTransport();
-
- Entry entry2{convert::ToArray("key2"), fidl::MakeOptional(std::move(buffer))};
-
- std::vector<Entry> entries;
- entries.push_back(std::move(entry1));
- entries.push_back(std::move(entry2));
-
- EXPECT_THAT(entries, MatchEntries({{"key1", "hello"}, {"key2", "hello2"}}));
- EXPECT_THAT(entries, MatchEntries({{"key1", HasSubstr("ll")},
- {"key2", HasSubstr("ll")}}));
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/testing/ledger_test_instance_provider/BUILD.gn b/bin/ledger/testing/ledger_test_instance_provider/BUILD.gn
deleted file mode 100644
index ab280b7..0000000
--- a/bin/ledger/testing/ledger_test_instance_provider/BUILD.gn
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-
-executable("ledger_test_instance_provider_bin") {
- testonly = true
-
- sources = [
- "ledger_test_instance_provider.cc",
- ]
-
- deps = [
- "//garnet/public/lib/component/cpp/testing",
- "//garnet/public/lib/svc/cpp",
- "//peridot/bin/ledger/fidl",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-
- public_deps = [
- "//peridot/lib/convert",
- "//peridot/lib/scoped_tmpfs",
- ]
-}
-
-package("ledger_test_instance_provider") {
- testonly = true
-
- meta = [
- {
- path = rebase_path("meta/ledger_test_instance_provider.cmx")
- dest = "ledger_test_instance_provider.cmx"
- },
- ]
-
- binary = "ledger_test_instance_provider_bin"
-
- deps = [
- ":ledger_test_instance_provider_bin",
- ]
-}
diff --git a/bin/ledger/testing/ledger_test_instance_provider/MAINTAINERS b/bin/ledger/testing/ledger_test_instance_provider/MAINTAINERS
deleted file mode 100644
index e4db192..0000000
--- a/bin/ledger/testing/ledger_test_instance_provider/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-etiennej@google.com
-jif@google.com
diff --git a/bin/ledger/testing/ledger_test_instance_provider/README.md b/bin/ledger/testing/ledger_test_instance_provider/README.md
deleted file mode 100644
index 3f28e73..0000000
--- a/bin/ledger/testing/ledger_test_instance_provider/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Ledger Test Instance Provider
-
-This is a package containing a `ledger_test_instance_provider_bin` binary whose
-purpose is to return Ledger instances backed by memfs.
-
-It exists to allow tests built outside of peridot to get access to a Ledger
-instance, a task otherwise impossible because the required API
-(LedgerRepository) is not available outside of peridot.
diff --git a/bin/ledger/testing/ledger_test_instance_provider/ledger_test_instance_provider.cc b/bin/ledger/testing/ledger_test_instance_provider/ledger_test_instance_provider.cc
deleted file mode 100644
index 7366005..0000000
--- a/bin/ledger/testing/ledger_test_instance_provider/ledger_test_instance_provider.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cstdlib>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-
-#include "lib/component/cpp/startup_context.h"
-#include "lib/fsl/io/fd.h"
-#include "lib/fxl/strings/string_view.h"
-#include "lib/svc/cpp/services.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace {
-
-constexpr char kLedgerBinaryPath[] =
- "fuchsia-pkg://fuchsia.com/ledger#meta/ledger.cmx";
-constexpr fxl::StringView kLedgerName = "test ledger instance";
-
-} // namespace
-
-// Exposes a public service that serves an in-memory Ledger.
-int main(int argc, char const *argv[]) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- std::unique_ptr<component::StartupContext> context(
- component::StartupContext::CreateFromStartupInfo());
-
- // Get a repository factory.
- component::Services services;
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = kLedgerBinaryPath;
- launch_info.directory_request = services.NewRequest();
- launch_info.arguments.push_back("--disable_reporting");
- fuchsia::sys::ComponentControllerPtr controller;
- context->launcher()->CreateComponent(std::move(launch_info),
- controller.NewRequest());
- fuchsia::ledger::internal::LedgerRepositoryFactoryPtr repository_factory;
- services.ConnectToService(repository_factory.NewRequest());
-
- // Create memfs.
- auto memfs = std::make_unique<scoped_tmpfs::ScopedTmpFS>();
- zx::channel memfs_channel =
- fsl::CloneChannelFromFileDescriptor(memfs->root_fd());
-
- // Get a repository.
- fuchsia::ledger::internal::LedgerRepositorySyncPtr repository;
- repository_factory->GetRepository(std::move(memfs_channel), nullptr, "",
- repository.NewRequest());
-
- // Serve the repository.
- context->outgoing().AddPublicService<fuchsia::ledger::Ledger>(
- [&repository](fidl::InterfaceRequest<fuchsia::ledger::Ledger> request) {
- repository->GetLedger(convert::ToArray(kLedgerName),
- std::move(request));
- });
- loop.Run();
- return EXIT_SUCCESS;
-}
\ No newline at end of file
diff --git a/bin/ledger/testing/ledger_test_instance_provider/meta/ledger_test_instance_provider.cmx b/bin/ledger/testing/ledger_test_instance_provider/meta/ledger_test_instance_provider.cmx
deleted file mode 100644
index 58bb40c..0000000
--- a/bin/ledger/testing/ledger_test_instance_provider/meta/ledger_test_instance_provider.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/testing/loop_controller.h b/bin/ledger/testing/loop_controller.h
deleted file mode 100644
index f76862a..0000000
--- a/bin/ledger/testing/loop_controller.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_H_
-#define PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_H_
-
-#include <functional>
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/compiler_specific.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace ledger {
-// Helper class for waiting for asynchronous event.
-// For a given |CallbackWaiter|, one can retrieve a callback through
-// |GetCallback|. The callback must be called when the asynchronous event
-// ends.
-// When |RunUntilCalled| is called, it will run the event loop, until either the
-// callback from |GetCallback| is called or or the loop determines that the
-// callback will never be called. It returns |true|, if the callback has been
-// called, |false| otherwise. If one is waiting for the callback to be called
-// multiple times, one can execute |RunUntilCalled| multiple times. The |n|th
-// run of |RunUntilCalled| will return once the callback have been called at
-// least |n| time. |GetCallback| can be called multiple time, and all the
-// returned callback will be equivalent.
-class CallbackWaiter {
- public:
- CallbackWaiter() {}
- virtual ~CallbackWaiter() {}
- virtual fit::function<void()> GetCallback() = 0;
- virtual bool RunUntilCalled() FXL_WARN_UNUSED_RESULT = 0;
- // Returns whether the next expected calback has not already been called. If
- // |false|, |RunUntilCalled| will return immediately.
- virtual bool NotCalledYet() = 0;
-};
-
-// A subloop.
-class SubLoop {
- public:
- virtual ~SubLoop() {}
-
- // Runs all currently enqueued tasks on the loop and quits the loop. The
- // SubLoop must not be used again once this method returns.
- virtual void DrainAndQuit() = 0;
-
- // Returns a dispatcher whose runloop is owned by |this|.
- virtual async_dispatcher_t* dispatcher() = 0;
-};
-
-// Controller for the main run loop. This allows to control the loop that will
-// call the factory and the multiple instances.
-class LoopController {
- public:
- virtual ~LoopController(){};
-
- // Runs the loop.
- virtual void RunLoop() = 0;
- // Stops the loop.
- virtual void StopLoop() = 0;
- // Starts a new subloop.
- virtual std::unique_ptr<SubLoop> StartNewLoop() = 0;
- // Returns a waiter that can be used to run the loop until a callback has
- // been called.
- virtual std::unique_ptr<CallbackWaiter> NewWaiter() = 0;
- // Returns the dispatcher.
- virtual async_dispatcher_t* dispatcher() = 0;
- // Runs the loop until |condition| returns true.
- virtual bool RunLoopUntil(fit::function<bool()> condition) = 0;
- // Runs the loop until |duration| as passed.
- virtual void RunLoopFor(zx::duration duration) = 0;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_H_
diff --git a/bin/ledger/testing/loop_controller_real_loop.cc b/bin/ledger/testing/loop_controller_real_loop.cc
deleted file mode 100644
index 0064cf1..0000000
--- a/bin/ledger/testing/loop_controller_real_loop.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/loop_controller_real_loop.h"
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/zx/time.h>
-
-#include "peridot/bin/ledger/testing/blocking_callback_waiter.h"
-
-namespace ledger {
-
-namespace {
-
-// Implementation of a SubLoop that uses a real loop.
-class SubLoopRealLoop : public SubLoop {
- public:
- SubLoopRealLoop() : loop_(&kAsyncLoopConfigNoAttachToThread) {
- loop_.StartThread();
- };
-
- ~SubLoopRealLoop() override { loop_.Shutdown(); }
-
- void DrainAndQuit() override {
- async::TaskClosure quit_task([this] { loop_.Quit(); });
- quit_task.Post(loop_.dispatcher());
- loop_.JoinThreads();
- }
-
- async_dispatcher_t* dispatcher() override { return loop_.dispatcher(); }
-
- private:
- async::Loop loop_;
-};
-
-} // namespace
-
-LoopControllerRealLoop::LoopControllerRealLoop()
- : loop_(&kAsyncLoopConfigAttachToThread) {}
-
-LoopControllerRealLoop::~LoopControllerRealLoop() {}
-
-void LoopControllerRealLoop::RunLoop() {
- loop_.Run();
- loop_.ResetQuit();
-}
-
-void LoopControllerRealLoop::StopLoop() { loop_.Quit(); }
-
-std::unique_ptr<SubLoop> LoopControllerRealLoop::StartNewLoop() {
- return std::make_unique<SubLoopRealLoop>();
-}
-
-std::unique_ptr<CallbackWaiter> LoopControllerRealLoop::NewWaiter() {
- return std::make_unique<BlockingCallbackWaiter>(this);
-}
-
-async_dispatcher_t* LoopControllerRealLoop::dispatcher() {
- return loop_.dispatcher();
-}
-
-bool LoopControllerRealLoop::RunLoopUntil(fit::function<bool()> condition) {
- while (true) {
- if (condition()) {
- return true;
- }
- RunLoopFor(zx::msec(10));
- }
-}
-
-void LoopControllerRealLoop::RunLoopFor(zx::duration duration) {
- async::TaskClosure task([this] { loop_.Quit(); });
- task.PostDelayed(loop_.dispatcher(), duration);
- loop_.Run();
- loop_.ResetQuit();
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/loop_controller_real_loop.h b/bin/ledger/testing/loop_controller_real_loop.h
deleted file mode 100644
index 0a72e7a..0000000
--- a/bin/ledger/testing/loop_controller_real_loop.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_REAL_LOOP_H_
-#define PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_REAL_LOOP_H_
-
-#include <memory>
-
-#include <lib/async-loop/cpp/loop.h>
-
-#include "peridot/bin/ledger/testing/loop_controller.h"
-
-namespace ledger {
-
-// Implementation of a LoopController that uses a real loop.
-class LoopControllerRealLoop : public LoopController {
- public:
- LoopControllerRealLoop();
- ~LoopControllerRealLoop() override;
-
- void RunLoop() override;
-
- void StopLoop() override;
-
- std::unique_ptr<SubLoop> StartNewLoop() override;
-
- std::unique_ptr<CallbackWaiter> NewWaiter() override;
-
- async_dispatcher_t* dispatcher() override;
-
- bool RunLoopUntil(fit::function<bool()> condition) override;
-
- void RunLoopFor(zx::duration duration) override;
-
- private:
- async::Loop loop_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_REAL_LOOP_H_
diff --git a/bin/ledger/testing/loop_controller_test_loop.cc b/bin/ledger/testing/loop_controller_test_loop.cc
deleted file mode 100644
index 505d014..0000000
--- a/bin/ledger/testing/loop_controller_test_loop.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/loop_controller_test_loop.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/fit/defer.h>
-#include <memory>
-
-namespace ledger {
-
-namespace {
-
-class SubLoopTestLoop : public SubLoop {
- public:
- explicit SubLoopTestLoop(LoopController* controller,
- std::unique_ptr<async::LoopInterface> loop_interface)
- : controller_(controller), loop_interface_(std::move(loop_interface)) {}
-
- void DrainAndQuit() override {
- // TODO(qsr): Implement drain on TestLoop.
- auto waiter = controller_->NewWaiter();
- async::PostTask(dispatcher(), waiter->GetCallback());
- FXL_CHECK(waiter->RunUntilCalled());
- }
-
- async_dispatcher_t* dispatcher() override {
- return loop_interface_->dispatcher();
- }
-
- private:
- LoopController* controller_;
- std::unique_ptr<async::LoopInterface> loop_interface_;
-};
-
-class CallbackWaiterImpl : public CallbackWaiter {
- public:
- explicit CallbackWaiterImpl(LoopController* loop) : loop_(loop) {}
- CallbackWaiterImpl(const CallbackWaiterImpl&) = delete;
- CallbackWaiterImpl& operator=(const CallbackWaiterImpl&) = delete;
- ~CallbackWaiterImpl() override = default;
-
- fit::function<void()> GetCallback() override {
- return [this] {
- ++callback_called_count_;
- if (running_) {
- loop_->StopLoop();
- }
- };
- }
-
- bool RunUntilCalled() override {
- FXL_DCHECK(!running_);
- running_ = true;
- auto cleanup = fit::defer([this] { running_ = false; });
- bool called = loop_->RunLoopUntil([this] { return !NotCalledYet(); });
- if (called) {
- ++run_until_called_count_;
- }
- return called;
- }
-
- bool NotCalledYet() override {
- return callback_called_count_ <= run_until_called_count_;
- }
-
- private:
- LoopController* loop_;
- size_t callback_called_count_ = 0;
- size_t run_until_called_count_ = 0;
- // Whether the waiter is currently in the |RunUntilCalled| method.
- bool running_ = false;
-};
-
-} // namespace
-
-LoopControllerTestLoop::LoopControllerTestLoop(async::TestLoop* loop)
- : loop_(loop) {}
-
-LoopControllerTestLoop::~LoopControllerTestLoop() {}
-
-void LoopControllerTestLoop::RunLoop() { loop_->RunUntilIdle(); }
-
-void LoopControllerTestLoop::StopLoop() { loop_->Quit(); }
-
-std::unique_ptr<SubLoop> LoopControllerTestLoop::StartNewLoop() {
- return std::make_unique<SubLoopTestLoop>(
- this,
- std::unique_ptr<async::LoopInterface>(loop_->StartNewLoop().release()));
-}
-
-std::unique_ptr<CallbackWaiter> LoopControllerTestLoop::NewWaiter() {
- return std::make_unique<CallbackWaiterImpl>(this);
-}
-
-async_dispatcher_t* LoopControllerTestLoop::dispatcher() {
- return loop_->dispatcher();
-}
-
-bool LoopControllerTestLoop::RunLoopUntil(fit::function<bool()> condition) {
- if (condition()) {
- return true;
- }
- // The condition is not true, but might be triggered after some delay due to a
- // delayed task (for example, because of backoffs). Try to advance the loop in
- // bigger and bigger increment. Fail if the event does not occur after ~100s
- // as if something doesn't happen in 100 simulated s, then it will almost
- // certainly be a problem for tests using a real loop.
- for (size_t i : {0, 1, 10, 100}) {
- loop_->RunFor(zx::sec(i));
- if (condition()) {
- return true;
- }
- }
- return false;
-}
-
-void LoopControllerTestLoop::RunLoopFor(zx::duration duration) {
- loop_->RunFor(duration);
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/loop_controller_test_loop.h b/bin/ledger/testing/loop_controller_test_loop.h
deleted file mode 100644
index bc1ba92..0000000
--- a/bin/ledger/testing/loop_controller_test_loop.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_TEST_LOOP_H_
-#define PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_TEST_LOOP_H_
-
-#include <memory>
-
-#include <lib/async-testutils/test_loop.h>
-
-#include "peridot/bin/ledger/testing/loop_controller.h"
-
-namespace ledger {
-
-// Implementation of a LoopController that uses a test loop. The test loop
-// simulates the time in a deterministic way and does not rely on the real
-// (physical) clock.
-class LoopControllerTestLoop : public LoopController {
- public:
- LoopControllerTestLoop(async::TestLoop* loop);
- ~LoopControllerTestLoop() override;
-
- void RunLoop() override;
-
- void StopLoop() override;
-
- std::unique_ptr<SubLoop> StartNewLoop() override;
-
- std::unique_ptr<CallbackWaiter> NewWaiter() override;
-
- async_dispatcher_t* dispatcher() override;
-
- bool RunLoopUntil(fit::function<bool()> condition) override;
-
- void RunLoopFor(zx::duration duration) override;
-
- async::TestLoop& test_loop() { return *loop_; }
-
- private:
- async::TestLoop* const loop_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_LOOP_CONTROLLER_TEST_LOOP_H_
diff --git a/bin/ledger/testing/netconnector/BUILD.gn b/bin/ledger/testing/netconnector/BUILD.gn
deleted file mode 100644
index 6d67c6f..0000000
--- a/bin/ledger/testing/netconnector/BUILD.gn
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("netconnector") {
- testonly = true
-
- sources = [
- "fake_netconnector.cc",
- "fake_netconnector.h",
- "netconnector_factory.cc",
- "netconnector_factory.h",
- ]
-
- public_deps = [
- "//garnet/public/fidl/fuchsia.netconnector",
- "//garnet/public/lib/callback",
- "//peridot/bin/ledger/fidl_helpers",
- "//peridot/bin/ledger/testing:lib",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/test_runner/cpp/reporting",
- "//peridot/lib/convert",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "netconnector_factory_unittest.cc",
- ]
-
- deps = [
- ":netconnector",
- "//garnet/public/fidl/fuchsia.netconnector",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/netconnector/cpp",
- "//peridot/bin/ledger/environment",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/testing/netconnector/fake_netconnector.cc b/bin/ledger/testing/netconnector/fake_netconnector.cc
deleted file mode 100644
index c0eaa12..0000000
--- a/bin/ledger/testing/netconnector/fake_netconnector.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/netconnector/fake_netconnector.h"
-
-namespace ledger {
-FakeNetConnector::FakeNetConnector(Delegate* delegate) : delegate_(delegate) {}
-
-void FakeNetConnector::ConnectToServiceProvider(
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request) {
- service_provider_impl_.AddBinding(std::move(request));
-}
-
-void FakeNetConnector::RegisterServiceProvider(
- std::string name,
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> service_provider) {
- fuchsia::sys::ServiceProviderPtr service_provider_ptr =
- service_provider.Bind();
- service_provider_impl_.AddServiceForName(
- [name, service_provider_ptr =
- std::move(service_provider_ptr)](zx::channel channel) {
- service_provider_ptr->ConnectToService(name, std::move(channel));
- },
- name);
-}
-
-void FakeNetConnector::GetDeviceServiceProvider(
- std::string device_name,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> service_provider) {
- delegate_->ConnectToServiceProvider(device_name, std::move(service_provider));
-}
-
-void FakeNetConnector::GetKnownDeviceNames(
- uint64_t version_last_seen, GetKnownDeviceNamesCallback callback) {
- delegate_->GetDevicesNames(version_last_seen, std::move(callback));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/netconnector/fake_netconnector.h b/bin/ledger/testing/netconnector/fake_netconnector.h
deleted file mode 100644
index ddd3565..0000000
--- a/bin/ledger/testing/netconnector/fake_netconnector.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_NETCONNECTOR_FAKE_NETCONNECTOR_H_
-#define PERIDOT_BIN_LEDGER_TESTING_NETCONNECTOR_FAKE_NETCONNECTOR_H_
-
-#include <fuchsia/netconnector/cpp/fidl.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-namespace ledger {
-
-// FakeNetConnector implements NetConnector. It acts as the singleton
-// NetConnector for a (virtual) host.
-class FakeNetConnector : public fuchsia::netconnector::NetConnector {
- public:
- class Delegate {
- public:
- virtual ~Delegate() {}
-
- // Returns the list of known devices. See NetConnector::GetKnownDeviceNames
- // for more details.
- virtual void GetDevicesNames(
- uint64_t last_version,
- fit::function<void(uint64_t, std::vector<std::string>)>
- callback) = 0;
-
- // Connects to the ServiceProvider from host |device_name|.
- virtual void ConnectToServiceProvider(
- std::string device_name,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request) = 0;
- };
-
- explicit FakeNetConnector(Delegate* delegate);
- ~FakeNetConnector() override {}
-
- // Connects to the service provider of this (virtual) host
- void ConnectToServiceProvider(
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request);
-
- private:
- // NetConnector implementation:
- void RegisterServiceProvider(
- std::string name,
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> service_provider)
- override;
- void GetDeviceServiceProvider(
- std::string device_name,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> service_provider)
- override;
- void GetKnownDeviceNames(uint64_t version_last_seen,
- GetKnownDeviceNamesCallback callback) override;
-
- component::ServiceProviderImpl service_provider_impl_;
- Delegate* const delegate_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeNetConnector);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_NETCONNECTOR_FAKE_NETCONNECTOR_H_
diff --git a/bin/ledger/testing/netconnector/netconnector_factory.cc b/bin/ledger/testing/netconnector/netconnector_factory.cc
deleted file mode 100644
index 21b0efe..0000000
--- a/bin/ledger/testing/netconnector/netconnector_factory.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/netconnector/netconnector_factory.h"
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fit/function.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-class NetConnectorFactory::Holder {
- public:
- Holder(FakeNetConnector::Delegate* delegate,
- fidl::InterfaceRequest<fuchsia::netconnector::NetConnector> request,
- std::string device_name, fit::closure on_disconnect);
-
- void set_on_empty(fit::closure on_empty);
-
- FakeNetConnector* impl();
-
- private:
- void OnEmpty();
-
- const std::string device_name_;
- fidl_helpers::BoundInterface<fuchsia::netconnector::NetConnector,
- FakeNetConnector>
- interface_;
- fit::closure on_empty_;
- fit::closure on_disconnect_;
-};
-
-NetConnectorFactory::Holder::Holder(
- FakeNetConnector::Delegate* delegate,
- fidl::InterfaceRequest<fuchsia::netconnector::NetConnector> request,
- std::string device_name, fit::closure on_disconnect)
- : device_name_(std::move(device_name)),
- interface_(std::move(request), delegate),
- on_disconnect_(std::move(on_disconnect)) {
- interface_.set_on_empty([this] { OnEmpty(); });
-}
-
-void NetConnectorFactory::Holder::set_on_empty(fit::closure on_empty) {
- on_empty_ = std::move(on_empty);
-}
-
-FakeNetConnector* NetConnectorFactory::Holder::impl() {
- return interface_.impl();
-}
-
-void NetConnectorFactory::Holder::OnEmpty() {
- // We need to deregister ourselves from the list of active devices (call
- // |on_empty_|) before updating the pending host list callbacks (call
- // |on_disconnect_|). As |on_empty_| destroys |this|, we move |on_disconnect_|
- // locally to be able to call it later.
- auto on_disconnect = std::move(on_disconnect_);
- if (on_empty_) {
- on_empty_();
- }
- if (on_disconnect) {
- on_disconnect();
- }
-}
-
-NetConnectorFactory::NetConnectorFactory() {}
-
-NetConnectorFactory::~NetConnectorFactory() {}
-
-void NetConnectorFactory::AddBinding(
- std::string host_name,
- fidl::InterfaceRequest<fuchsia::netconnector::NetConnector> request) {
- net_connectors_.emplace(
- std::piecewise_construct, std::forward_as_tuple(host_name),
- std::forward_as_tuple(this, std::move(request), host_name,
- [this] { UpdatedHostList(); }));
- UpdatedHostList();
-}
-
-void NetConnectorFactory::UpdatedHostList() {
- current_version_++;
- if (pending_device_list_callbacks_.empty()) {
- return;
- }
- std::vector<std::string> device_names;
- for (const auto& holder_pair : net_connectors_) {
- device_names.push_back(holder_pair.first);
- }
- for (const auto& callback : pending_device_list_callbacks_) {
- callback(current_version_, device_names);
- }
- pending_device_list_callbacks_.clear();
-}
-
-void NetConnectorFactory::GetDevicesNames(
- uint64_t last_version,
- fit::function<void(uint64_t, std::vector<std::string>)> callback) {
- FXL_CHECK(last_version <= current_version_)
- << "Last seen version (" << last_version
- << ") is more recent than current version (" << current_version_
- << "). Something is wrong here.";
- if (last_version == current_version_) {
- pending_device_list_callbacks_.push_back(std::move(callback));
- return;
- }
- std::vector<std::string> device_names;
- for (const auto& holder_pair : net_connectors_) {
- device_names.push_back(holder_pair.first);
- }
- callback(current_version_, std::move(device_names));
-}
-
-void NetConnectorFactory::ConnectToServiceProvider(
- std::string device_name,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request) {
- auto it = net_connectors_.find(device_name);
- if (it == net_connectors_.end()) {
- return;
- }
- (*it).second.impl()->ConnectToServiceProvider(std::move(request));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/netconnector/netconnector_factory.h b/bin/ledger/testing/netconnector/netconnector_factory.h
deleted file mode 100644
index 3b618d7..0000000
--- a/bin/ledger/testing/netconnector/netconnector_factory.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_NETCONNECTOR_NETCONNECTOR_FACTORY_H_
-#define PERIDOT_BIN_LEDGER_TESTING_NETCONNECTOR_NETCONNECTOR_FACTORY_H_
-
-#include <fuchsia/netconnector/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl_helpers/bound_interface.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/netconnector/fake_netconnector.h"
-
-namespace ledger {
-
-// NetConnectorFactory creates and manages connections to |FakeNetConnector|s.
-// It can be used to test the behavior of multiple NetConnector clients without
-// a multi-device setup.
-class NetConnectorFactory : public FakeNetConnector::Delegate {
- public:
- NetConnectorFactory();
- ~NetConnectorFactory() override;
-
- // Creates a new virtual host with the given host name, and connects to its
- // NetConnector.
- void AddBinding(
- std::string host_name,
- fidl::InterfaceRequest<fuchsia::netconnector::NetConnector> request);
-
- private:
- // Holder holds a NetConnector.
- class Holder;
-
- // UpdatedHostList is called when the list of hosts changes. It sends
- // notifications to waiting clients as necessary.
- void UpdatedHostList();
-
- // FakeNetConnector::Delegate:
- void GetDevicesNames(
- uint64_t last_version,
- fit::function<void(uint64_t, std::vector<std::string>)> callback)
- override;
- void ConnectToServiceProvider(
- std::string device_name,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request) override;
-
- // Counter incremented each time a NetConnector is added or removed; denotes
- // the version of the current device list.
- uint64_t current_version_ = 0;
- std::vector<fit::function<void(uint64_t, std::vector<std::string>)>>
- pending_device_list_callbacks_;
- callback::AutoCleanableMap<std::string, Holder> net_connectors_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(NetConnectorFactory);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_NETCONNECTOR_NETCONNECTOR_FACTORY_H_
diff --git a/bin/ledger/testing/netconnector/netconnector_factory_unittest.cc b/bin/ledger/testing/netconnector/netconnector_factory_unittest.cc
deleted file mode 100644
index 7346c1a..0000000
--- a/bin/ledger/testing/netconnector/netconnector_factory_unittest.cc
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/netconnector/netconnector_factory.h"
-
-#include <memory>
-
-#include <fuchsia/netconnector/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include <lib/netconnector/cpp/message_relay.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-namespace {
-
-class NetConnectorFactoryTest : public gtest::TestLoopFixture {
- public:
- NetConnectorFactoryTest() {}
- ~NetConnectorFactoryTest() override {}
-
- protected:
- NetConnectorFactory factory_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(NetConnectorFactoryTest);
-};
-
-// Verifies that the host list is correct for one host.
-TEST_F(NetConnectorFactoryTest, HostList_OneHost) {
- fuchsia::netconnector::NetConnectorPtr netconnector1;
- factory_.AddBinding("host1", netconnector1.NewRequest());
-
- bool called = false;
- uint64_t version = 0;
- std::vector<std::string> host_list;
- netconnector1->GetKnownDeviceNames(
- fuchsia::netconnector::kInitialKnownDeviceNames,
- callback::Capture(callback::SetWhenCalled(&called), &version,
- &host_list));
-
- RunLoopUntilIdle();
-
- EXPECT_TRUE(called);
- EXPECT_NE(fuchsia::netconnector::kInitialKnownDeviceNames, version);
- ASSERT_GE(1u, host_list.size());
- EXPECT_EQ(1u, host_list.size());
- EXPECT_EQ("host1", host_list.at(0));
-
- called = false;
- netconnector1->GetKnownDeviceNames(
- version, callback::Capture(callback::SetWhenCalled(&called), &version,
- &host_list));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-}
-
-// Verifies that the host list is correct for two hosts.
-TEST_F(NetConnectorFactoryTest, HostList_TwoHosts_Sequence) {
- fuchsia::netconnector::NetConnectorPtr netconnector1;
- factory_.AddBinding("host1", netconnector1.NewRequest());
-
- bool called = false;
- uint64_t version = 0;
- std::vector<std::string> host_list;
- netconnector1->GetKnownDeviceNames(
- fuchsia::netconnector::kInitialKnownDeviceNames,
- callback::Capture(callback::SetWhenCalled(&called), &version,
- &host_list));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- called = false;
- uint64_t new_version = version;
- netconnector1->GetKnownDeviceNames(
- version, callback::Capture(callback::SetWhenCalled(&called), &new_version,
- &host_list));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-
- fuchsia::netconnector::NetConnectorPtr netconnector2;
- factory_.AddBinding("host2", netconnector2.NewRequest());
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_NE(new_version, version);
- ASSERT_GE(2u, host_list.size());
- EXPECT_EQ(2u, host_list.size());
- EXPECT_EQ("host1", host_list.at(0));
- EXPECT_EQ("host2", host_list.at(1));
-
- called = false;
- netconnector2->GetKnownDeviceNames(
- fuchsia::netconnector::kInitialKnownDeviceNames,
- callback::Capture(callback::SetWhenCalled(&called), &new_version,
- &host_list));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- ASSERT_GE(2u, host_list.size());
- EXPECT_EQ(2u, host_list.size());
- EXPECT_EQ("host1", host_list.at(0));
- EXPECT_EQ("host2", host_list.at(1));
-
- netconnector2.Unbind();
-
- netconnector1->GetKnownDeviceNames(
- new_version, callback::Capture(callback::SetWhenCalled(&called),
- &new_version, &host_list));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- ASSERT_GE(1u, host_list.size());
- EXPECT_EQ(1u, host_list.size());
- EXPECT_EQ("host1", host_list.at(0));
-}
-
-// Verifies that the host list is correct for two hosts when calls are chained,
-// ie. when we have a pending call for a new host list waiting when a host
-// connects or disconnects.
-TEST_F(NetConnectorFactoryTest, HostList_TwoHosts_Chained) {
- fuchsia::netconnector::NetConnectorPtr netconnector1;
- factory_.AddBinding("host1", netconnector1.NewRequest());
-
- bool called = false;
- uint64_t version = 0;
- std::vector<std::string> host_list;
- netconnector1->GetKnownDeviceNames(
- fuchsia::netconnector::kInitialKnownDeviceNames,
- callback::Capture(callback::SetWhenCalled(&called), &version,
- &host_list));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- called = false;
- uint64_t new_version = version;
- netconnector1->GetKnownDeviceNames(
- version, callback::Capture(callback::SetWhenCalled(&called), &new_version,
- &host_list));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-
- fuchsia::netconnector::NetConnectorPtr netconnector2;
- factory_.AddBinding("host2", netconnector2.NewRequest());
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_NE(new_version, version);
- ASSERT_GE(2u, host_list.size());
- EXPECT_EQ(2u, host_list.size());
- EXPECT_EQ("host1", host_list.at(0));
- EXPECT_EQ("host2", host_list.at(1));
-
- netconnector1->GetKnownDeviceNames(
- new_version, callback::Capture(callback::SetWhenCalled(&called),
- &new_version, &host_list));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-
- netconnector2.Unbind();
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- ASSERT_GE(1u, host_list.size());
- EXPECT_EQ(1u, host_list.size());
- EXPECT_EQ("host1", host_list.at(0));
-}
-
-TEST_F(NetConnectorFactoryTest, HostList_TwoHosts_Callback) {
- fuchsia::netconnector::NetConnectorPtr netconnector1;
- factory_.AddBinding("host1", netconnector1.NewRequest());
-
- bool called = false;
- uint64_t version = 0;
- std::vector<std::string> host_list;
- netconnector1->GetKnownDeviceNames(
- fuchsia::netconnector::kInitialKnownDeviceNames,
- callback::Capture(callback::SetWhenCalled(&called), &version,
- &host_list));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
-
- called = false;
- uint64_t new_version;
- netconnector1->GetKnownDeviceNames(
- version, callback::Capture(callback::SetWhenCalled(&called), &new_version,
- &host_list));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-
- fuchsia::netconnector::NetConnectorPtr netconnector2;
- factory_.AddBinding("host2", netconnector2.NewRequest());
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_NE(new_version, version);
- ASSERT_GE(2u, host_list.size());
- EXPECT_EQ(2u, host_list.size());
- EXPECT_EQ("host1", host_list.at(0));
- EXPECT_EQ("host2", host_list.at(1));
-
- bool called2;
- netconnector1->GetKnownDeviceNames(
- new_version, callback::Capture(callback::SetWhenCalled(&called),
- &new_version, &host_list));
- netconnector2->GetKnownDeviceNames(
- new_version, callback::Capture(callback::SetWhenCalled(&called2),
- &new_version, &host_list));
-
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- EXPECT_FALSE(called2);
-
- netconnector2.Unbind();
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_FALSE(called2);
-
- ASSERT_GE(1u, host_list.size());
- EXPECT_EQ(1u, host_list.size());
- EXPECT_EQ("host1", host_list.at(0));
-}
-
-// Tests that two "hosts" can talk to each other through the NetConnector
-TEST_F(NetConnectorFactoryTest, ServiceProvider) {
- // Sets up the first host (server).
- fuchsia::netconnector::NetConnectorPtr netconnector1;
- factory_.AddBinding("host1", netconnector1.NewRequest());
-
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> handle;
- component::ServiceProviderImpl service_provider1;
- std::vector<std::unique_ptr<netconnector::MessageRelay>> relays_host1;
- service_provider1.AddBinding(handle.NewRequest());
- service_provider1.AddServiceForName(
- [&relays_host1](zx::channel channel) {
- auto relay = std::make_unique<netconnector::MessageRelay>();
- relay->SetChannel(std::move(channel));
- relays_host1.push_back(std::move(relay));
- },
- "test_service");
- netconnector1->RegisterServiceProvider("test_service", std::move(handle));
-
- RunLoopUntilIdle();
-
- // Sets up the second host (client).
- fuchsia::netconnector::NetConnectorPtr netconnector2;
- factory_.AddBinding("host2", netconnector2.NewRequest());
- zx::channel local;
- zx::channel remote;
- zx_status_t status = zx::channel::create(0u, &local, &remote);
-
- FXL_CHECK(status == ZX_OK) << "zx::channel::create failed, status " << status;
-
- fuchsia::sys::ServiceProviderPtr service_provider_ptr;
- netconnector2->GetDeviceServiceProvider("host1",
- service_provider_ptr.NewRequest());
-
- service_provider_ptr->ConnectToService("test_service", std::move(remote));
-
- RunLoopUntilIdle();
-
- // Verifies that we have received the connection from host2 to host1.
- ASSERT_GE(1u, relays_host1.size());
- EXPECT_EQ(1u, relays_host1.size());
-
- // Sets up MessageRelays to abstract sending messages through channels.
- bool called_host1 = false;
- std::vector<uint8_t> message_host1;
- relays_host1[0]->SetMessageReceivedCallback(callback::Capture(
- callback::SetWhenCalled(&called_host1), &message_host1));
-
- netconnector::MessageRelay relay2;
- relay2.SetChannel(std::move(local));
- bool called_host2 = false;
- std::vector<uint8_t> message_host2;
- relay2.SetMessageReceivedCallback(callback::Capture(
- callback::SetWhenCalled(&called_host2), &message_host2));
-
- // Sends a message from host2 to host1.
- relay2.SendMessage({0u, 1u});
- RunLoopUntilIdle();
-
- EXPECT_TRUE(called_host1);
- EXPECT_FALSE(called_host2);
- EXPECT_EQ(std::vector<uint8_t>({0u, 1u}), message_host1);
-
- // Sends a message from host1 to host2.
- called_host1 = false;
- relays_host1[0]->SendMessage({2u, 3u});
- RunLoopUntilIdle();
-
- EXPECT_FALSE(called_host1);
- EXPECT_TRUE(called_host2);
- EXPECT_EQ(std::vector<uint8_t>({2u, 3u}), message_host2);
-
- // Verifies that disconnection works.
- bool relay2_disconnected = false;
- relay2.SetChannelClosedCallback(
- callback::SetWhenCalled(&relay2_disconnected));
- relays_host1[0].reset();
-
- RunLoopUntilIdle();
- EXPECT_TRUE(relay2_disconnected);
-}
-} // namespace
-
-} // namespace ledger
diff --git a/bin/ledger/testing/page_data_generator.cc b/bin/ledger/testing/page_data_generator.cc
deleted file mode 100644
index 533ac74..0000000
--- a/bin/ledger/testing/page_data_generator.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/page_data_generator.h"
-
-#include <memory>
-
-#include <lib/callback/waiter.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-namespace {
-
-constexpr size_t kMaxInlineDataSize = ZX_CHANNEL_MAX_MSG_BYTES * 9 / 10;
-
-bool LogOnError(Status status, fxl::StringView description) {
- if (status != Status::OK) {
- FXL_LOG(ERROR) << description << " failed with status "
- << fidl::ToUnderlying(status) << ".";
- return true;
- }
- return false;
-}
-
-} // namespace
-
-PageDataGenerator::PageDataGenerator(rng::Random* random)
- : generator_(random) {}
-
-void PageDataGenerator::PutEntry(PagePtr* page, std::vector<uint8_t> key,
- std::vector<uint8_t> value,
- ReferenceStrategy ref_strategy,
- Priority priority,
- fit::function<void(Status)> callback) {
- if (ref_strategy == ReferenceStrategy::INLINE) {
- if (value.size() >= kMaxInlineDataSize) {
- FXL_LOG(ERROR)
- << "Value too large (" << value.size()
- << ") to be put inline. Consider putting as reference instead.";
- callback(Status::IO_ERROR);
- return;
- }
- (*page)->PutWithPriority(std::move(key), std::move(value), priority,
- [callback = std::move(callback)](Status status) {
- LogOnError(status, "Page::PutWithPriority");
- callback(status);
- });
- return;
- }
- fsl::SizedVmo vmo;
- if (!fsl::VmoFromString(convert::ToStringView(value), &vmo)) {
- LogOnError(Status::IO_ERROR, "fsl::VmoFromString");
- callback(Status::IO_ERROR);
- return;
- }
- (*page)->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- [page, key = std::move(key), priority, callback = std::move(callback)](
- Status status, ReferencePtr reference) mutable {
- if (LogOnError(status, "Page::CreateReferenceFromBuffer")) {
- callback(status);
- return;
- }
- (*page)->PutReference(std::move(key), std::move(*reference), priority,
- [callback = std::move(callback)](Status status) {
- LogOnError(status, "Page::PutReference");
- callback(status);
- });
- });
-}
-
-void PageDataGenerator::Populate(PagePtr* page,
- std::vector<std::vector<uint8_t>> keys,
- size_t value_size, size_t transaction_size,
- ReferenceStrategy ref_strategy,
- Priority priority,
- fit::function<void(Status)> callback) {
- if (transaction_size == 0) {
- PutMultipleEntries(page, std::move(keys), value_size, ref_strategy,
- priority, std::move(callback));
- return;
- }
- PutInTransaction(page, std::move(keys), 0, value_size, transaction_size,
- ref_strategy, priority, std::move(callback));
-}
-
-void PageDataGenerator::PutInTransaction(
- PagePtr* page, std::vector<std::vector<uint8_t>> keys,
- size_t current_key_index, size_t value_size, size_t transaction_size,
- ReferenceStrategy ref_strategy, Priority priority,
- fit::function<void(Status)> callback) {
- if (current_key_index >= keys.size()) {
- callback(Status::OK);
- return;
- }
- size_t this_transaction_size =
- std::min(transaction_size, keys.size() - current_key_index);
- std::vector<std::vector<uint8_t>> partial_keys;
- std::move(keys.begin() + current_key_index,
- keys.begin() + current_key_index + this_transaction_size,
- std::back_inserter(partial_keys));
-
- (*page)->StartTransaction(
- [this, page, partial_keys = std::move(partial_keys),
- keys = std::move(keys), current_key_index, transaction_size, value_size,
- ref_strategy, priority,
- callback = std::move(callback)](Status status) mutable {
- if (LogOnError(status, "Page::StartTransaction")) {
- callback(status);
- return;
- }
- PutMultipleEntries(
- page, std::move(partial_keys), value_size, ref_strategy, priority,
- [this, page, keys = std::move(keys), current_key_index, value_size,
- ref_strategy, priority, transaction_size,
- callback = std::move(callback)](Status status) mutable {
- if (LogOnError(status, "PutMultipleEntries")) {
- callback(status);
- return;
- }
- (*page)->Commit(
- [this, page, keys = std::move(keys), current_key_index,
- value_size, ref_strategy, transaction_size, priority,
- callback = std::move(callback)](Status status) mutable {
- if (LogOnError(status, "Page::Commit")) {
- callback(status);
- return;
- }
- PutInTransaction(page, std::move(keys),
- current_key_index + transaction_size,
- value_size, transaction_size, ref_strategy,
- priority, std::move(callback));
- });
- });
- });
-}
-
-void PageDataGenerator::PutMultipleEntries(
- PagePtr* page, std::vector<std::vector<uint8_t>> keys,
- size_t value_size, ReferenceStrategy ref_strategy, Priority priority,
- fit::function<void(Status)> callback) {
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- for (auto& key : keys) {
- std::vector<uint8_t> value = generator_.MakeValue(value_size);
- PutEntry(page, std::move(key), std::move(value), ref_strategy, priority,
- waiter->NewCallback());
- }
- waiter->Finalize(std::move(callback));
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/page_data_generator.h b/bin/ledger/testing/page_data_generator.h
deleted file mode 100644
index 2330a15..0000000
--- a/bin/ledger/testing/page_data_generator.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_PAGE_DATA_GENERATOR_H_
-#define PERIDOT_BIN_LEDGER_TESTING_PAGE_DATA_GENERATOR_H_
-
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/lib/rng/random.h"
-
-namespace ledger {
-
-// Helper class for filling a ledger page with random data.
-class PageDataGenerator {
- public:
- // Strategy on how to put values: inline or as references.
- // INLINE: Put entry inline (as a FIDL array).
- // REFERENCE: Put entry as reference.
- enum class ReferenceStrategy {
- INLINE,
- REFERENCE,
- };
-
- PageDataGenerator(rng::Random* random);
-
- // Put an entry (|key|, |value|) to the given page |page|, inline or as
- // reference depending on |ref_strategy| and with priority specified by
- // |priority|.
- void PutEntry(PagePtr* page, std::vector<uint8_t> key,
- std::vector<uint8_t> value, ReferenceStrategy ref_strategy,
- Priority priority, fit::function<void(Status)> callback);
-
- // Fill the page |page| with entries with keys |keys| and random values of
- // size |value_size|, performing at maximum
- // |transaction_size| Put operations per commit.
- void Populate(PagePtr* page, std::vector<std::vector<uint8_t>> keys,
- size_t value_size, size_t transaction_size,
- ReferenceStrategy ref_strategy, Priority priority,
- fit::function<void(Status)> /*callback*/);
-
- private:
- // Run PutEntry |transaction_size| times on provided keys |keys| with random
- // values of size |value_size|. in transaction starting with key
- // number |curent_key_index|. After commiting a transaction, run a next one
- // recursively. Call |callback| with Status::OK once all keys have been put,
- // or with a first encountered status that is different from Status::OK.
- void PutInTransaction(PagePtr* page,
- std::vector<std::vector<uint8_t>> keys,
- size_t current_key_index, size_t value_size,
- size_t transaction_size, ReferenceStrategy ref_strategy,
- Priority priority,
- fit::function<void(Status)> callback);
-
- // Run PutEntry on all the provided keys in |keys| with random value of size
- // |value_size|.
- void PutMultipleEntries(PagePtr* page,
- std::vector<std::vector<uint8_t>> keys,
- size_t value_size, ReferenceStrategy ref_strategy,
- Priority priority,
- fit::function<void(Status)> /*callback*/);
-
- DataGenerator generator_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_PAGE_DATA_GENERATOR_H_
diff --git a/bin/ledger/testing/quit_on_error.cc b/bin/ledger/testing/quit_on_error.cc
deleted file mode 100644
index a89cd4c..0000000
--- a/bin/ledger/testing/quit_on_error.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-
-#include <lib/fit/function.h>
-
-namespace ledger {
-
-bool QuitOnError(fit::closure quit_callback, Status status,
- fxl::StringView description) {
- if (status != Status::OK) {
- FXL_LOG(ERROR) << description << " failed with status "
- << fidl::ToUnderlying(status) << ".";
- quit_callback();
- return true;
- }
- return false;
-}
-
-fit::function<void(Status)> QuitOnErrorCallback(fit::closure quit_callback,
- std::string description) {
- return [quit_callback = std::move(quit_callback),
- description = std::move(description)](Status status) mutable {
- QuitOnError(quit_callback.share(), status, description);
- };
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/quit_on_error.h b/bin/ledger/testing/quit_on_error.h
deleted file mode 100644
index 8e9a911..0000000
--- a/bin/ledger/testing/quit_on_error.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_QUIT_ON_ERROR_H_
-#define PERIDOT_BIN_LEDGER_TESTING_QUIT_ON_ERROR_H_
-
-#include <functional>
-#include <string>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace ledger {
-
-// Logs an error and calls |quit_callback| which quits a related message loop if
-// the given ledger status is not Status::OK. Returns true if the loop
-// was quit .
-bool QuitOnError(fit::closure quit_callback, Status status,
- fxl::StringView description);
-
-fit::function<void(Status)> QuitOnErrorCallback(fit::closure quit_callback,
- std::string description);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_QUIT_ON_ERROR_H_
diff --git a/bin/ledger/testing/run_with_tracing.cc b/bin/ledger/testing/run_with_tracing.cc
deleted file mode 100644
index a099165..0000000
--- a/bin/ledger/testing/run_with_tracing.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-#include <trace-provider/provider.h>
-#include <trace/event.h>
-#include <trace/observer.h>
-
-namespace ledger {
-
-int RunWithTracing(async::Loop* loop, fit::function<void()> runnable) {
- trace::TraceProvider trace_provider(loop->dispatcher());
- trace::TraceObserver trace_observer;
-
- bool started = false;
- auto on_trace_state_changed = [runnable = std::move(runnable), &started]() {
- if (TRACE_CATEGORY_ENABLED("benchmark") && !started) {
- started = true;
- runnable();
- }
- };
- // In case tracing has already started.
- on_trace_state_changed();
-
- if (!started) {
- trace_observer.Start(loop->dispatcher(), std::move(on_trace_state_changed));
- }
-
- int err = 0;
- async::TaskClosure quit_task([&started, loop, &err] {
- if (!started) {
- // To avoid running the runnable if the tracing state changes to
- // started in the immediate next task on the queue (before the quit
- // task executes).
- started = true;
- FXL_LOG(ERROR)
- << "Timed out waiting for the tracing to start; Did you run the "
- "binary with the trace tool enabled?";
- err = -1;
- loop->Quit();
- }
- });
- quit_task.PostDelayed(loop->dispatcher(), zx::sec(5));
-
- loop->Run();
- return err;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/run_with_tracing.h b/bin/ledger/testing/run_with_tracing.h
deleted file mode 100644
index cab145f..0000000
--- a/bin/ledger/testing/run_with_tracing.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_RUN_WITH_TRACING_H_
-#define PERIDOT_BIN_LEDGER_TESTING_RUN_WITH_TRACING_H_
-
-#include <functional>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fit/function.h>
-
-namespace ledger {
-
-// Adds a TraceObserver to start running |runnable| as soon as the tracing is
-// enabled; then runs the message loop |loop|.
-// If tracing is still not enabled after 5 seconds, posts a quit task.
-int RunWithTracing(async::Loop* loop, fit::function<void()> runnable);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_RUN_WITH_TRACING_H_
diff --git a/bin/ledger/testing/sync_params.cc b/bin/ledger/testing/sync_params.cc
deleted file mode 100644
index 1921155..0000000
--- a/bin/ledger/testing/sync_params.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/sync_params.h"
-
-#include <iostream>
-
-#include <fuchsia/net/oldhttp/cpp/fidl.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/strings/string_view.h>
-#include <openssl/sha.h>
-
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/firebase_auth/testing/credentials.h"
-#include "peridot/lib/firebase_auth/testing/json_schema.h"
-
-namespace {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-constexpr fxl::StringView kSyncParamsSchema = R"({
- "type": "object",
- "properties": {
- "api-key": {
- "type": "string"
- },
- "service-account": {
- "type": "object"
- }
- },
- "required": ["api-key", "service-account"]
-})";
-
-constexpr fxl::StringView kCredentialsPathFlag = "credentials-path";
-constexpr fxl::StringView kGnCredentialsPathArg =
- "ledger_sync_credentials_file";
-constexpr fxl::StringView kCredentialsDefaultPath =
- "/pkg/data/sync_credentials.json";
-
-// URL that the sync infra bots use to pass the sync credentials to the tests.
-constexpr fxl::StringView kCredentialsFetchUrl =
- "http://10.0.2.2:8081/ledger_e2e_sync_credentials";
-
-void WarnIncorrectSyncParams() {
- std::cerr << "Missing the sync parameters." << std::endl;
- std::cerr << "This binary needs an ID of a configured Firestore instance "
- "to run along with access credentials. "
- << std::endl;
- std::cerr << "Please set the GN argument " << kGnCredentialsPathArg
- << " at build time to embed the credentials in the binary "
- << " or pass " << kCredentialsPathFlag
- << " at run time to override the default location" << std::endl;
- std::cerr << "If you're running it from a .tspec file, make sure "
- "you add --append-args=\""
- "--"
- << kCredentialsPathFlag << "=<file path>" << std::endl;
- std::cerr << "if the access credentials are not embedded in the binary "
- << "at build." << std::endl;
-}
-
-// Fetches the sync credentials from the network. This method is synchronous and
-// blocks until credentials are retrieved. This is intended exclusively for
-// infra bots that will expose the credentials over the network when running
-// sync tests.
-bool FetchCredentials(component::StartupContext* startup_context,
- std::string* credentials_path, std::string* credentials) {
- *credentials_path = kCredentialsFetchUrl.ToString();
-
- fidl::SynchronousInterfacePtr<http::HttpService> network_service;
- startup_context->ConnectToEnvironmentService(network_service.NewRequest());
- fidl::SynchronousInterfacePtr<http::URLLoader> url_loader;
-
- zx_status_t status =
- network_service->CreateURLLoader(url_loader.NewRequest());
- if (status != ZX_OK) {
- FXL_LOG(WARNING) << "Unable to retrieve an URLLoader.";
- return false;
- }
-
- http::URLRequest request;
- request.method = "GET";
- request.url = kCredentialsFetchUrl.ToString();
- request.response_body_mode = http::ResponseBodyMode::BUFFER;
- http::URLResponse response;
-
- status = url_loader->Start(std::move(request), &response);
- if (status != ZX_OK) {
- FXL_LOG(WARNING) << "Unable to start the network request.";
- return false;
- }
-
- if (response.error) {
- FXL_LOG(ERROR) << "Net error " << response.error->code << ": "
- << response.error->description;
- return false;
- }
-
- if (response.status_code != 200) {
- FXL_LOG(ERROR) << "Unexpected HTTP status code: " << response.status_code;
- return false;
- }
-
- return fsl::StringFromVmo(response.body->buffer(), credentials);
-}
-
-// Extracts the credentials content. This function will return |true| if it
-// finds the credentials in either:
-// - The command line
-// - The default location in the running package
-// - Over the network.
-// In that case, |credentials| will contain the content of the credentials file
-// and |credentials_path| the path to the file.
-// If it cannot find the credentials, this function will return |false|, and
-// |credentials_path| will contain the path of the last tried location.
-bool GetCredentialsContent(const fxl::CommandLine& command_line,
- component::StartupContext* startup_context,
- std::string* credentials_path,
- std::string* credentials) {
- if (command_line.GetOptionValue(kCredentialsPathFlag.ToString(),
- credentials_path)) {
- return files::ReadFileToString(*credentials_path, credentials);
- }
- *credentials_path = kCredentialsDefaultPath.ToString();
- if (files::IsFile(*credentials_path)) {
- return files::ReadFileToString(*credentials_path, credentials);
- }
-
- return FetchCredentials(startup_context, credentials_path, credentials);
-}
-
-std::string Hash(fxl::StringView data) {
- char result[SHA256_DIGEST_LENGTH];
- SHA256_CTX sha256;
- SHA256_Init(&sha256);
- SHA256_Update(&sha256, data.data(), data.size());
- SHA256_Final(reinterpret_cast<uint8_t*>(result), &sha256);
- return convert::ToHex(fxl::StringView(result, SHA256_DIGEST_LENGTH));
-}
-
-} // namespace
-
-namespace ledger {
-
-SyncParams::SyncParams() = default;
-
-SyncParams::SyncParams(SyncParams&& other) = default;
-
-SyncParams::SyncParams(const SyncParams& other) { *this = other; }
-
-SyncParams& SyncParams::operator=(SyncParams&& other) = default;
-
-SyncParams& SyncParams::operator=(const SyncParams& other) {
- api_key = other.api_key;
- if (other.credentials) {
- credentials = other.credentials->Clone();
- }
- return *this;
-}
-
-std::string GetSyncParamsUsage() {
- std::ostringstream result;
- result << " [--" << kCredentialsPathFlag << "=<file path>]";
- return result.str();
-}
-
-std::string ExtractJsonObject(const std::string& content) {
- auto start = content.find('{');
- auto end = content.rfind('}');
- if (start != std::string::npos && end != std::string::npos && start < end) {
- return content.substr(start, end + 1 - start);
- }
- return "";
-}
-
-bool ParseSyncParamsFromCommandLine(const fxl::CommandLine& command_line,
- component::StartupContext* startup_context,
- SyncParams* sync_params) {
- std::string credentials;
- std::string credentials_path;
- if (!GetCredentialsContent(command_line, startup_context, &credentials_path,
- &credentials)) {
- std::cerr << "Cannot access " << credentials_path << std::endl;
- WarnIncorrectSyncParams();
- return false;
- }
-
- FXL_LOG(INFO) << "Sync credentials sha256: " << Hash(credentials);
-
- rapidjson::Document document;
- document.Parse(credentials);
- if (document.HasParseError()) {
- std::cerr << "Cannot parse sync parameters at " << credentials_path
- << std::endl;
- // TODO(qsr): NET-1636 Remove this code once the network service handles
- // chunked encoding. Extract the content of credentials from the first '{'
- // to the last '}' to work around the network service not handling chunked
- // encoding.
- std::cerr << "Trying to extract a JSON object." << std::endl;
- credentials = ExtractJsonObject(credentials);
- if (credentials.empty()) {
- return false;
- }
- document.Parse(credentials);
- if (document.HasParseError()) {
- return false;
- }
- }
- auto sync_params_schema = json_schema::InitSchema(kSyncParamsSchema);
- if (!json_schema::ValidateSchema(document, *sync_params_schema)) {
- std::cerr << "Invalid schema at " << credentials_path << std::endl;
- return false;
- }
-
- sync_params->api_key = document["api-key"].GetString();
- sync_params->credentials =
- service_account::Credentials::Parse(document["service-account"]);
- if (!sync_params->credentials) {
- std::cerr << "Cannot parse credentials at " << credentials_path
- << std::endl;
- return false;
- }
- return true;
-}
-
-std::set<std::string> GetSyncParamFlags() {
- return {kCredentialsPathFlag.ToString()};
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/sync_params.gni b/bin/ledger/testing/sync_params.gni
deleted file mode 100644
index 501a99a..0000000
--- a/bin/ledger/testing/sync_params.gni
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-declare_args() {
- ledger_sync_credentials_file = ""
-}
diff --git a/bin/ledger/testing/sync_params.h b/bin/ledger/testing/sync_params.h
deleted file mode 100644
index 3aeb400..0000000
--- a/bin/ledger/testing/sync_params.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_SYNC_PARAMS_H_
-#define PERIDOT_BIN_LEDGER_TESTING_SYNC_PARAMS_H_
-
-#include <set>
-#include <string>
-
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/lib/firebase_auth/testing/credentials.h"
-
-namespace ledger {
-
-// Parameters needed to configure synchronization against a real server.
-struct SyncParams {
- SyncParams();
- SyncParams(const SyncParams& other);
- SyncParams(SyncParams&& other);
- SyncParams& operator=(const SyncParams& other);
- SyncParams& operator=(SyncParams&& other);
-
- // API key used to access the database.
- std::string api_key;
-
- // Credentials for the cloud service.
- std::unique_ptr<service_account::Credentials> credentials;
-};
-
-// Returns a string listing the command-line parameters which need to be
-// provided for a benchmark to connect to a cloud server.
-std::string GetSyncParamsUsage();
-
-// Reads the sync parameters from the command-line. Prints a warning and returns
-// false if these parameters are missing or cannot be parsed.
-bool ParseSyncParamsFromCommandLine(const fxl::CommandLine& command_line,
- component::StartupContext* startup_context,
- SyncParams* sync_params);
-
-// Returns the names of the flags parsed from the command line by
-// ParseSyncParamsFromCommandLine(), without the leading "--".
-std::set<std::string> GetSyncParamFlags();
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_SYNC_PARAMS_H_
diff --git a/bin/ledger/testing/test_with_environment.cc b/bin/ledger/testing/test_with_environment.cc
deleted file mode 100644
index 5a19b73..0000000
--- a/bin/ledger/testing/test_with_environment.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/test_with_environment.h"
-
-#include <lib/component/cpp/testing/startup_context_for_test.h>
-#include <lib/fit/function.h>
-#include <lib/timekeeper/test_loop_test_clock.h>
-
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-
-namespace {
-
-// Wrapper around a real CoroutineHandler for test.
-//
-// The wrapper allows to delay re-entering the coroutine body when the run loop
-// is running. When |Resume| is called, it quits the loop, and the main method
-// calls |ResumeIfNeeded| when the loop exits.
-class TestCoroutineHandler : public coroutine::CoroutineHandler {
- public:
- explicit TestCoroutineHandler(coroutine::CoroutineHandler* delegate,
- fit::closure quit_callback)
- : delegate_(delegate), quit_callback_(std::move(quit_callback)) {}
-
- coroutine::ContinuationStatus Yield() override { return delegate_->Yield(); }
-
- void Resume(coroutine::ContinuationStatus status) override {
- // If interrupting, no need to delay the call as the test will not run the
- // loop itself.
- if (status == coroutine::ContinuationStatus::INTERRUPTED) {
- delegate_->Resume(status);
- return;
- }
- quit_callback_();
- need_to_continue_ = true;
- }
-
- // Re-enters the coroutine body if the handler delayed the call.
- void ResumeIfNeeded() {
- if (need_to_continue_) {
- need_to_continue_ = false;
- delegate_->Resume(coroutine::ContinuationStatus::OK);
- }
- }
-
- private:
- std::unique_ptr<component::StartupContext> startup_context_;
- coroutine::CoroutineHandler* delegate_;
- fit::closure quit_callback_;
- bool need_to_continue_ = false;
-};
-
-} // namespace
-
-TestWithEnvironment::TestWithEnvironment()
- : startup_context_(component::testing::StartupContextForTest::Create()),
- environment_(
- EnvironmentBuilder()
- .SetAsync(dispatcher())
- .SetIOAsync(dispatcher())
- .SetStartupContext(startup_context_.get())
- .SetClock(
- std::make_unique<timekeeper::TestLoopTestClock>(&test_loop()))
- .SetRandom(std::make_unique<rng::TestRandom>(
- test_loop().initial_state()))
- .Build()) {}
-
-void TestWithEnvironment::RunInCoroutine(
- fit::function<void(coroutine::CoroutineHandler*)> run_test) {
- std::unique_ptr<TestCoroutineHandler> test_handler;
- volatile bool ended = false;
- environment_.coroutine_service()->StartCoroutine(
- [&](coroutine::CoroutineHandler* handler) {
- test_handler = std::make_unique<TestCoroutineHandler>(
- handler, [this] { QuitLoop(); });
- run_test(test_handler.get());
- ended = true;
- });
- while (!ended) {
- test_handler->ResumeIfNeeded();
- RunLoopUntilIdle();
- }
-}
-
-} // namespace ledger
diff --git a/bin/ledger/testing/test_with_environment.h b/bin/ledger/testing/test_with_environment.h
deleted file mode 100644
index 6e8a38c..0000000
--- a/bin/ledger/testing/test_with_environment.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTING_TEST_WITH_ENVIRONMENT_H_
-#define PERIDOT_BIN_LEDGER_TESTING_TEST_WITH_ENVIRONMENT_H_
-
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/ledger/coroutine/coroutine_impl.h"
-#include "peridot/bin/ledger/environment/environment.h"
-
-namespace ledger {
-
-class TestWithEnvironment : public gtest::TestLoopFixture {
- public:
- TestWithEnvironment();
-
- protected:
- // Runs the given test code in a coroutine.
- void RunInCoroutine(
- fit::function<void(coroutine::CoroutineHandler*)> run_test);
-
- std::unique_ptr<component::StartupContext> startup_context_;
- Environment environment_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(TestWithEnvironment);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTING_TEST_WITH_ENVIRONMENT_H_
diff --git a/bin/ledger/tests/benchmark/BUILD.gn b/bin/ledger/tests/benchmark/BUILD.gn
deleted file mode 100644
index 34ed4dd..0000000
--- a/bin/ledger/tests/benchmark/BUILD.gn
+++ /dev/null
@@ -1,292 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-import("//peridot/bin/ledger/testing/sync_params.gni")
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-package("ledger_benchmarks") {
- testonly = true
-
- deps = [
- "//peridot/bin/ledger/tests/benchmark/backlog",
- "//peridot/bin/ledger/tests/benchmark/convergence",
- "//peridot/bin/ledger/tests/benchmark/delete_entry",
- "//peridot/bin/ledger/tests/benchmark/disk_space",
- "//peridot/bin/ledger/tests/benchmark/fetch",
- "//peridot/bin/ledger/tests/benchmark/get_page",
- "//peridot/bin/ledger/tests/benchmark/put",
- "//peridot/bin/ledger/tests/benchmark/sync",
- "//peridot/bin/ledger/tests/benchmark/update_entry",
- ]
-
- meta = [
- {
- path = rebase_path("backlog/backlog.cmx")
- dest = "backlog.cmx"
- },
- {
- path = rebase_path("get_page/get_page.cmx")
- dest = "get_page.cmx"
- },
- {
- path = rebase_path("delete_entry/delete_entry.cmx")
- dest = "delete_entry.cmx"
- },
- {
- path = rebase_path("disk_space/disk_space.cmx")
- dest = "disk_space.cmx"
- },
- {
- path = rebase_path("convergence/convergence.cmx")
- dest = "convergence.cmx"
- },
- {
- path = rebase_path("fetch/fetch.cmx")
- dest = "fetch.cmx"
- },
- {
- path = rebase_path("put/put.cmx")
- dest = "put.cmx"
- },
- {
- path = rebase_path("sync/sync.cmx")
- dest = "sync.cmx"
- },
- {
- path = rebase_path("update_entry/update_entry.cmx")
- dest = "update_entry.cmx"
- },
- ]
-
- binaries = [
- {
- name = "ledger_benchmark_backlog"
- },
-
- {
- name = "ledger_benchmark_get_page"
- },
-
- {
- name = "ledger_benchmark_delete_entry"
- },
-
- {
- name = "ledger_benchmark_disk_space"
- },
-
- {
- name = "ledger_benchmark_convergence"
- },
-
- {
- name = "ledger_benchmark_fetch"
- },
-
- {
- name = "ledger_benchmark_put"
- },
-
- {
- name = "ledger_benchmark_sync"
- },
-
- {
- name = "ledger_benchmark_update_entry"
- },
- ]
-
- resources = [
- {
- path = rebase_path("get_page/add_new_page.tspec")
- dest = "add_new_page.tspec"
- },
-
- {
- path = rebase_path("get_page/add_new_page_precached.tspec")
- dest = "add_new_page_precached.tspec"
- },
-
- {
- path = rebase_path("backlog/backlog.tspec")
- dest = "backlog.tspec"
- },
-
- {
- path = rebase_path("backlog/backlog_big_entry.tspec")
- dest = "backlog_big_entry.tspec"
- },
-
- {
- path = rebase_path("backlog/backlog_big_entry_updates.tspec")
- dest = "backlog_big_entry_updates.tspec"
- },
-
- {
- path = rebase_path("backlog/backlog_many_big_entries.tspec")
- dest = "backlog_many_big_entries.tspec"
- },
-
- {
- path = rebase_path("backlog/backlog_many_small_entries.tspec")
- dest = "backlog_many_small_entries.tspec"
- },
-
- {
- path = rebase_path("backlog/backlog_small_entry_updates.tspec")
- dest = "DISABLED_backlog_small_entry_updates.tspec"
- },
-
- {
- path = rebase_path("delete_entry/disk_space_cleared_page.tspec")
- dest = "disk_space_cleared_page.tspec"
- },
-
- {
- path = rebase_path("disk_space/entries.tspec")
- dest = "disk_space_entries.tspec"
- },
-
- {
- path = rebase_path("disk_space/empty_ledger.tspec")
- dest = "disk_space_empty_ledger.tspec"
- },
-
- {
- path = rebase_path("disk_space/empty_pages.tspec")
- dest = "disk_space_empty_pages.tspec"
- },
-
- {
- path = rebase_path("disk_space/small_keys.tspec")
- dest = "disk_space_small_keys.tspec"
- },
-
- {
- path = rebase_path("disk_space/one_commit_per_entry.tspec")
- dest = "disk_space_one_commit_per_entry.tspec"
- },
-
- {
- path = rebase_path("backlog/disk_space_synced_updates.tspec")
- dest = "disk_space_synced_updates.tspec"
- },
-
- {
- path = rebase_path("backlog/disk_space_synced_entries.tspec")
- dest = "disk_space_synced_entries.tspec"
- },
-
- {
- path = rebase_path("backlog/disk_space_synced_entries_small_keys.tspec")
- dest = "disk_space_synced_entries_small_keys.tspec"
- },
-
- {
- path = rebase_path("disk_space/updates.tspec")
- dest = "disk_space_updates.tspec"
- },
-
- {
- path = rebase_path("get_page/get_same_page.tspec")
- dest = "get_same_page.tspec"
- },
-
- {
- path = rebase_path("get_page/get_page_id.tspec")
- dest = "get_page_id.tspec"
- },
-
- {
- path = rebase_path("convergence/convergence.tspec")
- dest = "convergence.tspec"
- },
-
- {
- path = rebase_path("convergence/multidevice_convergence.tspec")
- dest = "multidevice_convergence.tspec"
- },
-
- {
- path = rebase_path("put/transaction.tspec")
- dest = "transaction.tspec"
- },
-
- {
- path = rebase_path("put/put.tspec")
- dest = "put.tspec"
- },
-
- {
- path = rebase_path("put/put_big_entry.tspec")
- dest = "put_big_entry.tspec"
- },
-
- {
- path = rebase_path("put/put_as_reference.tspec")
- dest = "put_as_reference.tspec"
- },
-
- {
- path = rebase_path("sync/sync.tspec")
- dest = "sync.tspec"
- },
-
- {
- path = rebase_path("sync/sync_big_change.tspec")
- dest = "sync_big_change.tspec"
- },
-
- {
- path = rebase_path("update_entry/update_entry.tspec")
- dest = "update_entry.tspec"
- },
-
- {
- path = rebase_path("update_entry/update_big_entry.tspec")
- dest = "update_big_entry.tspec"
- },
-
- {
- path = rebase_path("update_entry/update_entry_transactions.tspec")
- dest = "update_entry_transactions.tspec"
- },
-
- {
- path = rebase_path("fetch/fetch.tspec")
- dest = "fetch.tspec"
- },
-
- {
- path = rebase_path("fetch/fetch_partial_big_entry.tspec")
- dest = "fetch_partial_big_entry.tspec"
- },
-
- {
- path = rebase_path("delete_entry/delete_entry.tspec")
- dest = "delete_entry.tspec"
- },
-
- {
- path = rebase_path("delete_entry/delete_entry_transactions.tspec")
- dest = "delete_entry_transactions.tspec"
- },
-
- {
- path = rebase_path("delete_entry/delete_big_entry.tspec")
- dest = "delete_big_entry.tspec"
- },
- ]
-
- if (ledger_sync_credentials_file != "") {
- resources += [
- {
- path = ledger_sync_credentials_file
- dest = "sync_credentials.json"
- },
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/README.md b/bin/ledger/tests/benchmark/README.md
deleted file mode 100644
index d8bf09b..0000000
--- a/bin/ledger/tests/benchmark/README.md
+++ /dev/null
@@ -1,164 +0,0 @@
-# benchmark
-
-## Overview
-This directory contains Ledger [trace-based benchmarks]. Each benchmark is
-implemented as a client connected to Ledger and using its API to perform one or
-more of its basic operations (creating a page, writing/deleting entries, ...).
-
-## Run benchmarks
-
-### Using trace spec files
-The easiest way to run a benchmark is using the associated trace spec file,
-for example:
-
-```
-trace record --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/put.tspec
-```
-
-You can read more on the trace spec file format in the [trace-based benchmarking
-guide](https://fuchsia.googlesource.com/docs/+/master/development/benchmarking/trace_based_benchmarking.md#specification-file).
-
-### Tracing benchmark apps directly
-You can also trace the app directly:
-
-```
-trace record --categories=benchmark,ledger \
- fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/put.cmx \
- --entry-count=10 --transaction-size=1 --key-size=100 --value-size=100 \
- --refs=off
-```
-
-That would generate a trace result file (default: `/data/trace.json`), which can
-be analysed manually or using special tools.
-
-### Benchmark parameters
-
-\*.tspec files specify the parameters with which benchmark apps are run. You can
-override these by passing the "--append-args" argument to the `trace record`
-tool.
-Commonly used among all the ledger benchmarks are the following parameters:
-
-* `entry-count` for the number of entries to perform operations on
-* `unique-key-count` if the number of operations and the number of entries
- differ (i.e. some entries are overwritten), this denotes the number of unique
- entries in the page
-* `key-size` for the size of the key (in bytes)
-* `value-size` for the size of the value (in bytes)
-* `refs` with the values `on` or `off` for the reference strategy: if set to
- `on`, entries will be put using `CreateReference`/`PutAsReference`, otherwise
- they will be treated as inline entries.
-* `commit-count` for the number of commits made to the page
-* `transaction-size` for the number of operations in a single transaction
-
-Unless the name of the benchmark suggest otherwise, default values are:
-* `100` entries
-* key size `100`
-* value size `1000`
-Benchmarks under `sync` and `convergence` use smaller number of entries and
-smaller value size.
-
-### Benchmarks using sync
-
-Some benchmarks exercise cloud synchronization using `cloud_provider_firestore`.
-
-To run these, follow the [cloud sync set-up instructions] to set up a Firestore instance,
-configure the build environment and obtain the sync parameters needed below.
-
-Then, run the selected benchmark as follows:
-
-```sh
-trace record --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/sync.tspec
-```
-
-### A note regarding benchmark apps
-Since the benchmark apps are designed to be used with tracing, running them
-without a tracing will not generate any results.
-
-## List of benchmarks
-
-Some of the benchmark apps have several corresponding tspec files, to exercise
-different possible scenarios of using Ledger. For example, `get_page` benchmark
-is used in `add_new_page.tspec` to emulate creating many pages with different
-IDs, and in `get_same_page.tspec` to create several connections to the same
-page.
-
-### Local benchmarks
-* __Get page__: How long does it take to establish a new page connection?
- * `add_new_page.tspec`: connection to the new page with previously unused
- ID.
- * `add_new_page_precached.tspec`: same as above, but waits for a precached
- Ledger Page to be ready before each request.
- * `get_same_page.tspec`: several connections to the same page
- * `get_page_id.tspec`: how long does the GetId() call takes on a newly
- created page?
-* __Put__: How long does it take to write data to a page? And how long before the
- client will receive a [PageWatcher notification] about its own change?
- * `put.tspec`: basic case
- * `put_big_entry.tspec`: writing big entries to the page
- * `put_as_reference.tspec`: entries are put as references (CreateReference +
- PutReference)
- * `transaction.tspec`: changes are made in a transaction
-* __Update entry__: How long does it take to update an existing value in Ledger
- (make several Put operations with the same key, but different values)?
- * `update_entry.tspec`: basic case
- * `update_big_entry.tspec`: put an entry of big size, then update its value
- * `update_entry_transactions.tspec`: changes are grouped in transactions
-* __Delete entry__: How long does it take to delete an entry from a page?
- * `delete_entry.tspec`: each entry is deleted separately (outside of a
- transaction)
- * `delete_big_entry.tspec`: same as above, but for big entries
- * `delete_entry_transactions.tspec`: deletions are grouped in transactions
- * `disk_space_cleared_page.tspec`: how much space does ledger take after the
- page was cleared out (all the entries deleted in one transaction)?
-* __Disk space__: How much disk space does ledger use to store pages, objects
- and commits?
- * `disk_space_empty_ledger.tspec`: empty ledger (with no pages)
- * `disk_space_empty_pages.tspec`: ledger containing only empty pages
- * `disk_space_entries.tspec`: ledger with one page containing some entries
- * `disk_space_small_keys.tspec`: same, but with small (10 bytes) keys.
- * `disk_space_updates.tspec`: ledger with one page containing only one
- entry, but long commit history
- * `disk_space_one_commit_per_entry.tspec`: ledger with one page containing
- several entries, each of them added in a separate commit
-
-### Sync benchmarks
-These benchmarks exercise synchronisation and need an ID of a Firestore instance
-passed to them as described [in a previous
-section](README.md#benchmarks-using-sync).
-
-* __Backlog__: How long does it take to download all existing data when
- establishing a new connection to an already populated data?
- * `backlog.tspec`: basic case
- * `backlog_big_entry.tspec`: page contains one entry, but of a big size
- * `backlog_big_entry_updates.tspec`: one big entry, but that was updated several
- times prior to the new connection (commit history)
- * `backlog_many_big_entries.tspec`: page contains several big entries
- * `backlog_many_small_entries.tspec`: many small entries
- * `backlog_small_entry_updates.tspec`: small entry, but a long commit
- history
- * `disk_space_synced_entries.tspec`: how much disk space does ledger take on a
- writer and a reader device, when several entries have been written (in one
- commit) on one device and then downloaded on another?
- * `disk_space_synced_entries_small_keys.tspec`: same, but with small (10
- bytes) keys.
- * `disk_space_synced_updates.tspec`: how much disk space does ledger take on a
- writer and a reader device, when several commits with updates has been made on
- one device and then downloaded on another?
-* __Convergence__: Several devices make concurrent changes to the page. How long does
- it take for all devices to see each other changes?
- * `convergence.tspec`: two devices
- * `multidevice_convergence`: several devices
-* __Fetch__: How long does it take to fetch a [lazy value]?
- * `fetch.tspec`: basic case
- * `fetch_partial_big_entry.tspec`: using FetchPartial (fetch in several
- parts) on a big entry
-* __Sync__: When one device makes changes to the page, how long does it take for
- another one to receive these changes?
- * `sync.tspec`: basic case
- * `sync_big_change.tspec`: syncing a big change (containing several write
- operations)
-
-[trace-based benchmarks]: https://fuchsia.googlesource.com/docs/+/master/development/benchmarking/trace_based_benchmarking.md
-[cloud sync set-up instructions]: /docs/ledger/testing.md#cloud-sync
-[lazy value]: /docs/ledger/api_guide.md#lazy-values
-[PageWatcher notification]: /docs/ledger/api_guide.md#watch
diff --git a/bin/ledger/tests/benchmark/backlog/BUILD.gn b/bin/ledger/tests/benchmark/backlog/BUILD.gn
deleted file mode 100644
index 73d4820..0000000
--- a/bin/ledger/tests/benchmark/backlog/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("backlog") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_backlog",
- ]
-}
-
-executable("ledger_benchmark_backlog") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/cloud_provider_firestore/testing",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "backlog.cc",
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/backlog.cc b/bin/ledger/tests/benchmark/backlog/backlog.cc
deleted file mode 100644
index 2a6f8ec..0000000
--- a/bin/ledger/tests/benchmark/backlog/backlog.cc
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-#include <vector>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/callback/waiter.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <trace/event.h>
-
-#include "peridot/bin/cloud_provider_firestore/testing/cloud_provider_factory.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/filesystem/get_directory_content_size.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/page_data_generator.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/bin/ledger/testing/sync_params.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-
-namespace {
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx";
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/backlog";
-constexpr fxl::StringView kUniqueKeyCountFlag = "unique-key-count";
-constexpr fxl::StringView kKeySizeFlag = "key-size";
-constexpr fxl::StringView kValueSizeFlag = "value-size";
-constexpr fxl::StringView kCommitCountFlag = "commit-count";
-constexpr fxl::StringView kRefsFlag = "refs";
-constexpr fxl::StringView kRefsOnFlag = "on";
-constexpr fxl::StringView kRefsOffFlag = "off";
-
-const std::string kUserDirectory = "/backlog_user";
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kUniqueKeyCountFlag << "=<int>"
- << " --" << kKeySizeFlag << "=<int>"
- << " --" << kValueSizeFlag << "=<int>"
- << " --" << kCommitCountFlag << "=<int>"
- << " --" << kRefsFlag << "=(" << kRefsOnFlag << "|" << kRefsOffFlag
- << ")" << GetSyncParamsUsage() << std::endl;
-}
-
-// Benchmark that measures time taken by a page connection to upload all local
-// changes to the cloud; and for another connection to the same page to download
-// all these changes.
-//
-// In contrast to the sync benchmark, backlog benchmark initiates the second
-// connection only after the first one has uploaded all changes. It is designed
-// to model the situation of adding new device instead of continuous
-// synchronisation.
-//
-// Cloud sync needs to be configured on the device in order for the benchmark to
-// run.
-//
-// Parameters:
-// --unique-key-count=<int> the number of unique keys to populate the page
-// with.
-// --key-size=<int> size of a key for each entry.
-// --value-size=<int> the size of values to populate the page with.
-// --commit-count=<int> the number of commits made to the page.
-// If this number is smaller than unique-key-count, changes will be bundled
-// into transactions. If it is bigger, some or all of the changes will use the
-// same keys, modifying the value.
-// --refs=(on|off) reference strategy: on to put values as references, off to
-// put them as FIDL arrays.
-// --credentials-path=<file path> Firestore service account credentials
-class BacklogBenchmark : public SyncWatcher {
- public:
- BacklogBenchmark(async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t unique_key_count, size_t key_size, size_t value_size,
- size_t commit_count,
- PageDataGenerator::ReferenceStrategy reference_strategy,
- SyncParams sync_params);
-
- void Run();
-
- // SyncWatcher:
- void SyncStateChanged(SyncState download, SyncState upload,
- SyncStateChangedCallback callback) override;
-
- private:
- void ConnectWriter();
- void Populate();
- void DisconnectAndRecordWriter();
- void ConnectUploader();
- void WaitForUploaderUpload();
- void ConnectReader();
- void WaitForReaderDownload();
-
- void GetReaderSnapshot();
- void GetEntriesStep(std::unique_ptr<Token> token, size_t entries_left);
- void CheckStatusAndGetMore(Status status, size_t entries_left,
- std::unique_ptr<Token> next_token);
-
- void RecordDirectorySize(const std::string& event_name,
- const std::string& path);
- void ShutDown();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- DataGenerator generator_;
- PageDataGenerator page_data_generator_;
- std::unique_ptr<component::StartupContext> startup_context_;
- cloud_provider_firestore::CloudProviderFactory cloud_provider_factory_;
- fidl::Binding<SyncWatcher> sync_watcher_binding_;
- const size_t unique_key_count_;
- const size_t key_size_;
- const size_t value_size_;
- const size_t commit_count_;
- const PageDataGenerator::ReferenceStrategy reference_strategy_;
- const cloud_provider_firestore::CloudProviderFactory::UserId user_id_;
- files::ScopedTempDir writer_tmp_dir_;
- files::ScopedTempDir reader_tmp_dir_;
- fuchsia::sys::ComponentControllerPtr writer_controller_;
- fuchsia::sys::ComponentControllerPtr uploader_controller_;
- fuchsia::sys::ComponentControllerPtr reader_controller_;
- LedgerPtr uploader_;
- LedgerPtr writer_;
- LedgerPtr reader_;
- PageId page_id_;
- PagePtr writer_page_;
- PagePtr uploader_page_;
- PagePtr reader_page_;
- PageSnapshotPtr reader_snapshot_;
- fit::function<void(SyncState, SyncState)> on_sync_state_changed_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(BacklogBenchmark);
-};
-
-BacklogBenchmark::BacklogBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t unique_key_count, size_t key_size, size_t value_size,
- size_t commit_count,
- PageDataGenerator::ReferenceStrategy reference_strategy,
- SyncParams sync_params)
- : loop_(loop),
- random_(0),
- generator_(&random_),
- page_data_generator_(&random_),
- startup_context_(std::move(startup_context)),
- cloud_provider_factory_(startup_context_.get(), &random_,
- std::move(sync_params.api_key),
- std::move(sync_params.credentials)),
- sync_watcher_binding_(this),
- unique_key_count_(unique_key_count),
- key_size_(key_size),
- value_size_(value_size),
- commit_count_(commit_count),
- reference_strategy_(reference_strategy),
- user_id_(cloud_provider_firestore::CloudProviderFactory::UserId::New()),
- writer_tmp_dir_(kStoragePath),
- reader_tmp_dir_(kStoragePath) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(unique_key_count_ > 0);
- FXL_DCHECK(key_size_ > 0);
- FXL_DCHECK(value_size_ > 0);
- FXL_DCHECK(commit_count_ > 0);
- cloud_provider_factory_.Init();
-}
-
-void BacklogBenchmark::SyncStateChanged(SyncState download, SyncState upload,
- SyncStateChangedCallback callback) {
- if (on_sync_state_changed_) {
- on_sync_state_changed_(download, upload);
- }
- callback();
-}
-
-void BacklogBenchmark::Run() { ConnectWriter(); }
-
-void BacklogBenchmark::ConnectWriter() {
- // Name of the storage directory currently identifies the user. Ensure the
- // most nested directory has the same name to make the ledgers sync.
- std::string writer_path = writer_tmp_dir_.path() + kUserDirectory;
- bool ret = files::CreateDirectory(writer_path);
- FXL_DCHECK(ret);
-
- Status status = GetLedger(
- startup_context_.get(), writer_controller_.NewRequest(), nullptr, "",
- "backlog", DetachedPath(std::move(writer_path)),
-
- []() { FXL_LOG(INFO) << "Writer closed."; }, &writer_);
- if (QuitOnError(QuitLoopClosure(), status, "Get writer ledger")) {
- return;
- }
-
- GetPageEnsureInitialized(
- &writer_, nullptr, DelayCallback::YES,
- []() { FXL_LOG(INFO) << "Writer page closed."; },
- [this](Status status, PagePtr writer_page, PageId page_id) {
- if (QuitOnError(QuitLoopClosure(), status,
- "Writer page initialization")) {
- return;
- }
-
- writer_page_ = std::move(writer_page);
- page_id_ = page_id;
-
- TRACE_ASYNC_BEGIN("benchmark", "populate", 0);
- Populate();
- });
-}
-
-void BacklogBenchmark::Populate() {
- int transaction_size = static_cast<int>(
- ceil(static_cast<double>(unique_key_count_) / commit_count_));
- int key_count = std::max(unique_key_count_, commit_count_);
- FXL_LOG(INFO) << "Transaction size: " << transaction_size
- << ", key count: " << key_count << ".";
- auto keys = generator_.MakeKeys(key_count, key_size_, unique_key_count_);
- page_data_generator_.Populate(
- &writer_page_, std::move(keys), value_size_, transaction_size,
- reference_strategy_, Priority::EAGER, [this](Status status) {
- if (status != Status::OK) {
- if (QuitOnError(QuitLoopClosure(), status,
- "PageGenerator::Populate")) {
- return;
- }
- return;
- }
- TRACE_ASYNC_END("benchmark", "populate", 0);
- DisconnectAndRecordWriter();
- });
-}
-
-void BacklogBenchmark::DisconnectAndRecordWriter() {
- KillLedgerProcess(&writer_controller_);
- RecordDirectorySize("writer_directory_size", writer_tmp_dir_.path());
- ConnectUploader();
-}
-
-void BacklogBenchmark::ConnectUploader() {
- // Name of the storage directory currently identifies the user. Ensure the
- // most nested directory has the same name to make the ledgers sync.
- std::string uploader_path = writer_tmp_dir_.path() + kUserDirectory;
-
- cloud_provider::CloudProviderPtr cloud_provider_uploader;
- cloud_provider_factory_.MakeCloudProvider(
- user_id_, cloud_provider_uploader.NewRequest());
- Status status = GetLedger(
- startup_context_.get(), uploader_controller_.NewRequest(),
- std::move(cloud_provider_uploader), user_id_.user_id(), "backlog",
- DetachedPath(std::move(uploader_path)), QuitLoopClosure(), &uploader_);
- if (QuitOnError(QuitLoopClosure(), status, "Get uploader ledger")) {
- return;
- }
-
- TRACE_ASYNC_BEGIN("benchmark", "get_uploader_page", 0);
- TRACE_ASYNC_BEGIN("benchmark", "upload", 0);
- uploader_->GetPage(fidl::MakeOptional(page_id_), uploader_page_.NewRequest(),
- [this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "GetPage")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "get_uploader_page", 0);
- WaitForUploaderUpload();
- });
-}
-
-void BacklogBenchmark::WaitForUploaderUpload() {
- on_sync_state_changed_ = [this](SyncState download, SyncState upload) {
- if (upload == SyncState::IDLE) {
- on_sync_state_changed_ = nullptr;
- TRACE_ASYNC_END("benchmark", "upload", 0);
- // Stop watching sync state for this page.
- sync_watcher_binding_.Unbind();
- ConnectReader();
- return;
- }
- };
- uploader_page_->SetSyncStateWatcher(
- sync_watcher_binding_.NewBinding(),
- QuitOnErrorCallback(QuitLoopClosure(), "Page::SetSyncStateWatcher"));
-}
-
-void BacklogBenchmark::ConnectReader() {
- std::string reader_path = reader_tmp_dir_.path() + kUserDirectory;
- bool ret = files::CreateDirectory(reader_path);
- FXL_DCHECK(ret);
-
- cloud_provider::CloudProviderPtr cloud_provider_reader;
- cloud_provider_factory_.MakeCloudProvider(user_id_,
- cloud_provider_reader.NewRequest());
- Status status = GetLedger(
- startup_context_.get(), reader_controller_.NewRequest(),
- std::move(cloud_provider_reader), user_id_.user_id(), "backlog",
- DetachedPath(std::move(reader_path)), QuitLoopClosure(), &reader_);
- if (QuitOnError(QuitLoopClosure(), status, "ConnectReader")) {
- return;
- }
-
- TRACE_ASYNC_BEGIN("benchmark", "download", 0);
- TRACE_ASYNC_BEGIN("benchmark", "get_reader_page", 0);
- reader_->GetPage(fidl::MakeOptional(page_id_), reader_page_.NewRequest(),
- [this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "GetPage")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "get_reader_page", 0);
- WaitForReaderDownload();
- });
-}
-
-void BacklogBenchmark::WaitForReaderDownload() {
- on_sync_state_changed_ = [this](SyncState download, SyncState upload) {
- if (download == SyncState::IDLE) {
- on_sync_state_changed_ = nullptr;
- TRACE_ASYNC_END("benchmark", "download", 0);
- GetReaderSnapshot();
- return;
- }
- };
- reader_page_->SetSyncStateWatcher(
- sync_watcher_binding_.NewBinding(),
- QuitOnErrorCallback(QuitLoopClosure(), "Page::SetSyncStateWatcher"));
-}
-
-void BacklogBenchmark::GetReaderSnapshot() {
- reader_page_->GetSnapshot(
- reader_snapshot_.NewRequest(), fidl::VectorPtr<uint8_t>::New(0), nullptr,
- QuitOnErrorCallback(QuitLoopClosure(), "GetSnapshot"));
- TRACE_ASYNC_BEGIN("benchmark", "get_all_entries", 0);
- GetEntriesStep(nullptr, unique_key_count_);
-}
-
-void BacklogBenchmark::CheckStatusAndGetMore(
- Status status, size_t entries_left, std::unique_ptr<Token> next_token) {
- if ((status != Status::OK) && (status != Status::PARTIAL_RESULT)) {
- if (QuitOnError(QuitLoopClosure(), status, "PageSnapshot::GetEntries")) {
- return;
- }
- }
-
- if (status == Status::OK) {
- TRACE_ASYNC_END("benchmark", "get_all_entries", 0);
- FXL_DCHECK(entries_left == 0);
- FXL_DCHECK(!next_token);
- ShutDown();
- RecordDirectorySize("uploader_directory_size", writer_tmp_dir_.path());
- RecordDirectorySize("reader_directory_size", reader_tmp_dir_.path());
- return;
- }
- FXL_DCHECK(next_token);
- GetEntriesStep(std::move(next_token), entries_left);
-}
-
-void BacklogBenchmark::GetEntriesStep(std::unique_ptr<Token> token,
- size_t entries_left) {
- FXL_DCHECK(entries_left > 0);
- TRACE_ASYNC_BEGIN("benchmark", "get_entries_partial", entries_left);
- if (reference_strategy_ == PageDataGenerator::ReferenceStrategy::INLINE) {
- reader_snapshot_->GetEntriesInline(
- std::vector<uint8_t>(), std::move(token),
- [this, entries_left](Status status, auto entries,
- auto next_token) mutable {
- TRACE_ASYNC_END("benchmark", "get_entries_partial", entries_left);
- CheckStatusAndGetMore(status, entries_left - entries.size(),
- std::move(next_token));
- });
- } else {
- reader_snapshot_->GetEntries(
- std::vector<uint8_t>(), std::move(token),
- [this, entries_left](Status status, auto entries,
- auto next_token) mutable {
- TRACE_ASYNC_END("benchmark", "get_entries_partial", entries_left);
- CheckStatusAndGetMore(status, entries_left - entries.size(),
- std::move(next_token));
- });
- }
-}
-
-void BacklogBenchmark::RecordDirectorySize(const std::string& event_name,
- const std::string& path) {
- uint64_t tmp_dir_size = 0;
- FXL_CHECK(GetDirectoryContentSize(DetachedPath(path), &tmp_dir_size));
- TRACE_COUNTER("benchmark", event_name.c_str(), 0, "directory_size",
- TA_UINT64(tmp_dir_size));
-}
-
-void BacklogBenchmark::ShutDown() {
- KillLedgerProcess(&uploader_controller_);
- KillLedgerProcess(&reader_controller_);
- loop_->Quit();
-}
-
-fit::closure BacklogBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- std::string unique_key_count_str;
- size_t unique_key_count;
- std::string key_size_str;
- size_t key_size;
- std::string value_size_str;
- size_t value_size;
- std::string commit_count_str;
- size_t commit_count;
- std::string reference_strategy_str;
- SyncParams sync_params;
- if (!command_line.GetOptionValue(kUniqueKeyCountFlag.ToString(),
- &unique_key_count_str) ||
- !fxl::StringToNumberWithError(unique_key_count_str, &unique_key_count) ||
- unique_key_count <= 0 ||
- !command_line.GetOptionValue(kKeySizeFlag.ToString(), &key_size_str) ||
- !fxl::StringToNumberWithError(key_size_str, &key_size) || key_size == 0 ||
- !command_line.GetOptionValue(kValueSizeFlag.ToString(),
- &value_size_str) ||
- !fxl::StringToNumberWithError(value_size_str, &value_size) ||
- value_size <= 0 ||
- !command_line.GetOptionValue(kCommitCountFlag.ToString(),
- &commit_count_str) ||
- !fxl::StringToNumberWithError(commit_count_str, &commit_count) ||
- commit_count <= 0 ||
- !command_line.GetOptionValue(kRefsFlag.ToString(),
- &reference_strategy_str) ||
- !ParseSyncParamsFromCommandLine(command_line, startup_context.get(),
- &sync_params)) {
- PrintUsage();
- return -1;
- }
-
- PageDataGenerator::ReferenceStrategy reference_strategy;
- if (reference_strategy_str == kRefsOnFlag) {
- reference_strategy = PageDataGenerator::ReferenceStrategy::REFERENCE;
- } else if (reference_strategy_str == kRefsOffFlag) {
- reference_strategy = PageDataGenerator::ReferenceStrategy::INLINE;
- } else {
- std::cerr << "Unknown option " << reference_strategy_str << " for "
- << kRefsFlag.ToString() << std::endl;
- PrintUsage();
- return -1;
- }
-
- BacklogBenchmark app(&loop, std::move(startup_context), unique_key_count,
- key_size, value_size, commit_count, reference_strategy,
- std::move(sync_params));
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/backlog/backlog.cmx b/bin/ledger/tests/benchmark/backlog/backlog.cmx
deleted file mode 100644
index 55b43a2..0000000
--- a/bin/ledger/tests/benchmark/backlog/backlog.cmx
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_backlog"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/backlog/backlog.tspec b/bin/ledger/tests/benchmark/backlog/backlog.tspec
deleted file mode 100644
index c5d4ac5..0000000
--- a/bin/ledger/tests/benchmark/backlog/backlog.tspec
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=100", "--key-size=100", "--value-size=1000",
- "--commit-count=100", "--refs=off"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "duration",
- "event_name": "populate",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_uploader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "upload",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_reader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "download",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_entries_partial",
- "event_category": "benchmark",
- "split_first": true
- },
- {
- "type": "duration",
- "event_name": "get_all_entries",
- "event_category": "benchmark"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/backlog_big_entry.tspec b/bin/ledger/tests/benchmark/backlog/backlog_big_entry.tspec
deleted file mode 100644
index 82a6af4..0000000
--- a/bin/ledger/tests/benchmark/backlog/backlog_big_entry.tspec
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=1", "--key-size=100", "--value-size=10000000",
- "--commit-count=1", "--refs=on"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "duration",
- "event_name": "populate",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_uploader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "upload",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_reader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "download",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_all_entries",
- "event_category": "benchmark"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/backlog_big_entry_updates.tspec b/bin/ledger/tests/benchmark/backlog/backlog_big_entry_updates.tspec
deleted file mode 100644
index deb9832..0000000
--- a/bin/ledger/tests/benchmark/backlog/backlog_big_entry_updates.tspec
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=1", "--key-size=100", "--value-size=100000",
- "--commit-count=100", "--refs=on"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "duration",
- "event_name": "populate",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_uploader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "upload",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_reader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "download",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_all_entries",
- "event_category": "benchmark"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/backlog_many_big_entries.tspec b/bin/ledger/tests/benchmark/backlog/backlog_many_big_entries.tspec
deleted file mode 100644
index 70fd7e4..0000000
--- a/bin/ledger/tests/benchmark/backlog/backlog_many_big_entries.tspec
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=1000", "--key-size=100", "--value-size=10000",
- "--commit-count=1", "--refs=on"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "duration",
- "event_name": "populate",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_uploader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "upload",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_reader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "download",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_entries_partial",
- "event_category": "benchmark",
- "split_first": true
- },
- {
- "type": "duration",
- "event_name": "get_all_entries",
- "event_category": "benchmark"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/backlog_many_small_entries.tspec b/bin/ledger/tests/benchmark/backlog/backlog_many_small_entries.tspec
deleted file mode 100644
index 1f14580..0000000
--- a/bin/ledger/tests/benchmark/backlog/backlog_many_small_entries.tspec
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=10000", "--value-size=1", "--key-size=100",
- "--commit-count=1", "--refs=off"],
- "categories": ["benchmark", "ledger"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "event_name": "populate",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_uploader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "upload",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_reader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "download",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_entries_partial",
- "event_category": "benchmark",
- "split_first": true
- },
- {
- "type": "duration",
- "event_name": "get_all_entries",
- "event_category": "benchmark"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/backlog_small_entry_updates.tspec b/bin/ledger/tests/benchmark/backlog/backlog_small_entry_updates.tspec
deleted file mode 100644
index 0a35e27..0000000
--- a/bin/ledger/tests/benchmark/backlog/backlog_small_entry_updates.tspec
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=1", "--key-size=100", "--value-size=1",
- "--commit-count=10000", "--refs=off"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "duration",
- "event_name": "populate",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_uploader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "upload",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_reader_page",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "download",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "get_entries_partial",
- "event_category": "benchmark",
- "split_first": true
- },
- {
- "type": "duration",
- "event_name": "get_all_entries",
- "event_category": "benchmark"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/disk_space_synced_entries.tspec b/bin/ledger/tests/benchmark/backlog/disk_space_synced_entries.tspec
deleted file mode 100644
index 5fdfbce..0000000
--- a/bin/ledger/tests/benchmark/backlog/disk_space_synced_entries.tspec
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=100", "--key-size=100", "--value-size=1000",
- "--commit-count=1", "--refs=on"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "argument_value",
- "event_name": "writer_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- },
- {
- "type": "argument_value",
- "event_name": "uploader_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- },
- {
- "type": "argument_value",
- "event_name": "reader_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/disk_space_synced_entries_small_keys.tspec b/bin/ledger/tests/benchmark/backlog/disk_space_synced_entries_small_keys.tspec
deleted file mode 100644
index 1dab193..0000000
--- a/bin/ledger/tests/benchmark/backlog/disk_space_synced_entries_small_keys.tspec
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=100", "--key-size=10", "--value-size=1000",
- "--commit-count=1", "--refs=on"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "argument_value",
- "event_name": "writer_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- },
- {
- "type": "argument_value",
- "event_name": "uploader_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- },
- {
- "type": "argument_value",
- "event_name": "reader_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/backlog/disk_space_synced_updates.tspec b/bin/ledger/tests/benchmark/backlog/disk_space_synced_updates.tspec
deleted file mode 100644
index ec9e68a..0000000
--- a/bin/ledger/tests/benchmark/backlog/disk_space_synced_updates.tspec
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/backlog.cmx",
- "args": ["--unique-key-count=1", "--key-size=100", "--value-size=1000",
- "--commit-count=100", "--refs=on"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "argument_value",
- "event_name": "writer_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- },
- {
- "type": "argument_value",
- "event_name": "uploader_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- },
- {
- "type": "argument_value",
- "event_name": "reader_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/convergence/BUILD.gn b/bin/ledger/tests/benchmark/convergence/BUILD.gn
deleted file mode 100644
index d9745d3..0000000
--- a/bin/ledger/tests/benchmark/convergence/BUILD.gn
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("convergence") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_convergence",
- ]
-}
-
-executable("ledger_benchmark_convergence") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/cloud_provider_firestore/testing",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "convergence.cc",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/benchmark/convergence/convergence.cc b/bin/ledger/tests/benchmark/convergence/convergence.cc
deleted file mode 100644
index 1935455..0000000
--- a/bin/ledger/tests/benchmark/convergence/convergence.cc
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-#include <set>
-#include <vector>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/callback/waiter.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/zx/time.h>
-#include <trace/event.h>
-
-#include "peridot/bin/cloud_provider_firestore/testing/cloud_provider_factory.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/bin/ledger/testing/sync_params.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/convergence.cmx";
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/convergence";
-constexpr fxl::StringView kEntryCountFlag = "entry-count";
-constexpr fxl::StringView kValueSizeFlag = "value-size";
-constexpr fxl::StringView kDeviceCountFlag = "device-count";
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kEntryCountFlag << "=<int>"
- << " --" << kValueSizeFlag << "=<int>"
- << " --" << kDeviceCountFlag << "=<int>" << GetSyncParamsUsage()
- << std::endl;
-}
-
-constexpr size_t kKeySize = 100;
-
-// Benchmark that measures the time it takes to sync and reconcile concurrent
-// writes.
-//
-// In this scenario there are specified number of (emulated) devices. At each
-// step, every device makes a concurrent write, and we measure the time until
-// all the changes are visible to all devices.
-//
-// Parameters:
-// --entry-count=<int> the number of entries to be put by each device
-// --value-size=<int> the size of a single value in bytes
-// --device-count=<int> number of devices writing to the same page
-// --credentials-path=<file path> Firestore service account credentials
-class ConvergenceBenchmark : public PageWatcher {
- public:
- ConvergenceBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- int entry_count, int value_size, int device_count,
- SyncParams sync_params);
-
- void Run();
-
- // PageWatcher:
- void OnChange(PageChange page_change, ResultState result_state,
- OnChangeCallback callback) override;
-
- private:
- // Instances needed to control the Ledger process associated with a device and
- // interact with it.
- struct DeviceContext {
- std::unique_ptr<files::ScopedTempDir> storage_directory;
- fuchsia::sys::ComponentControllerPtr controller;
- LedgerPtr ledger;
- PagePtr page_connection;
- std::unique_ptr<fidl::Binding<PageWatcher>> page_watcher;
- };
-
- void Start(int step);
-
- void ShutDown();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- DataGenerator generator_;
- std::unique_ptr<component::StartupContext> startup_context_;
- cloud_provider_firestore::CloudProviderFactory cloud_provider_factory_;
- const int entry_count_;
- const int value_size_;
- const int device_count_;
- const cloud_provider_firestore::CloudProviderFactory::UserId user_id_;
- // Track all Ledger instances running for this test and allow to interact with
- // it.
- std::vector<std::unique_ptr<DeviceContext>> devices_;
- PageId page_id_;
- std::multiset<std::string> remaining_keys_;
- int current_step_ = -1;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ConvergenceBenchmark);
-};
-
-ConvergenceBenchmark::ConvergenceBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context, int entry_count,
- int value_size, int device_count, SyncParams sync_params)
- : loop_(loop),
- random_(0),
- generator_(&random_),
- startup_context_(std::move(startup_context)),
- cloud_provider_factory_(startup_context_.get(), &random_,
- std::move(sync_params.api_key),
- std::move(sync_params.credentials)),
- entry_count_(entry_count),
- value_size_(value_size),
- device_count_(device_count),
- user_id_(cloud_provider_firestore::CloudProviderFactory::UserId::New()),
- devices_(device_count) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(entry_count_ > 0);
- FXL_DCHECK(value_size_ > 0);
- FXL_DCHECK(device_count_ > 1);
- for (auto& device_context : devices_) {
- device_context = std::make_unique<DeviceContext>();
- device_context->storage_directory =
- std::make_unique<files::ScopedTempDir>(kStoragePath);
- device_context->page_watcher =
- std::make_unique<fidl::Binding<PageWatcher>>(this);
- }
- page_id_ = generator_.MakePageId();
- cloud_provider_factory_.Init();
-}
-
-void ConvergenceBenchmark::Run() {
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- for (auto& device_context : devices_) {
- // Initialize ledgers in different paths to emulate separate devices,
- // but with the same lowest-level directory name, so they correspond to the
- // same "user".
- std::string synced_dir_path =
- device_context->storage_directory->path() + "/convergence_user";
- bool ret = files::CreateDirectory(synced_dir_path);
- FXL_DCHECK(ret);
-
- cloud_provider::CloudProviderPtr cloud_provider;
- cloud_provider_factory_.MakeCloudProvider(user_id_,
- cloud_provider.NewRequest());
-
- Status status = GetLedger(startup_context_.get(),
- device_context->controller.NewRequest(),
- std::move(cloud_provider), user_id_.user_id(),
- "convergence", DetachedPath(synced_dir_path),
- QuitLoopClosure(), &device_context->ledger);
- if (QuitOnError(QuitLoopClosure(), status, "GetLedger")) {
- return;
- }
- device_context->ledger->GetPage(
- fidl::MakeOptional(page_id_),
- device_context->page_connection.NewRequest(),
- QuitOnErrorCallback(QuitLoopClosure(), "GetPage"));
- PageSnapshotPtr snapshot;
- // Register a watcher; we don't really need the snapshot.
- device_context->page_connection->GetSnapshot(
- snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- device_context->page_watcher->NewBinding(), waiter->NewCallback());
- }
- waiter->Finalize([this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "GetSnapshot")) {
- return;
- }
- Start(0);
- });
-}
-
-void ConvergenceBenchmark::Start(int step) {
- if (step == entry_count_) {
- ShutDown();
- return;
- }
-
- for (int device_id = 0; device_id < device_count_; device_id++) {
- std::vector<uint8_t> key =
- generator_.MakeKey(device_count_ * step + device_id, kKeySize);
- // Insert each key N times, as we will receive N notifications - one for
- // each connection, sender included.
- for (int receiving_device = 0; receiving_device < device_count_;
- receiving_device++) {
- remaining_keys_.insert(convert::ToString(key));
- }
- fidl::VectorPtr<uint8_t> value = generator_.MakeValue(value_size_);
- devices_[device_id]->page_connection->Put(
- std::move(key), std::move(value),
- QuitOnErrorCallback(QuitLoopClosure(), "Put"));
- }
-
- TRACE_ASYNC_BEGIN("benchmark", "convergence", step);
- // Persist the current step, so that we know which dispatcher event to end in
- // OnChange().
- current_step_ = step;
-}
-
-void ConvergenceBenchmark::OnChange(PageChange page_change,
- ResultState result_state,
- OnChangeCallback callback) {
- FXL_DCHECK(result_state == ResultState::COMPLETED);
- for (auto& change : page_change.changed_entries) {
- auto find_one = remaining_keys_.find(convert::ToString(change.key));
- remaining_keys_.erase(find_one);
- }
- if (remaining_keys_.empty()) {
- TRACE_ASYNC_END("benchmark", "convergence", current_step_);
- Start(current_step_ + 1);
- }
- callback(nullptr);
-}
-
-void ConvergenceBenchmark::ShutDown() {
- for (auto& device_context : devices_) {
- KillLedgerProcess(&device_context->controller);
- }
- loop_->Quit();
-}
-
-fit::closure ConvergenceBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- std::string entry_count_str;
- int entry_count;
- std::string value_size_str;
- int value_size;
- std::string device_count_str;
- int device_count;
- SyncParams sync_params;
- if (!command_line.GetOptionValue(kEntryCountFlag.ToString(),
- &entry_count_str) ||
- !fxl::StringToNumberWithError(entry_count_str, &entry_count) ||
- entry_count <= 0 ||
- !command_line.GetOptionValue(kValueSizeFlag.ToString(),
- &value_size_str) ||
- !fxl::StringToNumberWithError(value_size_str, &value_size) ||
- value_size <= 0 ||
- !command_line.GetOptionValue(kDeviceCountFlag.ToString(),
- &device_count_str) ||
- !fxl::StringToNumberWithError(device_count_str, &device_count) ||
- device_count <= 0 ||
- !ParseSyncParamsFromCommandLine(command_line, startup_context.get(),
- &sync_params)) {
- PrintUsage();
- return -1;
- }
-
- ConvergenceBenchmark app(&loop, std::move(startup_context), entry_count,
- value_size, device_count, std::move(sync_params));
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/convergence/convergence.cmx b/bin/ledger/tests/benchmark/convergence/convergence.cmx
deleted file mode 100644
index 6052df1..0000000
--- a/bin/ledger/tests/benchmark/convergence/convergence.cmx
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_convergence"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/convergence/convergence.tspec b/bin/ledger/tests/benchmark/convergence/convergence.tspec
deleted file mode 100644
index f5f2b66..0000000
--- a/bin/ledger/tests/benchmark/convergence/convergence.tspec
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.local",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/convergence.cmx",
- "args": ["--entry-count=10", "--value-size=100", "--device-count=2"],
- "categories": ["benchmark"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "event_name": "convergence",
- "event_category": "benchmark",
- "expected_sample_count": 10
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/convergence/multidevice_convergence.tspec b/bin/ledger/tests/benchmark/convergence/multidevice_convergence.tspec
deleted file mode 100644
index b796900..0000000
--- a/bin/ledger/tests/benchmark/convergence/multidevice_convergence.tspec
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.local",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/convergence.cmx",
- "args": ["--entry-count=3", "--value-size=100", "--device-count=10"],
- "categories": ["benchmark"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "event_name": "convergence",
- "event_category": "benchmark",
- "expected_sample_count": 3
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/delete_entry/BUILD.gn b/bin/ledger/tests/benchmark/delete_entry/BUILD.gn
deleted file mode 100644
index a2c9c4a..0000000
--- a/bin/ledger/tests/benchmark/delete_entry/BUILD.gn
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("delete_entry") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_delete_entry",
- ]
-}
-
-executable("ledger_benchmark_delete_entry") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "delete_entry.cc",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/benchmark/delete_entry/delete_big_entry.tspec b/bin/ledger/tests/benchmark/delete_entry/delete_big_entry.tspec
deleted file mode 100644
index 36fa2d6..0000000
--- a/bin/ledger/tests/benchmark/delete_entry/delete_big_entry.tspec
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.delete_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/delete_entry.cmx",
- "args": ["--entry-count=100", "--key-size=100", "--value-size=20000",
- "--transaction-size=0"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "big_value/delete",
- "event_name": "delete_entry",
- "event_category": "benchmark",
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/delete_entry/delete_entry.cc b/bin/ledger/tests/benchmark/delete_entry/delete_entry.cc
deleted file mode 100644
index e22437d..0000000
--- a/bin/ledger/tests/benchmark/delete_entry/delete_entry.cc
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/callback/waiter.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/zx/time.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/filesystem/get_directory_content_size.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/page_data_generator.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/delete_entry.cmx";
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/delete_entry";
-constexpr fxl::StringView kEntryCountFlag = "entry-count";
-constexpr fxl::StringView kTransactionSizeFlag = "transaction-size";
-constexpr fxl::StringView kKeySizeFlag = "key-size";
-constexpr fxl::StringView kValueSizeFlag = "value-size";
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kEntryCountFlag << "=<int>"
- << " --" << kTransactionSizeFlag << "=<int>"
- << " --" << kKeySizeFlag << "=<int>"
- << " --" << kValueSizeFlag << "=<int>" << std::endl;
-}
-
-// Benchmark that measures the time taken to delete an entry from a page.
-//
-// Parameters:
-// --entry-count=<int> the number of entries to be put and deleted
-// --transaction_size=<int> number of delete operations in each transaction. 0
-// means no explicit transactions.
-// --key-size=<int> size of the keys for the entries
-// --value-size=<int> the size of a single value in bytes
-class DeleteEntryBenchmark {
- public:
- DeleteEntryBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t entry_count, size_t transaction_size, size_t key_size,
- size_t value_size);
-
- void Run();
-
- private:
- void Populate();
- void RunSingle(size_t i);
- void CommitAndRunNext(size_t i);
- void ShutDown();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- files::ScopedTempDir tmp_dir_;
- DataGenerator generator_;
- PageDataGenerator page_data_generator_;
- std::unique_ptr<component::StartupContext> startup_context_;
- const size_t entry_count_;
- const size_t transaction_size_;
- const size_t key_size_;
- const size_t value_size_;
- fuchsia::sys::ComponentControllerPtr component_controller_;
- LedgerPtr ledger_;
- PagePtr page_;
- std::vector<std::vector<uint8_t>> keys_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DeleteEntryBenchmark);
-};
-
-DeleteEntryBenchmark::DeleteEntryBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t entry_count, size_t transaction_size, size_t key_size,
- size_t value_size)
- : loop_(loop),
- random_(0),
- tmp_dir_(kStoragePath),
- generator_(&random_),
- page_data_generator_(&random_),
- startup_context_(std::move(startup_context)),
- entry_count_(entry_count),
- transaction_size_(transaction_size),
- key_size_(key_size),
- value_size_(value_size) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(entry_count_ > 0);
- FXL_DCHECK(transaction_size_ >= 0);
- FXL_DCHECK(key_size_ > 0);
- FXL_DCHECK(value_size_ > 0);
-}
-
-void DeleteEntryBenchmark::Run() {
- Status status =
- GetLedger(startup_context_.get(), component_controller_.NewRequest(),
- nullptr, "", "delete_entry", DetachedPath(tmp_dir_.path()),
- QuitLoopClosure(), &ledger_);
- if (QuitOnError(QuitLoopClosure(), status, "GetLedger")) {
- return;
- }
-
- GetPageEnsureInitialized(
- &ledger_, nullptr, DelayCallback::YES, QuitLoopClosure(),
- [this](Status status, PagePtr page, PageId id) {
- if (QuitOnError(QuitLoopClosure(), status, "Page initialization")) {
- return;
- }
- page_ = std::move(page);
- Populate();
- });
-}
-
-void DeleteEntryBenchmark::Populate() {
- auto keys = generator_.MakeKeys(entry_count_, key_size_, entry_count_);
- for (size_t i = 0; i < entry_count_; i++) {
- keys_.push_back(keys[i]);
- }
-
- page_data_generator_.Populate(
- &page_, std::move(keys), value_size_, entry_count_,
- PageDataGenerator::ReferenceStrategy::REFERENCE, Priority::EAGER,
- [this](Status status) {
- if (status != Status::OK) {
- QuitOnError(QuitLoopClosure(), status, "PageGenerator::Populate");
- return;
- }
- if (transaction_size_ > 0) {
- page_->StartTransaction([this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status,
- "Page::StartTransaction")) {
- return;
- }
- TRACE_ASYNC_BEGIN("benchmark", "transaction", 0);
- RunSingle(0);
- });
- } else {
- RunSingle(0);
- }
- });
-}
-
-void DeleteEntryBenchmark::RunSingle(size_t i) {
- if (i == entry_count_) {
- ShutDown();
-
- uint64_t tmp_dir_size = 0;
- FXL_CHECK(
- GetDirectoryContentSize(DetachedPath(tmp_dir_.path()), &tmp_dir_size));
- TRACE_COUNTER("benchmark", "ledger_directory_size", 0, "directory_size",
- TA_UINT64(tmp_dir_size));
- return;
- }
-
- TRACE_ASYNC_BEGIN("benchmark", "delete_entry", i);
- page_->Delete(std::move(keys_[i]), [this, i](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "Page::Delete")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "delete_entry", i);
- if (transaction_size_ > 0 &&
- (i % transaction_size_ == transaction_size_ - 1 ||
- i + 1 == entry_count_)) {
- CommitAndRunNext(i);
- } else {
- RunSingle(i + 1);
- }
- });
-}
-
-void DeleteEntryBenchmark::CommitAndRunNext(size_t i) {
- TRACE_ASYNC_BEGIN("benchmark", "commit", i / transaction_size_);
- page_->Commit([this, i](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "Page::Commit")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "commit", i / transaction_size_);
- TRACE_ASYNC_END("benchmark", "transaction", i / transaction_size_);
-
- if (i == entry_count_ - 1) {
- RunSingle(i + 1);
- return;
- }
- page_->StartTransaction([this, i = i + 1](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "Page::StartTransaction")) {
- return;
- }
- TRACE_ASYNC_BEGIN("benchmark", "transaction", i / transaction_size_);
- RunSingle(i);
- });
- });
-}
-
-void DeleteEntryBenchmark::ShutDown() {
- KillLedgerProcess(&component_controller_);
- loop_->Quit();
-}
-
-fit::closure DeleteEntryBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- std::string entry_count_str;
- size_t entry_count;
- std::string transaction_size_str;
- size_t transaction_size;
- std::string key_size_str;
- size_t key_size;
- std::string value_size_str;
- size_t value_size;
- if (!command_line.GetOptionValue(kEntryCountFlag.ToString(),
- &entry_count_str) ||
- !fxl::StringToNumberWithError(entry_count_str, &entry_count) ||
- entry_count == 0 ||
- !command_line.GetOptionValue(kTransactionSizeFlag.ToString(),
- &transaction_size_str) ||
- !fxl::StringToNumberWithError(transaction_size_str, &transaction_size) ||
- !command_line.GetOptionValue(kKeySizeFlag.ToString(), &key_size_str) ||
- !fxl::StringToNumberWithError(key_size_str, &key_size) || key_size == 0 ||
- !command_line.GetOptionValue(kValueSizeFlag.ToString(),
- &value_size_str) ||
- !fxl::StringToNumberWithError(value_size_str, &value_size) ||
- value_size == 0) {
- PrintUsage();
- return -1;
- }
-
- DeleteEntryBenchmark app(&loop, std::move(startup_context), entry_count,
- transaction_size, key_size, value_size);
-
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/delete_entry/delete_entry.cmx b/bin/ledger/tests/benchmark/delete_entry/delete_entry.cmx
deleted file mode 100644
index 4c162f5..0000000
--- a/bin/ledger/tests/benchmark/delete_entry/delete_entry.cmx
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_delete_entry"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/delete_entry/delete_entry.tspec b/bin/ledger/tests/benchmark/delete_entry/delete_entry.tspec
deleted file mode 100644
index 6b2d300..0000000
--- a/bin/ledger/tests/benchmark/delete_entry/delete_entry.tspec
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.delete_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/delete_entry.cmx",
- "args": ["--entry-count=100", "--key-size=100", "--value-size=1000",
- "--transaction-size=0"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "small_value/delete",
- "event_name": "delete_entry",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/delete_entry/delete_entry_transactions.tspec b/bin/ledger/tests/benchmark/delete_entry/delete_entry_transactions.tspec
deleted file mode 100644
index 8311d2a..0000000
--- a/bin/ledger/tests/benchmark/delete_entry/delete_entry_transactions.tspec
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.delete_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/delete_entry.cmx",
- "args": ["--entry-count=100", "--key-size=100", "--value-size=1000",
- "--transaction-size=10"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "transaction/transaction",
- "event_name": "transaction",
- "event_category": "benchmark",
- "expected_sample_count": 10,
- "split_first": true
- },
-
- {
- "type": "duration",
- "output_test_name": "transaction/commit",
- "event_name": "commit",
- "event_category": "benchmark",
- "expected_sample_count": 10,
- "split_first": true
- },
-
- {
- "type": "duration",
- "output_test_name": "transaction/delete",
- "event_name": "delete_entry",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/delete_entry/disk_space_cleared_page.tspec b/bin/ledger/tests/benchmark/delete_entry/disk_space_cleared_page.tspec
deleted file mode 100644
index e8fc340..0000000
--- a/bin/ledger/tests/benchmark/delete_entry/disk_space_cleared_page.tspec
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.delete_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/delete_entry.cmx",
- "args": ["--entry-count=100", "--key-size=100", "--value-size=1000",
- "--transaction-size=100"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "argument_value",
- "output_test_name": "cleared_page/ledger_directory_size",
- "event_name": "ledger_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/disk_space/BUILD.gn b/bin/ledger/tests/benchmark/disk_space/BUILD.gn
deleted file mode 100644
index 7ff2097..0000000
--- a/bin/ledger/tests/benchmark/disk_space/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("disk_space") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_disk_space",
- ]
-}
-
-executable("ledger_benchmark_disk_space") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "disk_space.cc",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/benchmark/disk_space/disk_space.cc b/bin/ledger/tests/benchmark/disk_space/disk_space.cc
deleted file mode 100644
index 1ec6ecf..0000000
--- a/bin/ledger/tests/benchmark/disk_space/disk_space.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <trace/event.h>
-#include <iostream>
-#include <memory>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/callback/waiter.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/zx/time.h>
-
-#include "garnet/public/lib/callback/waiter.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/filesystem/get_directory_content_size.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/page_data_generator.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/disk_space.cmx";
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/disk_space";
-constexpr fxl::StringView kPageCountFlag = "page-count";
-constexpr fxl::StringView kUniqueKeyCountFlag = "unique-key-count";
-constexpr fxl::StringView kCommitCountFlag = "commit-count";
-constexpr fxl::StringView kKeySizeFlag = "key-size";
-constexpr fxl::StringView kValueSizeFlag = "value-size";
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kPageCountFlag << "=<int>"
- << " --" << kUniqueKeyCountFlag << "=<int>"
- << " --" << kCommitCountFlag << "=<int>"
- << " --" << kKeySizeFlag << "=<int>"
- << " --" << kValueSizeFlag << "=<int>" << std::endl;
-}
-
-// Disk space "general usage" benchmark.
-// This benchmark is used to capture Ledger disk usage over the set of common
-// operations, such as getting a new page, adding several entries to the page,
-// modifying the same entry several times.
-//
-// The emulated scenario is as follows:
-// First, |page_count| pages is requested from ledger. Then each page is
-// populated with |unique_key_count| unique entries, making |commit_count|
-// commits in the process (so if |commit_count| is bigger than
-// |unique_key_count|, some entries get overwritten in subsequent commits,
-// whereas if |commit_count| is smaller than |unique_key_count|, insertion
-// operations get grouped together into the requested number of commits). Each
-// entry has a key size of |key_size| and a value size of |value_size|. After
-// that, the connection to the ledger is closed and the size of the directory
-// used by it is measured and reported using a trace counter event.
-//
-// Parameters:
-// --page-count=<int> number of pages to be requested.
-// --unique-key-count=<int> number of unique keys contained in each page
-// after population.
-// --commit-count=<int> number of commits made to each page.
-// If this number is smaller than unique-key-count, changes will be bundled
-// into transactions. If it is bigger, some or all of the changes will use the
-// same keys, modifying the value.
-// --key-size=<int> size of a key for each entry.
-// --value-size=<int> size of a value for each entry.
-class DiskSpaceBenchmark {
- public:
- DiskSpaceBenchmark(async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t page_count, size_t unique_key_count,
- size_t commit_count, size_t key_size, size_t value_size);
-
- void Run();
-
- private:
- void Populate();
- void ShutDownAndRecord();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- files::ScopedTempDir tmp_dir_;
- DataGenerator generator_;
- PageDataGenerator page_data_generator_;
- std::unique_ptr<component::StartupContext> startup_context_;
- const size_t page_count_;
- const size_t unique_key_count_;
- const size_t commit_count_;
- const size_t key_size_;
- const size_t value_size_;
- fuchsia::sys::ComponentControllerPtr component_controller_;
- LedgerPtr ledger_;
- std::vector<PagePtr> pages_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DiskSpaceBenchmark);
-};
-
-DiskSpaceBenchmark::DiskSpaceBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t page_count, size_t unique_key_count, size_t commit_count,
- size_t key_size, size_t value_size)
- : loop_(loop),
- random_(0),
- tmp_dir_(kStoragePath),
- generator_(&random_),
- page_data_generator_(&random_),
- startup_context_(std::move(startup_context)),
- page_count_(page_count),
- unique_key_count_(unique_key_count),
- commit_count_(commit_count),
- key_size_(key_size),
- value_size_(value_size) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(page_count_ >= 0);
- FXL_DCHECK(unique_key_count_ >= 0);
- FXL_DCHECK(commit_count_ >= 0);
- FXL_DCHECK(key_size_ > 0);
- FXL_DCHECK(value_size_ > 0);
-}
-
-void DiskSpaceBenchmark::Run() {
- Status status = GetLedger(
- startup_context_.get(), component_controller_.NewRequest(), nullptr, "",
- "disk_space", DetachedPath(tmp_dir_.path()), QuitLoopClosure(), &ledger_);
- if (QuitOnError(QuitLoopClosure(), status, "GetLedger")) {
- return;
- }
-
- auto waiter =
- fxl::MakeRefCounted<callback::Waiter<Status, PagePtr>>(Status::OK);
-
- for (size_t page_number = 0; page_number < page_count_; page_number++) {
- GetPageEnsureInitialized(&ledger_, nullptr, DelayCallback::YES,
- QuitLoopClosure(),
- [callback = waiter->NewCallback()](
- Status status, PagePtr page, PageId id) {
- callback(status, std::move(page));
- });
- }
-
- waiter->Finalize([this](Status status, std::vector<PagePtr> pages) {
- if (QuitOnError(QuitLoopClosure(), status, "GetPageEnsureInitialized")) {
- return;
- }
- pages_ = std::move(pages);
- if (commit_count_ == 0) {
- ShutDownAndRecord();
- return;
- }
- Populate();
- });
-}
-
-void DiskSpaceBenchmark::Populate() {
- int transaction_size = static_cast<int>(
- ceil(static_cast<double>(unique_key_count_) / commit_count_));
- int insertions = std::max(unique_key_count_, commit_count_);
- FXL_LOG(INFO) << "Transaction size: " << transaction_size
- << ", insertions: " << insertions << ".";
- auto waiter = fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- for (auto& page : pages_) {
- auto keys = generator_.MakeKeys(insertions, key_size_, unique_key_count_);
- page_data_generator_.Populate(
- &page, std::move(keys), value_size_, transaction_size,
- PageDataGenerator::ReferenceStrategy::REFERENCE, Priority::EAGER,
- waiter->NewCallback());
- }
- waiter->Finalize([this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "PageGenerator::Populate")) {
- return;
- }
- ShutDownAndRecord();
- });
-}
-
-void DiskSpaceBenchmark::ShutDownAndRecord() {
- KillLedgerProcess(&component_controller_);
- loop_->Quit();
-
- uint64_t tmp_dir_size = 0;
- FXL_CHECK(
- GetDirectoryContentSize(DetachedPath(tmp_dir_.path()), &tmp_dir_size));
- TRACE_COUNTER("benchmark", "ledger_directory_size", 0, "directory_size",
- TA_UINT64(tmp_dir_size));
-}
-
-fit::closure DiskSpaceBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- std::string page_count_str;
- size_t page_count;
- std::string unique_key_count_str;
- size_t unique_key_count;
- std::string commit_count_str;
- size_t commit_count;
- std::string key_size_str;
- size_t key_size;
- std::string value_size_str;
- size_t value_size;
- if (!command_line.GetOptionValue(kPageCountFlag.ToString(),
- &page_count_str) ||
- !fxl::StringToNumberWithError(page_count_str, &page_count) ||
- !command_line.GetOptionValue(kUniqueKeyCountFlag.ToString(),
- &unique_key_count_str) ||
- !fxl::StringToNumberWithError(unique_key_count_str, &unique_key_count) ||
- !command_line.GetOptionValue(kCommitCountFlag.ToString(),
- &commit_count_str) ||
- !fxl::StringToNumberWithError(commit_count_str, &commit_count) ||
- !command_line.GetOptionValue(kKeySizeFlag.ToString(), &key_size_str) ||
- !fxl::StringToNumberWithError(key_size_str, &key_size) || key_size == 0 ||
- !command_line.GetOptionValue(kValueSizeFlag.ToString(),
- &value_size_str) ||
- !fxl::StringToNumberWithError(value_size_str, &value_size) ||
- value_size == 0) {
- PrintUsage();
- return -1;
- }
-
- DiskSpaceBenchmark app(&loop, std::move(startup_context), page_count,
- unique_key_count, commit_count, key_size, value_size);
-
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/disk_space/disk_space.cmx b/bin/ledger/tests/benchmark/disk_space/disk_space.cmx
deleted file mode 100644
index a1f1390..0000000
--- a/bin/ledger/tests/benchmark/disk_space/disk_space.cmx
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_disk_space"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/disk_space/empty_ledger.tspec b/bin/ledger/tests/benchmark/disk_space/empty_ledger.tspec
deleted file mode 100644
index 23d6b4a..0000000
--- a/bin/ledger/tests/benchmark/disk_space/empty_ledger.tspec
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.disk_space",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/disk_space.cmx",
- "args": ["--page-count=0", "--unique-key-count=0", "--key-size=10",
- "--value-size=10", "--commit-count=0"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "argument_value",
- "output_test_name": "empty_ledger/ledger_directory_size",
- "event_name": "ledger_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/disk_space/empty_pages.tspec b/bin/ledger/tests/benchmark/disk_space/empty_pages.tspec
deleted file mode 100644
index 61b2570..0000000
--- a/bin/ledger/tests/benchmark/disk_space/empty_pages.tspec
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.disk_space",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/disk_space.cmx",
- "args": ["--page-count=10", "--unique-key-count=0", "--key-size=10",
- "--value-size=10", "--commit-count=0"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "argument_value",
- "output_test_name": "empty_pages/ledger_directory_size",
- "event_name": "ledger_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/disk_space/entries.tspec b/bin/ledger/tests/benchmark/disk_space/entries.tspec
deleted file mode 100644
index d685527..0000000
--- a/bin/ledger/tests/benchmark/disk_space/entries.tspec
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.disk_space",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/disk_space.cmx",
- "args": ["--page-count=1", "--unique-key-count=100", "--key-size=100",
- "--value-size=1000", "--commit-count=1"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "argument_value",
- "output_test_name": "entries/ledger_directory_size",
- "event_name": "ledger_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/disk_space/one_commit_per_entry.tspec b/bin/ledger/tests/benchmark/disk_space/one_commit_per_entry.tspec
deleted file mode 100644
index d2e750c..0000000
--- a/bin/ledger/tests/benchmark/disk_space/one_commit_per_entry.tspec
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.disk_space",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/disk_space.cmx",
- "args": ["--page-count=1", "--unique-key-count=100", "--key-size=100",
- "--value-size=1000", "--commit-count=100"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "argument_value",
- "output_test_name": "one_commit_per_entry/ledger_directory_size",
- "event_name": "ledger_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/disk_space/small_keys.tspec b/bin/ledger/tests/benchmark/disk_space/small_keys.tspec
deleted file mode 100644
index 6993b67..0000000
--- a/bin/ledger/tests/benchmark/disk_space/small_keys.tspec
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.disk_space",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/disk_space.cmx",
- "args": ["--page-count=1", "--unique-key-count=100", "--key-size=10",
- "--value-size=1000", "--commit-count=1"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "argument_value",
- "output_test_name": "small_keys/ledger_directory_size",
- "event_name": "ledger_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/disk_space/updates.tspec b/bin/ledger/tests/benchmark/disk_space/updates.tspec
deleted file mode 100644
index 8528790..0000000
--- a/bin/ledger/tests/benchmark/disk_space/updates.tspec
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.disk_space",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/disk_space.cmx",
- "args": ["--page-count=1", "--unique-key-count=1", "--commit-count=100",
- "--key-size=100", "--value-size=1000"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "argument_value",
- "output_test_name": "updates/ledger_directory_size",
- "event_name": "ledger_directory_size",
- "event_category": "benchmark",
- "argument_name": "directory_size",
- "argument_unit": "bytes"
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/fetch/BUILD.gn b/bin/ledger/tests/benchmark/fetch/BUILD.gn
deleted file mode 100644
index 93a302d..0000000
--- a/bin/ledger/tests/benchmark/fetch/BUILD.gn
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("fetch") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_fetch",
- ]
-}
-
-executable("ledger_benchmark_fetch") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/cloud_provider_firestore/testing",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "fetch.cc",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/benchmark/fetch/fetch.cc b/bin/ledger/tests/benchmark/fetch/fetch.cc
deleted file mode 100644
index 55efd61..0000000
--- a/bin/ledger/tests/benchmark/fetch/fetch.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-#include <vector>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/zx/time.h>
-#include <trace/event.h>
-
-#include "peridot/bin/cloud_provider_firestore/testing/cloud_provider_factory.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/page_data_generator.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/bin/ledger/testing/sync_params.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/fetch.cmx";
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/fetch";
-constexpr fxl::StringView kEntryCountFlag = "entry-count";
-constexpr fxl::StringView kValueSizeFlag = "value-size";
-constexpr fxl::StringView kPartSizeFlag = "part-size";
-
-constexpr size_t kKeySize = 100;
-
-const std::string kUserDirectory = "/fetch-user";
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kEntryCountFlag << "=<int>"
- << " --" << kValueSizeFlag << "=<int>"
- << " --" << kPartSizeFlag << "=<int>" << GetSyncParamsUsage()
- << std::endl;
-}
-
-// Benchmark that measures time to fetch lazy values from server.
-// Parameters:
-// --entry-count=<int> the number of entries to be put
-// --value-size=<int> the size of a single value in bytes
-// --part-size=<int> the size of the part to be read with one Fetch
-// call. If equal to zero, the whole value will be read.
-// --credentials-path=<file path> Firestore service account credentials
-class FetchBenchmark : public SyncWatcher {
- public:
- FetchBenchmark(async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t entry_count, size_t value_size, size_t part_size,
- SyncParams sync_params);
-
- void Run();
-
- // SyncWatcher:
- void SyncStateChanged(SyncState download, SyncState upload,
- SyncStateChangedCallback callback) override;
-
- private:
- void Populate();
- void WaitForWriterUpload();
- void ConnectReader();
- void WaitForReaderDownload();
-
- void FetchValues(PageSnapshotPtr snapshot, size_t i);
- void FetchPart(PageSnapshotPtr snapshot, size_t i, size_t part);
-
- void ShutDown();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- DataGenerator generator_;
- PageDataGenerator page_data_generator_;
- std::unique_ptr<component::StartupContext> startup_context_;
- cloud_provider_firestore::CloudProviderFactory cloud_provider_factory_;
- fidl::Binding<SyncWatcher> sync_watcher_binding_;
- const size_t entry_count_;
- const size_t value_size_;
- const size_t part_size_;
- const cloud_provider_firestore::CloudProviderFactory::UserId user_id_;
- files::ScopedTempDir writer_tmp_dir_;
- files::ScopedTempDir reader_tmp_dir_;
- fuchsia::sys::ComponentControllerPtr writer_controller_;
- fuchsia::sys::ComponentControllerPtr reader_controller_;
- LedgerPtr writer_;
- LedgerPtr reader_;
- PageId page_id_;
- PagePtr writer_page_;
- PagePtr reader_page_;
- std::vector<std::vector<uint8_t>> keys_;
- fit::function<void(SyncState, SyncState)> on_sync_state_changed_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FetchBenchmark);
-};
-
-FetchBenchmark::FetchBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t entry_count, size_t value_size, size_t part_size,
- SyncParams sync_params)
- : loop_(loop),
- random_(0),
- generator_(&random_),
- page_data_generator_(&random_),
- startup_context_(std::move(startup_context)),
- cloud_provider_factory_(startup_context_.get(), &random_,
- std::move(sync_params.api_key),
- std::move(sync_params.credentials)),
- sync_watcher_binding_(this),
- entry_count_(entry_count),
- value_size_(value_size),
- part_size_(part_size),
- user_id_(cloud_provider_firestore::CloudProviderFactory::UserId::New()),
- writer_tmp_dir_(kStoragePath),
- reader_tmp_dir_(kStoragePath) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(entry_count_ > 0);
- FXL_DCHECK(value_size_ > 0);
- FXL_DCHECK(part_size_ <= value_size);
- cloud_provider_factory_.Init();
-}
-
-void FetchBenchmark::SyncStateChanged(SyncState download, SyncState upload,
- SyncStateChangedCallback callback) {
- if (on_sync_state_changed_) {
- on_sync_state_changed_(download, upload);
- }
- callback();
-}
-
-void FetchBenchmark::Run() {
- // Name of the storage directory currently identifies the user. Ensure the
- // most nested directory has the same name to make the ledgers sync.
- std::string writer_path = writer_tmp_dir_.path() + kUserDirectory;
- bool ret = files::CreateDirectory(writer_path);
- FXL_DCHECK(ret);
-
- cloud_provider::CloudProviderPtr cloud_provider_writer;
- cloud_provider_factory_.MakeCloudProvider(user_id_,
- cloud_provider_writer.NewRequest());
- Status status = GetLedger(
- startup_context_.get(), writer_controller_.NewRequest(),
- std::move(cloud_provider_writer), user_id_.user_id(), "fetch",
- DetachedPath(std::move(writer_path)), QuitLoopClosure(), &writer_);
- if (QuitOnError(QuitLoopClosure(), status, "Get writer ledger")) {
- return;
- }
-
- GetPageEnsureInitialized(&writer_, nullptr, DelayCallback::YES,
- QuitLoopClosure(),
- [this](Status status, PagePtr page, PageId id) {
- if (QuitOnError(QuitLoopClosure(), status,
- "Writer page initialization")) {
- return;
- }
- writer_page_ = std::move(page);
- page_id_ = id;
-
- Populate();
- });
-}
-
-void FetchBenchmark::Populate() {
- auto keys = generator_.MakeKeys(entry_count_, kKeySize, entry_count_);
- for (size_t i = 0; i < entry_count_; i++) {
- keys_.push_back(keys[i]);
- }
-
- page_data_generator_.Populate(
- &writer_page_, std::move(keys), value_size_, entry_count_,
- PageDataGenerator::ReferenceStrategy::REFERENCE, Priority::LAZY,
- [this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "PageGenerator::Populate")) {
- return;
- }
- WaitForWriterUpload();
- });
-}
-
-void FetchBenchmark::WaitForWriterUpload() {
- on_sync_state_changed_ = [this](SyncState download, SyncState upload) {
- if (upload == SyncState::IDLE) {
- on_sync_state_changed_ = nullptr;
- // Stop watching sync state for this page.
- sync_watcher_binding_.Unbind();
- ConnectReader();
- return;
- }
- };
- writer_page_->SetSyncStateWatcher(
- sync_watcher_binding_.NewBinding(),
- QuitOnErrorCallback(QuitLoopClosure(), "Page::SetSyncStateWatcher"));
-}
-
-void FetchBenchmark::ConnectReader() {
- std::string reader_path = reader_tmp_dir_.path() + kUserDirectory;
- bool ret = files::CreateDirectory(reader_path);
- FXL_DCHECK(ret);
-
- cloud_provider::CloudProviderPtr cloud_provider_reader;
- cloud_provider_factory_.MakeCloudProvider(user_id_,
- cloud_provider_reader.NewRequest());
- Status status = GetLedger(
- startup_context_.get(), reader_controller_.NewRequest(),
- std::move(cloud_provider_reader), user_id_.user_id(), "fetch",
- DetachedPath(std::move(reader_path)), QuitLoopClosure(), &reader_);
- if (QuitOnError(QuitLoopClosure(), status, "ConnectReader")) {
- return;
- }
-
- reader_->GetPage(fidl::MakeOptional(page_id_), reader_page_.NewRequest(),
- [this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "GetPage")) {
- return;
- }
- WaitForReaderDownload();
- });
-}
-
-void FetchBenchmark::WaitForReaderDownload() {
- on_sync_state_changed_ = [this](SyncState download, SyncState upload) {
- if (download == SyncState::IDLE) {
- on_sync_state_changed_ = nullptr;
- PageSnapshotPtr snapshot;
- reader_page_->GetSnapshot(
- snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0), nullptr,
- QuitOnErrorCallback(QuitLoopClosure(), "GetSnapshot"));
- FetchValues(std::move(snapshot), 0);
- return;
- }
- };
- reader_page_->SetSyncStateWatcher(
- sync_watcher_binding_.NewBinding(),
- QuitOnErrorCallback(QuitLoopClosure(), "Page::SetSyncStateWatcher"));
-}
-
-void FetchBenchmark::FetchValues(PageSnapshotPtr snapshot, size_t i) {
- if (i >= entry_count_) {
- ShutDown();
- return;
- }
-
- if (part_size_ > 0) {
- TRACE_ASYNC_BEGIN("benchmark", "Fetch (cumulative)", i);
- FetchPart(std::move(snapshot), i, 0);
- return;
- }
- PageSnapshot* snapshot_ptr = snapshot.get();
-
- TRACE_ASYNC_BEGIN("benchmark", "Fetch", i);
- snapshot_ptr->Fetch(
- std::move(keys_[i]),
- [this, snapshot = std::move(snapshot), i](
- Status status, fuchsia::mem::BufferPtr value) mutable {
- if (QuitOnError(QuitLoopClosure(), status, "PageSnapshot::Fetch")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "Fetch", i);
- FetchValues(std::move(snapshot), i + 1);
- });
-}
-
-void FetchBenchmark::FetchPart(PageSnapshotPtr snapshot, size_t i,
- size_t part) {
- if (part * part_size_ >= value_size_) {
- TRACE_ASYNC_END("benchmark", "Fetch (cumulative)", i);
- FetchValues(std::move(snapshot), i + 1);
- return;
- }
- PageSnapshot* snapshot_ptr = snapshot.get();
- auto trace_event_id = TRACE_NONCE();
- TRACE_ASYNC_BEGIN("benchmark", "FetchPartial", trace_event_id);
- snapshot_ptr->FetchPartial(
- keys_[i], part * part_size_, part_size_,
- [this, snapshot = std::move(snapshot), i, part, trace_event_id](
- Status status, fuchsia::mem::BufferPtr value) mutable {
- if (QuitOnError(QuitLoopClosure(), status,
- "PageSnapshot::FetchPartial")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "FetchPartial", trace_event_id);
- FetchPart(std::move(snapshot), i, part + 1);
- });
-}
-
-void FetchBenchmark::ShutDown() {
- KillLedgerProcess(&writer_controller_);
- KillLedgerProcess(&reader_controller_);
- loop_->Quit();
-}
-
-fit::closure FetchBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- std::string entry_count_str;
- size_t entry_count;
- std::string value_size_str;
- size_t value_size;
- std::string part_size_str;
- size_t part_size;
- SyncParams sync_params;
- if (!command_line.GetOptionValue(kEntryCountFlag.ToString(),
- &entry_count_str) ||
- !fxl::StringToNumberWithError(entry_count_str, &entry_count) ||
- entry_count == 0 ||
- !command_line.GetOptionValue(kValueSizeFlag.ToString(),
- &value_size_str) ||
- !fxl::StringToNumberWithError(value_size_str, &value_size) ||
- value_size == 0 ||
- !command_line.GetOptionValue(kPartSizeFlag.ToString(), &part_size_str) ||
- !fxl::StringToNumberWithError(part_size_str, &part_size) ||
- !ParseSyncParamsFromCommandLine(command_line, startup_context.get(),
- &sync_params)) {
- PrintUsage();
- return -1;
- }
-
- FetchBenchmark app(&loop, std::move(startup_context), entry_count, value_size,
- part_size, std::move(sync_params));
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/fetch/fetch.cmx b/bin/ledger/tests/benchmark/fetch/fetch.cmx
deleted file mode 100644
index 52d64b8..0000000
--- a/bin/ledger/tests/benchmark/fetch/fetch.cmx
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_fetch"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/fetch/fetch.tspec b/bin/ledger/tests/benchmark/fetch/fetch.tspec
deleted file mode 100644
index e0ed34a..0000000
--- a/bin/ledger/tests/benchmark/fetch/fetch.tspec
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/fetch.cmx",
- "args": ["--entry-count=20", "--value-size=100000", "--part-size=0"],
- "categories": ["benchmark", "ledger"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "event_name": "Fetch",
- "event_category": "benchmark",
- "expected_sample_count": 20,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/fetch/fetch_partial_big_entry.tspec b/bin/ledger/tests/benchmark/fetch/fetch_partial_big_entry.tspec
deleted file mode 100644
index 08a2dff..0000000
--- a/bin/ledger/tests/benchmark/fetch/fetch_partial_big_entry.tspec
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/fetch.cmx",
- "args": ["--entry-count=1", "--value-size=10000000", "--part-size=50000"],
- "categories": ["benchmark", "ledger"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "event_name": "Fetch (cumulative)",
- "event_category": "benchmark",
- "expected_sample_count": 1
- },
- {
- "type": "duration",
- "event_name": "FetchPartial",
- "event_category": "benchmark",
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/get_page/BUILD.gn b/bin/ledger/tests/benchmark/get_page/BUILD.gn
deleted file mode 100644
index 90befb7..0000000
--- a/bin/ledger/tests/benchmark/get_page/BUILD.gn
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("get_page") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_get_page",
- ]
-}
-
-executable("ledger_benchmark_get_page") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "get_page.cc",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/benchmark/get_page/add_new_page.tspec b/bin/ledger/tests/benchmark/get_page/add_new_page.tspec
deleted file mode 100644
index d8a747a..0000000
--- a/bin/ledger/tests/benchmark/get_page/add_new_page.tspec
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.get_page",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/get_page.cmx",
- "args": ["--requests-count=500"],
- "categories": ["benchmark", "ledger"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "new_page/get_page",
- "event_name": "get page",
- "event_category": "benchmark",
- "expected_sample_count": 500,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "new_page/precache_db",
- "event_name": "prepare_cached_db",
- "event_category": "ledger",
- "expected_sample_count": 500,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/get_page/add_new_page_precached.tspec b/bin/ledger/tests/benchmark/get_page/add_new_page_precached.tspec
deleted file mode 100644
index cfc621d..0000000
--- a/bin/ledger/tests/benchmark/get_page/add_new_page_precached.tspec
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.get_page",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/get_page.cmx",
- "args": ["--requests-count=50", "--wait-for-cached-page"],
- "categories": ["benchmark", "ledger"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "precached_page/get_page",
- "event_name": "get page",
- "event_category": "benchmark",
- "expected_sample_count": 50,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "new_page/precache_db",
- "event_name": "prepare_cached_db",
- "event_category": "ledger",
- "expected_sample_count": 50,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/get_page/get_page.cc b/bin/ledger/tests/benchmark/get_page/get_page.cc
deleted file mode 100644
index 21ce34a..0000000
--- a/bin/ledger/tests/benchmark/get_page/get_page.cc
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <vector>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/zx/time.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/get_page.cmx";
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/get_page";
-constexpr fxl::StringView kPageCountFlag = "requests-count";
-constexpr fxl::StringView kReuseFlag = "reuse";
-constexpr fxl::StringView kWaitForCachedPageFlag = "wait-for-cached-page";
-
-constexpr zx::duration kDuration = zx::msec(500);
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kPageCountFlag << "=<int>"
- << " [--" << kReuseFlag << "]"
- << " [--" << kWaitForCachedPageFlag << "]" << std::endl;
-}
-
-// Benchmark that measures the time taken to get a page.
-//
-// Parameters:
-// --requests-count=<int> number of requests made.
-// --reuse - if this flag is specified, the same id will be used. Otherwise, a
-// new page with a random id is requested every time.
-// --wait_for_cached_page - if this flag is specified, the benchmark will wait
-// for a sufficient amount of time before each page request, to allow Ledger
-// to precache an empty new page.
-class GetPageBenchmark {
- public:
- GetPageBenchmark(async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t requests_count, bool reuse,
- bool wait_for_cached_page);
-
- void Run();
-
- private:
- void RunSingle(size_t request_number);
- void ShutDown();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- files::ScopedTempDir tmp_dir_;
- DataGenerator generator_;
- std::unique_ptr<component::StartupContext> startup_context_;
- const size_t requests_count_;
- const bool reuse_;
- const bool wait_for_cached_page_;
- fuchsia::sys::ComponentControllerPtr component_controller_;
- LedgerPtr ledger_;
- PageIdPtr page_id_;
- std::vector<PagePtr> pages_;
- bool get_page_called_ = false;
- bool get_page_id_called_ = false;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(GetPageBenchmark);
-};
-
-GetPageBenchmark::GetPageBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t requests_count, bool reuse, bool wait_for_cached_page)
- : loop_(loop),
- random_(0),
- tmp_dir_(kStoragePath),
- generator_(&random_),
- startup_context_(std::move(startup_context)),
- requests_count_(requests_count),
- reuse_(reuse),
- wait_for_cached_page_(wait_for_cached_page) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(requests_count_ > 0);
-}
-
-void GetPageBenchmark::Run() {
- Status status = GetLedger(
- startup_context_.get(), component_controller_.NewRequest(), nullptr, "",
- "get_page", DetachedPath(tmp_dir_.path()), QuitLoopClosure(), &ledger_);
-
- if (QuitOnError(QuitLoopClosure(), status, "GetLedger")) {
- return;
- }
-
- page_id_ = fidl::MakeOptional(generator_.MakePageId());
- RunSingle(requests_count_);
-}
-
-void GetPageBenchmark::RunSingle(size_t request_number) {
- if (request_number == 0) {
- ShutDown();
- return;
- }
- if (wait_for_cached_page_) {
- // Wait before each page request, so that a pre-cached page is ready.
- zx_nanosleep(zx_deadline_after(kDuration.get()));
- }
- TRACE_ASYNC_BEGIN("benchmark", "get page", requests_count_ - request_number);
- PagePtr page;
-
- get_page_called_ = false;
- get_page_id_called_ = false;
- ledger_->GetPage(
- reuse_ ? fidl::Clone(page_id_) : nullptr, page.NewRequest(),
- [this, request_number](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "Ledger::GetPage")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "get page",
- requests_count_ - request_number);
- get_page_called_ = true;
- if (get_page_id_called_) {
- // Wait for both GetPage and GetId to do the following run.
- RunSingle(request_number - 1);
- }
- });
-
- TRACE_ASYNC_BEGIN("benchmark", "get page id",
- requests_count_ - request_number);
- // Request the page id before the GetPage callback is called.
- page->GetId([this, request_number](PageId found_page_id) {
- TRACE_ASYNC_END("benchmark", "get page id",
- requests_count_ - request_number);
- get_page_id_called_ = true;
- if (get_page_called_) {
- // Wait for both GetPage and GetId to do the following run.
- RunSingle(request_number - 1);
- }
- });
-
- pages_.push_back(std::move(page));
-}
-
-void GetPageBenchmark::ShutDown() {
- KillLedgerProcess(&component_controller_);
- loop_->Quit();
-}
-
-fit::closure GetPageBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- std::string requests_count_str;
- size_t requests_count;
- if (!command_line.GetOptionValue(kPageCountFlag.ToString(),
- &requests_count_str) ||
- !fxl::StringToNumberWithError(requests_count_str, &requests_count) ||
- requests_count == 0) {
- PrintUsage();
- return EXIT_FAILURE;
- }
- bool reuse = command_line.HasOption(kReuseFlag);
- bool wait_for_cached_page = command_line.HasOption(kWaitForCachedPageFlag);
-
- GetPageBenchmark app(&loop, std::move(startup_context), requests_count, reuse,
- wait_for_cached_page);
-
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/get_page/get_page.cmx b/bin/ledger/tests/benchmark/get_page/get_page.cmx
deleted file mode 100644
index ca0d744..0000000
--- a/bin/ledger/tests/benchmark/get_page/get_page.cmx
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_get_page"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/get_page/get_page_id.tspec b/bin/ledger/tests/benchmark/get_page/get_page_id.tspec
deleted file mode 100644
index 888a540..0000000
--- a/bin/ledger/tests/benchmark/get_page/get_page_id.tspec
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.get_page",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/get_page.cmx",
- "args": ["--requests-count=50"],
- "categories": ["benchmark", "ledger"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "page_id/get_page_id",
- "event_name": "get page id",
- "event_category": "benchmark",
- "expected_sample_count": 50,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/get_page/get_same_page.tspec b/bin/ledger/tests/benchmark/get_page/get_same_page.tspec
deleted file mode 100644
index 102edac..0000000
--- a/bin/ledger/tests/benchmark/get_page/get_same_page.tspec
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.get_page",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/get_page.cmx",
- "args": ["--requests-count=500", "--reuse"],
- "categories": ["benchmark", "ledger"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "same_page/get_page",
- "event_name": "get page",
- "event_category": "benchmark",
- "expected_sample_count": 500,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/put/BUILD.gn b/bin/ledger/tests/benchmark/put/BUILD.gn
deleted file mode 100644
index b962bff..0000000
--- a/bin/ledger/tests/benchmark/put/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("put") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_put",
- ]
-}
-
-executable("ledger_benchmark_put") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "put.cc",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/benchmark/put/put.cc b/bin/ledger/tests/benchmark/put/put.cc
deleted file mode 100644
index a9b1fd5..0000000
--- a/bin/ledger/tests/benchmark/put/put.cc
+++ /dev/null
@@ -1,469 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-#include <set>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/zx/time.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/page_data_generator.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-
-// Benchmark that measures performance of the Put() operation.
-//
-// Parameters:
-// --entry-count=<int> the number of entries to be put
-// --transaction-size=<int> the size of a single transaction in number of put
-// operations. If equal to 0, no explicit transactions will be made.
-// --key-size=<int> the size of a single key in bytes
-// --value-size=<int> the size of a single value in bytes
-// --refs=(on|off) the reference strategy: on if every value is inserted
-// as a reference, off if every value is inserted as a FIDL array.
-// --update whether operations will update existing entries (put with existing
-// keys and new values)
-// --seed=<int> (optional) the seed for key and value generation
-class PutBenchmark : public PageWatcher {
- public:
- PutBenchmark(async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- int entry_count, int transaction_size, int key_size,
- int value_size, bool update,
- PageDataGenerator::ReferenceStrategy reference_strategy,
- uint64_t seed);
-
- void Run();
-
- // PageWatcher:
- void OnChange(PageChange page_change, ResultState result_state,
- OnChangeCallback callback) override;
-
- private:
- // Initilizes the keys to be used in the benchmark. In case the benchmark is
- // on updating entries, it also adds these keys in the ledger with some
- // initial values.
- void InitializeKeys(
- fit::function<void(std::vector<std::vector<uint8_t>>)> on_done);
-
- void BindWatcher(std::vector<std::vector<uint8_t>> keys);
- void RunSingle(int i, std::vector<std::vector<uint8_t>> keys);
- void CommitAndRunNext(int i, size_t key_number,
- std::vector<std::vector<uint8_t>> keys);
- void PutEntry(std::vector<uint8_t> key, std::vector<uint8_t> value,
- fit::function<void()> on_done);
-
- void ShutDown();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- DataGenerator generator_;
- PageDataGenerator page_data_generator_;
-
- files::ScopedTempDir tmp_dir_;
- std::unique_ptr<component::StartupContext> startup_context_;
- const int entry_count_;
- const int transaction_size_;
- const int key_size_;
- const int value_size_;
- const bool update_;
-
- fidl::Binding<PageWatcher> page_watcher_binding_;
- const PageDataGenerator::ReferenceStrategy reference_strategy_;
-
- fuchsia::sys::ComponentControllerPtr component_controller_;
- LedgerPtr ledger_;
- PagePtr page_;
- // Keys that we use to identify a change event. For transaction_size = 1 it
- // contains all the keys, otherwise only the last changed key for each
- // transaction.
- std::set<size_t> keys_to_receive_;
- // Whether all Put operations have terminated. Shut down should be blocked
- // until this is set to true.
- bool insertions_finished_ = false;
- // Whether all expected watch notifications have been received. Shut down
- // should be blocked until this is set to true.
- bool all_watcher_notifications_received_ = false;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PutBenchmark);
-};
-
-} // namespace
-} // namespace ledger
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/put";
-
-PutBenchmark::PutBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context, int entry_count,
- int transaction_size, int key_size, int value_size, bool update,
- PageDataGenerator::ReferenceStrategy reference_strategy, uint64_t seed)
- : loop_(loop),
- random_(seed),
- generator_(&random_),
- page_data_generator_(&random_),
- tmp_dir_(kStoragePath),
- startup_context_(std::move(startup_context)),
- entry_count_(entry_count),
- transaction_size_(transaction_size),
- key_size_(key_size),
- value_size_(value_size),
- update_(update),
- page_watcher_binding_(this),
- reference_strategy_(reference_strategy) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(entry_count > 0);
- FXL_DCHECK(transaction_size >= 0);
- FXL_DCHECK(key_size > 0);
- FXL_DCHECK(value_size > 0);
-}
-
-void PutBenchmark::Run() {
- FXL_LOG(INFO) << "--entry-count=" << entry_count_
- << " --transaction-size=" << transaction_size_
- << " --key-size=" << key_size_
- << " --value-size=" << value_size_ << " --refs="
- << (reference_strategy_ ==
- PageDataGenerator::ReferenceStrategy::INLINE
- ? "off"
- : "on")
- << (update_ ? " --update" : "");
- Status status = GetLedger(
- startup_context_.get(), component_controller_.NewRequest(), nullptr, "",
- "put", DetachedPath(tmp_dir_.path()), QuitLoopClosure(), &ledger_);
- if (QuitOnError(QuitLoopClosure(), status, "GetLedger")) {
- return;
- }
-
- GetPageEnsureInitialized(
- &ledger_, nullptr, DelayCallback::YES, QuitLoopClosure(),
- [this](Status status, PagePtr page, PageId id) mutable {
- if (QuitOnError(QuitLoopClosure(), status,
- "GetPageEnsureInitialized")) {
- return;
- }
- page_ = std::move(page);
-
- InitializeKeys([this](std::vector<std::vector<uint8_t>> keys) mutable {
- if (transaction_size_ > 0) {
- page_->StartTransaction(
- [this, keys = std::move(keys)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status,
- "Page::StartTransaction")) {
- return;
- }
- TRACE_ASYNC_BEGIN("benchmark", "transaction", 0);
- BindWatcher(std::move(keys));
- });
- } else {
- BindWatcher(std::move(keys));
- }
- });
- });
-}
-
-void PutBenchmark::OnChange(PageChange page_change,
- ResultState /*result_state*/,
- OnChangeCallback callback) {
- for (auto const& change : page_change.changed_entries) {
- size_t key_number = generator_.GetKeyId(change.key);
- if (keys_to_receive_.find(key_number) != keys_to_receive_.end()) {
- TRACE_ASYNC_END("benchmark", "local_change_notification", key_number);
- keys_to_receive_.erase(key_number);
- }
- }
- if (keys_to_receive_.empty()) {
- all_watcher_notifications_received_ = true;
- // All watcher notifications have been received, waiting for put operations
- // to finish before shutting down.
- if (insertions_finished_) {
- ShutDown();
- }
- }
- callback(nullptr);
-}
-
-void PutBenchmark::InitializeKeys(
- fit::function<void(std::vector<std::vector<uint8_t>>)> on_done) {
- std::vector<std::vector<uint8_t>> keys =
- generator_.MakeKeys(entry_count_, key_size_, entry_count_);
- std::vector<std::vector<uint8_t>> keys_cloned;
- for (int i = 0; i < entry_count_; ++i) {
- keys_cloned.push_back(keys[i]);
- if (transaction_size_ == 0 ||
- i % transaction_size_ == transaction_size_ - 1) {
- keys_to_receive_.insert(generator_.GetKeyId(keys[i]));
- }
- }
- // Last key should always be recorded so the last transaction is not lost.
- size_t last_key_number = generator_.GetKeyId(keys.back());
- keys_to_receive_.insert(last_key_number);
- if (!update_) {
- on_done(std::move(keys));
- return;
- }
- page_data_generator_.Populate(
- &page_, std::move(keys_cloned), value_size_, keys_cloned.size(),
- reference_strategy_, Priority::EAGER,
- [this, keys = std::move(keys),
- on_done = std::move(on_done)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status,
- "PageDataGenerator::Populate")) {
- return;
- }
- on_done(std::move(keys));
- });
-}
-
-void PutBenchmark::BindWatcher(std::vector<std::vector<uint8_t>> keys) {
- PageSnapshotPtr snapshot;
- page_->GetSnapshot(
- snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- page_watcher_binding_.NewBinding(),
- [this, keys = std::move(keys)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status, "GetSnapshot")) {
- return;
- }
- RunSingle(0, std::move(keys));
- });
-}
-
-void PutBenchmark::RunSingle(int i, std::vector<std::vector<uint8_t>> keys) {
- if (i == entry_count_) {
- insertions_finished_ = true;
- // All sent, waiting for watcher notifications before shutting down.
- if (all_watcher_notifications_received_) {
- ShutDown();
- }
- return;
- }
-
- fidl::VectorPtr<uint8_t> value = generator_.MakeValue(value_size_);
- size_t key_number = generator_.GetKeyId(keys[i]);
- if (transaction_size_ == 0) {
- TRACE_ASYNC_BEGIN("benchmark", "local_change_notification", key_number);
- }
- PutEntry(std::move(keys[i]), std::move(value),
- [this, i, key_number, keys = std::move(keys)]() mutable {
- if (transaction_size_ > 0 &&
- (i % transaction_size_ == transaction_size_ - 1 ||
- i + 1 == entry_count_)) {
- CommitAndRunNext(i, key_number, std::move(keys));
- } else {
- RunSingle(i + 1, std::move(keys));
- }
- });
-}
-
-void PutBenchmark::PutEntry(std::vector<uint8_t> key,
- std::vector<uint8_t> value,
- fit::function<void()> on_done) {
- auto trace_event_id = TRACE_NONCE();
- TRACE_ASYNC_BEGIN("benchmark", "put", trace_event_id);
- if (reference_strategy_ == PageDataGenerator::ReferenceStrategy::INLINE) {
- page_->Put(
- std::move(key), std::move(value),
- [this, trace_event_id, on_done = std::move(on_done)](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "Page::Put")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "put", trace_event_id);
- on_done();
- });
- return;
- }
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(convert::ToStringView(value), &vmo));
- TRACE_ASYNC_BEGIN("benchmark", "create_reference", trace_event_id);
- page_->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- [this, trace_event_id, key = std::move(key),
- on_done = std::move(on_done)](Status status,
- ReferencePtr reference) mutable {
- if (QuitOnError(QuitLoopClosure(), status,
- "Page::CreateReferenceFromBuffer")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "create_reference", trace_event_id);
- TRACE_ASYNC_BEGIN("benchmark", "put_reference", trace_event_id);
- page_->PutReference(
- std::move(key), std::move(*reference), Priority::EAGER,
- [this, trace_event_id,
- on_done = std::move(on_done)](Status status) {
- if (QuitOnError(QuitLoopClosure(), status,
- "Page::PutReference")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "put_reference", trace_event_id);
- TRACE_ASYNC_END("benchmark", "put", trace_event_id);
- on_done();
- });
- });
-}
-
-void PutBenchmark::CommitAndRunNext(int i, size_t key_number,
- std::vector<std::vector<uint8_t>> keys) {
- TRACE_ASYNC_BEGIN("benchmark", "local_change_notification", key_number);
- TRACE_ASYNC_BEGIN("benchmark", "commit", i / transaction_size_);
- page_->Commit([this, i, keys = std::move(keys)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status, "Page::Commit")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "commit", i / transaction_size_);
- TRACE_ASYNC_END("benchmark", "transaction", i / transaction_size_);
-
- if (i == entry_count_ - 1) {
- RunSingle(i + 1, std::move(keys));
- return;
- }
- page_->StartTransaction([this, i = i + 1,
- keys = std::move(keys)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status, "Page::StartTransaction")) {
- return;
- }
- TRACE_ASYNC_BEGIN("benchmark", "transaction", i / transaction_size_);
- RunSingle(i, std::move(keys));
- });
- });
-}
-
-void PutBenchmark::ShutDown() {
- // Shut down the Ledger process first as it relies on |tmp_dir_| storage.
- KillLedgerProcess(&component_controller_);
- loop_->Quit();
-}
-
-fit::closure PutBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-} // namespace
-} // namespace ledger
-
-namespace ledger {
-namespace {
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/put.cmx";
-constexpr fxl::StringView kEntryCountFlag = "entry-count";
-constexpr fxl::StringView kTransactionSizeFlag = "transaction-size";
-constexpr fxl::StringView kKeySizeFlag = "key-size";
-constexpr fxl::StringView kValueSizeFlag = "value-size";
-constexpr fxl::StringView kRefsFlag = "refs";
-constexpr fxl::StringView kUpdateFlag = "update";
-constexpr fxl::StringView kSeedFlag = "seed";
-
-constexpr fxl::StringView kRefsOnFlag = "on";
-constexpr fxl::StringView kRefsOffFlag = "off";
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kEntryCountFlag << "=<int>"
- << " --" << kTransactionSizeFlag << "=<int>"
- << " --" << kKeySizeFlag << "=<int>"
- << " --" << kValueSizeFlag << "=<int>"
- << " --" << kRefsFlag << "=(" << kRefsOnFlag << "|" << kRefsOffFlag
- << ")"
- << " [--" << kSeedFlag << "=<int>]"
- << " [--" << kUpdateFlag << "]" << std::endl;
-}
-
-bool GetPositiveIntValue(const fxl::CommandLine& command_line,
- fxl::StringView flag, int* value) {
- std::string value_str;
- int found_value;
- if (!command_line.GetOptionValue(flag.ToString(), &value_str) ||
- !fxl::StringToNumberWithError(value_str, &found_value) ||
- found_value <= 0) {
- return false;
- }
- *value = found_value;
- return true;
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- int entry_count;
- std::string transaction_size_str;
- int transaction_size;
- int key_size;
- int value_size;
- bool update = command_line.HasOption(kUpdateFlag.ToString());
- if (!GetPositiveIntValue(command_line, kEntryCountFlag, &entry_count) ||
- !command_line.GetOptionValue(kTransactionSizeFlag.ToString(),
- &transaction_size_str) ||
- !fxl::StringToNumberWithError(transaction_size_str, &transaction_size) ||
- transaction_size < 0 ||
- !GetPositiveIntValue(command_line, kKeySizeFlag, &key_size) ||
- !GetPositiveIntValue(command_line, kValueSizeFlag, &value_size)) {
- PrintUsage();
- return -1;
- }
-
- std::string ref_strategy_str;
- if (!command_line.GetOptionValue(kRefsFlag.ToString(), &ref_strategy_str)) {
- PrintUsage();
- return -1;
- }
- PageDataGenerator::ReferenceStrategy ref_strategy;
- if (ref_strategy_str == kRefsOnFlag) {
- ref_strategy = PageDataGenerator::ReferenceStrategy::REFERENCE;
- } else if (ref_strategy_str == kRefsOffFlag) {
- ref_strategy = PageDataGenerator::ReferenceStrategy::INLINE;
- } else {
- std::cerr << "Unknown option " << ref_strategy_str << " for "
- << kRefsFlag.ToString() << std::endl;
- PrintUsage();
- return -1;
- }
-
- int seed;
- std::string seed_str;
- if (command_line.GetOptionValue(kSeedFlag.ToString(), &seed_str)) {
- if (!fxl::StringToNumberWithError(seed_str, &seed)) {
- PrintUsage();
- return -1;
- }
- } else {
- seed = 0;
- }
-
- PutBenchmark app(&loop, std::move(startup_context), entry_count,
- transaction_size, key_size, value_size, update, ref_strategy,
- seed);
-
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/put/put.cmx b/bin/ledger/tests/benchmark/put/put.cmx
deleted file mode 100644
index ef59202..0000000
--- a/bin/ledger/tests/benchmark/put/put.cmx
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_put"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/put/put.tspec b/bin/ledger/tests/benchmark/put/put.tspec
deleted file mode 100644
index 64f3495..0000000
--- a/bin/ledger/tests/benchmark/put/put.tspec
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.put_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/put.cmx",
- "args": [
- "--entry-count=100", "--transaction-size=0", "--key-size=100",
- "--value-size=1000", "--refs=off"
- ],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "small_value/put",
- "event_name": "put",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "small_value/local_change_notification",
- "event_name": "local_change_notification",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/put/put_as_reference.tspec b/bin/ledger/tests/benchmark/put/put_as_reference.tspec
deleted file mode 100644
index c63fc74..0000000
--- a/bin/ledger/tests/benchmark/put/put_as_reference.tspec
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.put_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/put.cmx",
- "args": [
- "--entry-count=100", "--transaction-size=0", "--key-size=100",
- "--value-size=1000", "--refs=on"
- ],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "reference/put",
- "event_name": "put",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "reference/create_reference",
- "event_name": "create_reference",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "reference/put_reference",
- "event_name": "put_reference",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "reference/local_change_notification",
- "event_name": "local_change_notification",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/put/put_big_entry.tspec b/bin/ledger/tests/benchmark/put/put_big_entry.tspec
deleted file mode 100644
index f9048b6..0000000
--- a/bin/ledger/tests/benchmark/put/put_big_entry.tspec
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.put_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/put.cmx",
- "args": [
- "--entry-count=100", "--transaction-size=0", "--key-size=100",
- "--value-size=20000", "--refs=off"
- ],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "big_value/put",
- "event_name": "put",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "big_value/local_change_notification",
- "event_name": "local_change_notification",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/put/transaction.tspec b/bin/ledger/tests/benchmark/put/transaction.tspec
deleted file mode 100644
index 4588c3a..0000000
--- a/bin/ledger/tests/benchmark/put/transaction.tspec
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.put_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/put.cmx",
- "args": [
- "--entry-count=100", "--transaction-size=10", "--key-size=100",
- "--value-size=1000", "--refs=off"
- ],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "transaction/transaction",
- "event_name": "transaction",
- "event_category": "benchmark",
- "expected_sample_count": 10,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "transaction/commit",
- "event_name": "commit",
- "event_category": "benchmark",
- "expected_sample_count": 10,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "transaction/put",
- "event_name": "put",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- },
- {
- "type": "duration",
- "output_test_name": "transaction/local_change_notification",
- "event_name": "local_change_notification",
- "event_category": "benchmark",
- "expected_sample_count": 10,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/sync/BUILD.gn b/bin/ledger/tests/benchmark/sync/BUILD.gn
deleted file mode 100644
index f1cc292..0000000
--- a/bin/ledger/tests/benchmark/sync/BUILD.gn
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("sync") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_sync",
- ]
-}
-
-executable("ledger_benchmark_sync") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/cloud_provider_firestore/testing",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "sync.cc",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/benchmark/sync/sync.cc b/bin/ledger/tests/benchmark/sync/sync.cc
deleted file mode 100644
index d0cc4df..0000000
--- a/bin/ledger/tests/benchmark/sync/sync.cc
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/zx/time.h>
-#include <trace/event.h>
-
-#include "peridot/bin/cloud_provider_firestore/testing/cloud_provider_factory.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/page_data_generator.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/bin/ledger/testing/sync_params.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/sync.cmx";
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/sync";
-constexpr fxl::StringView kChangeCountFlag = "change-count";
-constexpr fxl::StringView kValueSizeFlag = "value-size";
-constexpr fxl::StringView kEntriesPerChangeFlag = "entries-per-change";
-constexpr fxl::StringView kRefsFlag = "refs";
-
-constexpr fxl::StringView kRefsOnFlag = "on";
-constexpr fxl::StringView kRefsOffFlag = "off";
-
-constexpr size_t kKeySize = 100;
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kChangeCountFlag << "=<int>"
- << " --" << kValueSizeFlag << "=<int>"
- << " --" << kEntriesPerChangeFlag << "=<int>"
- << " --" << kRefsFlag << "=(" << kRefsOnFlag << "|" << kRefsOffFlag
- << ")" << GetSyncParamsUsage() << std::endl;
-}
-
-// Benchmark that measures sync latency between two Ledger instances syncing
-// through the cloud. This emulates syncing between devices, as the Ledger
-// instances have separate disk storage.
-//
-// Cloud sync needs to be configured on the device in order for the benchmark to
-// run.
-//
-// Parameters:
-// --change-count=<int> the number of changes to be made to the page (each
-// change is done as transaction and can include several put operations).
-// --value-size=<int> the size of a single value in bytes
-// --entries-per-change=<int> number of entries added in the transaction
-// --refs=(on|off) reference strategy: on to put values as references, off to
-// put them as FIDL arrays.
-// --credentials-path=<file path> Firestore service account credentials
-class SyncBenchmark : public PageWatcher {
- public:
- SyncBenchmark(async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t change_count, size_t value_size,
- size_t entries_per_change,
- PageDataGenerator::ReferenceStrategy reference_strategy,
- SyncParams sync_params);
-
- void Run();
-
- // PageWatcher:
- void OnChange(PageChange page_change, ResultState result_state,
- OnChangeCallback callback) override;
-
- private:
- void RunSingleChange(size_t change_number);
-
- void ShutDown();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- DataGenerator generator_;
- PageDataGenerator page_data_generator_;
- std::unique_ptr<component::StartupContext> startup_context_;
- cloud_provider_firestore::CloudProviderFactory cloud_provider_factory_;
- const size_t change_count_;
- const size_t value_size_;
- const size_t entries_per_change_;
- const PageDataGenerator::ReferenceStrategy reference_strategy_;
- const cloud_provider_firestore::CloudProviderFactory::UserId user_id_;
- fidl::Binding<PageWatcher> page_watcher_binding_;
- files::ScopedTempDir alpha_tmp_dir_;
- files::ScopedTempDir beta_tmp_dir_;
- fuchsia::sys::ComponentControllerPtr alpha_controller_;
- fuchsia::sys::ComponentControllerPtr beta_controller_;
- LedgerPtr alpha_;
- LedgerPtr beta_;
- PageId page_id_;
- PagePtr alpha_page_;
- PagePtr beta_page_;
-
- size_t changed_entries_received_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SyncBenchmark);
-};
-
-SyncBenchmark::SyncBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- size_t change_count, size_t value_size, size_t entries_per_change,
- PageDataGenerator::ReferenceStrategy reference_strategy,
- SyncParams sync_params)
- : loop_(loop),
- random_(0),
- generator_(&random_),
- page_data_generator_(&random_),
- startup_context_(std::move(startup_context)),
- cloud_provider_factory_(startup_context_.get(), &random_,
- std::move(sync_params.api_key),
- std::move(sync_params.credentials)),
- change_count_(change_count),
- value_size_(value_size),
- entries_per_change_(entries_per_change),
- reference_strategy_(reference_strategy),
- user_id_(cloud_provider_firestore::CloudProviderFactory::UserId::New()),
- page_watcher_binding_(this),
- alpha_tmp_dir_(kStoragePath),
- beta_tmp_dir_(kStoragePath) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(change_count_ > 0);
- FXL_DCHECK(value_size_ > 0);
- FXL_DCHECK(entries_per_change_ > 0);
- cloud_provider_factory_.Init();
-}
-
-void SyncBenchmark::Run() {
- // Name of the storage directory currently identifies the user. Ensure the
- // most nested directory has the same name to make the ledgers sync.
- std::string alpha_path = alpha_tmp_dir_.path() + "/sync_user";
- bool ret = files::CreateDirectory(alpha_path);
- FXL_DCHECK(ret);
-
- std::string beta_path = beta_tmp_dir_.path() + "/sync_user";
- ret = files::CreateDirectory(beta_path);
- FXL_DCHECK(ret);
-
- cloud_provider::CloudProviderPtr cloud_provider_alpha;
- cloud_provider_factory_.MakeCloudProvider(user_id_,
- cloud_provider_alpha.NewRequest());
- Status status = GetLedger(
- startup_context_.get(), alpha_controller_.NewRequest(),
- std::move(cloud_provider_alpha), user_id_.user_id(), "sync",
- DetachedPath(std::move(alpha_path)), QuitLoopClosure(), &alpha_);
- if (QuitOnError(QuitLoopClosure(), status, "alpha ledger")) {
- return;
- };
-
- cloud_provider::CloudProviderPtr cloud_provider_beta;
- cloud_provider_factory_.MakeCloudProvider(user_id_,
- cloud_provider_beta.NewRequest());
-
- status = GetLedger(startup_context_.get(), beta_controller_.NewRequest(),
- std::move(cloud_provider_beta), user_id_.user_id(), "sync",
- DetachedPath(beta_path), QuitLoopClosure(), &beta_);
- if (QuitOnError(QuitLoopClosure(), status, "beta ledger")) {
- return;
- }
- GetPageEnsureInitialized(
- &alpha_, nullptr, DelayCallback::YES, QuitLoopClosure(),
- [this](Status status, PagePtr page, PageId id) {
- if (QuitOnError(QuitLoopClosure(), status,
- "alpha page initialization")) {
- return;
- }
- alpha_page_ = std::move(page);
- page_id_ = id;
- beta_->GetPage(fidl::MakeOptional(id), beta_page_.NewRequest(),
- QuitOnErrorCallback(QuitLoopClosure(), "GetPage"));
-
- PageSnapshotPtr snapshot;
- beta_page_->GetSnapshot(
- snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- page_watcher_binding_.NewBinding(), [this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status, "GetSnapshot")) {
- return;
- }
- RunSingleChange(0);
- });
- });
-}
-
-void SyncBenchmark::OnChange(PageChange page_change, ResultState result_state,
- OnChangeCallback callback) {
- FXL_DCHECK(!page_change.changed_entries.empty());
- size_t i = generator_.GetKeyId(page_change.changed_entries.at(0).key);
- changed_entries_received_ += page_change.changed_entries.size();
- if (result_state == ResultState::COMPLETED ||
- result_state == ResultState::PARTIAL_STARTED) {
- TRACE_ASYNC_END("benchmark", "sync latency", i);
- }
- if (result_state == ResultState::COMPLETED ||
- result_state == ResultState::PARTIAL_COMPLETED) {
- FXL_DCHECK(changed_entries_received_ == entries_per_change_);
- RunSingleChange(i + 1);
- }
- callback(nullptr);
-}
-
-void SyncBenchmark::RunSingleChange(size_t change_number) {
- if (change_number == change_count_) {
- ShutDown();
- return;
- }
-
- std::vector<std::vector<uint8_t>> keys(entries_per_change_);
- for (size_t i = 0; i < entries_per_change_; i++) {
- // Keys are distinct, but they all have the same id (|change_number|), which
- // will be used to end the trace.
- keys[i] = generator_.MakeKey(change_number, kKeySize);
- }
-
- changed_entries_received_ = 0;
- TRACE_ASYNC_BEGIN("benchmark", "sync latency", change_number);
- page_data_generator_.Populate(
- &alpha_page_, std::move(keys), value_size_, entries_per_change_,
- reference_strategy_, Priority::EAGER, [this](Status status) {
- if (QuitOnError(QuitLoopClosure(), status,
- "PageDataGenerator::Populate")) {
- return;
- }
- });
-}
-
-void SyncBenchmark::ShutDown() {
- KillLedgerProcess(&alpha_controller_);
- KillLedgerProcess(&beta_controller_);
- loop_->Quit();
-}
-
-fit::closure SyncBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- std::string change_count_str;
- size_t change_count;
- std::string value_size_str;
- size_t value_size;
- std::string entries_per_change_str;
- size_t entries_per_change;
- std::string reference_strategy_str;
- SyncParams sync_params;
- if (!command_line.GetOptionValue(kChangeCountFlag.ToString(),
- &change_count_str) ||
- !fxl::StringToNumberWithError(change_count_str, &change_count) ||
- change_count <= 0 ||
- !command_line.GetOptionValue(kValueSizeFlag.ToString(),
- &value_size_str) ||
- !fxl::StringToNumberWithError(value_size_str, &value_size) ||
- value_size <= 0 ||
- !command_line.GetOptionValue(kEntriesPerChangeFlag.ToString(),
- &entries_per_change_str) ||
- !fxl::StringToNumberWithError(entries_per_change_str,
- &entries_per_change) ||
- !command_line.GetOptionValue(kRefsFlag.ToString(),
- &reference_strategy_str) ||
- !ParseSyncParamsFromCommandLine(command_line, startup_context.get(),
- &sync_params)) {
- PrintUsage();
- return -1;
- }
-
- PageDataGenerator::ReferenceStrategy reference_strategy;
- if (reference_strategy_str == kRefsOnFlag) {
- reference_strategy = PageDataGenerator::ReferenceStrategy::REFERENCE;
- } else if (reference_strategy_str == kRefsOffFlag) {
- reference_strategy = PageDataGenerator::ReferenceStrategy::INLINE;
- } else {
- std::cerr << "Unknown option " << reference_strategy_str << " for "
- << kRefsFlag.ToString() << std::endl;
- PrintUsage();
- return -1;
- }
-
- SyncBenchmark app(&loop, std::move(startup_context), change_count, value_size,
- entries_per_change, reference_strategy,
- std::move(sync_params));
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/sync/sync.cmx b/bin/ledger/tests/benchmark/sync/sync.cmx
deleted file mode 100644
index eea9b39..0000000
--- a/bin/ledger/tests/benchmark/sync/sync.cmx
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_sync"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/sync/sync.tspec b/bin/ledger/tests/benchmark/sync/sync.tspec
deleted file mode 100644
index b3b731a..0000000
--- a/bin/ledger/tests/benchmark/sync/sync.tspec
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/sync.cmx",
- "args": ["--change-count=10", "--entries-per-change=1", "--value-size=100",
- "--refs=off"],
- "categories": ["benchmark", "ledger"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "event_name": "sync latency",
- "event_category": "benchmark",
- "expected_sample_count": 10,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/sync/sync_big_change.tspec b/bin/ledger/tests/benchmark/sync/sync_big_change.tspec
deleted file mode 100644
index 6f14baf..0000000
--- a/bin/ledger/tests/benchmark/sync/sync_big_change.tspec
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/sync.cmx",
- "args": ["--change-count=10", "--entries-per-change=100", "--value-size=100",
- "--refs=off"],
- "categories": ["benchmark", "ledger"],
- "duration": 240,
- "measure": [
- {
- "type": "duration",
- "event_name": "sync latency",
- "event_category": "benchmark",
- "expected_sample_count": 10
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/update_entry/BUILD.gn b/bin/ledger/tests/benchmark/update_entry/BUILD.gn
deleted file mode 100644
index 2f501d7..0000000
--- a/bin/ledger/tests/benchmark/update_entry/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-group("update_entry") {
- testonly = true
-
- public_deps = [
- ":ledger_benchmark_update_entry",
- ]
-}
-
-executable("ledger_benchmark_update_entry") {
- testonly = true
-
- deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/public/fidl/fuchsia.ledger",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- "//zircon/public/lib/trace-provider",
- ]
-
- sources = [
- "update_entry.cc",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/benchmark/update_entry/update_big_entry.tspec b/bin/ledger/tests/benchmark/update_entry/update_big_entry.tspec
deleted file mode 100644
index 0fe0524..0000000
--- a/bin/ledger/tests/benchmark/update_entry/update_big_entry.tspec
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.update_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/update_entry.cmx",
- "args": ["--entry-count=100", "--transaction-size=0", "--value-size=20000"],
- "categories": ["benchmark", "ledger"],
- "duration": 180,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "big_value/put",
- "event_name": "put",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/update_entry/update_entry.cc b/bin/ledger/tests/benchmark/update_entry/update_entry.cc
deleted file mode 100644
index b076080..0000000
--- a/bin/ledger/tests/benchmark/update_entry/update_entry.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-#include <memory>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/zx/time.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_ledger.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/testing/quit_on_error.h"
-#include "peridot/bin/ledger/testing/run_with_tracing.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/rng/test_random.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kBinaryPath =
- "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/update_entry.cmx";
-constexpr fxl::StringView kStoragePath = "/data/benchmark/ledger/update_entry";
-constexpr fxl::StringView kEntryCountFlag = "entry-count";
-constexpr fxl::StringView kValueSizeFlag = "value-size";
-constexpr fxl::StringView kTransactionSizeFlag = "transaction-size";
-
-const int kKeySize = 100;
-
-void PrintUsage() {
- std::cout << "Usage: trace record "
- << kBinaryPath
- // Comment to make clang format not break formatting.
- << " --" << kEntryCountFlag << "=<int>"
- << " --" << kValueSizeFlag << "=<int>"
- << " --" << kTransactionSizeFlag << "=<int>" << std::endl;
-}
-
-// Benchmark that measures a performance of Put() operation under the condition
-// that it modifies the same entry.
-//
-// Parameters:
-// --entry-count=<int> the number of entries to be put
-// --value-size=<int> the size of the value for each entry
-// --transaction-size=<int> the size of a single transaction in number of put
-// operations. If equal to 0, every put operation will be executed
-// individually (implicit transaction).
-class UpdateEntryBenchmark {
- public:
- UpdateEntryBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context,
- int entry_count, int value_size, int transaction_size);
-
- void Run();
-
- private:
- void RunSingle(int i, std::vector<uint8_t> key);
- void CommitAndRunNext(int i, std::vector<uint8_t> key);
-
- void ShutDown();
- fit::closure QuitLoopClosure();
-
- async::Loop* const loop_;
- rng::TestRandom random_;
- DataGenerator generator_;
-
- files::ScopedTempDir tmp_dir_;
- std::unique_ptr<component::StartupContext> startup_context_;
- const int entry_count_;
- const int transaction_size_;
- const int key_size_;
- const int value_size_;
-
- fuchsia::sys::ComponentControllerPtr component_controller_;
- LedgerPtr ledger_;
- PagePtr page_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(UpdateEntryBenchmark);
-};
-
-UpdateEntryBenchmark::UpdateEntryBenchmark(
- async::Loop* loop,
- std::unique_ptr<component::StartupContext> startup_context, int entry_count,
- int value_size, int transaction_size)
- : loop_(loop),
- random_(0),
- generator_(&random_),
- tmp_dir_(kStoragePath),
- startup_context_(std::move(startup_context)),
- entry_count_(entry_count),
- transaction_size_(transaction_size),
- key_size_(kKeySize),
- value_size_(value_size) {
- FXL_DCHECK(loop_);
- FXL_DCHECK(entry_count_ > 0);
- FXL_DCHECK(value_size_ > 0);
- FXL_DCHECK(key_size_ > 0);
- FXL_DCHECK(transaction_size_ >= 0);
-}
-
-void UpdateEntryBenchmark::Run() {
- FXL_LOG(INFO) << "--entry-count=" << entry_count_
- << " --transaction-size=" << transaction_size_;
- Status status =
- GetLedger(startup_context_.get(), component_controller_.NewRequest(),
- nullptr, "", "update_entry", DetachedPath(tmp_dir_.path()),
- QuitLoopClosure(), &ledger_);
- if (QuitOnError(QuitLoopClosure(), status, "GetLedger")) {
- return;
- }
- GetPageEnsureInitialized(
- &ledger_, nullptr, DelayCallback::YES, QuitLoopClosure(),
- [this](Status status, PagePtr page, PageId id) {
- if (QuitOnError(QuitLoopClosure(), status,
- "GetPageEnsureInitialized")) {
- return;
- }
- page_ = std::move(page);
- std::vector<uint8_t> key = generator_.MakeKey(0, key_size_);
- if (transaction_size_ > 0) {
- page_->StartTransaction(
- [this, key = std::move(key)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status,
- "Page::StartTransaction")) {
- return;
- }
- TRACE_ASYNC_BEGIN("benchmark", "transaction", 0);
- RunSingle(0, std::move(key));
- });
- } else {
- RunSingle(0, std::move(key));
- }
- });
-}
-
-void UpdateEntryBenchmark::RunSingle(int i, std::vector<uint8_t> key) {
- if (i == entry_count_) {
- ShutDown();
- return;
- }
-
- std::vector<uint8_t> value = generator_.MakeValue(value_size_);
- TRACE_ASYNC_BEGIN("benchmark", "put", i);
- page_->Put(key, std::move(value),
- [this, i, key = std::move(key)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status, "Page::Put")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "put", i);
- if (transaction_size_ > 0 &&
- (i % transaction_size_ == transaction_size_ - 1 ||
- i + 1 == entry_count_)) {
- CommitAndRunNext(i, std::move(key));
- } else {
- RunSingle(i + 1, std::move(key));
- }
- });
-}
-
-void UpdateEntryBenchmark::CommitAndRunNext(int i,
- std::vector<uint8_t> key) {
- TRACE_ASYNC_BEGIN("benchmark", "commit", i / transaction_size_);
- page_->Commit([this, i, key = std::move(key)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status, "Page::Commit")) {
- return;
- }
- TRACE_ASYNC_END("benchmark", "commit", i / transaction_size_);
- TRACE_ASYNC_END("benchmark", "transaction", i / transaction_size_);
-
- if (i == entry_count_ - 1) {
- RunSingle(i + 1, std::move(key));
- return;
- }
- page_->StartTransaction([this, i = i + 1,
- key = std::move(key)](Status status) mutable {
- if (QuitOnError(QuitLoopClosure(), status, "Page::StartTransaction")) {
- return;
- }
- TRACE_ASYNC_BEGIN("benchmark", "transaction", i / transaction_size_);
- RunSingle(i, std::move(key));
- });
- });
-}
-
-void UpdateEntryBenchmark::ShutDown() {
- // Shut down the Ledger process first as it relies on |tmp_dir_| storage.
- KillLedgerProcess(&component_controller_);
- loop_->Quit();
-}
-
-fit::closure UpdateEntryBenchmark::QuitLoopClosure() {
- return [this] { loop_->Quit(); };
-}
-
-int Main(int argc, const char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- std::string entry_count_str;
- size_t entry_count;
- std::string value_size_str;
- int value_size;
- std::string transaction_size_str;
- int transaction_size;
- if (!command_line.GetOptionValue(kEntryCountFlag.ToString(),
- &entry_count_str) ||
- !fxl::StringToNumberWithError(entry_count_str, &entry_count) ||
- entry_count <= 0 ||
- !command_line.GetOptionValue(kValueSizeFlag.ToString(),
- &value_size_str) ||
- !fxl::StringToNumberWithError(value_size_str, &value_size) ||
- value_size <= 0 ||
- !command_line.GetOptionValue(kTransactionSizeFlag.ToString(),
- &transaction_size_str) ||
- !fxl::StringToNumberWithError(transaction_size_str, &transaction_size) ||
- transaction_size < 0) {
- PrintUsage();
- return -1;
- }
-
- UpdateEntryBenchmark app(&loop, std::move(startup_context), entry_count,
- value_size, transaction_size);
- return RunWithTracing(&loop, [&app] { app.Run(); });
-}
-
-} // namespace
-} // namespace ledger
-
-int main(int argc, const char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/benchmark/update_entry/update_entry.cmx b/bin/ledger/tests/benchmark/update_entry/update_entry.cmx
deleted file mode 100644
index 92c10fa..0000000
--- a/bin/ledger/tests/benchmark/update_entry/update_entry.cmx
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "program": {
- "binary": "bin/ledger_benchmark_update_entry"
- },
- "sandbox": {
- "features": [
- "persistent-storage"
- ],
- "services": [
- "fuchsia.tracelink.Registry",
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/benchmark/update_entry/update_entry.tspec b/bin/ledger/tests/benchmark/update_entry/update_entry.tspec
deleted file mode 100644
index b4570c0..0000000
--- a/bin/ledger/tests/benchmark/update_entry/update_entry.tspec
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.update_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/update_entry.cmx",
- "args": ["--entry-count=100", "--transaction-size=0", "--value-size=1000"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "small_value/put",
- "event_name": "put",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/benchmark/update_entry/update_entry_transactions.tspec b/bin/ledger/tests/benchmark/update_entry/update_entry_transactions.tspec
deleted file mode 100644
index 70775a3..0000000
--- a/bin/ledger/tests/benchmark/update_entry/update_entry_transactions.tspec
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "test_suite_name": "fuchsia.ledger.update_entry",
- "app": "fuchsia-pkg://fuchsia.com/ledger_benchmarks#meta/update_entry.cmx",
- "args": ["--entry-count=100", "--transaction-size=10", "--value-size=1000"],
- "categories": ["benchmark", "ledger"],
- "duration": 60,
- "measure": [
- {
- "type": "duration",
- "output_test_name": "transaction/transaction",
- "event_name": "transaction",
- "event_category": "benchmark",
- "expected_sample_count": 10,
- "split_first": true
- },
-
- {
- "type": "duration",
- "output_test_name": "transaction/commit",
- "event_name": "commit",
- "event_category": "benchmark",
- "expected_sample_count": 10,
- "split_first": true
- },
-
- {
- "type": "duration",
- "output_test_name": "transaction/put",
- "event_name": "put",
- "event_category": "benchmark",
- "expected_sample_count": 100,
- "split_first": true
- }
- ]
-}
diff --git a/bin/ledger/tests/cloud_provider/BUILD.gn b/bin/ledger/tests/cloud_provider/BUILD.gn
deleted file mode 100644
index e0c4625..0000000
--- a/bin/ledger/tests/cloud_provider/BUILD.gn
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-executable("cloud_provider") {
- testonly = true
-
- output_name = "cloud_provider_validation_tests"
-
- sources = [
- "convert.cc",
- "convert.h",
- "device_set_test.cc",
- "page_cloud_test.cc",
- "types.h",
- "validation_test.cc",
- "validation_test.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//peridot/lib/commit_pack",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/ledger/tests/cloud_provider/README.md b/bin/ledger/tests/cloud_provider/README.md
deleted file mode 100644
index 6cd8ad6..0000000
--- a/bin/ledger/tests/cloud_provider/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Validation Test Suite for cloud providers
-
-This directory contains implementation-independent tests for implementations of
-the [CloudProvider] interface.
-
-In order to run the tests, run the `cloud_provider_validation_tests` binary with
-the cloud provider implementation exposed to it via the `svc` directory.
-
-We expect that individual cloud provider implementations would develop custom
-launcher applications that configure and run the validation tests against their
-implementation of CloudProvider ([example]).
-
-[CloudProvider]: /public/fidl/fuchsia.ledger.cloud/cloud_provider.fidl
-[example]: /bin/cloud_provider_firestore/validation/
diff --git a/bin/ledger/tests/cloud_provider/cloud_provider_validation_tests.cmx b/bin/ledger/tests/cloud_provider/cloud_provider_validation_tests.cmx
deleted file mode 100644
index 59e8a0b..0000000
--- a/bin/ledger/tests/cloud_provider/cloud_provider_validation_tests.cmx
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "program": {
- "binary": "test/disabled/cloud_provider_validation_tests"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.ledger.cloud.CloudProvider"
- ]
- }
-}
diff --git a/bin/ledger/tests/cloud_provider/convert.cc b/bin/ledger/tests/cloud_provider/convert.cc
deleted file mode 100644
index 8c3a2e9..0000000
--- a/bin/ledger/tests/cloud_provider/convert.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/tests/cloud_provider/convert.h"
-
-namespace cloud_provider {
-
-namespace {
-const char kHexDigits[] = "0123456789ABCDEF";
-}
-
-fidl::VectorPtr<uint8_t> ToArray(const std::string& val) {
- fidl::VectorPtr<uint8_t> ret(val.size());
- memcpy(ret->data(), val.data(), val.size());
- return ret;
-}
-
-std::string ToString(const fidl::VectorPtr<uint8_t>& bytes) {
- return std::string(reinterpret_cast<const char*>(bytes->data()),
- bytes->size());
-}
-
-std::string ToHex(const std::string& bytes) {
- std::string result;
- result.reserve(bytes.size() * 2);
- for (unsigned char c : bytes) {
- result.push_back(kHexDigits[c >> 4]);
- result.push_back(kHexDigits[c & 0xf]);
- }
- return result;
-}
-
-} // namespace cloud_provider
diff --git a/bin/ledger/tests/cloud_provider/convert.h b/bin/ledger/tests/cloud_provider/convert.h
deleted file mode 100644
index 762e852..0000000
--- a/bin/ledger/tests/cloud_provider/convert.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_CONVERT_H_
-#define PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_CONVERT_H_
-
-#include <string>
-
-#include <lib/fidl/cpp/vector.h>
-
-namespace cloud_provider {
-
-fidl::VectorPtr<uint8_t> ToArray(const std::string& val);
-
-std::string ToString(const fidl::VectorPtr<uint8_t>& bytes);
-
-std::string ToHex(const std::string& bytes);
-
-} // namespace cloud_provider
-
-#endif // PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_CONVERT_H_
diff --git a/bin/ledger/tests/cloud_provider/device_set_test.cc b/bin/ledger/tests/cloud_provider/device_set_test.cc
deleted file mode 100644
index e9f58a7..0000000
--- a/bin/ledger/tests/cloud_provider/device_set_test.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <gtest/gtest.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/ledger/tests/cloud_provider/convert.h"
-#include "peridot/bin/ledger/tests/cloud_provider/types.h"
-#include "peridot/bin/ledger/tests/cloud_provider/validation_test.h"
-
-namespace cloud_provider {
-namespace {
-
-class DeviceSetTest : public ValidationTest, public DeviceSetWatcher {
- public:
- DeviceSetTest() {}
- ~DeviceSetTest() override {}
-
- protected:
- ::testing::AssertionResult GetDeviceSet(DeviceSetSyncPtr* device_set) {
- *device_set = DeviceSetSyncPtr();
- Status status = Status::INTERNAL_ERROR;
-
- if (cloud_provider_->GetDeviceSet(device_set->NewRequest(), &status) !=
- ZX_OK) {
- return ::testing::AssertionFailure()
- << "Failed to retrieve the device set due to channel error.";
- }
-
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "Failed to retrieve the device set, received status: "
- << fidl::ToUnderlying(status);
- }
-
- return ::testing::AssertionSuccess();
- }
-
- int on_cloud_erased_calls_ = 0;
-
- private:
- // DeviceSetWatcher:
- void OnCloudErased() override { on_cloud_erased_calls_++; }
-
- void OnNetworkError() override {
- // Do nothing - the validation test suite currently does not inject and test
- // for network errors.
- FXL_NOTIMPLEMENTED();
- }
-};
-
-TEST_F(DeviceSetTest, GetDeviceSet) {
- DeviceSetSyncPtr device_set;
- ASSERT_TRUE(GetDeviceSet(&device_set));
-}
-
-TEST_F(DeviceSetTest, CheckMissingFingerprint) {
- DeviceSetSyncPtr device_set;
- ASSERT_TRUE(GetDeviceSet(&device_set));
-
- Status status = Status::INTERNAL_ERROR;
- ASSERT_EQ(ZX_OK, device_set->CheckFingerprint(ToArray("bazinga"), &status));
- EXPECT_EQ(Status::NOT_FOUND, status);
-}
-
-TEST_F(DeviceSetTest, SetAndCheckFingerprint) {
- DeviceSetSyncPtr device_set;
- ASSERT_TRUE(GetDeviceSet(&device_set));
-
- Status status = Status::INTERNAL_ERROR;
- ASSERT_EQ(ZX_OK, device_set->SetFingerprint(ToArray("bazinga"), &status));
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_EQ(ZX_OK, device_set->CheckFingerprint(ToArray("bazinga"), &status));
- EXPECT_EQ(Status::OK, status);
-}
-
-TEST_F(DeviceSetTest, WatchMisingFingerprint) {
- DeviceSetSyncPtr device_set;
- ASSERT_TRUE(GetDeviceSet(&device_set));
- Status status = Status::INTERNAL_ERROR;
- fidl::Binding<DeviceSetWatcher> binding(this);
- DeviceSetWatcherPtr watcher;
- binding.Bind(watcher.NewRequest());
- ASSERT_EQ(ZX_OK, device_set->SetWatcher(ToArray("bazinga"),
- std::move(watcher), &status));
- EXPECT_EQ(Status::NOT_FOUND, status);
-}
-
-TEST_F(DeviceSetTest, SetAndWatchFingerprint) {
- DeviceSetSyncPtr device_set;
- ASSERT_TRUE(GetDeviceSet(&device_set));
-
- Status status = Status::INTERNAL_ERROR;
- EXPECT_EQ(ZX_OK, device_set->SetFingerprint(ToArray("bazinga"), &status));
- EXPECT_EQ(Status::OK, status);
-
- fidl::Binding<DeviceSetWatcher> binding(this);
- DeviceSetWatcherPtr watcher;
- binding.Bind(watcher.NewRequest());
- ASSERT_EQ(ZX_OK, device_set->SetWatcher(ToArray("bazinga"),
- std::move(watcher), &status));
- EXPECT_EQ(Status::OK, status);
-}
-
-TEST_F(DeviceSetTest, EraseWhileWatching) {
- DeviceSetSyncPtr device_set;
- ASSERT_TRUE(GetDeviceSet(&device_set));
-
- Status status = Status::INTERNAL_ERROR;
- ASSERT_EQ(ZX_OK, device_set->SetFingerprint(ToArray("bazinga"), &status));
- EXPECT_EQ(Status::OK, status);
-
- fidl::Binding<DeviceSetWatcher> binding(this);
- DeviceSetWatcherPtr watcher;
- binding.Bind(watcher.NewRequest());
- ASSERT_EQ(ZX_OK, device_set->SetWatcher(ToArray("bazinga"),
- std::move(watcher), &status));
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_EQ(0, on_cloud_erased_calls_);
- ASSERT_EQ(ZX_OK, device_set->Erase(&status));
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_EQ(ZX_OK, binding.WaitForMessage());
- EXPECT_EQ(1, on_cloud_erased_calls_);
-}
-
-} // namespace
-} // namespace cloud_provider
diff --git a/bin/ledger/tests/cloud_provider/launcher/BUILD.gn b/bin/ledger/tests/cloud_provider/launcher/BUILD.gn
deleted file mode 100644
index 27c5099..0000000
--- a/bin/ledger/tests/cloud_provider/launcher/BUILD.gn
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("launcher") {
- testonly = true
-
- sources = [
- "validation_tests_launcher.cc",
- "validation_tests_launcher.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-}
diff --git a/bin/ledger/tests/cloud_provider/launcher/validation_tests_launcher.cc b/bin/ledger/tests/cloud_provider/launcher/validation_tests_launcher.cc
deleted file mode 100644
index 79ad4e1..0000000
--- a/bin/ledger/tests/cloud_provider/launcher/validation_tests_launcher.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/tests/cloud_provider/launcher/validation_tests_launcher.h"
-
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/logging.h>
-
-namespace cloud_provider {
-
-namespace {
-constexpr char kValidationTestsUrl[] =
- "fuchsia-pkg://fuchsia.com/ledger_tests"
- "#meta/cloud_provider_validation_tests.cmx";
-} // namespace
-
-ValidationTestsLauncher::ValidationTestsLauncher(
- component::StartupContext* startup_context,
- std::function<
- void(fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>)>
- factory)
- : startup_context_(startup_context), factory_(std::move(factory)) {
- service_provider_impl_.AddService<fuchsia::ledger::cloud::CloudProvider>(
- [this](fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>
- request) { factory_(std::move(request)); });
-}
-
-void ValidationTestsLauncher::Run(const std::vector<std::string>& arguments,
- std::function<void(int32_t)> callback) {
- callback_ = std::move(callback);
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = kValidationTestsUrl;
- fuchsia::sys::ServiceList service_list;
- service_list.names.push_back(fuchsia::ledger::cloud::CloudProvider::Name_);
- service_provider_impl_.AddBinding(service_list.provider.NewRequest());
- launch_info.additional_services = fidl::MakeOptional(std::move(service_list));
- for (const auto& argument : arguments) {
- launch_info.arguments.push_back(argument);
- }
-
- startup_context_->launcher()->CreateComponent(
- std::move(launch_info), validation_tests_controller_.NewRequest());
-
- validation_tests_controller_.events().OnTerminated =
- [this](int32_t return_code, fuchsia::sys::TerminationReason reason) {
- callback_(return_code);
- };
- validation_tests_controller_.set_error_handler([this](zx_status_t status) {
- FXL_LOG(ERROR) << "Lost connection to validation tests binary.";
- callback_(-1);
- });
-}
-
-} // namespace cloud_provider
diff --git a/bin/ledger/tests/cloud_provider/launcher/validation_tests_launcher.h b/bin/ledger/tests/cloud_provider/launcher/validation_tests_launcher.h
deleted file mode 100644
index 06e50c0..0000000
--- a/bin/ledger/tests/cloud_provider/launcher/validation_tests_launcher.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_LAUNCHER_VALIDATION_TESTS_LAUNCHER_H_
-#define PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_LAUNCHER_VALIDATION_TESTS_LAUNCHER_H_
-
-#include <functional>
-#include <string>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/component/cpp/startup_context.h>
-
-namespace cloud_provider {
-
-// Helper for building launcher apps for the validation tests.
-class ValidationTestsLauncher {
- public:
- // The constructor.
- //
- // |factory| is called to produce instances of the cloud provider under test.
- ValidationTestsLauncher(
- component::StartupContext* startup_context,
- std::function<
- void(fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>)>
- factory);
-
- // Starts the tests.
- //
- // |arguments| are passed to the test binary.
- // |callback| is called after the tests are finished and passed the exit code
- // of the test binary.
- void Run(const std::vector<std::string>& arguments,
- std::function<void(int32_t)> callback);
-
- private:
- component::StartupContext* const startup_context_;
- std::function<void(
- fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>)>
- factory_;
- component::ServiceProviderImpl service_provider_impl_;
- fuchsia::sys::ComponentControllerPtr validation_tests_controller_;
- std::function<void(int32_t)> callback_;
-};
-
-} // namespace cloud_provider
-
-#endif // PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_LAUNCHER_VALIDATION_TESTS_LAUNCHER_H_
diff --git a/bin/ledger/tests/cloud_provider/page_cloud_test.cc b/bin/ledger/tests/cloud_provider/page_cloud_test.cc
deleted file mode 100644
index 9dcf140..0000000
--- a/bin/ledger/tests/cloud_provider/page_cloud_test.cc
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <gtest/gtest.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/random/uuid.h>
-
-#include "peridot/bin/ledger/tests/cloud_provider/convert.h"
-#include "peridot/bin/ledger/tests/cloud_provider/types.h"
-#include "peridot/bin/ledger/tests/cloud_provider/validation_test.h"
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-namespace cloud_provider {
-namespace {
-
-// Verifies that the given array of commits contains a commit of the given id
-// and data.
-::testing::AssertionResult CheckThatCommitsContain(
- const std::vector<CommitPackEntry>& entries, const std::string& id,
- const std::string& data) {
- for (auto& entry : entries) {
- if (entry.id != id) {
- continue;
- }
-
- if (entry.data != data) {
- return ::testing::AssertionFailure()
- << "The commit of the expected id: 0x" << ToHex(id) << " (" << id
- << ") "
- << " was found but its data doesn't match - expected: 0x"
- << ToHex(data) << " but found: " << ToHex(entry.data);
- }
-
- return ::testing::AssertionSuccess();
- }
-
- return ::testing::AssertionFailure()
- << "The commit of the id: " << ToHex(id) << " (" << id << ") "
- << " is missing.";
-}
-
-class PageCloudTest : public ValidationTest, public PageCloudWatcher {
- public:
- PageCloudTest() {}
- ~PageCloudTest() override {}
-
- protected:
- ::testing::AssertionResult GetPageCloud(fidl::VectorPtr<uint8_t> app_id,
- fidl::VectorPtr<uint8_t> page_id,
- PageCloudSyncPtr* page_cloud) {
- *page_cloud = PageCloudSyncPtr();
- Status status = Status::INTERNAL_ERROR;
-
- if (cloud_provider_->GetPageCloud(std::move(app_id), std::move(page_id),
- page_cloud->NewRequest(),
- &status) != ZX_OK) {
- return ::testing::AssertionFailure()
- << "Failed to retrieve the page cloud due to channel error.";
- }
-
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "Failed to retrieve the page cloud, received status: "
- << fidl::ToUnderlying(status);
- }
-
- return ::testing::AssertionSuccess();
- }
-
- ::testing::AssertionResult GetLatestPositionToken(
- PageCloudSyncPtr* page_cloud,
- std::unique_ptr<cloud_provider::Token>* token) {
- Status status = Status::INTERNAL_ERROR;
- std::unique_ptr<cloud_provider::CommitPack> commit_pack;
- if ((*page_cloud)->GetCommits(nullptr, &status, &commit_pack, token) !=
- ZX_OK) {
- return ::testing::AssertionFailure()
- << "Failed to retrieve the position token due to channel error.";
- }
-
- if (status != Status::OK) {
- return ::testing::AssertionFailure()
- << "Failed to retrieve the position token, received status: "
- << fidl::ToUnderlying(status);
- }
-
- return ::testing::AssertionSuccess();
- }
-
- int on_new_commits_calls_ = 0;
- std::vector<CommitPackEntry> on_new_commits_commits_;
- cloud_provider::Token on_new_commits_position_token_;
- OnNewCommitsCallback on_new_commits_commits_callback_;
-
- cloud_provider::Status on_error_status_ = cloud_provider::Status::OK;
-
- private:
- // PageCloudWatcher:
- void OnNewCommits(CommitPack commits, cloud_provider::Token position_token,
- OnNewCommitsCallback callback) override {
- std::vector<CommitPackEntry> entries;
- ASSERT_TRUE(DecodeCommitPack(commits, &entries));
-
- on_new_commits_calls_++;
- std::move(entries.begin(), entries.end(),
- std::back_inserter(on_new_commits_commits_));
- on_new_commits_position_token_ = std::move(position_token);
- on_new_commits_commits_callback_ = std::move(callback);
- }
-
- void OnNewObject(std::vector<uint8_t> /*id*/,
- fuchsia::mem::Buffer /*data*/,
- OnNewObjectCallback /*callback*/) override {
- // We don't have any implementations yet that support this API.
- // TODO(ppi): add tests for the OnNewObject notifications.
- FXL_NOTIMPLEMENTED();
- }
-
- void OnError(cloud_provider::Status status) override {
- on_error_status_ = status;
- }
-};
-
-TEST_F(PageCloudTest, GetPageCloud) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
-}
-
-TEST_F(PageCloudTest, GetNoCommits) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
-
- std::unique_ptr<cloud_provider::CommitPack> commit_pack;
- std::unique_ptr<Token> token;
- Status status = Status::INTERNAL_ERROR;
- ASSERT_EQ(ZX_OK,
- page_cloud->GetCommits(nullptr, &status, &commit_pack, &token));
- EXPECT_EQ(Status::OK, status);
- ASSERT_TRUE(commit_pack);
- std::vector<CommitPackEntry> entries;
- ASSERT_TRUE(DecodeCommitPack(*commit_pack, &entries));
- EXPECT_TRUE(entries.empty());
- EXPECT_FALSE(token);
-}
-
-TEST_F(PageCloudTest, AddAndGetCommits) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
-
- std::vector<CommitPackEntry> entries{{"id0", "data0"}, {"id1", "data1"}};
- CommitPack commit_pack;
- ASSERT_TRUE(EncodeCommitPack(entries, &commit_pack));
- Status status = Status::INTERNAL_ERROR;
- ASSERT_EQ(ZX_OK, page_cloud->AddCommits(std::move(commit_pack), &status));
- EXPECT_EQ(Status::OK, status);
-
- std::unique_ptr<CommitPack> result;
- std::unique_ptr<Token> token;
- ASSERT_EQ(ZX_OK, page_cloud->GetCommits(nullptr, &status, &result, &token));
- EXPECT_EQ(Status::OK, status);
- ASSERT_TRUE(result);
- ASSERT_TRUE(DecodeCommitPack(*result, &entries));
- EXPECT_EQ(2u, entries.size());
- EXPECT_TRUE(CheckThatCommitsContain(entries, "id0", "data0"));
- EXPECT_TRUE(CheckThatCommitsContain(entries, "id1", "data1"));
- EXPECT_TRUE(token);
-}
-
-TEST_F(PageCloudTest, GetCommitsByPositionToken) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
-
- // Add two commits.
- std::vector<CommitPackEntry> entries{{"id0", "data0"}, {"id1", "data1"}};
- CommitPack commit_pack;
- ASSERT_TRUE(EncodeCommitPack(entries, &commit_pack));
- Status status = Status::INTERNAL_ERROR;
- ASSERT_EQ(ZX_OK, page_cloud->AddCommits(std::move(commit_pack), &status));
- EXPECT_EQ(Status::OK, status);
-
- // Retrieve the position token of the newest of the two (`id1`).
- std::unique_ptr<cloud_provider::Token> token;
- ASSERT_TRUE(GetLatestPositionToken(&page_cloud, &token));
- EXPECT_TRUE(token);
-
- // Add one more commit.
- std::vector<CommitPackEntry> more_entries{{"id2", "data2"}};
- ASSERT_TRUE(EncodeCommitPack(more_entries, &commit_pack));
- ASSERT_EQ(ZX_OK, page_cloud->AddCommits(std::move(commit_pack), &status));
- EXPECT_EQ(Status::OK, status);
-
- // Retrieve the commits again with the position token of `id1`.
- std::unique_ptr<CommitPack> result;
- ASSERT_EQ(ZX_OK,
- page_cloud->GetCommits(std::move(token), &status, &result, &token));
- EXPECT_EQ(Status::OK, status);
- ASSERT_TRUE(result);
- ASSERT_TRUE(DecodeCommitPack(*result, &entries));
-
- // As per the API contract, the response must include `id1` and everything
- // newer than it. It may or may not include `id0`.
- EXPECT_TRUE(CheckThatCommitsContain(entries, "id1", "data1"));
- EXPECT_TRUE(CheckThatCommitsContain(entries, "id2", "data2"));
-}
-
-TEST_F(PageCloudTest, AddAndGetObjects) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
-
- fsl::SizedVmo data;
- ASSERT_TRUE(fsl::VmoFromString("bazinga!", &data));
- Status status = Status::INTERNAL_ERROR;
- // Generate a random ID - the current cloud provider implementations don't
- // erase storage objects upon .Erase(), and we want to avoid interference from
- // previous test runs.
- // TODO(ppi): use a fixed ID here once the cloud provider implementations
- // support erasing objects.
- const std::string id = fxl::GenerateUUID();
- ASSERT_EQ(ZX_OK, page_cloud->AddObject(
- ToArray(id), std::move(data).ToTransport(), &status));
- EXPECT_EQ(Status::OK, status);
-
- ::fuchsia::mem::BufferPtr buffer_ptr;
- ASSERT_EQ(ZX_OK, page_cloud->GetObject(ToArray(id), &status, &buffer_ptr));
- EXPECT_EQ(Status::OK, status);
- std::string read_data;
- ASSERT_TRUE(fsl::StringFromVmo(*buffer_ptr, &read_data));
- EXPECT_EQ("bazinga!", read_data);
-}
-
-TEST_F(PageCloudTest, AddSameObjectTwice) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
-
- fsl::SizedVmo data;
- ASSERT_TRUE(fsl::VmoFromString("bazinga!", &data));
- Status status = Status::INTERNAL_ERROR;
- const std::string id = "some id";
- ASSERT_EQ(ZX_OK, page_cloud->AddObject(
- ToArray(id), std::move(data).ToTransport(), &status));
- EXPECT_EQ(Status::OK, status);
- // Adding the same object again must succeed as per cloud provider contract.
- fsl::SizedVmo more_data;
- ASSERT_TRUE(fsl::VmoFromString("bazinga!", &more_data));
- ASSERT_EQ(ZX_OK,
- page_cloud->AddObject(ToArray(id),
- std::move(more_data).ToTransport(), &status));
- EXPECT_EQ(Status::OK, status);
-}
-
-TEST_F(PageCloudTest, WatchAndReceiveCommits) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
- Status status = Status::INTERNAL_ERROR;
- fidl::Binding<PageCloudWatcher> binding(this);
- PageCloudWatcherPtr watcher;
- binding.Bind(watcher.NewRequest());
- ASSERT_EQ(ZX_OK,
- page_cloud->SetWatcher(nullptr, std::move(watcher), &status));
- EXPECT_EQ(Status::OK, status);
-
- std::vector<CommitPackEntry> entries{{"id0", "data0"}, {"id1", "data1"}};
- CommitPack commit_pack;
- ASSERT_TRUE(EncodeCommitPack(entries, &commit_pack));
- ASSERT_EQ(ZX_OK, page_cloud->AddCommits(std::move(commit_pack), &status));
- EXPECT_EQ(Status::OK, status);
-
- // The two commits could be delivered in one or two notifications. If they are
- // delivered over two notifications, the second one can only be delivered
- // after the client confirms having processed the first one by calling the
- // notification callback.
- while (on_new_commits_commits_.size() < 2u) {
- ASSERT_EQ(ZX_OK, binding.WaitForMessage());
- on_new_commits_commits_callback_();
- }
- EXPECT_TRUE(CheckThatCommitsContain(on_new_commits_commits_, "id0", "data0"));
- EXPECT_TRUE(CheckThatCommitsContain(on_new_commits_commits_, "id1", "data1"));
-}
-
-// Verifies that the pre-existing commits are also delivered when a watcher is
-// registered.
-TEST_F(PageCloudTest, WatchWithBacklog) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
- Status status = Status::INTERNAL_ERROR;
-
- std::vector<CommitPackEntry> entries{{"id0", "data0"}, {"id1", "data1"}};
- CommitPack commit_pack;
- ASSERT_TRUE(EncodeCommitPack(entries, &commit_pack));
- ASSERT_EQ(ZX_OK, page_cloud->AddCommits(std::move(commit_pack), &status));
- EXPECT_EQ(Status::OK, status);
-
- fidl::Binding<PageCloudWatcher> binding(this);
- PageCloudWatcherPtr watcher;
- binding.Bind(watcher.NewRequest());
- ASSERT_EQ(ZX_OK,
- page_cloud->SetWatcher(nullptr, std::move(watcher), &status));
- EXPECT_EQ(Status::OK, status);
-
- while (on_new_commits_commits_.size() < 2u) {
- ASSERT_EQ(ZX_OK, binding.WaitForMessage());
- on_new_commits_commits_callback_();
- }
- EXPECT_TRUE(CheckThatCommitsContain(on_new_commits_commits_, "id0", "data0"));
- EXPECT_TRUE(CheckThatCommitsContain(on_new_commits_commits_, "id1", "data1"));
-}
-
-TEST_F(PageCloudTest, WatchWithPositionToken) {
- PageCloudSyncPtr page_cloud;
- ASSERT_TRUE(GetPageCloud(ToArray("app_id"), ToArray("page_id"), &page_cloud));
-
- // Add two commits.
- std::vector<CommitPackEntry> entries{{"id0", "data0"}, {"id1", "data1"}};
- CommitPack commit_pack;
- ASSERT_TRUE(EncodeCommitPack(entries, &commit_pack));
- Status status = Status::INTERNAL_ERROR;
- ASSERT_EQ(ZX_OK, page_cloud->AddCommits(std::move(commit_pack), &status));
- EXPECT_EQ(Status::OK, status);
-
- // Retrieve the position token of the newest of the two (`id1`).
- std::unique_ptr<cloud_provider::Token> token;
- ASSERT_TRUE(GetLatestPositionToken(&page_cloud, &token));
- EXPECT_TRUE(token);
-
- // Set the watcher with the position token of `id1`.
- fidl::Binding<PageCloudWatcher> binding(this);
- PageCloudWatcherPtr watcher;
- binding.Bind(watcher.NewRequest());
- ASSERT_EQ(ZX_OK, page_cloud->SetWatcher(std::move(token), std::move(watcher),
- &status));
- EXPECT_EQ(Status::OK, status);
-
- // As per the API contract, the commits delivered in notifications must
- // include `id1`. They may or may not include `id0`.
- while (!CheckThatCommitsContain(on_new_commits_commits_, "id1", "data1")) {
- ASSERT_EQ(ZX_OK, binding.WaitForMessage());
- on_new_commits_commits_callback_();
- }
-
- // Add one more commit.
- std::vector<CommitPackEntry> more_entries{{"id2", "data2"}};
- ASSERT_TRUE(EncodeCommitPack(more_entries, &commit_pack));
- ASSERT_EQ(ZX_OK, page_cloud->AddCommits(std::move(commit_pack), &status));
- EXPECT_EQ(Status::OK, status);
-
- while (!CheckThatCommitsContain(on_new_commits_commits_, "id2", "data2")) {
- ASSERT_EQ(ZX_OK, binding.WaitForMessage());
- on_new_commits_commits_callback_();
- }
-}
-
-} // namespace
-} // namespace cloud_provider
diff --git a/bin/ledger/tests/cloud_provider/types.h b/bin/ledger/tests/cloud_provider/types.h
deleted file mode 100644
index f4661a4..0000000
--- a/bin/ledger/tests/cloud_provider/types.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_TYPES_H_
-#define PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_TYPES_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-
-// More convenient aliases for FIDL types.
-
-namespace cloud_provider {
-using CloudProvider = fuchsia::ledger::cloud::CloudProvider;
-using CloudProviderPtr = fuchsia::ledger::cloud::CloudProviderPtr;
-using CloudProviderSyncPtr = fuchsia::ledger::cloud::CloudProviderSyncPtr;
-using CommitPack = fuchsia::ledger::cloud::CommitPack;
-using DeviceSet = fuchsia::ledger::cloud::DeviceSet;
-using DeviceSetPtr = fuchsia::ledger::cloud::DeviceSetPtr;
-using DeviceSetSyncPtr = fuchsia::ledger::cloud::DeviceSetSyncPtr;
-using DeviceSetWatcher = fuchsia::ledger::cloud::DeviceSetWatcher;
-using DeviceSetWatcherPtr = fuchsia::ledger::cloud::DeviceSetWatcherPtr;
-using PageCloud = fuchsia::ledger::cloud::PageCloud;
-using PageCloudPtr = fuchsia::ledger::cloud::PageCloudPtr;
-using PageCloudSyncPtr = fuchsia::ledger::cloud::PageCloudSyncPtr;
-using PageCloudWatcher = fuchsia::ledger::cloud::PageCloudWatcher;
-using PageCloudWatcherPtr = fuchsia::ledger::cloud::PageCloudWatcherPtr;
-using Status = fuchsia::ledger::cloud::Status;
-using Token = fuchsia::ledger::cloud::Token;
-} // namespace cloud_provider
-
-#endif // PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_TYPES_H_
diff --git a/bin/ledger/tests/cloud_provider/validation_test.cc b/bin/ledger/tests/cloud_provider/validation_test.cc
deleted file mode 100644
index 05c042e..0000000
--- a/bin/ledger/tests/cloud_provider/validation_test.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/tests/cloud_provider/validation_test.h"
-
-namespace cloud_provider {
-
-ValidationTest::ValidationTest()
- : startup_context_(component::StartupContext::CreateFromStartupInfo()) {}
-ValidationTest::~ValidationTest() {}
-
-void ValidationTest::SetUp() {
- startup_context_->ConnectToEnvironmentService(cloud_provider_.NewRequest());
-}
-
-} // namespace cloud_provider
diff --git a/bin/ledger/tests/cloud_provider/validation_test.h b/bin/ledger/tests/cloud_provider/validation_test.h
deleted file mode 100644
index 6a9c45b..0000000
--- a/bin/ledger/tests/cloud_provider/validation_test.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_VALIDATION_TEST_H_
-#define PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_VALIDATION_TEST_H_
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <gtest/gtest.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/bin/ledger/tests/cloud_provider/types.h"
-
-namespace cloud_provider {
-
-class ValidationTest : public ::gtest::TestLoopFixture {
- public:
- ValidationTest();
- ~ValidationTest() override;
-
- void SetUp() override;
-
- protected:
- CloudProviderSyncPtr cloud_provider_;
-
- private:
- std::unique_ptr<component::StartupContext> startup_context_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ValidationTest);
-};
-
-} // namespace cloud_provider
-
-#endif // PERIDOT_BIN_LEDGER_TESTS_CLOUD_PROVIDER_VALIDATION_TEST_H_
diff --git a/bin/ledger/tests/e2e_local/BUILD.gn b/bin/ledger/tests/e2e_local/BUILD.gn
deleted file mode 100644
index f4def97..0000000
--- a/bin/ledger/tests/e2e_local/BUILD.gn
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-executable("e2e_local") {
- output_name = "ledger_e2e_local"
-
- testonly = true
-
- sources = [
- "get_ledger_test.cc",
- "ledger_e2e_test.cc",
- ]
-
- deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//peridot/bin/ledger/app:serialization_version",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/ledger/filesystem",
- "//peridot/bin/ledger/testing:get_ledger",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/bin/ledger/testing/cloud_provider",
- "//peridot/lib/scoped_tmpfs",
- "//peridot/public/fidl/fuchsia.ledger",
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest_main",
- ]
-
- data_deps = [
- "//peridot/bin/ledger/app",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/e2e_local/get_ledger_test.cc b/bin/ledger/tests/e2e_local/get_ledger_test.cc
deleted file mode 100644
index cfc7d6c..0000000
--- a/bin/ledger/tests/e2e_local/get_ledger_test.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/testing/get_ledger.h"
-
-#include <lib/async-loop/cpp/loop.h>
-
-#include "garnet/public/lib/callback/capture.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace ledger {
-namespace {
-
-TEST(GetLedgerTest, CreateAndDeleteLedger) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- scoped_tmpfs::ScopedTmpFS tmpfs;
-
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
- fuchsia::sys::ComponentControllerPtr controller;
-
- LedgerPtr ledger;
- Status status = GetLedger(
- startup_context.get(), controller.NewRequest(), nullptr, "",
- "ledger_name", DetachedPath(tmpfs.root_fd()), [&] { loop.Quit(); },
- &ledger);
-
- // No need to |Sync| as |GetLedger| handles it.
- EXPECT_EQ(Status::OK, status);
-
- KillLedgerProcess(&controller);
-}
-
-TEST(GetLedgerTest, GetPageEnsureInitialized) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- scoped_tmpfs::ScopedTmpFS tmpfs;
-
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
- fuchsia::sys::ComponentControllerPtr controller;
-
- LedgerPtr ledger;
- Status status = GetLedger(
- startup_context.get(), controller.NewRequest(), nullptr, "",
- "ledger_name", DetachedPath(tmpfs.root_fd()), [&] { loop.Quit(); },
- &ledger);
-
- ASSERT_EQ(Status::OK, status);
-
- status = Status::UNKNOWN_ERROR;
- PagePtr page;
- PageId page_id;
-
- GetPageEnsureInitialized(
- &ledger, nullptr, DelayCallback::NO, [&] { loop.Quit(); },
- callback::Capture([&] { loop.Quit(); }, &status, &page, &page_id));
- loop.Run();
-
- EXPECT_EQ(Status::OK, status);
-
- KillLedgerProcess(&controller);
-}
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/e2e_local/ledger_e2e_local.cmx b/bin/ledger/tests/e2e_local/ledger_e2e_local.cmx
deleted file mode 100644
index 1f1f45c..0000000
--- a/bin/ledger/tests/e2e_local/ledger_e2e_local.cmx
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "program": {
- "binary": "test/ledger_e2e_local"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/ledger/tests/e2e_local/ledger_e2e_test.cc b/bin/ledger/tests/e2e_local/ledger_e2e_test.cc
deleted file mode 100644
index 974a028..0000000
--- a/bin/ledger/tests/e2e_local/ledger_e2e_test.cc
+++ /dev/null
@@ -1,373 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string.h>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/synchronous_interface_ptr.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/io/fd.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/gtest/real_loop_fixture.h>
-#include <lib/svc/cpp/services.h>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/serialization_version.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/filesystem/detached_path.h"
-#include "peridot/bin/ledger/filesystem/directory_reader.h"
-#include "peridot/bin/ledger/testing/cloud_provider/fake_cloud_provider.h"
-#include "peridot/bin/ledger/testing/cloud_provider/types.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace test {
-namespace e2e_local {
-namespace {
-
-using ::testing::ElementsAre;
-
-template <class A>
-bool Equals(const fidl::VectorPtr<uint8_t>& a1, const A& a2) {
- if (a1->size() != a2.size())
- return false;
- return memcmp(a1->data(), a2.data(), a1->size()) == 0;
-}
-
-fidl::VectorPtr<uint8_t> TestArray() {
- std::string value = "value";
- fidl::VectorPtr<uint8_t> result(value.size());
- memcpy(&result->at(0), &value[0], value.size());
- return result;
-}
-
-class LedgerEndToEndTest : public gtest::RealLoopFixture {
- public:
- LedgerEndToEndTest()
- : startup_context_(component::StartupContext::CreateFromStartupInfo()) {}
- ~LedgerEndToEndTest() override {}
-
- protected:
- void Init(std::vector<std::string> additional_args) {
- component::Services child_services;
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = "fuchsia-pkg://fuchsia.com/ledger#meta/ledger.cmx";
- launch_info.directory_request = child_services.NewRequest();
- launch_info.arguments.push_back("--disable_reporting");
- for (auto& additional_arg : additional_args) {
- launch_info.arguments.push_back(additional_arg);
- }
- startup_context()->launcher()->CreateComponent(
- std::move(launch_info), ledger_controller_.NewRequest());
-
- ledger_controller_.set_error_handler([this](zx_status_t status) {
- for (const auto& callback : ledger_shutdown_callbacks_) {
- callback();
- }
- });
-
- ledger_repository_factory_.set_error_handler([](zx_status_t status) {
- if (status != ZX_ERR_PEER_CLOSED) {
- ADD_FAILURE() << "Ledger repository error: " << status;
- }
- });
- child_services.ConnectToService(ledger_repository_factory_.NewRequest());
- child_services.ConnectToService(controller_.NewRequest());
- }
-
- void RegisterShutdownCallback(fit::function<void()> callback) {
- ledger_shutdown_callbacks_.push_back(std::move(callback));
- }
-
- component::StartupContext* startup_context() {
- return startup_context_.get();
- }
-
- private:
- fuchsia::sys::ComponentControllerPtr ledger_controller_;
- std::vector<fit::function<void()>> ledger_shutdown_callbacks_;
- std::unique_ptr<component::StartupContext> startup_context_;
-
- protected:
- ledger_internal::LedgerRepositoryFactoryPtr ledger_repository_factory_;
- fidl::SynchronousInterfacePtr<ledger::Ledger> ledger_;
- fidl::SynchronousInterfacePtr<ledger_internal::LedgerController> controller_;
-};
-
-TEST_F(LedgerEndToEndTest, PutAndGet) {
- Init({});
- ledger::Status status;
- fidl::SynchronousInterfacePtr<ledger_internal::LedgerRepository>
- ledger_repository;
- scoped_tmpfs::ScopedTmpFS tmpfs;
- ledger_repository_factory_->GetRepository(
- fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()), nullptr, "",
- ledger_repository.NewRequest());
-
- ledger_repository->GetLedger(TestArray(), ledger_.NewRequest());
- ASSERT_EQ(ZX_OK, ledger_repository->Sync());
-
- fidl::SynchronousInterfacePtr<ledger::Page> page;
- ledger_->GetRootPage(page.NewRequest(), &status);
- ASSERT_EQ(ledger::Status::OK, status);
- page->Put(TestArray(), TestArray(), &status);
- EXPECT_EQ(ledger::Status::OK, status);
- fidl::SynchronousInterfacePtr<ledger::PageSnapshot> snapshot;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- nullptr, &status);
- EXPECT_EQ(ledger::Status::OK, status);
- fuchsia::mem::BufferPtr value;
- snapshot->Get(TestArray(), &status, &value);
- EXPECT_EQ(ledger::Status::OK, status);
- std::string value_as_string;
- EXPECT_TRUE(fsl::StringFromVmo(*value, &value_as_string));
- EXPECT_TRUE(Equals(TestArray(), value_as_string));
-}
-
-TEST_F(LedgerEndToEndTest, Terminate) {
- Init({});
- bool called = false;
- RegisterShutdownCallback([this, &called] {
- called = true;
- QuitLoop();
- });
- controller_->Terminate();
- RunLoop();
- EXPECT_TRUE(called);
-}
-
-// Verifies the cloud erase recovery in case of a cloud that was erased before
-// startup.
-//
-// Expected behavior: Ledger disconnects the clients and the local state is
-// cleared.
-TEST_F(LedgerEndToEndTest, CloudEraseRecoveryOnInitialCheck) {
- Init({});
- bool ledger_shut_down = false;
- RegisterShutdownCallback([&ledger_shut_down] { ledger_shut_down = true; });
-
- ledger_internal::LedgerRepositoryPtr ledger_repository;
- scoped_tmpfs::ScopedTmpFS tmpfs;
- const std::string content_path = ledger::kSerializationVersion.ToString();
- const std::string deletion_sentinel_path = content_path + "/sentinel";
- ASSERT_TRUE(files::CreateDirectoryAt(tmpfs.root_fd(), content_path));
- ASSERT_TRUE(
- files::WriteFileAt(tmpfs.root_fd(), deletion_sentinel_path, "", 0));
- ASSERT_TRUE(files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path));
-
- // Write a fingerprint file, so that Ledger will check if it is still in the
- // cloud device set.
- const std::string fingerprint_path = content_path + "/fingerprint";
- const std::string fingerprint = "bazinga";
- ASSERT_TRUE(files::WriteFileAt(tmpfs.root_fd(), fingerprint_path,
- fingerprint.c_str(), fingerprint.size()));
-
- // Create a cloud provider configured to trigger the cloude erase recovery on
- // initial check.
- auto cloud_provider =
- ledger::FakeCloudProvider::Builder()
- .SetCloudEraseOnCheck(ledger::CloudEraseOnCheck::YES)
- .Build();
- cloud_provider::CloudProviderPtr cloud_provider_ptr;
- fidl::Binding<cloud_provider::CloudProvider> cloud_provider_binding(
- cloud_provider.get(), cloud_provider_ptr.NewRequest());
-
- ledger_repository_factory_->GetRepository(
- fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()),
- std::move(cloud_provider_ptr), "user_id", ledger_repository.NewRequest());
-
- bool repo_disconnected = false;
- ledger_repository.set_error_handler(
- [&repo_disconnected](zx_status_t status) { repo_disconnected = true; });
-
- // Run the message loop until Ledger clears the repo directory and disconnects
- // the client.
- RunLoopUntil([&] {
- return !files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path) &&
- repo_disconnected;
- });
- EXPECT_FALSE(files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path));
- EXPECT_TRUE(repo_disconnected);
-
- // Make sure all the contents are deleted. Only the staging directory should
- // be present.
- std::vector<std::string> directory_entries;
- auto on_next_directory_entry = [&](fxl::StringView entry) {
- directory_entries.push_back(entry.ToString());
- return true;
- };
- EXPECT_TRUE(ledger::GetDirectoryEntries(ledger::DetachedPath(tmpfs.root_fd()),
- on_next_directory_entry));
- EXPECT_THAT(directory_entries, ElementsAre("staging"));
-
- // Verify that the Ledger app didn't crash.
- EXPECT_FALSE(ledger_shut_down);
-}
-
-// Verifies the cloud erase recovery in case of a cloud that is erased while
-// Ledger is connected to it.
-//
-// Expected behavior: Ledger disconnects the clients and the local state is
-// cleared.
-TEST_F(LedgerEndToEndTest, CloudEraseRecoveryFromTheWatcher) {
- Init({});
- bool ledger_shut_down = false;
- RegisterShutdownCallback([&ledger_shut_down] { ledger_shut_down = true; });
-
- ledger_internal::LedgerRepositoryPtr ledger_repository;
- scoped_tmpfs::ScopedTmpFS tmpfs;
- const std::string content_path = ledger::kSerializationVersion.ToString();
- const std::string deletion_sentinel_path = content_path + "/sentinel";
- ASSERT_TRUE(files::CreateDirectoryAt(tmpfs.root_fd(), content_path));
- ASSERT_TRUE(
- files::WriteFileAt(tmpfs.root_fd(), deletion_sentinel_path, "", 0));
- ASSERT_TRUE(files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path));
-
- // Create a cloud provider configured to trigger the cloud erase recovery
- // while Ledger is connected.
- auto cloud_provider =
- ledger::FakeCloudProvider::Builder()
- .SetCloudEraseFromWatcher(ledger::CloudEraseFromWatcher::YES)
- .Build();
- cloud_provider::CloudProviderPtr cloud_provider_ptr;
- fidl::Binding<cloud_provider::CloudProvider> cloud_provider_binding(
- cloud_provider.get(), cloud_provider_ptr.NewRequest());
-
- ledger_repository_factory_->GetRepository(
- fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()),
- std::move(cloud_provider_ptr), "user_id", ledger_repository.NewRequest());
-
- bool repo_disconnected = false;
- ledger_repository.set_error_handler(
- [&repo_disconnected](zx_status_t status) { repo_disconnected = true; });
-
- // Run the message loop until Ledger clears the repo directory and disconnects
- // the client.
- RunLoopUntil([&] {
- return !files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path) &&
- repo_disconnected;
- });
- EXPECT_FALSE(files::IsFileAt(tmpfs.root_fd(), deletion_sentinel_path));
- EXPECT_TRUE(repo_disconnected);
-
- // Verify that the Ledger app didn't crash.
- EXPECT_FALSE(ledger_shut_down);
-}
-
-// Verifies that Ledger instance continues to work even if the cloud provider
-// goes away (for example, because it crashes).
-//
-// In the future, we need to also be able to reconnect/request a new cloud
-// provider, see LE-567.
-TEST_F(LedgerEndToEndTest, HandleCloudProviderDisconnectBeforePageInit) {
- Init({});
- bool ledger_app_shut_down = false;
- RegisterShutdownCallback(
- [&ledger_app_shut_down] { ledger_app_shut_down = true; });
- ledger::Status status;
- scoped_tmpfs::ScopedTmpFS tmpfs;
-
- cloud_provider::CloudProviderPtr cloud_provider_ptr;
- fidl::SynchronousInterfacePtr<ledger_internal::LedgerRepository>
- ledger_repository;
- ledger::FakeCloudProvider cloud_provider;
- fidl::Binding<cloud_provider::CloudProvider> cloud_provider_binding(
- &cloud_provider, cloud_provider_ptr.NewRequest());
- ledger_repository_factory_->GetRepository(
- fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()),
- std::move(cloud_provider_ptr), "user_id", ledger_repository.NewRequest());
-
- ledger_repository->GetLedger(TestArray(), ledger_.NewRequest());
- ASSERT_EQ(ZX_OK, ledger_repository->Sync());
-
- // Close the cloud provider channel.
- cloud_provider_binding.Unbind();
-
- // Write and read some data to verify that Ledger still works.
- fidl::SynchronousInterfacePtr<ledger::Page> page;
- status = ledger::Status::INTERNAL_ERROR;
- ledger_->GetPage(nullptr, page.NewRequest(), &status);
- ASSERT_EQ(ledger::Status::OK, status);
- status = ledger::Status::INTERNAL_ERROR;
- page->Put(TestArray(), TestArray(), &status);
- EXPECT_EQ(ledger::Status::OK, status);
- fidl::SynchronousInterfacePtr<ledger::PageSnapshot> snapshot;
- status = ledger::Status::INTERNAL_ERROR;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- nullptr, &status);
- EXPECT_EQ(ledger::Status::OK, status);
- fuchsia::mem::BufferPtr value;
- status = ledger::Status::INTERNAL_ERROR;
- snapshot->Get(TestArray(), &status, &value);
- ASSERT_EQ(ledger::Status::OK, status);
- std::string value_as_string;
- EXPECT_TRUE(fsl::StringFromVmo(*value, &value_as_string));
- EXPECT_TRUE(Equals(TestArray(), value_as_string));
-
- // Verify that the Ledger app didn't crash or shut down.
- EXPECT_TRUE(ledger_repository);
- EXPECT_FALSE(ledger_app_shut_down);
-}
-
-TEST_F(LedgerEndToEndTest, HandleCloudProviderDisconnectBetweenReadAndWrite) {
- Init({});
- bool ledger_app_shut_down = false;
- RegisterShutdownCallback(
- [&ledger_app_shut_down] { ledger_app_shut_down = true; });
- ledger::Status status;
- scoped_tmpfs::ScopedTmpFS tmpfs;
-
- cloud_provider::CloudProviderPtr cloud_provider_ptr;
- fidl::SynchronousInterfacePtr<ledger_internal::LedgerRepository>
- ledger_repository;
- ledger::FakeCloudProvider cloud_provider;
- fidl::Binding<cloud_provider::CloudProvider> cloud_provider_binding(
- &cloud_provider, cloud_provider_ptr.NewRequest());
- ledger_repository_factory_->GetRepository(
- fsl::CloneChannelFromFileDescriptor(tmpfs.root_fd()),
- std::move(cloud_provider_ptr), "user_id", ledger_repository.NewRequest());
-
- ledger_repository->GetLedger(TestArray(), ledger_.NewRequest());
- ASSERT_EQ(ZX_OK, ledger_repository->Sync());
-
- // Write some data.
- fidl::SynchronousInterfacePtr<ledger::Page> page;
- status = ledger::Status::INTERNAL_ERROR;
- ledger_->GetPage(nullptr, page.NewRequest(), &status);
- ASSERT_EQ(ledger::Status::OK, status);
- status = ledger::Status::INTERNAL_ERROR;
- page->Put(TestArray(), TestArray(), &status);
- EXPECT_EQ(ledger::Status::OK, status);
-
- // Close the cloud provider channel.
- cloud_provider_binding.Unbind();
-
- // Read the data back.
- fidl::SynchronousInterfacePtr<ledger::PageSnapshot> snapshot;
- status = ledger::Status::INTERNAL_ERROR;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- nullptr, &status);
- EXPECT_EQ(ledger::Status::OK, status);
- fuchsia::mem::BufferPtr value;
- status = ledger::Status::INTERNAL_ERROR;
- snapshot->Get(TestArray(), &status, &value);
- ASSERT_EQ(ledger::Status::OK, status);
- std::string value_as_string;
- EXPECT_TRUE(fsl::StringFromVmo(*value, &value_as_string));
- EXPECT_TRUE(Equals(TestArray(), value_as_string));
-
- // Verify that the Ledger app didn't crash or shut down.
- EXPECT_TRUE(ledger_repository);
- EXPECT_FALSE(ledger_app_shut_down);
-}
-
-} // namespace
-} // namespace e2e_local
-} // namespace test
diff --git a/bin/ledger/tests/e2e_sync/BUILD.gn b/bin/ledger/tests/e2e_sync/BUILD.gn
deleted file mode 100644
index 58bf24e..0000000
--- a/bin/ledger/tests/e2e_sync/BUILD.gn
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-executable("e2e_sync") {
- output_name = "ledger_e2e_sync"
- testonly = true
-
- sources = [
- "e2e_sync_main.cc",
- "ledger_app_instance_factory_e2e.cc",
- "ledger_app_instance_factory_e2e.h",
- ]
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/cloud_provider_firestore/fidl",
- "//peridot/bin/cloud_provider_firestore/testing",
- "//peridot/bin/ledger/fidl_helpers",
- "//peridot/bin/ledger/testing:ledger_instance_factory",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/bin/ledger/tests/integration/sync",
- "//peridot/lib/convert",
- "//peridot/lib/firebase_auth/testing",
- "//peridot/lib/rng:system",
- "//third_party/googletest:gtest",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/e2e_sync/README.md b/bin/ledger/tests/e2e_sync/README.md
deleted file mode 100644
index e6ee5fb..0000000
--- a/bin/ledger/tests/e2e_sync/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Synchronization tests
-
-This directory contains an "end-to-end" test suite for synchronization and needs a working Firebase instance to run correctly. It uses the synchronization tests from the integration test suite.
-
-To run this test suite, follow the instruction at [Synchronization tests]
-
-[Synchronization tests]: /docs/ledger/testing.md#synchronization-tests
diff --git a/bin/ledger/tests/e2e_sync/e2e_sync_main.cc b/bin/ledger/tests/e2e_sync/e2e_sync_main.cc
deleted file mode 100644
index 4ecdebe..0000000
--- a/bin/ledger/tests/e2e_sync/e2e_sync_main.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include <gtest/gtest.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/ledger/testing/loop_controller_real_loop.h"
-#include "peridot/bin/ledger/testing/sync_params.h"
-#include "peridot/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.h"
-
-namespace ledger {
-namespace {
-SyncParams* sync_params_ptr = nullptr;
-
-class FactoryBuilderE2eImpl : public LedgerAppInstanceFactoryBuilder {
- public:
- std::unique_ptr<LedgerAppInstanceFactory> NewFactory() const override {
- return std::make_unique<LedgerAppInstanceFactoryImpl>(
- std::make_unique<LoopControllerRealLoop>(), *sync_params_ptr);
- }
-};
-
-int Main(int argc, char** argv) {
- fxl::CommandLine command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- SyncParams sync_params;
-
- {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto startup_context = component::StartupContext::CreateFromStartupInfo();
-
- if (!ParseSyncParamsFromCommandLine(command_line, startup_context.get(),
- &sync_params)) {
- std::cerr << GetSyncParamsUsage();
- return -1;
- }
- sync_params_ptr = &sync_params;
- }
-
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
-
-} // namespace
-
-std::vector<const LedgerAppInstanceFactoryBuilder*>
-GetLedgerAppInstanceFactoryBuilders() {
- static auto static_builder = FactoryBuilderE2eImpl();
- std::vector<const LedgerAppInstanceFactoryBuilder*> builders = {
- &static_builder};
- return builders;
-}
-
-} // namespace ledger
-
-int main(int argc, char** argv) { return ledger::Main(argc, argv); }
diff --git a/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.cc b/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.cc
deleted file mode 100644
index a884718..0000000
--- a/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.h"
-
-#include <utility>
-
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/svc/cpp/services.h>
-
-#include "peridot/bin/cloud_provider_firestore/testing/cloud_provider_factory.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/fidl_helpers/bound_interface_set.h"
-#include "peridot/bin/ledger/testing/ledger_app_instance_factory.h"
-#include "peridot/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/firebase_auth/testing/fake_token_manager.h"
-
-namespace ledger {
-namespace {
-constexpr fxl::StringView kLedgerName = "AppTests";
-
-class LedgerAppInstanceImpl final
- : public LedgerAppInstanceFactory::LedgerAppInstance {
- public:
- LedgerAppInstanceImpl(
- LoopController* loop_controller, rng::Random* random,
- ledger_internal::LedgerRepositoryFactoryPtr ledger_repository_factory,
- SyncParams sync_params,
- cloud_provider_firestore::CloudProviderFactory::UserId user_id);
-
- void Init(fidl::InterfaceRequest<ledger_internal::LedgerRepositoryFactory>
- repository_factory_request);
-
- private:
- cloud_provider::CloudProviderPtr MakeCloudProvider() override;
- std::string GetUserId() override;
-
- SyncParams sync_params_;
- std::unique_ptr<component::StartupContext> startup_context_;
- cloud_provider_firestore::CloudProviderFactory cloud_provider_factory_;
-
- fuchsia::sys::ComponentControllerPtr controller_;
- const cloud_provider_firestore::CloudProviderFactory::UserId user_id_;
-};
-
-LedgerAppInstanceImpl::LedgerAppInstanceImpl(
- LoopController* loop_controller, rng::Random* random,
- ledger_internal::LedgerRepositoryFactoryPtr ledger_repository_factory,
- SyncParams sync_params,
- cloud_provider_firestore::CloudProviderFactory::UserId user_id)
- : LedgerAppInstanceFactory::LedgerAppInstance(
- loop_controller, convert::ToArray(kLedgerName),
- std::move(ledger_repository_factory)),
- sync_params_(sync_params),
- startup_context_(component::StartupContext::CreateFromStartupInfo()),
- cloud_provider_factory_(startup_context_.get(), random,
- std::move(sync_params.api_key),
- std::move(sync_params.credentials)),
- user_id_(std::move(user_id)) {
-}
-
-void LedgerAppInstanceImpl::Init(
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryFactory>
- repository_factory_request) {
- cloud_provider_factory_.Init();
-
- component::Services child_services;
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = "fuchsia-pkg://fuchsia.com/ledger#meta/ledger.cmx";
- launch_info.directory_request = child_services.NewRequest();
- launch_info.arguments.push_back("--disable_reporting");
- launch_info.arguments.push_back("--firebase_api_key=" + sync_params_.api_key);
-
- startup_context_->launcher()->CreateComponent(std::move(launch_info),
- controller_.NewRequest());
- child_services.ConnectToService(std::move(repository_factory_request));
-}
-
-cloud_provider::CloudProviderPtr LedgerAppInstanceImpl::MakeCloudProvider() {
- cloud_provider::CloudProviderPtr cloud_provider;
- cloud_provider_factory_.MakeCloudProvider(user_id_,
- cloud_provider.NewRequest());
- return cloud_provider;
-}
-
-std::string LedgerAppInstanceImpl::GetUserId() { return user_id_.user_id(); }
-
-} // namespace
-
-LedgerAppInstanceFactoryImpl::LedgerAppInstanceFactoryImpl(
- std::unique_ptr<LoopController> loop_controller, SyncParams sync_params)
- : loop_controller_(std::move(loop_controller)),
- sync_params_(std::move(sync_params)),
- user_id_(cloud_provider_firestore::CloudProviderFactory::UserId::New()) {}
-
-LedgerAppInstanceFactoryImpl::~LedgerAppInstanceFactoryImpl() {}
-
-std::unique_ptr<LedgerAppInstanceFactory::LedgerAppInstance>
-LedgerAppInstanceFactoryImpl::NewLedgerAppInstance() {
- ledger_internal::LedgerRepositoryFactoryPtr repository_factory;
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryFactory>
- repository_factory_request = repository_factory.NewRequest();
- auto result = std::make_unique<LedgerAppInstanceImpl>(
- loop_controller_.get(), &random_, std::move(repository_factory),
- sync_params_, user_id_);
- result->Init(std::move(repository_factory_request));
- return result;
-}
-
-LoopController* LedgerAppInstanceFactoryImpl::GetLoopController() {
- return loop_controller_.get();
-}
-
-rng::Random* LedgerAppInstanceFactoryImpl::GetRandom() { return &random_; }
-
-} // namespace ledger
diff --git a/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.h b/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.h
deleted file mode 100644
index 6d1c894..0000000
--- a/bin/ledger/tests/e2e_sync/ledger_app_instance_factory_e2e.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTS_E2E_SYNC_LEDGER_APP_INSTANCE_FACTORY_E2E_H_
-#define PERIDOT_BIN_LEDGER_TESTS_E2E_SYNC_LEDGER_APP_INSTANCE_FACTORY_E2E_H_
-
-#include <memory>
-#include <string>
-
-#include "peridot/bin/cloud_provider_firestore/testing/cloud_provider_factory.h"
-#include "peridot/bin/ledger/testing/ledger_app_instance_factory.h"
-#include "peridot/bin/ledger/testing/sync_params.h"
-#include "peridot/lib/rng/system_random.h"
-
-namespace ledger {
-
-class LedgerAppInstanceFactoryImpl : public LedgerAppInstanceFactory {
- public:
- explicit LedgerAppInstanceFactoryImpl(
- std::unique_ptr<LoopController> loop_controller, SyncParams sync_params);
- ~LedgerAppInstanceFactoryImpl() override;
-
- std::unique_ptr<LedgerAppInstance> NewLedgerAppInstance() override;
- LoopController* GetLoopController() override;
- rng::Random* GetRandom() override;
-
- private:
- std::unique_ptr<LoopController> loop_controller_;
- rng::SystemRandom random_;
- const SyncParams sync_params_;
- const cloud_provider_firestore::CloudProviderFactory::UserId user_id_;
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTS_E2E_SYNC_LEDGER_APP_INSTANCE_FACTORY_E2E_H_
diff --git a/bin/ledger/tests/e2e_sync/ledger_e2e_sync.cmx b/bin/ledger/tests/e2e_sync/ledger_e2e_sync.cmx
deleted file mode 100644
index a782c4f..0000000
--- a/bin/ledger/tests/e2e_sync/ledger_e2e_sync.cmx
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "facets": {
- "fuchsia.test": {
- "injected-services": {
- "fuchsia.net.oldhttp.HttpService": "http"
- },
- "system-services": [
- "fuchsia.net.SocketProvider",
- "fuchsia.netstack.Netstack",
- "fuchsia.net.stack.Stack"
- ]
- }
- },
- "program": {
- "binary": "test/disabled/ledger_e2e_sync"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.sys.Launcher",
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/bin/ledger/tests/integration/BUILD.gn b/bin/ledger/tests/integration/BUILD.gn
deleted file mode 100644
index 802d68f..0000000
--- a/bin/ledger/tests/integration/BUILD.gn
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-executable("integration") {
- output_name = "ledger_integration_tests"
-
- testonly = true
-
- sources = [
- "integration_test_tests.cc",
- "ledger_app_instance_factory_integration.cc",
- "merging_tests.cc",
- "page_mutation_tests.cc",
- "page_snapshot_tests.cc",
- "page_tests.cc",
- "page_watcher_tests.cc",
- ]
-
- deps = [
- ":integration_lib",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/component/cpp/testing",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/timekeeper:testing",
- "//peridot/bin/ledger/app:lib",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/ledger/fidl:error_notifier",
- "//peridot/bin/ledger/p2p_provider/impl",
- "//peridot/bin/ledger/p2p_provider/public",
- "//peridot/bin/ledger/p2p_sync/impl",
- "//peridot/bin/ledger/p2p_sync/public",
- "//peridot/bin/ledger/storage/fake:lib",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/testing:ledger_instance_factory",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/bin/ledger/testing/cloud_provider",
- "//peridot/bin/ledger/testing/netconnector",
- "//peridot/bin/ledger/tests/integration/sync",
- "//peridot/lib/convert",
- "//peridot/lib/firebase_auth/testing",
- "//peridot/lib/socket",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//third_party/googletest:gtest_main",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("integration_lib") {
- testonly = true
-
- sources = [
- "integration_test.cc",
- "integration_test.h",
- "test_utils.cc",
- "test_utils.h",
- ]
-
- deps = [
- "//peridot/lib/convert",
- "//peridot/lib/socket",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/ledger/testing:ledger_instance_factory",
- "//peridot/public/fidl/fuchsia.ledger",
- "//third_party/googletest:gtest",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/async-testutils",
- "//zircon/public/lib/trace-provider",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/integration/integration_test.cc b/bin/ledger/tests/integration/integration_test.cc
deleted file mode 100644
index 2509e60..0000000
--- a/bin/ledger/tests/integration/integration_test.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-#include "peridot/lib/socket/socket_pair.h"
-#include "peridot/lib/socket/socket_writer.h"
-
-namespace ledger {
-
-BaseIntegrationTest::BaseIntegrationTest(
- const LedgerAppInstanceFactoryBuilder* factory_builder)
- : factory_builder_(factory_builder) {}
-
-BaseIntegrationTest::~BaseIntegrationTest() = default;
-
-void BaseIntegrationTest::SetUp() {
- ::testing::Test::SetUp();
- factory_ = factory_builder_->NewFactory();
- trace_provider_ = std::make_unique<trace::TraceProvider>(dispatcher());
- services_loop_ = GetLoopController()->StartNewLoop();
-}
-
-void BaseIntegrationTest::TearDown() {
- services_loop_.reset();
- ::testing::Test::TearDown();
-}
-
-void BaseIntegrationTest::RunLoop() { GetLoopController()->RunLoop(); }
-
-void BaseIntegrationTest::StopLoop() { GetLoopController()->StopLoop(); }
-
-std::unique_ptr<SubLoop> BaseIntegrationTest::StartNewLoop() {
- return GetLoopController()->StartNewLoop();
-}
-
-std::unique_ptr<CallbackWaiter> BaseIntegrationTest::NewWaiter() {
- return GetLoopController()->NewWaiter();
-}
-
-async_dispatcher_t* BaseIntegrationTest::dispatcher() {
- return GetLoopController()->dispatcher();
-}
-
-bool BaseIntegrationTest::RunLoopUntil(fit::function<bool()> condition) {
- return GetLoopController()->RunLoopUntil(std::move(condition));
-}
-
-void BaseIntegrationTest::RunLoopFor(zx::duration duration) {
- GetLoopController()->RunLoopFor(duration);
-}
-
-zx::socket BaseIntegrationTest::StreamDataToSocket(std::string data) {
- socket::SocketPair sockets;
- async::PostTask(
- services_loop_->dispatcher(),
- [socket = std::move(sockets.socket1), data = std::move(data)]() mutable {
- auto writer = new socket::StringSocketWriter();
- writer->Start(std::move(data), std::move(socket));
- });
- return std::move(sockets.socket2);
-}
-
-std::unique_ptr<LedgerAppInstanceFactory::LedgerAppInstance>
-BaseIntegrationTest::NewLedgerAppInstance() {
- return GetAppFactory()->NewLedgerAppInstance();
-}
-
-LedgerAppInstanceFactory* BaseIntegrationTest::GetAppFactory() {
- FXL_DCHECK(factory_) << "|SetUp| has not been called.";
- return factory_.get();
-}
-
-LoopController* BaseIntegrationTest::GetLoopController() {
- return GetAppFactory()->GetLoopController();
-}
-
-rng::Random* BaseIntegrationTest::GetRandom() {
- return GetAppFactory()->GetRandom();
-}
-
-IntegrationTest::IntegrationTest() : BaseIntegrationTest(GetParam()) {}
-
-IntegrationTest::~IntegrationTest() = default;
-
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/integration_test.h b/bin/ledger/tests/integration/integration_test.h
deleted file mode 100644
index 1e2972e..0000000
--- a/bin/ledger/tests/integration/integration_test.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_INTEGRATION_TEST_H_
-#define PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_INTEGRATION_TEST_H_
-
-#include <functional>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/real_loop_fixture.h>
-#include <trace-provider/provider.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/ledger_app_instance_factory.h"
-
-namespace ledger {
-
-// Base class for integration tests.
-//
-// Integration tests verify interactions with client-facing FIDL services
-// exposed by Ledger. The FIDL services are run within the test process, on a
-// separate thread.
-class BaseIntegrationTest : public ::testing::Test, public LoopController {
- public:
- explicit BaseIntegrationTest(
- const LedgerAppInstanceFactoryBuilder* factory_builder);
- ~BaseIntegrationTest() override;
-
- BaseIntegrationTest(const BaseIntegrationTest&) = delete;
- BaseIntegrationTest(BaseIntegrationTest&&) = delete;
- BaseIntegrationTest& operator=(const BaseIntegrationTest&) = delete;
- BaseIntegrationTest& operator=(BaseIntegrationTest&&) = delete;
-
- // LoopController:
- void RunLoop() override;
- void StopLoop() override;
- std::unique_ptr<SubLoop> StartNewLoop() override;
- std::unique_ptr<CallbackWaiter> NewWaiter() override;
- async_dispatcher_t* dispatcher() override;
- bool RunLoopUntil(fit::function<bool()> condition) override;
- void RunLoopFor(zx::duration duration) override;
-
- protected:
- // ::testing::Test:
- void SetUp() override;
- void TearDown() override;
-
- zx::socket StreamDataToSocket(std::string data);
-
- std::unique_ptr<LedgerAppInstanceFactory::LedgerAppInstance>
- NewLedgerAppInstance();
-
- LedgerAppInstanceFactory* GetAppFactory();
-
- LoopController* GetLoopController();
-
- rng::Random* GetRandom();
-
- private:
- const LedgerAppInstanceFactoryBuilder* factory_builder_;
- std::unique_ptr<LedgerAppInstanceFactory> factory_;
- // Loop used to run network service and token provider tasks.
- std::unique_ptr<SubLoop> services_loop_;
- std::unique_ptr<trace::TraceProvider> trace_provider_;
-};
-
-class IntegrationTest : public BaseIntegrationTest,
- public ::testing::WithParamInterface<
- const LedgerAppInstanceFactoryBuilder*> {
- public:
- IntegrationTest();
- ~IntegrationTest() override;
-};
-
-// Initializes test environment based on the command line arguments.
-//
-// Returns true iff the initialization was successful.
-bool ProcessCommandLine(int argc, char** argv);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_INTEGRATION_TEST_H_
diff --git a/bin/ledger/tests/integration/integration_test_tests.cc b/bin/ledger/tests/integration/integration_test_tests.cc
deleted file mode 100644
index 5e536ac..0000000
--- a/bin/ledger/tests/integration/integration_test_tests.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <utility>
-#include <vector>
-
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-class IntegrationTestTests : public IntegrationTest {};
-
-TEST_P(IntegrationTestTests, MultipleLedgerAppInstances) {
- auto instance1 = NewLedgerAppInstance();
- auto instance2 = NewLedgerAppInstance();
-
- EXPECT_TRUE(instance1->GetTestLedger());
- EXPECT_TRUE(instance2->GetTestLedger());
-}
-
-INSTANTIATE_TEST_CASE_P(
- IntegrationTestTests, IntegrationTestTests,
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders()));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/ledger_app_instance_factory_integration.cc b/bin/ledger/tests/integration/ledger_app_instance_factory_integration.cc
deleted file mode 100644
index de173e5..0000000
--- a/bin/ledger/tests/integration/ledger_app_instance_factory_integration.cc
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/component/cpp/testing/startup_context_for_test.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/handles/object_info.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/timekeeper/test_loop_test_clock.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/ledger_repository_factory_impl.h"
-#include "peridot/bin/ledger/fidl/error_notifier.h"
-#include "peridot/bin/ledger/fidl_helpers/bound_interface_set.h"
-#include "peridot/bin/ledger/p2p_provider/impl/p2p_provider_impl.h"
-#include "peridot/bin/ledger/p2p_sync/impl/user_communicator_impl.h"
-#include "peridot/bin/ledger/p2p_sync/public/user_communicator_factory.h"
-#include "peridot/bin/ledger/testing/cloud_provider/fake_cloud_provider.h"
-#include "peridot/bin/ledger/testing/cloud_provider/types.h"
-#include "peridot/bin/ledger/testing/ledger_app_instance_factory.h"
-#include "peridot/bin/ledger/testing/loop_controller_test_loop.h"
-#include "peridot/bin/ledger/testing/netconnector/netconnector_factory.h"
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-#include "peridot/lib/rng/random.h"
-#include "peridot/lib/rng/test_random.h"
-#include "peridot/lib/socket/socket_pair.h"
-#include "peridot/lib/socket/socket_writer.h"
-
-namespace ledger {
-namespace {
-
-constexpr fxl::StringView kLedgerName = "AppTests";
-constexpr zx::duration kBackoffDuration = zx::msec(5);
-const char kUserId[] = "user";
-
-// Implementation of rng::Random that delegates to another instance. This is
-// needed because EnvironmentBuilder requires taking ownership of the random
-// implementation.
-class DelegatedRandom final : public rng::Random {
- public:
- DelegatedRandom(rng::Random* base) : base_(base) {}
- ~DelegatedRandom() override = default;
-
- private:
- void InternalDraw(void* buffer, size_t buffer_size) {
- base_->Draw(buffer, buffer_size);
- }
-
- rng::Random* base_;
-};
-
-Environment BuildEnvironment(async::TestLoop* loop,
- async_dispatcher_t* dispatcher,
- async_dispatcher_t* io_dispatcher,
- component::StartupContext* startup_context,
- rng::Random* random) {
- return EnvironmentBuilder()
- .SetAsync(dispatcher)
- .SetIOAsync(io_dispatcher)
- .SetStartupContext(startup_context)
- .SetBackoffFactory([random] {
- return std::make_unique<backoff::ExponentialBackoff>(
- kBackoffDuration, 1u, kBackoffDuration,
- random->NewBitGenerator<uint64_t>());
- })
- .SetClock(std::make_unique<timekeeper::TestLoopTestClock>(loop))
- .SetRandom(std::make_unique<DelegatedRandom>(random))
- .Build();
-}
-
-class LedgerAppInstanceImpl final
- : public LedgerAppInstanceFactory::LedgerAppInstance {
- public:
- LedgerAppInstanceImpl(
- LoopControllerTestLoop* loop_controller,
- async_dispatcher_t* services_dispatcher, rng::Random* random,
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryFactory>
- repository_factory_request,
- fidl::InterfacePtr<ledger_internal::LedgerRepositoryFactory>
- repository_factory_ptr,
- fidl_helpers::BoundInterfaceSet<cloud_provider::CloudProvider,
- FakeCloudProvider>* cloud_provider,
- std::unique_ptr<p2p_sync::UserCommunicatorFactory>
- user_communicator_factory);
- ~LedgerAppInstanceImpl() override;
-
- private:
- class LedgerRepositoryFactoryContainer {
- public:
- LedgerRepositoryFactoryContainer(
- async::TestLoop* loop, async_dispatcher_t* dispatcher,
- async_dispatcher_t* io_dispatcher, rng::Random* random,
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryFactory>
- request,
- std::unique_ptr<p2p_sync::UserCommunicatorFactory>
- user_communicator_factory)
- : startup_context_(component::testing::StartupContextForTest::Create()),
- environment_(BuildEnvironment(loop, dispatcher, io_dispatcher,
- startup_context_.get(), random)),
- factory_impl_(&environment_, std::move(user_communicator_factory),
- component::ObjectDir()),
- binding_(&factory_impl_, std::move(request)) {}
- ~LedgerRepositoryFactoryContainer() {}
-
- private:
- std::unique_ptr<component::StartupContext> startup_context_;
- Environment environment_;
- LedgerRepositoryFactoryImpl factory_impl_;
- ErrorNotifierBinding<
- fuchsia::ledger::internal::LedgerRepositoryFactoryErrorNotifierDelegate>
- binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerRepositoryFactoryContainer);
- };
-
- cloud_provider::CloudProviderPtr MakeCloudProvider() override;
- std::string GetUserId() override;
-
- std::unique_ptr<SubLoop> loop_;
- std::unique_ptr<SubLoop> io_loop_;
- std::unique_ptr<LedgerRepositoryFactoryContainer> factory_container_;
- async_dispatcher_t* services_dispatcher_;
- fidl_helpers::BoundInterfaceSet<cloud_provider::CloudProvider,
- FakeCloudProvider>* const cloud_provider_;
-
- // This must be the last field of this class.
- fxl::WeakPtrFactory<LedgerAppInstanceImpl> weak_ptr_factory_;
-};
-
-LedgerAppInstanceImpl::LedgerAppInstanceImpl(
- LoopControllerTestLoop* loop_controller,
- async_dispatcher_t* services_dispatcher, rng::Random* random,
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryFactory>
- repository_factory_request,
- fidl::InterfacePtr<ledger_internal::LedgerRepositoryFactory>
- repository_factory_ptr,
- fidl_helpers::BoundInterfaceSet<cloud_provider::CloudProvider,
- FakeCloudProvider>* cloud_provider,
- std::unique_ptr<p2p_sync::UserCommunicatorFactory>
- user_communicator_factory)
- : LedgerAppInstanceFactory::LedgerAppInstance(
- loop_controller, convert::ToArray(kLedgerName),
- std::move(repository_factory_ptr)),
- loop_(loop_controller->StartNewLoop()),
- io_loop_(loop_controller->StartNewLoop()),
- services_dispatcher_(services_dispatcher),
- cloud_provider_(cloud_provider),
- weak_ptr_factory_(this) {
- async::PostTask(loop_->dispatcher(),
- [this, loop_controller, random,
- request = std::move(repository_factory_request),
- user_communicator_factory =
- std::move(user_communicator_factory)]() mutable {
- factory_container_ =
- std::make_unique<LedgerRepositoryFactoryContainer>(
- &loop_controller->test_loop(), loop_->dispatcher(),
- io_loop_->dispatcher(), random, std::move(request),
- std::move(user_communicator_factory));
- });
-}
-
-cloud_provider::CloudProviderPtr LedgerAppInstanceImpl::MakeCloudProvider() {
- cloud_provider::CloudProviderPtr cloud_provider;
- async::PostTask(services_dispatcher_,
- callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this, request = cloud_provider.NewRequest()]() mutable {
- cloud_provider_->AddBinding(std::move(request));
- }));
- return cloud_provider;
-}
-
-std::string LedgerAppInstanceImpl::GetUserId() { return kUserId; }
-
-LedgerAppInstanceImpl::~LedgerAppInstanceImpl() {
- async::PostTask(loop_->dispatcher(), [this] { factory_container_.reset(); });
- loop_->DrainAndQuit();
- loop_.release();
-}
-
-class FakeUserCommunicatorFactory : public p2p_sync::UserCommunicatorFactory {
- public:
- FakeUserCommunicatorFactory(async::TestLoop* loop,
- async_dispatcher_t* services_dispatcher,
- rng::Random* random,
- NetConnectorFactory* netconnector_factory,
- std::string host_name)
- : services_dispatcher_(services_dispatcher),
- startup_context_(component::testing::StartupContextForTest::Create()),
- environment_(BuildEnvironment(loop, services_dispatcher,
- services_dispatcher,
- startup_context_.get(), random)),
- netconnector_factory_(netconnector_factory),
- host_name_(std::move(host_name)),
- weak_ptr_factory_(this) {}
- ~FakeUserCommunicatorFactory() override {}
-
- std::unique_ptr<p2p_sync::UserCommunicator> GetUserCommunicator(
- std::unique_ptr<p2p_provider::UserIdProvider> user_id_provider) override {
- fuchsia::netconnector::NetConnectorPtr netconnector;
- async::PostTask(services_dispatcher_,
- callback::MakeScoped(
- weak_ptr_factory_.GetWeakPtr(),
- [this, request = netconnector.NewRequest()]() mutable {
- netconnector_factory_->AddBinding(host_name_,
- std::move(request));
- }));
- std::unique_ptr<p2p_provider::P2PProvider> provider =
- std::make_unique<p2p_provider::P2PProviderImpl>(
- host_name_, std::move(netconnector), std::move(user_id_provider));
- return std::make_unique<p2p_sync::UserCommunicatorImpl>(
- std::move(provider), environment_.coroutine_service());
- }
-
- private:
- async_dispatcher_t* const services_dispatcher_;
- std::unique_ptr<component::StartupContext> startup_context_;
- Environment environment_;
- NetConnectorFactory* const netconnector_factory_;
- std::string host_name_;
-
- // This must be the last field of this class.
- fxl::WeakPtrFactory<FakeUserCommunicatorFactory> weak_ptr_factory_;
-};
-
-enum EnableP2PMesh { NO, YES };
-
-} // namespace
-
-class LedgerAppInstanceFactoryImpl : public LedgerAppInstanceFactory {
- public:
- LedgerAppInstanceFactoryImpl(InjectNetworkError inject_network_error,
- EnableP2PMesh enable_p2p_mesh)
- : loop_controller_(&loop_),
- random_(loop_.initial_state()),
- services_loop_(loop_controller_.StartNewLoop()),
- cloud_provider_(FakeCloudProvider::Builder().SetInjectNetworkError(
- inject_network_error)),
- enable_p2p_mesh_(enable_p2p_mesh) {}
- ~LedgerAppInstanceFactoryImpl() override;
-
- std::unique_ptr<LedgerAppInstance> NewLedgerAppInstance() override;
-
- LoopController* GetLoopController() override;
-
- rng::Random* GetRandom() override;
-
- private:
- async::TestLoop loop_;
- LoopControllerTestLoop loop_controller_;
- rng::TestRandom random_;
- // Loop on which to run services.
- std::unique_ptr<SubLoop> services_loop_;
- fidl_helpers::BoundInterfaceSet<cloud_provider::CloudProvider,
- FakeCloudProvider>
- cloud_provider_;
- int app_instance_counter_ = 0;
- NetConnectorFactory netconnector_factory_;
- const EnableP2PMesh enable_p2p_mesh_;
-};
-
-LedgerAppInstanceFactoryImpl::~LedgerAppInstanceFactoryImpl() {
- services_loop_->DrainAndQuit();
- services_loop_.reset();
-}
-
-std::unique_ptr<LedgerAppInstanceFactory::LedgerAppInstance>
-LedgerAppInstanceFactoryImpl::NewLedgerAppInstance() {
- ledger_internal::LedgerRepositoryFactoryPtr repository_factory_ptr;
- fidl::InterfaceRequest<ledger_internal::LedgerRepositoryFactory>
- repository_factory_request = repository_factory_ptr.NewRequest();
-
- std::unique_ptr<p2p_sync::UserCommunicatorFactory> user_communicator_factory;
- if (enable_p2p_mesh_ == EnableP2PMesh::YES) {
- std::string host_name = "host_" + std::to_string(app_instance_counter_);
- user_communicator_factory = std::make_unique<FakeUserCommunicatorFactory>(
- &loop_controller_.test_loop(), services_loop_->dispatcher(), &random_,
- &netconnector_factory_, std::move(host_name));
- }
- auto result = std::make_unique<LedgerAppInstanceImpl>(
- &loop_controller_, services_loop_->dispatcher(), &random_,
- std::move(repository_factory_request), std::move(repository_factory_ptr),
- &cloud_provider_, std::move(user_communicator_factory));
- app_instance_counter_++;
- return result;
-}
-
-LoopController* LedgerAppInstanceFactoryImpl::GetLoopController() {
- return &loop_controller_;
-}
-
-rng::Random* LedgerAppInstanceFactoryImpl::GetRandom() { return &random_; }
-
-namespace {
-
-class FactoryBuilderIntegrationImpl : public LedgerAppInstanceFactoryBuilder {
- public:
- FactoryBuilderIntegrationImpl(InjectNetworkError inject_error,
- EnableP2PMesh enable_p2p)
- : inject_error_(inject_error), enable_p2p_(enable_p2p){};
-
- std::unique_ptr<LedgerAppInstanceFactory> NewFactory() const override {
- return std::make_unique<LedgerAppInstanceFactoryImpl>(inject_error_,
- enable_p2p_);
- }
-
- private:
- InjectNetworkError inject_error_;
- EnableP2PMesh enable_p2p_;
-};
-
-} // namespace
-
-std::vector<const LedgerAppInstanceFactoryBuilder*>
-GetLedgerAppInstanceFactoryBuilders() {
- static std::vector<std::unique_ptr<FactoryBuilderIntegrationImpl>>
- static_builders;
- static std::once_flag flag;
-
- auto static_builders_ptr = &static_builders;
- std::call_once(flag, [&static_builders_ptr] {
- for (auto inject_error :
- {InjectNetworkError::NO, InjectNetworkError::YES}) {
- for (auto enable_p2p : {EnableP2PMesh::NO, EnableP2PMesh::YES}) {
- if (enable_p2p == EnableP2PMesh::YES &&
- inject_error != InjectNetworkError::YES) {
- // Only enable p2p when cloud has errors. This helps ensure our tests
- // are fast enough for the CQ.
- continue;
- }
- static_builders_ptr->push_back(
- std::make_unique<FactoryBuilderIntegrationImpl>(inject_error,
- enable_p2p));
- }
- }
- });
-
- std::vector<const LedgerAppInstanceFactoryBuilder*> builders;
-
- for (const auto& builder : static_builders) {
- builders.push_back(builder.get());
- }
-
- return builders;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/ledger_integration_tests.cmx b/bin/ledger/tests/integration/ledger_integration_tests.cmx
deleted file mode 100644
index 5f7761c..0000000
--- a/bin/ledger/tests/integration/ledger_integration_tests.cmx
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "program": {
- "binary": "test/ledger_integration_tests"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/bin/ledger/tests/integration/merging_tests.cc b/bin/ledger/tests/integration/merging_tests.cc
deleted file mode 100644
index 852d79f..0000000
--- a/bin/ledger/tests/integration/merging_tests.cc
+++ /dev/null
@@ -1,2298 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <map>
-#include <utility>
-#include <vector>
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/callback/capture.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-class MergingIntegrationTest : public IntegrationTest {
- public:
- MergingIntegrationTest() {}
- ~MergingIntegrationTest() override {}
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(MergingIntegrationTest);
-};
-
-class Watcher : public PageWatcher {
- public:
- Watcher(fidl::InterfaceRequest<PageWatcher> request,
- fit::closure change_callback)
- : binding_(this, std::move(request)),
- change_callback_(std::move(change_callback)) {}
-
- uint changes_seen = 0;
- PageSnapshotPtr last_snapshot_;
- PageChange last_page_change_;
-
- private:
- // PageWatcher:
- void OnChange(PageChange page_change, ResultState result_state,
- OnChangeCallback callback) override {
- FXL_DCHECK(result_state == ResultState::COMPLETED)
- << "Handling OnChange pagination not implemented yet";
- changes_seen++;
- last_page_change_ = std::move(page_change);
- last_snapshot_.Unbind();
- callback(last_snapshot_.NewRequest());
- change_callback_();
- }
-
- fidl::Binding<PageWatcher> binding_;
- fit::closure change_callback_;
-};
-
-enum class MergeType {
- SIMPLE,
- MULTIPART,
-};
-
-class ConflictResolverImpl : public ConflictResolver {
- public:
- explicit ConflictResolverImpl(
- LoopController* loop_controller,
- fidl::InterfaceRequest<ConflictResolver> request)
- : loop_controller_(loop_controller),
- resolve_waiter_(loop_controller->NewWaiter()),
- binding_(this, std::move(request)) {
- binding_.set_error_handler(callback::Capture([] {}, &disconnected));
- }
- ~ConflictResolverImpl() override {}
-
- struct ResolveRequest {
- fidl::InterfaceHandle<PageSnapshot> left_version;
- fidl::InterfaceHandle<PageSnapshot> right_version;
- fidl::InterfaceHandle<PageSnapshot> common_version;
- MergeResultProviderPtr result_provider;
- zx_status_t result_provider_status = ZX_OK;
-
- ResolveRequest(LoopController* loop_controller,
- fidl::InterfaceHandle<PageSnapshot> left_version,
- fidl::InterfaceHandle<PageSnapshot> right_version,
- fidl::InterfaceHandle<PageSnapshot> common_version,
- fidl::InterfaceHandle<MergeResultProvider> result_provider)
- : left_version(std::move(left_version)),
- right_version(std::move(right_version)),
- common_version(std::move(common_version)),
- result_provider(result_provider.Bind()),
- disconnect_waiter_(loop_controller->NewWaiter()),
- loop_controller_(loop_controller) {
- this->result_provider.set_error_handler(callback::Capture(
- disconnect_waiter_->GetCallback(), &result_provider_status));
- }
-
- // Returns the full list of changes.
- // Returns the full list of changes between branches and makes sure that at
- // least |min_queries| of partial results are returned before retrieving the
- // complete result for the left and for the right changes.
- ::testing::AssertionResult GetFullDiff(std::vector<DiffEntry>* entries,
- size_t min_queries = 0) {
- return GetDiff(
- [this](std::unique_ptr<Token> token,
- fit::function<void(IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) mutable {
- result_provider->GetFullDiffNew(std::move(token),
- std::move(callback));
- },
- entries, min_queries);
- }
-
- ::testing::AssertionResult GetConflictingDiff(
- std::vector<DiffEntry>* entries, size_t min_queries = 0) {
- return GetDiff(
- [this](std::unique_ptr<Token> token,
- fit::function<void(IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>
- callback) mutable {
- result_provider->GetConflictingDiffNew(std::move(token),
- std::move(callback));
- },
- entries, min_queries);
- }
-
- // Resolves the conflict by sending the given merge results. If
- // |merge_type| is MULTIPART, the merge will be send in two parts, each
- // sending half of |results|' elements.
- ::testing::AssertionResult Merge(std::vector<MergedValue> results,
- MergeType merge_type = MergeType::SIMPLE) {
- FXL_DCHECK(merge_type == MergeType::SIMPLE || results.size() >= 2);
-
- if (!result_provider) {
- return ::testing::AssertionFailure()
- << "Merge failed: result_provider is disconnected.";
- }
-
- if (merge_type == MergeType::SIMPLE) {
- ::testing::AssertionResult merge_status =
- PartialMerge(std::move(results));
- if (!merge_status) {
- return merge_status;
- }
- } else {
- size_t part1_size = results.size() / 2;
- std::vector<MergedValue> part2;
- for (size_t i = part1_size; i < results.size(); ++i) {
- part2.push_back(std::move(results.at(i)));
- }
- results.resize(part1_size);
-
- ::testing::AssertionResult merge_status =
- PartialMerge(std::move(results));
- if (!merge_status) {
- return merge_status;
- }
- merge_status = PartialMerge(std::move(part2));
- if (!merge_status) {
- return merge_status;
- }
- }
-
- result_provider->DoneNew();
- return RunUntilDisconnected();
- }
-
- ::testing::AssertionResult MergeNonConflictingEntries() {
- result_provider->MergeNonConflictingEntriesNew();
- return Sync();
- }
-
- private:
- ::testing::AssertionResult Sync() {
- auto waiter = loop_controller_->NewWaiter();
- result_provider->Sync(waiter->GetCallback());
- if (!waiter->RunUntilCalled()) {
- // Printing the |result_provider_status| in case the issue is that the
- // object has been disconnected.
- return ::testing::AssertionFailure()
- << "|Sync| failed to called back. Error provider status: "
- << result_provider_status;
- }
- return ::testing::AssertionSuccess();
- }
-
- ::testing::AssertionResult RunUntilDisconnected() {
- if (!disconnect_waiter_->RunUntilCalled()) {
- return ::testing::AssertionFailure()
- << "Timeout while waiting for the ConflictResolver to be "
- "disconnected from the ResultProvider.";
- }
- return ::testing::AssertionSuccess();
- }
-
- ::testing::AssertionResult GetDiff(
- fit::function<
- void(std::unique_ptr<Token>,
- fit::function<void(IterationStatus, std::vector<DiffEntry>,
- std::unique_ptr<Token>)>)>
- get_diff,
- std::vector<DiffEntry>* entries, size_t min_queries) {
- entries->resize(0);
- size_t num_queries = 0u;
- std::unique_ptr<Token> token;
- do {
- std::vector<DiffEntry> new_entries;
- IterationStatus status;
- auto waiter = loop_controller_->NewWaiter();
- std::unique_ptr<Token> new_token;
- get_diff(std::move(token),
- callback::Capture(waiter->GetCallback(), &status, &new_entries,
- &new_token));
- if (!waiter->RunUntilCalled()) {
- return ::testing::AssertionFailure()
- << "|get_diff| failed to called back.";
- }
- token = std::move(new_token);
- if (!token != (status == IterationStatus::OK)) {
- return ::testing::AssertionFailure()
- << "token is "
- << (token ? convert::ToString(token->opaque_id) : "null")
- << ", but status is:" << fidl::ToUnderlying(status);
- }
- entries->insert(entries->end(),
- std::make_move_iterator(new_entries.begin()),
- std::make_move_iterator(new_entries.end()));
- ++num_queries;
- } while (token);
-
- if (num_queries < min_queries) {
- return ::testing::AssertionFailure()
- << "Only " << num_queries
- << " partial results were found, but at least " << min_queries
- << " were expected";
- }
- return ::testing::AssertionSuccess();
- }
-
- ::testing::AssertionResult PartialMerge(
- std::vector<MergedValue> partial_result) {
- result_provider->MergeNew(std::move(partial_result));
- return Sync();
- }
-
- std::unique_ptr<CallbackWaiter> disconnect_waiter_;
- LoopController* loop_controller_;
- };
-
-
- void RunUntilResolveCalled() {
- ASSERT_TRUE(resolve_waiter_->RunUntilCalled());
- }
-
- std::vector<ResolveRequest> requests;
- bool disconnected = false;
-
- private:
- // ConflictResolver:
- void Resolve(
- fidl::InterfaceHandle<PageSnapshot> left_version,
- fidl::InterfaceHandle<PageSnapshot> right_version,
- fidl::InterfaceHandle<PageSnapshot> common_version,
- fidl::InterfaceHandle<MergeResultProvider> result_provider) override {
- requests.emplace_back(loop_controller_, std::move(left_version),
- std::move(right_version), std::move(common_version),
- std::move(result_provider));
- resolve_waiter_->GetCallback()();
- }
-
- LoopController* loop_controller_;
- std::unique_ptr<CallbackWaiter> resolve_waiter_;
- fidl::Binding<ConflictResolver> binding_;
-};
-
-// Custom conflict resolver that doesn't resolve any conflicts.
-class DummyConflictResolver : public ConflictResolver {
- public:
- explicit DummyConflictResolver(
- fidl::InterfaceRequest<ConflictResolver> request)
- : binding_(this, std::move(request)) {}
- ~DummyConflictResolver() override {}
-
- private:
- // ConflictResolver:
- void Resolve(fidl::InterfaceHandle<PageSnapshot> /*left_version*/,
- fidl::InterfaceHandle<PageSnapshot> /*right_version*/,
- fidl::InterfaceHandle<PageSnapshot> /*common_version*/,
- fidl::InterfaceHandle<MergeResultProvider>
- /*result_provider*/) override {
- // Do nothing.
- }
-
- fidl::Binding<ConflictResolver> binding_;
-};
-
-class TestConflictResolverFactory : public ConflictResolverFactory {
- public:
- TestConflictResolverFactory(
- LoopController* loop_controller, MergePolicy policy,
- fidl::InterfaceRequest<ConflictResolverFactory> request,
- fit::closure on_get_policy_called_callback,
- zx::duration response_delay = zx::msec(0))
- : loop_controller_(loop_controller),
- new_conflict_resolver_waiter_(loop_controller->NewWaiter()),
- policy_(policy),
- binding_(this, std::move(request)),
- callback_(std::move(on_get_policy_called_callback)),
- response_delay_(response_delay) {}
-
- uint get_policy_calls = 0;
- std::map<storage::PageId, ConflictResolverImpl> resolvers;
-
- void set_use_dummy_resolver(bool use_dummy_resolver) {
- use_dummy_resolver_ = use_dummy_resolver;
- }
-
- void RunUntilNewConflictResolverCalled() {
- ASSERT_TRUE(new_conflict_resolver_waiter_->RunUntilCalled());
- }
-
- void Disconnect() { binding_.Unbind(); }
-
- private:
- // ConflictResolverFactory:
- void GetPolicy(PageId /*page_id*/, GetPolicyCallback callback) override {
- get_policy_calls++;
- async::PostDelayedTask(
- loop_controller_->dispatcher(),
- [this, callback = std::move(callback)] {
- callback(policy_);
- if (callback_) {
- callback_();
- }
- },
- response_delay_);
- }
-
- void NewConflictResolver(
- PageId page_id,
- fidl::InterfaceRequest<ConflictResolver> resolver) override {
- if (use_dummy_resolver_) {
- dummy_resolvers_.emplace(
- std::piecewise_construct,
- std::forward_as_tuple(convert::ToString(page_id.id)),
- std::forward_as_tuple(std::move(resolver)));
- new_conflict_resolver_waiter_->GetCallback()();
- return;
- }
- resolvers.emplace(
- std::piecewise_construct,
- std::forward_as_tuple(convert::ToString(page_id.id)),
- std::forward_as_tuple(loop_controller_, std::move(resolver)));
- new_conflict_resolver_waiter_->GetCallback()();
- }
-
- LoopController* loop_controller_;
- std::unique_ptr<CallbackWaiter> new_conflict_resolver_waiter_;
- MergePolicy policy_;
- bool use_dummy_resolver_ = false;
- std::map<storage::PageId, DummyConflictResolver> dummy_resolvers_;
- fidl::Binding<ConflictResolverFactory> binding_;
- fit::closure callback_;
- zx::duration response_delay_;
-};
-
-// Optional is an object that optionally contains another object.
-template <typename T>
-class Optional {
- public:
- Optional() : obj_() {}
- explicit Optional(T obj) : valid_(true), obj_(std::move(obj)) {}
-
- constexpr const T& operator*() const& { return obj_; }
-
- constexpr const T* operator->() const { return &obj_; }
-
- constexpr explicit operator bool() const { return valid_; }
-
- private:
- bool const valid_ = false;
- T const obj_;
-};
-
-::testing::AssertionResult ValueMatch(const std::string& type,
- const ValuePtr& value,
- const Optional<std::string>& expected) {
- if (expected) {
- if (!value) {
- return ::testing::AssertionFailure()
- << type << " has no value but expected \"" << *expected << "\".";
- }
- if (ToString(value->value) != *expected) {
- return ::testing::AssertionFailure()
- << type << " has value \"" << ToString(value->value)
- << "\" but expected \"" << *expected << "\".";
- }
- } else if (!expected && value) {
- return ::testing::AssertionFailure()
- << type << " has value \"" << ToString(value->value)
- << "\" but expected no value.";
- }
- return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult ChangeMatch(std::string expected_key,
- Optional<std::string> expected_base,
- Optional<std::string> expected_left,
- Optional<std::string> expected_right,
- const DiffEntry& entry) {
- convert::ExtendedStringView found_key(entry.key);
- if (expected_key != convert::ExtendedStringView(found_key)) {
- return ::testing::AssertionFailure()
- << "Expected key \"" << expected_key << "\" but found \""
- << found_key << "\"";
- }
- ::testing::AssertionResult result =
- ValueMatch("Base", entry.base, expected_base);
- if (!result) {
- return result;
- }
- result = ValueMatch("Left", entry.left, expected_left);
- if (!result) {
- return result;
- }
- return ValueMatch("Right", entry.right, expected_right);
-}
-
-TEST_P(MergingIntegrationTest, Merging) {
- auto instance = NewLedgerAppInstance();
- PagePtr page1 = instance->GetTestPage();
- auto waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- PageWatcherPtr watcher1_ptr;
- auto watcher1_waiter = NewWaiter();
- Watcher watcher1(watcher1_ptr.NewRequest(), watcher1_waiter->GetCallback());
-
- PageSnapshotPtr snapshot1;
- Status status;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot1.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher1_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageWatcherPtr watcher2_ptr;
- auto watcher2_waiter = NewWaiter();
- Watcher watcher2(watcher2_ptr.NewRequest(), watcher2_waiter->GetCallback());
-
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page2->GetSnapshot(snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher2_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("city"), convert::ToArray("Paris"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("phone"), convert::ToArray("0123456789"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Verify that each change is seen by the right watcher.
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- ASSERT_TRUE(watcher1_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher1.changes_seen);
- PageChange change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(2u, change.changed_entries.size());
- EXPECT_EQ("city", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Paris", ToString(change.changed_entries.at(0).value));
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(1).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(1).value));
-
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- ASSERT_TRUE(watcher2_waiter->RunUntilCalled());
-
- EXPECT_EQ(1u, watcher2.changes_seen);
- change = std::move(watcher2.last_page_change_);
- ASSERT_EQ(2u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Bob", ToString(change.changed_entries.at(0).value));
- EXPECT_EQ("phone", convert::ToString(change.changed_entries.at(1).key));
- EXPECT_EQ("0123456789", ToString(change.changed_entries.at(1).value));
-
- ASSERT_TRUE(watcher1_waiter->RunUntilCalled());
- ASSERT_TRUE(watcher2_waiter->RunUntilCalled());
-
- // Each change is seen once, and by the correct watcher only.
- EXPECT_EQ(2u, watcher1.changes_seen);
- change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(2u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Bob", ToString(change.changed_entries.at(0).value));
- EXPECT_EQ("phone", convert::ToString(change.changed_entries.at(1).key));
- EXPECT_EQ("0123456789", ToString(change.changed_entries.at(1).value));
-
- EXPECT_EQ(2u, watcher2.changes_seen);
- change = std::move(watcher2.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("city", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Paris", ToString(change.changed_entries.at(0).value));
-}
-
-TEST_P(MergingIntegrationTest, MergingWithConflictResolutionFactory) {
- auto instance = NewLedgerAppInstance();
- PagePtr page1 = instance->GetTestPage();
- auto waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- // Set up a resolver configured not to resolve any conflicts.
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory_waiter = NewWaiter();
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr.NewRequest(),
- resolver_factory_waiter->GetCallback());
- resolver_factory->set_use_dummy_resolver(true);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- Status status;
- waiter = NewWaiter();
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Wait for the conflict resolver factory policy to be requested.
- ASSERT_TRUE(resolver_factory_waiter->RunUntilCalled());
-
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- PageWatcherPtr watcher1_ptr;
- auto watcher1_waiter = NewWaiter();
- Watcher watcher1(watcher1_ptr.NewRequest(), watcher1_waiter->GetCallback());
- PageSnapshotPtr snapshot1;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot1.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher1_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageWatcherPtr watcher2_ptr;
- auto watcher2_waiter = NewWaiter();
- Watcher watcher2(watcher2_ptr.NewRequest(), watcher2_waiter->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page2->GetSnapshot(snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher2_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("city"), convert::ToArray("Paris"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("phone"), convert::ToArray("0123456789"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Verify that each change is seen by the right watcher.
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher1_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher1.changes_seen);
- PageChange change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(2u, change.changed_entries.size());
- EXPECT_EQ("city", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Paris", ToString(change.changed_entries.at(0).value));
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(1).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(1).value));
-
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher2_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher2.changes_seen);
- change = std::move(watcher2.last_page_change_);
- ASSERT_EQ(2u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Bob", ToString(change.changed_entries.at(0).value));
- EXPECT_EQ("phone", convert::ToString(change.changed_entries.at(1).key));
- EXPECT_EQ("0123456789", ToString(change.changed_entries.at(1).value));
-
- // Check that the resolver fectory GetPolicy method is not called.
- RunLoopFor(zx::sec(1));
- EXPECT_TRUE(resolver_factory_waiter->NotCalledYet());
- EXPECT_EQ(1u, resolver_factory->get_policy_calls);
-
- // Change the merge strategy, triggering resolution of the conflicts.
- resolver_factory_ptr = nullptr; // Suppress misc-use-after-move.
- resolver_factory_waiter = NewWaiter();
- resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::LAST_ONE_WINS, resolver_factory_ptr.NewRequest(),
- resolver_factory_waiter->GetCallback());
- waiter = NewWaiter();
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(resolver_factory_waiter->RunUntilCalled());
- ASSERT_TRUE(watcher1_waiter->RunUntilCalled());
- ASSERT_TRUE(watcher2_waiter->RunUntilCalled());
-
- // Each change is seen once, and by the correct watcher only.
- EXPECT_EQ(2u, watcher1.changes_seen);
- change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(2u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Bob", ToString(change.changed_entries.at(0).value));
- EXPECT_EQ("phone", convert::ToString(change.changed_entries.at(1).key));
- EXPECT_EQ("0123456789", ToString(change.changed_entries.at(1).value));
-
- EXPECT_EQ(2u, watcher2.changes_seen);
- change = std::move(watcher2.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("city", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Paris", ToString(change.changed_entries.at(0).value));
-
- EXPECT_EQ(1u, resolver_factory->get_policy_calls);
-}
-
-TEST_P(MergingIntegrationTest, CustomConflictResolutionNoConflict) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("city"), convert::ToArray("Paris"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("phone"), convert::ToArray("0123456789"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("email"), convert::ToArray("alice@example.org"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have a conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl->requests.size());
-
- std::vector<DiffEntry> changes;
- ASSERT_TRUE(resolver_impl->requests[0].GetFullDiff(&changes));
-
- EXPECT_EQ(4u, changes.size());
- EXPECT_TRUE(ChangeMatch("city", Optional<std::string>(),
- Optional<std::string>(),
- Optional<std::string>("Paris"), changes[0]));
- EXPECT_TRUE(ChangeMatch("email", Optional<std::string>(),
- Optional<std::string>("alice@example.org"),
- Optional<std::string>(), changes[1]));
- EXPECT_TRUE(ChangeMatch("name", Optional<std::string>(),
- Optional<std::string>(),
- Optional<std::string>("Alice"), changes[2]));
- EXPECT_TRUE(ChangeMatch("phone", Optional<std::string>(),
- Optional<std::string>("0123456789"),
- Optional<std::string>(), changes[3]));
-
- // Common ancestor is empty.
- PageSnapshotPtr snapshot = resolver_impl->requests[0].common_version.Bind();
- auto entries = SnapshotGetEntries(this, &snapshot);
- EXPECT_EQ(0u, entries.size());
-
- // Prepare the merged values
- std::vector<MergedValue> merged_values;
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("name");
- merged_value.source = ValueSource::RIGHT;
- merged_values.push_back(std::move(merged_value));
- }
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("email");
- merged_value.source = ValueSource::DELETE;
- merged_values.push_back(std::move(merged_value));
- }
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("pager");
- merged_value.source = ValueSource::NEW;
- BytesOrReferencePtr value = BytesOrReference::New();
- value->set_bytes(convert::ToArray("pager@example.org"));
- merged_value.new_value = std::move(value);
- merged_values.push_back(std::move(merged_value));
- }
-
- // Watch for the change.
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_TRUE(resolver_impl->requests[0].Merge(std::move(merged_values)));
-
- // Wait for the watcher to be called.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
-
- auto final_entries = SnapshotGetEntries(this, &watcher.last_snapshot_);
- ASSERT_EQ(3u, final_entries.size());
- EXPECT_EQ("name", convert::ExtendedStringView(final_entries[0].key));
- EXPECT_EQ("pager", convert::ExtendedStringView(final_entries[1].key));
- EXPECT_EQ("phone", convert::ExtendedStringView(final_entries[2].key));
-}
-
-TEST_P(MergingIntegrationTest, CustomConflictResolutionGetDiffMultiPart) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- int N = 50;
- std::vector<std::string> page1_keys;
- for (int i = 0; i < N; ++i) {
- page1_keys.push_back(fxl::StringPrintf("page1_key_%02d", i));
- waiter = NewWaiter();
- page1->Put(convert::ToArray(page1_keys.back()), convert::ToArray("value"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- std::vector<std::string> page2_keys;
- for (int i = 0; i < N; ++i) {
- page2_keys.push_back(fxl::StringPrintf("page2_key_%02d", i));
- waiter = NewWaiter();
- page2->Put(convert::ToArray(page2_keys.back()), convert::ToArray("value"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // We now have a conflict, wait for the resolve to be called.
- resolver_factory->RunUntilNewConflictResolverCalled();
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl->requests.size());
-
- std::vector<DiffEntry> changes;
- ASSERT_TRUE(resolver_impl->requests[0].GetFullDiff(&changes, 1));
-
- EXPECT_EQ(2u * N, changes.size());
- // Keys are in order, so we expect to have all the page1_key_* keys before the
- // page2_key_* keys.
- for (int i = 0; i < N; ++i) {
- // Left change is the most recent, so the one made on |page2|; right change
- // comes from |page1|.
- EXPECT_TRUE(ChangeMatch(page1_keys[i], Optional<std::string>(),
- Optional<std::string>(),
- Optional<std::string>("value"), changes[i]));
-
- EXPECT_TRUE(ChangeMatch(page2_keys[i], Optional<std::string>(),
- Optional<std::string>("value"),
- Optional<std::string>(), changes[N + i]));
- }
-}
-
-TEST_P(MergingIntegrationTest, CustomConflictResolutionClosingPipe) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have a conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- EXPECT_EQ(1u, resolver_impl->requests.size());
-
- // Kill the resolver
- resolver_factory->resolvers.clear();
- EXPECT_EQ(0u, resolver_factory->resolvers.size());
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We should ask again for a resolution.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl->requests.size());
-
- // Remove all references to a page:
- page1 = nullptr;
- page2 = nullptr;
- RunLoopFor(zx::msec(500));
-
- // Resolution should not crash the Ledger
- std::vector<MergedValue> merged_values;
- EXPECT_TRUE(resolver_impl->requests[0].Merge(std::move(merged_values)));
- RunLoopFor(zx::msec(200));
-}
-
-TEST_P(MergingIntegrationTest, CustomConflictResolutionResetFactory) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have a conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- EXPECT_FALSE(resolver_impl->disconnected);
- resolver_impl->RunUntilResolveCalled();
- EXPECT_EQ(1u, resolver_impl->requests.size());
-
- // Change the factory.
- ConflictResolverFactoryPtr resolver_factory_ptr2;
- auto resolver_factory2 = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr2.NewRequest(), nullptr);
- waiter = NewWaiter();
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr2),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->Disconnect();
-
- // Waiting for the conflict resolution request
- resolver_factory2->RunUntilNewConflictResolverCalled();
-
- // We should ask again for a resolution on a new resolver.
- EXPECT_EQ(1u, resolver_factory2->resolvers.size());
- ASSERT_NE(
- resolver_factory2->resolvers.end(),
- resolver_factory2->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl2 =
- &(resolver_factory2->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl2->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl2->requests.size());
-
- // Remove all references to a page:
- page1 = nullptr;
- page2 = nullptr;
- RunLoopFor(zx::msec(500));
-
- // Resolution should not crash the Ledger
- std::vector<MergedValue> merged_values;
-
- EXPECT_TRUE(resolver_impl2->requests[0].Merge(std::move(merged_values)));
- RunLoopFor(zx::msec(200));
-}
-
-TEST_P(MergingIntegrationTest, CustomConflictResolutionMultipartMerge) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("email"), convert::ToArray("alice@example.org"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have a conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl->requests.size());
-
- // Prepare the merged values
- std::vector<MergedValue> merged_values;
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("name");
- merged_value.source = ValueSource::RIGHT;
- merged_values.push_back(std::move(merged_value));
- }
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("email");
- merged_value.source = ValueSource::DELETE;
- merged_values.push_back(std::move(merged_value));
- }
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("pager");
- merged_value.source = ValueSource::NEW;
- BytesOrReferencePtr value = BytesOrReference::New();
- value->set_bytes(convert::ToArray("pager@example.org"));
- merged_value.new_value = std::move(value);
- merged_values.push_back(std::move(merged_value));
- }
-
- // Watch for the change.
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_TRUE(resolver_impl->requests[0].Merge(std::move(merged_values),
- MergeType::MULTIPART));
-
- // Wait for the watcher to be called.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
-
- auto final_entries = SnapshotGetEntries(this, &watcher.last_snapshot_);
- ASSERT_EQ(2u, final_entries.size());
- EXPECT_EQ("name", convert::ExtendedStringView(final_entries[0].key));
- EXPECT_EQ("pager", convert::ExtendedStringView(final_entries[1].key));
-}
-
-TEST_P(MergingIntegrationTest, AutoConflictResolutionNoConflict) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::AUTOMATIC_WITH_FALLBACK,
- resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- // Watch for changes.
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("city"), convert::ToArray("Paris"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("email"), convert::ToArray("alice@example.org"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("phone"), convert::ToArray("0123456789"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- // We should have seen the first commit at this point.
- EXPECT_EQ(1u, watcher.changes_seen);
-
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have an automatically-resolved conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
-
- // The waiter is notified of the second change while the resolver has not been
- // asked to resolve anything.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(0u, resolver_impl->requests.size());
- EXPECT_EQ(2u, watcher.changes_seen);
-
- auto final_entries = SnapshotGetEntries(this, &watcher.last_snapshot_);
- ASSERT_EQ(4u, final_entries.size());
- EXPECT_EQ("city", convert::ExtendedStringView(final_entries[0].key));
- EXPECT_EQ("email", convert::ExtendedStringView(final_entries[1].key));
- EXPECT_EQ("name", convert::ExtendedStringView(final_entries[2].key));
- EXPECT_EQ("phone", convert::ExtendedStringView(final_entries[3].key));
-}
-
-TEST_P(MergingIntegrationTest, AutoConflictResolutionWithConflict) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::AUTOMATIC_WITH_FALLBACK,
- resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- Status status;
- auto waiter = NewWaiter();
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- PageId test_page_id;
- waiter = NewWaiter();
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("city"), convert::ToArray("Paris"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("city"), convert::ToArray("San Francisco"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have a conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl->requests.size());
-
- std::vector<DiffEntry> changes;
- ASSERT_TRUE(resolver_impl->requests[0].GetFullDiff(&changes));
-
- EXPECT_EQ(2u, changes.size());
- // Left change is the most recent, so the one made on |page2|.
- EXPECT_TRUE(ChangeMatch("city", Optional<std::string>(),
- Optional<std::string>("San Francisco"),
- Optional<std::string>("Paris"), changes[0]));
- EXPECT_TRUE(ChangeMatch("name", Optional<std::string>(),
- Optional<std::string>("Alice"),
- Optional<std::string>(), changes[1]));
-
- // Common ancestor is empty.
- PageSnapshotPtr snapshot = resolver_impl->requests[0].common_version.Bind();
- auto entries = SnapshotGetEntries(this, &snapshot);
- EXPECT_EQ(0u, entries.size());
-
- // Prepare the merged values
- std::vector<MergedValue> merged_values;
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("city");
- merged_value.source = ValueSource::RIGHT;
- merged_values.push_back(std::move(merged_value));
- }
-
- // Watch for the change.
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_TRUE(resolver_impl->requests[0].Merge(std::move(merged_values)));
-
- // Wait for the watcher to be called.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
-
- auto final_entries = SnapshotGetEntries(this, &watcher.last_snapshot_);
- ASSERT_EQ(2u, final_entries.size());
- EXPECT_EQ("city", convert::ExtendedStringView(final_entries[0].key));
- EXPECT_EQ("name", convert::ExtendedStringView(final_entries[1].key));
-}
-
-TEST_P(MergingIntegrationTest, AutoConflictResolutionMultipartMerge) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::AUTOMATIC_WITH_FALLBACK,
- resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- Status status;
- auto waiter = NewWaiter();
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
-
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("city"), convert::ToArray("Paris"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("city"), convert::ToArray("San Francisco"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have a conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl->requests.size());
-
- // Prepare the merged values
- std::vector<MergedValue> merged_values;
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("city");
- merged_value.source = ValueSource::RIGHT;
- merged_values.push_back(std::move(merged_value));
- }
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("previous_city");
- merged_value.source = ValueSource::NEW;
- merged_value.new_value = BytesOrReference::New();
- merged_value.new_value->set_bytes(convert::ToArray("San Francisco"));
- merged_values.push_back(std::move(merged_value));
- }
-
- // Watch for the change.
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_TRUE(resolver_impl->requests[0].Merge(std::move(merged_values),
- MergeType::MULTIPART));
-
- // Wait for the watcher to be called.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
-
- auto final_entries = SnapshotGetEntries(this, &watcher.last_snapshot_);
- ASSERT_EQ(3u, final_entries.size());
- EXPECT_EQ("city", convert::ExtendedStringView(final_entries[0].key));
- EXPECT_EQ("name", convert::ExtendedStringView(final_entries[1].key));
- EXPECT_EQ("previous_city", convert::ExtendedStringView(final_entries[2].key));
-}
-
-// Tests a merge in which the right side contains no change (e.g. a change was
-// made in a commit, then reverted in another commit).
-TEST_P(MergingIntegrationTest, AutoConflictResolutionNoRightChange) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::AUTOMATIC_WITH_FALLBACK,
- resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- // Watch for changes.
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot1;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot1.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // We should have seen the first commit of page 1.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Delete(convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // We should have seen the second commit of page 1.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(2u, watcher.changes_seen);
-
- waiter = NewWaiter();
- page2->Put(convert::ToArray("email"), convert::ToArray("alice@example.org"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have an automatically-resolved conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- ASSERT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
-
- // The waiter is notified of the third change while the resolver has not been
- // asked to resolve anything.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(0u, resolver_impl->requests.size());
- EXPECT_EQ(3u, watcher.changes_seen);
-
- auto final_entries = SnapshotGetEntries(this, &watcher.last_snapshot_);
- ASSERT_EQ(1u, final_entries.size());
- EXPECT_EQ("email", convert::ExtendedStringView(final_entries[0].key));
-}
-
-TEST_P(MergingIntegrationTest, WaitForCustomMerge) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Create a conflict: two pointers to the same page.
- PagePtr page1 = instance->GetTestPage();
- waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- // Parallel put in transactions.
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("email"), convert::ToArray("alice@example.org"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // Check that we have a resolver and pending conflict resolution request.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl->requests.size());
-
- // Try to wait for conflicts resolution.
- auto conflicts_resolved_callback_waiter = NewWaiter();
- ConflictResolutionWaitStatus wait_status;
- page1->WaitForConflictResolution(callback::Capture(
- conflicts_resolved_callback_waiter->GetCallback(), &wait_status));
-
- // Check that conflicts_resolved_callback is not called, as there are merge
- // requests pending.
- RunLoopFor(zx::msec(250));
- EXPECT_TRUE(conflicts_resolved_callback_waiter->NotCalledYet());
-
- // Merge manually.
- std::vector<MergedValue> merged_values;
- EXPECT_TRUE(resolver_impl->requests[0].Merge(std::move(merged_values),
- MergeType::SIMPLE));
- EXPECT_TRUE(conflicts_resolved_callback_waiter->NotCalledYet());
-
- // Now conflict_resolved_callback can run.
- ASSERT_TRUE(conflicts_resolved_callback_waiter->RunUntilCalled());
- EXPECT_EQ(ConflictResolutionWaitStatus::CONFLICTS_RESOLVED, wait_status);
-}
-
-TEST_P(MergingIntegrationTest, CustomConflictResolutionConflictingMerge) {
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::CUSTOM, resolver_factory_ptr.NewRequest(), nullptr);
- LedgerPtr ledger_ptr = instance->GetTestLedger();
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
- PageId test_page_id;
- waiter = NewWaiter();
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("city"), convert::ToArray("Paris"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("phone"), convert::ToArray("0123456789"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->RunUntilNewConflictResolverCalled();
-
- // We now have a conflict.
- EXPECT_EQ(1u, resolver_factory->resolvers.size());
- EXPECT_NE(
- resolver_factory->resolvers.end(),
- resolver_factory->resolvers.find(convert::ToString(test_page_id.id)));
- ConflictResolverImpl* resolver_impl =
- &(resolver_factory->resolvers.find(convert::ToString(test_page_id.id))
- ->second);
- resolver_impl->RunUntilResolveCalled();
- ASSERT_EQ(1u, resolver_impl->requests.size());
-
- std::vector<DiffEntry> changes;
- ASSERT_TRUE(resolver_impl->requests[0].GetConflictingDiff(&changes));
-
- EXPECT_EQ(1u, changes.size());
- EXPECT_TRUE(ChangeMatch("name", Optional<std::string>(),
- Optional<std::string>("Bob"),
- Optional<std::string>("Alice"), changes[0]));
-
- // Prepare the merged values
- std::vector<MergedValue> merged_values;
- {
- MergedValue merged_value;
- merged_value.key = convert::ToArray("name");
- merged_value.source = ValueSource::RIGHT;
- merged_values.push_back(std::move(merged_value));
- }
- ASSERT_TRUE(resolver_impl->requests[0].MergeNonConflictingEntries());
-
- // Watch for the change.
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- EXPECT_TRUE(resolver_impl->requests[0].Merge(std::move(merged_values)));
-
- // Wait for the watcher to be called.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
-
- auto final_entries = SnapshotGetEntries(this, &watcher.last_snapshot_);
- ASSERT_EQ(3u, final_entries.size());
- EXPECT_EQ("city", convert::ExtendedStringView(final_entries[0].key));
- EXPECT_EQ("Paris", ToString(final_entries[0].value));
- EXPECT_EQ("name", convert::ExtendedStringView(final_entries[1].key));
- EXPECT_EQ("Alice", ToString(final_entries[1].value));
- EXPECT_EQ("phone", convert::ExtendedStringView(final_entries[2].key));
- EXPECT_EQ("0123456789", ToString(final_entries[2].value));
-}
-
-// Test that multiple ConflictResolverFactories can be registered, and that
-// when registering a new one:
-// - the existing conflict resolvers are not updated
-// - the first factory is still used for new pages
-TEST_P(MergingIntegrationTest, ConflictResolverFactoryNotChanged) {
- auto resolver_factory_waiter1 = NewWaiter();
- auto resolver_factory_waiter2 = NewWaiter();
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr1;
- auto resolver_factory1 = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::LAST_ONE_WINS, resolver_factory_ptr1.NewRequest(),
- resolver_factory_waiter1->GetCallback());
- ConflictResolverFactoryPtr resolver_factory_ptr2;
- auto resolver_factory2 = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::LAST_ONE_WINS, resolver_factory_ptr2.NewRequest(),
- resolver_factory_waiter2->GetCallback());
- LedgerPtr ledger_ptr = instance->GetTestLedger();
-
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr1),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
-
- // resolver_factory1 has received one request for page1
- ASSERT_TRUE(resolver_factory_waiter1->RunUntilCalled());
- EXPECT_EQ(1u, resolver_factory1->get_policy_calls);
-
- // Connect resolver_factory2 on ledger_ptr1. It does not receive requests
- waiter = NewWaiter();
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr2),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- RunLoopFor(zx::msec(250));
- EXPECT_EQ(0u, resolver_factory2->get_policy_calls);
-
- PagePtr page2 = instance->GetTestPage();
- // resolver_factory1 has received one request for page2
- ASSERT_TRUE(resolver_factory_waiter1->RunUntilCalled());
- EXPECT_EQ(2u, resolver_factory1->get_policy_calls);
- EXPECT_EQ(0u, resolver_factory2->get_policy_calls);
-}
-
-// Tests that when a conflict resolution factory disconnects:
-// - the next factory is used
-// - already open pages update their policy
-TEST_P(MergingIntegrationTest, ConflictResolutionFactoryFailover) {
- auto resolver_factory_waiter1 = NewWaiter();
- auto resolver_factory_waiter2 = NewWaiter();
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr1;
- auto resolver_factory1 = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::LAST_ONE_WINS, resolver_factory_ptr1.NewRequest(),
- resolver_factory_waiter1->GetCallback());
- ConflictResolverFactoryPtr resolver_factory_ptr2;
- auto resolver_factory2 = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::LAST_ONE_WINS, resolver_factory_ptr2.NewRequest(),
- resolver_factory_waiter2->GetCallback());
- LedgerPtr ledger_ptr = instance->GetTestLedger();
-
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr1),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page1 = instance->GetTestPage();
-
- // resolver_factory1 has received one request for page1
- ASSERT_TRUE(resolver_factory_waiter1->RunUntilCalled());
- EXPECT_EQ(1u, resolver_factory1->get_policy_calls);
-
- // Connect resolver_factory2 on ledger_ptr1. It does not receive requests
- waiter = NewWaiter();
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr2),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Disconnect resolver_factory1
- resolver_factory1->Disconnect();
- ASSERT_TRUE(resolver_factory_waiter2->RunUntilCalled());
- EXPECT_EQ(1u, resolver_factory2->get_policy_calls);
-
- PagePtr page2 = instance->GetTestPage();
- // resolver_factory2 has received one request for page2
- ASSERT_TRUE(resolver_factory_waiter2->RunUntilCalled());
- EXPECT_EQ(2u, resolver_factory2->get_policy_calls);
-}
-
-// Tests that when a conflict resolution factory disconnects, already
-// open pages still get their conflicts resolved
-TEST_P(MergingIntegrationTest,
- ConflictResolutionFactoryUnavailableMergingContinues) {
- auto resolver_factory_waiter = NewWaiter();
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::LAST_ONE_WINS, resolver_factory_ptr.NewRequest(),
- resolver_factory_waiter->GetCallback());
- LedgerPtr ledger_ptr = instance->GetTestLedger();
-
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PagePtr page_conn1 = instance->GetTestPage();
- PageId test_page_id;
- waiter = NewWaiter();
- page_conn1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page_conn2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- // wait for the conflict resolver to be set up, then disconnect
- ASSERT_TRUE(resolver_factory_waiter->RunUntilCalled());
- resolver_factory->Disconnect();
-
- PageWatcherPtr watcher1_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher1(watcher1_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot1;
- waiter = NewWaiter();
- page_conn1->GetSnapshot(snapshot1.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher1_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageWatcherPtr watcher2_ptr;
- Watcher watcher2(watcher2_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page_conn2->GetSnapshot(snapshot2.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher2_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page_conn1->StartTransaction(
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page_conn1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page_conn2->StartTransaction(
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page_conn2->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page_conn1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher1.changes_seen);
- PageChange change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(0).value));
-
- waiter = NewWaiter();
- page_conn2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher2.changes_seen);
- change = std::move(watcher2.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Bob", ToString(change.changed_entries.at(0).value));
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- PageSnapshotPtr snapshot3;
- waiter = NewWaiter();
- page_conn1->GetSnapshot(snapshot3.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(status, Status::OK);
-
- InlinedValuePtr val1;
- waiter = NewWaiter();
- snapshot3->GetInline(
- convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status, &val1));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(status, Status::OK);
-
- PageSnapshotPtr snapshot4;
- waiter = NewWaiter();
- page_conn1->GetSnapshot(snapshot4.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(status, Status::OK);
-
- InlinedValuePtr val2;
- waiter = NewWaiter();
- snapshot4->GetInline(
- convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status, &val2));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(status, Status::OK);
-
- EXPECT_EQ(convert::ToString(val1->value), convert::ToString(val2->value));
-}
-
-// Tests that pages opened after disconnection of a conflict resolver
-// factory do not see their conflict resolved, including if another connection
-// is present with no conflict resolution set
-TEST_P(MergingIntegrationTest,
- ConflictResolutionFactoryUnavailableNewPagesMergeBlocked) {
- auto resolver_factory_waiter = NewWaiter();
- auto instance = NewLedgerAppInstance();
- ConflictResolverFactoryPtr resolver_factory_ptr;
- auto resolver_factory = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::LAST_ONE_WINS, resolver_factory_ptr.NewRequest(),
- resolver_factory_waiter->GetCallback());
- LedgerPtr ledger_ptr = instance->GetTestLedger();
-
- // Open another connection to check that its (null) strategy is not used
- LedgerPtr ledger_ptr2 = instance->GetTestLedger();
-
- auto waiter = NewWaiter();
- Status status;
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- resolver_factory->Disconnect();
-
- PagePtr page_conn1 = instance->GetTestPage();
- PageId test_page_id;
- waiter = NewWaiter();
- page_conn1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- PagePtr page_conn2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- PageWatcherPtr watcher1_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher1(watcher1_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot1;
- waiter = NewWaiter();
- page_conn1->GetSnapshot(snapshot1.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher1_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageWatcherPtr watcher2_ptr;
- Watcher watcher2(watcher2_ptr.NewRequest(), watcher_waiter->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page_conn2->GetSnapshot(snapshot2.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher2_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page_conn1->StartTransaction(
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page_conn1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page_conn2->StartTransaction(
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page_conn2->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page_conn1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher1.changes_seen);
- PageChange change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(0).value));
-
- waiter = NewWaiter();
- page_conn2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher2.changes_seen);
- change = std::move(watcher2.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Bob", ToString(change.changed_entries.at(0).value));
-
- RunLoopFor(zx::sec(1));
- EXPECT_TRUE(watcher_waiter->NotCalledYet());
-
- waiter = NewWaiter();
- auto resolver_factory_waiter2 = NewWaiter();
- ConflictResolverFactoryPtr resolver_factory_ptr2;
- auto resolver_factory2 = std::make_unique<TestConflictResolverFactory>(
- this, MergePolicy::LAST_ONE_WINS, resolver_factory_ptr2.NewRequest(),
- resolver_factory_waiter2->GetCallback());
- ledger_ptr->SetConflictResolverFactory(
- std::move(resolver_factory_ptr2),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
-
- PageSnapshotPtr snapshot3;
- waiter = NewWaiter();
- page_conn1->GetSnapshot(snapshot3.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(status, Status::OK);
-
- InlinedValuePtr val1;
- waiter = NewWaiter();
- snapshot3->GetInline(
- convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status, &val1));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(status, Status::OK);
-
- PageSnapshotPtr snapshot4;
- waiter = NewWaiter();
- page_conn1->GetSnapshot(snapshot4.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(status, Status::OK);
-
- InlinedValuePtr val2;
- waiter = NewWaiter();
- snapshot4->GetInline(
- convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status, &val2));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(status, Status::OK);
-
- EXPECT_EQ(convert::ToString(val1->value), convert::ToString(val2->value));
-}
-
-INSTANTIATE_TEST_CASE_P(
- MergingIntegrationTest, MergingIntegrationTest,
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders()));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/page_mutation_tests.cc b/bin/ledger/tests/integration/page_mutation_tests.cc
deleted file mode 100644
index 5840009..0000000
--- a/bin/ledger/tests/integration/page_mutation_tests.cc
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/callback/waiter.h>
-
-#include "peridot/bin/ledger/testing/ledger_matcher.h"
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-
-using testing::IsEmpty;
-
-namespace ledger {
-namespace {
-
-// Tests in this suite execute a series of operations and check the content of
-// the Page afterwards.
-class PageMutationTest : public IntegrationTest {
- public:
- void SetUp() override {
- IntegrationTest::SetUp();
- app_instance_ = NewLedgerAppInstance();
- page_ = app_instance_->GetTestPage();
- }
-
- PageSnapshotPtr PageGetSnapshot() {
- Status status;
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- page_->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- nullptr,
- callback::Capture(waiter->GetCallback(), &status));
- if (!waiter->RunUntilCalled()) {
- ADD_FAILURE() << "|GetSnapshot| failed to called back.";
- return nullptr;
- }
- EXPECT_EQ(Status::OK, status);
- return snapshot;
- }
-
- std::vector<Entry> GetEntries() {
- PageSnapshotPtr snapshot = PageGetSnapshot();
- return SnapshotGetEntries(this, &snapshot);
- }
-
- testing::AssertionResult Put(std::string key, std::string value) {
- return Do("Put", [&](auto callback) {
- page_->Put(convert::ToArray(key), convert::ToArray(value),
- std::move(callback));
- });
- }
-
- testing::AssertionResult Delete(std::string key) {
- return Do("Delete", [&](auto callback) {
- page_->Delete(convert::ToArray(key), std::move(callback));
- });
- }
-
- testing::AssertionResult Clear() {
- return Do("Clear",
- [&](auto callback) { page_->Clear(std::move(callback)); });
- }
-
- testing::AssertionResult StartTransaction() {
- return Do("StartTransaction", [&](auto callback) {
- page_->StartTransaction(std::move(callback));
- });
- }
-
- testing::AssertionResult Commit() {
- return Do("Commit",
- [&](auto callback) { page_->Commit(std::move(callback)); });
- }
-
- testing::AssertionResult Rollback() {
- return Do("Rollback",
- [&](auto callback) { page_->Rollback(std::move(callback)); });
- }
-
- private:
- // Executes the given action on the current page.
- //
- // This helper function handles the heavy lifting of calling an operation of
- // the page, waiting for the result and returning an assertion error in case
- // of non ok status. It expects |action| to operate the operation on the page
- // and returns the status in its callback.
- testing::AssertionResult Do(
- std::string operation_name,
- fit::function<void(fit::function<void(Status)>)> action) {
- Status status;
- auto waiter = NewWaiter();
- action(callback::Capture(waiter->GetCallback(), &status));
- if (!waiter->RunUntilCalled()) {
- return testing::AssertionFailure()
- << "Error while executing " << operation_name
- << ". |action| failed to call back.";
- }
- if (status == Status::OK) {
- return testing::AssertionSuccess();
- }
- return testing::AssertionFailure()
- << "Error while executing " << operation_name
- << ". Status: " << static_cast<uint32_t>(status);
- }
-
- protected:
- std::unique_ptr<LedgerAppInstanceFactory::LedgerAppInstance> app_instance_;
- PagePtr page_;
-};
-
-TEST_P(PageMutationTest, InitialSnapshotIsEmpty) {
- EXPECT_THAT(GetEntries(), IsEmpty());
-}
-
-TEST_P(PageMutationTest, PutOutsideOfTransaction) {
- ASSERT_TRUE(Put("key", "value"));
-
- ASSERT_THAT(GetEntries(), MatchEntries({{"key", "value"}}));
-
- ASSERT_TRUE(Put("key2", "value2"));
-
- ASSERT_THAT(GetEntries(),
- MatchEntries({{"key", "value"}, {"key2", "value2"}}));
-}
-
-TEST_P(PageMutationTest, PutInsideOfTransaction) {
- ASSERT_TRUE(StartTransaction());
- ASSERT_TRUE(Put("key", "value"));
-
- ASSERT_THAT(GetEntries(), IsEmpty());
-
- ASSERT_TRUE(Put("key2", "value2"));
- ASSERT_TRUE(Commit());
-
- ASSERT_THAT(GetEntries(),
- MatchEntries({{"key", "value"}, {"key2", "value2"}}));
-}
-
-TEST_P(PageMutationTest, RollbackTransaction) {
- ASSERT_TRUE(StartTransaction());
- ASSERT_TRUE(Put("key", "value"));
-
- ASSERT_THAT(GetEntries(), IsEmpty());
-
- ASSERT_TRUE(Put("key2", "value2"));
- ASSERT_TRUE(Rollback());
-
- ASSERT_THAT(GetEntries(), IsEmpty());
-}
-
-TEST_P(PageMutationTest, DeleteOutsideOfTransaction) {
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_TRUE(Put("key2", "value2"));
- ASSERT_THAT(GetEntries(),
- MatchEntries({{"key", "value"}, {"key2", "value2"}}));
-
- ASSERT_TRUE(Delete("key"));
-
- ASSERT_THAT(GetEntries(), MatchEntries({{"key2", "value2"}}));
-}
-
-TEST_P(PageMutationTest, DeleteInsideOfTransaction) {
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_TRUE(Put("key2", "value2"));
- ASSERT_THAT(GetEntries(),
- MatchEntries({{"key", "value"}, {"key2", "value2"}}));
-
- ASSERT_TRUE(StartTransaction());
- ASSERT_TRUE(Delete("key"));
- ASSERT_TRUE(Put("key3", "value3"));
- ASSERT_TRUE(Delete("key3"));
- ASSERT_TRUE(Commit());
-
- ASSERT_THAT(GetEntries(), MatchEntries({{"key2", "value2"}}));
-}
-
-TEST_P(PageMutationTest, ClearOutsideOfTransaction) {
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_TRUE(Put("key2", "value2"));
- ASSERT_THAT(GetEntries(),
- MatchEntries({{"key", "value"}, {"key2", "value2"}}));
-
- ASSERT_TRUE(Clear());
-
- ASSERT_THAT(GetEntries(), IsEmpty());
-}
-
-TEST_P(PageMutationTest, ClearInsideOfTransaction) {
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_TRUE(Put("key2", "value2"));
- ASSERT_THAT(GetEntries(),
- MatchEntries({{"key", "value"}, {"key2", "value2"}}));
-
- ASSERT_TRUE(StartTransaction());
- ASSERT_TRUE(Put("key3", "value3"));
- ASSERT_TRUE(Clear());
- ASSERT_TRUE(Put("key4", "value4"));
- ASSERT_TRUE(Commit());
-
- ASSERT_THAT(GetEntries(), MatchEntries({{"key4", "value4"}}));
-}
-
-TEST_P(PageMutationTest, MultipleClearCallsInsideOfTransaction) {
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_TRUE(Put("key2", "value2"));
- ASSERT_THAT(GetEntries(),
- MatchEntries({{"key", "value"}, {"key2", "value2"}}));
-
- ASSERT_TRUE(StartTransaction());
- ASSERT_TRUE(Put("key3", "value3"));
- ASSERT_TRUE(Clear());
- ASSERT_TRUE(Put("key4", "value4"));
- ASSERT_TRUE(Clear());
- ASSERT_TRUE(Put("key5", "value5"));
- ASSERT_TRUE(Commit());
-
- ASSERT_THAT(GetEntries(), MatchEntries({{"key5", "value5"}}));
-}
-
-TEST_P(PageMutationTest, ClearAndDeleteInsideOfTransaction) {
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_THAT(GetEntries(), MatchEntries({{"key", "value"}}));
-
- ASSERT_TRUE(StartTransaction());
- ASSERT_TRUE(Clear());
- ASSERT_TRUE(Delete("key"));
- ASSERT_TRUE(Commit());
-
- ASSERT_THAT(GetEntries(), IsEmpty());
-}
-
-TEST_P(PageMutationTest, DeleteAndClearInsideOfTransaction) {
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_THAT(GetEntries(), MatchEntries({{"key", "value"}}));
-
- ASSERT_TRUE(StartTransaction());
- ASSERT_TRUE(Delete("key"));
- ASSERT_TRUE(Clear());
- ASSERT_TRUE(Commit());
-
- ASSERT_THAT(GetEntries(), IsEmpty());
-}
-
-TEST_P(PageMutationTest, ClearAndRestoreInsideTransaction) {
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_THAT(GetEntries(), MatchEntries({{"key", "value"}}));
-
- ASSERT_TRUE(StartTransaction());
- ASSERT_TRUE(Clear());
- ASSERT_TRUE(Put("key", "value"));
- ASSERT_TRUE(Commit());
-
- ASSERT_THAT(GetEntries(), MatchEntries({{"key", "value"}}));
-}
-
-INSTANTIATE_TEST_CASE_P(
- PageMutationTest, PageMutationTest,
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders()));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/page_snapshot_tests.cc b/bin/ledger/tests/integration/page_snapshot_tests.cc
deleted file mode 100644
index 3f3fdbb..0000000
--- a/bin/ledger/tests/integration/page_snapshot_tests.cc
+++ /dev/null
@@ -1,751 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <utility>
-#include <vector>
-
-#include <lib/callback/capture.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-#include "garnet/public/lib/callback/capture.h"
-#include "garnet/public/lib/callback/waiter.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-class PageSnapshotIntegrationTest : public IntegrationTest {
- public:
- PageSnapshotIntegrationTest() {}
- ~PageSnapshotIntegrationTest() override {}
-
- // Returns a snapshot of |page|, checking success.
- PageSnapshotPtr PageGetSnapshot(
- PagePtr* page,
- fidl::VectorPtr<uint8_t> prefix = fidl::VectorPtr<uint8_t>::New(0)) {
- Status status;
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- (*page)->GetSnapshot(snapshot.NewRequest(), std::move(prefix), nullptr,
- callback::Capture(waiter->GetCallback(), &status));
- if (!waiter->RunUntilCalled()) {
- ADD_FAILURE() << "|GetSnapshot| failed to call back.";
- return nullptr;
- }
- EXPECT_EQ(Status::OK, status);
- return snapshot;
- }
-
- // Returns all keys from |snapshot|, starting at |start|. If |num_queries| is
- // not null, stores the number of calls to GetKeys.
- std::vector<std::vector<uint8_t>> SnapshotGetKeys(
- PageSnapshotPtr* snapshot,
- std::vector<uint8_t> start = std::vector<uint8_t>(),
- int* num_queries = nullptr) {
- std::vector<std::vector<uint8_t>> result;
- std::unique_ptr<Token> token;
- if (num_queries) {
- *num_queries = 0;
- }
- do {
- Status status;
- std::vector<std::vector<uint8_t>> keys;
- auto waiter = NewWaiter();
- (*snapshot)->GetKeys(
- start, std::move(token),
- callback::Capture(waiter->GetCallback(), &status, &keys, &token));
- if (!waiter->RunUntilCalled()) {
- ADD_FAILURE() << "|GetKeys| failed to call back.";
- return {};
- }
- EXPECT_TRUE(status == Status::OK || status == Status::PARTIAL_RESULT);
- if (num_queries) {
- (*num_queries)++;
- }
- for (auto& key : keys) {
- result.push_back(std::move(key));
- }
- } while (token);
- return result;
- }
-
- std::string SnapshotFetchPartial(PageSnapshotPtr* snapshot,
- std::vector<uint8_t> key, int64_t offset,
- int64_t max_size) {
- Status status;
- fuchsia::mem::BufferPtr buffer;
- auto waiter = NewWaiter();
- (*snapshot)->FetchPartial(
- std::move(key), offset, max_size,
- callback::Capture(waiter->GetCallback(), &status, &buffer));
- if (!waiter->RunUntilCalled()) {
- ADD_FAILURE() << "|FetchPartial| failed to call back.";
- return {};
- }
- EXPECT_EQ(Status::OK, status);
- std::string result;
- EXPECT_TRUE(fsl::StringFromVmo(*buffer, &result));
- return result;
- }
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageSnapshotIntegrationTest);
-};
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotGet) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- Status status;
- auto waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- fuchsia::mem::BufferPtr value;
- waiter = NewWaiter();
- snapshot->Get(convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ("Alice", ToString(value));
-
- // Attempt to get an entry that is not in the page.
- waiter = NewWaiter();
- snapshot->Get(convert::ToArray("favorite book"),
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
- // People don't read much these days.
- EXPECT_EQ(Status::KEY_NOT_FOUND, status);
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotGetPipeline) {
- auto instance = NewLedgerAppInstance();
- std::string expected_value = "Alice";
- expected_value.resize(100);
-
- auto status_waiter =
- fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
-
- PagePtr page = instance->GetTestPage();
- page->Put(convert::ToArray("name"), convert::ToArray(expected_value),
- status_waiter->NewCallback());
-
- PageSnapshotPtr snapshot;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- nullptr, status_waiter->NewCallback());
-
- Status status;
- fuchsia::mem::BufferPtr value;
- snapshot->Get(convert::ToArray("name"),
- [&value, status_callback = status_waiter->NewCallback()](
- Status status, fuchsia::mem::BufferPtr received_value) {
- value = std::move(received_value);
- status_callback(status);
- });
- auto waiter = NewWaiter();
- status_waiter->Finalize(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- ASSERT_TRUE(value);
- EXPECT_EQ(expected_value, ToString(value));
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotPutOrder) {
- auto instance = NewLedgerAppInstance();
- std::string value1 = "Alice";
- value1.resize(100);
- std::string value2;
-
- // Put the 2 values without waiting for the callbacks.
- PagePtr page = instance->GetTestPage();
- auto status_waiter =
- fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- page->Put(convert::ToArray("name"), convert::ToArray(value1),
- status_waiter->NewCallback());
- page->Put(convert::ToArray("name"), convert::ToArray(value2),
- status_waiter->NewCallback());
- Status status;
- auto waiter = NewWaiter();
- status_waiter->Finalize(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- fuchsia::mem::BufferPtr value;
- waiter = NewWaiter();
- snapshot->Get(convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(value2, ToString(value));
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotFetchPartial) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- Status status;
- auto waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- EXPECT_EQ("Alice",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), 0, -1));
- EXPECT_EQ("e",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), 4, -1));
- EXPECT_EQ("",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), 5, -1));
- EXPECT_EQ("",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), 6, -1));
- EXPECT_EQ("i",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), 2, 1));
- EXPECT_EQ("",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), 2, 0));
-
- // Negative offsets.
- EXPECT_EQ("Alice",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), -5, -1));
- EXPECT_EQ("e",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), -1, -1));
- EXPECT_EQ("",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), -5, 0));
- EXPECT_EQ("i",
- SnapshotFetchPartial(&snapshot, convert::ToArray("name"), -3, 1));
-
- // Attempt to get an entry that is not in the page.
- fuchsia::mem::BufferPtr value;
- waiter = NewWaiter();
- snapshot->FetchPartial(
- convert::ToArray("favorite book"), 0, -1,
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
- // People don't read much these days.
- EXPECT_EQ(Status::KEY_NOT_FOUND, status);
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotGetKeys) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
-
- // Grab a snapshot before adding any entries and verify that GetKeys()
- // returns empty results.
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- std::vector<std::vector<uint8_t>> result = SnapshotGetKeys(&snapshot);
- EXPECT_EQ(0u, result.size());
-
- // Add entries and grab a new snapshot.
- const size_t N = 4;
- std::vector<uint8_t> keys[N] = {
- RandomArray(GetRandom(), 20, {0, 0, 0}),
- RandomArray(GetRandom(), 20, {0, 0, 1}),
- RandomArray(GetRandom(), 20, {0, 1, 0}),
- RandomArray(GetRandom(), 20, {0, 1, 1}),
- };
- Status status;
- for (auto& key : keys) {
- auto waiter = NewWaiter();
- page->Put(key, RandomArray(GetRandom(), 50),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
- snapshot = PageGetSnapshot(&page);
-
- // Get all keys.
- result = SnapshotGetKeys(&snapshot);
- EXPECT_EQ(N, result.size());
- for (size_t i = 0; i < N; ++i) {
- EXPECT_EQ(keys[i], result.at(i));
- }
-
- // Get keys matching the prefix "0".
- snapshot =
- PageGetSnapshot(&page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{0}));
- result = SnapshotGetKeys(&snapshot);
- EXPECT_EQ(N, result.size());
- for (size_t i = 0; i < N; ++i) {
- EXPECT_EQ(keys[i], result.at(i));
- }
-
- // Get keys matching the prefix "00".
- snapshot = PageGetSnapshot(
- &page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{0, 0}));
- result = SnapshotGetKeys(&snapshot);
- ASSERT_EQ(2u, result.size());
- for (size_t i = 0; i < 2u; ++i) {
- EXPECT_EQ(keys[i], result.at(i));
- }
-
- // Get keys matching the prefix "010".
- snapshot = PageGetSnapshot(
- &page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{0, 1, 0}));
- result = SnapshotGetKeys(&snapshot);
- ASSERT_EQ(1u, result.size());
- EXPECT_EQ(keys[2], result.at(0));
-
- // Get keys matching the prefix "5".
- snapshot =
- PageGetSnapshot(&page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{5}));
- result = SnapshotGetKeys(&snapshot);
- EXPECT_EQ(0u, result.size());
-
- // Get keys matching the prefix "0" and starting with the key "010".
- snapshot =
- PageGetSnapshot(&page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{0}));
- result = SnapshotGetKeys(
- &snapshot, std::vector<uint8_t>(std::vector<uint8_t>{0, 1, 0}));
- EXPECT_EQ(2u, result.size());
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotGetKeysMultiPart) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
-
- // Grab a snapshot before adding any entries and verify that GetKeys()
- // returns empty results.
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- int num_queries;
- std::vector<std::vector<uint8_t>> result = SnapshotGetKeys(
- &snapshot, std::vector<uint8_t>(), &num_queries);
- EXPECT_EQ(0u, result.size());
- EXPECT_EQ(1, num_queries);
-
- // Add entries and grab a new snapshot.
- // Add enough keys so they don't all fit in memory and we will have to have
- // multiple queries.
- const size_t key_size = kMaxKeySize;
- const size_t N = fidl_serialization::kMaxInlineDataSize / key_size + 1;
- std::vector<uint8_t> keys[N];
- for (size_t i = 0; i < N; ++i) {
- // Generate keys so that they are in increasing order to match the order
- // of results from GetKeys().
- keys[i] = RandomArray(
- GetRandom(), key_size,
- {static_cast<uint8_t>(i >> 8), static_cast<uint8_t>(i & 0xFF)});
- }
-
- Status status;
- for (auto& key : keys) {
- auto waiter = NewWaiter();
- page->Put(key, RandomArray(GetRandom(), 10),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
- snapshot = PageGetSnapshot(&page);
-
- // Get all keys.
- result = SnapshotGetKeys(&snapshot, fidl::VectorPtr<uint8_t>::New(0),
- &num_queries);
- EXPECT_TRUE(num_queries > 1);
- ASSERT_EQ(N, result.size());
- for (size_t i = 0; i < N; ++i) {
- EXPECT_EQ(keys[i], result.at(i));
- }
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotGetEntries) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
-
- // Grab a snapshot before adding any entries and verify that GetEntries()
- // returns empty results.
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- auto entries = SnapshotGetEntries(this, &snapshot);
- EXPECT_EQ(0u, entries.size());
-
- // Add entries and grab a new snapshot.
- const size_t N = 4;
- std::vector<uint8_t> keys[N] = {
- RandomArray(GetRandom(), 20, {0, 0, 0}),
- RandomArray(GetRandom(), 20, {0, 0, 1}),
- RandomArray(GetRandom(), 20, {0, 1, 0}),
- RandomArray(GetRandom(), 20, {0, 1, 1}),
- };
- std::vector<uint8_t> values[N] = {
- RandomArray(GetRandom(), 50),
- RandomArray(GetRandom(), 50),
- RandomArray(GetRandom(), 50),
- RandomArray(GetRandom(), 50),
- };
- Status status;
- for (size_t i = 0; i < N; ++i) {
- auto waiter = NewWaiter();
- page->Put(keys[i], values[i],
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
- snapshot = PageGetSnapshot(&page);
-
- // Get all entries.
- entries = SnapshotGetEntries(this, &snapshot);
- EXPECT_EQ(N, entries.size());
- for (size_t i = 0; i < N; ++i) {
- EXPECT_EQ(keys[i], entries.at(i).key);
- EXPECT_EQ(values[i], ToArray(entries.at(i).value));
- }
-
- // Get entries matching the prefix "0".
- snapshot =
- PageGetSnapshot(&page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{0}));
- entries = SnapshotGetEntries(this, &snapshot);
- EXPECT_EQ(N, entries.size());
- for (size_t i = 0; i < N; ++i) {
- EXPECT_EQ(keys[i], entries.at(i).key);
- EXPECT_EQ(values[i], ToArray(entries.at(i).value));
- }
-
- // Get entries matching the prefix "00".
- snapshot = PageGetSnapshot(
- &page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{0, 0}));
- entries = SnapshotGetEntries(this, &snapshot);
- ASSERT_EQ(2u, entries.size());
- for (size_t i = 0; i < 2; ++i) {
- EXPECT_EQ(keys[i], entries.at(i).key);
- EXPECT_EQ(values[i], ToArray(entries.at(i).value));
- }
-
- // Get keys matching the prefix "010".
- snapshot = PageGetSnapshot(
- &page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{0, 1, 0}));
- entries = SnapshotGetEntries(this, &snapshot);
- ASSERT_EQ(1u, entries.size());
- EXPECT_EQ(keys[2], entries.at(0).key);
- EXPECT_EQ(values[2], ToArray(entries.at(0).value));
-
- // Get keys matching the prefix "5".
- snapshot =
- PageGetSnapshot(&page, fidl::VectorPtr<uint8_t>(std::vector<uint8_t>{5}));
-
- entries = SnapshotGetEntries(this, &snapshot);
- EXPECT_EQ(0u, entries.size());
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotGetEntriesMultiPartSize) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
-
- // Grab a snapshot before adding any entries and verify that GetEntries()
- // returns empty results.
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- int num_queries;
- auto entries = SnapshotGetEntries(
- this, &snapshot, fidl::VectorPtr<uint8_t>::New(0), &num_queries);
- EXPECT_EQ(0u, entries.size());
- EXPECT_EQ(1, num_queries);
-
- // Add entries and grab a new snapshot.
- // Add enough keys so they don't all fit in memory and we will have to have
- // multiple queries.
- const size_t value_size = 100;
- const size_t key_size = kMaxKeySize;
- const size_t N =
- fidl_serialization::kMaxInlineDataSize / (key_size + value_size) + 1;
- std::vector<uint8_t> keys[N];
- std::vector<uint8_t> values[N];
- for (size_t i = 0; i < N; ++i) {
- // Generate keys so that they are in increasing order to match the order
- // of results from GetEntries().
- keys[i] = RandomArray(
- GetRandom(), key_size,
- {static_cast<uint8_t>(i >> 8), static_cast<uint8_t>(i & 0xFF)});
- values[i] = RandomArray(GetRandom(), value_size);
- }
-
- Status status;
- for (size_t i = 0; i < N; ++i) {
- auto waiter = NewWaiter();
- page->Put(keys[i], values[i],
- callback::Capture(waiter->GetCallback(), &status));
-
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- EXPECT_EQ(Status::OK, status);
- }
- snapshot = PageGetSnapshot(&page);
-
- // Get all entries.
- entries = SnapshotGetEntries(this, &snapshot,
- fidl::VectorPtr<uint8_t>::New(0), &num_queries);
- EXPECT_TRUE(num_queries > 1);
- ASSERT_EQ(N, entries.size());
- for (size_t i = 0; i < N; ++i) {
- EXPECT_EQ(keys[i], entries[i].key);
- EXPECT_EQ(values[i], ToArray(entries[i].value));
- }
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotGetEntriesMultiPartHandles) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
-
- // Grab a snapshot before adding any entries and verify that GetEntries()
- // returns empty results.
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- int num_queries;
- auto entries = SnapshotGetEntries(
- this, &snapshot, fidl::VectorPtr<uint8_t>::New(0), &num_queries);
- EXPECT_EQ(0u, entries.size());
- EXPECT_EQ(1, num_queries);
-
- // Add entries and grab a new snapshot.
- const size_t N = 100;
- std::vector<uint8_t> keys[N];
- std::vector<uint8_t> values[N];
- for (size_t i = 0; i < N; ++i) {
- // Generate keys so that they are in increasing order to match the order
- // of results from GetEntries().
- keys[i] = RandomArray(
- GetRandom(), 20,
- {static_cast<uint8_t>(i >> 8), static_cast<uint8_t>(i & 0xFF)});
- values[i] = RandomArray(GetRandom(), 100);
- }
-
- for (size_t i = 0; i < N; ++i) {
- Status status;
- auto waiter = NewWaiter();
- page->Put(keys[i], values[i],
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
- snapshot = PageGetSnapshot(&page);
-
- // Get all entries.
- entries = SnapshotGetEntries(this, &snapshot,
- fidl::VectorPtr<uint8_t>::New(0), &num_queries);
- EXPECT_TRUE(num_queries > 1);
- ASSERT_EQ(N, entries.size());
- for (size_t i = 0; i < N; ++i) {
- EXPECT_EQ(keys[i], entries[i].key);
- EXPECT_EQ(values[i], ToArray(entries[i].value));
- }
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotGettersReturnSortedEntries) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
-
- const size_t N = 4;
- std::vector<uint8_t> keys[N] = {
- RandomArray(GetRandom(), 20, {2}),
- RandomArray(GetRandom(), 20, {5}),
- RandomArray(GetRandom(), 20, {3}),
- RandomArray(GetRandom(), 20, {0}),
- };
- std::vector<uint8_t> values[N] = {
- RandomArray(GetRandom(), 20),
- RandomArray(GetRandom(), 20),
- RandomArray(GetRandom(), 20),
- RandomArray(GetRandom(), 20),
- };
- for (size_t i = 0; i < N; ++i) {
- Status status;
- auto waiter = NewWaiter();
- page->Put(keys[i], values[i],
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
-
- // Get a snapshot.
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
-
- // Verify that GetKeys() results are sorted.
- std::vector<std::vector<uint8_t>> result = SnapshotGetKeys(&snapshot);
- EXPECT_EQ(keys[3], result.at(0));
- EXPECT_EQ(keys[0], result.at(1));
- EXPECT_EQ(keys[2], result.at(2));
- EXPECT_EQ(keys[1], result.at(3));
-
- // Verify that GetEntries() results are sorted.
- auto entries = SnapshotGetEntries(this, &snapshot);
- EXPECT_EQ(keys[3], entries[0].key);
- EXPECT_EQ(values[3], ToArray(entries[0].value));
- EXPECT_EQ(keys[0], entries[1].key);
- EXPECT_EQ(values[0], ToArray(entries[1].value));
- EXPECT_EQ(keys[2], entries[2].key);
- EXPECT_EQ(values[2], ToArray(entries[2].value));
- EXPECT_EQ(keys[1], entries[3].key);
- EXPECT_EQ(values[1], ToArray(entries[3].value));
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageCreateReferenceFromSocketWrongSize) {
- auto instance = NewLedgerAppInstance();
- const std::string big_data(1'000'000, 'a');
-
- PagePtr page = instance->GetTestPage();
-
- Status status;
- ReferencePtr reference;
- auto waiter = NewWaiter();
- page->CreateReferenceFromSocket(
- 123, StreamDataToSocket(big_data),
- callback::Capture(waiter->GetCallback(), &status, &reference));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::IO_ERROR, status);
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageCreatePutLargeReferenceFromSocket) {
- auto instance = NewLedgerAppInstance();
- const std::string big_data(1'000'000, 'a');
-
- PagePtr page = instance->GetTestPage();
-
- // Stream the data into the reference.
- Status status;
- ReferencePtr reference;
- auto waiter = NewWaiter();
- page->CreateReferenceFromSocket(
- big_data.size(), StreamDataToSocket(big_data),
- callback::Capture(waiter->GetCallback(), &status, &reference));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Set the reference under a key.
- waiter = NewWaiter();
- page->PutReference(convert::ToArray("big data"), std::move(*reference),
- Priority::EAGER,
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Get a snapshot and read the value.
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- fuchsia::mem::BufferPtr value;
- waiter = NewWaiter();
- snapshot->Get(convert::ToArray("big data"),
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(big_data, ToString(value));
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageCreatePutLargeReferenceFromVmo) {
- auto instance = NewLedgerAppInstance();
- const std::string big_data(1'000'000, 'a');
- fsl::SizedVmo vmo;
- ASSERT_TRUE(fsl::VmoFromString(big_data, &vmo));
-
- PagePtr page = instance->GetTestPage();
-
- // Stream the data into the reference.
- Status status;
- ReferencePtr reference;
- auto waiter = NewWaiter();
- page->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- callback::Capture(waiter->GetCallback(), &status, &reference));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Set the reference under a key.
- waiter = NewWaiter();
- page->PutReference(convert::ToArray("big data"), std::move(*reference),
- Priority::EAGER,
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Get a snapshot and read the value.
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- fuchsia::mem::BufferPtr value;
- waiter = NewWaiter();
- snapshot->Get(convert::ToArray("big data"),
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ(big_data, ToString(value));
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageSnapshotClosePageGet) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- Status status;
- auto waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
-
- // Close the channel. PageSnapshotPtr should remain valid.
- page.Unbind();
-
- fuchsia::mem::BufferPtr value;
- waiter = NewWaiter();
- snapshot->Get(convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ("Alice", ToString(value));
-
- // Attempt to get an entry that is not in the page.
- waiter = NewWaiter();
- snapshot->Get(convert::ToArray("favorite book"),
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
- // People don't read much these days.
- EXPECT_EQ(Status::KEY_NOT_FOUND, status);
-}
-
-TEST_P(PageSnapshotIntegrationTest, PageGetById) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageId test_page_id;
- auto waiter = NewWaiter();
- page->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- Status status;
- waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- page.Unbind();
-
- page = instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
- PageId page_id;
- waiter = NewWaiter();
- page->GetId(callback::Capture(waiter->GetCallback(), &page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(test_page_id.id, page_id.id);
-
- PageSnapshotPtr snapshot = PageGetSnapshot(&page);
- fuchsia::mem::BufferPtr value;
- waiter = NewWaiter();
- snapshot->Get(convert::ToArray("name"),
- callback::Capture(waiter->GetCallback(), &status, &value));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ("Alice", ToString(value));
-}
-
-INSTANTIATE_TEST_CASE_P(
- PageSnapshotIntegrationTest, PageSnapshotIntegrationTest,
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders()));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/page_tests.cc b/bin/ledger/tests/integration/page_tests.cc
deleted file mode 100644
index a9623dc..0000000
--- a/bin/ledger/tests/integration/page_tests.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <utility>
-#include <vector>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/callback/capture.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/macros.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-class PageIntegrationTest : public IntegrationTest {
- public:
- PageIntegrationTest() {}
- ~PageIntegrationTest() override {}
-
- // Returns the id of the given page.
- PageId PageGetId(PagePtr* page) {
- PageId id;
- auto loop_waiter = NewWaiter();
- (*page)->GetId(callback::Capture(loop_waiter->GetCallback(), &id));
- EXPECT_TRUE(loop_waiter->RunUntilCalled());
- return id;
- }
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageIntegrationTest);
-};
-
-TEST_P(PageIntegrationTest, LedgerRepositoryDuplicate) {
- auto instance = NewLedgerAppInstance();
-
- ledger_internal::LedgerRepositoryPtr repository =
- instance->GetTestLedgerRepository();
-
- ledger_internal::LedgerRepositoryPtr duplicated_repository;
- repository->Duplicate(duplicated_repository.NewRequest());
- auto loop_waiter = NewWaiter();
- duplicated_repository->Sync(loop_waiter->GetCallback());
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
-}
-
-TEST_P(PageIntegrationTest, GetLedger) {
- auto instance = NewLedgerAppInstance();
- EXPECT_TRUE(instance->GetTestLedger());
-}
-
-TEST_P(PageIntegrationTest, GetRootPage) {
- auto instance = NewLedgerAppInstance();
- LedgerPtr ledger = instance->GetTestLedger();
- Status status;
- PagePtr page;
- auto loop_waiter = NewWaiter();
- ledger->GetRootPage(page.NewRequest(),
- callback::Capture(loop_waiter->GetCallback(), &status));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-}
-
-TEST_P(PageIntegrationTest, NewPage) {
- auto instance = NewLedgerAppInstance();
- // Get two pages and check that their ids are different.
- PagePtr page1 = instance->GetTestPage();
- PageId id1 = PageGetId(&page1);
- PagePtr page2 = instance->GetTestPage();
- PageId id2 = PageGetId(&page2);
-
- EXPECT_TRUE(id1.id != id2.id);
-}
-
-TEST_P(PageIntegrationTest, GetPage) {
- auto instance = NewLedgerAppInstance();
- // Create a page and expect to find it by its id.
- PagePtr page = instance->GetTestPage();
- PageId id = PageGetId(&page);
- instance->GetPage(fidl::MakeOptional(id), Status::OK);
-}
-
-// Verifies that a page can be connected to twice.
-TEST_P(PageIntegrationTest, MultiplePageConnections) {
- auto instance = NewLedgerAppInstance();
- // Create a new page and find its id.
- PagePtr page1 = instance->GetTestPage();
- PageId page_id_1 = PageGetId(&page1);
-
- // Connect to the same page again.
- PagePtr page2 = instance->GetPage(fidl::MakeOptional(page_id_1), Status::OK);
- PageId page_id_2 = PageGetId(&page2);
- EXPECT_EQ(page_id_1.id, page_id_2.id);
-}
-
-INSTANTIATE_TEST_CASE_P(
- PageIntegrationTest, PageIntegrationTest,
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders()));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/page_watcher_tests.cc b/bin/ledger/tests/integration/page_watcher_tests.cc
deleted file mode 100644
index f7955da..0000000
--- a/bin/ledger/tests/integration/page_watcher_tests.cc
+++ /dev/null
@@ -1,860 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <utility>
-#include <vector>
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/callback/capture.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "garnet/public/lib/callback/capture.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/app/constants.h"
-#include "peridot/bin/ledger/app/fidl/serialization_size.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-using ::testing::SizeIs;
-
-class PageWatcherIntegrationTest : public IntegrationTest {
- public:
- PageWatcherIntegrationTest() {}
- ~PageWatcherIntegrationTest() override {}
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(PageWatcherIntegrationTest);
-};
-
-class Watcher : public PageWatcher {
- public:
- explicit Watcher(
- fidl::InterfaceRequest<PageWatcher> request,
- fit::closure change_callback = [] {})
- : binding_(this, std::move(request)),
- change_callback_(std::move(change_callback)) {}
-
- void DelayCallback(bool delay_callback) { delay_callback_ = delay_callback; }
-
- void CallOnChangeCallback() {
- FXL_CHECK(on_change_callback_);
- on_change_callback_(last_snapshot_.NewRequest());
- on_change_callback_ = nullptr;
- }
-
- uint changes_seen = 0;
- ResultState last_result_state_;
- PageSnapshotPtr last_snapshot_;
- PageChange last_page_change_;
-
- private:
- // PageWatcher:
- void OnChange(PageChange page_change, ResultState result_state,
- OnChangeCallback callback) override {
- changes_seen++;
- last_result_state_ = result_state;
- last_page_change_ = std::move(page_change);
- last_snapshot_.Unbind();
- FXL_CHECK(!on_change_callback_);
- on_change_callback_ = std::move(callback);
- if (!delay_callback_) {
- CallOnChangeCallback();
- }
- change_callback_();
- }
-
- fidl::Binding<PageWatcher> binding_;
- bool delay_callback_ = false;
- OnChangeCallback on_change_callback_;
- fit::closure change_callback_;
-};
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherSimple) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- Status status;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher.last_result_state_);
- PageChange change = std::move(watcher.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(0).value));
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherAggregatedNotifications) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- // Call Put and don't let the OnChange callback be called, yet.
- watcher.DelayCallback(true);
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- Status status;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- page->Put(convert::ToArray("key"), convert::ToArray("value1"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher.last_result_state_);
- auto changed_entries = std::move(watcher.last_page_change_.changed_entries);
- ASSERT_THAT(changed_entries, SizeIs(1));
- EXPECT_EQ("key", convert::ToString(changed_entries.at(0).key));
- EXPECT_EQ("value1", ToString(changed_entries.at(0).value));
-
- // Update the value of "key" initially to "value2" and then to "value3".
- page->Put(convert::ToArray("key"), convert::ToArray("value2"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- page->Put(convert::ToArray("key"), convert::ToArray("value3"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Since the previous OnChange callback hasn't been called yet, the next
- // notification should be blocked.
- ASSERT_FALSE(watcher_waiter->RunUntilCalled());
-
- // Call the OnChange callback and expect a new OnChange call.
- watcher.CallOnChangeCallback();
- watcher.DelayCallback(false);
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
-
- // Only the last value of "key" should be found in the changed entries set.
- EXPECT_EQ(2u, watcher.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher.last_result_state_);
- changed_entries = std::move(watcher.last_page_change_.changed_entries);
- ASSERT_THAT(changed_entries, SizeIs(1));
- EXPECT_EQ("key", convert::ToString(changed_entries.at(0).key));
- EXPECT_EQ("value3", ToString(changed_entries.at(0).value));
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherDisconnectClient) {
- auto instance = NewLedgerAppInstance();
- Status status;
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- auto watcher = std::make_unique<Watcher>(watcher_ptr.NewRequest(),
- watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Make a change on the page and verify that it was received.
- waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher->changes_seen);
-
- // Make another change and disconnect the watcher immediately.
- waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- watcher.reset();
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherDisconnectPage) {
- auto instance = NewLedgerAppInstance();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- {
- PagePtr page = instance->GetTestPage();
- PageSnapshotPtr snapshot;
- Status status;
- auto waiter = NewWaiter();
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Queue many put operations on the page.
- for (int i = 0; i < 1000; i++) {
- page->Put(convert::ToArray("name"), convert::ToArray(std::to_string(i)),
- [](Status status) { EXPECT_EQ(Status::OK, status); });
- }
- }
- // Page is out of scope now, but watcher is not. Verify that we don't crash
- // and a change notification is still delivered.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherDelete) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- auto waiter = NewWaiter();
- Status status;
- page->Put(convert::ToArray("foo"), convert::ToArray("bar"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- auto watcher_waiter = NewWaiter();
- PageWatcherPtr watcher_ptr;
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- waiter = NewWaiter();
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->Delete(convert::ToArray("foo"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- ASSERT_EQ(1u, watcher.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher.last_result_state_);
- PageChange change = std::move(watcher.last_page_change_);
- EXPECT_EQ(0u, change.changed_entries.size());
- ASSERT_EQ(1u, change.deleted_keys.size());
- EXPECT_EQ("foo", convert::ToString(change.deleted_keys.at(0)));
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherBigChangeSize) {
- auto instance = NewLedgerAppInstance();
- // Put enough entries to ensure we will need more than one query to retrieve
- // them. The number of entries that can be retrieved in one query is bound by
- // |kMaxMessageHandles| and by size of the fidl message (determined by
- // |kMaxInlineDataSize|), so we insert one entry more than that.
- const size_t key_size = kMaxKeySize;
- const size_t entry_size = fidl_serialization::GetEntrySize(key_size);
- const size_t entry_count =
- std::min(fidl_serialization::kMaxMessageHandles,
- fidl_serialization::kMaxInlineDataSize / entry_size) +
- 1;
- const auto key_generator = [](size_t i) {
- std::string prefix = fxl::StringPrintf("key%03" PRIuMAX, i);
- std::string filler(key_size - prefix.size(), 'k');
- return prefix + filler;
- };
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- Status status;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- for (size_t i = 0; i < entry_count; ++i) {
- waiter = NewWaiter();
- page->Put(convert::ToArray(key_generator(i)), convert::ToArray("value"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
-
- RunLoopFor(zx::msec(100));
- EXPECT_EQ(0u, watcher.changes_seen);
-
- waiter = NewWaiter();
- page->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Get the first OnChagne call.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
- EXPECT_EQ(watcher.last_result_state_, ResultState::PARTIAL_STARTED);
- PageChange change = std::move(watcher.last_page_change_);
- size_t initial_size = change.changed_entries.size();
- for (size_t i = 0; i < initial_size; ++i) {
- EXPECT_EQ(key_generator(i),
- convert::ToString(change.changed_entries.at(i).key));
- EXPECT_EQ("value", ToString(change.changed_entries.at(i).value));
- EXPECT_EQ(Priority::EAGER, change.changed_entries.at(i).priority);
- }
-
- // Get the second OnChagne call.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(2u, watcher.changes_seen);
- EXPECT_EQ(ResultState::PARTIAL_COMPLETED, watcher.last_result_state_);
- change = std::move(watcher.last_page_change_);
-
- ASSERT_EQ(entry_count, initial_size + change.changed_entries.size());
- for (size_t i = 0; i < change.changed_entries.size(); ++i) {
- EXPECT_EQ(key_generator(i + initial_size),
- convert::ToString(change.changed_entries.at(i).key));
- EXPECT_EQ("value", ToString(change.changed_entries.at(i).value));
- EXPECT_EQ(Priority::EAGER, change.changed_entries.at(i).priority);
- }
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherBigChangeHandles) {
- auto instance = NewLedgerAppInstance();
- size_t entry_count = 70;
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- Status status;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- for (size_t i = 0; i < entry_count; ++i) {
- waiter = NewWaiter();
- page->Put(convert::ToArray(fxl::StringPrintf("key%02" PRIuMAX, i)),
- convert::ToArray("value"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
-
- RunLoopFor(zx::msec(100));
- EXPECT_EQ(0u, watcher.changes_seen);
-
- waiter = NewWaiter();
- page->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Get the first OnChagne call.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
- EXPECT_EQ(watcher.last_result_state_, ResultState::PARTIAL_STARTED);
- PageChange change = std::move(watcher.last_page_change_);
- size_t initial_size = change.changed_entries.size();
- for (size_t i = 0; i < initial_size; ++i) {
- EXPECT_EQ(fxl::StringPrintf("key%02" PRIuMAX, i),
- convert::ToString(change.changed_entries.at(i).key));
- EXPECT_EQ("value", ToString(change.changed_entries.at(i).value));
- EXPECT_EQ(Priority::EAGER, change.changed_entries.at(i).priority);
- }
-
- // Get the second OnChagne call.
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(2u, watcher.changes_seen);
- EXPECT_EQ(ResultState::PARTIAL_COMPLETED, watcher.last_result_state_);
- change = std::move(watcher.last_page_change_);
-
- ASSERT_EQ(entry_count, initial_size + change.changed_entries.size());
- for (size_t i = 0; i < change.changed_entries.size(); ++i) {
- EXPECT_EQ(fxl::StringPrintf("key%02" PRIuMAX, i + initial_size),
- convert::ToString(change.changed_entries.at(i).key));
- EXPECT_EQ("value", ToString(change.changed_entries.at(i).value));
- EXPECT_EQ(Priority::EAGER, change.changed_entries.at(i).priority);
- }
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherSnapshot) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- Status status;
- auto waiter = NewWaiter();
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher.last_result_state_);
- auto entries = SnapshotGetEntries(this, &(watcher.last_snapshot_));
- ASSERT_EQ(1u, entries.size());
- EXPECT_EQ("name", convert::ToString(entries[0].key));
- EXPECT_EQ("Alice", ToString(entries[0].value));
- EXPECT_EQ(Priority::EAGER, entries[0].priority);
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherTransaction) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- Status status;
- auto waiter = NewWaiter();
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- RunLoopFor(zx::msec(100));
- EXPECT_EQ(0u, watcher.changes_seen);
-
- waiter = NewWaiter();
- page->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher.last_result_state_);
- PageChange change = std::move(watcher.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(0).value));
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherParallel) {
- auto instance = NewLedgerAppInstance();
- PagePtr page1 = instance->GetTestPage();
- auto waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- PageWatcherPtr watcher1_ptr;
- auto watcher_waiter1 = NewWaiter();
- Watcher watcher1(watcher1_ptr.NewRequest(), watcher_waiter1->GetCallback());
- PageSnapshotPtr snapshot1;
- Status status;
- waiter = NewWaiter();
- page1->GetSnapshot(snapshot1.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher1_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- PageWatcherPtr watcher2_ptr;
- auto watcher_waiter2 = NewWaiter();
- Watcher watcher2(watcher2_ptr.NewRequest(), watcher_waiter2->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page2->GetSnapshot(snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher2_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page2->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page2->Put(convert::ToArray("name"), convert::ToArray("Bob"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- // Verify that each change is seen by the right watcher.
- waiter = NewWaiter();
- page1->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter1->RunUntilCalled());
- EXPECT_EQ(1u, watcher1.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher1.last_result_state_);
- PageChange change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(0).value));
-
- waiter = NewWaiter();
- page2->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter2->RunUntilCalled());
- EXPECT_EQ(1u, watcher2.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher2.last_result_state_);
- change = std::move(watcher2.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Bob", ToString(change.changed_entries.at(0).value));
-
- RunLoopFor(zx::msec(100));
-
- // A merge happens now. Only the first watcher should see a change.
- ASSERT_TRUE(watcher_waiter1->RunUntilCalled());
- EXPECT_EQ(2u, watcher1.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher2.last_result_state_);
- EXPECT_EQ(1u, watcher2.changes_seen);
-
- change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Bob", ToString(change.changed_entries.at(0).value));
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherEmptyTransaction) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- Watcher watcher(watcher_ptr.NewRequest());
-
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- Status status;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- RunLoopFor(zx::msec(100));
- EXPECT_EQ(0u, watcher.changes_seen);
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcher1Change2Pages) {
- auto instance = NewLedgerAppInstance();
- PagePtr page1 = instance->GetTestPage();
- auto waiter = NewWaiter();
- PageId test_page_id;
- page1->GetId(callback::Capture(waiter->GetCallback(), &test_page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- PagePtr page2 =
- instance->GetPage(fidl::MakeOptional(test_page_id), Status::OK);
-
- PageWatcherPtr watcher1_ptr;
- auto watcher1_waiter = NewWaiter();
- Watcher watcher1(watcher1_ptr.NewRequest(), watcher1_waiter->GetCallback());
- PageSnapshotPtr snapshot1;
- waiter = NewWaiter();
- Status status;
- page1->GetSnapshot(snapshot1.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher1_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- auto watcher2_waiter = NewWaiter();
- PageWatcherPtr watcher2_ptr;
- Watcher watcher2(watcher2_ptr.NewRequest(), watcher2_waiter->GetCallback());
- PageSnapshotPtr snapshot2;
- waiter = NewWaiter();
- page2->GetSnapshot(snapshot2.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher2_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page1->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher1_waiter->RunUntilCalled());
- ASSERT_TRUE(watcher2_waiter->RunUntilCalled());
-
- ASSERT_EQ(1u, watcher1.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher1.last_result_state_);
- PageChange change = std::move(watcher1.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(0).value));
-
- ASSERT_EQ(1u, watcher2.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher2.last_result_state_);
- change = std::move(watcher2.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("name", convert::ToString(change.changed_entries.at(0).key));
- EXPECT_EQ("Alice", ToString(change.changed_entries.at(0).value));
-}
-
-class WaitingWatcher : public PageWatcher {
- public:
- WaitingWatcher(fidl::InterfaceRequest<PageWatcher> request,
- fit::closure change_callback)
- : binding_(this, std::move(request)),
- change_callback_(std::move(change_callback)) {}
-
- struct Change {
- PageChange change;
- OnChangeCallback callback;
-
- Change(PageChange change, OnChangeCallback callback)
- : change(std::move(change)), callback(std::move(callback)) {}
- };
-
- std::vector<Change> changes;
-
- private:
- // PageWatcher:
- void OnChange(PageChange page_change, ResultState result_state,
- OnChangeCallback callback) override {
- FXL_DCHECK(result_state == ResultState::COMPLETED)
- << "Handling OnChange pagination not implemented yet";
- changes.emplace_back(std::move(page_change), std::move(callback));
- change_callback_();
- }
-
- fidl::Binding<PageWatcher> binding_;
- fit::closure change_callback_;
-};
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherConcurrentTransaction) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- WaitingWatcher watcher(watcher_ptr.NewRequest(),
- watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- Status status;
- page->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->Put(convert::ToArray("name"), convert::ToArray("Alice"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes.size());
-
- waiter = NewWaiter();
- page->Put(convert::ToArray("foo"), convert::ToArray("bar"),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- auto transaction_waiter = NewWaiter();
- Status start_transaction_status;
- page->StartTransaction(callback::Capture(transaction_waiter->GetCallback(),
- &start_transaction_status));
-
- RunLoopFor(zx::msec(100));
-
- // We haven't sent the callback of the first change, so nothing should have
- // happened.
- EXPECT_EQ(1u, watcher.changes.size());
- EXPECT_TRUE(transaction_waiter->NotCalledYet());
-
- watcher.changes[0].callback(nullptr);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(2u, watcher.changes.size());
- EXPECT_TRUE(transaction_waiter->NotCalledYet());
-
- RunLoopFor(zx::msec(100));
-
- // We haven't sent the callback of the first change, so nothing should have
- // happened.
- EXPECT_EQ(2u, watcher.changes.size());
- EXPECT_TRUE(transaction_waiter->NotCalledYet());
-
- watcher.changes[1].callback(nullptr);
-
- ASSERT_TRUE(transaction_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, start_transaction_status);
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherPrefix) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- Status status;
- page->GetSnapshot(snapshot.NewRequest(), convert::ToArray("01"),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page->Put(convert::ToArray("00-key"), convert::ToArray("value-00"),
-
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page->Put(convert::ToArray("01-key"), convert::ToArray("value-01"),
-
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page->Put(convert::ToArray("02-key"), convert::ToArray("value-02"),
-
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- waiter = NewWaiter();
- page->Commit(callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- ASSERT_TRUE(watcher_waiter->RunUntilCalled());
- EXPECT_EQ(1u, watcher.changes_seen);
- EXPECT_EQ(ResultState::COMPLETED, watcher.last_result_state_);
- PageChange change = std::move(watcher.last_page_change_);
- ASSERT_EQ(1u, change.changed_entries.size());
- EXPECT_EQ("01-key", convert::ToString(change.changed_entries.at(0).key));
-}
-
-TEST_P(PageWatcherIntegrationTest, PageWatcherPrefixNoChange) {
- auto instance = NewLedgerAppInstance();
- PagePtr page = instance->GetTestPage();
- PageWatcherPtr watcher_ptr;
- auto watcher_waiter = NewWaiter();
- Watcher watcher(watcher_ptr.NewRequest(), watcher_waiter->GetCallback());
-
- PageSnapshotPtr snapshot;
- auto waiter = NewWaiter();
- Status status;
- page->GetSnapshot(snapshot.NewRequest(), convert::ToArray("01"),
- std::move(watcher_ptr),
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->Put(convert::ToArray("00-key"), convert::ToArray("value-00"),
-
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- waiter = NewWaiter();
- page->StartTransaction(callback::Capture(waiter->GetCallback(), &status));
- EXPECT_EQ(Status::OK, status);
-
- // Starting a transaction drains all watcher notifications, so if we were to
- // be called, we would know at this point.
- EXPECT_EQ(0u, watcher.changes_seen);
-}
-
-INSTANTIATE_TEST_CASE_P(
- PageWatcherIntegrationTest, PageWatcherIntegrationTest,
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders()));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/sync/BUILD.gn b/bin/ledger/tests/integration/sync/BUILD.gn
deleted file mode 100644
index 621075e..0000000
--- a/bin/ledger/tests/integration/sync/BUILD.gn
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/bin/ledger/*" ]
-
-source_set("sync") {
- testonly = true
-
- sources = [
- "convergence.cc",
- "long_history.cc",
- "sync_tests.cc",
- "test_sync_state_watcher.cc",
- "test_sync_state_watcher.h",
- ]
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl_helpers",
- "//peridot/bin/ledger/storage/public",
- "//peridot/bin/ledger/testing:lib",
- "//peridot/lib/convert",
- "//peridot/lib/firebase_auth/testing",
- ]
-
- public_deps = [
- "//peridot/bin/ledger/testing:ledger_instance_factory",
- "//peridot/bin/ledger/tests/integration:integration_lib",
- "//third_party/googletest:gtest",
- "//zircon/public/lib/trace-provider",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
diff --git a/bin/ledger/tests/integration/sync/convergence.cc b/bin/ledger/tests/integration/sync/convergence.cc
deleted file mode 100644
index 8a3c96f..0000000
--- a/bin/ledger/tests/integration/sync/convergence.cc
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <lib/callback/auto_cleanable.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/waiter.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/vector.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/zx/time.h>
-#include <trace/event.h>
-
-#include "peridot/bin/ledger/storage/public/types.h"
-#include "peridot/bin/ledger/testing/data_generator.h"
-#include "peridot/bin/ledger/testing/get_page_ensure_initialized.h"
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-fidl::VectorPtr<uint8_t> DoubleToArray(double dbl) {
- fidl::VectorPtr<uint8_t> array =
- fidl::VectorPtr<uint8_t>::New(sizeof(double));
- std::memcpy(array->data(), &dbl, sizeof(double));
- return array;
-}
-
-::testing::AssertionResult VmoToDouble(const fuchsia::mem::BufferPtr& vmo,
- double* dbl) {
- *dbl = 0;
- if (vmo->size != sizeof(double)) {
- return ::testing::AssertionFailure()
- << "VMO has the wrong size: " << vmo->size << " instead of "
- << sizeof(double) << ".";
- }
- zx_status_t status = vmo->vmo.read(dbl, 0, sizeof(double));
- if (status < 0) {
- return ::testing::AssertionFailure() << "Unable to read the VMO.";
- }
- return ::testing::AssertionSuccess();
-}
-
-class RefCountedPageSnapshot
- : public fxl::RefCountedThreadSafe<RefCountedPageSnapshot> {
- public:
- RefCountedPageSnapshot() {}
-
- PageSnapshotPtr& operator->() { return snapshot_; }
- PageSnapshotPtr& operator*() { return snapshot_; }
-
- private:
- PageSnapshotPtr snapshot_;
-};
-
-class PageWatcherImpl : public PageWatcher {
- public:
- PageWatcherImpl(fidl::InterfaceRequest<PageWatcher> request,
- fxl::RefPtr<RefCountedPageSnapshot> base_snapshot)
- : binding_(this, std::move(request)),
- current_snapshot_(std::move(base_snapshot)) {}
-
- int changes = 0;
-
- void GetInlineOnLatestSnapshot(std::vector<uint8_t> key,
- PageSnapshot::GetInlineCallback callback) {
- // We need to make sure the PageSnapshotPtr used to make the |GetInline|
- // call survives as long as the call is active, even if a new snapshot
- // arrives in between.
- (*current_snapshot_)
- ->GetInline(
- std::move(key),
- [snapshot = current_snapshot_.Clone(),
- callback = std::move(callback)](
- Status status, std::unique_ptr<InlinedValue> value) mutable {
- callback(status, std::move(value));
- });
- }
-
- private:
- // PageWatcher:
- void OnChange(PageChange /*page_change*/, ResultState /*result_state*/,
- OnChangeCallback callback) override {
- changes++;
- current_snapshot_ = fxl::MakeRefCounted<RefCountedPageSnapshot>();
- callback((**current_snapshot_).NewRequest());
- }
-
- fidl::Binding<PageWatcher> binding_;
- fxl::RefPtr<RefCountedPageSnapshot> current_snapshot_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageWatcherImpl);
-};
-
-class SyncWatcherImpl : public SyncWatcher {
- public:
- SyncWatcherImpl() : binding_(this) {}
-
- auto NewBinding() { return binding_.NewBinding(); }
-
- bool new_state = false;
- SyncState download;
- SyncState upload;
-
- private:
- // SyncWatcher
- void SyncStateChanged(SyncState download, SyncState upload,
- SyncStateChangedCallback callback) override {
- this->download = download;
- this->upload = upload;
- new_state = true;
- callback();
- }
-
- fidl::Binding<SyncWatcher> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SyncWatcherImpl);
-};
-
-// NonAssociativeConflictResolverImpl uses a merge function which is neither
-// associative nor commutative. This means that merging ((1, 2), 3) results in
-// a different value than merging ((2, 3), 1), or ((2, 1), 3).
-// This conflict resolver only works on numeric data. For values A and B, it
-// produces the merged value (4*A+B)/3.
-class NonAssociativeConflictResolverImpl : public ConflictResolver {
- public:
- explicit NonAssociativeConflictResolverImpl(
- fidl::InterfaceRequest<ConflictResolver> request)
- : binding_(this, std::move(request)) {}
- ~NonAssociativeConflictResolverImpl() override {}
-
- private:
- // ConflictResolver:
- void Resolve(
- fidl::InterfaceHandle<PageSnapshot> /*left_version*/,
- fidl::InterfaceHandle<PageSnapshot> /*right_version*/,
- fidl::InterfaceHandle<PageSnapshot> /*common_version*/,
- fidl::InterfaceHandle<MergeResultProvider> result_provider) override {
- auto merge_result_provider =
- std::make_unique<MergeResultProviderPtr>(result_provider.Bind());
- merge_result_provider->set_error_handler(
- [](zx_status_t status) { EXPECT_EQ(ZX_OK, status); });
- MergeResultProvider* merge_result_provider_ptr =
- merge_result_provider->get();
- merge_result_provider_ptr->GetFullDiffNew(
- nullptr, [merge_result_provider = std::move(merge_result_provider)](
- IterationStatus status, std::vector<DiffEntry> changes,
- std::unique_ptr<Token> next_token) mutable {
- ASSERT_EQ(IterationStatus::OK, status);
- ASSERT_EQ(1u, changes.size());
-
- double d1, d2;
- EXPECT_TRUE(VmoToDouble(changes.at(0).left->value, &d1));
- EXPECT_TRUE(VmoToDouble(changes.at(0).right->value, &d2));
- double new_value = (4 * d1 + d2) / 3;
- MergedValue merged_value;
- merged_value.key = std::move(changes.at(0).key);
- merged_value.source = ValueSource::NEW;
- merged_value.new_value = BytesOrReference::New();
- merged_value.new_value->set_bytes(DoubleToArray(new_value));
- std::vector<MergedValue> merged_values;
- merged_values.push_back(std::move(merged_value));
- (*merge_result_provider)->MergeNew(std::move(merged_values));
- (*merge_result_provider)->DoneNew();
- });
- }
-
- fidl::Binding<ConflictResolver> binding_;
-};
-
-class TestConflictResolverFactory : public ConflictResolverFactory {
- public:
- explicit TestConflictResolverFactory(
- fidl::InterfaceRequest<ConflictResolverFactory> request)
- : binding_(this, std::move(request)) {}
-
- private:
- // ConflictResolverFactory:
- void GetPolicy(PageId /*page_id*/, GetPolicyCallback callback) override {
- callback(MergePolicy::CUSTOM);
- }
-
- void NewConflictResolver(
- PageId page_id,
- fidl::InterfaceRequest<ConflictResolver> resolver) override {
- resolvers.emplace(std::piecewise_construct,
- std::forward_as_tuple(convert::ToString(page_id.id)),
- std::forward_as_tuple(std::move(resolver)));
- }
-
- std::map<storage::PageId, NonAssociativeConflictResolverImpl> resolvers;
-
- fidl::Binding<ConflictResolverFactory> binding_;
-};
-
-enum class MergeType {
- LAST_ONE_WINS,
- NON_ASSOCIATIVE_CUSTOM,
-};
-
-class ConvergenceTest
- : public BaseIntegrationTest,
- public ::testing::WithParamInterface<
- std::tuple<MergeType, int, const LedgerAppInstanceFactoryBuilder*>> {
- public:
- ConvergenceTest()
- : BaseIntegrationTest(
- std::get<const LedgerAppInstanceFactoryBuilder*>(GetParam())) {}
- ~ConvergenceTest() override{};
-
- void SetUp() override {
- BaseIntegrationTest::SetUp();
-
- data_generator_ = std::make_unique<DataGenerator>(GetRandom());
-
- std::tie(merge_function_type_, num_ledgers_, std::ignore) = GetParam();
-
- ASSERT_GT(num_ledgers_, 1);
-
- PageId page_id;
-
- for (int i = 0; i < num_ledgers_; i++) {
- auto ledger_instance = NewLedgerAppInstance();
- ASSERT_TRUE(ledger_instance);
- ledger_instances_.push_back(std::move(ledger_instance));
- pages_.emplace_back();
- LedgerPtr ledger_ptr = ledger_instances_[i]->GetTestLedger();
- Status status = Status::UNKNOWN_ERROR;
- auto loop_waiter = NewWaiter();
- GetPageEnsureInitialized(
- &ledger_ptr,
- // The first ledger gets a random page id, the others use the
- // same id for their pages.
- i == 0 ? nullptr : fidl::MakeOptional(page_id), DelayCallback::NO,
- [&] {
- ADD_FAILURE() << "Page should not be disconnected.";
- StopLoop();
- },
- callback::Capture(loop_waiter->GetCallback(), &status, &pages_[i],
- &page_id));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
- }
- }
-
- protected:
- std::unique_ptr<PageWatcherImpl> WatchPageContents(PagePtr* page) {
- PageWatcherPtr page_watcher;
- auto page_snapshot = fxl::MakeRefCounted<RefCountedPageSnapshot>();
- fidl::InterfaceRequest<PageSnapshot> page_snapshot_request =
- (**page_snapshot).NewRequest();
- std::unique_ptr<PageWatcherImpl> watcher =
- std::make_unique<PageWatcherImpl>(page_watcher.NewRequest(),
- std::move(page_snapshot));
- Status status = Status::UNKNOWN_ERROR;
- auto loop_waiter = NewWaiter();
- (*page)->GetSnapshot(
- std::move(page_snapshot_request), fidl::VectorPtr<uint8_t>::New(0),
- std::move(page_watcher),
- callback::Capture(loop_waiter->GetCallback(), &status));
- EXPECT_TRUE(loop_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- return watcher;
- }
-
- std::unique_ptr<SyncWatcherImpl> WatchPageSyncState(PagePtr* page) {
- std::unique_ptr<SyncWatcherImpl> watcher =
- std::make_unique<SyncWatcherImpl>();
- Status status = Status::UNKNOWN_ERROR;
- auto loop_waiter = NewWaiter();
- (*page)->SetSyncStateWatcher(
- watcher->NewBinding(),
- callback::Capture(loop_waiter->GetCallback(), &status));
- EXPECT_TRUE(loop_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- return watcher;
- }
-
- // Returns true if the values for |key| on all the watchers are identical.
- bool AreValuesIdentical(
- const std::vector<std::unique_ptr<PageWatcherImpl>>& watchers,
- std::string key) {
- std::vector<std::unique_ptr<InlinedValue>> values;
- for (int i = 0; i < num_ledgers_; i++) {
- values.emplace_back();
- Status status = Status::UNKNOWN_ERROR;
- auto loop_waiter = NewWaiter();
- watchers[i]->GetInlineOnLatestSnapshot(
- convert::ToArray(key),
- callback::Capture(loop_waiter->GetCallback(), &status, &values[i]));
- EXPECT_TRUE(loop_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
-
- bool values_are_identical = true;
- for (int i = 1; i < num_ledgers_; i++) {
- values_are_identical &= convert::ExtendedStringView(values[0]->value) ==
- convert::ExtendedStringView(values[i]->value);
- }
- return values_are_identical;
- }
-
- int num_ledgers_;
- MergeType merge_function_type_;
-
- std::vector<std::unique_ptr<LedgerAppInstanceFactory::LedgerAppInstance>>
- ledger_instances_;
- std::vector<PagePtr> pages_;
- std::unique_ptr<DataGenerator> data_generator_;
-};
-
-// Verify that the Ledger converges over different settings of merging functions
-// and number of ledger instances.
-TEST_P(ConvergenceTest, NLedgersConverge) {
- std::vector<std::unique_ptr<PageWatcherImpl>> watchers;
- std::vector<std::unique_ptr<SyncWatcherImpl>> sync_watchers;
-
- std::vector<std::unique_ptr<TestConflictResolverFactory>> resolver_factories;
- std::independent_bits_engine<std::default_random_engine, CHAR_BIT, uint8_t>
- generator;
- std::uniform_real_distribution<> distribution(1, 100);
-
- for (int i = 0; i < num_ledgers_; i++) {
- Status status = Status::UNKNOWN_ERROR;
- if (merge_function_type_ == MergeType::NON_ASSOCIATIVE_CUSTOM) {
- ConflictResolverFactoryPtr resolver_factory_ptr;
- resolver_factories.push_back(
- std::make_unique<TestConflictResolverFactory>(
- resolver_factory_ptr.NewRequest()));
- LedgerPtr ledger = ledger_instances_[i]->GetTestLedger();
- auto loop_waiter = NewWaiter();
- ledger->SetConflictResolverFactory(
- std::move(resolver_factory_ptr),
- callback::Capture(loop_waiter->GetCallback(), &status));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
-
- watchers.push_back(WatchPageContents(&pages_[i]));
- sync_watchers.push_back(WatchPageSyncState(&pages_[i]));
-
- auto loop_waiter = NewWaiter();
- pages_[i]->StartTransaction(
- callback::Capture(loop_waiter->GetCallback(), &status));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- loop_waiter = NewWaiter();
- if (merge_function_type_ == MergeType::NON_ASSOCIATIVE_CUSTOM) {
- pages_[i]->Put(convert::ToArray("value"),
- DoubleToArray(distribution(generator)),
- callback::Capture(loop_waiter->GetCallback(), &status));
- } else {
- pages_[i]->Put(convert::ToArray("value"), data_generator_->MakeValue(50),
- callback::Capture(loop_waiter->GetCallback(), &status));
- }
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
- }
-
- auto commit_waiter =
- fxl::MakeRefCounted<callback::StatusWaiter<Status>>(Status::OK);
- Status status = Status::UNKNOWN_ERROR;
- for (int i = 0; i < num_ledgers_; i++) {
- pages_[i]->Commit(commit_waiter->NewCallback());
- }
- auto loop_waiter = NewWaiter();
- commit_waiter->Finalize(
- callback::Capture(loop_waiter->GetCallback(), &status));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
-
- // Function to verify if the visible Ledger state has not changed since last
- // call and all values are identical.
- fit::function<bool()> has_state_converged = [this, &watchers,
- &sync_watchers]() {
- // Counts the number of visible changes. Used to verify that the minimal
- // number of changes for all Ledgers to have communicated is accounted for
- // (see also below).
- int num_changes = 0;
- for (int i = 0; i < num_ledgers_; i++) {
- num_changes += watchers[i]->changes;
- }
- // All ledgers should see their own change (num_ledgers_). Then, at least
- // all but one should receive a change with the "final" value. There might
- // be more changes seen, though.
- if (num_changes < 2 * num_ledgers_ - 1) {
- return false;
- }
-
- // All synchronization must be idle.
- bool idle = true;
- for (int i = 0; i < num_ledgers_; i++) {
- if (sync_watchers[i]->download != SyncState::IDLE ||
- sync_watchers[i]->upload != SyncState::IDLE ||
- sync_watchers[i]->new_state) {
- idle = false;
- }
- // With this, we make sure we can verify if the state changes during the
- // next cycle. If it has changed, we are sure the convergence has not
- // happened yet.
- sync_watchers[i]->new_state = false;
- }
-
- return idle && AreValuesIdentical(watchers, "value");
- };
-
- bool merge_done = false;
- ConflictResolutionWaitStatus wait_status =
- ConflictResolutionWaitStatus::NO_CONFLICTS;
- fxl::RefPtr<callback::StatusWaiter<ConflictResolutionWaitStatus>> waiter;
-
- // In addition of verifying that the external states of the ledgers have
- // converged, we also verify we are not currently performing a merge in the
- // background, indicating that the convergence did not finish.
- auto is_sync_and_merge_complete = [this, &has_state_converged, &merge_done,
- &wait_status, &waiter] {
- TRACE_DURATION("ledger", "ledger_test_is_sync_and_merge_complete");
-
- if (has_state_converged()) {
- if (merge_done &&
- wait_status == ConflictResolutionWaitStatus::NO_CONFLICTS) {
- return true;
- }
- if (!waiter) {
- waiter = fxl::MakeRefCounted<
- callback::StatusWaiter<ConflictResolutionWaitStatus>>(
- ConflictResolutionWaitStatus::NO_CONFLICTS);
- for (int i = 0; i < num_ledgers_; i++) {
- pages_[i]->WaitForConflictResolution(waiter->NewCallback());
- }
- waiter->Finalize([&merge_done, &wait_status,
- &waiter](ConflictResolutionWaitStatus status) {
- merge_done = true;
- wait_status = status;
- waiter = nullptr;
- });
- }
- return false;
- }
- merge_done = false;
- if (waiter) {
- waiter->Cancel();
- waiter = nullptr;
- }
- return false;
- };
-
- // If |RunLoopUntil| returns, the condition is met, thus the ledgers have
- // converged.
- RunLoopUntil(std::move(is_sync_and_merge_complete));
- int num_changes = 0;
- for (int i = 0; i < num_ledgers_; i++) {
- num_changes += watchers[i]->changes;
- }
- EXPECT_GE(num_changes, 2 * num_ledgers_ - 1);
-
- // All synchronization must still be idle.
- for (int i = 0; i < num_ledgers_; i++) {
- EXPECT_FALSE(sync_watchers[i]->new_state);
- EXPECT_EQ(SyncState::IDLE, sync_watchers[i]->download);
- EXPECT_EQ(SyncState::IDLE, sync_watchers[i]->upload);
- }
-
- EXPECT_TRUE(AreValuesIdentical(watchers, "value"));
-}
-
-INSTANTIATE_TEST_CASE_P(
- ManyLedgersConvergenceTest, ConvergenceTest,
- ::testing::Combine(
- ::testing::Values(MergeType::LAST_ONE_WINS,
- MergeType::NON_ASSOCIATIVE_CUSTOM),
- // Temporarily reduce the number of simulated Ledgers to reduce flaky
- // failures on bots, see LE-624 and ZX-2613. TODO(ppi): revert back to
- // (2, 6).
- // ::testing::Range(2, 6),
- ::testing::Range(2, 3),
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders())));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/sync/long_history.cc b/bin/ledger/tests/integration/sync/long_history.cc
deleted file mode 100644
index 2557bc4..0000000
--- a/bin/ledger/tests/integration/sync/long_history.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/callback/capture.h>
-#include <lib/callback/waiter.h>
-#include <lib/fidl/cpp/optional.h>
-
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/bin/ledger/tests/integration/sync/test_sync_state_watcher.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-class LongHistorySyncTest : public IntegrationTest {
- protected:
- std::unique_ptr<TestSyncStateWatcher> WatchPageSyncState(PagePtr* page) {
- auto watcher = std::make_unique<TestSyncStateWatcher>();
-
- Status status = Status::INTERNAL_ERROR;
- auto waiter = NewWaiter();
- (*page)->SetSyncStateWatcher(
- watcher->NewBinding(),
- callback::Capture(waiter->GetCallback(), &status));
- if (!waiter->RunUntilCalled()) {
- return nullptr;
- }
- if (status != Status::OK) {
- return nullptr;
- }
- return watcher;
- }
-
- bool WaitUntilSyncIsIdle(TestSyncStateWatcher* watcher) {
- return RunLoopUntil([watcher] {
- return watcher->Equals(SyncState::IDLE, SyncState::IDLE);
- });
- }
-};
-
-TEST_P(LongHistorySyncTest, SyncLongHistory) {
- PageId page_id;
- Status status = Status::INTERNAL_ERROR;
-
- // Create the first instance and write the page entries.
- auto instance1 = NewLedgerAppInstance();
- auto page1 = instance1->GetTestPage();
- auto page1_state_watcher = WatchPageSyncState(&page1);
- ASSERT_TRUE(page1_state_watcher);
- const int commit_history_length = 500;
- // Overwrite one key N times, creating N implicit commits.
- for (int i = 0; i < commit_history_length; i++) {
- // TODO(ppi): switch to using a StatusWaiter to wait in parallel on all
- // puts, once this does not crash w/ ZX_ERR_SHOULD_WAIT in the test loop
- // dispatcher.
- auto put_waiter = NewWaiter();
- page1->Put(convert::ToArray("iteration"),
- convert::ToArray(std::to_string(i)),
- callback::Capture(put_waiter->GetCallback(), &status));
- ASSERT_TRUE(put_waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
- }
- // Wait until the commits are uploaded.
- EXPECT_TRUE(WaitUntilSyncIsIdle(page1_state_watcher.get()));
-
- // Retrieve the page ID so that we can later connect to the same page from
- // another app instance.
- auto waiter = NewWaiter();
- page1->GetId(callback::Capture(waiter->GetCallback(), &page_id));
- ASSERT_TRUE(waiter->RunUntilCalled());
-
- // Create the second instance, connect to the same page and download the
- // data.
- auto instance2 = NewLedgerAppInstance();
- auto page2 = instance2->GetPage(fidl::MakeOptional(page_id), Status::OK);
- auto page2_state_watcher = WatchPageSyncState(&page2);
- ASSERT_TRUE(page2_state_watcher);
- EXPECT_TRUE(WaitUntilSyncIsIdle(page2_state_watcher.get()));
-
- PageSnapshotPtr snapshot;
- waiter = NewWaiter();
- page2->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- nullptr,
- callback::Capture(waiter->GetCallback(), &status));
- ASSERT_TRUE(waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
- std::unique_ptr<InlinedValue> inlined_value;
-
- waiter = NewWaiter();
- snapshot->GetInline(
- convert::ToArray("iteration"),
- callback::Capture(waiter->GetCallback(), &status, &inlined_value));
- ASSERT_TRUE(waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
- ASSERT_TRUE(inlined_value);
- const int last_iteration = commit_history_length - 1;
- ASSERT_EQ(std::to_string(last_iteration),
- convert::ToString(inlined_value->value));
-
- // Verify that the sync state of the second page connection eventually becomes
- // idle.
- EXPECT_TRUE(WaitUntilSyncIsIdle(page2_state_watcher.get()));
-}
-
-INSTANTIATE_TEST_CASE_P(
- LongHistorySyncTest, LongHistorySyncTest,
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders()));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/sync/sync_tests.cc b/bin/ledger/tests/integration/sync/sync_tests.cc
deleted file mode 100644
index 36cfbd3..0000000
--- a/bin/ledger/tests/integration/sync/sync_tests.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/callback/capture.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/bin/ledger/tests/integration/integration_test.h"
-#include "peridot/bin/ledger/tests/integration/sync/test_sync_state_watcher.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-namespace {
-
-class SyncIntegrationTest : public IntegrationTest {
- protected:
- std::unique_ptr<TestSyncStateWatcher> WatchPageSyncState(PagePtr* page) {
- auto watcher = std::make_unique<TestSyncStateWatcher>();
-
- Status status = Status::INTERNAL_ERROR;
- auto loop_waiter = NewWaiter();
- (*page)->SetSyncStateWatcher(
- watcher->NewBinding(),
- callback::Capture(loop_waiter->GetCallback(), &status));
- EXPECT_TRUE(loop_waiter->RunUntilCalled());
- EXPECT_EQ(Status::OK, status);
-
- return watcher;
- }
-
- bool WaitUntilSyncIsIdle(TestSyncStateWatcher* watcher) {
- return RunLoopUntil([watcher] {
- return watcher->Equals(SyncState::IDLE, SyncState::IDLE);
- });
- }
-};
-
-// Verifies that a new page entry is correctly synchronized between two Ledger
-// app instances.
-//
-// In this test the app instances connect to the cloud one after the other: the
-// first instance uploads data to the cloud and shuts down, and only after that
-// the second instance is created and connected.
-TEST_P(SyncIntegrationTest, SerialConnection) {
- PageId page_id;
- Status status;
-
- // Create the first instance and write the page entry.
- auto instance1 = NewLedgerAppInstance();
- auto page1 = instance1->GetTestPage();
- auto page1_state_watcher = WatchPageSyncState(&page1);
- auto loop_waiter = NewWaiter();
- page1->Put(convert::ToArray("Hello"), convert::ToArray("World"),
- callback::Capture(loop_waiter->GetCallback(), &status));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
-
- // Retrieve the page ID so that we can later connect to the same page from
- // another app instance.
- ASSERT_EQ(Status::OK, status);
- loop_waiter = NewWaiter();
- page1->GetId(callback::Capture(loop_waiter->GetCallback(), &page_id));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
-
- // Wait until the sync state becomes idle.
- EXPECT_TRUE(WaitUntilSyncIsIdle(page1_state_watcher.get()));
-
- // Create the second instance, connect to the same page and download the
- // data.
- auto instance2 = NewLedgerAppInstance();
- auto page2 = instance2->GetPage(fidl::MakeOptional(page_id), Status::OK);
- auto page2_state_watcher = WatchPageSyncState(&page2);
- EXPECT_TRUE(WaitUntilSyncIsIdle(page2_state_watcher.get()));
-
- PageSnapshotPtr snapshot;
- loop_waiter = NewWaiter();
- page2->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- nullptr,
- callback::Capture(loop_waiter->GetCallback(), &status));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
- std::unique_ptr<InlinedValue> inlined_value;
-
- loop_waiter = NewWaiter();
- snapshot->GetInline(
- convert::ToArray("Hello"),
- callback::Capture(loop_waiter->GetCallback(), &status, &inlined_value));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
- ASSERT_TRUE(inlined_value);
- ASSERT_EQ("World", convert::ToString(inlined_value->value));
-
- // Verify that the sync state of the second page connection eventually becomes
- // idle.
- EXPECT_TRUE(WaitUntilSyncIsIdle(page2_state_watcher.get()));
-}
-
-// Verifies that a new page entry is correctly synchronized between two Ledger
-// app instances.
-//
-// In this test the app instances connect to the cloud concurrently: the second
-// instance is already connected when the first instance writes the entry.
-TEST_P(SyncIntegrationTest, ConcurrentConnection) {
- auto instance1 = NewLedgerAppInstance();
- auto instance2 = NewLedgerAppInstance();
-
- auto page1 = instance1->GetTestPage();
- auto page1_state_watcher = WatchPageSyncState(&page1);
- PageId page_id;
- auto loop_waiter = NewWaiter();
- page1->GetId(callback::Capture(loop_waiter->GetCallback(), &page_id));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- auto page2 = instance2->GetPage(fidl::MakeOptional(page_id), Status::OK);
- auto page2_state_watcher = WatchPageSyncState(&page2);
- // Wait until the sync on the second device is idle and record the number of
- // state updates.
- EXPECT_TRUE(WaitUntilSyncIsIdle(page2_state_watcher.get()));
- int page2_initial_state_change_count =
- page2_state_watcher->state_change_count;
-
- Status status;
- loop_waiter = NewWaiter();
- page1->Put(convert::ToArray("Hello"), convert::ToArray("World"),
- callback::Capture(loop_waiter->GetCallback(), &status));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
-
- // Wait until page1 finishes uploading the changes.
- EXPECT_TRUE(WaitUntilSyncIsIdle(page1_state_watcher.get()));
-
- // Note that we cannot just wait for the sync to become idle on the second
- // instance, as it might still be idle upon the first check because the device
- // hasn't yet received the remote notification about new commits. This is why
- // we also check that another state change notification was delivered.
- EXPECT_TRUE(
- RunLoopUntil([&page2_state_watcher, page2_initial_state_change_count] {
- return page2_state_watcher->state_change_count >
- page2_initial_state_change_count &&
- page2_state_watcher->Equals(SyncState::IDLE, SyncState::IDLE);
- }));
-
- PageSnapshotPtr snapshot;
- loop_waiter = NewWaiter();
- page2->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- nullptr,
- callback::Capture(loop_waiter->GetCallback(), &status));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
- std::unique_ptr<InlinedValue> inlined_value;
- loop_waiter = NewWaiter();
- snapshot->GetInline(
- convert::ToArray("Hello"),
- callback::Capture(loop_waiter->GetCallback(), &status, &inlined_value));
- ASSERT_TRUE(loop_waiter->RunUntilCalled());
- ASSERT_EQ(Status::OK, status);
- ASSERT_TRUE(inlined_value);
- ASSERT_EQ("World", convert::ToString(inlined_value->value));
-
- // Verify that the sync states of page2 eventually become idle.
- EXPECT_TRUE(WaitUntilSyncIsIdle(page2_state_watcher.get()));
-}
-
-INSTANTIATE_TEST_CASE_P(
- SyncIntegrationTest, SyncIntegrationTest,
- ::testing::ValuesIn(GetLedgerAppInstanceFactoryBuilders()));
-
-} // namespace
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/sync/test_sync_state_watcher.cc b/bin/ledger/tests/integration/sync/test_sync_state_watcher.cc
deleted file mode 100644
index 1f5495c..0000000
--- a/bin/ledger/tests/integration/sync/test_sync_state_watcher.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/tests/integration/sync/test_sync_state_watcher.h"
-
-namespace ledger {
-
-TestSyncStateWatcher::TestSyncStateWatcher() : binding_(this) {}
-TestSyncStateWatcher::~TestSyncStateWatcher() {}
-
-void TestSyncStateWatcher::SyncStateChanged(SyncState download,
- SyncState upload,
- SyncStateChangedCallback callback) {
- state_change_count++;
- download_state = download;
- upload_state = upload;
- callback();
-}
-
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/sync/test_sync_state_watcher.h b/bin/ledger/tests/integration/sync/test_sync_state_watcher.h
deleted file mode 100644
index 0442121..0000000
--- a/bin/ledger/tests/integration/sync/test_sync_state_watcher.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_SYNC_TEST_SYNC_STATE_WATCHER_H_
-#define PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_SYNC_TEST_SYNC_STATE_WATCHER_H_
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-
-namespace ledger {
-
-class TestSyncStateWatcher : public SyncWatcher {
- public:
- TestSyncStateWatcher();
- ~TestSyncStateWatcher() override;
-
- auto NewBinding() { return binding_.NewBinding(); }
-
- bool Equals(SyncState download, SyncState upload) {
- return download == download_state && upload == upload_state;
- }
-
- SyncState download_state = SyncState::PENDING;
- SyncState upload_state = SyncState::PENDING;
- int state_change_count = 0;
-
- private:
- // SyncWatcher:
- void SyncStateChanged(SyncState download, SyncState upload,
- SyncStateChangedCallback callback) override;
-
- fidl::Binding<SyncWatcher> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestSyncStateWatcher);
-};
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_SYNC_TEST_SYNC_STATE_WATCHER_H_
diff --git a/bin/ledger/tests/integration/test_utils.cc b/bin/ledger/tests/integration/test_utils.cc
deleted file mode 100644
index 809a1c1..0000000
--- a/bin/ledger/tests/integration/test_utils.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/ledger/tests/integration/test_utils.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/time/time_delta.h>
-#include <lib/zx/time.h>
-
-#include "garnet/public/lib/callback/capture.h"
-#include "gtest/gtest.h"
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/lib/convert/convert.h"
-
-namespace ledger {
-
-std::vector<uint8_t> RandomArray(rng::Random* random, size_t size,
- const std::vector<uint8_t>& prefix) {
- EXPECT_TRUE(size >= prefix.size());
- std::vector<uint8_t> array(size);
- for (size_t i = 0; i < prefix.size(); ++i) {
- array.at(i) = prefix[i];
- }
- random->Draw(&array[prefix.size()], size - prefix.size());
- return array;
-}
-
-std::string ToString(const fuchsia::mem::BufferPtr& vmo) {
- std::string value;
- bool status = fsl::StringFromVmo(*vmo, &value);
- FXL_DCHECK(status);
- return value;
-}
-
-std::vector<uint8_t> ToArray(const fuchsia::mem::BufferPtr& vmo) {
- return convert::ToArray(ToString(vmo));
-}
-
-std::vector<Entry> SnapshotGetEntries(LoopController* loop_controller,
- PageSnapshotPtr* snapshot,
- fidl::VectorPtr<uint8_t> start,
- int* num_queries) {
- std::vector<Entry> result;
- std::unique_ptr<Token> token;
- if (num_queries) {
- *num_queries = 0;
- }
- do {
- Status status;
- std::vector<Entry> entries;
- auto waiter = loop_controller->NewWaiter();
- (*snapshot)->GetEntries(
- start.Clone(), std::move(token),
- callback::Capture(waiter->GetCallback(), &status, &entries, &token));
- if (!waiter->RunUntilCalled()) {
- ADD_FAILURE() << "|GetEntries| failed to call back.";
- return {};
- }
- if (status != Status::OK && status != Status::PARTIAL_RESULT) {
- ADD_FAILURE() << "Actual status: " << fidl::ToUnderlying(status);
- return {};
- }
- if (num_queries) {
- (*num_queries)++;
- }
- for (auto& entry : entries) {
- result.push_back(std::move(entry));
- }
- } while (token);
- return result;
-}
-
-} // namespace ledger
diff --git a/bin/ledger/tests/integration/test_utils.h b/bin/ledger/tests/integration/test_utils.h
deleted file mode 100644
index 01f27f8..0000000
--- a/bin/ledger/tests/integration/test_utils.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_TEST_UTILS_H_
-#define PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_TEST_UTILS_H_
-
-#include <string>
-#include <vector>
-
-#include <lib/fsl/vmo/sized_vmo.h>
-
-#include "peridot/bin/ledger/fidl/include/types.h"
-#include "peridot/bin/ledger/testing/ledger_app_instance_factory.h"
-#include "peridot/lib/rng/random.h"
-
-namespace ledger {
-
-// Builds an array of length |size|, starting with |prefix| and completed with
-// random data.
-std::vector<uint8_t> RandomArray(rng::Random* random, size_t size,
- const std::vector<uint8_t>& prefix = {});
-
-// Extracts the content of |vmo| as a std::string.
-std::string ToString(const fuchsia::mem::BufferPtr& vmo);
-
-// Extracts the content of |vmo| as a FIDL vector.
-std::vector<uint8_t> ToArray(const fuchsia::mem::BufferPtr& vmo);
-
-// Retrieves all entries from the snapshot with a key greater of equals to
-// |start|. If |num_queries| is not null, returns the number of calls to
-// |GetEntries|. If any call fails, this function will fail the current test.
-std::vector<Entry> SnapshotGetEntries(
- LoopController* loop_controller, PageSnapshotPtr* snapshot,
- fidl::VectorPtr<uint8_t> start = fidl::VectorPtr<uint8_t>::New(0),
- int* num_queries = nullptr);
-
-} // namespace ledger
-
-#endif // PERIDOT_BIN_LEDGER_TESTS_INTEGRATION_TEST_UTILS_H_
diff --git a/bin/ledger/tests/ledger_unittests.cmx b/bin/ledger/tests/ledger_unittests.cmx
deleted file mode 100644
index 8e55c9b..0000000
--- a/bin/ledger/tests/ledger_unittests.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/ledger_unittests"
- },
- "sandbox": {
- "features": [],
- "services": [
- ]
- }
-}
diff --git a/bin/module_resolver/BUILD.gn b/bin/module_resolver/BUILD.gn
deleted file mode 100644
index 09f661f..0000000
--- a/bin/module_resolver/BUILD.gn
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-import("//peridot/build/executable_package.gni")
-import("//peridot/build/tests_package.gni")
-
-executable_package("module_resolver") {
- meta = [
- {
- path = "meta/module_resolver.cmx"
- dest = "module_resolver.cmx"
- },
- ]
-
- sources = [
- "module_resolver_main.cc",
- ]
-
- deps = [
- ":local_module_resolver",
- "//garnet/public/fidl/fuchsia.net.oldhttp",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/module_manifest_source:firebase_source",
- "//peridot/lib/module_manifest_source:module_package_source",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:app_driver",
- "//peridot/public/lib/entity/cpp:json",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-tests_package("module_resolver_unittests") {
- deps = [
- ":local_module_resolver_unittest",
- ]
-}
-
-source_set("local_module_resolver") {
- sources = [
- "local_module_resolver.cc",
- "local_module_resolver.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/module_manifest_source",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- "//peridot/public/lib/context/cpp:context_helper",
- "//peridot/public/lib/entity/cpp:json",
- ]
-}
-
-executable("local_module_resolver_unittest") {
- testonly = true
-
- sources = [
- "local_module_resolver_unittest.cc",
- ]
-
- deps = [
- ":local_module_resolver",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/testing:entity_resolver_fake",
- "//peridot/public/lib/entity/cpp:json",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/module_resolver/local_module_resolver.cc b/bin/module_resolver/local_module_resolver.cc
deleted file mode 100644
index 0ac049b..0000000
--- a/bin/module_resolver/local_module_resolver.cc
+++ /dev/null
@@ -1,647 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/module_resolver/local_module_resolver.h"
-
-#include <algorithm>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/context/cpp/context_helper.h>
-#include <lib/entity/cpp/json.h>
-#include <lib/fxl/strings/split_string.h>
-
-#include "peridot/lib/fidl/clone.h"
-
-namespace modular {
-namespace {
-
-// << operator for LocalModuleResolver::ManifestId.
-std::ostream& operator<<(std::ostream& o,
- const std::pair<std::string, std::string>& id) {
- return o << id.first << ":" << id.second;
-}
-
-} // namespace
-
-LocalModuleResolver::LocalModuleResolver()
- : query_handler_binding_(this),
- already_checking_if_sources_are_ready_(false),
- weak_factory_(this) {}
-
-LocalModuleResolver::~LocalModuleResolver() = default;
-
-std::set<LocalModuleResolver::ManifestId> LocalModuleResolver::FindHandlers(
- ModuleUri handler) {
- // Search through each known repository source for |handler|, and return a
- // set<ManifestId> containing them.
- std::set<ManifestId> manifests;
- for (auto& source : ready_sources_) {
- auto it = manifests_.find(ManifestId(source, handler));
- if (it != manifests_.end()) {
- manifests.insert(it->first);
- }
- }
- return manifests;
-}
-
-void LocalModuleResolver::AddSource(
- std::string source_name, std::unique_ptr<ModuleManifestSource> repo) {
- FXL_CHECK(bindings_.size() == 0);
-
- auto ptr = repo.get();
- sources_.emplace(source_name, std::move(repo));
-
- ptr->Watch(
- async_get_default_dispatcher(),
- [this, source_name]() { OnSourceIdle(source_name); },
- [this, source_name](std::string module_uri,
- fuchsia::modular::ModuleManifest manifest) {
- OnNewManifestEntry(source_name, module_uri, std::move(manifest));
- },
- [this, source_name](std::string module_uri) {
- OnRemoveManifestEntry(source_name, std::move(module_uri));
- });
-}
-
-void LocalModuleResolver::Connect(
- fidl::InterfaceRequest<fuchsia::modular::ModuleResolver> request) {
- if (!AllSourcesAreReady()) {
- PeriodicCheckIfSourcesAreReady();
- pending_bindings_.push_back(std::move(request));
- } else {
- bindings_.AddBinding(this, std::move(request));
- }
-}
-
-void LocalModuleResolver::BindQueryHandler(
- fidl::InterfaceRequest<fuchsia::modular::QueryHandler> request) {
- query_handler_binding_.Bind(std::move(request));
-}
-
-class LocalModuleResolver::FindModulesCall
- : public Operation<fuchsia::modular::FindModulesResponse> {
- public:
- FindModulesCall(LocalModuleResolver* local_module_resolver,
- fuchsia::modular::FindModulesQuery query,
- ResultCall result_call)
- : Operation("LocalModuleResolver::FindModulesCall",
- std::move(result_call)),
- local_module_resolver_(local_module_resolver),
- query_(std::move(query)) {}
-
- // Finds all modules that match |query_|.
- //
- // The specified action is used to filter potential modules, and
- // the associated parameters are required to match in both name and type. If
- // |query_.module_handler| is specified, then the search for the action and
- // parameters are restricted to the specified handler.
- void Run() override {
- FlowToken flow{this, &response_};
-
- // 1. If a handler is specified, use only that for |candidates_|.
- if (!query_.handler.is_null()) {
- auto found_handlers =
- local_module_resolver_->FindHandlers(query_.handler);
- if (found_handlers.empty()) {
- response_ = CreateEmptyResponseWithStatus(
- fuchsia::modular::FindModulesStatus::UNKNOWN_HANDLER);
- return;
- }
-
- candidates_ = found_handlers;
- }
-
- // 2. Find all modules that can handle the action and then take an
- // intersection |candidates_| if its non-empty.
- auto action_it =
- local_module_resolver_->action_to_manifests_.find(query_.action);
- if (action_it != local_module_resolver_->action_to_manifests_.end()) {
- if (!candidates_.empty()) {
- std::set<ManifestId> new_candidates;
- if (action_it != local_module_resolver_->action_to_manifests_.end()) {
- candidates_ = action_it->second;
- std::set_intersection(
- candidates_.begin(), candidates_.end(), action_it->second.begin(),
- action_it->second.end(),
- std::inserter(new_candidates, new_candidates.begin()));
- candidates_ = new_candidates;
- }
- } else {
- candidates_ = action_it->second;
- }
- }
-
- // 3. For each parameter in the FindModulesQuery, try to filter
- // |candidates_| to only the modules that provide the types in the parameter
- // constraints.
- if (!candidates_.empty()) {
- for (const auto& parameter_entry : query_.parameter_constraints) {
- ProcessParameterTypes(parameter_entry.param_name,
- parameter_entry.param_types);
- }
- }
-
- FinalizeResponse(flow);
- }
-
- private:
- // |parameter_name| and |types| come from the FindModulesQuery.
- void ProcessParameterTypes(const std::string& parameter_name,
- const std::vector<std::string>& types) {
- std::set<ManifestId> parameter_type_entries;
- for (const auto& type : types) {
- std::set<ManifestId> found_entries =
- GetManifestsMatchingParameterByTypeAndName(type, parameter_name);
- parameter_type_entries.insert(found_entries.begin(), found_entries.end());
- }
-
- std::set<ManifestId> new_result_entries;
- // All parameters in the query must be handled by the candidates. For each
- // parameter that is processed, filter out any existing results that can't
- // also handle the new parameter type.
- std::set_intersection(
- candidates_.begin(), candidates_.end(), parameter_type_entries.begin(),
- parameter_type_entries.end(),
- std::inserter(new_result_entries, new_result_entries.begin()));
-
- candidates_.swap(new_result_entries);
- }
-
- // Returns the ManifestIds of all entries with a parameter that matches the
- // provided name and type.
- std::set<ManifestId> GetManifestsMatchingParameterByTypeAndName(
- const std::string& parameter_type, const std::string& parameter_name) {
- std::set<ManifestId> found_entries;
- auto found_manifests_it =
- local_module_resolver_->parameter_type_and_name_to_manifests_.find(
- std::make_pair(parameter_type, parameter_name));
- if (found_manifests_it !=
- local_module_resolver_->parameter_type_and_name_to_manifests_.end()) {
- found_entries.insert(found_manifests_it->second.begin(),
- found_manifests_it->second.end());
- }
- return found_entries;
- }
-
- // At this point |candidates_| contains all the modules that satisfy the
- // query. The purpose of this method is to create a response using these
- // candidates.
- void FinalizeResponse(FlowToken flow) {
- response_ = CreateEmptyResponseWithStatus(
- fuchsia::modular::FindModulesStatus::SUCCESS);
- if (candidates_.empty()) {
- return;
- }
-
- for (auto manifest_id : candidates_) {
- auto entry_it = local_module_resolver_->manifests_.find(manifest_id);
- FXL_CHECK(entry_it != local_module_resolver_->manifests_.end())
- << manifest_id;
-
- const auto& manifest = entry_it->second;
- fuchsia::modular::FindModulesResult result;
- result.module_id = manifest.binary;
- result.manifest = fuchsia::modular::ModuleManifest::New();
- result.manifest->intent_filters.resize(0);
- fidl::Clone(manifest, result.manifest.get());
-
- response_.results.push_back(std::move(result));
- }
- }
-
- fuchsia::modular::FindModulesResponse CreateEmptyResponseWithStatus(
- fuchsia::modular::FindModulesStatus status) {
- fuchsia::modular::FindModulesResponse response;
- response.status = status;
- response.results.resize(0);
- return response;
- }
-
- fuchsia::modular::FindModulesResponse response_;
- LocalModuleResolver* const local_module_resolver_;
- fuchsia::modular::FindModulesQuery query_;
-
- std::set<ManifestId> candidates_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FindModulesCall);
-};
-
-class LocalModuleResolver::FindModulesByTypesCall
- : public Operation<fuchsia::modular::FindModulesByTypesResponse> {
- public:
- FindModulesByTypesCall(LocalModuleResolver* const local_module_resolver,
- fuchsia::modular::FindModulesByTypesQuery query,
- ResultCall result_call)
- : Operation("LocalModuleResolver::FindModulesByTypesCall",
- std::move(result_call)),
- local_module_resolver_(local_module_resolver),
- query_(std::move(query)) {}
-
- void Run() override {
- FlowToken flow{this, &response_};
-
- response_ = CreateEmptyResponseWithStatus();
-
- std::set<ManifestId> candidates;
- for (auto& constraint : query_.parameter_constraints) {
- std::set<ManifestId> param_type_entries;
- parameter_types_cache_[constraint.constraint_name] =
- constraint.param_types;
- for (auto& type : constraint.param_types) {
- auto found_entries = GetManifestsMatchingParameterByType(type);
- candidates.insert(found_entries.begin(), found_entries.end());
- }
- }
-
- for (auto& candidate : candidates) {
- auto results = MatchQueryParametersToManifestParametersByType(
- local_module_resolver_->manifests_[candidate]);
-
- using iter = decltype(results->begin());
- response_.results.insert(response_.results.end(),
- std::move_iterator<iter>(results->begin()),
- std::move_iterator<iter>(results->end()));
- }
- }
-
- private:
- fuchsia::modular::FindModulesByTypesResponse CreateEmptyResponseWithStatus() {
- fuchsia::modular::FindModulesByTypesResponse r;
- r.results.resize(0);
- return r;
- }
-
- // Returns the set of all modules that have a parameter whose type is
- // |parameter_type|.
- std::set<LocalModuleResolver::ManifestId> GetManifestsMatchingParameterByType(
- const std::string& parameter_type) {
- std::set<ManifestId> found_entries;
- auto found_manifests_it =
- local_module_resolver_->parameter_type_to_manifests_.find(
- parameter_type);
- if (found_manifests_it !=
- local_module_resolver_->parameter_type_to_manifests_.end()) {
- found_entries.insert(found_manifests_it->second.begin(),
- found_manifests_it->second.end());
- }
- return found_entries;
- }
-
- // Creates FindModulesResults for each available mapping from
- // parameters in |query_| to the corresponding parameters in each candidate
- // manifest.
- //
- // In order for a query to match an manifest, it must contain enough
- // parameters to populate each of the manifest parameters.
- // TODO(MI4-866): Handle entries with optional parameters.
- fidl::VectorPtr<fuchsia::modular::FindModulesByTypesResult>
- MatchQueryParametersToManifestParametersByType(
- const fuchsia::modular::ModuleManifest& manifest) {
- fidl::VectorPtr<fuchsia::modular::FindModulesByTypesResult> modules;
- modules.resize(0);
-
- for (const auto& intent_filter : *manifest.intent_filters) {
- if (query_.parameter_constraints.size() <
- intent_filter.parameter_constraints.size()) {
- return modules;
- }
-
- // Map each parameter in |intent_filter| to the query parameter names that
- // could be used to populate the |intent_filter| parameter.
- std::map<ParameterName, std::vector<ParameterName>>
- intent_filter_params_to_query_constraints =
- MapManifestParametersToCompatibleQueryParameters(intent_filter);
-
- // Compute each possible map from |query_| parameter to the
- // |intent_filter| parameter that it should populate.
- std::vector<std::map<ParameterName, ParameterName>> parameter_mappings =
- ComputeResultsFromEntryParameterToQueryParameterMapping(
- intent_filter_params_to_query_constraints);
-
- // For each of the possible mappings, create a resolver result.
- for (const auto& parameter_mapping : parameter_mappings) {
- fuchsia::modular::FindModulesByTypesResult result;
- // TODO(vardhan): This score is a place holder. Compute a simple score
- // for results.
- result.score = 1.0f;
- result.module_id = manifest.binary;
- result.action = intent_filter.action;
- for (auto& kv : parameter_mapping) {
- fuchsia::modular::FindModulesByTypesParameterMapping mapping;
- mapping.query_constraint_name = kv.first;
- mapping.result_param_name = kv.second;
- result.parameter_mappings.push_back(std::move(mapping));
- }
- result.manifest = fuchsia::modular::ModuleManifest::New();
- fidl::Clone(manifest, result.manifest.get());
-
- modules.push_back(std::move(result));
- }
- }
-
- return modules;
- }
-
- // Returns a map where the keys are the |intent_filter|'s parameter names, and
- // the values are all the |query_| parameter names that are type-compatible
- // with that |intent_filter| parameter name.
- std::map<std::string, std::vector<std::string>>
- MapManifestParametersToCompatibleQueryParameters(
- const fuchsia::modular::IntentFilter& intent_filter) {
- std::map<ParameterName, std::vector<ParameterName>>
- intent_filter_param_to_query_constraints;
- for (const auto& intent_filter_param :
- intent_filter.parameter_constraints) {
- std::vector<ParameterName> matching_query_constraints;
- for (const auto& query_constraint : query_.parameter_constraints) {
- const auto& this_query_constraint_cache =
- parameter_types_cache_[query_constraint.constraint_name];
- if (std::find(this_query_constraint_cache.begin(),
- this_query_constraint_cache.end(),
- intent_filter_param.type) !=
- this_query_constraint_cache.end()) {
- matching_query_constraints.push_back(
- query_constraint.constraint_name);
- }
- }
- intent_filter_param_to_query_constraints[intent_filter_param.name] =
- matching_query_constraints;
- }
- return intent_filter_param_to_query_constraints;
- }
-
- // Returns a collection of valid mappings where the key is the query
- // parameter, and the value is the manifest parameter to be populated with the
- // query parameters contents.
- //
- // |remaining_intent_filter_params| are all the manifest parameters that are
- // yet to be matched. |used_query_constraints| are all the query parameters
- // that have already been used in the current solution.
- std::vector<std::map<std::string, std::string>>
- ComputeResultsFromEntryParameterToQueryParameterMapping(
- const std::map<std::string, std::vector<std::string>>&
- remaining_intent_filter_params,
- const std::set<std::string>& used_query_constraints = {}) {
- std::vector<std::map<std::string, std::string>> result;
- if (remaining_intent_filter_params.empty()) {
- return result;
- }
-
- auto first_intent_filter_param_it = remaining_intent_filter_params.begin();
- const std::string& first_intent_filter_param_name =
- first_intent_filter_param_it->first;
- const std::vector<std::string> query_constraints_for_first_entry =
- first_intent_filter_param_it->second;
-
- // If there is only one remaining manifest parameter, create one result
- // mapping for each viable query parameter.
- if (remaining_intent_filter_params.size() == 1) {
- for (const auto& query_constraint_name :
- query_constraints_for_first_entry) {
- // Don't create solutions where the query parameter has already been
- // used.
- if (used_query_constraints.find(query_constraint_name) !=
- used_query_constraints.end()) {
- continue;
- }
-
- std::map<std::string, std::string> result_map;
- result_map[query_constraint_name] = first_intent_filter_param_name;
- result.push_back(result_map);
- }
- return result;
- }
-
- for (const auto& query_constraint_name :
- first_intent_filter_param_it->second) {
- // If the query parameter has already been used, it cannot be matched
- // again, and thus the loop continues.
- if (used_query_constraints.find(query_constraint_name) !=
- used_query_constraints.end()) {
- continue;
- }
-
- // The current query parameter that will be used by the first manifest
- // parameter must be added to the used set before computing the solution
- // to the smaller problem.
- std::set<std::string> new_used_query_constraints = used_query_constraints;
- new_used_query_constraints.insert(query_constraint_name);
-
- // Recurse for the remaining parameters.
- std::vector<std::map<std::string, std::string>> solution_for_remainder =
- ComputeResultsFromEntryParameterToQueryParameterMapping(
- {std::next(remaining_intent_filter_params.begin()),
- remaining_intent_filter_params.end()},
- new_used_query_constraints);
-
- // Expand each solution to the smaller problem by inserting the current
- // query parameter -> manifest parameter into the solution.
- for (const auto& existing_solution : solution_for_remainder) {
- std::map<std::string, std::string> updated_solution = existing_solution;
- updated_solution[query_constraint_name] =
- first_intent_filter_param_name;
- result.push_back(updated_solution);
- }
- }
-
- return result;
- }
-
- LocalModuleResolver* const local_module_resolver_;
- fuchsia::modular::FindModulesByTypesQuery const query_;
- fuchsia::modular::FindModulesByTypesResponse response_;
- // A cache of the parameter types for each parameter name in |query_|.
- std::map<std::string, std::vector<std::string>>
- parameter_types_cache_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FindModulesByTypesCall);
-};
-
-void LocalModuleResolver::FindModules(fuchsia::modular::FindModulesQuery query,
- FindModulesCallback callback) {
- operations_.Add(new FindModulesCall(this, std::move(query), callback));
-}
-
-void LocalModuleResolver::FindModulesByTypes(
- fuchsia::modular::FindModulesByTypesQuery query,
- FindModulesByTypesCallback callback) {
- operations_.Add(new FindModulesByTypesCall(this, std::move(query), callback));
-}
-
-void LocalModuleResolver::GetModuleManifest(
- std::string module_id, GetModuleManifestCallback callback) {
- auto found_handlers = FindHandlers(module_id);
- if (!found_handlers.empty()) {
- callback(CloneOptional(manifests_[*found_handlers.begin()]));
- return;
- }
-
- callback(nullptr);
-}
-
-namespace {
-bool StringStartsWith(const std::string& str, const std::string& prefix) {
- return str.compare(0, prefix.length(), prefix) == 0;
-}
-} // namespace
-
-void LocalModuleResolver::OnQuery(fuchsia::modular::UserInput query,
- OnQueryCallback done) {
- // TODO(thatguy): This implementation is bare-bones. Don't judge.
- // Before adding new member variables to support OnQuery() (and tying the
- // LocalModuleResolver internals up with what's needed for this method),
- // please split the index-building & querying portion of LocalModuleResolver
- // out into its own class. Then, make a new class to handle OnQuery() and
- // share the same index instance here and there.
- std::vector<fuchsia::modular::Proposal> proposals;
- if (query.text.empty()) {
- fuchsia::modular::QueryResponse response;
- response.proposals = std::move(proposals);
- done(std::move(response));
- return;
- }
-
- for (const auto& id_entry : manifests_) {
- const auto& manifest = id_entry.second;
- for (const auto& intent_filter : *manifest.intent_filters) {
- // Simply prefix match on the last element of the action.
- // actions have a convention of being namespaced like java classes:
- // com.google.subdomain.action
- std::string action = intent_filter.action;
- auto parts = fxl::SplitString(action, ".", fxl::kKeepWhitespace,
- fxl::kSplitWantAll);
- const auto& last_part = parts.back();
- if (StringStartsWith(intent_filter.action, query.text) ||
- StringStartsWith(last_part.ToString(), query.text)) {
- fuchsia::modular::Proposal proposal;
- proposal.id = manifest.binary;
- proposal.affinity.resize(0);
-
- fuchsia::modular::AddMod add_mod;
- add_mod.intent.handler = manifest.binary;
- add_mod.mod_name.push_back("root");
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- proposal.on_selected.push_back(std::move(command));
-
- proposal.display.headline =
- std::string("Go go gadget ") + last_part.ToString();
- proposal.display.subheadline = manifest.binary;
- proposal.display.color = 0xffffffff;
- proposal.display.annoyance = fuchsia::modular::AnnoyanceType::NONE;
-
- proposal.confidence = 1.0; // Yeah, super confident.
-
- proposals.push_back(std::move(proposal));
- }
- }
- }
-
- if (proposals.size() > 10) {
- proposals.resize(10);
- }
-
- fuchsia::modular::QueryResponse response;
- response.proposals = std::move(proposals);
- done(std::move(response));
-}
-
-void LocalModuleResolver::OnSourceIdle(const std::string& source_name) {
- auto res = ready_sources_.insert(source_name);
- if (!res.second) {
- // It's OK for us to get an idle notification twice from a repo. This
- // happens, for instance, if there's a network problem and we have to
- // re-establish it.
- return;
- }
-
- if (AllSourcesAreReady()) {
- // They are all ready. Bind any pending Connect() calls.
- for (auto& request : pending_bindings_) {
- bindings_.AddBinding(this, std::move(request));
- }
- pending_bindings_.clear();
- }
-}
-
-void LocalModuleResolver::OnNewManifestEntry(
- const std::string& source_name, std::string module_uri,
- fuchsia::modular::ModuleManifest new_manifest) {
- FXL_LOG(INFO) << "New Module manifest for binary " << module_uri << " with "
- << new_manifest.intent_filters->size() << " intent filters.";
- auto manifest_id = ManifestId(source_name, module_uri);
- // Add this new manifest info to our local index.
- if (manifests_.count(manifest_id) > 0) {
- // Remove this existing manifest first, then add it back in.
- OnRemoveManifestEntry(source_name, module_uri);
- }
- if (new_manifest.intent_filters->size() == 0) {
- new_manifest.intent_filters.resize(0);
- }
- auto ret = manifests_.emplace(manifest_id, std::move(new_manifest));
- FXL_CHECK(ret.second);
- const auto& manifest = ret.first->second;
- for (const auto& intent_filter : *manifest.intent_filters) {
- action_to_manifests_[intent_filter.action].insert(manifest_id);
-
- for (const auto& constraint : intent_filter.parameter_constraints) {
- parameter_type_and_name_to_manifests_[std::make_pair(constraint.type,
- constraint.name)]
- .insert(manifest_id);
- parameter_type_to_manifests_[constraint.type].insert(manifest_id);
- }
- }
-}
-
-void LocalModuleResolver::OnRemoveManifestEntry(const std::string& source_name,
- std::string module_uri) {
- ManifestId manifest_id(source_name, module_uri);
- auto it = manifests_.find(manifest_id);
- if (it == manifests_.end()) {
- FXL_LOG(WARNING) << "Asked to remove non-existent manifest: "
- << manifest_id;
- return;
- }
-
- const auto& manifest = it->second;
- for (const auto& intent_filter : *manifest.intent_filters) {
- action_to_manifests_[intent_filter.action].erase(manifest_id);
-
- for (const auto& constraint : intent_filter.parameter_constraints) {
- parameter_type_and_name_to_manifests_[std::make_pair(constraint.type,
- constraint.name)]
- .erase(manifest_id);
- parameter_type_to_manifests_[constraint.type].erase(manifest_id);
- }
- }
-
- manifests_.erase(manifest_id);
-}
-
-void LocalModuleResolver::PeriodicCheckIfSourcesAreReady() {
- if (!AllSourcesAreReady()) {
- for (const auto& it : sources_) {
- if (ready_sources_.count(it.first) == 0) {
- FXL_LOG(WARNING) << "Still waiting on source: " << it.first;
- }
- }
-
- if (already_checking_if_sources_are_ready_) return;
- already_checking_if_sources_are_ready_ = true;
- async::PostDelayedTask(
- async_get_default_dispatcher(),
- [weak_this = weak_factory_.GetWeakPtr()]() {
- if (weak_this) {
- weak_this->already_checking_if_sources_are_ready_ = false;
- weak_this->PeriodicCheckIfSourcesAreReady();
- }
- },
- zx::sec(10));
- }
-}
-
-} // namespace modular
diff --git a/bin/module_resolver/local_module_resolver.h b/bin/module_resolver/local_module_resolver.h
deleted file mode 100644
index e59e75b..0000000
--- a/bin/module_resolver/local_module_resolver.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_MODULE_RESOLVER_LOCAL_MODULE_RESOLVER_H_
-#define PERIDOT_BIN_MODULE_RESOLVER_LOCAL_MODULE_RESOLVER_H_
-
-#include <functional>
-#include <memory>
-#include <set>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/lib/module_manifest_source/module_manifest_source.h"
-
-namespace modular {
-
-class LocalModuleResolver : fuchsia::modular::ModuleResolver,
- fuchsia::modular::QueryHandler {
- public:
- LocalModuleResolver();
- ~LocalModuleResolver() override;
-
- // Adds a source of Module manifests to index. It is not allowed to call
- // AddSource() after Connect(). |name| must be unique.
- void AddSource(std::string name, std::unique_ptr<ModuleManifestSource> repo);
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::ModuleResolver> request);
-
- void BindQueryHandler(
- fidl::InterfaceRequest<fuchsia::modular::QueryHandler> request);
-
- // |ModuleResolver|
- void FindModules(fuchsia::modular::FindModulesQuery query,
- FindModulesCallback callback) override;
- // |ModuleResolver|
- void FindModulesByTypes(fuchsia::modular::FindModulesByTypesQuery query,
- FindModulesByTypesCallback callback) override;
- // |ModuleResolver|
- void GetModuleManifest(std::string module_id,
- GetModuleManifestCallback callback) override;
-
- private:
- class FindModulesCall;
- class FindModulesByTypesCall;
-
- using ModuleUri = std::string;
- using RepoSource = std::string;
- // We use the module URI to identify the module manifest.
- using ManifestId = std::tuple<RepoSource, ModuleUri>;
- using ParameterName = std::string;
- using ParameterType = std::string;
- using Action = std::string;
-
- std::set<ManifestId> FindHandlers(ModuleUri handler);
-
- // |fuchsia::modular::QueryHandler|
- void OnQuery(fuchsia::modular::UserInput query,
- OnQueryCallback done) override;
-
- void OnSourceIdle(const std::string& source_name);
- void OnNewManifestEntry(const std::string& source_name, std::string id_in,
- fuchsia::modular::ModuleManifest new_entry);
- void OnRemoveManifestEntry(const std::string& source_name, std::string id_in);
-
- void PeriodicCheckIfSourcesAreReady();
-
- bool AllSourcesAreReady() const {
- return ready_sources_.size() == sources_.size();
- }
-
- // TODO(thatguy): At some point, factor the index functions out of
- // LocalModuleResolver so that they can be re-used by the general all-modules
- // Ask handler.
- std::map<std::string, std::unique_ptr<ModuleManifestSource>> sources_;
- // Set of sources that have told us they are idle, meaning they have
- // sent us all manifests they knew about at construction time.
- std::set<std::string> ready_sources_;
- // Map of module manifest ID -> module manifest.
- using ManifestMap = std::map<ManifestId, fuchsia::modular::ModuleManifest>;
- ManifestMap manifests_;
-
- // action -> key in |manifests_|
- std::map<Action, std::set<ManifestId>> action_to_manifests_;
- // (parameter type, parameter name) -> key in |manifests_|
- std::map<std::pair<ParameterType, ParameterName>, std::set<ManifestId>>
- parameter_type_and_name_to_manifests_;
- // (parameter type) -> keys in |manifests_|.
- std::map<ParameterType, std::set<ManifestId>> parameter_type_to_manifests_;
-
- fidl::BindingSet<fuchsia::modular::ModuleResolver> bindings_;
- fidl::Binding<fuchsia::modular::QueryHandler> query_handler_binding_;
- // These are buffered until AllSourcesAreReady() == true.
- std::vector<fidl::InterfaceRequest<fuchsia::modular::ModuleResolver>>
- pending_bindings_;
-
- bool already_checking_if_sources_are_ready_;
-
- OperationCollection operations_;
-
- fxl::WeakPtrFactory<LocalModuleResolver> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LocalModuleResolver);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_MODULE_RESOLVER_LOCAL_MODULE_RESOLVER_H_
diff --git a/bin/module_resolver/local_module_resolver_unittest.cc b/bin/module_resolver/local_module_resolver_unittest.cc
deleted file mode 100644
index dcf08c7..0000000
--- a/bin/module_resolver/local_module_resolver_unittest.cc
+++ /dev/null
@@ -1,824 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/module_resolver/local_module_resolver.h"
-
-#include <lib/entity/cpp/json.h>
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fxl/files/file.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/testing/entity_resolver_fake.h"
-
-namespace modular {
-namespace {
-
-fuchsia::modular::IntentFilter MakeIntentFilter(
- std::string action,
- std::vector<fuchsia::modular::ParameterConstraint> param_constraints) {
- fuchsia::modular::IntentFilter f;
- f.action = action;
- f.parameter_constraints = param_constraints;
- return f;
-}
-
-class TestManifestSource : public ModuleManifestSource {
- public:
- IdleFn idle;
- NewEntryFn add;
- RemovedEntryFn remove;
-
- private:
- void Watch(async_dispatcher_t* dispatcher, IdleFn idle_fn, NewEntryFn new_fn,
- RemovedEntryFn removed_fn) override {
- idle = std::move(idle_fn);
- add = std::move(new_fn);
- remove = std::move(removed_fn);
- }
-};
-
-class FindModulesTest : public gtest::TestLoopFixture {
- protected:
- void ResetResolver() {
- // TODO: |impl_| will fail to resolve any queries whose parameters are
- // entity references.
- impl_ = std::make_unique<LocalModuleResolver>();
- for (auto entry : test_sources_) {
- impl_->AddSource(entry.first,
- std::unique_ptr<ModuleManifestSource>(entry.second));
- }
- test_sources_.clear();
- impl_->Connect(resolver_.NewRequest());
- }
-
- TestManifestSource* AddSource(std::string name) {
- // Ownership given to |impl_| in ResetResolver().
- auto ptr = new TestManifestSource;
- test_sources_.emplace(name, ptr);
- return ptr;
- }
-
- void FindModules(fuchsia::modular::FindModulesQuery query) {
- bool got_response = false;
- resolver_->FindModules(
- std::move(query),
- [this, &got_response](fuchsia::modular::FindModulesResponse response) {
- got_response = true;
- response.Clone(&response_);
- });
- RunLoopUntilIdle();
- ASSERT_TRUE(got_response);
- }
-
- const std::vector<fuchsia::modular::FindModulesResult>& results() const {
- return response_.results;
- }
-
- class QueryBuilder {
- public:
- QueryBuilder() = delete;
-
- QueryBuilder(std::string action)
- : query(fuchsia::modular::FindModulesQuery()) {
- query.action = action;
- query.parameter_constraints.resize(0);
- }
-
- fuchsia::modular::FindModulesQuery build() { return std::move(query); }
-
- QueryBuilder& AddParameter(std::string name,
- std::vector<std::string> types) {
- fuchsia::modular::FindModulesParameterConstraint constraint;
- constraint.param_name = name;
- constraint.param_types = types;
- query.parameter_constraints.push_back(std::move(constraint));
- return *this;
- }
-
- private:
- fuchsia::modular::FindModulesQuery query;
- };
-
- std::unique_ptr<LocalModuleResolver> impl_;
-
- std::map<std::string, ModuleManifestSource*> test_sources_;
- fuchsia::modular::ModuleResolverPtr resolver_;
-
- fuchsia::modular::FindModulesResponse response_;
-};
-
-class FindModulesByTypesTest : public gtest::TestLoopFixture {
- protected:
- void ResetResolver() {
- // TODO: |impl_| will fail to resolve any queries whose parameters are
- // entity references.
- impl_ = std::make_unique<LocalModuleResolver>();
- for (auto entry : test_sources_) {
- impl_->AddSource(entry.first,
- std::unique_ptr<ModuleManifestSource>(entry.second));
- }
- test_sources_.clear();
- impl_->Connect(resolver_.NewRequest());
- }
-
- TestManifestSource* AddSource(std::string name) {
- // Ownership given to |impl_| in ResetResolver().
- auto ptr = new TestManifestSource;
- test_sources_.emplace(name, ptr);
- return ptr;
- }
-
- void FindModulesByTypes(fuchsia::modular::FindModulesByTypesQuery query) {
- bool got_response = false;
- resolver_->FindModulesByTypes(
- std::move(query),
- [this,
- &got_response](fuchsia::modular::FindModulesByTypesResponse response) {
- got_response = true;
- response.Clone(&response_);
- });
- RunLoopUntilIdle();
- ASSERT_TRUE(got_response);
- }
-
- const std::vector<fuchsia::modular::FindModulesByTypesResult>& results()
- const {
- return response_.results;
- }
-
- class QueryBuilder {
- public:
- fuchsia::modular::FindModulesByTypesQuery build() {
- return std::move(query);
- }
-
- QueryBuilder& AddParameter(std::string name,
- std::vector<std::string> types) {
- fuchsia::modular::FindModulesByTypesParameterConstraint constraint;
- constraint.constraint_name = name;
- constraint.param_types = types;
- query.parameter_constraints.push_back(std::move(constraint));
- return *this;
- }
-
- private:
- fuchsia::modular::FindModulesByTypesQuery query;
- };
-
- std::string GetMappingFromQuery(
- const std::vector<
- fuchsia::modular::FindModulesByTypesParameterMapping>& mapping,
- std::string query_constraint_name) {
- for (auto& item : mapping) {
- if (item.query_constraint_name == query_constraint_name) {
- return item.result_param_name;
- }
- }
- return "";
- }
-
- std::unique_ptr<LocalModuleResolver> impl_;
-
- std::map<std::string, ModuleManifestSource*> test_sources_;
- fuchsia::modular::ModuleResolverPtr resolver_;
-
- fuchsia::modular::FindModulesByTypesResponse response_;
-};
-
-TEST_F(FindModulesTest, Null) {
- auto source = AddSource("test");
- ResetResolver();
-
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "id1";
- entry.intent_filters.push_back(MakeIntentFilter("verb wont match", {}));
- source->add("1", std::move(entry));
- source->idle();
-
- FindModules(QueryBuilder("no matchy!").build());
-
- // The Resolver returns an empty candidate list
- ASSERT_EQ(0lu, results().size());
-}
-
-TEST_F(FindModulesTest, Simpleaction) {
- // Also add Modules from multiple different sources.
- auto source1 = AddSource("test1");
- auto source2 = AddSource("test2");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1", {}));
- source1->add("module1", std::move(entry));
- }
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module2";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1", {}));
- source2->add("module2", std::move(entry));
- }
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module3";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.exist.vinfinity", {}));
- source1->add("module3", std::move(entry));
- }
-
- source1->idle();
- source2->idle();
-
- // This is mostly the contents of the FindModules() convenience function
- // above. It's copied here so that we can call source2->idle() before
- // RunLoopUntilIdle() for this case only.
- bool got_response = false;
- resolver_->FindModules(
- QueryBuilder("com.google.fuchsia.navigate.v1").build(),
- [this, &got_response](fuchsia::modular::FindModulesResponse response) {
- got_response = true;
- response.Clone(&response_);
- });
-
- // Waiting until here to set |source2| as idle shows that FindModules() is
- // effectively delayed until all sources have indicated idle ("module2" is in
- // |source2|).
- source2->idle();
- RunLoopUntilIdle();
- ASSERT_TRUE(got_response);
-
- ASSERT_EQ(2lu, results().size());
- EXPECT_EQ("module1", results().at(0).module_id);
- EXPECT_EQ("module2", results().at(1).module_id);
-
- // Remove the entries and we should see no more results. Our
- // TestManifestSource implementation above doesn't send its tasks to the
- // task_runner so we don't have to wait.
- source1->remove("module1");
- source2->remove("module2");
-
- FindModules(QueryBuilder("com.google.fuchsia.navigate.v1").build());
- ASSERT_EQ(0lu, results().size());
-}
-
-TEST_F(FindModulesTest, SimpleParameterTypes) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter1;
- parameter1.name = "start";
- parameter1.type = "foo";
- fuchsia::modular::ParameterConstraint parameter2;
- parameter2.name = "destination";
- parameter2.type = "baz";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1",
- {std::move(parameter1), std::move(parameter2)}));
- source->add("1", std::move(entry));
- }
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module2";
- fuchsia::modular::ParameterConstraint parameter1;
- parameter1.name = "start";
- parameter1.type = "frob";
- fuchsia::modular::ParameterConstraint parameter2;
- parameter2.name = "destination";
- parameter2.type = "froozle";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1",
- {std::move(parameter1), std::move(parameter2)}));
- source->add("2", std::move(entry));
- }
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module3";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "with";
- parameter.type = "compantionCube";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.exist.vinfinity", {std::move(parameter)}));
- source->add("3", std::move(entry));
- }
- source->idle();
-
- // Either 'foo' or 'tangoTown' would be acceptible types. Only 'foo' will
- // actually match.
- FindModules(QueryBuilder("com.google.fuchsia.navigate.v1")
- .AddParameter("start", {"foo", "tangoTown"})
- .build());
- ASSERT_EQ(1lu, results().size());
- EXPECT_EQ("module1", results().at(0).module_id);
-
- // This one will match one of the two parameter constraints on module1, but
- // not both, so no match at all is expected.
- FindModules(QueryBuilder("com.google.fuchsia.navigate.v1")
- .AddParameter("start", {"foo", "tangoTown"})
- .AddParameter("destination", {"notbaz"})
- .build());
- ASSERT_EQ(0lu, results().size());
-
- // Given parameter of type "frob", find a module with action
- // com.google.fuchsia.navigate.v1.
- FindModules(QueryBuilder("com.google.fuchsia.navigate.v1")
- .AddParameter("start", {"frob"})
- .build());
- ASSERT_EQ(1u, results().size());
- auto& res = results().at(0);
- EXPECT_EQ("module2", res.module_id);
-}
-
-TEST_F(FindModulesTest, ReAddExistingEntries) {
- // Add the same entry twice, to simulate what could happen during a network
- // reconnect, and show that the Module is still available.
- auto source = AddSource("test1");
- ResetResolver();
-
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "id1";
- entry.intent_filters.push_back(MakeIntentFilter("action1", {}));
-
- fuchsia::modular::ModuleManifest entry1;
- entry.Clone(&entry1);
- source->add("1", std::move(entry1));
- source->idle();
- FindModules(QueryBuilder("action1").build());
- ASSERT_EQ(1lu, results().size());
- EXPECT_EQ("id1", results().at(0).module_id);
-
- fuchsia::modular::ModuleManifest entry2;
- entry.Clone(&entry2);
- source->add("1", std::move(entry2));
- FindModules(QueryBuilder("action1").build());
- ASSERT_EQ(1lu, results().size());
- EXPECT_EQ("id1", results().at(0).module_id);
-}
-
-// Tests that a query that does not contain a action or a URL matches a
-// parameter with the correct types.
-TEST_F(FindModulesByTypesTest, MatchingParameterWithNoactionOrUrl) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "start";
- parameter.type = "foo";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1", {parameter}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(
- QueryBuilder().AddParameter("start", {"foo", "bar"}).build());
-
- ASSERT_EQ(1lu, results().size());
- EXPECT_EQ("module1", results().at(0).module_id);
-}
-
-// Tests that a query that does not contain a action or a URL matches when the
-// parameter types do, even if the parameter name does not.
-TEST_F(FindModulesByTypesTest, CorrectParameterTypeWithNoactionOrUrl) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "end";
- parameter.type = "foo";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1", {parameter}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(
- QueryBuilder().AddParameter("start", {"foo", "bar"}).build());
-
- ASSERT_EQ(1lu, results().size());
- EXPECT_EQ("module1", results().at(0).module_id);
-}
-
-// Tests that a query that does not contain a action or a URL returns results
-// for multiple matching entries.
-TEST_F(FindModulesByTypesTest,
- CorrectParameterTypeWithNoactionOrUrlMultipleMatches) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "end";
- parameter.type = "foo";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v1", {std::move(parameter)}));
- source->add("1", std::move(entry));
- }
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module2";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "end";
- parameter.type = "foo";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v2", {std::move(parameter)}));
- source->add("2", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(
- QueryBuilder().AddParameter("start", {"foo", "bar"}).build());
-
- ASSERT_EQ(2lu, results().size());
- EXPECT_EQ("module1", results().at(0).module_id);
- EXPECT_EQ("module2", results().at(1).module_id);
-}
-
-// Tests that a query that does not contain a action or a URL does not match
-// when the parameter types don't match.
-TEST_F(FindModulesByTypesTest, IncorrectParameterTypeWithNoactionOrUrl) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "start";
- parameter.type = "not";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v1", {std::move(parameter)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(
- QueryBuilder().AddParameter("start", {"foo", "bar"}).build());
-
- EXPECT_EQ(0lu, results().size());
-}
-
-// Tests that a query without a action or url, that contains more parameters
-// than the potential result, still returns that result.
-TEST_F(FindModulesByTypesTest, QueryWithMoreParametersThanEntry) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "start";
- parameter.type = "gps";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v1", {std::move(parameter)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(QueryBuilder()
- .AddParameter("start", {"gps", "bar"})
- .AddParameter("end", {"foo", "bar"})
- .build());
-
- EXPECT_EQ(1lu, results().size());
-}
-
-// Tests that for a query with multiple parameters, each parameter gets assigned
-// to the correct module parameters.
-TEST_F(FindModulesByTypesTest, QueryWithoutActionAndMultipleParameters) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter1;
- parameter1.name = "start";
- parameter1.type = "gps";
- fuchsia::modular::ParameterConstraint parameter2;
- parameter2.name = "end";
- parameter2.type = "not_gps";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1",
- {std::move(parameter1), std::move(parameter2)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(QueryBuilder()
- .AddParameter("parameter1", {"gps"})
- .AddParameter("parameter2", {"not_gps"})
- .build());
-
- ASSERT_EQ(1lu, results().size());
- auto& result = results().at(0);
-
- EXPECT_EQ("start",
- GetMappingFromQuery(result.parameter_mappings, "parameter1"));
- EXPECT_EQ("end",
- GetMappingFromQuery(result.parameter_mappings, "parameter2"));
-}
-
-// Tests that when there are multiple valid mappings of query parameter types to
-// entities, all such combinations are returned.
-TEST_F(FindModulesByTypesTest, FindModulesByTypeWithTwoParametersOfSameType) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter1;
- parameter1.name = "start";
- parameter1.type = "gps";
- fuchsia::modular::ParameterConstraint parameter2;
- parameter2.name = "end";
- parameter2.type = "gps";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1",
- {std::move(parameter1), std::move(parameter2)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(QueryBuilder()
- .AddParameter("parameter1", {"gps"})
- .AddParameter("parameter2", {"gps"})
- .build());
-
- EXPECT_EQ(2lu, results().size());
-
- bool found_first_mapping = false;
- bool found_second_mapping = false;
-
- for (const auto& result : results()) {
- bool start_mapped_to_p1 =
- GetMappingFromQuery(result.parameter_mappings, "parameter1") == "start";
-
- bool start_mapped_to_p2 =
- GetMappingFromQuery(result.parameter_mappings, "parameter2") == "start";
-
- bool end_mapped_to_p1 =
- GetMappingFromQuery(result.parameter_mappings, "parameter1") == "end";
-
- bool end_mapped_to_p2 =
- GetMappingFromQuery(result.parameter_mappings, "parameter2") == "end";
-
- found_first_mapping |= start_mapped_to_p1 && end_mapped_to_p2;
- found_second_mapping |= start_mapped_to_p2 && end_mapped_to_p1;
- }
-
- EXPECT_TRUE(found_first_mapping);
- EXPECT_TRUE(found_second_mapping);
-}
-
-// Tests that a query with three parameters of the same type matches an entry
-// with three expected parameters in 6 different ways.
-TEST_F(FindModulesByTypesTest, QueryWithoutActionAndThreeParametersOfSameType) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter1;
- parameter1.name = "start";
- parameter1.type = "gps";
- fuchsia::modular::ParameterConstraint parameter2;
- parameter2.name = "end";
- parameter2.type = "gps";
- fuchsia::modular::ParameterConstraint parameter3;
- parameter3.name = "middle";
- parameter3.type = "gps";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v1",
- {std::move(parameter1), std::move(parameter2), std::move(parameter3)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(QueryBuilder()
- .AddParameter("parameter1", {"gps"})
- .AddParameter("parameter2", {"gps"})
- .AddParameter("parameter3", {"gps"})
- .build());
-
- EXPECT_EQ(6lu, results().size());
-}
-
-// Tests that a query with three parameters of the same type matches an entry
-// with two expected parameters in 6 different ways.
-TEST_F(FindModulesByTypesTest,
- QueryWithoutActionAndDifferentNumberOfParametersInQueryVsEntry) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter1;
- parameter1.name = "start";
- parameter1.type = "gps";
- fuchsia::modular::ParameterConstraint parameter2;
- parameter2.name = "end";
- parameter2.type = "gps";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1",
- {std::move(parameter1), std::move(parameter2)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(QueryBuilder()
- .AddParameter("parameter1", {"gps"})
- .AddParameter("parameter2", {"gps"})
- .AddParameter("parameter3", {"gps"})
- .build());
-
- EXPECT_EQ(6lu, results().size());
-}
-
-// Tests that a query without a action does not match a module that requires a
-// proper superset of the query parameters.
-TEST_F(FindModulesByTypesTest,
- QueryWithoutActionWithEntryContainingProperSuperset) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter1;
- parameter1.name = "start";
- parameter1.type = "gps";
- fuchsia::modular::ParameterConstraint parameter2;
- parameter2.name = "end";
- parameter2.type = "gps";
- entry.intent_filters.push_back(
- MakeIntentFilter("com.google.fuchsia.navigate.v1",
- {std::move(parameter1), std::move(parameter2)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- // The query only contains an fuchsia::modular::Entity for "parameter1", but
- // the module manifest requires two parameters of type "gps."
- FindModulesByTypes(
- QueryBuilder().AddParameter("parameter1", {"gps"}).build());
-
- EXPECT_EQ(0lu, results().size());
-}
-
-// Tests that a query without a action does not match an entry where the
-// parameter types are incompatible.
-TEST_F(FindModulesByTypesTest, QueryWithoutActionIncompatibleParameterTypes) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "start";
- parameter.type = "gps";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v1", {std::move(parameter)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- // The query only contains an fuchsia::modular::Entity for "parameter1", but
- // the module manifest requires two parameters of type "gps."
- FindModulesByTypes(
- QueryBuilder().AddParameter("parameter1", {"not_gps"}).build());
-
- EXPECT_EQ(0lu, results().size());
-}
-
-// Tests that a query with a action requires parameter name and type to match
-// (i.e. does not behave like action-less matching where the parameter names are
-// disregarded).
-TEST_F(FindModulesTest, QueryWithActionMatchesBothParameterNamesAndTypes) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "end";
- parameter.type = "foo";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v1", {std::move(parameter)}));
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModules(QueryBuilder("com.google.fuchsia.navigate.v1")
- .AddParameter("start", {"foo", "baz"})
- .build());
-
- EXPECT_EQ(0lu, results().size());
-}
-
-TEST_F(FindModulesTest, MultipleIntentFilters) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "end";
- parameter.type = "foo";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v1", {modular::CloneStruct(parameter)}));
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v2", {modular::CloneStruct(parameter)}));
-
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModules(QueryBuilder("com.google.fuchsia.navigate.v1")
- .AddParameter("end", {"foo"})
- .build());
- ASSERT_EQ(1lu, results().size());
- EXPECT_EQ("module1", results().at(0).module_id);
-
- FindModules(QueryBuilder("com.google.fuchsia.navigate.v2")
- .AddParameter("end", {"foo"})
- .build());
- ASSERT_EQ(1lu, results().size());
- EXPECT_EQ("module1", results().at(0).module_id);
-
- FindModules(QueryBuilder("com.google.fuchsia.navigate.v3")
- .AddParameter("end", {"foo"})
- .build());
- ASSERT_EQ(0lu, results().size());
-}
-
-TEST_F(FindModulesByTypesTest, MultipleIntentFilters) {
- auto source = AddSource("test");
- ResetResolver();
-
- {
- fuchsia::modular::ModuleManifest entry;
- entry.binary = "module1";
- fuchsia::modular::ParameterConstraint parameter;
- parameter.name = "end";
- parameter.type = "foo";
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v1", {modular::CloneStruct(parameter)}));
- entry.intent_filters.push_back(MakeIntentFilter(
- "com.google.fuchsia.navigate.v2", {modular::CloneStruct(parameter)}));
-
- source->add("1", std::move(entry));
- }
-
- source->idle();
-
- FindModulesByTypes(QueryBuilder().AddParameter("end", {"foo"}).build());
-
- ASSERT_EQ(2lu, results().size());
- // expected action =>.
- std::set<std::string> actual_actions;
- for (size_t i = 0; i < 2u; i++) {
- EXPECT_EQ("module1", results().at(i).module_id);
- actual_actions.insert(results().at(i).action);
- }
- EXPECT_EQ(1u, actual_actions.count("com.google.fuchsia.navigate.v1"));
- EXPECT_EQ(1u, actual_actions.count("com.google.fuchsia.navigate.v2"));
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/module_resolver/meta/module_resolver.cmx b/bin/module_resolver/meta/module_resolver.cmx
deleted file mode 100644
index 352ce55..0000000
--- a/bin/module_resolver/meta/module_resolver.cmx
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "pkgfs": [
- "packages"
- ],
- "services": [
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.IntelligenceServices",
- "fuchsia.net.oldhttp.HttpService"
- ],
- "system": [
- "data/initial_module_packages"
- ]
- }
-}
diff --git a/bin/module_resolver/module_package_indexer/BUILD.gn b/bin/module_resolver/module_package_indexer/BUILD.gn
deleted file mode 100644
index c7bc507..0000000
--- a/bin/module_resolver/module_package_indexer/BUILD.gn
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("module_package_indexer") {
- sources = [
- "main.cc",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/lib:maxwell_internal",
- "//peridot/lib/module_manifest_source:package_util",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fdio",
- ]
-
- meta = [
- {
- path = "meta/module_package_indexer.cmx"
- dest = "module_package_indexer.cmx"
- },
- ]
-}
diff --git a/bin/module_resolver/module_package_indexer/main.cc b/bin/module_resolver/module_package_indexer/main.cc
deleted file mode 100644
index 83a5cdc..0000000
--- a/bin/module_resolver/module_package_indexer/main.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <dirent.h>
-#include <glob.h>
-#include <sys/types.h>
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include <fuchsia/maxwell/internal/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fdio/util.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/log_settings_command_line.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "peridot/lib/module_manifest_source/package_util.h"
-
-using ::fuchsia::maxwell::internal::ModulePackageIndexer;
-using ::fuchsia::maxwell::internal::ModulePackageIndexerPtr;
-
-// This function finds the ModulePackageIndexer fidl service that the
-// module_resolver runs.
-std::string FindModulePackageIndexerService() {
- // The ModulePackageIndexer service is run by the module_resolver component
- // under current sys realm. The structured path of to this service is:
- // /hub//r/user-<userid>/<koid>/c/module_resolver/<koid>/out/debug
- auto glob_str =
- fxl::StringPrintf("/hub/r/user-*/*/c/module_resolver/*/out/debug/%s",
- ModulePackageIndexer::Name_);
-
- glob_t globbuf;
- std::string service_path;
- FXL_CHECK(glob(glob_str.data(), 0, nullptr, &globbuf) == 0);
- if (globbuf.gl_pathc > 0) {
- service_path = globbuf.gl_pathv[0];
- }
- if (globbuf.gl_pathc > 1) {
- FXL_DLOG(WARNING) << "Found more than one module resolver.";
- }
- globfree(&globbuf);
- return service_path;
-}
-
-int main(int argc, const char** argv) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
-
- const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- fxl::SetLogSettingsFromCommandLine(command_line);
-
- if (command_line.positional_args().size() != 2) {
- std::cerr << "Usage: " << command_line.argv0()
- << " <package name> <version>";
- return 1;
- }
-
- auto service_path = FindModulePackageIndexerService();
- FXL_CHECK(!service_path.empty())
- << "Could not find a running module resolver. Is the user logged in?";
-
- ModulePackageIndexerPtr indexer;
- auto req_handle = indexer.NewRequest().TakeChannel();
- if (fdio_service_connect(service_path.c_str(), req_handle.get()) != ZX_OK) {
- FXL_LOG(FATAL) << "Could not connect to service " << service_path;
- return 1;
- }
-
- const auto& package_name = command_line.positional_args()[0];
- const auto& package_version = command_line.positional_args()[1];
- indexer->IndexManifest(
- package_name,
- modular::GetModuleManifestPathFromPackage(package_name, package_version));
-
- return 0;
-}
diff --git a/bin/module_resolver/module_package_indexer/meta/module_package_indexer.cmx b/bin/module_resolver/module_package_indexer/meta/module_package_indexer.cmx
deleted file mode 100644
index 7fa3eae..0000000
--- a/bin/module_resolver/module_package_indexer/meta/module_package_indexer.cmx
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [
- "shell"
- ],
- "services": []
- }
-}
diff --git a/bin/module_resolver/module_resolver_main.cc b/bin/module_resolver/module_resolver_main.cc
deleted file mode 100644
index f44cf3d..0000000
--- a/bin/module_resolver/module_resolver_main.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/net/oldhttp/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/entity/cpp/json.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/module_resolver/local_module_resolver.h"
-#include "peridot/lib/module_manifest_source/firebase_source.h"
-#include "peridot/lib/module_manifest_source/module_package_source.h"
-
-namespace modular {
-namespace {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-class ModuleResolverApp {
- public:
- ModuleResolverApp(component::StartupContext* const context, bool is_test) {
- resolver_impl_ = std::make_unique<LocalModuleResolver>();
- // Set up |resolver_impl_|.
- resolver_impl_->AddSource("module_package",
- std::make_unique<ModulePackageSource>(context));
-
- context->outgoing().AddPublicService<fuchsia::modular::ModuleResolver>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::ModuleResolver> request) {
- resolver_impl_->Connect(std::move(request));
- });
- }
-
- void Terminate(const std::function<void()>& done) { done(); }
-
- private:
- std::unique_ptr<LocalModuleResolver> resolver_impl_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ModuleResolverApp);
-};
-
-} // namespace
-} // namespace modular
-
-const char kUsage[] = R"USAGE(%s [--test])USAGE";
-
-int main(int argc, const char** argv) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- if (command_line.HasOption("help")) {
- printf(kUsage, argv[0]);
- return 0;
- }
- auto is_test = command_line.HasOption("test");
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AppDriver<modular::ModuleResolverApp> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<modular::ModuleResolverApp>(context.get(), is_test),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/bin/module_resolver/type_inference.cc b/bin/module_resolver/type_inference.cc
deleted file mode 100644
index 9520b1d..0000000
--- a/bin/module_resolver/type_inference.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/module_resolver/type_inference.h"
-
-#include <string>
-#include <vector>
-
-#include <lib/async/cpp/operation.h>
-#include <lib/entity/cpp/json.h>
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/type_converter.h>
-
-namespace modular {
-
-ParameterTypeInferenceHelper::ParameterTypeInferenceHelper(
- fuchsia::modular::EntityResolverPtr entity_resolver)
- : entity_resolver_(std::move(entity_resolver)) {}
-
-ParameterTypeInferenceHelper::~ParameterTypeInferenceHelper() = default;
-
-class ParameterTypeInferenceHelper::GetParameterTypesCall
- : public Operation<std::vector<std::string>> {
- public:
- GetParameterTypesCall(fuchsia::modular::EntityResolver* entity_resolver,
- const fidl::StringPtr& entity_reference,
- ResultCall result)
- : Operation("ParameterTypeInferenceHelper::GetParameterTypesCall",
- std::move(result)),
- entity_resolver_(entity_resolver),
- entity_reference_(entity_reference) {}
-
- void Run() {
- entity_resolver_->ResolveEntity(entity_reference_, entity_.NewRequest());
- entity_->GetTypes([this](const fidl::VectorPtr<fidl::StringPtr>& types) {
- Done(fxl::To<std::vector<std::string>>(types));
- });
- }
-
- private:
- fuchsia::modular::EntityResolver* const entity_resolver_;
- fidl::StringPtr const entity_reference_;
- fuchsia::modular::EntityPtr entity_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(GetParameterTypesCall);
-};
-
-void ParameterTypeInferenceHelper::GetParameterTypes(
- const fuchsia::modular::ResolverParameterConstraint& parameter_constraint,
- const std::function<void(std::vector<std::string>)>& result_callback) {
- if (parameter_constraint.is_entity_type()) {
- result_callback(
- std::vector<std::string>(parameter_constraint.entity_type()->begin(),
- parameter_constraint.entity_type()->end()));
- } else if (parameter_constraint.is_json()) {
- std::vector<std::string> types;
- if (!ExtractEntityTypesFromJson(parameter_constraint.json(), &types)) {
- FXL_LOG(WARNING) << "Mal-formed JSON in parameter: "
- << parameter_constraint.json();
- result_callback({});
- } else {
- result_callback(types);
- }
- } else if (parameter_constraint.is_entity_reference()) {
- operation_collection_.Add(new GetParameterTypesCall(
- entity_resolver_.get(), parameter_constraint.entity_reference(),
- result_callback));
- } else if (parameter_constraint.is_link_info()) {
- if (parameter_constraint.link_info().allowed_types) {
- std::vector<std::string> types(
- parameter_constraint.link_info()
- .allowed_types->allowed_entity_types->begin(),
- parameter_constraint.link_info()
- .allowed_types->allowed_entity_types->end());
- result_callback(std::move(types));
- } else if (parameter_constraint.link_info().content_snapshot) {
- // TODO(thatguy): See if there's an fuchsia::modular::Entity reference on
- // the fuchsia::modular::Link. If so, get the types from that. If
- // resolution results in a Module being started, this
- // fuchsia::modular::Link should have its allowed types constrained, since
- // *another* Module is now relying on a small set of types being set.
- // Consider doing this when we move type extraction to the Framework and
- // simplify the Resolver.
- std::string entity_reference;
- if (EntityReferenceFromJson(
- parameter_constraint.link_info().content_snapshot,
- &entity_reference)) {
- operation_collection_.Add(new GetParameterTypesCall(
- entity_resolver_.get(), entity_reference, result_callback));
- }
- }
- } else {
- FXL_NOTREACHED();
- }
-}
-
-} // namespace modular
diff --git a/bin/module_resolver/type_inference.h b/bin/module_resolver/type_inference.h
deleted file mode 100644
index f84a445..0000000
--- a/bin/module_resolver/type_inference.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_MODULE_RESOLVER_TYPE_INFERENCE_H_
-#define PERIDOT_BIN_MODULE_RESOLVER_TYPE_INFERENCE_H_
-
-#include <string>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-namespace modular {
-
-class ParameterTypeInferenceHelper {
- public:
- ParameterTypeInferenceHelper(
- fuchsia::modular::EntityResolverPtr entity_resolver);
- ~ParameterTypeInferenceHelper();
-
- // Returns a list of types represented in |parameter_constraint|. Chooses the
- // correct process for type extraction based on the type of Parameter.
- void GetParameterTypes(
- const fuchsia::modular::ResolverParameterConstraint& parameter_constraint,
- const std::function<void(std::vector<std::string>)>& result_callback);
-
- private:
- class GetParameterTypesCall;
-
- fuchsia::modular::EntityResolverPtr entity_resolver_;
- OperationCollection operation_collection_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ParameterTypeInferenceHelper);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_MODULE_RESOLVER_TYPE_INFERENCE_H_
diff --git a/bin/sessionctl/BUILD.gn b/bin/sessionctl/BUILD.gn
deleted file mode 100644
index 7bdf776..0000000
--- a/bin/sessionctl/BUILD.gn
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-import("//peridot/build/tests_package.gni")
-
-executable_package("sessionctl") {
- # We do this only to have `sessionctl` appear in the shell's
- # PATH. When a solution to this is available, remove this line
- # and uncomment the "meta =" stanza below.
- deprecated_system_image = true
-
- sources = [
- "main.cc",
- ]
-
- deps = [
- ":lib",
- "//garnet/public/lib/fxl",
- "//peridot/lib/rapidjson",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/lib/async/cpp:future",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fdio",
- ]
-
- # meta = [
- # {
- # path = "meta/sessionctl.cmx"
- # dest = "sessionctl.cmx"
- # },
- # ]
-}
-
-source_set("lib") {
- sources = [
- "logger.cc",
- "logger.h",
- "session_ctl_app.cc",
- "session_ctl_app.h",
- "session_ctl_constants.h",
- ]
-
- deps = [
- "//peridot/lib/rapidjson",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/lib/async/cpp:future",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable("sessionctl_unittest") {
- testonly = true
-
- sources = [
- "session_ctl_app_unittest.cc",
- ]
-
- deps = [
- ":lib",
- "//peridot/bin/sessionmgr/puppet_master:puppet_master_impl",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:test_story_command_executor",
- "//peridot/lib/testing:test_with_session_storage",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-tests_package("sessionctl_unittests") {
- deps = [
- ":sessionctl_unittest",
- ]
-}
diff --git a/bin/sessionctl/logger.cc b/bin/sessionctl/logger.cc
deleted file mode 100644
index 9cfca00..0000000
--- a/bin/sessionctl/logger.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionctl/logger.h"
-#include "peridot/bin/sessionctl/session_ctl_constants.h"
-
-namespace modular {
-
-const char kSuccessString[] = "success";
-const char kCommandString[] = "command";
-
-// Key strings for JSON output.
-const char kParamsKeyString[] = "params";
-const char kStoriesKeyString[] = "stories";
-
-Logger::Logger(bool json_out) : json_out_(json_out) {}
-
-void Logger::LogError(const std::string& command,
- const std::string& error) const {
- if (json_out_) {
- rapidjson::Document document;
- document.SetObject();
-
- document.AddMember(kSuccessString, false, document.GetAllocator());
- document.AddMember(kCommandString, command, document.GetAllocator());
- document.AddMember("error", error, document.GetAllocator());
-
- std::cout << JsonValueToPrettyString(document) << std::endl;
- } else {
- std::cout << error << std::endl;
- }
-}
-
-void Logger::Log(const std::string& command,
- const std::vector<std::string>& params) const {
- std::stringstream output;
-
- if (json_out_) {
- std::cout << GenerateJsonLogString(command, params) << std::endl;
- } else {
- if (command == kListStoriesCommandString) {
- output << "Stories in this session:" << std::endl;
- }
-
- for (auto& param : params) {
- output << param << std::endl;
- }
-
- std::cout << output.str() << std::endl;
- }
-}
-
-void Logger::Log(const std::string& command,
- const std::map<std::string, std::string>& params) const {
- if (json_out_) {
- std::cout << GenerateJsonLogString(command, params) << std::endl;
- } else {
- std::cout << GenerateLogString(command, params) << std::endl;
- }
-}
-
-std::string Logger::GenerateJsonLogString(
- const std::string& command, const std::vector<std::string>& params) const {
- rapidjson::Document document = GetDocument(command);
-
- // Generate array of |params| strings.
- rapidjson::Document stories;
- stories.SetArray();
- for (auto& param : params) {
- rapidjson::Value story;
- story.SetString(param.data(), param.size());
- stories.PushBack(story, stories.GetAllocator());
- }
-
- // Determine what the strings in |params| represent.
- rapidjson::Value key;
- if (command == kListStoriesCommandString) {
- key.SetString(kStoriesKeyString);
- } else {
- key.SetString(kParamsKeyString);
- }
-
- document.AddMember(key, stories, document.GetAllocator());
- return JsonValueToPrettyString(document);
-}
-
-std::string Logger::GenerateJsonLogString(
- const std::string& command,
- const std::map<std::string, std::string>& params) const {
- rapidjson::Document document = GetDocument(command);
-
- // Generate a document containing |params| keys and values.
- rapidjson::Document paramsJson;
- paramsJson.SetObject();
- for (const auto& p : params) {
- rapidjson::Value name;
- name.SetString(p.first.data(), p.first.size());
-
- rapidjson::Value value;
- value.SetString(p.second.data(), p.second.size());
- paramsJson.AddMember(name, value, paramsJson.GetAllocator());
- }
-
- document.AddMember(kParamsKeyString, paramsJson, document.GetAllocator());
- return JsonValueToPrettyString(document);
-}
-
-rapidjson::Document Logger::GetDocument(const std::string& command) const {
- rapidjson::Document document;
- document.SetObject();
- document.AddMember(kSuccessString, true, document.GetAllocator());
- document.AddMember(kCommandString, command, document.GetAllocator());
- return document;
-}
-
-std::string Logger::GenerateLogString(
- const std::string& command,
- const std::map<std::string, std::string>& params) const {
- std::stringstream output;
-
- if (command == kDeleteStoryCommandString) {
- output << "Deleted";
- } else {
- if (command == kAddModCommandString) {
- output << "Added";
- } else if (command == kRemoveModCommandString) {
- output << "Removed";
- }
-
- output << " mod_name: " << params.at(kModNameFlagString).c_str() << " in";
- }
-
- output << " story_name: " << params.at(kStoryNameFlagString).c_str();
- return output.str();
-}
-
-} // namespace modular
diff --git a/bin/sessionctl/logger.h b/bin/sessionctl/logger.h
deleted file mode 100644
index b5235eb..0000000
--- a/bin/sessionctl/logger.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONCTL_LOGGER_H_
-#define PERIDOT_BIN_SESSIONCTL_LOGGER_H_
-
-#include <iostream>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/future.h>
-#include <lib/async/cpp/task.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/strings/string_printf.h>
-#include "lib/fxl/functional/make_copyable.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-
-namespace modular {
-
-class Logger {
- public:
- explicit Logger(bool json_out);
-
- void LogError(const std::string& command, const std::string& error) const;
-
- void Log(const std::string& command,
- const std::vector<std::string>& params) const;
-
- void Log(const std::string& command,
- const std::map<std::string, std::string>& params) const;
-
- private:
- // Returns a JSON formatted string of the executed |command| with respective
- // |params| to be logged.
- std::string GenerateJsonLogString(
- const std::string& command,
- const std::vector<std::string>& params) const;
-
- std::string GenerateJsonLogString(
- const std::string& command,
- const std::map<std::string, std::string>& params) const;
-
- rapidjson::Document GetDocument(const std::string& command) const;
-
- // Returns a string of the executed |command| with respective |params| to be
- // logged.
- std::string GenerateLogString(
- const std::string& command,
- const std::map<std::string, std::string>& params) const;
- bool json_out_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONCTL_LOGGER_H_
diff --git a/bin/sessionctl/main.cc b/bin/sessionctl/main.cc
deleted file mode 100644
index 7dec5ce..0000000
--- a/bin/sessionctl/main.cc
+++ /dev/null
@@ -1,284 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <dirent.h>
-#include <glob.h>
-#include <sys/types.h>
-#include <chrono>
-#include <iostream>
-#include <regex>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/future.h>
-#include <lib/async/cpp/task.h>
-#include <lib/fdio/util.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/log_settings_command_line.h>
-#include <lib/fxl/strings/string_printf.h>
-#include "lib/fxl/functional/make_copyable.h"
-
-#include "peridot/bin/sessionctl/logger.h"
-#include "peridot/bin/sessionctl/session_ctl_app.h"
-#include "peridot/bin/sessionctl/session_ctl_constants.h"
-
-using ::fuchsia::modular::PuppetMaster;
-using ::fuchsia::modular::PuppetMasterPtr;
-
-struct DebugService {
- std::string name;
- std::string service_path;
-};
-
-std::string GetUsage() {
- return R"(sessionctl <flags> <command> <argument>
-Example:
-sessionctl add_mod slider_mod
-
-sessionctl --mod_name=mod1 --story_name=story1 --focus_mod=false
- --focus_story=false add_mod slider_mod
-
-sessionctl --story_name=story1 remove_mod slider_mod
-
-<flags>
---story_name=STORY_NAME
---mod_name=MOD_NAME
---focus_mod=false
- Don't focus the mod.
---focus_story=false
- Don't focus the story.
---json_out
- If flag is set output json for consuming instead of text.
-
-<command>
-add_mod
- Usage: [--story_name=foo] [--mod_name=bar] [--focus_mod=false] [--focus_story=false] add_mod MOD_URL
-
- Add a new mod or update an existing mod if a mod with --mod_name already
- exists in --story_name.
- Defaults --story_name and --mod_name to MOD_URL.
- Defaults --focus_mod and --focus_story to 'true'.
-
- MOD_URL
- This can be either the mod's full package url or the mod component's name.
- The mod components name will be converted to the following package url
- format: fuchsia-pkg://fuchsia.com/MOD_URL#meta/MOD_URL.cmx.
-
- optional: --story_name, --mod_name, --focus_mod, --focus_story
-
-remove_mod
- Usage: [--story_name=foo] remove_mod MOD_NAME
-
- Removes an existing mod by name. If the mod was added with add_mod,
- use the value you passed to add_mod's --mod_name flag or the default
- value which would be the mod_url.
- Defaults --story_name to MOD_NAME.
-
- MOD_NAME
- The name of the mod.
-
- optional: --story_name
-
-delete_story
- Usage: delete_story STORY_NAME
-
- Deletes the story.
-
- STORY_NAME
- The name of the story.
-
-list_stories
- List all the stories in the current session.
-
-login_guest
- Logs in a guest user.
-
-restart_session
- Restarts the current session.)";
-}
-
-void FindDebugServicesForPath(const char* glob_str, const char* regex_str,
- std::vector<DebugService>* services) {
- glob_t globbuf;
- bool service_exists = glob(glob_str, 0, nullptr, &globbuf) == 0;
- std::regex name_regex(regex_str);
- if (service_exists) {
- for (size_t i = 0; i < globbuf.gl_pathc; ++i) {
- DebugService s;
- s.service_path = globbuf.gl_pathv[i];
- std::smatch match;
- FXL_CHECK(std::regex_search(s.service_path, match, name_regex))
- << s.service_path;
- s.name = match[1];
- services->push_back(std::move(s));
- }
- globfree(&globbuf);
- }
-}
-
-// Returns a list of all running sessions.
-std::vector<DebugService> FindAllSessions() {
- const char kRegex[] = "/sessionmgr.cmx/(\\d+)";
- // See peridot/bin/sessionmgr/sessionmgr_impl.cc's definition of
- // kSessionCtlDir for "sessionctl". These must match.
- std::vector<DebugService> sessions;
- FindDebugServicesForPath(modular::kSessionCtlServiceGlobPath, kRegex,
- &sessions);
-
- // Path to sessionctl service from a virtual console
- FindDebugServicesForPath(
- "/hub/r/sys/*/c/sessionmgr.cmx/*/out/debug/sessionctl", kRegex,
- &sessions);
- return sessions;
-}
-
-PuppetMasterPtr ConnectToPuppetMaster(const DebugService& session) {
- PuppetMasterPtr puppet_master;
- auto request = puppet_master.NewRequest().TakeChannel();
- std::string service_path = session.service_path + "/" + PuppetMaster::Name_;
- if (fdio_service_connect(service_path.c_str(), request.get()) != ZX_OK) {
- FXL_LOG(FATAL) << "Could not connect to PuppetMaster service in "
- << session.service_path;
- }
- return puppet_master;
-}
-
-fuchsia::modular::internal::BasemgrDebugPtr ConnectToBasemgr() {
- const char kRegex[] = "/basemgr.cmx/(\\d+)";
- std::vector<DebugService> services;
- FindDebugServicesForPath(modular::kBasemgrDebugServiceGlobPath, kRegex,
- &services);
-
- // Path to basemgr debug service from a virtual console
- FindDebugServicesForPath("/hub/r/sys/*/c/basemgr.cmx/*/out/debug/basemgr",
- kRegex, &services);
-
- if (services.empty()) {
- return nullptr;
- }
- FXL_CHECK(services.size() == 1);
- std::string service_path = services[0].service_path;
-
- fuchsia::modular::internal::BasemgrDebugPtr basemgr;
- auto request = basemgr.NewRequest().TakeChannel();
- if (fdio_service_connect(service_path.c_str(), request.get()) != ZX_OK) {
- FXL_LOG(FATAL) << "Could not connect to basemgr service in "
- << service_path;
- }
-
- return basemgr;
-}
-
-// Returns true if a guest user was logged in.
-bool LoginAsGuest(bool has_running_sessions,
- fuchsia::modular::internal::BasemgrDebug* basemgr,
- modular::Logger logger) {
- if (has_running_sessions) {
- logger.LogError(modular::kLoginGuestCommandString,
- "A user is already logged in. You may log a guest user out "
- "by running 'sessionctl restart_session' or you may issue "
- "any other sessionctl command.");
- return false;
- }
-
- basemgr->LoginAsGuest();
- logger.Log(modular::kLoginGuestCommandString, std::vector<std::string>());
- return true;
-}
-
-// Returns true if a guest user was logged in.
-bool LoginDefaultGuestUser(fuchsia::modular::internal::BasemgrDebug* basemgr,
- modular::Logger logger,
- std::vector<DebugService>* sessions,
- std::string cmd) {
- std::cout << "Logging in as a guest user in the absence of running sessions."
- << std::endl;
- LoginAsGuest(/*has_running_sessions=*/false, basemgr, logger);
-
- // Wait 2 seconds to allow sessionmgr to initialize
- std::this_thread::sleep_for(std::chrono::seconds(2));
- std::cout << "Finding sessions..." << std::endl;
- *sessions = FindAllSessions();
-
- if (sessions->empty()) {
- logger.LogError(cmd,
- "Unable find a running session after logging in. "
- "Please try your command again.");
- return false;
- }
- return true;
-}
-
-int main(int argc, const char** argv) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
-
- const auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- fxl::SetLogSettingsFromCommandLine(command_line);
- const auto& positional_args = command_line.positional_args();
- const auto& cmd = positional_args.empty() ? "" : positional_args[0];
-
- const modular::Logger logger(
- command_line.HasOption(modular::kJsonOutFlagString));
-
- auto basemgr = ConnectToBasemgr();
- if (!basemgr) {
- logger.LogError(cmd, "Could not find a running basemgr. Is it running?");
- return 1;
- }
-
- auto sessions = FindAllSessions();
-
- // Continue with log in flow if user issued a login_guest command
- if (cmd == modular::kLoginGuestCommandString) {
- if (LoginAsGuest(/*has_running_sessions=*/!sessions.empty(), basemgr.get(),
- logger)) {
- return 0;
- }
- return 1;
- }
-
- // Log in a guest user if no session is found before continuing to execute
- // the requested command
- if (sessions.empty()) {
- // Exit here if no sessions were found after logging in a guest user
- if (!LoginDefaultGuestUser(basemgr.get(), logger, &sessions, cmd)) {
- return 1;
- }
- }
-
- if (!command_line.HasOption(modular::kJsonOutFlagString)) {
- std::cout << "Found the following sessions:\n\n";
- for (const auto& session : sessions) {
- std::cout << "\t" << session.name << ": " << session.service_path
- << std::endl;
- }
- std::cout << std::endl;
- }
-
- // To get a PuppetMaster service for a session, use the following code:
- PuppetMasterPtr puppet_master = ConnectToPuppetMaster(sessions[0]);
-
- modular::SessionCtlApp app(basemgr.get(), puppet_master.get(), logger,
- loop.dispatcher(), [&loop] { loop.Quit(); });
-
- std::string parsing_error = app.ExecuteCommand(cmd, command_line);
- if (parsing_error == modular::kGetUsageErrorString) {
- // Print help if command doesn't match a valid command.
- std::cout << GetUsage() << std::endl;
- return 1;
- }
-
- if (!parsing_error.empty()) {
- return 1;
- }
-
- loop.Run();
-
- return 0;
-}
diff --git a/bin/sessionctl/meta/sessionctl.cmx b/bin/sessionctl/meta/sessionctl.cmx
deleted file mode 100644
index 1291751..0000000
--- a/bin/sessionctl/meta/sessionctl.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [
- "shell"
- ]
- }
-}
diff --git a/bin/sessionctl/session_ctl_app.cc b/bin/sessionctl/session_ctl_app.cc
deleted file mode 100644
index 5e9b39f..0000000
--- a/bin/sessionctl/session_ctl_app.cc
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <regex>
-
-#include "peridot/bin/sessionctl/session_ctl_app.h"
-#include "peridot/bin/sessionctl/session_ctl_constants.h"
-
-namespace modular {
-
-SessionCtlApp::SessionCtlApp(
- fuchsia::modular::internal::BasemgrDebug* const basemgr,
- fuchsia::modular::PuppetMaster* const puppet_master,
- const modular::Logger& logger, async_dispatcher_t* const dispatcher,
- const std::function<void()>& on_command_executed)
- : basemgr_(basemgr),
- puppet_master_(puppet_master),
- logger_(logger),
- dispatcher_(dispatcher),
- on_command_executed_(on_command_executed) {}
-
-std::string SessionCtlApp::ExecuteCommand(
- std::string cmd, const fxl::CommandLine& command_line) {
- if (cmd == kAddModCommandString) {
- return ExecuteAddModCommand(command_line);
- } else if (cmd == kRemoveModCommandString) {
- return ExecuteRemoveModCommand(command_line);
- } else if (cmd == kDeleteStoryCommandString) {
- return ExecuteDeleteStoryCommand(command_line);
- } else if (cmd == kListStoriesCommandString) {
- return ExecuteListStoriesCommand();
- } else if (cmd == kRestartSessionCommandString) {
- return ExecuteRestartSessionCommand();
- } else {
- return kGetUsageErrorString;
- }
-}
-
-std::string SessionCtlApp::ExecuteRemoveModCommand(
- const fxl::CommandLine& command_line) {
- if (command_line.positional_args().size() == 1) {
- auto parsing_error =
- "Missing MOD_NAME. Ex: sessionctl remove_mod slider_mod";
- logger_.LogError(kRemoveModCommandString, parsing_error);
- return parsing_error;
- }
-
- // Get the mod name and default the story name to the mod name
- std::string mod_name = command_line.positional_args().at(1);
- std::string story_name = mod_name;
-
- // If the story_name flag isn't set, the story name will remain defaulted to
- // the mod name
- command_line.GetOptionValue(kStoryNameFlagString, &story_name);
-
- auto commands = MakeRemoveModCommands(mod_name);
-
- std::map<std::string, std::string> params = {
- {kModNameFlagString, mod_name}, {kStoryNameFlagString, story_name}};
-
- puppet_master_->ControlStory(story_name, story_puppet_master_.NewRequest());
- PostTaskExecuteStoryCommand(kRemoveModCommandString, std::move(commands),
- params);
-
- return "";
-}
-
-std::string SessionCtlApp::ExecuteAddModCommand(
- const fxl::CommandLine& command_line) {
- if (command_line.positional_args().size() == 1) {
- auto parsing_error = "Missing MOD_URL. Ex: sessionctl add_mod slider_mod";
- logger_.LogError(kAddModCommandString, parsing_error);
- return parsing_error;
- }
-
- // Get the mod url and default the mod name and story name to the mod url
- std::string mod_url = command_line.positional_args().at(1);
- std::string mod_name = mod_url;
- std::string story_name = mod_url;
-
- if (mod_url.find(kFuchsiaPkgPrefix) == 0) {
- // Extract the component name from the mod url and use it as the mod and
- // story name
- std::regex pkg_regex(".*#meta/(\\w+)\\.cmx");
- std::smatch match;
- if (std::regex_search(mod_url, match, pkg_regex)) {
- mod_name = match[1];
- story_name = match[1];
- }
- } else {
- // Replace mod url short name with full package path
- mod_url =
- fxl::StringPrintf(kFuchsiaPkgPath, mod_url.c_str(), mod_url.c_str());
- }
-
- // If the following options aren't specified, their respective values will
- // remain unchanged.
- command_line.GetOptionValue(kStoryNameFlagString, &story_name);
- command_line.GetOptionValue(kModNameFlagString, &mod_name);
-
- auto commands = MakeAddModCommands(mod_url, mod_name);
-
- // Focus the mod and story by default
- std::string focus_mod;
- command_line.GetOptionValue(kFocusModFlagString, &focus_mod);
- if (focus_mod == "" || focus_mod == "true") {
- commands.push_back(MakeFocusModCommand(mod_name));
- }
-
- std::string focus_story;
- command_line.GetOptionValue(kFocusStoryFlagString, &focus_story);
- if (focus_story == "" || focus_story == "true") {
- commands.push_back(MakeFocusStoryCommand());
- }
-
- std::map<std::string, std::string> params = {
- {kModUrlFlagString, mod_url},
- {kModNameFlagString, mod_name},
- {kStoryNameFlagString, story_name}};
-
- puppet_master_->ControlStory(story_name, story_puppet_master_.NewRequest());
- PostTaskExecuteStoryCommand(kAddModCommandString, std::move(commands),
- params);
-
- return "";
-}
-
-std::string SessionCtlApp::ExecuteDeleteStoryCommand(
- const fxl::CommandLine& command_line) {
- if (command_line.positional_args().size() == 1) {
- auto parsing_error =
- "Missing STORY_NAME. Ex. sessionctl delete_story story";
- logger_.LogError(kStoryNameFlagString, parsing_error);
- return parsing_error;
- }
-
- // Get the story name
- std::string story_name = command_line.positional_args().at(1);
-
- std::map<std::string, std::string> params = {
- {kStoryNameFlagString, story_name}};
-
- async::PostTask(dispatcher_, [this, story_name, params]() mutable {
- puppet_master_->DeleteStory(story_name, [this, params] {
- logger_.Log(kDeleteStoryCommandString, params);
- on_command_executed_();
- });
- });
-
- return "";
-}
-
-std::string SessionCtlApp::ExecuteListStoriesCommand() {
- async::PostTask(dispatcher_, [this]() mutable {
- puppet_master_->GetStories([this](std::vector<std::string> story_names) {
- logger_.Log(kListStoriesCommandString, std::move(story_names));
- on_command_executed_();
- });
- });
-
- return "";
-}
-
-std::string SessionCtlApp::ExecuteRestartSessionCommand() {
- basemgr_->RestartSession();
- logger_.Log(kRestartSessionCommandString, std::vector<std::string>());
- on_command_executed_();
-
- return "";
-}
-
-fuchsia::modular::StoryCommand SessionCtlApp::MakeFocusStoryCommand() {
- fuchsia::modular::StoryCommand command;
- fuchsia::modular::SetFocusState set_focus_state;
- set_focus_state.focused = true;
- command.set_set_focus_state(std::move(set_focus_state));
- return command;
-}
-
-fuchsia::modular::StoryCommand SessionCtlApp::MakeFocusModCommand(
- const std::string& mod_name) {
- fuchsia::modular::StoryCommand command;
- fuchsia::modular::FocusMod focus_mod;
- focus_mod.mod_name.push_back(mod_name);
- command.set_focus_mod(std::move(focus_mod));
- return command;
-}
-
-std::vector<fuchsia::modular::StoryCommand> SessionCtlApp::MakeAddModCommands(
- const std::string& mod_url, const std::string& mod_name) {
- fuchsia::modular::Intent intent;
- intent.handler = mod_url;
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::StoryCommand command;
-
- // Add command to add or update the mod (it will be updated if the mod_name
- // already exists in the story).
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back(mod_name);
- intent.Clone(&add_mod.intent);
- // TODO(MI4-953): Sessionctl takes in inital intent and other fields.
-
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
-
- return commands;
-}
-
-std::vector<fuchsia::modular::StoryCommand>
-SessionCtlApp::MakeRemoveModCommands(const std::string& mod_name) {
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::StoryCommand command;
-
- fuchsia::modular::RemoveMod remove_mod;
- remove_mod.mod_name.push_back(mod_name);
- command.set_remove_mod(std::move(remove_mod));
- commands.push_back(std::move(command));
- return commands;
-}
-
-void SessionCtlApp::PostTaskExecuteStoryCommand(
- const std::string command_name,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::map<std::string, std::string> params) {
- async::PostTask(dispatcher_, [this, command_name,
- commands = std::move(commands),
- params]() mutable {
- ExecuteStoryCommand(std::move(commands), params.at(kStoryNameFlagString))
- ->Then(
- [this, command_name, params](bool has_error, std::string result) {
- if (has_error) {
- logger_.LogError(command_name, result);
- } else {
- auto params_copy = params;
- params_copy.emplace(kStoryIdFlagString, result);
- logger_.Log(command_name, params_copy);
- }
- on_command_executed_();
- });
- });
-}
-
-modular::FuturePtr<bool, std::string> SessionCtlApp::ExecuteStoryCommand(
- std::vector<fuchsia::modular::StoryCommand> commands,
- const std::string& story_name) {
- story_puppet_master_->Enqueue(std::move(commands));
-
- auto fut = modular::Future<bool, std::string>::Create(
- "Sessionctl StoryPuppetMaster::Execute");
-
- story_puppet_master_->Execute(fxl::MakeCopyable(
- [this, fut](fuchsia::modular::ExecuteResult result) mutable {
- if (result.status == fuchsia::modular::ExecuteStatus::OK) {
- fut->Complete(false, result.story_id->c_str());
- } else {
- std::string error = fxl::StringPrintf(
- "Puppet master returned status: %d and error: %s",
- (uint32_t)result.status, result.error_message->c_str());
-
- FXL_LOG(WARNING) << error << std::endl;
- fut->Complete(true, std::move(error));
- }
- }));
-
- return fut;
-}
-
-} // namespace modular
diff --git a/bin/sessionctl/session_ctl_app.h b/bin/sessionctl/session_ctl_app.h
deleted file mode 100644
index c618435..0000000
--- a/bin/sessionctl/session_ctl_app.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONCTL_SESSION_CTL_APP_H_
-#define PERIDOT_BIN_SESSIONCTL_SESSION_CTL_APP_H_
-
-#include <iostream>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/future.h>
-#include <lib/async/cpp/task.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/strings/string_printf.h>
-#include "lib/fxl/functional/make_copyable.h"
-#include "peridot/bin/sessionctl/logger.h"
-
-using ::fuchsia::modular::PuppetMaster;
-using ::fuchsia::modular::PuppetMasterPtr;
-
-namespace modular {
-
-class SessionCtlApp {
- public:
- // Constructs a SessionCtlApp which can read and execute session commands.
- // |puppet_master| The interface used to execute commands.
- // |basemgr| The basemgr to use to restart sessions.
- // |command_line| The command line used to read commands and arguments.
- // |logger| The logger used to log the results of commands.
- // |dispatcher| The dispatcher which is used to post the command tasks.
- // |on_command_executed| A callback which is called whenever a command has
- // finished executing.
- explicit SessionCtlApp(
- fuchsia::modular::internal::BasemgrDebug* const basemgr,
- fuchsia::modular::PuppetMaster* const puppet_master,
- const modular::Logger& logger, async_dispatcher_t* const dispatcher,
- const std::function<void()>& on_command_executed);
-
- // Dispatches the |cmd| and returns an empty string on success, "GetUsage" if
- // |cmd| is not valid, and a string of missing flags on failure.
- std::string ExecuteCommand(std::string cmd,
- const fxl::CommandLine& command_line);
-
- private:
- // Executes the respective command and returns an empty string on success and
- // a string of missing flags on failure.
- std::string ExecuteAddModCommand(const fxl::CommandLine& command_line);
- std::string ExecuteRemoveModCommand(const fxl::CommandLine& command_line);
- std::string ExecuteDeleteStoryCommand(const fxl::CommandLine& command_line);
- std::string ExecuteListStoriesCommand();
- std::string ExecuteRestartSessionCommand();
-
- // Focus the story to which the mod we are adding belongs.
- fuchsia::modular::StoryCommand MakeFocusStoryCommand();
-
- // Focus the mod we just added. This is not necessary when adding a new mod
- // since it will be always focused. However, when a mod is updated it might
- // not be focused.
- fuchsia::modular::StoryCommand MakeFocusModCommand(
- const std::string& mod_name);
-
- std::vector<fuchsia::modular::StoryCommand> MakeAddModCommands(
- const std::string& mod_url, const std::string& mod_name);
-
- std::vector<fuchsia::modular::StoryCommand> MakeRemoveModCommands(
- const std::string& mod_name);
-
- // Does a PostTask to Execute the commands on StoryPuppetMaster.
- // When the commands are executed do logging and then call
- // on_command_executed_() callback.
- // |command_name| the string command name.
- // |commands| the StoryCommands to execute on StoryPuppetMaster.
- // |params| map of {command_line arg : command_line value}. Used for logging.
- void PostTaskExecuteStoryCommand(
- const std::string command_name,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::map<std::string, std::string> params);
-
- modular::FuturePtr<bool, std::string> ExecuteStoryCommand(
- std::vector<fuchsia::modular::StoryCommand> commands,
- const std::string& story_name);
-
- std::string GenerateMissingFlagString(
- const std::vector<std::string>& missing_flags);
-
- fuchsia::modular::internal::BasemgrDebug* const basemgr_;
- fuchsia::modular::PuppetMaster* const puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- const fxl::CommandLine command_line_;
- const modular::Logger logger_;
- async_dispatcher_t* const dispatcher_;
- const std::function<void()> on_command_executed_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONCTL_SESSION_CTL_APP_H_
diff --git a/bin/sessionctl/session_ctl_app_unittest.cc b/bin/sessionctl/session_ctl_app_unittest.cc
deleted file mode 100644
index 0dc36ff..0000000
--- a/bin/sessionctl/session_ctl_app_unittest.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionctl/session_ctl_app.h"
-#include "peridot/bin/sessionctl/session_ctl_constants.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionmgr/puppet_master/puppet_master_impl.h"
-#include "peridot/lib/testing/test_story_command_executor.h"
-#include "peridot/lib/testing/test_with_session_storage.h"
-
-namespace modular {
-namespace {
-
-class SessionCtlAppTest : public testing::TestWithSessionStorage {
- public:
- void SetUp() override {
- TestWithSessionStorage::SetUp();
- session_storage_ = MakeSessionStorage("page");
- puppet_master_impl_ = std::make_unique<PuppetMasterImpl>(
- session_storage_.get(), &test_executor_);
- puppet_master_impl_->Connect(puppet_master.NewRequest());
- done_ = false;
- }
-
- protected:
- fuchsia::modular::PuppetMasterPtr puppet_master;
- std::unique_ptr<SessionStorage> session_storage_;
- std::unique_ptr<PuppetMasterImpl> puppet_master_impl_;
- std::unique_ptr<Logger> logger_;
- testing::TestStoryCommandExecutor test_executor_;
- bool done_;
-
- SessionCtlApp CreateSessionCtl(fxl::CommandLine command_line) {
- logger_ =
- std::make_unique<Logger>(command_line.HasOption(kJsonOutFlagString));
- SessionCtlApp sessionctl(nullptr /* basemgr */, puppet_master_impl_.get(),
- *(logger_.get()), async_get_default_dispatcher(),
- [&] { done_ = true; });
- return sessionctl;
- }
-
- std::string RunLoopUntilCommandExecutes(
- std::function<std::string()> command) {
- done_ = false;
- std::string error = command();
-
- RunLoopUntil([&] { return done_; });
-
- return error;
- }
-
- fuchsia::modular::internal::StoryDataPtr GetStoryData(
- const std::string& story_id) {
- fuchsia::modular::internal::StoryDataPtr sd;
- done_ = false;
- session_storage_->GetStoryData(story_id)->Then(
- [&](fuchsia::modular::internal::StoryDataPtr story_data) {
- sd = std::move(story_data);
- done_ = true;
- });
- RunLoopUntil([&] { return done_; });
-
- return sd;
- }
-};
-
-TEST_F(SessionCtlAppTest, GetUsage) {
- auto command_line = fxl::CommandLineFromInitializerList(
- {"sessionctl", "--mod_name=mod", "--story_name=story", "--mod_url=foo"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
-
- // Try to execute an invalid command
- std::string error = sessionctl.ExecuteCommand("fake_cmd", command_line);
- RunLoopUntilIdle();
-
- EXPECT_EQ(kGetUsageErrorString, error);
-}
-
-TEST_F(SessionCtlAppTest, AddMod) {
- // Add a mod
- auto command_line = fxl::CommandLineFromInitializerList(
- {"sessionctl", "add_mod",
- "fuchsia-pkg://fuchsia.com/mod_url#meta/mod_url.cmx"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
- RunLoopUntilCommandExecutes([&] {
- return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
- });
-
- // Assert the story and the mod were added with default story and mod names
- auto story_data = GetStoryData("mod_url");
- ASSERT_TRUE(story_data);
- EXPECT_EQ("mod_url", story_data->story_name);
- EXPECT_EQ("mod_url",
- test_executor_.last_commands().at(0).add_mod().mod_name.at(0));
- EXPECT_EQ("fuchsia-pkg://fuchsia.com/mod_url#meta/mod_url.cmx",
- test_executor_.last_commands().at(0).add_mod().intent.handler);
- EXPECT_EQ(1, test_executor_.execute_count());
-}
-
-TEST_F(SessionCtlAppTest, AddModOverrideDefaults) {
- // Add a mod
- auto command_line = fxl::CommandLineFromInitializerList(
- {"sessionctl", "--story_name=s", "--mod_name=m", "add_mod", "mod_url"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
- RunLoopUntilCommandExecutes([&] {
- return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
- });
-
- // Assert the story and the mod were added with overriden story and mod names
- auto story_data = GetStoryData("s");
- ASSERT_TRUE(story_data);
- EXPECT_EQ("s", story_data->story_name);
- EXPECT_EQ("m", test_executor_.last_commands().at(0).add_mod().mod_name.at(0));
- EXPECT_EQ("fuchsia-pkg://fuchsia.com/mod_url#meta/mod_url.cmx",
- test_executor_.last_commands().at(0).add_mod().intent.handler);
- EXPECT_EQ(1, test_executor_.execute_count());
-}
-
-TEST_F(SessionCtlAppTest, AddModMissingModUrl) {
- // Attempt to add a mod without a mod url
- auto command_line =
- fxl::CommandLineFromInitializerList({"sessionctl", "add_mod"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
- std::string error =
- sessionctl.ExecuteCommand(kAddModCommandString, command_line);
-
- RunLoopUntilIdle();
- EXPECT_EQ("Missing MOD_URL. Ex: sessionctl add_mod slider_mod", error);
-}
-
-TEST_F(SessionCtlAppTest, RemoveMod) {
- // Add a mod
- auto command_line =
- fxl::CommandLineFromInitializerList({"sessionctl", "add_mod", "mod"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
- RunLoopUntilCommandExecutes([&] {
- return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
- });
-
- // Remove the mod
- command_line =
- fxl::CommandLineFromInitializerList({"sessionctl", "remove_mod", "mod"});
- RunLoopUntilCommandExecutes([&] {
- return sessionctl.ExecuteCommand(kRemoveModCommandString, command_line);
- });
-
- // Assert session_storage still contains the story
- auto story_data = GetStoryData("mod");
- ASSERT_TRUE(story_data);
- EXPECT_EQ("mod", story_data->story_name);
- EXPECT_EQ("mod",
- test_executor_.last_commands().at(0).remove_mod().mod_name.at(0));
- EXPECT_EQ(2, test_executor_.execute_count());
-}
-
-TEST_F(SessionCtlAppTest, RemoveModOverrideDefault) {
- // Add a mod with overridden story and mod names
- auto command_line = fxl::CommandLineFromInitializerList(
- {"sessionctl", "--story_name=s", "--mod_name=m", "add_mod", "mod"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
- RunLoopUntilCommandExecutes([&] {
- return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
- });
-
- // Remove the mod with an overridden story name
- command_line = fxl::CommandLineFromInitializerList(
- {"sessionctl", "--story_name=s", "remove_mod", "m"});
- RunLoopUntilCommandExecutes([&] {
- return sessionctl.ExecuteCommand(kRemoveModCommandString, command_line);
- });
-
- // Assert session_storage still contains the story
- auto story_data = GetStoryData("s");
- ASSERT_TRUE(story_data);
- EXPECT_EQ("s", story_data->story_name);
- EXPECT_EQ("m",
- test_executor_.last_commands().at(0).remove_mod().mod_name.at(0));
- EXPECT_EQ(2, test_executor_.execute_count());
-}
-
-TEST_F(SessionCtlAppTest, RemoveModMissingModName) {
- // Attempt to remove a mod without a mod name
- auto command_line =
- fxl::CommandLineFromInitializerList({"sessionctl", "remove_mod"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
- std::string error =
- sessionctl.ExecuteCommand(kRemoveModCommandString, command_line);
-
- RunLoopUntilIdle();
- EXPECT_EQ("Missing MOD_NAME. Ex: sessionctl remove_mod slider_mod", error);
-}
-
-TEST_F(SessionCtlAppTest, DeleteStory) {
- // Add a mod with overridden story name
- auto command_line = fxl::CommandLineFromInitializerList(
- {"sessionctl", "--story_name=story", "add_mod", "mod"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
- RunLoopUntilCommandExecutes([&] {
- return sessionctl.ExecuteCommand(kAddModCommandString, command_line);
- });
-
- // Remove the story
- command_line = fxl::CommandLineFromInitializerList(
- {"sessionctl", "delete_story", "story"});
- RunLoopUntilCommandExecutes([&] {
- return sessionctl.ExecuteCommand(kDeleteStoryCommandString, command_line);
- });
-
- auto story_data = GetStoryData("mod");
- EXPECT_FALSE(story_data);
- EXPECT_EQ(1, test_executor_.execute_count());
-}
-
-TEST_F(SessionCtlAppTest, DeleteStoryMissingStoryName) {
- // Attempt to delete a story without the required flags
- auto command_line =
- fxl::CommandLineFromInitializerList({"sessionctl", "delete_story"});
- SessionCtlApp sessionctl = CreateSessionCtl(command_line);
- std::string error =
- sessionctl.ExecuteCommand(kDeleteStoryCommandString, command_line);
-
- RunLoopUntilIdle();
- EXPECT_EQ("Missing STORY_NAME. Ex. sessionctl delete_story story", error);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionctl/session_ctl_constants.h b/bin/sessionctl/session_ctl_constants.h
deleted file mode 100644
index 40fb2cc..0000000
--- a/bin/sessionctl/session_ctl_constants.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONCTL_SESSION_CTL_CONSTANTS_H_
-#define PERIDOT_BIN_SESSIONCTL_SESSION_CTL_CONSTANTS_H_
-
-namespace modular {
-
-// Commands available to SessionCtlApp.
-constexpr char kAddModCommandString[] = "add_mod";
-constexpr char kDeleteStoryCommandString[] = "delete_story";
-constexpr char kListStoriesCommandString[] = "list_stories";
-constexpr char kLoginGuestCommandString[] = "login_guest";
-constexpr char kRemoveModCommandString[] = "remove_mod";
-constexpr char kRestartSessionCommandString[] = "restart_session";
-
-// Flags to pass to SessionCtlApp.
-constexpr char kJsonOutFlagString[] = "json_out";
-constexpr char kFocusModFlagString[] = "focus_mod";
-constexpr char kFocusStoryFlagString[] = "focus_story";
-constexpr char kModNameFlagString[] = "mod_name";
-constexpr char kModUrlFlagString[] = "mod_url";
-constexpr char kStoryIdFlagString[] = "story_id";
-constexpr char kStoryNameFlagString[] = "story_name";
-
-// Internal error string returned from SessionCtlApp.ExecuteCommand() if
-// the user does not set a required flag.
-constexpr char kGetUsageErrorString[] = "GetUsage";
-
-// Fuchsia package paths for add_mod
-constexpr char kFuchsiaPkgPrefix[] = "fuchsia-pkg://";
-constexpr char kFuchsiaPkgPath[] = "fuchsia-pkg://fuchsia.com/%s#meta/%s.cmx";
-
-// hub paths to debug services.
-constexpr char kSessionCtlServiceGlobPath[] =
- "/hub/c/sessionmgr.cmx/*/out/debug/sessionctl";
-constexpr char kBasemgrDebugServiceGlobPath[] =
- "/hub/c/basemgr.cmx/*/out/debug/basemgr";
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONCTL_SESSION_CTL_CONSTANTS_H_
diff --git a/bin/sessionmgr/BUILD.gn b/bin/sessionmgr/BUILD.gn
deleted file mode 100644
index f49eb6e..0000000
--- a/bin/sessionmgr/BUILD.gn
+++ /dev/null
@@ -1,232 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("sessionmgr") {
- meta = [
- {
- path = "meta/sessionmgr.cmx"
- dest = "sessionmgr.cmx"
- },
- ]
-
- sources = [
- "device_map_impl.cc",
- "device_map_impl.h",
- "sessionmgr.cc",
- "sessionmgr_impl.cc",
- "sessionmgr_impl.h",
- ]
-
- deps = [
- ":component_context",
- ":focus",
- ":presentation_provider",
- ":session_ctl",
- ":user_intelligence_provider",
- "//garnet/public/fidl/fuchsia.net.oldhttp",
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/basemgr/cobalt",
- "//peridot/bin/cloud_provider_firestore/fidl",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/sessionmgr/agent_runner",
- "//peridot/bin/sessionmgr/entity_provider_runner",
- "//peridot/bin/sessionmgr/message_queue",
- "//peridot/bin/sessionmgr/puppet_master:make_production_impl",
- "//peridot/bin/sessionmgr/puppet_master:puppet_master_impl",
- "//peridot/bin/sessionmgr/puppet_master:story_command_executor",
- "//peridot/bin/sessionmgr/storage",
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/bin/sessionmgr/story_runner",
- "//peridot/lib/common:async_holder",
- "//peridot/lib/common:names",
- "//peridot/lib/common:teardown",
- "//peridot/lib/common:xdr",
- "//peridot/lib/device_info",
- "//peridot/lib/fidl:app_client",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/fidl:environment",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/fidl:view_host",
- "//peridot/lib/ledger_client:constants",
- "//peridot/lib/ledger_client:operations",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/ledger_client:status",
- "//peridot/lib/ledger_client:types",
- "//peridot/lib/module_manifest:module_facet_reader_impl",
- "//peridot/lib/rapidjson",
- "//peridot/lib/scoped_tmpfs",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/fidl/fuchsia.speech",
- "//peridot/public/lib/app_driver/cpp:app_driver",
- "//peridot/public/lib/async/cpp:operation",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-
- public_deps = [
- "//peridot/bin/basemgr/cobalt:basemgr_metrics_registry",
- ]
-
- resources = [
- {
- path = rebase_path(
- get_label_info(
- "//peridot/bin/basemgr/cobalt:basemgr_metrics_registry",
- "target_gen_dir") + "/basemgr_metrics_registry.pb")
- dest = "basemgr_metrics_registry.pb"
- },
- ]
-}
-
-executable_package("dev_session_shell") {
- meta = [
- {
- path = "meta/dev_session_shell.cmx"
- dest = "dev_session_shell.cmx"
- },
- ]
-
- sources = [
- "dev_session_shell.cc",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/common:names",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:single_service_app",
- "//peridot/lib/fidl:view_host",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:test_driver",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-}
-
-source_set("session_ctl") {
- sources = [
- "session_ctl.cc",
- "session_ctl.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr/puppet_master:puppet_master_impl",
- "//zircon/public/lib/fs",
- ]
-}
-
-source_set("component_context") {
- sources = [
- "component_context_impl.cc",
- "component_context_impl.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/sessionmgr/agent_runner:public",
- "//peridot/bin/sessionmgr/entity_provider_runner",
- "//peridot/bin/sessionmgr/message_queue",
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/ledger_client:operations",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/ledger_client:types",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-source_set("focus") {
- sources = [
- "focus.cc",
- "focus.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/ledger_client:operations",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/ledger_client:types",
- "//peridot/lib/rapidjson",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-source_set("presentation_provider") {
- sources = [
- "presentation_provider.cc",
- "presentation_provider.h",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("user_intelligence_provider") {
- sources = [
- "user_intelligence_provider_impl.cc",
- "user_intelligence_provider_impl.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- ]
-
- deps = [
- ":focus",
- ":intelligence_services",
- "//garnet/public/fidl/fuchsia.bluetooth.le",
- "//garnet/public/fidl/fuchsia.net.oldhttp",
- "//peridot/bin/basemgr/cobalt",
- "//peridot/lib:maxwell_internal",
- "//peridot/lib/util:rate_limited_retry",
- "//peridot/public/fidl/fuchsia.modular",
- "//zircon/public/fidl/fuchsia-cobalt",
- ]
-}
-
-source_set("intelligence_services") {
- sources = [
- "intelligence_services_impl.cc",
- "intelligence_services_impl.h",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
diff --git a/bin/sessionmgr/agent_runner/BUILD.gn b/bin/sessionmgr/agent_runner/BUILD.gn
deleted file mode 100644
index 50d20ed..0000000
--- a/bin/sessionmgr/agent_runner/BUILD.gn
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-source_set("agent_runner") {
- sources = [
- "agent_context_impl.cc",
- "agent_context_impl.h",
- "agent_runner.cc",
- "agent_runner_storage_impl.cc",
- "agent_runner_storage_impl.h",
- ]
-
- public_deps = [
- ":public",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr:component_context",
- "//peridot/bin/sessionmgr/message_queue",
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/lib/common:teardown",
- "//peridot/lib/fidl:app_client",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/ledger_client:types",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-executable("agent_runner_unittest") {
- testonly = true
-
- sources = [
- "agent_runner_unittest.cc",
- ]
-
- deps = [
- ":agent_runner",
- ":public",
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/component/cpp/testing:fake_launcher",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr/entity_provider_runner",
- "//peridot/bin/sessionmgr/message_queue",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/testing:fake_agent_runner_storage",
- "//peridot/lib/testing:mock_base",
- "//peridot/lib/testing:test_with_ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//third_party/googletest:gtest_main",
- "//zircon/public/lib/trace",
- ]
-}
-
-tests_package("agent_runner_unittests") {
- deps = [
- ":agent_runner_unittest",
- ]
-}
-
-# Broken out for component to depend on w/o creating circles.
-source_set("public") {
- sources = [
- "agent_runner.h",
- "agent_runner_storage.cc",
- "agent_runner_storage.h",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/sessionmgr/entity_provider_runner",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
diff --git a/bin/sessionmgr/agent_runner/agent_context_impl.cc b/bin/sessionmgr/agent_runner/agent_context_impl.cc
deleted file mode 100644
index 641b932..0000000
--- a/bin/sessionmgr/agent_runner/agent_context_impl.cc
+++ /dev/null
@@ -1,366 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_context_impl.h"
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner.h"
-#include "peridot/lib/common/teardown.h"
-
-namespace modular {
-
-constexpr char kAppStoragePath[] = "/data/APP_DATA";
-
-namespace {
-
-// A stopgap solution to map an agent's url to a directory name where the
-// agent's /data is mapped. We need three properties here - (1) two module urls
-// that are the same get mapped to the same hash, (2) two modules urls that are
-// different don't get the same name (with very high probability) and (3) the
-// name is visually inspectable.
-std::string HashAgentUrl(const std::string& agent_url) {
- std::size_t found = agent_url.find_last_of('/');
- auto last_part =
- found == agent_url.length() - 1 ? "" : agent_url.substr(found + 1);
- return std::to_string(std::hash<std::string>{}(agent_url)) + last_part;
-}
-
-}; // namespace
-
-class AgentContextImpl::InitializeCall : public Operation<> {
- public:
- InitializeCall(AgentContextImpl* const agent_context_impl,
- fuchsia::sys::Launcher* const launcher,
- fuchsia::modular::AppConfig agent_config)
- : Operation("AgentContextImpl::InitializeCall", [] {},
- agent_context_impl->url_),
- agent_context_impl_(agent_context_impl),
- launcher_(launcher),
- agent_config_(std::move(agent_config)) {}
-
- private:
- void Run() override {
- FXL_CHECK(agent_context_impl_->state_ == State::INITIALIZING);
-
- FlowToken flow{this};
-
- // No user intelligence provider is available during testing. We want to
- // keep going without it.
- if (!agent_context_impl_->user_intelligence_provider_) {
- auto service_list = fuchsia::sys::ServiceList::New();
- Continue(std::move(service_list), flow);
- return;
- }
-
- agent_context_impl_->user_intelligence_provider_->GetServicesForAgent(
- agent_context_impl_->url_,
- [this, flow](fuchsia::sys::ServiceList maxwell_service_list) {
- auto service_list = fuchsia::sys::ServiceList::New();
- service_list->names = std::move(maxwell_service_list.names);
- agent_context_impl_->service_provider_impl_.SetDefaultServiceProvider(
- maxwell_service_list.provider.Bind());
- Continue(std::move(service_list), flow);
- });
- }
-
- void Continue(fuchsia::sys::ServiceListPtr service_list, FlowToken flow) {
- service_list->names.push_back(fuchsia::modular::ComponentContext::Name_);
- service_list->names.push_back(fuchsia::modular::AgentContext::Name_);
- agent_context_impl_->service_provider_impl_.AddBinding(
- service_list->provider.NewRequest());
- agent_context_impl_->app_client_ =
- std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- launcher_, std::move(agent_config_),
- std::string(kAppStoragePath) +
- HashAgentUrl(agent_context_impl_->url_),
- std::move(service_list));
-
- agent_context_impl_->app_client_->services().ConnectToService(
- agent_context_impl_->agent_.NewRequest());
-
- // We only want to use fuchsia::modular::Lifecycle if it exists.
- agent_context_impl_->app_client_->primary_service().set_error_handler(
- [agent_context_impl = agent_context_impl_](zx_status_t status) {
- agent_context_impl->app_client_->primary_service().Unbind();
- });
-
- // When the agent process dies, we remove it.
- // TODO(alhaad): In the future we would want to detect a crashing agent and
- // stop scheduling tasks for it.
- agent_context_impl_->app_client_->SetAppErrorHandler(
- [agent_context_impl = agent_context_impl_] {
- agent_context_impl->agent_runner_->RemoveAgent(
- agent_context_impl->url_);
- });
-
- // When all the |fuchsia::modular::AgentController| bindings go away maybe
- // stop the agent.
- agent_context_impl_->agent_controller_bindings_.set_empty_set_handler(
- [agent_context_impl = agent_context_impl_] {
- agent_context_impl->StopAgentIfIdle();
- });
-
- agent_context_impl_->state_ = State::RUNNING;
- }
-
- AgentContextImpl* const agent_context_impl_;
- fuchsia::sys::Launcher* const launcher_;
- fuchsia::modular::AppConfig agent_config_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(InitializeCall);
-};
-
-// If |terminating| is set to true, the agent will be torn down irrespective
-// of whether there is an open-connection or running task. Returns |true| if the
-// agent was stopped, false otherwise (could be because agent has pending
-// tasks).
-class AgentContextImpl::StopCall : public Operation<bool> {
- public:
- StopCall(const bool terminating, AgentContextImpl* const agent_context_impl,
- ResultCall result_call)
- : Operation("AgentContextImpl::StopCall", std::move(result_call),
- agent_context_impl->url_),
- agent_context_impl_(agent_context_impl),
- terminating_(terminating) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &stopped_};
-
- if (agent_context_impl_->state_ == State::TERMINATING) {
- return;
- }
-
- if (terminating_ ||
- (agent_context_impl_->agent_controller_bindings_.size() == 0 &&
- agent_context_impl_->incomplete_task_count_ == 0)) {
- Stop(flow);
- }
- }
-
- void Stop(FlowToken flow) {
- agent_context_impl_->state_ = State::TERMINATING;
- // Calling Teardown() below will branch |flow| into normal and timeout
- // paths. |flow| must go out of scope when either of the paths finishes.
- //
- // TODO(mesch): AppClient/AsyncHolder should implement this. See also
- // StoryProviderImpl::StopStoryShellCall.
- FlowTokenHolder branch{flow};
- agent_context_impl_->app_client_->Teardown(kBasicTimeout, [this, branch] {
- std::unique_ptr<FlowToken> cont = branch.Continue();
- if (cont) {
- Kill(*cont);
- }
- });
- }
-
- void Kill(FlowToken flow) {
- stopped_ = true;
- agent_context_impl_->agent_.Unbind();
- agent_context_impl_->agent_context_bindings_.CloseAll();
- agent_context_impl_->token_manager_bindings_.CloseAll();
- }
-
- bool stopped_ = false;
- AgentContextImpl* const agent_context_impl_;
- const bool terminating_; // is the agent runner terminating?
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StopCall);
-};
-
-AgentContextImpl::AgentContextImpl(const AgentContextInfo& info,
- fuchsia::modular::AppConfig agent_config)
- : url_(agent_config.url),
- agent_runner_(info.component_context_info.agent_runner),
- component_context_impl_(info.component_context_info,
- kAgentComponentNamespace, url_, url_),
- token_manager_(info.token_manager),
- entity_provider_runner_(
- info.component_context_info.entity_provider_runner),
- user_intelligence_provider_(info.user_intelligence_provider) {
- service_provider_impl_.AddService<fuchsia::modular::ComponentContext>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request) {
- component_context_impl_.Connect(std::move(request));
- });
- service_provider_impl_.AddService<fuchsia::modular::AgentContext>(
- [this](fidl::InterfaceRequest<fuchsia::modular::AgentContext> request) {
- agent_context_bindings_.AddBinding(this, std::move(request));
- });
- operation_queue_.Add(
- new InitializeCall(this, info.launcher, std::move(agent_config)));
-}
-
-AgentContextImpl::~AgentContextImpl() = default;
-
-void AgentContextImpl::NewAgentConnection(
- const std::string& requestor_url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) {
- // Queue adding the connection
- operation_queue_.Add(new SyncCall(fxl::MakeCopyable(
- [this, requestor_url,
- incoming_services_request = std::move(incoming_services_request),
- agent_controller_request =
- std::move(agent_controller_request)]() mutable {
- FXL_CHECK(state_ == State::RUNNING);
-
- agent_->Connect(requestor_url, std::move(incoming_services_request));
-
- // Add a binding to the |controller|. When all the bindings go away,
- // the agent will stop.
- agent_controller_bindings_.AddBinding(
- this, std::move(agent_controller_request));
- })));
-}
-
-void AgentContextImpl::NewEntityProviderConnection(
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) {
- operation_queue_.Add(new SyncCall(fxl::MakeCopyable(
- [this, entity_provider_request = std::move(entity_provider_request),
- agent_controller_request =
- std::move(agent_controller_request)]() mutable {
- FXL_CHECK(state_ == State::RUNNING);
- app_client_->services().ConnectToService(
- std::move(entity_provider_request));
- agent_controller_bindings_.AddBinding(
- this, std::move(agent_controller_request));
- })));
-}
-
-void AgentContextImpl::NewTask(const std::string& task_id) {
- operation_queue_.Add(new SyncCall([this, task_id] {
- FXL_CHECK(state_ == State::RUNNING);
- // Increment the counter for number of incomplete tasks. Decrement it when
- // we receive its callback;
- incomplete_task_count_++;
- agent_->RunTask(task_id, [this] {
- incomplete_task_count_--;
- StopAgentIfIdle();
- });
- }));
-}
-
-void AgentContextImpl::GetComponentContext(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request) {
- component_context_impl_.Connect(std::move(request));
-}
-
-void AgentContextImpl::GetTokenManager(
- fidl::InterfaceRequest<fuchsia::auth::TokenManager> request) {
- token_manager_bindings_.AddBinding(this, std::move(request));
-}
-
-void AgentContextImpl::GetEntityReferenceFactory(
- fidl::InterfaceRequest<fuchsia::modular::EntityReferenceFactory> request) {
- entity_provider_runner_->ConnectEntityReferenceFactory(url_,
- std::move(request));
-}
-
-void AgentContextImpl::ScheduleTask(fuchsia::modular::TaskInfo task_info) {
- agent_runner_->ScheduleTask(url_, std::move(task_info));
-}
-
-void AgentContextImpl::DeleteTask(std::string task_id) {
- agent_runner_->DeleteTask(url_, task_id);
-}
-
-void AgentContextImpl::Authorize(
- fuchsia::auth::AppConfig app_config,
- fidl::InterfaceHandle<fuchsia::auth::AuthenticationUIContext>
- auth_ui_context,
- std::vector<::std::string> app_scopes, fidl::StringPtr user_profile_id,
- fidl::StringPtr auth_code, AuthorizeCallback callback) {
- FXL_LOG(ERROR) << "AgentContextImpl::Authorize() not supported from agent "
- << "context";
- callback(fuchsia::auth::Status::INVALID_REQUEST, nullptr);
-}
-
-void AgentContextImpl::GetAccessToken(fuchsia::auth::AppConfig app_config,
- std::string user_profile_id,
- std::vector<::std::string> app_scopes,
- GetAccessTokenCallback callback) {
- FXL_CHECK(token_manager_);
-
- FXL_DLOG(INFO) << "AgentContextImpl::GetAccessToken() invoked for user:"
- << user_profile_id;
- token_manager_->GetAccessToken(std::move(app_config),
- std::move(user_profile_id),
- std::move(app_scopes), std::move(callback));
-}
-
-void AgentContextImpl::GetIdToken(fuchsia::auth::AppConfig app_config,
- std::string user_profile_id,
- fidl::StringPtr audience,
- GetIdTokenCallback callback) {
- FXL_CHECK(token_manager_);
-
- FXL_DLOG(INFO) << "AgentContextImpl::GetIdToken() invoked for user:"
- << user_profile_id;
- token_manager_->GetIdToken(std::move(app_config), std::move(user_profile_id),
- std::move(audience), std::move(callback));
-}
-
-void AgentContextImpl::GetFirebaseToken(fuchsia::auth::AppConfig app_config,
- std::string user_profile_id,
- std::string audience,
- std::string firebase_api_key,
- GetFirebaseTokenCallback callback) {
- FXL_CHECK(token_manager_);
-
- FXL_DLOG(INFO) << "AgentContextImpl::GetFirebaseToken() invoked for user:"
- << user_profile_id;
- token_manager_->GetFirebaseToken(
- std::move(app_config), std::move(user_profile_id), std::move(audience),
- std::move(firebase_api_key), std::move(callback));
-}
-
-void AgentContextImpl::DeleteAllTokens(fuchsia::auth::AppConfig app_config,
- std::string user_profile_id,
- DeleteAllTokensCallback callback) {
- FXL_LOG(ERROR) << "AgentContextImpl::DeleteAllTokens() not supported from "
- << "agent context";
- callback(fuchsia::auth::Status::INVALID_REQUEST);
-}
-
-void AgentContextImpl::ListProfileIds(fuchsia::auth::AppConfig app_config,
- ListProfileIdsCallback callback) {
- FXL_CHECK(token_manager_);
-
- token_manager_->ListProfileIds(std::move(app_config), std::move(callback));
-}
-
-void AgentContextImpl::StopAgentIfIdle() {
- operation_queue_.Add(new StopCall(false /* is agent runner terminating? */,
- this, [this](bool stopped) {
- if (stopped) {
- agent_runner_->RemoveAgent(url_);
- // |this| is no longer valid at this
- // point.
- }
- }));
-}
-
-void AgentContextImpl::StopForTeardown(const std::function<void()>& callback) {
- FXL_DLOG(INFO) << "AgentContextImpl::StopForTeardown() " << url_;
- operation_queue_.Add(new StopCall(true /* is agent runner terminating? */,
- this, [this, callback](bool stopped) {
- FXL_DCHECK(stopped);
- agent_runner_->RemoveAgent(url_);
- callback();
- // |this| is no longer valid at this
- // point.
- }));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/agent_runner/agent_context_impl.h b/bin/sessionmgr/agent_runner/agent_context_impl.h
deleted file mode 100644
index afb742c..0000000
--- a/bin/sessionmgr/agent_runner/agent_context_impl.h
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_CONTEXT_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_CONTEXT_IMPL_H_
-
-#include <string>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/component_context_impl.h"
-#include "peridot/lib/fidl/app_client.h"
-
-namespace modular {
-
-class AgentRunner;
-
-// The parameters of agent context that do not vary by instance.
-struct AgentContextInfo {
- const ComponentContextInfo component_context_info;
- fuchsia::sys::Launcher* const launcher;
- fuchsia::auth::TokenManager* const token_manager;
- fuchsia::modular::UserIntelligenceProvider* const user_intelligence_provider;
-};
-
-// This class manages an agent and its life cycle. AgentRunner owns this class,
-// and instantiates one for every instance of an agent running. All requests for
-// this agent (identified for now by the agent's URL) are routed to this
-// class. This class manages all AgentControllers associated with this agent.
-class AgentContextImpl : fuchsia::modular::AgentContext,
- fuchsia::modular::AgentController,
- fuchsia::auth::TokenManager {
- public:
- // Starts the agent specified in |agent_config| and provides it:
- // 1) AgentContext service
- // 2) A set of services from UserIntelligenceProvider for this agent's url.
- explicit AgentContextImpl(const AgentContextInfo& info,
- fuchsia::modular::AppConfig agent_config);
- ~AgentContextImpl() override;
-
- // Stops the running agent, irrespective of whether there are active
- // AgentControllers or outstanding tasks. Calls into
- // |AgentRunner::RemoveAgent()| to remove itself.
- void StopForTeardown(const std::function<void()>& callback);
-
- // Called by AgentRunner when a component wants to connect to this agent.
- // Connections will pend until fuchsia::modular::Agent::Initialize() responds
- // back, at which point all connections will be forwarded to the agent.
- void NewAgentConnection(
- const std::string& requestor_url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request);
-
- // Called by AgentRunner when the framework wants to talk to the
- // |fuchsia::modular::EntityProvider| service from this agent. Similar to
- // NewAgentConnection(), this operation will pend until the entity provider
- // agent is initialized.
- void NewEntityProviderConnection(
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request);
-
- // Called by AgentRunner when a new task has been scheduled.
- void NewTask(const std::string& task_id);
-
- enum class State { INITIALIZING, RUNNING, TERMINATING };
- State state() { return state_; }
-
- private:
- // |fuchsia::modular::AgentContext|
- void GetComponentContext(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request)
- override;
- // |fuchsia::modular::AgentContext|
- void GetTokenManager(
- fidl::InterfaceRequest<fuchsia::auth::TokenManager> request) override;
- // |fuchsia::modular::AgentContext|
- void ScheduleTask(fuchsia::modular::TaskInfo task_info) override;
- // |fuchsia::modular::AgentContext|
- void DeleteTask(std::string task_id) override;
- // |fuchsia::modular::AgentContext|
- void GetEntityReferenceFactory(
- fidl::InterfaceRequest<fuchsia::modular::EntityReferenceFactory> request)
- override;
-
- // |fuchsia::auth::TokenManager|
- void Authorize(fuchsia::auth::AppConfig app_config,
- fidl::InterfaceHandle<fuchsia::auth::AuthenticationUIContext>
- auth_ui_context,
- std::vector<::std::string> app_scopes,
- fidl::StringPtr user_profile_id, fidl::StringPtr auth_code,
- AuthorizeCallback callback) override;
-
- // |fuchsia::auth::TokenManager|
- void GetAccessToken(fuchsia::auth::AppConfig app_config,
- std::string user_profile_id,
- std::vector<::std::string> app_scopes,
- GetAccessTokenCallback callback) override;
-
- // |fuchsia::auth::TokenManager|
- void GetIdToken(fuchsia::auth::AppConfig app_config,
- std::string user_profile_id, fidl::StringPtr audience,
- GetIdTokenCallback callback) override;
-
- // |fuchsia::auth::TokenManager|
- void GetFirebaseToken(fuchsia::auth::AppConfig app_config,
- std::string user_profile_id,
- std::string audience,
- std::string firebase_api_key,
- GetFirebaseTokenCallback callback) override;
-
- // |fuchsia::auth::TokenManager|
- void DeleteAllTokens(fuchsia::auth::AppConfig app_config,
- std::string user_profile_id,
- DeleteAllTokensCallback callback) override;
-
- // |fuchsia::auth::TokenManager|
- void ListProfileIds(fuchsia::auth::AppConfig app_config,
- ListProfileIdsCallback callback) override;
-
- // Adds an operation on |operation_queue_|. This operation is immediately
- // Done() if this agent is not |ready_|. Else if there are no active
- // AgentControllers and no outstanding task, fuchsia::modular::Agent.Stop() is
- // called with a timeout.
- void StopAgentIfIdle();
-
- const std::string url_;
-
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> app_client_;
- fuchsia::modular::AgentPtr agent_;
- fidl::BindingSet<fuchsia::modular::AgentContext> agent_context_bindings_;
- fidl::BindingSet<fuchsia::modular::AgentController>
- agent_controller_bindings_;
- fidl::BindingSet<fuchsia::auth::TokenManager> token_manager_bindings_;
-
- AgentRunner* const agent_runner_;
-
- ComponentContextImpl component_context_impl_;
-
- // A service provider that represents the services to be added into an
- // application's namespace.
- component::ServiceProviderImpl service_provider_impl_;
-
- fuchsia::auth::TokenManager* const token_manager_; // Not owned.
- EntityProviderRunner* const entity_provider_runner_; // Not owned.
- fuchsia::modular::UserIntelligenceProvider* const
- user_intelligence_provider_; // Not owned.
-
- State state_ = State::INITIALIZING;
-
- // Number of times fuchsia::modular::Agent.RunTask() was called but we're
- // still waiting on its completion callback.
- int incomplete_task_count_ = 0;
-
- OperationQueue operation_queue_;
-
- // Operations implemented here.
- class InitializeCall;
- class StopCall;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AgentContextImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_CONTEXT_IMPL_H_
diff --git a/bin/sessionmgr/agent_runner/agent_runner.cc b/bin/sessionmgr/agent_runner/agent_runner.cc
deleted file mode 100644
index 47cf6c2..0000000
--- a/bin/sessionmgr/agent_runner/agent_runner.cc
+++ /dev/null
@@ -1,509 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner.h"
-
-#include <map>
-#include <set>
-#include <utility>
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_context_impl.h"
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner_storage_impl.h"
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace modular {
-
-constexpr zx::duration kTeardownTimeout = zx::sec(3);
-
-AgentRunner::AgentRunner(
- fuchsia::sys::Launcher* const launcher,
- MessageQueueManager* const message_queue_manager,
- fuchsia::ledger::internal::LedgerRepository* const ledger_repository,
- AgentRunnerStorage* const agent_runner_storage,
- fuchsia::auth::TokenManager* const token_manager,
- fuchsia::modular::UserIntelligenceProvider* const
- user_intelligence_provider,
- EntityProviderRunner* const entity_provider_runner)
- : launcher_(launcher),
- message_queue_manager_(message_queue_manager),
- ledger_repository_(ledger_repository),
- agent_runner_storage_(agent_runner_storage),
- token_manager_(token_manager),
- user_intelligence_provider_(user_intelligence_provider),
- entity_provider_runner_(entity_provider_runner),
- terminating_(std::make_shared<bool>(false)) {
- agent_runner_storage_->Initialize(this, [] {});
-}
-
-AgentRunner::~AgentRunner() = default;
-
-void AgentRunner::Connect(
- fidl::InterfaceRequest<fuchsia::modular::AgentProvider> request) {
- agent_provider_bindings_.AddBinding(this, std::move(request));
-}
-
-void AgentRunner::Teardown(const std::function<void()>& callback) {
- // No new agents will be scheduled to run.
- *terminating_ = true;
-
- FXL_LOG(INFO) << "AgentRunner::Teardown() " << running_agents_.size()
- << " agents";
-
- // No agents were running, we are good to go.
- if (running_agents_.empty()) {
- callback();
- return;
- }
-
- // This is called when agents are done being removed
- auto called = std::make_shared<bool>(false);
- auto termination_callback = [this, called,
- callback](const bool from_timeout) {
- if (*called) {
- return;
- }
-
- *called = true;
-
- if (from_timeout) {
- FXL_LOG(ERROR) << "AgentRunner::Teardown() timed out";
- }
-
- callback();
- };
-
- for (auto& it : running_agents_) {
- // The running agent will call |AgentRunner::RemoveAgent()| to remove itself
- // from the agent runner. When all agents are done being removed,
- // |termination_callback| will be executed.
- it.second->StopForTeardown([this, termination_callback]() {
- if (running_agents_.empty()) {
- termination_callback(/* from_timeout= */ false);
- }
- });
- }
-
- async::PostDelayedTask(async_get_default_dispatcher(),
- [termination_callback] {
- termination_callback(/* from_timeout= */ true);
- },
- kTeardownTimeout);
-}
-
-void AgentRunner::EnsureAgentIsRunning(const std::string& agent_url,
- const std::function<void()>& done) {
- auto agent_it = running_agents_.find(agent_url);
- if (agent_it != running_agents_.end()) {
- if (agent_it->second->state() == AgentContextImpl::State::TERMINATING) {
- run_agent_callbacks_[agent_url].push_back(done);
- return;
- }
- // fuchsia::modular::Agent is already running, so we can issue the callback
- // immediately.
- done();
- return;
- }
-
- run_agent_callbacks_[agent_url].push_back(done);
-
- RunAgent(agent_url);
-}
-
-void AgentRunner::RunAgent(const std::string& agent_url) {
- // Start the agent and issue all callbacks.
- ComponentContextInfo component_info = {message_queue_manager_, this,
- ledger_repository_,
- entity_provider_runner_};
- AgentContextInfo info = {component_info, launcher_, token_manager_,
- user_intelligence_provider_};
- fuchsia::modular::AppConfig agent_config;
- agent_config.url = agent_url;
-
- FXL_CHECK(running_agents_
- .emplace(agent_url, std::make_unique<AgentContextImpl>(
- info, std::move(agent_config)))
- .second);
-
- auto run_callbacks_it = run_agent_callbacks_.find(agent_url);
- if (run_callbacks_it != run_agent_callbacks_.end()) {
- for (auto& callback : run_callbacks_it->second) {
- callback();
- }
- run_agent_callbacks_.erase(agent_url);
- }
-
- UpdateWatchers();
-}
-
-void AgentRunner::ConnectToAgent(
- const std::string& requestor_url, const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) {
- // Drop all new requests if AgentRunner is terminating.
- if (*terminating_) {
- return;
- }
-
- pending_agent_connections_[agent_url].push_back(
- {requestor_url, std::move(incoming_services_request),
- std::move(agent_controller_request)});
-
- EnsureAgentIsRunning(agent_url, [this, agent_url] {
- // If the agent was terminating and has restarted, forwarding connections
- // here is redundant, since it was already forwarded earlier.
- ForwardConnectionsToAgent(agent_url);
- });
-}
-
-void AgentRunner::ConnectToEntityProvider(
- const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) {
- // Drop all new requests if AgentRunner is terminating.
- if (*terminating_) {
- return;
- }
-
- pending_entity_provider_connections_[agent_url] = {
- std::move(entity_provider_request), std::move(agent_controller_request)};
-
- EnsureAgentIsRunning(agent_url, [this, agent_url] {
- auto it = pending_entity_provider_connections_.find(agent_url);
- FXL_DCHECK(it != pending_entity_provider_connections_.end());
- running_agents_[agent_url]->NewEntityProviderConnection(
- std::move(it->second.entity_provider_request),
- std::move(it->second.agent_controller_request));
- pending_entity_provider_connections_.erase(it);
- });
-}
-
-void AgentRunner::RemoveAgent(const std::string agent_url) {
- running_agents_.erase(agent_url);
-
- if (*terminating_) {
- return;
- }
-
- UpdateWatchers();
-
- // At this point, if there are pending requests to start the agent (because
- // the previous one was in a terminating state), we can start it up again.
- if (run_agent_callbacks_.find(agent_url) != run_agent_callbacks_.end()) {
- RunAgent(agent_url);
- }
-}
-
-void AgentRunner::ForwardConnectionsToAgent(const std::string& agent_url) {
- // Did we hold onto new connections as the previous one was exiting?
- auto found_it = pending_agent_connections_.find(agent_url);
- if (found_it != pending_agent_connections_.end()) {
- AgentContextImpl* agent = running_agents_[agent_url].get();
- for (auto& pending_connection : found_it->second) {
- agent->NewAgentConnection(
- pending_connection.requestor_url,
- std::move(pending_connection.incoming_services_request),
- std::move(pending_connection.agent_controller_request));
- }
- pending_agent_connections_.erase(found_it);
- }
-}
-
-void AgentRunner::ScheduleTask(const std::string& agent_url,
- fuchsia::modular::TaskInfo task_info) {
- AgentRunnerStorage::TriggerInfo data;
- data.agent_url = agent_url;
- data.task_id = task_info.task_id;
-
- if (task_info.trigger_condition.is_message_on_queue()) {
- data.queue_name = task_info.trigger_condition.message_on_queue();
- data.task_type = AgentRunnerStorage::TriggerInfo::TYPE_QUEUE_MESSAGE;
- } else if (task_info.trigger_condition.is_queue_deleted()) {
- data.queue_token = task_info.trigger_condition.queue_deleted();
- data.task_type = AgentRunnerStorage::TriggerInfo::TYPE_QUEUE_DELETION;
- } else if (task_info.trigger_condition.is_alarm_in_seconds()) {
- data.task_type = AgentRunnerStorage::TriggerInfo::TYPE_ALARM;
- data.alarm_in_seconds = task_info.trigger_condition.alarm_in_seconds();
- } else {
- // Not a defined trigger condition.
- FXL_NOTREACHED();
- }
-
- if (task_info.persistent) {
- // |AgentRunnerStorageImpl::WriteTask| eventually calls |AddedTask()| after
- // this trigger information has been added to the ledger via a ledger page
- // watching mechanism.
- agent_runner_storage_->WriteTask(agent_url, data, [](bool) {});
- } else {
- AddedTask(MakeTriggerKey(agent_url, data.task_id), data);
- }
-}
-
-void AgentRunner::AddedTask(const std::string& key,
- AgentRunnerStorage::TriggerInfo data) {
- switch (data.task_type) {
- case AgentRunnerStorage::TriggerInfo::TYPE_QUEUE_MESSAGE:
- ScheduleMessageQueueNewMessageTask(data.agent_url, data.task_id,
- data.queue_name);
- break;
- case AgentRunnerStorage::TriggerInfo::TYPE_QUEUE_DELETION:
- ScheduleMessageQueueDeletionTask(data.agent_url, data.task_id,
- data.queue_token);
- break;
- case AgentRunnerStorage::TriggerInfo::TYPE_ALARM:
- ScheduleAlarmTask(data.agent_url, data.task_id, data.alarm_in_seconds,
- true);
- break;
- }
-
- task_by_ledger_key_[key] = std::make_pair(data.agent_url, data.task_id);
- UpdateWatchers();
-}
-
-void AgentRunner::DeletedTask(const std::string& key) {
- auto data = task_by_ledger_key_.find(key);
- if (data == task_by_ledger_key_.end()) {
- // Never scheduled, nothing to delete.
- return;
- }
-
- DeleteMessageQueueTask(data->second.first, data->second.second);
- DeleteAlarmTask(data->second.first, data->second.second);
-
- task_by_ledger_key_.erase(key);
- UpdateWatchers();
-}
-
-void AgentRunner::DeleteMessageQueueTask(const std::string& agent_url,
- const std::string& task_id) {
- auto agent_it = watched_queues_.find(agent_url);
- if (agent_it == watched_queues_.end()) {
- return;
- }
-
- auto& agent_map = agent_it->second;
- auto task_id_it = agent_map.find(task_id);
- if (task_id_it == agent_map.end()) {
- return;
- }
-
- // The specific type of message queue task identified by |task_id| is not
- // available, so explicitly clean up both types.
- message_queue_manager_->DropMessageWatcher(kAgentComponentNamespace,
- agent_url, task_id_it->second);
- message_queue_manager_->DropDeletionWatcher(kAgentComponentNamespace,
- agent_url, task_id_it->second);
-
- watched_queues_[agent_url].erase(task_id);
- if (watched_queues_[agent_url].empty()) {
- watched_queues_.erase(agent_url);
- }
-}
-
-void AgentRunner::DeleteAlarmTask(const std::string& agent_url,
- const std::string& task_id) {
- auto agent_it = running_alarms_.find(agent_url);
- if (agent_it == running_alarms_.end()) {
- return;
- }
-
- auto& agent_map = agent_it->second;
- auto task_id_it = agent_map.find(task_id);
- if (task_id_it == agent_map.end()) {
- return;
- }
-
- running_alarms_[agent_url].erase(task_id);
- if (running_alarms_[agent_url].empty()) {
- running_alarms_.erase(agent_url);
- }
-}
-
-void AgentRunner::ScheduleMessageQueueDeletionTask(
- const std::string& agent_url, const std::string& task_id,
- const std::string& queue_token) {
- auto found_it = watched_queues_.find(agent_url);
- if (found_it != watched_queues_.end()) {
- if (found_it->second.count(task_id) != 0) {
- if (found_it->second[task_id] == queue_token) {
- // This means that we are already watching the message queue.
- // Do nothing.
- return;
- }
-
- // We were watching some other queue for this task_id. Stop watching.
- message_queue_manager_->DropMessageWatcher(
- kAgentComponentNamespace, agent_url, found_it->second[task_id]);
- }
- } else {
- bool inserted = false;
- std::tie(found_it, inserted) = watched_queues_.emplace(
- agent_url, std::map<std::string, std::string>());
- FXL_DCHECK(inserted);
- }
-
- found_it->second[task_id] = queue_token;
- message_queue_manager_->RegisterDeletionWatcher(
- kAgentComponentNamespace, agent_url, queue_token,
- [this, agent_url, task_id, terminating = terminating_] {
- // If agent runner is terminating or has already terminated, do not run
- // any new tasks.
- if (*terminating) {
- return;
- }
-
- EnsureAgentIsRunning(agent_url, [agent_url, task_id, this] {
- running_agents_[agent_url]->NewTask(task_id);
- });
- });
-}
-
-void AgentRunner::ScheduleMessageQueueNewMessageTask(
- const std::string& agent_url, const std::string& task_id,
- const std::string& queue_name) {
- auto found_it = watched_queues_.find(agent_url);
- if (found_it != watched_queues_.end()) {
- if (found_it->second.count(task_id) != 0) {
- if (found_it->second[task_id] == queue_name) {
- // This means that we are already watching the message queue.
- // Do nothing.
- return;
- }
-
- // We were watching some other queue for this task_id. Stop watching.
- message_queue_manager_->DropMessageWatcher(
- kAgentComponentNamespace, agent_url, found_it->second[task_id]);
- }
- } else {
- bool inserted = false;
- std::tie(found_it, inserted) = watched_queues_.emplace(
- agent_url, std::map<std::string, std::string>());
- FXL_DCHECK(inserted);
- }
-
- found_it->second[task_id] = queue_name;
- auto terminating = terminating_;
- message_queue_manager_->RegisterMessageWatcher(
- kAgentComponentNamespace, agent_url, queue_name,
- [this, agent_url, task_id, terminating] {
- // If agent runner is terminating or has already terminated, do not run
- // any new tasks.
- if (*terminating) {
- return;
- }
-
- EnsureAgentIsRunning(agent_url, [agent_url, task_id, this] {
- running_agents_[agent_url]->NewTask(task_id);
- });
- });
-}
-
-void AgentRunner::ScheduleAlarmTask(const std::string& agent_url,
- const std::string& task_id,
- const uint32_t alarm_in_seconds,
- const bool is_new_request) {
- auto found_it = running_alarms_.find(agent_url);
- if (found_it != running_alarms_.end()) {
- if (found_it->second.count(task_id) != 0 && is_new_request) {
- // We are already running a task with the same task_id. We might
- // just have to update the alarm frequency.
- found_it->second[task_id] = alarm_in_seconds;
- return;
- }
- } else {
- bool inserted = false;
- std::tie(found_it, inserted) =
- running_alarms_.emplace(agent_url, std::map<std::string, uint32_t>());
- FXL_DCHECK(inserted);
- }
-
- found_it->second[task_id] = alarm_in_seconds;
- auto terminating = terminating_;
- async::PostDelayedTask(
- async_get_default_dispatcher(),
- [this, agent_url, task_id, terminating] {
- // If agent runner is terminating, do not run any new tasks.
- if (*terminating) {
- return;
- }
-
- // Stop the alarm if entry not found.
- auto found_it = running_alarms_.find(agent_url);
- if (found_it == running_alarms_.end()) {
- return;
- }
- if (found_it->second.count(task_id) == 0) {
- return;
- }
-
- EnsureAgentIsRunning(agent_url, [agent_url, task_id, found_it, this]() {
- running_agents_[agent_url]->NewTask(task_id);
- ScheduleAlarmTask(agent_url, task_id, found_it->second[task_id],
- false);
- });
- },
- zx::sec(alarm_in_seconds));
-}
-
-void AgentRunner::DeleteTask(const std::string& agent_url,
- const std::string& task_id) {
- // This works for non-persistent tasks too since
- // |AgentRunnerStorageImpl::DeleteTask| handles missing keys in ledger
- // gracefully.
- agent_runner_storage_->DeleteTask(agent_url, task_id, [](bool) {});
-}
-
-std::vector<std::string> AgentRunner::GetAllAgents() {
- // A set of all agents that are either running or scheduled to be run.
- std::set<std::string> agents;
- for (auto const& it : running_agents_) {
- agents.insert(it.first);
- }
- for (auto const& it : watched_queues_) {
- agents.insert(it.first);
- }
- for (auto const& it : running_alarms_) {
- agents.insert(it.first);
- }
-
- std::vector<std::string> agent_urls;
- for (auto const& it : agents) {
- agent_urls.push_back(it);
- }
-
- return agent_urls;
-}
-
-void AgentRunner::UpdateWatchers() {
- if (*terminating_) {
- return;
- }
-
- for (auto& watcher : agent_provider_watchers_.ptrs()) {
- (*watcher)->OnUpdate(GetAllAgents());
- }
-}
-
-void AgentRunner::Watch(
- fidl::InterfaceHandle<fuchsia::modular::AgentProviderWatcher> watcher) {
- auto ptr = watcher.Bind();
- // 1. Send this watcher the current list of agents.
- ptr->OnUpdate(GetAllAgents());
-
- // 2. Add this watcher to a set that is updated when a new list of agents is
- // available.
- agent_provider_watchers_.AddInterfacePtr(std::move(ptr));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/agent_runner/agent_runner.h b/bin/sessionmgr/agent_runner/agent_runner.h
deleted file mode 100644
index ca734f0..0000000
--- a/bin/sessionmgr/agent_runner/agent_runner.h
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_H_
-
-#include <functional>
-#include <map>
-#include <memory>
-#include <string>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner_storage.h"
-
-namespace modular {
-
-// This is the component namespace we give to all agents; used for namespacing
-// storage between different component types.
-constexpr char kAgentComponentNamespace[] = "agents";
-
-class AgentContextImpl;
-class EntityProviderRunner;
-class MessageQueueManager;
-
-// This class provides a way for components to connect to agents and
-// manages the life time of a running agent.
-class AgentRunner : fuchsia::modular::AgentProvider,
- AgentRunnerStorage::NotificationDelegate {
- public:
- AgentRunner(
- fuchsia::sys::Launcher* launcher,
- MessageQueueManager* message_queue_manager,
- fuchsia::ledger::internal::LedgerRepository* ledger_repository,
- AgentRunnerStorage* agent_runner_storage,
- fuchsia::auth::TokenManager* token_manager,
- fuchsia::modular::UserIntelligenceProvider* user_intelligence_provider,
- EntityProviderRunner* entity_provider_runner);
- ~AgentRunner() override;
-
- void Connect(fidl::InterfaceRequest<fuchsia::modular::AgentProvider> request);
-
- // |callback| is called after - (1) all agents have been shutdown and (2)
- // no new tasks are scheduled to run.
- void Teardown(const std::function<void()>& callback);
-
- // Connects to an agent (and starts it up if it doesn't exist) through
- // |fuchsia::modular::Agent.Connect|. Called using
- // fuchsia::modular::ComponentContext.
- void ConnectToAgent(const std::string& requestor_url,
- const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request);
-
- // Connects to an agent (and starts it up if it doesn't exist) through its
- // |fuchsia::modular::EntityProvider| service.
- void ConnectToEntityProvider(
- const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request);
-
- // Removes an agent. Called by AgentContextImpl when it is done.
- // NOTE: This should NOT take a const reference, since |agent_url| will die
- // the moment we delete |AgentContextImpl|.
- void RemoveAgent(std::string agent_url);
-
- // fuchsia::modular::Agent at |agent_url| is run (if not already running) and
- // fuchsia::modular::Agent.RunTask() is called with |task_id| as the agent
- // specified identifier for the task when a trigger condition specified in
- // |task_info| is satisfied. The trigger condition is also replicated to the
- // ledger and the task my get scheduled on other user devices too.
- void ScheduleTask(const std::string& agent_url,
- fuchsia::modular::TaskInfo task_info);
-
- // Deletes a task for |agent_url| that is identified by agent provided
- // |task_id|. The trigger condition is removed from the ledger.
- void DeleteTask(const std::string& agent_url, const std::string& task_id);
-
- private:
- // Schedules the agent to start running if it isn't already running (e.g., it
- // could be not running or in the middle of terminating). Once the agent is in
- // a running state, calls |done|.
- void EnsureAgentIsRunning(const std::string& agent_url,
- const std::function<void()>& done);
-
- // Actually starts up an agent (used by |EnsureAgentIsRunning()| above).
- void RunAgent(const std::string& agent_url);
-
- // Will also start and initialize the agent as a consequence.
- void ForwardConnectionsToAgent(const std::string& agent_url);
-
- // Schedules a task that triggers when a new message is available on a message
- // queue.
- //
- // |agent_url| The URL of the agent creating the trigger. Only the message
- // queue owner can schedule a task with a new message trigger, and thus this
- // is also the agent url of the owner of the message queue.
- // |queue_name| The name of the message queue to observe.
- // |task_id| The identifier for the task.
- void ScheduleMessageQueueNewMessageTask(const std::string& agent_url,
- const std::string& task_id,
- const std::string& queue_name);
-
- // Schedules a task that triggers when a message queue is deleted.
- //
- // |agent_url| The URL of the agent creating the trigger.
- // |queue_token| The token of the queue that is to be observed.
- // |task_id| The identifier of the task.
- void ScheduleMessageQueueDeletionTask(const std::string& agent_url,
- const std::string& task_id,
- const std::string& queue_token);
-
- // Deletes the task scheduled for |agent_url| and |task_id|, regardless of the
- // task type.
- void DeleteMessageQueueTask(const std::string& agent_url,
- const std::string& task_id);
-
- // For triggers based on alarms.
- void ScheduleAlarmTask(const std::string& agent_url,
- const std::string& task_id, uint32_t alarm_in_seconds,
- bool is_new_request);
- void DeleteAlarmTask(const std::string& agent_url,
- const std::string& task_id);
-
- // A set of all agents that are either running or scheduled to be run.
- std::vector<std::string> GetAllAgents();
-
- // |UpdateWatchers| will not notify watchers if we are tearing down.
- void UpdateWatchers();
-
- // |fuchsia::modular::AgentProvider|
- void Watch(fidl::InterfaceHandle<fuchsia::modular::AgentProviderWatcher>
- watcher) override;
-
- // |AgentRunnerStorage::Delegate|
- void AddedTask(const std::string& key,
- AgentRunnerStorage::TriggerInfo data) override;
-
- // |AgentRunnerStorage::Delegate|
- void DeletedTask(const std::string& key) override;
-
- // agent URL -> { task id -> queue name }
- std::map<std::string, std::map<std::string, std::string>> watched_queues_;
-
- // agent URL -> { task id -> alarm in seconds }
- std::map<std::string, std::map<std::string, uint32_t>> running_alarms_;
-
- // agent URL -> pending agent connections
- // This map holds connections to an agent that we hold onto while the existing
- // agent is in a terminating state.
- struct PendingAgentConnectionEntry {
- const std::string requestor_url;
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request;
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request;
- };
- std::map<std::string, std::vector<struct PendingAgentConnectionEntry>>
- pending_agent_connections_;
-
- // agent URL -> pending entity provider connection
- // This map holds connections to an agents' fuchsia::modular::EntityProvider
- // that we hold onto while the existing agent is in a terminating state.
- struct PendingEntityProviderConnectionEntry {
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request;
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request;
- };
- std::map<std::string, struct PendingEntityProviderConnectionEntry>
- pending_entity_provider_connections_;
-
- // agent URL -> done callbacks to invoke once agent has started.
- // Holds requests to start an agent; in case an agent is already in a
- // terminating state, we pend those requests here until the agent terminates.
- std::map<std::string, std::vector<std::function<void()>>>
- run_agent_callbacks_;
-
- // agent URL -> modular.fuchsia::modular::AgentContext
- std::map<std::string, std::unique_ptr<AgentContextImpl>> running_agents_;
-
- // ledger key -> [agent URL, task ID]
- //
- // Used to delete entries from the maps above when a ledger key is
- // deleted. This saves us from having to parse a ledger key, which
- // becomes impossible once we use hashes to construct it, or from
- // having to read the value from the previous snapshot, which would
- // be nifty but is easy only once we have Operations.
- std::map<std::string, std::pair<std::string, std::string>>
- task_by_ledger_key_;
-
- fuchsia::sys::Launcher* const launcher_;
- MessageQueueManager* const message_queue_manager_;
- fuchsia::ledger::internal::LedgerRepository* const ledger_repository_;
- // |agent_runner_storage_| must outlive this class.
- AgentRunnerStorage* const agent_runner_storage_;
- fuchsia::auth::TokenManager* const token_manager_;
- fuchsia::modular::UserIntelligenceProvider* const user_intelligence_provider_;
- EntityProviderRunner* const entity_provider_runner_;
-
- fidl::BindingSet<fuchsia::modular::AgentProvider> agent_provider_bindings_;
- fidl::InterfacePtrSet<fuchsia::modular::AgentProviderWatcher>
- agent_provider_watchers_;
-
- // When this is marked true, no new new tasks will be scheduled.
- std::shared_ptr<bool> terminating_;
-
- OperationQueue operation_queue_;
-
- // Operations implemented here.
- class InitializeCall;
- class UpdateCall;
- class DeleteCall;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AgentRunner);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_H_
diff --git a/bin/sessionmgr/agent_runner/agent_runner_storage.cc b/bin/sessionmgr/agent_runner/agent_runner_storage.cc
deleted file mode 100644
index e5f6c6f..0000000
--- a/bin/sessionmgr/agent_runner/agent_runner_storage.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner_storage.h"
-
-namespace modular {
-
-AgentRunnerStorage::AgentRunnerStorage() = default;
-AgentRunnerStorage::~AgentRunnerStorage() = default;
-
-} // namespace modular
diff --git a/bin/sessionmgr/agent_runner/agent_runner_storage.h b/bin/sessionmgr/agent_runner/agent_runner_storage.h
deleted file mode 100644
index 562f1b9..0000000
--- a/bin/sessionmgr/agent_runner/agent_runner_storage.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_STORAGE_H_
-#define PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_STORAGE_H_
-
-#include <functional>
-#include <string>
-
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-// This abstract class is used by AgentRunner to persist data related to
-// agents, such as tasks and their triggers. See |AgentRunnerStorageImpl| for
-// an implementation of an AgentRunnerStorage.
-class AgentRunnerStorage {
- public:
- AgentRunnerStorage();
- virtual ~AgentRunnerStorage();
-
- struct TriggerInfo {
- std::string agent_url;
- std::string task_id;
-
- // NOTE(mesch): We could include the fuchsia::modular::TaskInfo fidl struct
- // here directly, but it contains a union, and dealing with a fidl union in
- // XDR is still rather complicated if we don't want to serialize the union
- // tag enum value directly.
- enum TaskType {
- TYPE_ALARM = 0,
- TYPE_QUEUE_MESSAGE = 1,
- TYPE_QUEUE_DELETION = 2,
- };
-
- TaskType task_type{};
-
- // If this is a TYPE_QUEUE_MESSAGE task, this is the message queue name. If
- // TYPE_QUEUE_DELETION, this is not set. Only the component that obtained
- // the message queue originally can observe new messages, so the name is
- // sufficient.
- std::string queue_name;
-
- // If this is a TYPE_QUEUE_DELETION task, this is the message queue token.
- // If TYPE_QUEUE_MESSAGE, this is not set. Both readers and writers can
- // observe message queue deletion, and thus the token must be used as
- // opposed to just the name.
- std::string queue_token;
-
- uint32_t alarm_in_seconds{};
- };
-
- // Consumers of AgentRunnerStorage provide a NotificationDelegate
- // implementation to |Initialize()| to receive notifications for newly added
- // and deleted tasks.
- class NotificationDelegate {
- public:
- virtual void AddedTask(const std::string& key,
- TriggerInfo trigger_info) = 0;
- virtual void DeletedTask(const std::string& key) = 0;
- };
-
- // Loads up all tasks (across all agents) from storage. |NotifcationDelegate|
- // is notified of each added task, and also for any added and deleted tasks in
- // the future.
- //
- // Ownership of |delegate| is not taken and it must out-live *this.
- virtual void Initialize(NotificationDelegate* delegate,
- std::function<void()> done) = 0;
-
- // Writes a new task to storage. |NotificationDelegate| will be notified of
- // the new task.
- virtual void WriteTask(const std::string& agent_url, TriggerInfo info,
- std::function<void(bool)> done) = 0;
-
- // Deletes existing task on the storage. |NotificationDelegate| will be
- // notified of the deleted task.
- virtual void DeleteTask(const std::string& agent_url,
- const std::string& task_id,
- std::function<void(bool)> done) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(AgentRunnerStorage);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_STORAGE_H_
diff --git a/bin/sessionmgr/agent_runner/agent_runner_storage_impl.cc b/bin/sessionmgr/agent_runner/agent_runner_storage_impl.cc
deleted file mode 100644
index 193457a..0000000
--- a/bin/sessionmgr/agent_runner/agent_runner_storage_impl.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner_storage_impl.h"
-
-#include <functional>
-#include <utility>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace modular {
-namespace {
-
-void XdrTriggerInfo_v1(XdrContext* const xdr,
- AgentRunnerStorage::TriggerInfo* const data) {
- xdr->Field("agent_url", &data->agent_url);
- xdr->Field("task_id", &data->task_id);
- xdr->Field("task_type", &data->task_type);
- xdr->Field("alarm_in_seconds", &data->alarm_in_seconds);
- xdr->Field("queue_name", &data->queue_name);
- xdr->Field("queue_token", &data->queue_token);
-}
-
-void XdrTriggerInfo_v2(XdrContext* const xdr,
- AgentRunnerStorage::TriggerInfo* const data) {
- if (!xdr->Version(2)) {
- return;
- }
- xdr->Field("agent_url", &data->agent_url);
- xdr->Field("task_id", &data->task_id);
- xdr->Field("task_type", &data->task_type);
- xdr->Field("alarm_in_seconds", &data->alarm_in_seconds);
- xdr->Field("queue_name", &data->queue_name);
- xdr->Field("queue_token", &data->queue_token);
-}
-
-constexpr XdrFilterType<AgentRunnerStorage::TriggerInfo> XdrTriggerInfo[] = {
- XdrTriggerInfo_v2,
- XdrTriggerInfo_v1,
- nullptr,
-};
-
-} // namespace
-
-class AgentRunnerStorageImpl::InitializeCall : public Operation<> {
- public:
- InitializeCall(NotificationDelegate* const delegate,
- fuchsia::ledger::PageSnapshotPtr snapshot,
- std::function<void()> done)
- : Operation("AgentRunnerStorageImpl::InitializeCall", std::move(done)),
- delegate_(delegate),
- snapshot_(std::move(snapshot)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- GetEntries(snapshot_.get(), &entries_,
- [this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR)
- << trace_name() << " "
- << "GetEntries() " << fidl::ToUnderlying(status);
- return;
- }
-
- Cont(flow);
- });
- }
-
- void Cont(FlowToken /*flow*/) {
- if (entries_.empty()) {
- // No existing entries.
- return;
- }
-
- for (const auto& entry : entries_) {
- std::string key(reinterpret_cast<const char*>(entry.key.data()),
- entry.key.size());
- std::string value;
- if (!fsl::StringFromVmo(*entry.value, &value)) {
- FXL_LOG(ERROR) << trace_name() << " " << key << " "
- << "VMO could nt be copied.";
- continue;
- }
-
- TriggerInfo data;
- if (!XdrRead(value, &data, XdrTriggerInfo)) {
- return;
- }
- delegate_->AddedTask(key, std::move(data));
- }
- }
-
- NotificationDelegate* const delegate_;
- fuchsia::ledger::PageSnapshotPtr snapshot_;
- std::vector<fuchsia::ledger::Entry> entries_;
- FXL_DISALLOW_COPY_AND_ASSIGN(InitializeCall);
-};
-
-class AgentRunnerStorageImpl::WriteTaskCall : public Operation<bool> {
- public:
- WriteTaskCall(AgentRunnerStorageImpl* storage, std::string agent_url,
- TriggerInfo data, std::function<void(bool)> done)
- : Operation("AgentRunnerStorageImpl::WriteTaskCall", done),
- storage_(storage),
- agent_url_(std::move(agent_url)),
- data_(std::move(data)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &success_result_};
-
- std::string key = MakeTriggerKey(agent_url_, data_.task_id);
- std::string value;
- XdrWrite(&value, &data_, XdrTriggerInfo);
-
- storage_->page()->PutWithPriority(
- to_array(key), to_array(value), fuchsia::ledger::Priority::EAGER,
- [this, key, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " " << key << " "
- << "Page.PutWithPriority() "
- << fidl::ToUnderlying(status);
- return;
- }
-
- success_result_ = true;
- });
- }
-
- bool success_result_ = false;
- AgentRunnerStorageImpl* const storage_;
- const std::string agent_url_;
- TriggerInfo data_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(WriteTaskCall);
-};
-
-class AgentRunnerStorageImpl::DeleteTaskCall : public Operation<bool> {
- public:
- DeleteTaskCall(AgentRunnerStorageImpl* storage, std::string agent_url,
- std::string task_id, std::function<void(bool)> done)
- : Operation("AgentRunnerStorageImpl::DeleteTaskCall", done),
- storage_(storage),
- agent_url_(std::move(agent_url)),
- task_id_(std::move(task_id)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &success_result_};
-
- std::string key = MakeTriggerKey(agent_url_, task_id_);
- storage_->page()->Delete(
- to_array(key), [this, key, flow](fuchsia::ledger::Status status) {
- // fuchsia::ledger::Status::INVALID_TOKEN is okay because we might
- // have gotten a request to delete a token which does not exist. This
- // is okay.
- if (status != fuchsia::ledger::Status::OK &&
- status != fuchsia::ledger::Status::INVALID_TOKEN) {
- FXL_LOG(ERROR) << trace_name() << " " << key << " "
- << "Page.Delete() " << fidl::ToUnderlying(status);
- return;
- }
- success_result_ = true;
- });
- }
-
- bool success_result_ = false;
- AgentRunnerStorageImpl* const storage_;
- const std::string agent_url_;
- const std::string task_id_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DeleteTaskCall);
-};
-
-AgentRunnerStorageImpl::AgentRunnerStorageImpl(LedgerClient* ledger_client,
- fuchsia::ledger::PageId page_id)
- : PageClient("AgentRunnerStorageImpl", ledger_client, std::move(page_id)),
- delegate_(nullptr) {}
-
-AgentRunnerStorageImpl::~AgentRunnerStorageImpl() = default;
-
-void AgentRunnerStorageImpl::Initialize(NotificationDelegate* const delegate,
- std::function<void()> done) {
- FXL_DCHECK(!delegate_);
- delegate_ = delegate;
- operation_queue_.Add(
- new InitializeCall(delegate_, NewSnapshot(), std::move(done)));
-}
-
-void AgentRunnerStorageImpl::WriteTask(const std::string& agent_url,
- const TriggerInfo data,
- std::function<void(bool)> done) {
- operation_queue_.Add(
- new WriteTaskCall(this, agent_url, data, std::move(done)));
-}
-
-void AgentRunnerStorageImpl::DeleteTask(const std::string& agent_url,
- const std::string& task_id,
- std::function<void(bool)> done) {
- operation_queue_.Add(
- new DeleteTaskCall(this, agent_url, task_id, std::move(done)));
-}
-
-void AgentRunnerStorageImpl::OnPageChange(const std::string& key,
- const std::string& value) {
- FXL_DCHECK(delegate_ != nullptr);
- operation_queue_.Add(new SyncCall([this, key, value] {
- TriggerInfo data;
- if (!XdrRead(value, &data, XdrTriggerInfo)) {
- return;
- }
- delegate_->AddedTask(key, data);
- }));
-}
-
-void AgentRunnerStorageImpl::OnPageDelete(const std::string& key) {
- FXL_DCHECK(delegate_ != nullptr);
- operation_queue_.Add(
- new SyncCall([this, key] { delegate_->DeletedTask(key); }));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/agent_runner/agent_runner_storage_impl.h b/bin/sessionmgr/agent_runner/agent_runner_storage_impl.h
deleted file mode 100644
index 1fe95bc..0000000
--- a/bin/sessionmgr/agent_runner/agent_runner_storage_impl.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_STORAGE_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_STORAGE_IMPL_H_
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner_storage.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/types.h"
-
-namespace modular {
-
-// An implementation of |AgentRunnerStorage| that persists data in the ledger.
-class AgentRunnerStorageImpl : public AgentRunnerStorage, PageClient {
- public:
- explicit AgentRunnerStorageImpl(LedgerClient* ledger_client,
- fuchsia::ledger::PageId page_id);
- ~AgentRunnerStorageImpl() override;
-
- private:
- // |AgentRunnerStorage|
- void Initialize(NotificationDelegate* delegate,
- std::function<void()> done) override;
-
- // |AgentRunnerStorage|
- void WriteTask(const std::string& agent_url, TriggerInfo data,
- std::function<void(bool)> done) override;
-
- // |AgentRunnerStorage|
- void DeleteTask(const std::string& agent_url, const std::string& task_id,
- std::function<void(bool)> done) override;
-
- // Operation subclasses:
- class InitializeCall;
- class WriteTaskCall;
- class DeleteTaskCall;
-
- // |PageClient|
- void OnPageChange(const std::string& key, const std::string& value) override;
- // |PageClient|
- void OnPageDelete(const std::string& key) override;
-
- // Only valid after |Initialize()| is called.
- NotificationDelegate* delegate_; // Not owned.
-
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AgentRunnerStorageImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_AGENT_RUNNER_AGENT_RUNNER_STORAGE_IMPL_H_
diff --git a/bin/sessionmgr/agent_runner/agent_runner_unittest.cc b/bin/sessionmgr/agent_runner/agent_runner_unittest.cc
deleted file mode 100644
index 0ec09da..0000000
--- a/bin/sessionmgr/agent_runner/agent_runner_unittest.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner.h"
-
-#include <memory>
-
-#include <fs/service.h>
-#include <fs/synchronous-vfs.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/component/cpp/testing/fake_launcher.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/macros.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h"
-#include "peridot/bin/sessionmgr/message_queue/message_queue_manager.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/testing/fake_agent_runner_storage.h"
-#include "peridot/lib/testing/mock_base.h"
-#include "peridot/lib/testing/test_with_ledger.h"
-
-namespace modular {
-namespace testing {
-namespace {
-
-using ::component::testing::FakeLauncher;
-
-class AgentRunnerTest : public TestWithLedger {
- public:
- AgentRunnerTest() = default;
-
- void SetUp() override {
- TestWithLedger::SetUp();
-
- mqm_ = std::make_unique<MessageQueueManager>(
- ledger_client(), MakePageId("0123456789123456"), mq_data_dir_.path());
- entity_provider_runner_ = std::make_unique<EntityProviderRunner>(nullptr);
- // The |fuchsia::modular::UserIntelligenceProvider| below must be nullptr in
- // order for agent creation to be synchronous, which these tests assume.
- agent_runner_ = std::make_unique<AgentRunner>(
- &launcher_, mqm_.get(), ledger_repository(), &agent_runner_storage_,
- token_manager_.get(), nullptr, entity_provider_runner_.get());
- }
-
- void TearDown() override {
- agent_runner_.reset();
- entity_provider_runner_.reset();
- mqm_.reset();
-
- TestWithLedger::TearDown();
- }
-
- MessageQueueManager* message_queue_manager() { return mqm_.get(); }
-
- protected:
- AgentRunner* agent_runner() { return agent_runner_.get(); }
- FakeLauncher* launcher() { return &launcher_; }
-
- private:
- FakeLauncher launcher_;
-
- files::ScopedTempDir mq_data_dir_;
- std::unique_ptr<MessageQueueManager> mqm_;
- FakeAgentRunnerStorage agent_runner_storage_;
- std::unique_ptr<EntityProviderRunner> entity_provider_runner_;
- std::unique_ptr<AgentRunner> agent_runner_;
-
- fuchsia::auth::TokenManagerPtr token_manager_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AgentRunnerTest);
-};
-
-class MyDummyAgent : fuchsia::modular::Agent,
- public fuchsia::sys::ComponentController,
- public testing::MockBase {
- public:
- MyDummyAgent(zx::channel directory_request,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl)
- : vfs_(async_get_default_dispatcher()),
- outgoing_directory_(fbl::AdoptRef(new fs::PseudoDir())),
- controller_(this, std::move(ctrl)),
- agent_binding_(this) {
- outgoing_directory_->AddEntry(
- fuchsia::modular::Agent::Name_,
- fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
- agent_binding_.Bind(std::move(channel));
- return ZX_OK;
- })));
- vfs_.ServeDirectory(outgoing_directory_, std::move(directory_request));
- }
-
- void KillApplication() { controller_.Unbind(); }
-
- size_t GetCallCount(const std::string func) { return counts.count(func); }
-
- private:
- // |ComponentController|
- void Kill() override { ++counts["Kill"]; }
- // |ComponentController|
- void Detach() override { ++counts["Detach"]; }
-
- // |fuchsia::modular::Agent|
- void Connect(
- std::string /*requestor_url*/,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> /*services*/)
- override {
- ++counts["Connect"];
- }
-
- // |fuchsia::modular::Agent|
- void RunTask(std::string /*task_id*/,
- RunTaskCallback /*callback*/) override {
- ++counts["RunTask"];
- }
-
- private:
- fs::SynchronousVfs vfs_;
- fbl::RefPtr<fs::PseudoDir> outgoing_directory_;
- fidl::Binding<fuchsia::sys::ComponentController> controller_;
- fidl::Binding<fuchsia::modular::Agent> agent_binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(MyDummyAgent);
-};
-
-// Test that connecting to an agent will start it up.
-// Then there should be an fuchsia::modular::Agent.Connect().
-TEST_F(AgentRunnerTest, ConnectToAgent) {
- int agent_launch_count = 0;
- std::unique_ptr<MyDummyAgent> dummy_agent;
- constexpr char kMyAgentUrl[] = "file:///my_agent";
- launcher()->RegisterComponent(
- kMyAgentUrl,
- [&dummy_agent, &agent_launch_count](
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- dummy_agent = std::make_unique<MyDummyAgent>(
- std::move(launch_info.directory_request), std::move(ctrl));
- ++agent_launch_count;
- });
-
- fuchsia::sys::ServiceProviderPtr incoming_services;
- fuchsia::modular::AgentControllerPtr agent_controller;
- agent_runner()->ConnectToAgent("requestor_url", kMyAgentUrl,
- incoming_services.NewRequest(),
- agent_controller.NewRequest());
-
- RunLoopWithTimeoutOrUntil([&dummy_agent] {
- return dummy_agent && dummy_agent->GetCallCount("Connect") > 0;
- });
- EXPECT_EQ(1, agent_launch_count);
- dummy_agent->ExpectCalledOnce("Connect");
- dummy_agent->ExpectNoOtherCalls();
-
- // Connecting to the same agent again shouldn't launch a new instance and
- // shouldn't re-initialize the existing instance of the agent application,
- // but should call |Connect()|.
-
- fuchsia::modular::AgentControllerPtr agent_controller2;
- fuchsia::sys::ServiceProviderPtr incoming_services2;
- agent_runner()->ConnectToAgent("requestor_url2", kMyAgentUrl,
- incoming_services2.NewRequest(),
- agent_controller2.NewRequest());
-
- RunLoopWithTimeoutOrUntil([&dummy_agent] {
- return dummy_agent && dummy_agent->GetCallCount("Connect");
- });
- EXPECT_EQ(1, agent_launch_count);
- dummy_agent->ExpectCalledOnce("Connect");
- dummy_agent->ExpectNoOtherCalls();
-}
-
-// Test that if an agent application dies, it is removed from agent runner
-// (which means outstanding AgentControllers are closed).
-TEST_F(AgentRunnerTest, AgentController) {
- std::unique_ptr<MyDummyAgent> dummy_agent;
- constexpr char kMyAgentUrl[] = "file:///my_agent";
- launcher()->RegisterComponent(
- kMyAgentUrl,
- [&dummy_agent](
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- dummy_agent = std::make_unique<MyDummyAgent>(
- std::move(launch_info.directory_request), std::move(ctrl));
- });
-
- fuchsia::sys::ServiceProviderPtr incoming_services;
- fuchsia::modular::AgentControllerPtr agent_controller;
- agent_runner()->ConnectToAgent("requestor_url", kMyAgentUrl,
- incoming_services.NewRequest(),
- agent_controller.NewRequest());
-
- RunLoopWithTimeoutOrUntil([&dummy_agent] { return !!dummy_agent; });
- dummy_agent->KillApplication();
-
- // fuchsia::modular::Agent application died, so check that
- // fuchsia::modular::AgentController dies here.
- agent_controller.set_error_handler(
- [&agent_controller](zx_status_t status) { agent_controller.Unbind(); });
- RunLoopWithTimeoutOrUntil(
- [&agent_controller] { return !agent_controller.is_bound(); });
- EXPECT_FALSE(agent_controller.is_bound());
-}
-
-} // namespace
-} // namespace testing
-} // namespace modular
diff --git a/bin/sessionmgr/component_context_impl.cc b/bin/sessionmgr/component_context_impl.cc
deleted file mode 100644
index cd7dc9c..0000000
--- a/bin/sessionmgr/component_context_impl.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/component_context_impl.h"
-
-#include <utility>
-
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner.h"
-#include "peridot/lib/fidl/array_to_string.h"
-
-namespace modular {
-
-ComponentContextImpl::ComponentContextImpl(const ComponentContextInfo& info,
- std::string component_namespace,
- std::string component_instance_id,
- std::string component_url)
- : message_queue_manager_(info.message_queue_manager),
- agent_runner_(info.agent_runner),
- ledger_repository_(info.ledger_repository),
- entity_provider_runner_(info.entity_provider_runner),
- component_namespace_(std::move(component_namespace)),
- component_instance_id_(std::move(component_instance_id)),
- component_url_(std::move(component_url)) {
- FXL_DCHECK(message_queue_manager_);
- FXL_DCHECK(agent_runner_);
- FXL_DCHECK(ledger_repository_);
- FXL_DCHECK(entity_provider_runner_);
-}
-
-ComponentContextImpl::~ComponentContextImpl() = default;
-
-void ComponentContextImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-fuchsia::modular::ComponentContextPtr ComponentContextImpl::NewBinding() {
- fuchsia::modular::ComponentContextPtr ptr;
- Connect(ptr.NewRequest());
- return ptr;
-}
-
-void ComponentContextImpl::GetLedger(
- fidl::InterfaceRequest<fuchsia::ledger::Ledger> request) {
- ledger_repository_->GetLedger(to_array(component_url_), std::move(request));
-}
-
-void ComponentContextImpl::ConnectToAgent(
- std::string url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) {
- agent_runner_->ConnectToAgent(component_instance_id_, url,
- std::move(incoming_services_request),
- std::move(agent_controller_request));
-}
-
-void ComponentContextImpl::ObtainMessageQueue(
- std::string name,
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request) {
- message_queue_manager_->ObtainMessageQueue(
- component_namespace_, component_instance_id_, name, std::move(request));
-}
-
-void ComponentContextImpl::DeleteMessageQueue(std::string name) {
- message_queue_manager_->DeleteMessageQueue(component_namespace_,
- component_instance_id_, name);
-}
-
-void ComponentContextImpl::GetMessageSender(
- std::string queue_token,
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request) {
- message_queue_manager_->GetMessageSender(queue_token, std::move(request));
-}
-
-void ComponentContextImpl::GetEntityResolver(
- fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request) {
- entity_provider_runner_->ConnectEntityResolver(std::move(request));
-}
-
-void ComponentContextImpl::CreateEntityWithData(
- std::vector<fuchsia::modular::TypeToDataEntry> type_to_data,
- CreateEntityWithDataCallback result) {
- std::map<std::string, std::string> copy;
- for (const auto& it : type_to_data) {
- copy[it.type] = it.data;
- }
- result(entity_provider_runner_->CreateReferenceFromData(std::move(copy)));
-}
-
-void ComponentContextImpl::GetPackageName(GetPackageNameCallback result) {
- result(component_url_);
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/component_context_impl.h b/bin/sessionmgr/component_context_impl.h
deleted file mode 100644
index 15416cf..0000000
--- a/bin/sessionmgr/component_context_impl.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_COMPONENT_CONTEXT_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_COMPONENT_CONTEXT_IMPL_H_
-
-#include <string>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h"
-#include "peridot/bin/sessionmgr/message_queue/message_queue_manager.h"
-
-namespace modular {
-
-class AgentRunner;
-
-// The parameters of component context that do not vary by instance.
-struct ComponentContextInfo {
- MessageQueueManager* const message_queue_manager;
- AgentRunner* const agent_runner;
- fuchsia::ledger::internal::LedgerRepository* const ledger_repository;
- EntityProviderRunner* const entity_provider_runner;
-};
-
-// Implements the fuchsia::modular::ComponentContext interface, which is
-// provided to modules and agents. The interface is public, because the class
-// doesn't contain the Bindings for this interface. TODO(mesch): Move
-// bindings into the class.
-class ComponentContextImpl : public fuchsia::modular::ComponentContext {
- public:
- // * A component namespace identifies components whose lifetimes are related,
- // where all of their persisted information will live together; for modules
- // this is the story id, for agents it is kAgentComponentNamespace, etc.
- // * A component instance ID identifies a particular instance of a component;
- // for modules, this is the module path in their story. For agents, it is
- // the agent URL.
- // * A component URL is the origin from which the executable associated with
- // the component was fetched from.
- explicit ComponentContextImpl(const ComponentContextInfo& info,
- std::string component_namespace,
- std::string component_instance_id,
- std::string component_url);
-
- ~ComponentContextImpl() override;
-
- const std::string& component_instance_id() { return component_instance_id_; }
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request);
- fuchsia::modular::ComponentContextPtr NewBinding();
-
- private:
- // |fuchsia::modular::ComponentContext|
- void GetLedger(
- fidl::InterfaceRequest<fuchsia::ledger::Ledger> request) override;
-
- // |fuchsia::modular::ComponentContext|
- void ConnectToAgent(std::string url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) override;
-
- // |fuchsia::modular::ComponentContext|
- void ObtainMessageQueue(
- std::string name,
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request) override;
-
- // |fuchsia::modular::ComponentContext|
- void DeleteMessageQueue(std::string name) override;
-
- // |fuchsia::modular::ComponentContext|
- void GetMessageSender(
- std::string queue_token,
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request) override;
-
- // |fuchsia::modular::ComponentContext|
- void GetEntityResolver(
- fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request)
- override;
-
- // |fuchsia::modular::ComponentContext|
- void CreateEntityWithData(
- std::vector<fuchsia::modular::TypeToDataEntry> type_to_data,
- CreateEntityWithDataCallback result) override;
-
- // |fuchsia::modular::ComponentContext|
- void GetPackageName(GetPackageNameCallback result) override;
-
- MessageQueueManager* const message_queue_manager_;
- AgentRunner* const agent_runner_;
- fuchsia::ledger::internal::LedgerRepository* const ledger_repository_;
- EntityProviderRunner* const entity_provider_runner_;
-
- const std::string component_namespace_;
- const std::string component_instance_id_;
- const std::string component_url_;
-
- fidl::BindingSet<fuchsia::modular::ComponentContext> bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ComponentContextImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_COMPONENT_CONTEXT_IMPL_H_
diff --git a/bin/sessionmgr/dev_session_shell.cc b/bin/sessionmgr/dev_session_shell.cc
deleted file mode 100644
index 8e60acd..0000000
--- a/bin/sessionmgr/dev_session_shell.cc
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implementation of a session shell for module development. It takes a
-// root module URL and data for its fuchsia::modular::Link as command line
-// arguments, which can be set using the basemgr --user-shell-args flag.
-
-#include <memory>
-#include <utility>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <zx/eventpair.h>
-
-#include "peridot/lib/common/names.h"
-#include "peridot/lib/fidl/single_service_app.h"
-#include "peridot/lib/fidl/view_host.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/test_driver.h"
-
-namespace {
-
-class Settings {
- public:
- explicit Settings(const fxl::CommandLine& command_line) {
- root_module =
- command_line.GetOptionValueWithDefault("root_module", "example_recipe");
- root_link = command_line.GetOptionValueWithDefault("root_link", "");
- story_id = command_line.GetOptionValueWithDefault("story_id", "story");
- module_under_test_url =
- command_line.GetOptionValueWithDefault("module_under_test_url", "");
- test_driver_url =
- command_line.GetOptionValueWithDefault("test_driver_url", "");
- }
-
- std::string root_module;
- std::string root_link;
- std::string story_id;
- std::string module_under_test_url;
- std::string test_driver_url;
-};
-
-class DevSessionShellApp : fuchsia::modular::StoryWatcher,
- fuchsia::modular::InterruptionListener,
- fuchsia::modular::NextListener,
- fuchsia::modular::SessionShell,
- public modular::ViewApp {
- public:
- explicit DevSessionShellApp(component::StartupContext* const startup_context,
- Settings settings)
- : ViewApp(startup_context),
- settings_(std::move(settings)),
- story_watcher_binding_(this) {
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
- startup_context->ConnectToEnvironmentService(
- session_shell_context_.NewRequest());
- session_shell_context_->GetStoryProvider(story_provider_.NewRequest());
- session_shell_context_->GetSuggestionProvider(
- suggestion_provider_.NewRequest());
- session_shell_context_->GetFocusController(focus_controller_.NewRequest());
- session_shell_context_->GetVisibleStoriesController(
- visible_stories_controller_.NewRequest());
-
- suggestion_provider_->SubscribeToInterruptions(
- interruption_listener_bindings_.AddBinding(this));
- suggestion_provider_->SubscribeToNext(
- next_listener_bindings_.AddBinding(this), 3);
-
- startup_context->outgoing().AddPublicService(
- session_shell_bindings_.GetHandler(this));
- }
-
- ~DevSessionShellApp() override = default;
-
- private:
- // |ViewApp|
- void CreateView(
- zx::eventpair view_token,
- fidl::InterfaceRequest<
- fuchsia::sys::ServiceProvider> /*incoming_services*/,
- fidl::InterfaceHandle<
- fuchsia::sys::ServiceProvider> /*outgoing_services*/) override {
- view_token_ = std::move(view_token);
-
- Connect();
- }
-
- void Connect() {
- FXL_CHECK(!!view_token_);
- FXL_CHECK(!!story_provider_);
- FXL_CHECK(!!puppet_master_);
- FXL_LOG(INFO) << "DevSessionShell START " << settings_.root_module << " "
- << settings_.root_link;
-
- auto scenic =
- startup_context()
- ->ConnectToEnvironmentService<fuchsia::ui::scenic::Scenic>();
- scenic::ViewContext context = {
- .session_and_listener_request =
- scenic::CreateScenicSessionPtrAndListenerRequest(scenic.get()),
- .view_token = std::move(view_token_),
- .startup_context = startup_context(),
- };
-
- view_ = std::make_unique<modular::ViewHost>(std::move(context));
-
- puppet_master_->ControlStory(settings_.story_id,
- story_puppet_master_.NewRequest());
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("root");
- add_mod.intent.handler = settings_.root_module;
- add_mod.intent.action = "action";
- add_mod.intent.parameters = CreateIntentParameters();
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- StartStoryById(settings_.story_id);
- });
- }
-
- fidl::VectorPtr<fuchsia::modular::IntentParameter> CreateIntentParameters() {
- if (settings_.module_under_test_url.empty() ||
- settings_.test_driver_url.empty()) {
- // For debugging: log that both items must be set in the event that one is
- // set and the other is not. It may be unclear why the intent is not being
- // created with the intended links if one is forgotten by accident.
- if (settings_.module_under_test_url.empty() !=
- settings_.test_driver_url.empty()) {
- FXL_LOG(WARNING) << "Both the module_under_test_url and "
- "test_driver_url must be set";
- }
- return nullptr;
- }
- auto intent_params =
- fidl::VectorPtr<fuchsia::modular::IntentParameter>::New(0);
- fuchsia::modular::IntentParameterData test_driver_link_data;
-
- rapidjson::Document document;
- document.SetObject();
- document.AddMember(modular::testing::kModuleUnderTestPath,
- settings_.module_under_test_url,
- document.GetAllocator());
- document.AddMember(modular::testing::kTestDriverPath,
- settings_.test_driver_url, document.GetAllocator());
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(modular::JsonValueToString(document), &vmo));
- test_driver_link_data.set_json(std::move(vmo).ToTransport());
-
- fuchsia::modular::IntentParameter test_driver_link_param;
- test_driver_link_param.name = modular::testing::kTestDriverLinkName;
- test_driver_link_param.data = std::move(test_driver_link_data);
- intent_params.push_back(std::move(test_driver_link_param));
-
- return intent_params;
- }
-
- void StartStoryById(const fidl::StringPtr& story_id) {
- story_provider_->GetController(story_id, story_controller_.NewRequest());
- story_controller_.set_error_handler([this, story_id](zx_status_t status) {
- FXL_LOG(ERROR) << "Story controller for story " << story_id
- << " died. Does this story exist?";
- });
-
- story_controller_->Watch(story_watcher_binding_.NewBinding());
-
- FXL_LOG(INFO) << "DevSessionShell Starting story with id: " << story_id;
-
- story_controller_->RequestStart();
- focus_controller_->Set(story_id);
- auto visible_stories = fidl::VectorPtr<std::string>::New(0);
- visible_stories.push_back(story_id);
- visible_stories_controller_->Set(std::move(visible_stories));
-
- if (!settings_.root_link.empty()) {
- fuchsia::modular::LinkPtr root;
-
- fuchsia::modular::LinkPath link_path = fuchsia::modular::LinkPath();
- link_path.link_name = "root";
- story_controller_->GetLink(std::move(link_path), root.NewRequest());
-
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(settings_.root_link, &vmo));
- root->Set(nullptr, std::move(vmo).ToTransport());
- }
- }
-
- // |SessionShell|
- void AttachView(fuchsia::modular::ViewIdentifier view_id,
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner) override {
- FXL_LOG(INFO) << "DevSessionShell AttachView(): " << view_id.story_id;
- view_->ConnectView(std::move(view_owner));
- }
-
- // |SessionShell|
- void DetachView(fuchsia::modular::ViewIdentifier view_id,
- std::function<void()> done) override {
- FXL_LOG(INFO) << "DevSessionShell DetachView(): " << view_id.story_id;
- done();
- }
-
- // |fuchsia::modular::StoryWatcher|
- void OnStateChange(fuchsia::modular::StoryState state) override {
- FXL_LOG(INFO) << "DevSessionShell State " << fidl::ToUnderlying(state);
- }
-
- // |fuchsia::modular::StoryWatcher|
- void OnModuleAdded(fuchsia::modular::ModuleData /*module_data*/) override {}
-
- // |fuchsia::modular::StoryWatcher|
- void OnModuleFocused(
- std::vector<std::string> /*module_path*/) override {}
-
- // |fuchsia::modular::NextListener|
- void OnNextResults(
- std::vector<fuchsia::modular::Suggestion> suggestions) override {
- FXL_VLOG(4)
- << "DevSessionShell/fuchsia::modular::NextListener::OnNextResults()";
- for (auto& suggestion : suggestions) {
- FXL_LOG(INFO) << " " << suggestion.uuid << " "
- << suggestion.display.headline;
- }
- }
-
- // |fuchsia::modular::InterruptionListener|
- void OnInterrupt(fuchsia::modular::Suggestion suggestion) override {
- FXL_VLOG(4) << "DevSessionShell/"
- "fuchsia::modular::InterruptionListener::OnInterrupt() "
- << suggestion.uuid;
- }
-
- // |fuchsia::modular::NextListener|
- void OnProcessingChange(bool processing) override {
- FXL_VLOG(4)
- << "DevSessionShell/fuchsia::modular::NextListener::OnProcessingChange("
- << processing << ")";
- }
-
- const Settings settings_;
-
- fidl::BindingSet<fuchsia::modular::SessionShell> session_shell_bindings_;
-
- zx::eventpair view_token_;
- std::unique_ptr<modular::ViewHost> view_;
-
- fuchsia::modular::SessionShellContextPtr session_shell_context_;
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- fuchsia::modular::StoryProviderPtr story_provider_;
- fuchsia::modular::StoryControllerPtr story_controller_;
- fuchsia::modular::FocusControllerPtr focus_controller_;
- fuchsia::modular::VisibleStoriesControllerPtr visible_stories_controller_;
-
- fidl::Binding<fuchsia::modular::StoryWatcher> story_watcher_binding_;
-
- fuchsia::modular::SuggestionProviderPtr suggestion_provider_;
- fidl::BindingSet<fuchsia::modular::InterruptionListener>
- interruption_listener_bindings_;
- fidl::BindingSet<fuchsia::modular::NextListener> next_listener_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DevSessionShellApp);
-};
-
-} // namespace
-
-int main(int argc, const char** argv) {
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- Settings settings(command_line);
-
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
-
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AppDriver<DevSessionShellApp> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<DevSessionShellApp>(context.get(), std::move(settings)),
- [&loop] { loop.Quit(); });
-
- loop.Run();
- return 0;
-}
diff --git a/bin/sessionmgr/device_map_impl.cc b/bin/sessionmgr/device_map_impl.cc
deleted file mode 100644
index 6938713..0000000
--- a/bin/sessionmgr/device_map_impl.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/device_map_impl.h"
-
-#include <limits.h>
-#include <unistd.h>
-
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/time/time_point.h>
-
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/ledger_client/operations.h"
-
-namespace modular {
-
-namespace {
-
-using ReadDeviceDataCall = ReadDataCall<fuchsia::modular::DeviceMapEntry>;
-using ReadAllDeviceDataCall = ReadAllDataCall<fuchsia::modular::DeviceMapEntry>;
-using WriteDeviceDataCall = WriteDataCall<fuchsia::modular::DeviceMapEntry>;
-
-// Reads old versions of device data, which are missing a timestamp.
-void XdrDeviceMapEntry_v1(XdrContext* const xdr,
- fuchsia::modular::DeviceMapEntry* const data) {
- xdr->Field("name", &data->name);
- xdr->Field("device_id", &data->device_id);
- xdr->Field("profile", &data->profile);
- xdr->Field("hostname", &data->hostname);
-
- // The time below is 26 Sep 2017 17:44:40 GMT, just to mark the entry as old.
- // Since this filter is not the latest, it is only ever used FROM_JSON, never
- // TO_JSON.
- data->last_change_timestamp = 1506447879;
-}
-
-void XdrDeviceMapEntry_v2(XdrContext* const xdr,
- fuchsia::modular::DeviceMapEntry* const data) {
- xdr->Field("name", &data->name);
- xdr->Field("device_id", &data->device_id);
- xdr->Field("profile", &data->profile);
- xdr->Field("hostname", &data->hostname);
- xdr->Field("last_change_timestamp", &data->last_change_timestamp);
-}
-
-void XdrDeviceMapEntry_v3(XdrContext* const xdr,
- fuchsia::modular::DeviceMapEntry* const data) {
- if (!xdr->Version(3)) {
- return;
- }
- xdr->Field("name", &data->name);
- xdr->Field("device_id", &data->device_id);
- xdr->Field("profile", &data->profile);
- xdr->Field("hostname", &data->hostname);
- xdr->Field("last_change_timestamp", &data->last_change_timestamp);
-}
-
-constexpr XdrFilterType<fuchsia::modular::DeviceMapEntry> XdrDeviceMapEntry[] =
- {
- XdrDeviceMapEntry_v3,
- XdrDeviceMapEntry_v2,
- XdrDeviceMapEntry_v1,
- nullptr,
-};
-
-std::string LoadHostname() {
- char host_name_buffer[HOST_NAME_MAX + 1];
- int result = gethostname(host_name_buffer, sizeof(host_name_buffer));
-
- if (result < 0) {
- FXL_LOG(ERROR) << "unable to get hostname. errno " << errno;
- return "fuchsia";
- }
-
- return host_name_buffer;
-}
-
-} // namespace
-
-DeviceMapImpl::DeviceMapImpl(const std::string& device_name,
- const std::string& device_id,
- const std::string& device_profile,
- LedgerClient* const ledger_client,
- LedgerPageId page_id)
- : PageClient("DeviceMapImpl", ledger_client, std::move(page_id),
- kDeviceKeyPrefix) {
- current_device_id_ = device_id;
-
- // TODO(jimbe) Load the fuchsia::modular::DeviceMapEntry for the current
- // device from the Ledger.
- fuchsia::modular::DeviceMapEntry device;
- device.name = device_name;
- device.device_id = device_id;
- device.profile = device_profile;
- device.hostname = LoadHostname();
-
- devices_[device_id] = std::move(device);
- SaveCurrentDevice();
-}
-
-DeviceMapImpl::~DeviceMapImpl() = default;
-
-void DeviceMapImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::DeviceMap> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void DeviceMapImpl::Query(QueryCallback callback) {
- operation_queue_.Add(new ReadAllDeviceDataCall(page(), kDeviceKeyPrefix,
- XdrDeviceMapEntry, callback));
-}
-
-void DeviceMapImpl::GetCurrentDevice(GetCurrentDeviceCallback callback) {
- callback(devices_[current_device_id_]);
-}
-
-void DeviceMapImpl::SetCurrentDeviceProfile(::std::string profile) {
- devices_[current_device_id_].profile = profile;
- Notify(current_device_id_);
- SaveCurrentDevice();
-}
-
-void DeviceMapImpl::SaveCurrentDevice() {
- auto& device = devices_[current_device_id_];
- device.last_change_timestamp = time(nullptr);
-
- operation_queue_.Add(new WriteDeviceDataCall(
- page(), MakeDeviceKey(current_device_id_), XdrDeviceMapEntry,
- fidl::MakeOptional(device), [] {}));
-}
-
-void DeviceMapImpl::WatchDeviceMap(
- fidl::InterfaceHandle<fuchsia::modular::DeviceMapWatcher> watcher) {
- auto watcher_ptr = watcher.Bind();
- for (const auto& item : devices_) {
- const auto& device = item.second;
- watcher_ptr->OnDeviceMapChange(device);
- }
- change_watchers_.AddInterfacePtr(std::move(watcher_ptr));
-}
-
-void DeviceMapImpl::Notify(const std::string& device_id) {
- const fuchsia::modular::DeviceMapEntry& device = devices_[current_device_id_];
- for (auto& watcher : change_watchers_.ptrs()) {
- (*watcher)->OnDeviceMapChange(device);
- }
-}
-
-void DeviceMapImpl::OnPageChange(const std::string& key,
- const std::string& value) {
- FXL_LOG(INFO) << "Updated Device: " << key << " value=" << value;
-
- fuchsia::modular::DeviceMapEntry device;
- if (!XdrRead(value, &device, XdrDeviceMapEntry)) {
- FXL_DCHECK(false);
- return;
- }
-
- fidl::StringPtr device_id = device.device_id;
- devices_[device_id] = std::move(device);
- Notify(device_id);
-}
-
-void DeviceMapImpl::OnPageDelete(const std::string& key) {
- // This shouldn't happen.
- FXL_LOG(ERROR) << "Deleted Device: " << key;
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/device_map_impl.h b/bin/sessionmgr/device_map_impl.h
deleted file mode 100644
index a8b9163..0000000
--- a/bin/sessionmgr/device_map_impl.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_DEVICE_MAP_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_DEVICE_MAP_IMPL_H_
-
-#include <map>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/types.h"
-
-namespace modular {
-
-// See services/user/device_map.fidl for details.
-//
-// Mostly scaffolding to demonstrate a complete page client.
-class DeviceMapImpl : fuchsia::modular::DeviceMap, PageClient {
- public:
- DeviceMapImpl(const std::string& device_name, const std::string& device_id,
- const std::string& device_profile, LedgerClient* ledger_client,
- LedgerPageId page_id);
- ~DeviceMapImpl() override;
-
- const std::string& current_device_id() const { return current_device_id_; }
-
- void Connect(fidl::InterfaceRequest<fuchsia::modular::DeviceMap> request);
-
- private:
- // |fuchsia::modular::DeviceMap|
- void Query(QueryCallback callback) override;
-
- // |fuchsia::modular::DeviceMap|
- void GetCurrentDevice(GetCurrentDeviceCallback callback) override;
-
- // |fuchsia::modular::DeviceMap|
- void SetCurrentDeviceProfile(::std::string profile) override;
-
- // |fuchsia::modular::DeviceMap|
- void WatchDeviceMap(fidl::InterfaceHandle<fuchsia::modular::DeviceMapWatcher>
- watcher) override;
-
- // |PageClient|
- void OnPageChange(const std::string& key, const std::string& value) override;
-
- // |PageClient|
- void OnPageDelete(const std::string& key) override;
-
- // Update the timestamp for the current device and save it to the Ledger.
- void SaveCurrentDevice();
-
- // Notify all watchers that the given device has changed
- void Notify(const std::string& device_id);
-
- // Clients that have connected to this service.
- fidl::BindingSet<fuchsia::modular::DeviceMap> bindings_;
-
- // All known devices from the Ledger page.
- std::map<std::string, fuchsia::modular::DeviceMapEntry> devices_;
-
- // The local device in the |devices_| map.
- std::string current_device_id_;
-
- OperationQueue operation_queue_;
-
- fidl::InterfacePtrSet<fuchsia::modular::DeviceMapWatcher> change_watchers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DeviceMapImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_DEVICE_MAP_IMPL_H_
diff --git a/bin/sessionmgr/entity_provider_runner/BUILD.gn b/bin/sessionmgr/entity_provider_runner/BUILD.gn
deleted file mode 100644
index 9967cb7..0000000
--- a/bin/sessionmgr/entity_provider_runner/BUILD.gn
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-source_set("entity_provider_runner") {
- sources = [
- "entity_provider_controller.cc",
- "entity_provider_controller.h",
- "entity_provider_launcher.cc",
- "entity_provider_launcher.h",
- "entity_provider_runner.cc",
- "entity_provider_runner.h",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/util",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-tests_package("entity_provider_runner_unittests") {
- deps = [
- ":entity_provider_runner_unittest",
- ]
-}
-
-executable("entity_provider_runner_unittest") {
- testonly = true
-
- sources = [
- "entity_provider_runner_unittest.cc",
- ]
-
- deps = [
- ":entity_provider_runner",
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/component/cpp/testing:fake_launcher",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr/agent_runner",
- "//peridot/bin/sessionmgr/message_queue",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/testing:fake_agent_runner_storage",
- "//peridot/lib/testing:mock_base",
- "//peridot/lib/testing:test_with_ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//peridot/public/lib/agent/cpp",
- "//third_party/googletest:gtest_main",
- "//zircon/public/lib/trace",
- ]
-}
diff --git a/bin/sessionmgr/entity_provider_runner/entity_provider_controller.cc b/bin/sessionmgr/entity_provider_runner/entity_provider_controller.cc
deleted file mode 100644
index 2d50f46..0000000
--- a/bin/sessionmgr/entity_provider_runner/entity_provider_controller.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_controller.h"
-
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h"
-
-namespace modular {
-
-class EntityProviderController::EntityImpl : fuchsia::modular::Entity {
- public:
- EntityImpl(EntityProviderController* const entity_provider_controller,
- fuchsia::modular::EntityProvider* const entity_provider,
- const std::string& cookie, const std::string& entity_reference)
- : entity_provider_controller_(entity_provider_controller),
- entity_provider_(entity_provider),
- cookie_(cookie),
- entity_reference_(entity_reference) {
- entity_bindings_.set_empty_set_handler([this] {
- entity_provider_controller_->OnEmptyEntityImpls(cookie_);
- // |this| is no longer valid.
- });
- }
-
- // Serves this |fuchsia::modular::Entity| for the cookie this |EntityImpl| was
- // instantiated for.
- void ProvideEntity(fidl::InterfaceRequest<fuchsia::modular::Entity> request) {
- entity_bindings_.AddBinding(this, std::move(request));
- }
-
- private:
- // |fuchsia::modular::Entity|
- void GetTypes(GetTypesCallback callback) override {
- entity_provider_->GetTypes(cookie_, callback);
- }
-
- // |fuchsia::modular::Entity|
- void GetData(std::string type, GetDataCallback callback) override {
- entity_provider_->GetData(cookie_, type, callback);
- }
-
- // |fuchsia::modular::Entity|
- void WriteData(std::string type, fuchsia::mem::Buffer data,
- WriteDataCallback callback) override {
- entity_provider_->WriteData(cookie_, type, std::move(data), callback);
- }
-
- // |fuchsia::modular::Entity|
- void GetReference(GetReferenceCallback callback) override {
- callback(entity_reference_);
- }
-
- // |fuchsia::modular::Entity|
- void Watch(
- std::string type,
- fidl::InterfaceHandle<fuchsia::modular::EntityWatcher> watcher) override {
- entity_provider_->Watch(cookie_, type, std::move(watcher));
- }
-
- EntityProviderController* const entity_provider_controller_;
- fuchsia::modular::EntityProvider* const entity_provider_;
- const std::string cookie_;
- const std::string entity_reference_;
- fidl::BindingSet<fuchsia::modular::Entity> entity_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(EntityImpl);
-};
-
-EntityProviderController::EntityProviderController(
- fuchsia::modular::EntityProviderPtr entity_provider,
- fuchsia::modular::AgentControllerPtr agent_controller,
- std::function<void()> done)
- : entity_provider_(std::move(entity_provider)),
- agent_controller_(std::move(agent_controller)),
- done_(done) {
- FXL_DLOG(INFO) << "Running fuchsia::modular::EntityProvider";
- if (agent_controller_) {
- agent_controller_.set_error_handler([this](zx_status_t status) {
- done_();
- // |this| no longer valid.
- });
- }
-}
-
-EntityProviderController::~EntityProviderController() = default;
-
-void EntityProviderController::ProvideEntity(
- const std::string& cookie, const std::string& entity_reference,
- fidl::InterfaceRequest<fuchsia::modular::Entity> request) {
- auto it = entity_impls_.find(cookie);
- if (it == entity_impls_.end()) {
- bool inserted;
- std::tie(it, inserted) = entity_impls_.insert(std::make_pair(
- cookie, std::make_unique<EntityImpl>(this, entity_provider_.get(),
- cookie, entity_reference)));
- FXL_DCHECK(inserted);
- }
- // When there are no more |fuchsia::modular::Entity|s being serviced for this
- // |cookie|, |OnEmptyEntityImpl()| is triggered.
- it->second->ProvideEntity(std::move(request));
-}
-
-void EntityProviderController::OnEmptyEntityImpls(const std::string cookie) {
- entity_impls_.erase(cookie);
- if (entity_impls_.size() == 0ul) {
- // We can drop our connection to the fuchsia::modular::EntityProvider at
- // this point.
- done_();
- // |this| no longer valid.
- }
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/entity_provider_runner/entity_provider_controller.h b/bin/sessionmgr/entity_provider_runner/entity_provider_controller.h
deleted file mode 100644
index 02165be..0000000
--- a/bin/sessionmgr/entity_provider_runner/entity_provider_controller.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_CONTROLLER_H_
-#define PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_CONTROLLER_H_
-
-#include <map>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-class EntityProviderRunner;
-
-// This class runs and manages the lifetime of an EntityProvider service.
-//
-// When the entity provider is an agent the controller keeps the agent
-// connection alive.
-class EntityProviderController {
- public:
- // Creates an controller for a given entity provider.
- //
- // |entity_provider| The provider which is managed by this controller.
- // |agent_controller| If the entity provider is backed by an agent, this is
- // the associated agent controller. If no such controller exists, nullptr is
- // acceptable.
- // |done| The callback which is called when the entity provider managed by
- // this controller has finished running.
- EntityProviderController(
- fuchsia::modular::EntityProviderPtr entity_provider,
- fuchsia::modular::AgentControllerPtr agent_controller,
- std::function<void()> done);
-
- ~EntityProviderController();
-
- // Called by |EntityProviderRunner| when an |fuchsia::modular::Entity| needs
- // to be provided, usually when an entity reference is being resolved to an
- // |fuchsia::modular::Entity|.
- void ProvideEntity(const std::string& cookie,
- const std::string& entity_reference,
- fidl::InterfaceRequest<fuchsia::modular::Entity> request);
-
- private:
- // This class manages the lifetime of all |fuchsia::modular::Entity|s for a
- // given cookie.
- class EntityImpl;
-
- // Called when there are no more outstanding |fuchsia::modular::Entity|
- // interfaces we need to provide for. At this point, we can tear down the
- // |EntityImpl| providing for this cookie.
- void OnEmptyEntityImpls(const std::string cookie);
-
- // cookie -> EntityImpl
- std::map<std::string, std::unique_ptr<EntityImpl>> entity_impls_;
-
- // The managed entity provider connection.
- fuchsia::modular::EntityProviderPtr entity_provider_;
-
- // The agent controller connection for entity providers which are agents.
- fuchsia::modular::AgentControllerPtr agent_controller_;
-
- // The callback which is called when the entity provider finishes running.
- std::function<void()> done_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(EntityProviderController);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_CONTROLLER_H_
diff --git a/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.cc b/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.cc
deleted file mode 100644
index 0051c0c..0000000
--- a/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.h"
-
-namespace modular {
-EntityProviderLauncher::~EntityProviderLauncher() = default;
-} // namespace modular
diff --git a/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.h b/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.h
deleted file mode 100644
index 4eeb724..0000000
--- a/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_LAUNCHER_H_
-#define PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_LAUNCHER_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-// An interface for launching EntityProviders. This interface helps break the
-// dependency cycle between |AgentRunner| and |EntityProviderRunner|.
-class EntityProviderLauncher {
- public:
- // Connects to the entity provider service of the agent at the specified
- // |agent_url|.
- //
- // |agent_controller_request| is used to keep the agent running. Once dropped,
- // the agent may be killed and the entity provider will thus be dropped.
- virtual void ConnectToEntityProvider(
- const std::string& provider_uri,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) = 0;
-
- // Connets to the entity provider service for the story with the given
- // |story_id|.
- //
- // If no such story is found, the request is dropped.
- virtual void ConnectToStoryEntityProvider(
- const std::string& provider_uri,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request) = 0;
-
- protected:
- virtual ~EntityProviderLauncher();
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_LAUNCHER_H_
diff --git a/bin/sessionmgr/entity_provider_runner/entity_provider_runner.cc b/bin/sessionmgr/entity_provider_runner/entity_provider_runner.cc
deleted file mode 100644
index 759b529..0000000
--- a/bin/sessionmgr/entity_provider_runner/entity_provider_runner.cc
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(vardhan): Make entity references secure (no introspection allowed).
-
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h"
-
-#include <utility>
-
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/join_strings.h>
-#include <lib/fxl/type_converter.h>
-
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_controller.h"
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/util/string_escape.h"
-
-namespace modular {
-namespace {
-
-constexpr char kEntityReferencePrefix[] = "EntityRef";
-constexpr char kEntityDataReferencePrefix[] = "EntityData";
-constexpr char kStoryEntityReferencePrefix[] = "Story";
-
-using StringMap = std::map<std::string, std::string>;
-constexpr XdrFilterType<StringMap> XdrStringMap[] = {
- XdrFilter<StringMap>,
- nullptr,
-};
-
-// Given a |entity_namespace|, |provider_uri| and a |cookie|, encodes it into an
-// entity reference.
-std::string EncodeEntityReference(const std::string& entity_namespace,
- const std::string& provider_uri,
- const std::string& cookie) {
- std::vector<std::string> parts(3);
- parts[0] = entity_namespace;
- parts[1] = StringEscape(provider_uri, "/");
- parts[2] = StringEscape(cookie, "/");
- return fxl::JoinStrings(parts, "/");
-}
-
-// Returns an entity reference for an entity associated with the given
-// |story_id| and |cookie|.
-std::string EncodeStoryEntityReference(const std::string& story_id,
- const std::string& cookie) {
- return EncodeEntityReference(kStoryEntityReferencePrefix, story_id, cookie);
-}
-
-// Returns an entity reference for an entity associated with the given
-// |agent_url| and |cookie|.
-std::string EncodeAgentEntityReference(const std::string& agent_url,
- const std::string& cookie) {
- return EncodeEntityReference(kEntityReferencePrefix, agent_url, cookie);
-}
-
-// Inverse of EncodeEntityReference.
-bool DecodeEntityReference(const std::string& entity_reference,
- std::string* const prefix,
- std::string* const provider_uri,
- std::string* const cookie) {
- auto parts = SplitEscapedString(entity_reference, '/');
- if (parts.size() != 3) {
- return false;
- }
- *prefix = StringUnescape(parts[0].ToString());
- *provider_uri = StringUnescape(parts[1].ToString());
- *cookie = StringUnescape(parts[2].ToString());
- return true;
-}
-
-bool DecodeEntityDataReference(const std::string& entity_reference,
- std::map<std::string, std::string>* data) {
- auto parts = SplitEscapedString(entity_reference, '/');
- if (parts.size() != 2 ||
- StringUnescape(parts[0]) != kEntityDataReferencePrefix) {
- return false;
- }
-
- return XdrRead(StringUnescape(parts[1].ToString()), data, XdrStringMap);
-}
-
-} // namespace
-
-class EntityProviderRunner::EntityReferenceFactoryImpl
- : fuchsia::modular::EntityReferenceFactory {
- public:
- // Creates an entity reference factory for the given |provider_uri|.
- //
- // |entity_provider_runner| exposes the concrete implementations for encoding
- // entity references.
- EntityReferenceFactoryImpl(const std::string& agent_url,
- EntityProviderRunner* const entity_provider_runner)
- : agent_url_(agent_url),
- entity_provider_runner_(entity_provider_runner) {}
-
- void AddBinding(
- fidl::InterfaceRequest<fuchsia::modular::EntityReferenceFactory>
- request) {
- bindings_.AddBinding(this, std::move(request));
- }
-
- void set_empty_set_handler(const std::function<void()>& handler) {
- bindings_.set_empty_set_handler(handler);
- }
-
- private:
- // |fuchsia::modular::EntityReferenceFactory|
- void CreateReference(std::string cookie,
- CreateReferenceCallback callback) override {
- entity_provider_runner_->CreateReference(agent_url_, cookie, callback);
- }
-
- // The agent url if the entity reference factory produces references to
- // entities backed by agents, otherwise the story id of the story entity
- // provider.
- const std::string agent_url_;
-
- EntityProviderRunner* const entity_provider_runner_;
- fidl::BindingSet<fuchsia::modular::EntityReferenceFactory> bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(EntityReferenceFactoryImpl);
-};
-
-// This class provides |fuchsia::modular::Entity| implementations for a given
-// data entity reference.
-class EntityProviderRunner::DataEntity : fuchsia::modular::Entity {
- public:
- DataEntity(EntityProviderRunner* const provider,
- const std::string& entity_reference,
- std::map<std::string, std::string> data) {
- for (const auto& kv : data) {
- types_.push_back(kv.first);
- }
- data_ = std::move(data);
-
- bindings_.set_empty_set_handler([provider, entity_reference] {
- provider->OnDataEntityFinished(entity_reference);
- });
- };
-
- void AddBinding(fidl::InterfaceRequest<fuchsia::modular::Entity> request) {
- bindings_.AddBinding(this, std::move(request));
- }
-
- private:
- // |fuchsia::modular::Entity|
- void GetTypes(GetTypesCallback result) override {
- result(types_);
- }
- // |fuchsia::modular::Entity|
- void GetData(std::string type, GetDataCallback result) override {
- auto it = data_.find(type);
- if (it != data_.end()) {
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(it->second, &vmo));
- auto vmo_ptr =
- std::make_unique<fuchsia::mem::Buffer>(std::move(vmo).ToTransport());
-
- result(std::move(vmo_ptr));
- } else {
- result(nullptr);
- }
- }
- // |fuchsia::modular::Entity|
- void WriteData(std::string type, fuchsia::mem::Buffer data,
- WriteDataCallback callback) override {
- // TODO(MI4-1301)
- callback(fuchsia::modular::EntityWriteStatus::READ_ONLY);
- }
- // |fuchsia::modular::Entity|
- void GetReference(GetReferenceCallback callback) override {
- // TODO(MI4-1301)
- FXL_NOTIMPLEMENTED();
- }
- // |fuchsia::modular::Entity|
- void Watch(
- std::string type,
- fidl::InterfaceHandle<fuchsia::modular::EntityWatcher> watcher) override {
- // TODO(MI4-1301)
- FXL_NOTIMPLEMENTED();
- }
-
- std::vector<std::string> types_;
- std::map<std::string, std::string> data_;
- fidl::BindingSet<fuchsia::modular::Entity> bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DataEntity);
-};
-
-EntityProviderRunner::EntityProviderRunner(
- EntityProviderLauncher* const entity_provider_launcher)
- : entity_provider_launcher_(entity_provider_launcher) {}
-
-EntityProviderRunner::~EntityProviderRunner() = default;
-
-void EntityProviderRunner::ConnectEntityReferenceFactory(
- const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::modular::EntityReferenceFactory> request) {
- auto it = entity_reference_factory_bindings_.find(agent_url);
- if (it == entity_reference_factory_bindings_.end()) {
- bool inserted;
- std::tie(it, inserted) = entity_reference_factory_bindings_.emplace(
- std::make_pair(agent_url, std::make_unique<EntityReferenceFactoryImpl>(
- agent_url, this)));
- FXL_DCHECK(inserted);
- it->second->set_empty_set_handler([this, agent_url] {
- entity_reference_factory_bindings_.erase(agent_url);
- });
- }
- it->second->AddBinding(std::move(request));
-}
-
-std::string EntityProviderRunner::CreateStoryEntityReference(
- const std::string& story_id, const std::string& cookie) {
- return EncodeStoryEntityReference(story_id, cookie);
-}
-
-void EntityProviderRunner::ConnectEntityResolver(
- fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request) {
- entity_resolver_bindings_.AddBinding(this, std::move(request));
-}
-
-void EntityProviderRunner::OnEntityProviderFinished(
- const std::string agent_url) {
- entity_provider_controllers_.erase(agent_url);
-}
-
-std::string EntityProviderRunner::CreateReferenceFromData(
- std::map<std::string, std::string> type_to_data) {
- // TODO(rosswang): Several of these heap allocations are unnecessary but this
- // code is only temporary.
- std::string encoded;
- XdrWrite(&encoded, &type_to_data, XdrStringMap);
-
- std::vector<std::string> parts(2);
- parts[0] = kEntityDataReferencePrefix;
- parts[1] = StringEscape(encoded, "/");
- std::string joined = fxl::JoinStrings(parts, "/");
- if (joined.length() > ZX_CHANNEL_MAX_MSG_BYTES) {
- FXL_LOG(ERROR) << "data entity reference size exceeds FIDL channel message "
- "size limits";
- }
- return joined;
-}
-
-void EntityProviderRunner::CreateReference(
- const std::string& agent_url, const std::string& cookie,
- fuchsia::modular::EntityReferenceFactory::CreateReferenceCallback
- callback) {
- auto entity_ref = EncodeAgentEntityReference(agent_url, cookie);
- callback(entity_ref);
-}
-
-void EntityProviderRunner::ResolveDataEntity(
- fidl::StringPtr entity_reference,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request) {
- std::map<std::string, std::string> entity_data;
- if (!DecodeEntityDataReference(entity_reference, &entity_data)) {
- FXL_LOG(INFO) << "Could not decode entity reference: " << entity_reference;
- return;
- // |entity_request| closes here.
- }
-
- auto inserted =
- data_entities_.emplace(std::make_pair(entity_reference.get(), nullptr));
- if (inserted.second) {
- // This is a new entity.
- inserted.first->second = std::make_unique<DataEntity>(
- this, entity_reference.get(), std::move(entity_data));
- }
- inserted.first->second->AddBinding(std::move(entity_request));
-}
-
-void EntityProviderRunner::OnDataEntityFinished(
- const std::string& entity_reference) {
- data_entities_.erase(entity_reference);
-}
-
-void EntityProviderRunner::ResolveEntity(
- std::string entity_reference,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request) {
- if (entity_reference.find(kEntityDataReferencePrefix) == 0ul) {
- ResolveDataEntity(entity_reference, std::move(entity_request));
- return;
- }
-
- std::string provider_uri;
- std::string cookie;
- std::string prefix;
- fuchsia::modular::EntityProviderPtr entity_provider;
- fuchsia::modular::AgentControllerPtr agent_controller;
-
- if (!DecodeEntityReference(entity_reference, &prefix, &provider_uri,
- &cookie)) {
- return;
- // |entity_request| is closed here.
- }
-
- bool is_story_entity = prefix == kStoryEntityReferencePrefix;
-
- if (is_story_entity) {
- entity_provider_launcher_->ConnectToStoryEntityProvider(
- provider_uri, entity_provider.NewRequest());
- } else if (prefix == kEntityReferencePrefix) {
- entity_provider_launcher_->ConnectToEntityProvider(
- provider_uri, entity_provider.NewRequest(),
- agent_controller.NewRequest());
- } else {
- return;
- // |entity_request| is closed here.
- }
-
- // Connect to the EntityProviderController managing this entity.
- auto it = entity_provider_controllers_.find(provider_uri);
- if (it == entity_provider_controllers_.end()) {
- bool inserted;
- std::tie(it, inserted) =
- entity_provider_controllers_.emplace(std::make_pair(
- provider_uri,
- std::make_unique<EntityProviderController>(
- std::move(entity_provider), std::move(agent_controller),
- [this, is_story_entity, provider_uri] {
- if (!is_story_entity) {
- OnEntityProviderFinished(provider_uri);
- }
- })));
- FXL_DCHECK(inserted);
- }
-
- it->second->ProvideEntity(cookie, entity_reference,
- std::move(entity_request));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h b/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h
deleted file mode 100644
index a76207a..0000000
--- a/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_RUNNER_H_
-
-#include <map>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-class EntityProviderController;
-class EntityProviderLauncher;
-
-// This class provides an implementation for |fuchsia::modular::EntityResolver|
-// and |fuchsia::modular::EntityReferenceFactory| and manages all the
-// EntityProviders running in the system. One |EntityProviderRunner| instance
-// services all |fuchsia::modular::EntityResolver| interfaces, and there is one
-// |EntityReferenceFactoryImpl| for each
-// |fuchsia::modular::EntityReferenceFactory| interface.
-class EntityProviderRunner : public fuchsia::modular::EntityResolver {
- public:
- EntityProviderRunner(EntityProviderLauncher* entity_provider_launcher);
- ~EntityProviderRunner() override;
-
- // Connects to the entity reference factory for the agent at |agent_url|.
- //
- // The created entity references will be resolved back to that particular
- // agent.
- void ConnectEntityReferenceFactory(
- const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::modular::EntityReferenceFactory> request);
-
- // Connects to the entity resolver service. The resolver service can resolve
- // any references, regardless if they are backed by an agent or a story entity
- // provider.
- void ConnectEntityResolver(
- fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request);
-
- // Creates an entity reference for the given |cookie| associated with the
- // specified |story_id|.
- std::string CreateStoryEntityReference(const std::string& story_id,
- const std::string& cookie);
-
- // Given a map of entity type -> entity data, creates an entity reference for
- // it. This data is encoded into the entity reference, and must be within
- // 16KB. If successful, a non-null value is returned.
- std::string CreateReferenceFromData(
- std::map<std::string, std::string> type_to_data);
-
- // Called by a DataEntity when it has no more |fuchsia::modular::Entity|s it
- // needs to serve for a particular |entity_reference|.
- void OnDataEntityFinished(const std::string& entity_reference);
-
- private:
- class EntityReferenceFactoryImpl;
- class DataEntity;
-
- // The |EntityReferenceFactory| uses this to create entity references for
- // a particular agent.
- //
- // |agent_url| The url of the agent creating the entity reference.
- // |cookie| The cookie identifying the entity.
- // |callback| The callback which is called with the constructed entity
- // reference.
- void CreateReference(
- const std::string& agent_url, const std::string& cookie,
- fuchsia::modular::EntityReferenceFactory::CreateReferenceCallback
- callback);
-
- // |fuchsia::modular::EntityResolver|
- void ResolveEntity(
- std::string entity_reference,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request) override;
-
- void ResolveDataEntity(
- fidl::StringPtr entity_reference,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request);
-
- // Performs the cleanup required when the entity provider at the provided
- // agent_url finished.
- void OnEntityProviderFinished(const std::string agent_url);
-
- EntityProviderLauncher* const entity_provider_launcher_;
-
- // agent url -> EntityReferenceFactoryImpl
- std::map<std::string, std::unique_ptr<EntityReferenceFactoryImpl>>
- entity_reference_factory_bindings_;
-
- // story id -> StoryEntityReferenceFactoryImpl
- std::map<std::string, std::unique_ptr<EntityReferenceFactoryImpl>>
- story_entity_reference_factory_bindings_;
-
- fidl::BindingSet<fuchsia::modular::EntityResolver> entity_resolver_bindings_;
-
- // These are the running entity providers.
- // component id -> EntityProviderController.
- std::map<std::string, std::unique_ptr<EntityProviderController>>
- entity_provider_controllers_;
-
- // entity reference -> |fuchsia::modular::Entity| implementation.
- std::map<std::string, std::unique_ptr<DataEntity>> data_entities_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(EntityProviderRunner);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_ENTITY_PROVIDER_RUNNER_ENTITY_PROVIDER_RUNNER_H_
diff --git a/bin/sessionmgr/entity_provider_runner/entity_provider_runner_unittest.cc b/bin/sessionmgr/entity_provider_runner/entity_provider_runner_unittest.cc
deleted file mode 100644
index fdcd966..0000000
--- a/bin/sessionmgr/entity_provider_runner/entity_provider_runner_unittest.cc
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h"
-
-#include <memory>
-
-#include <fs/service.h>
-#include <fs/synchronous-vfs.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/agent/cpp/agent_impl.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/component/cpp/testing/fake_launcher.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-#include <lib/fxl/macros.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner.h"
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.h"
-#include "peridot/bin/sessionmgr/message_queue/message_queue_manager.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/testing/fake_agent_runner_storage.h"
-#include "peridot/lib/testing/mock_base.h"
-#include "peridot/lib/testing/test_with_ledger.h"
-
-namespace modular {
-namespace testing {
-namespace {
-
-using ::component::testing::FakeLauncher;
-
-class EntityProviderRunnerTest : public TestWithLedger, EntityProviderLauncher {
- public:
- EntityProviderRunnerTest() = default;
-
- void SetUp() override {
- TestWithLedger::SetUp();
-
- mqm_ = std::make_unique<MessageQueueManager>(
- ledger_client(), MakePageId("0123456789123456"), mq_data_dir_.path());
- entity_provider_runner_ = std::make_unique<EntityProviderRunner>(
- static_cast<EntityProviderLauncher*>(this));
- // The |fuchsia::modular::UserIntelligenceProvider| below must be nullptr in
- // order for agent creation to be synchronous, which these tests assume.
- agent_runner_ = std::make_unique<AgentRunner>(
- &launcher_, mqm_.get(), ledger_repository(), &agent_runner_storage_,
- token_manager_.get(), nullptr, entity_provider_runner_.get());
- }
-
- void TearDown() override {
- agent_runner_.reset();
- entity_provider_runner_.reset();
- mqm_.reset();
-
- TestWithLedger::TearDown();
- }
-
- MessageQueueManager* message_queue_manager() { return mqm_.get(); }
-
- protected:
- AgentRunner* agent_runner() { return agent_runner_.get(); }
- FakeLauncher* launcher() { return &launcher_; }
- EntityProviderRunner* entity_provider_runner() {
- return entity_provider_runner_.get();
- }
-
- private:
- // TODO(vardhan): A test probably shouldn't be implementing this..
- // |EntityProviderLauncher|
- void ConnectToEntityProvider(
- const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) override {
- agent_runner_->ConnectToEntityProvider(agent_url,
- std::move(entity_provider_request),
- std::move(agent_controller_request));
- }
-
- void ConnectToStoryEntityProvider(
- const std::string& story_id,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request) override {
- FXL_NOTIMPLEMENTED();
- }
-
- FakeLauncher launcher_;
-
- files::ScopedTempDir mq_data_dir_;
- std::unique_ptr<MessageQueueManager> mqm_;
- FakeAgentRunnerStorage agent_runner_storage_;
- std::unique_ptr<EntityProviderRunner> entity_provider_runner_;
- std::unique_ptr<AgentRunner> agent_runner_;
-
- fuchsia::auth::TokenManagerPtr token_manager_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(EntityProviderRunnerTest);
-};
-
-class MyEntityProvider : AgentImpl::Delegate,
- fuchsia::modular::EntityProvider,
- public fuchsia::sys::ComponentController,
- public testing::MockBase {
- public:
- MyEntityProvider(
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl)
- : vfs_(async_get_default_dispatcher()),
- outgoing_directory_(fbl::AdoptRef(new fs::PseudoDir())),
- controller_(this, std::move(ctrl)),
- entity_provider_binding_(this),
- launch_info_(std::move(launch_info)) {
- outgoing_directory_->AddEntry(
- fuchsia::modular::EntityProvider::Name_,
- fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
- entity_provider_binding_.Bind(std::move(channel));
- return ZX_OK;
- })));
- vfs_.ServeDirectory(outgoing_directory_,
- std::move(launch_info_.directory_request));
- agent_impl_ = std::make_unique<AgentImpl>(
- outgoing_directory_, static_cast<AgentImpl::Delegate*>(this));
-
- // Get |agent_context_| and |entity_resolver_| from incoming namespace.
- FXL_CHECK(launch_info_.additional_services);
- FXL_CHECK(launch_info_.additional_services->provider.is_valid());
- auto additional_services =
- launch_info_.additional_services->provider.Bind();
- component::ConnectToService(additional_services.get(),
- agent_context_.NewRequest());
- fuchsia::modular::ComponentContextPtr component_context;
- agent_context_->GetComponentContext(component_context.NewRequest());
- component_context->GetEntityResolver(entity_resolver_.NewRequest());
- }
-
- size_t GetCallCount(const std::string func) { return counts.count(func); }
- fuchsia::modular::EntityResolver* entity_resolver() {
- return entity_resolver_.get();
- }
- fuchsia::modular::AgentContext* agent_context() {
- return agent_context_.get();
- }
-
- private:
- // |ComponentController|
- void Kill() override { ++counts["Kill"]; }
- // |ComponentController|
- void Detach() override { ++counts["Detach"]; }
-
- // |AgentImpl::Delegate|
- void Connect(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- outgoing_services) override {
- ++counts["Connect"];
- }
- // |AgentImpl::Delegate|
- void RunTask(const fidl::StringPtr& task_id,
- const std::function<void()>& done) override {
- ++counts["RunTask"];
- done();
- }
-
- // |fuchsia::modular::EntityProvider|
- void GetTypes(std::string cookie, GetTypesCallback callback) override {
- std::vector<std::string> types;
- types.push_back("MyType");
- callback(std::move(types));
- }
-
- // |fuchsia::modular::EntityProvider|
- void GetData(std::string cookie, std::string type,
- GetDataCallback callback) override {
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(type + ":MyData", &vmo));
- auto vmo_ptr =
- std::make_unique<fuchsia::mem::Buffer>(std::move(vmo).ToTransport());
-
- callback(std::move(vmo_ptr));
- }
-
- // |fuchsia::modular::EntityProvider|
- void WriteData(std::string cookie, std::string type,
- fuchsia::mem::Buffer data,
- WriteDataCallback callback) override {
- // TODO(MI4-1301)
- callback(fuchsia::modular::EntityWriteStatus::READ_ONLY);
- }
-
- // |fuchsia::modular::EntityProvider|
- void Watch(
- std::string cookie, std::string type,
- fidl::InterfaceHandle<fuchsia::modular::EntityWatcher> watcher) override {
- // TODO(MI4-1301)
- FXL_NOTIMPLEMENTED();
- }
-
- private:
- fs::SynchronousVfs vfs_;
- fbl::RefPtr<fs::PseudoDir> outgoing_directory_;
- fuchsia::modular::AgentContextPtr agent_context_;
- std::unique_ptr<AgentImpl> agent_impl_;
- fuchsia::modular::EntityResolverPtr entity_resolver_;
- fidl::Binding<fuchsia::sys::ComponentController> controller_;
- fidl::Binding<fuchsia::modular::EntityProvider> entity_provider_binding_;
- fuchsia::sys::LaunchInfo launch_info_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(MyEntityProvider);
-};
-
-TEST_F(EntityProviderRunnerTest, Basic) {
- std::unique_ptr<MyEntityProvider> dummy_agent;
- constexpr char kMyAgentUrl[] = "file:///my_agent";
- launcher()->RegisterComponent(
- kMyAgentUrl,
- [&dummy_agent](
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- dummy_agent = std::make_unique<MyEntityProvider>(std::move(launch_info),
- std::move(ctrl));
- });
-
- // 1. Start up the entity provider agent.
- fuchsia::sys::ServiceProviderPtr incoming_services;
- fuchsia::modular::AgentControllerPtr agent_controller;
- agent_runner()->ConnectToAgent("dummy_requestor_url", kMyAgentUrl,
- incoming_services.NewRequest(),
- agent_controller.NewRequest());
-
- RunLoopWithTimeoutOrUntil([&dummy_agent] {
- return dummy_agent.get() != nullptr &&
- dummy_agent->GetCallCount("Connect") == 1;
- });
- dummy_agent->ExpectCalledOnce("Connect");
-
- // 2. Make an entity reference on behalf of this agent.
- // The framework should use |kMyAgentUrl| as the agent to associate new
- // references.
- fuchsia::modular::EntityReferenceFactoryPtr factory;
- dummy_agent->agent_context()->GetEntityReferenceFactory(factory.NewRequest());
- fidl::StringPtr entity_ref;
- factory->CreateReference("my_cookie", [&entity_ref](fidl::StringPtr retval) {
- entity_ref = retval;
- });
-
- RunLoopWithTimeoutOrUntil([&entity_ref] { return !entity_ref.is_null(); });
- EXPECT_FALSE(entity_ref.is_null());
-
- // 3. Resolve the reference into an |fuchsia::modular::Entity|, make calls to
- // GetTypes and
- // GetData, which should route into our |MyEntityProvider|.
- fuchsia::modular::EntityPtr entity;
- dummy_agent->entity_resolver()->ResolveEntity(entity_ref,
- entity.NewRequest());
-
- std::map<std::string, uint32_t> counts;
- entity->GetTypes([&counts](const std::vector<std::string>& types) {
- EXPECT_EQ(1u, types.size());
- EXPECT_EQ("MyType", types.at(0));
- counts["GetTypes"]++;
- });
- entity->GetData("MyType",
- [&counts](std::unique_ptr<fuchsia::mem::Buffer> data) {
- std::string data_string;
- FXL_CHECK(fsl::StringFromVmo(*data, &data_string));
- EXPECT_EQ("MyType:MyData", data_string);
- counts["GetData"]++;
- });
- RunLoopWithTimeoutOrUntil(
- [&counts] { return counts["GetTypes"] == 1 && counts["GetData"] == 1; });
- EXPECT_EQ(1u, counts["GetTypes"]);
- EXPECT_EQ(1u, counts["GetData"]);
-}
-
-TEST_F(EntityProviderRunnerTest, DataEntity) {
- std::map<std::string, std::string> data;
- data["type1"] = "data1";
-
- auto entity_ref = entity_provider_runner()->CreateReferenceFromData(data);
-
- fuchsia::modular::EntityResolverPtr entity_resolver;
- entity_provider_runner()->ConnectEntityResolver(entity_resolver.NewRequest());
- fuchsia::modular::EntityPtr entity;
- entity_resolver->ResolveEntity(entity_ref, entity.NewRequest());
-
- fidl::VectorPtr<std::string> output_types;
- entity->GetTypes([&output_types](std::vector<std::string> result) {
- output_types.reset(std::move(result));
- });
- RunLoopWithTimeoutOrUntil(
- [&output_types] { return !output_types.is_null(); });
-
- EXPECT_EQ(data.size(), output_types->size());
- EXPECT_EQ("type1", output_types->at(0));
-
- fidl::StringPtr output_data;
- entity->GetData("type1",
- [&output_data](std::unique_ptr<fuchsia::mem::Buffer> result) {
- std::string data_string;
- FXL_CHECK(fsl::StringFromVmo(*result, &data_string));
- output_data = data_string;
- });
- RunLoopWithTimeoutOrUntil([&output_data] { return !output_data.is_null(); });
- EXPECT_EQ("data1", output_data);
-}
-
-} // namespace
-} // namespace testing
-} // namespace modular
diff --git a/bin/sessionmgr/focus.cc b/bin/sessionmgr/focus.cc
deleted file mode 100644
index 0af8337..0000000
--- a/bin/sessionmgr/focus.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/focus.h"
-
-#include <lib/fidl/cpp/array.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/time/time_point.h>
-
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/ledger_client/operations.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-
-namespace modular {
-
-namespace {
-
-// Serialization and deserialization of fuchsia::modular::FocusInfo to and from
-// JSON.
-void XdrFocusInfo_v1(XdrContext* const xdr,
- fuchsia::modular::FocusInfo* const data) {
- xdr->Field("device_id", &data->device_id);
- xdr->Field("focused_story_id", &data->focused_story_id);
- xdr->Field("last_focus_timestamp", &data->last_focus_change_timestamp);
-}
-
-void XdrFocusInfo_v2(XdrContext* const xdr,
- fuchsia::modular::FocusInfo* const data) {
- if (!xdr->Version(2)) {
- return;
- }
- xdr->Field("device_id", &data->device_id);
- xdr->Field("focused_story_id", &data->focused_story_id);
- xdr->Field("last_focus_timestamp", &data->last_focus_change_timestamp);
-}
-
-constexpr XdrFilterType<fuchsia::modular::FocusInfo> XdrFocusInfo[] = {
- XdrFocusInfo_v2,
- XdrFocusInfo_v1,
- nullptr,
-};
-
-} // namespace
-
-FocusHandler::FocusHandler(fidl::StringPtr device_id,
- LedgerClient* const ledger_client,
- LedgerPageId page_id)
- : PageClient("FocusHandler", ledger_client, std::move(page_id),
- kFocusKeyPrefix),
- device_id_(device_id) {}
-
-FocusHandler::~FocusHandler() = default;
-
-void FocusHandler::AddProviderBinding(
- fidl::InterfaceRequest<fuchsia::modular::FocusProvider> request) {
- provider_bindings_.AddBinding(this, std::move(request));
-}
-
-void FocusHandler::AddControllerBinding(
- fidl::InterfaceRequest<fuchsia::modular::FocusController> request) {
- controller_bindings_.AddBinding(this, std::move(request));
-}
-
-// |fuchsia::modular::FocusProvider|
-void FocusHandler::Query(QueryCallback callback) {
- operation_queue_.Add(new ReadAllDataCall<fuchsia::modular::FocusInfo>(
- page(), kFocusKeyPrefix, XdrFocusInfo,
- [callback](std::vector<fuchsia::modular::FocusInfo> infos) {
- callback(std::move(infos));
- }));
-}
-
-// |fuchsia::modular::FocusProvider|
-void FocusHandler::Watch(
- fidl::InterfaceHandle<fuchsia::modular::FocusWatcher> watcher) {
- change_watchers_.push_back(watcher.Bind());
-}
-
-// |fuchsia::modular::FocusProvider|
-void FocusHandler::Request(fidl::StringPtr story_id) {
- for (const auto& watcher : request_watchers_) {
- watcher->OnFocusRequest(story_id);
- }
-}
-
-// |fuchsia::modular::FocusController|
-void FocusHandler::Set(fidl::StringPtr story_id) {
- fuchsia::modular::FocusInfoPtr data = fuchsia::modular::FocusInfo::New();
- data->device_id = device_id_;
- data->focused_story_id = story_id;
- data->last_focus_change_timestamp = time(nullptr);
-
- operation_queue_.Add(new WriteDataCall<fuchsia::modular::FocusInfo>(
- page(), MakeFocusKey(device_id_), XdrFocusInfo, std::move(data), [] {}));
-}
-
-// |fuchsia::modular::FocusController|
-void FocusHandler::WatchRequest(
- fidl::InterfaceHandle<fuchsia::modular::FocusRequestWatcher> watcher) {
- request_watchers_.push_back(watcher.Bind());
-}
-
-// |PageClient|
-void FocusHandler::OnPageChange(const std::string& /*key*/,
- const std::string& value) {
- auto focus_info = fuchsia::modular::FocusInfo::New();
- if (!XdrRead(value, &focus_info, XdrFocusInfo)) {
- return;
- }
-
- for (const auto& watcher : change_watchers_) {
- watcher->OnFocusChange(CloneOptional(focus_info));
- }
-}
-
-VisibleStoriesHandler::VisibleStoriesHandler() {}
-
-VisibleStoriesHandler::~VisibleStoriesHandler() = default;
-
-void VisibleStoriesHandler::AddProviderBinding(
- fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesProvider> request) {
- provider_bindings_.AddBinding(this, std::move(request));
-}
-
-void VisibleStoriesHandler::AddControllerBinding(
- fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesController>
- request) {
- controller_bindings_.AddBinding(this, std::move(request));
-}
-
-void VisibleStoriesHandler::Query(QueryCallback callback) {
- callback(visible_stories_);
-}
-
-void VisibleStoriesHandler::Watch(
- fidl::InterfaceHandle<fuchsia::modular::VisibleStoriesWatcher> watcher) {
- change_watchers_.push_back(watcher.Bind());
-}
-
-void VisibleStoriesHandler::Set(fidl::VectorPtr<std::string> story_ids) {
- visible_stories_ = std::move(story_ids);
- for (const auto& watcher : change_watchers_) {
- watcher->OnVisibleStoriesChange(visible_stories_.Clone());
- }
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/focus.h b/bin/sessionmgr/focus.h
deleted file mode 100644
index 2b8b43a..0000000
--- a/bin/sessionmgr/focus.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_FOCUS_H_
-#define PERIDOT_BIN_SESSIONMGR_FOCUS_H_
-
-#include <string>
-#include <vector>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/string.h>
-
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/types.h"
-
-// See services/user/focus.fidl for details.
-
-namespace modular {
-
-class FocusHandler : fuchsia::modular::FocusProvider,
- fuchsia::modular::FocusController,
- PageClient {
- public:
- FocusHandler(fidl::StringPtr device_id, LedgerClient* ledger_client,
- LedgerPageId page_id);
- ~FocusHandler() override;
-
- void AddProviderBinding(
- fidl::InterfaceRequest<fuchsia::modular::FocusProvider> request);
- void AddControllerBinding(
- fidl::InterfaceRequest<fuchsia::modular::FocusController> request);
-
- private:
- // |fuchsia::modular::FocusProvider|
- void Query(QueryCallback callback) override;
- void Watch(
- fidl::InterfaceHandle<fuchsia::modular::FocusWatcher> watcher) override;
- void Request(fidl::StringPtr story_id) override;
-
- // |fuchsia::modular::FocusController|
- void Set(fidl::StringPtr story_id) override;
- void WatchRequest(fidl::InterfaceHandle<fuchsia::modular::FocusRequestWatcher>
- watcher) override;
-
- // |PageClient|
- void OnPageChange(const std::string& key, const std::string& value) override;
-
- const fidl::StringPtr device_id_;
-
- fidl::BindingSet<fuchsia::modular::FocusProvider> provider_bindings_;
- fidl::BindingSet<fuchsia::modular::FocusController> controller_bindings_;
-
- std::vector<fuchsia::modular::FocusWatcherPtr> change_watchers_;
- std::vector<fuchsia::modular::FocusRequestWatcherPtr> request_watchers_;
-
- // Operations on an instance of this clas are sequenced in this operation
- // queue. TODO(mesch): They currently do not need to be, but it's easier to
- // reason this way.
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FocusHandler);
-};
-
-class VisibleStoriesHandler : fuchsia::modular::VisibleStoriesProvider,
- fuchsia::modular::VisibleStoriesController {
- public:
- VisibleStoriesHandler();
- ~VisibleStoriesHandler() override;
-
- void AddProviderBinding(
- fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesProvider> request);
- void AddControllerBinding(
- fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesController>
- request);
-
- private:
- // |fuchsia::modular::VisibleStoriesProvider|
- void Query(QueryCallback callback) override;
- void Watch(fidl::InterfaceHandle<fuchsia::modular::VisibleStoriesWatcher>
- watcher) override;
-
- // |fuchsia::modular::VisibleStoriesController|
- void Set(fidl::VectorPtr<std::string> story_ids) override;
-
- fidl::BindingSet<fuchsia::modular::VisibleStoriesProvider> provider_bindings_;
- fidl::BindingSet<fuchsia::modular::VisibleStoriesController>
- controller_bindings_;
-
- std::vector<fuchsia::modular::VisibleStoriesWatcherPtr> change_watchers_;
-
- fidl::VectorPtr<std::string> visible_stories_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(VisibleStoriesHandler);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_FOCUS_H_
diff --git a/bin/sessionmgr/intelligence_services_impl.cc b/bin/sessionmgr/intelligence_services_impl.cc
deleted file mode 100644
index 4064069..0000000
--- a/bin/sessionmgr/intelligence_services_impl.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/intelligence_services_impl.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace modular {
-
-IntelligenceServicesImpl::IntelligenceServicesImpl(
- fuchsia::modular::ComponentScope scope,
- fuchsia::modular::ContextEngine* context_engine,
- fuchsia::modular::SuggestionEngine* suggestion_engine)
- : scope_(std::move(scope)),
- context_engine_(context_engine),
- suggestion_engine_(suggestion_engine) {}
-
-fuchsia::modular::ComponentScope IntelligenceServicesImpl::CloneScope() {
- fuchsia::modular::ComponentScope scope;
- fidl::Clone(scope_, &scope);
- return scope;
-}
-
-void IntelligenceServicesImpl::GetContextReader(
- fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) {
- context_engine_->GetReader(CloneScope(), std::move(request));
-}
-
-void IntelligenceServicesImpl::GetContextWriter(
- fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request) {
- context_engine_->GetWriter(CloneScope(), std::move(request));
-}
-
-void IntelligenceServicesImpl::GetProposalPublisher(
- fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher> request) {
- fidl::StringPtr component_id;
- if (scope_.is_agent_scope()) {
- component_id = scope_.agent_scope().url;
- } else if (scope_.is_module_scope()) {
- component_id = scope_.module_scope().url;
- } else { // scope_.is_global_scope()
- component_id = "global";
- }
-
- // TODO(thatguy): Change |component_id| to use
- // fuchsia::modular::ComponentScope once it is renamed to something like
- // ComponentInfo.
- suggestion_engine_->RegisterProposalPublisher(component_id,
- std::move(request));
-}
-
-void IntelligenceServicesImpl::RegisterQueryHandler(
- fidl::InterfaceHandle<fuchsia::modular::QueryHandler> query_handler) {
- fidl::StringPtr component_id;
- if (scope_.is_agent_scope()) {
- component_id = scope_.agent_scope().url;
- } else if (scope_.is_module_scope()) {
- component_id = scope_.module_scope().url;
- } else { // scope_.is_global_scope()
- component_id = "global";
- }
-
- suggestion_engine_->RegisterQueryHandler(component_id,
- std::move(query_handler));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/intelligence_services_impl.h b/bin/sessionmgr/intelligence_services_impl.h
deleted file mode 100644
index 2559d5d..0000000
--- a/bin/sessionmgr/intelligence_services_impl.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_INTELLIGENCE_SERVICES_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_INTELLIGENCE_SERVICES_IMPL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace modular {
-
-class IntelligenceServicesImpl : public fuchsia::modular::IntelligenceServices {
- public:
- // |context_engine| and |suggestion_engine| are not owned and must outlive
- // this instance.
- IntelligenceServicesImpl(
- fuchsia::modular::ComponentScope scope,
- fuchsia::modular::ContextEngine* context_engine,
- fuchsia::modular::SuggestionEngine* suggestion_engine);
-
- void GetContextReader(
- fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) override;
- void GetContextWriter(
- fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request) override;
-
- void GetProposalPublisher(
- fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher> request)
- override;
-
- void RegisterQueryHandler(
- fidl::InterfaceHandle<fuchsia::modular::QueryHandler> query_handler)
- override;
-
- private:
- fuchsia::modular::ComponentScope CloneScope();
-
- fuchsia::modular::ComponentScope scope_;
- fuchsia::modular::ContextEngine* const context_engine_; // Not owned.
- fuchsia::modular::SuggestionEngine* const suggestion_engine_; // Not owned.
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_INTELLIGENCE_SERVICES_IMPL_H_
diff --git a/bin/sessionmgr/message_queue/BUILD.gn b/bin/sessionmgr/message_queue/BUILD.gn
deleted file mode 100644
index 8896ce2..0000000
--- a/bin/sessionmgr/message_queue/BUILD.gn
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("message_queue") {
- sources = [
- "message_queue_manager.cc",
- "message_queue_manager.h",
- "persistent_queue.cc",
- "persistent_queue.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/sessionmgr/agent_runner:public",
- "//peridot/bin/sessionmgr/entity_provider_runner",
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/ledger_client:operations",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/ledger_client:types",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
diff --git a/bin/sessionmgr/message_queue/message_queue_manager.cc b/bin/sessionmgr/message_queue/message_queue_manager.cc
deleted file mode 100644
index 35f8127..0000000
--- a/bin/sessionmgr/message_queue/message_queue_manager.cc
+++ /dev/null
@@ -1,921 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/message_queue/message_queue_manager.h"
-
-#include <algorithm>
-#include <deque>
-#include <utility>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "peridot/bin/sessionmgr/message_queue/persistent_queue.h"
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/ledger_client/operations.h"
-#include "peridot/lib/ledger_client/page_client.h"
-
-namespace modular {
-
-struct MessageQueueInfo {
- std::string component_namespace;
- std::string component_instance_id;
- std::string queue_name;
- std::string queue_token;
-
- bool is_complete() const {
- return !component_instance_id.empty() && !queue_name.empty();
- }
-
- bool operator==(const MessageQueueInfo& a) const {
- return component_namespace == a.component_namespace &&
- component_instance_id == a.component_instance_id &&
- queue_name == a.queue_name && queue_token == a.queue_token;
- }
-};
-
-namespace {
-
-void XdrMessageQueueInfo_v1(XdrContext* const xdr,
- MessageQueueInfo* const data) {
- xdr->Field("component_namespace", &data->component_namespace);
- xdr->Field("component_instance_id", &data->component_instance_id);
- xdr->Field("queue_name", &data->queue_name);
- xdr->Field("queue_token", &data->queue_token);
-}
-
-void XdrMessageQueueInfo_v2(XdrContext* const xdr,
- MessageQueueInfo* const data) {
- if (!xdr->Version(2)) {
- return;
- }
- xdr->Field("component_namespace", &data->component_namespace);
- xdr->Field("component_instance_id", &data->component_instance_id);
- xdr->Field("queue_name", &data->queue_name);
- xdr->Field("queue_token", &data->queue_token);
-}
-
-constexpr XdrFilterType<MessageQueueInfo> XdrMessageQueueInfo[] = {
- XdrMessageQueueInfo_v2,
- XdrMessageQueueInfo_v1,
- nullptr,
-};
-
-} // namespace
-
-class MessageQueueStorage;
-
-// This class implements the |fuchsia::modular::MessageQueue| fidl interface,
-// and is owned by |MessageQueueStorage|. It forwards all calls to its owner,
-// and expects its owner to manage outstanding
-// |fuchsia::modular::MessageQueue.Receive| calls. It also notifies its owner on
-// object destruction.
-//
-// Interface is public, because bindings are outside of the class.
-class MessageQueueConnection : public fuchsia::modular::MessageQueue {
- public:
- explicit MessageQueueConnection(MessageQueueStorage* queue_storage);
- ~MessageQueueConnection() override;
-
- private:
- // |fuchsia::modular::MessageQueue|
- void RegisterReceiver(
- fidl::InterfaceHandle<fuchsia::modular::MessageReader> receiver) override;
-
- // |fuchsia::modular::MessageQueue|
- void GetToken(GetTokenCallback callback) override;
-
- MessageQueueStorage* const queue_storage_;
-};
-
-// Class for managing a particular message queue, its tokens and its storage.
-// Implementations of |fuchsia::modular::MessageQueue| and
-// |fuchsia::modular::MessageSender| call into this class to manipulate the
-// message queue. Owned by |MessageQueueManager|.
-class MessageQueueStorage : fuchsia::modular::MessageSender {
- public:
- MessageQueueStorage(std::string queue_name, std::string queue_token,
- const std::string& file_name_)
- : queue_name_(std::move(queue_name)),
- queue_token_(std::move(queue_token)),
- queue_data_(file_name_) {}
-
- ~MessageQueueStorage() override = default;
-
- void RegisterReceiver(
- fidl::InterfaceHandle<fuchsia::modular::MessageReader> receiver) {
- if (message_receiver_) {
- FXL_DLOG(WARNING)
- << "Existing fuchsia::modular::MessageReader is being replaced for "
- "message queue. queue name="
- << queue_name_;
- }
-
- message_receiver_.Bind(std::move(receiver));
- message_receiver_.set_error_handler(
- [this](zx_status_t status) {
- if (receive_ack_pending_) {
- FXL_DLOG(WARNING)
- << "MessageReceiver closed, but OnReceive acknowledgement still"
- " pending.";
- }
- message_receiver_.Unbind();
- receive_ack_pending_ = false;
- });
-
- MaybeSendNextMessage();
- }
-
- const std::string& queue_token() const { return queue_token_; }
-
- void AddMessageSenderBinding(
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request) {
- message_sender_bindings_.AddBinding(this, std::move(request));
- }
-
- void AddMessageQueueBinding(
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request) {
- message_queue_bindings_.AddBinding(
- std::make_unique<MessageQueueConnection>(this), std::move(request));
- }
-
- void RegisterWatcher(const std::function<void()>& watcher) {
- watcher_ = watcher;
- if (watcher_ && !queue_data_.IsEmpty()) {
- watcher_();
- }
- }
-
- void DropWatcher() { watcher_ = nullptr; }
-
- private:
- void MaybeSendNextMessage() {
- if (!message_receiver_ || receive_ack_pending_ || queue_data_.IsEmpty()) {
- return;
- }
-
- receive_ack_pending_ = true;
-
- fsl::SizedVmo queue_data_vmo;
- FXL_CHECK(VmoFromString(queue_data_.Peek(), &queue_data_vmo));
- message_receiver_->OnReceive(std::move(queue_data_vmo).ToTransport(),
- [this] {
- receive_ack_pending_ = false;
- queue_data_.Dequeue();
- MaybeSendNextMessage();
- });
- }
-
- // |fuchsia::modular::MessageSender|
- void Send(fuchsia::mem::Buffer message) override {
- std::string msg_str;
- FXL_CHECK(fsl::StringFromVmo(message, &msg_str));
- queue_data_.Enqueue(msg_str);
- MaybeSendNextMessage();
- if (watcher_) {
- watcher_();
- }
- }
-
- const std::string queue_name_;
- const std::string queue_token_;
-
- std::function<void()> watcher_;
-
- PersistentQueue queue_data_;
-
- bool receive_ack_pending_ = false;
- fuchsia::modular::MessageReaderPtr message_receiver_;
-
- // When a |fuchsia::modular::MessageQueue| connection closes, the
- // corresponding MessageQueueConnection instance gets removed.
- fidl::BindingSet<fuchsia::modular::MessageQueue,
- std::unique_ptr<MessageQueueConnection>>
- message_queue_bindings_;
-
- fidl::BindingSet<fuchsia::modular::MessageSender> message_sender_bindings_;
-};
-
-// MessageQueueConnection -----------------------------------------------------
-
-MessageQueueConnection::MessageQueueConnection(
- MessageQueueStorage* const queue_storage)
- : queue_storage_(queue_storage) {}
-
-MessageQueueConnection::~MessageQueueConnection() = default;
-
-void MessageQueueConnection::RegisterReceiver(
- fidl::InterfaceHandle<fuchsia::modular::MessageReader> receiver) {
- queue_storage_->RegisterReceiver(std::move(receiver));
-}
-
-void MessageQueueConnection::GetToken(GetTokenCallback callback) {
- callback(queue_storage_->queue_token());
-}
-
-// MessageQueueManager --------------------------------------------------------
-
-namespace {
-
-std::string GenerateQueueToken() {
- // Get 256 bits of pseudo-randomness.
- constexpr size_t kBitCount = 256;
- constexpr size_t kBitsPerByte = 8;
- constexpr size_t kCharsPerByte = 2;
- constexpr size_t kByteCount = kBitCount / kBitsPerByte;
- constexpr char kHex[] = "0123456789ABCDEF";
- uint8_t bytes[kByteCount] = {};
- zx_cprng_draw(bytes, kByteCount);
- std::string token(kByteCount * kCharsPerByte, '\0');
- for (size_t i = 0; i < kByteCount; ++i) {
- uint8_t byte = bytes[i];
- token[2 * i] = kHex[byte & 0x0F];
- token[2 * i + 1] = kHex[byte / 0x10];
- }
- return token;
-}
-
-} // namespace
-
-class MessageQueueManager::GetQueueTokenCall
- : public PageOperation<fidl::StringPtr> {
- public:
- GetQueueTokenCall(fuchsia::ledger::Page* const page,
- std::string component_namespace,
- std::string component_instance_id,
- const std::string& queue_name, ResultCall result_call)
- : PageOperation("MessageQueueManager::GetQueueTokenCall", page,
- std::move(result_call), queue_name),
- component_namespace_(std::move(component_namespace)),
- component_instance_id_(std::move(component_instance_id)),
- queue_name_(queue_name) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &result_};
-
- page()->GetSnapshot(snapshot_.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "Page.GetSnapshot() "
- << fidl::ToUnderlying(status);
- return;
- }
-
- Cont(flow);
- }));
- }
-
- void Cont(FlowToken flow) {
- snapshot_.set_error_handler([](zx_status_t status) {
- FXL_LOG(WARNING) << "Error on snapshot connection";
- });
-
- key_ = MakeMessageQueueTokenKey(component_namespace_,
- component_instance_id_, queue_name_);
- snapshot_->Get(to_array(key_), [this, flow](fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr value) {
- if (status == fuchsia::ledger::Status::KEY_NOT_FOUND) {
- // Key wasn't found, that's not an error.
- return;
- }
-
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " " << key_ << " "
- << "PageSnapshot.Get() " << fidl::ToUnderlying(status);
- return;
- }
-
- if (!value) {
- FXL_LOG(ERROR) << trace_name() << " " << key_ << " "
- << "Value is null.";
- return;
- }
-
- std::string queue_token;
- if (!fsl::StringFromVmo(*value, &queue_token)) {
- FXL_LOG(ERROR) << trace_name() << " " << key_ << " "
- << "VMO could not be copied.";
- return;
- }
- result_ = queue_token;
- });
- }
-
- const std::string component_namespace_;
- const std::string component_instance_id_;
- const std::string queue_name_;
- fuchsia::ledger::PageSnapshotPtr snapshot_;
- std::string key_;
-
- fidl::StringPtr result_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(GetQueueTokenCall);
-};
-
-class MessageQueueManager::GetMessageSenderCall : public PageOperation<> {
- public:
- GetMessageSenderCall(
- MessageQueueManager* const message_queue_manager,
- fuchsia::ledger::Page* const page, std::string token,
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request)
- : PageOperation("MessageQueueManager::GetMessageSenderCall", page, [] {}),
- message_queue_manager_(message_queue_manager),
- token_(std::move(token)),
- request_(std::move(request)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- page()->GetSnapshot(snapshot_.NewRequest(), std::vector<uint8_t>(), nullptr,
- Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "Page.GetSnapshot() "
- << fidl::ToUnderlying(status);
- return;
- }
-
- Cont(flow);
- }));
- }
-
- void Cont(FlowToken flow) {
- std::string key = MakeMessageQueueKey(token_);
- snapshot_->Get(to_array(key), [this, flow](fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr value) {
- if (status != fuchsia::ledger::Status::OK) {
- if (status != fuchsia::ledger::Status::KEY_NOT_FOUND) {
- // It's expected that the key is not found when the link
- // is accessed for the first time. Don't log an error
- // then.
- FXL_LOG(ERROR) << trace_name() << " " << token_ << " "
- << "PageSnapshot.Get() " << fidl::ToUnderlying(status);
- }
- return;
- }
-
- std::string value_as_string;
- if (value) {
- if (!fsl::StringFromVmo(*value, &value_as_string)) {
- FXL_LOG(ERROR) << trace_name() << " " << token_ << " "
- << "VMO could not be copied.";
- return;
- }
- }
-
- if (!XdrRead(value_as_string, &result_, XdrMessageQueueInfo)) {
- return;
- }
-
- if (!result_.is_complete()) {
- FXL_LOG(WARNING) << trace_name() << " " << token_ << " "
- << "Queue token not found in the ledger.";
- return;
- }
-
- message_queue_manager_->GetMessageQueueStorage(result_)
- ->AddMessageSenderBinding(std::move(request_));
- });
- }
-
- MessageQueueManager* const message_queue_manager_; // not owned
- const std::string token_;
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request_;
-
- fuchsia::ledger::PageSnapshotPtr snapshot_;
- std::string key_;
-
- MessageQueueInfo result_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(GetMessageSenderCall);
-};
-
-class MessageQueueManager::ObtainMessageQueueCall : public PageOperation<> {
- public:
- ObtainMessageQueueCall(
- MessageQueueManager* const message_queue_manager,
- fuchsia::ledger::Page* const page, const std::string& component_namespace,
- const std::string& component_instance_id, const std::string& queue_name,
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request)
- : PageOperation("MessageQueueManager::ObtainMessageQueueCall", page,
- [] {}, queue_name),
- message_queue_manager_(message_queue_manager),
- request_(std::move(request)) {
- message_queue_info_.component_namespace = component_namespace;
- message_queue_info_.component_instance_id = component_instance_id;
- message_queue_info_.queue_name = queue_name;
- }
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- operation_collection_.Add(new GetQueueTokenCall(
- page(), message_queue_info_.component_namespace,
- message_queue_info_.component_instance_id,
- message_queue_info_.queue_name, [this, flow](fidl::StringPtr token) {
- if (token) {
- // Queue token was found in the ledger.
- message_queue_info_.queue_token = token.get();
- Finish(flow);
- return;
- }
-
- Cont(flow);
- }));
- }
-
- void Cont(FlowToken flow) {
- // Not found in the ledger, time to create a new message
- // queue.
- message_queue_info_.queue_token = GenerateQueueToken();
-
- page()->StartTransaction(Protect([this](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "Page.StartTransaction() "
- << fidl::ToUnderlying(status);
- }
- }));
-
- const std::string message_queue_token_key =
- MakeMessageQueueTokenKey(message_queue_info_.component_namespace,
- message_queue_info_.component_instance_id,
- message_queue_info_.queue_name);
-
- page()->Put(to_array(message_queue_token_key),
- to_array(message_queue_info_.queue_token),
- Protect([this, key = message_queue_token_key](
- fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR)
- << trace_name() << " " << key << " "
- << "Page.Put() " << fidl::ToUnderlying(status);
- }
- }));
-
- const std::string message_queue_key =
- MakeMessageQueueKey(message_queue_info_.queue_token);
-
- std::string json;
- XdrWrite(&json, &message_queue_info_, XdrMessageQueueInfo);
-
- page()->Put(to_array(message_queue_key), to_array(json),
- Protect([this, key = message_queue_key](
- fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR)
- << trace_name() << " " << key << " "
- << "Page.Put() " << fidl::ToUnderlying(status);
- }
- }));
-
- page()->Commit(Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "Page.Commit() " << static_cast<uint32_t>(status);
- return;
- }
-
- FXL_LOG(INFO) << trace_name() << " "
- << "Created message queue: "
- << message_queue_info_.queue_token;
-
- Finish(flow);
- }));
- }
-
- void Finish(FlowToken /*flow*/) {
- message_queue_manager_->GetMessageQueueStorage(message_queue_info_)
- ->AddMessageQueueBinding(std::move(request_));
- }
-
- MessageQueueManager* const message_queue_manager_; // not owned
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request_;
-
- MessageQueueInfo message_queue_info_;
- fuchsia::ledger::PageSnapshotPtr snapshot_;
-
- OperationCollection operation_collection_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ObtainMessageQueueCall);
-};
-
-class MessageQueueManager::DeleteMessageQueueCall : public PageOperation<> {
- public:
- DeleteMessageQueueCall(MessageQueueManager* const message_queue_manager,
- fuchsia::ledger::Page* const page,
- const std::string& component_namespace,
- const std::string& component_instance_id,
- const std::string& queue_name)
- : PageOperation("MessageQueueManager::DeleteMessageQueueCall", page,
- [] {}, queue_name),
- message_queue_manager_(message_queue_manager) {
- message_queue_info_.component_namespace = component_namespace;
- message_queue_info_.component_instance_id = component_instance_id;
- message_queue_info_.queue_name = queue_name;
- }
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- operation_collection_.Add(new GetQueueTokenCall(
- page(), message_queue_info_.component_namespace,
- message_queue_info_.component_instance_id,
- message_queue_info_.queue_name, [this, flow](fidl::StringPtr token) {
- if (!token) {
- FXL_LOG(WARNING)
- << trace_name() << " " << message_queue_info_.queue_name << " "
- << "Request to delete queue not found in ledger"
- << " for component instance "
- << message_queue_info_.component_instance_id << ".";
- return;
- }
-
- message_queue_info_.queue_token = token.get();
-
- std::string message_queue_key =
- MakeMessageQueueKey(message_queue_info_.queue_token);
-
- std::string message_queue_token_key = MakeMessageQueueTokenKey(
- message_queue_info_.component_namespace,
- message_queue_info_.component_instance_id,
- message_queue_info_.queue_name);
-
- // Delete the ledger entries.
- page()->StartTransaction(
- Protect([this](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "Page.StartTransaction() "
- << fidl::ToUnderlying(status);
- }
- }));
-
- page()->Delete(to_array(message_queue_key),
- Protect([this, key = message_queue_key](
- fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " " << key << " "
- << "Page.Delete() "
- << fidl::ToUnderlying(status);
- }
- }));
-
- page()->Delete(to_array(message_queue_token_key),
- Protect([this, key = message_queue_token_key](
- fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " " << key << " "
- << "Page.Delete() "
- << fidl::ToUnderlying(status);
- }
- }));
-
- message_queue_manager_->ClearMessageQueueStorage(message_queue_info_);
-
- page()->Commit(Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "Page.Commit() " << fidl::ToUnderlying(status);
- return;
- }
-
- FXL_LOG(INFO) << trace_name() << " "
- << "Deleted message queue: "
- << message_queue_info_.component_instance_id << "/"
- << message_queue_info_.queue_name;
- }));
- }));
- }
-
- MessageQueueManager* const message_queue_manager_; // not owned
- MessageQueueInfo message_queue_info_;
- fuchsia::ledger::PageSnapshotPtr snapshot_;
-
- OperationCollection operation_collection_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DeleteMessageQueueCall);
-};
-
-class MessageQueueManager::DeleteNamespaceCall : public PageOperation<> {
- public:
- DeleteNamespaceCall(MessageQueueManager* const message_queue_manager,
- fuchsia::ledger::Page* const page,
- const std::string& component_namespace,
- std::function<void()> done)
- : PageOperation("MessageQueueManager::DeleteNamespaceCall", page,
- std::move(done), component_namespace),
- message_queue_manager_(message_queue_manager),
- component_namespace_(component_namespace),
- message_queues_key_prefix_(
- MakeMessageQueuesPrefix(component_namespace)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- page()->GetSnapshot(snapshot_.NewRequest(),
- to_array(message_queues_key_prefix_), nullptr,
- Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "Page.GetSnapshot() "
- << fidl::ToUnderlying(status);
- return;
- }
- GetKeysToDelete(flow);
- }));
- }
-
- void GetKeysToDelete(FlowToken flow) {
- GetEntries(snapshot_.get(), &component_entries_,
- [this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR)
- << trace_name() << " "
- << "GetEntries() " << fidl::ToUnderlying(status);
- return;
- }
-
- ProcessKeysToDelete(flow);
- });
- }
-
- void ProcessKeysToDelete(FlowToken flow) {
- std::vector<std::string> keys_to_delete;
- for (const auto& entry : component_entries_) {
- FXL_DCHECK(entry.value) << "Value vmo handle is null";
-
- keys_to_delete.push_back(to_string(entry.key));
-
- std::string queue_token;
- if (!fsl::StringFromVmo(*entry.value, &queue_token)) {
- FXL_LOG(ERROR) << trace_name() << " " << to_string(entry.key)
- << "VMO could not be copied.";
- continue;
- }
-
- keys_to_delete.push_back(MakeMessageQueueKey(queue_token));
- }
-
- for (auto& i : keys_to_delete) {
- page()->Delete(
- to_array(i), Protect([this, i, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " " << i << "Page.Delete() "
- << fidl::ToUnderlying(status);
- }
- }));
- }
-
- message_queue_manager_->ClearMessageQueueStorage(component_namespace_);
- }
-
- MessageQueueManager* const message_queue_manager_; // not owned
- fuchsia::ledger::PageSnapshotPtr snapshot_;
- const std::string component_namespace_;
- const std::string message_queues_key_prefix_;
- std::vector<fuchsia::ledger::Entry> component_entries_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DeleteNamespaceCall);
-};
-
-MessageQueueManager::MessageQueueManager(LedgerClient* const ledger_client,
- fuchsia::ledger::PageId page_id,
- std::string local_path)
- : PageClient("MessageQueueManager", ledger_client, std::move(page_id)),
- local_path_(std::move(local_path)) {}
-
-MessageQueueManager::~MessageQueueManager() = default;
-
-void MessageQueueManager::ObtainMessageQueue(
- const std::string& component_namespace,
- const std::string& component_instance_id, const std::string& queue_name,
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request) {
- operation_collection_.Add(new ObtainMessageQueueCall(
- this, page(), component_namespace, component_instance_id, queue_name,
- std::move(request)));
-}
-
-template <typename ValueType>
-const ValueType* MessageQueueManager::FindQueueName(
- const ComponentQueueNameMap<ValueType>& queue_map,
- const MessageQueueInfo& info) {
- auto it1 = queue_map.find(info.component_namespace);
- if (it1 != queue_map.end()) {
- auto it2 = it1->second.find(info.component_instance_id);
- if (it2 != it1->second.end()) {
- auto it3 = it2->second.find(info.queue_name);
- if (it3 != it2->second.end()) {
- return &(it3->second);
- }
- }
- }
-
- return nullptr;
-}
-
-template <typename ValueType>
-void MessageQueueManager::EraseQueueName(
- ComponentQueueNameMap<ValueType>& queue_map, const MessageQueueInfo& info) {
- auto it1 = queue_map.find(info.component_namespace);
- if (it1 != queue_map.end()) {
- auto it2 = it1->second.find(info.component_instance_id);
- if (it2 != it1->second.end()) {
- it2->second.erase(info.queue_name);
- }
- }
-}
-
-template <typename ValueType>
-void MessageQueueManager::EraseNamespace(
- ComponentQueueNameMap<ValueType>& queue_map,
- const std::string& component_namespace) {
- auto it1 = queue_map.find(component_namespace);
- if (it1 != queue_map.end()) {
- it1->second.erase(component_namespace);
- }
-}
-
-MessageQueueStorage* MessageQueueManager::GetMessageQueueStorage(
- const MessageQueueInfo& info) {
- auto it = message_queues_.find(info.queue_token);
- if (it == message_queues_.end()) {
- // Not found, create one.
- bool inserted;
- std::string path = local_path_;
- path.push_back('/');
- path.append(info.queue_token);
- path.append(".json");
- auto new_queue = std::make_unique<MessageQueueStorage>(
- info.queue_name, info.queue_token, std::move(path));
- std::tie(it, inserted) = message_queues_.insert(
- std::make_pair(info.queue_token, std::move(new_queue)));
- FXL_DCHECK(inserted);
-
- message_queue_infos_[info.queue_token] = info;
-
- message_queue_tokens_[info.component_namespace][info.component_instance_id]
- [info.queue_name] = info.queue_token;
-
- const std::function<void()>* const watcher =
- FindQueueName(pending_watcher_callbacks_, info);
- if (watcher) {
- it->second->RegisterWatcher(*watcher);
- EraseQueueName(pending_watcher_callbacks_, info);
- }
- }
- return it->second.get();
-}
-
-void MessageQueueManager::ClearMessageQueueStorage(
- const MessageQueueInfo& info) {
- // Remove the |MessageQueueStorage| and delete it which in turn will
- // close all outstanding fuchsia::modular::MessageSender and
- // fuchsia::modular::MessageQueue interface connections, and delete all
- // messages on the queue permanently.
- message_queues_.erase(info.queue_token);
-
- // Clear entries in message_queue_tokens_ and
- // pending_watcher_callbacks_.
- EraseQueueName(pending_watcher_callbacks_, info);
- EraseQueueName(message_queue_tokens_, info);
-
- auto deletion_watchers = FindQueueName(deletion_watchers_, info);
- for (const auto& component_namespace_iter : *deletion_watchers) {
- for (const auto& component_instance_iter :
- component_namespace_iter.second) {
- component_instance_iter.second();
- }
- }
-
- EraseQueueName(deletion_watchers_, info);
-}
-
-void MessageQueueManager::ClearMessageQueueStorage(
- const std::string& component_namespace) {
- auto namespace_to_delete = deletion_watchers_[component_namespace];
- for (const auto& instances_in_namespace : namespace_to_delete) {
- for (const auto& queue_names : instances_in_namespace.second) {
- for (const auto& watcher_namespace : queue_names.second) {
- for (const auto& watcher_instance : watcher_namespace.second) {
- watcher_instance.second();
- }
- }
- }
- }
-
- EraseNamespace(pending_watcher_callbacks_, component_namespace);
- EraseNamespace(message_queue_tokens_, component_namespace);
- EraseNamespace(deletion_watchers_, component_namespace);
-}
-
-void MessageQueueManager::DeleteMessageQueue(
- const std::string& component_namespace,
- const std::string& component_instance_id, const std::string& queue_name) {
- operation_collection_.Add(new DeleteMessageQueueCall(
- this, page(), component_namespace, component_instance_id, queue_name));
-}
-
-void MessageQueueManager::DeleteNamespace(
- const std::string& component_namespace, std::function<void()> done) {
- operation_collection_.Add(new DeleteNamespaceCall(
- this, page(), component_namespace, std::move(done)));
-}
-
-void MessageQueueManager::GetMessageSender(
- const std::string& queue_token,
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request) {
- const auto& it = message_queues_.find(queue_token);
- if (it != message_queues_.cend()) {
- // Found the message queue already.
- it->second->AddMessageSenderBinding(std::move(request));
- return;
- }
-
- operation_collection_.Add(
- new GetMessageSenderCall(this, page(), queue_token, std::move(request)));
-}
-
-void MessageQueueManager::RegisterMessageWatcher(
- const std::string& component_namespace,
- const std::string& component_instance_id, const std::string& queue_name,
- const std::function<void()>& watcher) {
- const std::string* const token =
- FindQueueName(message_queue_tokens_,
- MessageQueueInfo{component_namespace, component_instance_id,
- queue_name, ""});
- if (!token) {
- pending_watcher_callbacks_[component_namespace][component_instance_id]
- [queue_name] = watcher;
- return;
- }
-
- auto msq_it = message_queues_.find(*token);
- FXL_DCHECK(msq_it != message_queues_.end());
- msq_it->second->RegisterWatcher(watcher);
-}
-
-void MessageQueueManager::RegisterDeletionWatcher(
- const std::string& component_namespace,
- const std::string& component_instance_id, const std::string& queue_token,
- const std::function<void()>& watcher) {
- auto it = message_queue_infos_.find(queue_token);
- if (it == message_queue_infos_.end()) {
- return;
- }
-
- const MessageQueueInfo queue_info = it->second;
-
- deletion_watchers_[queue_info.component_namespace]
- [queue_info.component_instance_id][queue_info.queue_name]
- [component_namespace][component_instance_id] = watcher;
-}
-
-void MessageQueueManager::DropMessageWatcher(
- const std::string& component_namespace,
- const std::string& component_instance_id, const std::string& queue_name) {
- MessageQueueInfo queue_info{component_namespace, component_instance_id,
- queue_name, ""};
- const std::string* const token =
- FindQueueName(message_queue_tokens_, queue_info);
- if (token) {
- // The |MessageQueueStorage| doesn't exist yet.
- EraseQueueName(message_queue_tokens_, queue_info);
- return;
- }
-
- auto msq_it = message_queues_.find(*token);
- if (msq_it == message_queues_.end()) {
- FXL_LOG(WARNING) << "Asked to DropWatcher for a queue that doesn't exist";
- return;
- }
- msq_it->second->DropWatcher();
-}
-
-void MessageQueueManager::DropDeletionWatcher(
- const std::string& watcher_namespace,
- const std::string& watcher_instance_id, const std::string& queue_token) {
- auto it = message_queue_infos_.find(queue_token);
- if (it == message_queue_infos_.end()) {
- return;
- }
-
- const MessageQueueInfo queue_info = it->second;
- deletion_watchers_[queue_info.component_namespace]
- [queue_info.component_instance_id][queue_info.queue_name]
- [watcher_namespace]
- .erase(watcher_instance_id);
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/message_queue/message_queue_manager.h b/bin/sessionmgr/message_queue/message_queue_manager.h
deleted file mode 100644
index cff7dd1..0000000
--- a/bin/sessionmgr/message_queue/message_queue_manager.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_MESSAGE_QUEUE_MESSAGE_QUEUE_MANAGER_H_
-#define PERIDOT_BIN_SESSIONMGR_MESSAGE_QUEUE_MESSAGE_QUEUE_MANAGER_H_
-
-#include <functional>
-#include <map>
-#include <memory>
-#include <queue>
-#include <string>
-#include <utility>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/types.h"
-
-namespace modular {
-
-class MessageQueueStorage;
-struct MessageQueueInfo;
-
-// Manages message queues for components. One MessageQueueManager
-// instance is used by all ComponentContextImpl instances, and manages
-// the message queues for all component instances. The
-// fuchsia::modular::ComponentContext instance is responsible for deleting the
-// message queues it has created, otherwise they are persisted.
-class MessageQueueManager : PageClient {
- public:
- MessageQueueManager(LedgerClient* ledger_client,
- fuchsia::ledger::PageId page_id, std::string local_path);
- ~MessageQueueManager() override;
-
- // An enum describing the types of events that can be watched via
- // |RegisterWatcher|.
- enum WatcherEventType {
- // Triggers when there is a new message on the watched messsage queue.
- NEW_MESSAGE,
- // Triggers when the watched message queue is deleted.
- QUEUE_DELETED,
- };
-
- void ObtainMessageQueue(
- const std::string& component_namespace,
- const std::string& component_instance_id, const std::string& queue_name,
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request);
-
- void DeleteMessageQueue(const std::string& component_namespace,
- const std::string& component_instance_id,
- const std::string& queue_name);
-
- void DeleteNamespace(const std::string& component_namespace,
- std::function<void()> done);
-
- void GetMessageSender(
- const std::string& queue_token,
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request);
-
- // Registers a watcher that will be called when there is a new message on a
- // queue corresponding to |component_namespace| x |component_instance_id| x
- // |queue_name|.
- //
- // |component_namespace| is the namespace of the watching component (i.e. the
- // creator of the queue).
- // |component_instance_id| is the namespace of the watching component (i.e.
- // the creator of the queue).
- // |queue_name| is the name of the message queue.
- //
- // Only one message watcher can be active for a given queue, and registering a
- // new one will remove any existing watcher.
- void RegisterMessageWatcher(const std::string& component_namespace,
- const std::string& component_instance_id,
- const std::string& queue_name,
- const std::function<void()>& watcher);
-
- // Registers a watcher that gets notified when a message queue with
- // |queue_token| is deleted.
- //
- // Only one deletion watcher can be active for a given queue, and registering
- // a new one will remove any existing watcher.
- //
- // |watcher_namespace| is the namespace of the component that is watching the
- // message queue deletion.
- // |watcher_instance_id| is the instance id of the component that is watching
- // the message queue deletion.
- // |queue_token| is the message queue token for the queue to be observed.
- // |watcher| is the callback that will be triggered.
- //
- // Note that this is different from |RegisterMessageWatcher|, where the passed
- // in namespace, instance ids, and queue name directly describe the queue.
- void RegisterDeletionWatcher(const std::string& component_namespace,
- const std::string& component_instance_id,
- const std::string& queue_token,
- const std::function<void()>& watcher);
-
- // Drops the watcher for |component_namespace| x |component_instance_id| x
- // |queue_name|.
- void DropMessageWatcher(const std::string& component_namespace,
- const std::string& component_instance_id,
- const std::string& queue_name);
-
- // Drops the watcher described by |queue_info| from watching for the
- // deletion of the queue with |queue_token|.
- void DropDeletionWatcher(const std::string& watcher_namespace,
- const std::string& watcher_instance_id,
- const std::string& queue_token);
-
- private:
- using ComponentNamespace = std::string;
- using ComponentInstanceId = std::string;
- using ComponentQueueName = std::string;
- template <typename Value>
- using ComponentQueueNameMap = std::map<
- ComponentNamespace,
- std::map<ComponentInstanceId, std::map<ComponentQueueName, Value>>>;
-
- using DeletionWatchers =
- std::map<std::string, std::map<std::string, std::function<void()>>>;
-
- // Returns the |MessageQueueStorage| for the queue_token. Creates it
- // if it doesn't exist yet.
- MessageQueueStorage* GetMessageQueueStorage(const MessageQueueInfo& info);
-
- // Clears the |MessageQueueStorage| for the queue_token.
- void ClearMessageQueueStorage(const MessageQueueInfo& info);
-
- // Clears the |MessageQueueStorage| for all the queues in the provided
- // component namespace.
- void ClearMessageQueueStorage(const std::string& component_namespace);
-
- // |FindQueueName()| and |EraseQueueName()| are helpers used to operate on
- // component (namespace, id, queue name) mappings.
- // If the given message queue |info| is found the stored pointer value, or
- // nullptr otherwise.
- template <typename ValueType>
- const ValueType* FindQueueName(
- const ComponentQueueNameMap<ValueType>& queue_map,
- const MessageQueueInfo& info);
-
- // Erases the |ValueType| stored under the provided |info|.
- // Implementation is in the .cc.
- template <typename ValueType>
- void EraseQueueName(ComponentQueueNameMap<ValueType>& queue_map,
- const MessageQueueInfo& info);
- // Erases all |ValueType|s under the provided namespace.
- // Implementation is in the .cc.
- template <typename ValueType>
- void EraseNamespace(ComponentQueueNameMap<ValueType>& queue_map,
- const std::string& component_namespace);
-
- const std::string local_path_;
-
- // A map of queue_token to |MessageQueueStorage|.
- std::map<std::string, std::unique_ptr<MessageQueueStorage>> message_queues_;
-
- // A map of queue_token to |MessageQueueInfo|. This allows for easy lookup of
- // message queue information for registering watchers that take message queue
- // tokens as parameters.
- std::map<std::string, MessageQueueInfo> message_queue_infos_;
-
- // A map of component instance id and queue name to queue tokens.
- // Entries are only here while a |MessageQueueStorage| exists.
- ComponentQueueNameMap<std::string> message_queue_tokens_;
-
- // A map of component instance id and queue name to watcher
- // callbacks. If a watcher is registered before a
- // |MessageQueueStorage| exists then it is stashed here until a
- // |MessageQueueStorage| is available.
- ComponentQueueNameMap<std::function<void()>> pending_watcher_callbacks_;
-
- // A map containing watchers that are to be notified when the described
- // message queue is deleted.
- ComponentQueueNameMap<DeletionWatchers> deletion_watchers_;
-
- OperationCollection operation_collection_;
-
- // Operations implemented here.
- class GetQueueTokenCall;
- class GetMessageSenderCall;
- class ObtainMessageQueueCall;
- class DeleteMessageQueueCall;
- class DeleteNamespaceCall;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(MessageQueueManager);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_MESSAGE_QUEUE_MESSAGE_QUEUE_MANAGER_H_
diff --git a/bin/sessionmgr/message_queue/persistent_queue.cc b/bin/sessionmgr/message_queue/persistent_queue.cc
deleted file mode 100644
index e82de2f..0000000
--- a/bin/sessionmgr/message_queue/persistent_queue.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/message_queue/persistent_queue.h"
-
-#include <utility>
-
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-
-namespace modular {
-
-PersistentQueue::PersistentQueue(std::string file_name)
- : file_name_(std::move(file_name)) {
- std::string contents;
- if (files::ReadFileToString(file_name_, &contents)) {
- rapidjson::Document document;
- document.Parse(contents);
- if (!document.IsArray()) {
- FXL_LOG(ERROR) << "Expected " << file_name_ << " to contain a JSON array";
- return;
- }
- for (rapidjson::Value::ConstValueIterator it = document.Begin();
- it != document.End(); ++it) {
- if (!it->IsString()) {
- FXL_LOG(ERROR) << "Expected a string but got: " << it;
- continue;
- }
- queue_.emplace_back(it->GetString(), it->GetStringLength());
- }
- }
-}
-
-void PersistentQueue::Save() {
- rapidjson::Document document;
- document.SetArray();
- for (const auto& it : queue_) {
- rapidjson::Value value;
- value.SetString(it.data(), it.size());
- document.PushBack(value, document.GetAllocator());
- }
- std::string contents = JsonValueToString(document);
- if (!files::WriteFile(file_name_, contents.data(), contents.size())) {
- FXL_LOG(ERROR) << "Failed to write to: " << file_name_;
- }
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/message_queue/persistent_queue.h b/bin/sessionmgr/message_queue/persistent_queue.h
deleted file mode 100644
index 554178c..0000000
--- a/bin/sessionmgr/message_queue/persistent_queue.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_MESSAGE_QUEUE_PERSISTENT_QUEUE_H_
-#define PERIDOT_BIN_SESSIONMGR_MESSAGE_QUEUE_PERSISTENT_QUEUE_H_
-
-#include <deque>
-#include <string>
-
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-/* Implements a FIFO queue of strings that is persisted to local storage as
- * JSON. It is not safe to use from multiple processes or threads. If writing
- * the queue JSON to disk fails an error will be logged but calls will not fail.
- */
-class PersistentQueue {
- public:
- explicit PersistentQueue(std::string file_name);
- bool IsEmpty() const { return queue_.empty(); }
-
- std::string Peek() const {
- FXL_DCHECK(!queue_.empty());
- return queue_.front();
- }
-
- std::string Dequeue() {
- std::string value = queue_.front();
- queue_.pop_front();
- Save();
- return value;
- }
-
- void Enqueue(const std::string& value) {
- queue_.push_back(value);
- Save();
- }
-
- private:
- std::string file_name_;
- std::deque<std::string> queue_;
-
- void Save();
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_MESSAGE_QUEUE_PERSISTENT_QUEUE_H_
diff --git a/bin/sessionmgr/meta/dev_session_shell.cmx b/bin/sessionmgr/meta/dev_session_shell.cmx
deleted file mode 100644
index a95f213..0000000
--- a/bin/sessionmgr/meta/dev_session_shell.cmx
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/bin/sessionmgr/meta/sessionmgr.cmx b/bin/sessionmgr/meta/sessionmgr.cmx
deleted file mode 100644
index 96b4b19..0000000
--- a/bin/sessionmgr/meta/sessionmgr.cmx
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/bin/sessionmgr/presentation_provider.cc b/bin/sessionmgr/presentation_provider.cc
deleted file mode 100644
index 0778be9..0000000
--- a/bin/sessionmgr/presentation_provider.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/presentation_provider.h"
-
-namespace modular {
-
-PresentationProvider::PresentationProvider() = default;
-PresentationProvider::~PresentationProvider() = default;
-
-} // namespace modular
diff --git a/bin/sessionmgr/presentation_provider.h b/bin/sessionmgr/presentation_provider.h
deleted file mode 100644
index a8cc8bd..0000000
--- a/bin/sessionmgr/presentation_provider.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PRESENTATION_PROVIDER_H_
-#define PERIDOT_BIN_SESSIONMGR_PRESENTATION_PROVIDER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-// Interface that allows a class that implements this functionality to pass a
-// purposeful reference to itself to another class that needs the functionality.
-class PresentationProvider {
- public:
- PresentationProvider();
- virtual ~PresentationProvider();
-
- virtual void GetPresentation(
- fidl::StringPtr story_id,
- fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request) = 0;
-
- virtual void WatchVisualState(
- fidl::StringPtr story_id,
- fidl::InterfaceHandle<fuchsia::modular::StoryVisualStateWatcher>
- watcher) = 0;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PRESENTATION_PROVIDER_H_
diff --git a/bin/sessionmgr/puppet_master/BUILD.gn b/bin/sessionmgr/puppet_master/BUILD.gn
deleted file mode 100644
index 51d3cbd..0000000
--- a/bin/sessionmgr/puppet_master/BUILD.gn
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-hermetic_tests_package("puppet_master_unittests") {
- deps = [
- ":dispatch_story_command_executor_unittest",
- ":puppet_master_impl_unittest",
- ":story_command_executor_unittest",
- "command_runners:add_mod_command_runner_unittest",
- "command_runners:focus_mod_command_runner_unittest",
- "command_runners:remove_mod_command_runner_unittest",
- "command_runners:set_focus_state_command_runner_unittest",
- "command_runners:set_kind_of_proto_story_option_command_runner_unittest",
- "command_runners:set_link_value_command_runner_unittest",
- ]
-}
-
-source_set("puppet_master_impl") {
- sources = [
- "puppet_master_impl.cc",
- "puppet_master_impl.h",
- "story_puppet_master_impl.cc",
- "story_puppet_master_impl.h",
- ]
-
- deps = [
- ":story_command_executor",
- "//garnet/public/lib/fxl",
- ]
-
- public_deps = [
- "//peridot/bin/sessionmgr/storage",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-executable("puppet_master_impl_unittest") {
- testonly = true
-
- sources = [
- "puppet_master_impl_unittest.cc",
- ]
-
- deps = [
- ":puppet_master_impl",
- ":story_command_executor",
- "//peridot/lib/testing:test_story_command_executor",
- "//peridot/lib/testing:test_with_session_storage",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("story_command_executor") {
- sources = [
- "story_command_executor.cc",
- "story_command_executor.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("story_command_executor_unittest") {
- testonly = true
-
- sources = [
- "story_command_executor_unittest.cc",
- ]
-
- deps = [
- ":story_command_executor",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("dispatch_story_command_executor") {
- sources = [
- "dispatch_story_command_executor.cc",
- "dispatch_story_command_executor.h",
- ]
-
- public_deps = [
- ":story_command_executor",
- "//peridot/bin/sessionmgr/puppet_master/command_runners:command_runner",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:future",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-executable("dispatch_story_command_executor_unittest") {
- testonly = true
-
- sources = [
- "dispatch_story_command_executor_unittest.cc",
- ]
-
- deps = [
- ":dispatch_story_command_executor",
- "//peridot/lib/testing:test_with_ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("make_production_impl") {
- sources = [
- "make_production_impl.cc",
- "make_production_impl.h",
- ]
-
- deps = [
- ":dispatch_story_command_executor",
- ":puppet_master_impl",
- "//peridot/bin/sessionmgr/puppet_master/command_runners:add_mod_command_runner",
- "//peridot/bin/sessionmgr/puppet_master/command_runners:focus_mod_command_runner",
- "//peridot/bin/sessionmgr/puppet_master/command_runners:remove_mod_command_runner",
- "//peridot/bin/sessionmgr/puppet_master/command_runners:set_focus_state_command_runner",
- "//peridot/bin/sessionmgr/puppet_master/command_runners:set_kind_of_proto_story_option_command_runner",
- "//peridot/bin/sessionmgr/puppet_master/command_runners:set_link_value_command_runner",
- "//peridot/lib/module_manifest:module_facet_reader",
- ]
-}
diff --git a/bin/sessionmgr/puppet_master/command_runners/BUILD.gn b/bin/sessionmgr/puppet_master/command_runners/BUILD.gn
deleted file mode 100644
index 98d33b4..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/BUILD.gn
+++ /dev/null
@@ -1,209 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("command_runner") {
- sources = [
- "command_runner.cc",
- "command_runner.h",
- ]
-
- public_deps = [
- "//peridot/bin/sessionmgr/storage",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("set_link_value_command_runner") {
- sources = [
- "set_link_value_command_runner.cc",
- "set_link_value_command_runner.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls:set_link_value_call",
- ]
-
- public_deps = [
- ":command_runner",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-executable("set_link_value_command_runner_unittest") {
- testonly = true
-
- sources = [
- "set_link_value_command_runner_unittest.cc",
- ]
-
- deps = [
- ":set_link_value_command_runner",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/gtest",
- "//peridot/lib/testing:test_with_session_storage",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("add_mod_command_runner") {
- sources = [
- "add_mod_command_runner.cc",
- "add_mod_command_runner.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls:add_mod_call",
- "//peridot/lib/module_manifest:module_facet_reader",
- ]
-
- public_deps = [
- ":command_runner",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-executable("add_mod_command_runner_unittest") {
- testonly = true
-
- sources = [
- "add_mod_command_runner_unittest.cc",
- ]
-
- deps = [
- ":add_mod_command_runner",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//peridot/lib/testing:entity_resolver_fake",
- "//peridot/lib/testing:module_facet_reader_fake",
- "//peridot/lib/testing:module_resolver_fake",
- "//peridot/lib/testing:test_with_session_storage",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("remove_mod_command_runner") {
- sources = [
- "remove_mod_command_runner.cc",
- "remove_mod_command_runner.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- ]
-
- public_deps = [
- ":command_runner",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-executable("remove_mod_command_runner_unittest") {
- testonly = true
-
- sources = [
- "remove_mod_command_runner_unittest.cc",
- ]
-
- deps = [
- ":remove_mod_command_runner",
- "//garnet/public/lib/gtest",
- "//peridot/lib/testing:test_with_session_storage",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("set_focus_state_command_runner") {
- sources = [
- "set_focus_state_command_runner.cc",
- "set_focus_state_command_runner.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- ]
-
- public_deps = [
- ":command_runner",
- ]
-}
-
-executable("set_focus_state_command_runner_unittest") {
- testonly = true
-
- sources = [
- "set_focus_state_command_runner_unittest.cc",
- ]
-
- deps = [
- ":set_focus_state_command_runner",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("focus_mod_command_runner") {
- sources = [
- "focus_mod_command_runner.cc",
- "focus_mod_command_runner.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- deps = [
- ":command_runner",
- ]
-}
-
-executable("focus_mod_command_runner_unittest") {
- testonly = true
-
- sources = [
- "focus_mod_command_runner_unittest.cc",
- ]
-
- deps = [
- ":focus_mod_command_runner",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("set_kind_of_proto_story_option_command_runner") {
- sources = [
- "set_kind_of_proto_story_option_command_runner.cc",
- "set_kind_of_proto_story_option_command_runner.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- deps = [
- ":command_runner",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-executable("set_kind_of_proto_story_option_command_runner_unittest") {
- testonly = true
-
- sources = [
- "set_kind_of_proto_story_option_command_runner_unittest.cc",
- ]
-
- deps = [
- ":set_kind_of_proto_story_option_command_runner",
- "//garnet/public/lib/gtest",
- "//peridot/lib/testing:test_with_session_storage",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.cc b/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.cc
deleted file mode 100644
index de39cd5..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.h"
-
-#include <lib/fxl/logging.h>
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h"
-
-namespace modular {
-
-AddModCommandRunner::AddModCommandRunner(
- fuchsia::modular::ModuleResolver* const module_resolver,
- fuchsia::modular::EntityResolver* const entity_resolver)
- : module_resolver_(module_resolver), entity_resolver_(entity_resolver) {
- FXL_DCHECK(module_resolver_);
- FXL_DCHECK(entity_resolver_);
-}
-
-AddModCommandRunner::~AddModCommandRunner() = default;
-
-void AddModCommandRunner::Execute(
- fidl::StringPtr story_id, StoryStorage* const story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- FXL_CHECK(command.is_add_mod());
-
- auto& add_mod = command.add_mod();
- if (add_mod.mod_name.size() == 0) {
- fuchsia::modular::ExecuteResult result;
- result.status = fuchsia::modular::ExecuteStatus::INVALID_COMMAND;
- result.error_message = "A Module name must be specified";
- done(result);
- return;
- }
-
- AddModParams params;
- params.parent_mod_path = std::move(add_mod.surface_parent_mod_name);
- if (add_mod.mod_name.size() == 1) {
- params.mod_name = add_mod.mod_name[0];
- } else {
- params.mod_name = add_mod.mod_name.back();
-
- add_mod.mod_name.pop_back();
- params.parent_mod_path = add_mod.mod_name;
- }
- params.is_embedded = false;
- params.intent = std::move(add_mod.intent);
- params.surface_relation = std::make_unique<fuchsia::modular::SurfaceRelation>(
- std::move(add_mod.surface_relation));
- params.module_source = fuchsia::modular::ModuleSource::EXTERNAL;
-
- AddAddModOperation(
- &operation_queue_, story_storage, module_resolver_, entity_resolver_,
- std::move(params),
- [done = std::move(done)](fuchsia::modular::ExecuteResult result,
- fuchsia::modular::ModuleData module_data) {
- done(std::move(result));
- });
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.h b/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.h
deleted file mode 100644
index f55e7b1..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_ADD_MOD_COMMAND_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_ADD_MOD_COMMAND_RUNNER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/command_runner.h"
-
-namespace modular {
-
-class AddModCommandRunner : public CommandRunner {
- public:
- // The following dependencies are needed for adding a module to the story:
- // * ModuleResolver: used to resolve an intent into a module.
- // * EntityResolver: used to resolve an intent parameter's type, which is
- // supplied to the module resolver for use in resolution.
- AddModCommandRunner(fuchsia::modular::ModuleResolver* const module_resolver,
- fuchsia::modular::EntityResolver* const entity_resolver);
- ~AddModCommandRunner() override;
-
- void Execute(
- fidl::StringPtr story_id, StoryStorage* story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override;
-
- private:
- OperationQueue operation_queue_;
- fuchsia::modular::ModuleResolver* const module_resolver_; // Not owned.
- fuchsia::modular::EntityResolver* const entity_resolver_; // Not owned.
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_ADD_MOD_COMMAND_RUNNER_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner_unittest.cc b/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner_unittest.cc
deleted file mode 100644
index 7337588..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner_unittest.cc
+++ /dev/null
@@ -1,659 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.h"
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/type_converter.h>
-
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/testing/entity_resolver_fake.h"
-#include "peridot/lib/testing/module_resolver_fake.h"
-#include "peridot/lib/testing/test_with_session_storage.h"
-
-namespace modular {
-namespace {
-
-fuchsia::modular::IntentFilter MakeIntentFilter(
- std::string action,
- std::vector<fuchsia::modular::ParameterConstraint> param_constraints) {
- fuchsia::modular::IntentFilter f;
- f.action = action;
- f.parameter_constraints = param_constraints;
- return f;
-}
-
-class AddModCommandRunnerTest : public testing::TestWithSessionStorage {
- public:
- void SetUp() override {
- testing::TestWithSessionStorage::SetUp();
- session_storage_ = MakeSessionStorage("page");
- story_id_ = CreateStory(session_storage_.get());
- story_storage_ = GetStoryStorage(session_storage_.get(), story_id_);
- fake_module_resolver_->Connect(module_resolver_.NewRequest());
- fake_entity_resolver_->Connect(entity_resolver_.NewRequest());
- runner_ = MakeRunner(module_resolver_.get(), entity_resolver_.get());
- }
-
- protected:
- // This method compares intents field by field, where fuchsia::mem::Buffers
- // are compared via their contents.
- bool AreIntentsEqual(const fuchsia::modular::Intent& old_intent,
- const fuchsia::modular::Intent& new_intent) {
- if (old_intent.handler != new_intent.handler) {
- return false;
- }
-
- if (old_intent.action != new_intent.action) {
- return false;
- }
-
- std::map<fidl::StringPtr, const fuchsia::modular::IntentParameterData*>
- old_params;
- if (old_intent.parameters) {
- for (const auto& entry : *old_intent.parameters) {
- old_params[entry.name] = &entry.data;
- }
- }
-
- std::map<fidl::StringPtr, const fuchsia::modular::IntentParameterData*>
- new_params;
- if (new_intent.parameters) {
- for (const auto& entry : *new_intent.parameters) {
- new_params[entry.name] = &entry.data;
- }
- }
-
- if (new_params.size() != old_params.size()) {
- return false;
- }
-
- for (const auto& entry : new_params) {
- const auto& name = entry.first;
- if (old_params.count(name) == 0) {
- return false;
- }
-
- const auto& new_param = *entry.second;
- const auto& old_param = *old_params[name];
-
- // If a parameter type changed, or a link mapping changed, we
- // need to relaunch.
- if (old_param.Which() != new_param.Which()) {
- return false;
- }
-
- switch (old_param.Which()) {
- case fuchsia::modular::IntentParameterData::Tag::kEntityType:
- if (old_param.entity_type() != new_param.entity_type()) {
- return false;
- }
- break;
- case fuchsia::modular::IntentParameterData::Tag::kEntityReference:
- if (old_param.entity_reference() != new_param.entity_reference()) {
- return false;
- }
- break;
- case fuchsia::modular::IntentParameterData::Tag::kJson: {
- std::string old_string;
- std::string new_string;
- if (old_param.json().size == 0 && new_param.json().size == 0) {
- break;
- }
-
- FXL_CHECK(fsl::StringFromVmo(old_param.json(), &old_string));
- FXL_CHECK(fsl::StringFromVmo(new_param.json(), &new_string));
- if (old_string != new_string) {
- return false;
- }
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::Invalid:
- break;
- }
- }
- return true;
- }
-
- std::unique_ptr<AddModCommandRunner> MakeRunner(
- fuchsia::modular::ModuleResolver* const module_resolver,
- fuchsia::modular::EntityResolver* const entity_resolver) {
- return std::make_unique<AddModCommandRunner>(module_resolver,
- entity_resolver);
- }
-
- fuchsia::modular::StoryCommand MakeAddModCommand(
- const std::string& mod_name, const std::string& parent_mod_name,
- float surface_emphasis, const fuchsia::modular::Intent& intent) {
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name = {mod_name};
- if (!parent_mod_name.empty()) {
- add_mod.surface_parent_mod_name.reset({parent_mod_name});
- }
- add_mod.surface_relation.emphasis = surface_emphasis;
- intent.Clone(&add_mod.intent);
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- return command;
- }
-
- fuchsia::modular::Intent CreateEmptyIntent(const std::string& action,
- const std::string& handler = "") {
- fuchsia::modular::Intent intent;
- intent.action = "intent_action";
- if (!handler.empty()) {
- intent.handler = "mod_url";
- }
- return intent;
- }
-
- void AddEntityRefParameter(fuchsia::modular::Intent* intent,
- const std::string& name,
- const std::string& reference) {
- fuchsia::modular::IntentParameter parameter;
- parameter.name = name;
- parameter.data.set_entity_reference(reference);
- intent->parameters.push_back(std::move(parameter));
- }
-
- void AddEntityTypeParameter(fuchsia::modular::Intent* intent,
- const std::string& name,
- std::vector<std::string> types) {
- fuchsia::modular::IntentParameter parameter;
- parameter.name = name;
- parameter.data.set_entity_type(types);
- intent->parameters.push_back(std::move(parameter));
- }
-
- void AddParameterWithoutName(fuchsia::modular::Intent* intent) {
- fuchsia::modular::IntentParameter parameter;
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString("10", &vmo));
- parameter.data.set_json(std::move(vmo).ToTransport());
- intent->parameters.push_back(std::move(parameter));
- }
-
- void AddJsonParameter(fuchsia::modular::Intent* intent,
- const std::string& name, const std::string& json) {
- fuchsia::modular::IntentParameter parameter;
- parameter.name = name;
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(json, &vmo));
- parameter.data.set_json(std::move(vmo).ToTransport());
- intent->parameters.push_back(std::move(parameter));
- }
-
- void AddInvalidParameter(fuchsia::modular::Intent* intent,
- const std::string& name) {
- // This parameter has no data union field set, hence it's invalid.
- fuchsia::modular::IntentParameterData data;
- fuchsia::modular::IntentParameter parameter;
- parameter.name = name;
- parameter.data = std::move(data);
- intent->parameters.push_back(std::move(parameter));
- }
-
- // Initializes a parent mod for the mod created during the test. The goal of
- // this mod is to test parameters of type link_name and as the
- // surface_relation_parent_mod.
- void InitParentMod(const std::string& mod_name, const std::string& param_name,
- const std::string& param_value,
- const std::string& link_path_name) {
- fuchsia::modular::ModuleData module_data;
- module_data.module_path.push_back(mod_name);
- module_data.intent = fuchsia::modular::Intent::New();
- AddJsonParameter(module_data.intent.get(), param_name, param_value);
-
- fuchsia::modular::ModuleParameterMapEntry parameter_entry;
- auto link_path = MakeLinkPath(link_path_name);
- fidl::Clone(module_data.module_path, &link_path.module_path);
- parameter_entry.name = param_name;
- fidl::Clone(link_path, ¶meter_entry.link_path);
- module_data.parameter_map.entries.push_back(std::move(parameter_entry));
-
- SetLinkValue(story_storage_.get(), link_path, param_value);
- WriteModuleData(story_storage_.get(), std::move(module_data));
- }
-
- std::unique_ptr<AddModCommandRunner> runner_;
- std::unique_ptr<SessionStorage> session_storage_;
- std::unique_ptr<StoryStorage> story_storage_;
- fuchsia::modular::ModuleResolverPtr module_resolver_;
- fuchsia::modular::EntityResolverPtr entity_resolver_;
- std::string story_id_;
- std::unique_ptr<ModuleResolverFake> fake_module_resolver_ =
- std::make_unique<ModuleResolverFake>();
- std::unique_ptr<EntityResolverFake> fake_entity_resolver_ =
- std::make_unique<EntityResolverFake>();
-};
-
-TEST_F(AddModCommandRunnerTest, ExecuteIntentWithIntentHandler) {
- // Set up command
- auto intent = CreateEmptyIntent("intent_action", "mod_url");
- intent.parameters.resize(0);
- auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);
-
- auto manifest = fuchsia::modular::ModuleManifest::New();
- manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
- manifest->binary = "mod_url";
-
- // Set up fake module resolver and set validation of GetModuleManifest call.
- fuchsia::modular::ModuleManifestPtr manifest_out;
- fuchsia::modular::ModuleManifestPtr manifest_to_add;
- fidl::Clone(manifest, &manifest_out);
- fidl::Clone(manifest, &manifest_to_add);
- fake_module_resolver_->SetManifest(std::move(manifest_out));
- fake_module_resolver_->SetGetModuleManifestValidation(
- [&](const fidl::StringPtr& module_id) {
- EXPECT_EQ(intent.handler, module_id);
- });
-
- fuchsia::modular::FindModulesResult res;
- res.module_id = "mod_url";
- res.manifest = std::move(manifest_to_add);
- fake_module_resolver_->AddFindModulesResult(std::move(res));
-
- // Run the command and assert results.
- bool done = false;
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- ASSERT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- done = false;
- std::vector<std::string> full_path{"parent_mod", "mod"};
- story_storage_->ReadModuleData(std::move(full_path))
- ->Then([&](fuchsia::modular::ModuleDataPtr module_data) {
- EXPECT_EQ("mod_url", module_data->module_url);
- EXPECT_EQ(full_path, module_data->module_path);
- EXPECT_FALSE(module_data->module_deleted);
- EXPECT_EQ(fuchsia::modular::ModuleSource::EXTERNAL,
- module_data->module_source);
- EXPECT_EQ(0.5, module_data->surface_relation->emphasis);
- EXPECT_TRUE(AreIntentsEqual(intent, *module_data->intent));
- EXPECT_EQ(0u, module_data->parameter_map.entries.size());
- done = true;
- });
-
- RunLoopUntil([&] { return done; });
-}
-
-// Explicitly leave surface_parent_mod_name as null when providing the Intent.
-// We should tolerate this, and initialize it to a zero-length vector
-// internally.
-TEST_F(AddModCommandRunnerTest, ExecuteIntentWithIntentHandler_NoParent) {
- auto intent = CreateEmptyIntent("intent_action", "mod_url");
- intent.parameters.resize(0);
- auto command =
- MakeAddModCommand("mod", "" /* parent mod is null */, 0.5, intent);
-
- auto manifest = fuchsia::modular::ModuleManifest::New();
- manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
- manifest->binary = "mod_url";
-
- // Set up fake module resolver and set validation of GetModuleManifest call.
- fuchsia::modular::ModuleManifestPtr manifest_out;
- fuchsia::modular::ModuleManifestPtr manifest_to_add;
- fidl::Clone(manifest, &manifest_out);
- fidl::Clone(manifest, &manifest_to_add);
- fake_module_resolver_->SetManifest(std::move(manifest_out));
- fake_module_resolver_->SetGetModuleManifestValidation(
- [&](const fidl::StringPtr& module_id) {
- EXPECT_EQ(intent.handler, module_id);
- });
-
- fuchsia::modular::FindModulesResult res;
- res.module_id = "mod_url";
- res.manifest = std::move(manifest_to_add);
- fake_module_resolver_->AddFindModulesResult(std::move(res));
-
- // Run the command and assert results.
- bool done = false;
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- ASSERT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- done = false;
- std::vector<std::string> full_path{"mod"};
- story_storage_->ReadModuleData(std::move(full_path))
- ->Then([&](fuchsia::modular::ModuleDataPtr module_data) {
- EXPECT_EQ("mod_url", module_data->module_url);
- EXPECT_EQ(full_path, module_data->module_path);
- EXPECT_FALSE(module_data->module_deleted);
- EXPECT_EQ(fuchsia::modular::ModuleSource::EXTERNAL,
- module_data->module_source);
- EXPECT_EQ(0.5, module_data->surface_relation->emphasis);
- EXPECT_TRUE(AreIntentsEqual(intent, *module_data->intent));
- EXPECT_EQ(0u, module_data->parameter_map.entries.size());
- done = true;
- });
-
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(AddModCommandRunnerTest, ExecuteIntentThatNeedsResolution) {
- auto reference =
- fake_entity_resolver_->AddEntity({{"entity_type1", "entity_data"}});
-
- InitParentMod("parent_mod", "param", R"({"@type": "baz"})",
- "parent_link_name");
-
- // Set up command
- auto intent = CreateEmptyIntent("intent_action");
- AddJsonParameter(&intent, "param_json", R"({"@type": "foo"})");
- AddEntityRefParameter(&intent, "param_ref", reference);
- AddEntityTypeParameter(&intent, "param_type", {"entity_type2"});
- auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);
-
- auto manifest = fuchsia::modular::ModuleManifest::New();
- manifest->binary = "mod_url";
- manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
- fuchsia::modular::FindModulesResult result;
- result.module_id = "mod_url";
- fidl::Clone(manifest, &result.manifest);
-
- fake_module_resolver_->AddFindModulesResult(std::move(result));
- // Since we are mocking module resolver and returning the expected |result|,
- // ensure that at least it's being called with the right parameters.
- fake_module_resolver_->SetFindModulesValidation(
- [&](const fuchsia::modular::FindModulesQuery& query) {
- EXPECT_EQ("intent_action", query.action);
- auto& constraints = query.parameter_constraints;
- EXPECT_EQ(3u, constraints.size());
- for (auto& constraint : constraints) {
- EXPECT_EQ(1u, constraint.param_types.size());
- }
- EXPECT_EQ("param_json", constraints.at(0).param_name);
- EXPECT_EQ("foo", constraints.at(0).param_types.at(0));
- EXPECT_EQ("param_ref", constraints.at(1).param_name);
- EXPECT_EQ("entity_type1", constraints.at(1).param_types.at(0));
- EXPECT_EQ("param_ref", constraints.at(1).param_name);
- EXPECT_EQ("entity_type1", constraints.at(1).param_types.at(0));
- EXPECT_EQ("param_type", constraints.at(2).param_name);
- EXPECT_EQ("entity_type2", constraints.at(2).param_types.at(0));
- });
-
- bool done{};
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- done = false;
- std::vector<std::string> full_path{"parent_mod", "mod"};
- fuchsia::modular::ModuleDataPtr module_data;
- story_storage_->ReadModuleData(std::move(full_path))
- ->Then([&](fuchsia::modular::ModuleDataPtr result) {
- module_data = std::move(result);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- EXPECT_EQ("mod_url", module_data->module_url);
- EXPECT_EQ(full_path, module_data->module_path);
- EXPECT_FALSE(module_data->module_deleted);
- EXPECT_EQ(fuchsia::modular::ModuleSource::EXTERNAL,
- module_data->module_source);
- EXPECT_EQ(0.5, module_data->surface_relation->emphasis);
- EXPECT_TRUE(AreIntentsEqual(intent, *module_data->intent));
- EXPECT_EQ(3u, module_data->parameter_map.entries.size());
-
- // Verify parameters
- auto& link_path1 = module_data->parameter_map.entries.at(0).link_path;
- EXPECT_EQ("param_json", module_data->parameter_map.entries.at(0).name);
- EXPECT_EQ(full_path, link_path1.module_path);
- EXPECT_EQ("param_json", link_path1.link_name);
- EXPECT_EQ(R"({"@type": "foo"})",
- GetLinkValue(story_storage_.get(), link_path1));
-
- auto& link_path2 = module_data->parameter_map.entries.at(1).link_path;
- EXPECT_EQ("param_ref", module_data->parameter_map.entries.at(1).name);
- EXPECT_EQ(full_path, link_path2.module_path);
- EXPECT_EQ("param_ref", link_path2.link_name);
- EXPECT_EQ(R"({"@entityRef":")" + *reference + R"("})",
- GetLinkValue(story_storage_.get(), link_path2));
-
- auto& link_path3 = module_data->parameter_map.entries.at(2).link_path;
- EXPECT_EQ("param_type", module_data->parameter_map.entries.at(2).name);
- EXPECT_EQ(full_path, link_path3.module_path);
- EXPECT_EQ("param_type", link_path3.link_name);
- EXPECT_EQ("null", GetLinkValue(story_storage_.get(), link_path3));
-}
-
-TEST_F(AddModCommandRunnerTest, ExecuteNoModulesFound) {
- fuchsia::modular::Intent intent;
- fuchsia::modular::AddMod add_mod;
- intent.Clone(&add_mod.intent);
- add_mod.mod_name.push_back("mymod");
- add_mod.intent.action = "intent_action";
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
-
- bool done{};
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(
- fuchsia::modular::ExecuteStatus::NO_MODULES_FOUND,
- result.status);
- EXPECT_EQ("Resolution of intent gave zero results.",
- result.error_message);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(AddModCommandRunnerTest, ExecuteInvalidParameter) {
- // Set up command
- auto intent = CreateEmptyIntent("intent_action", "mod_url");
- AddInvalidParameter(&intent, "invalid_param");
- auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);
-
- auto manifest = fuchsia::modular::ModuleManifest::New();
- manifest->binary = "mod_url";
- manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
-
- // Set up fake module resolver.
- fuchsia::modular::ModuleManifestPtr manifest_out;
- fidl::Clone(manifest, &manifest_out);
- fake_module_resolver_->SetManifest(std::move(manifest_out));
-
- // Run the command and assert results.
- bool done{};
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND,
- result.status);
- EXPECT_EQ(
- "Invalid data for parameter with name: "
- "invalid_param",
- result.error_message);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(AddModCommandRunnerTest, ExecuteInvalidParameterWithResulution) {
- // Set up command
- auto intent = CreateEmptyIntent("intent_action");
- AddInvalidParameter(&intent, "invalid_param");
- auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);
-
- // Set up fake module resolver.
- auto manifest = fuchsia::modular::ModuleManifest::New();
- manifest->binary = "mod_url";
- manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
- fuchsia::modular::FindModulesResult result;
- result.module_id = "mod_url";
- fidl::Clone(manifest, &result.manifest);
-
- fake_module_resolver_->AddFindModulesResult(std::move(result));
-
- // Run the command and assert results.
- bool done{};
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND,
- result.status);
- EXPECT_EQ(
- "Invalid data for parameter with name: "
- "invalid_param",
- result.error_message);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(AddModCommandRunnerTest, ExecuteNullHandlerAndParameter) {
- // Set up command
- auto intent = CreateEmptyIntent("intent_action");
- AddParameterWithoutName(&intent);
- auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);
-
- // Run the command and assert results.
- bool done{};
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND,
- result.status);
- EXPECT_EQ(
- "A null-named module parameter is not allowed "
- "when using fuchsia::modular::Intent.",
- result.error_message);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(AddModCommandRunnerTest, ExecuteInvalidJsonParamResolution) {
- // Set up command
- auto intent = CreateEmptyIntent("intent_action");
- AddJsonParameter(&intent, "invalid_param", "x}");
- auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);
-
- // Set up fake module resolver.
- auto manifest = fuchsia::modular::ModuleManifest::New();
- manifest->binary = "mod_url";
- manifest->intent_filters.push_back(MakeIntentFilter("intent_action", {}));
- fuchsia::modular::FindModulesResult result;
- result.module_id = "mod_url";
- fidl::Clone(manifest, &result.manifest);
- fake_module_resolver_->AddFindModulesResult(std::move(result));
-
- // Run the command and assert results.
- bool done{};
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND,
- result.status);
- EXPECT_EQ("Mal-formed JSON in parameter: invalid_param",
- result.error_message);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(AddModCommandRunnerTest, UpdatesModIfItExists) {
- // Set up command
- auto intent = CreateEmptyIntent("intent_action", "mod_url");
- AddJsonParameter(&intent, "param_json", R"({"@type": "foo"})");
- auto command = MakeAddModCommand("mod", "parent_mod", 0.5, intent);
-
- auto manifest = fuchsia::modular::ModuleManifest::New();
- manifest->binary = "mod_url";
- manifest->intent_filters.push_back(MakeIntentFilter(
- "intent_action",
- {fuchsia::modular::ParameterConstraint{"param_json", "foo"}}));
-
- // Set up fake module resolver, set validaiton of GetModuleManifest call, and
- // a dummy result.
- {
- fuchsia::modular::ModuleManifestPtr manifest_out;
- fidl::Clone(manifest, &manifest_out);
- fake_module_resolver_->SetManifest(std::move(manifest_out));
-
- fuchsia::modular::FindModulesResult res;
- res.module_id = "mod_url";
- res.manifest = std::move(manifest);
- fake_module_resolver_->AddFindModulesResult(std::move(res));
- }
-
- // Add a mod to begin with.
- bool done{};
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- ASSERT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // Get the link path for the param of the mod we created.
- fuchsia::modular::LinkPath link_path;
- std::vector<std::string> full_path{"parent_mod", "mod"};
- story_storage_->ReadModuleData(full_path)->Then(
- [&](fuchsia::modular::ModuleDataPtr result) {
- for (auto& entry : result->parameter_map.entries) {
- if (entry.name == "param_json") {
- fidl::Clone(entry.link_path, &link_path);
- }
- }
- });
-
- // Create AddMod intent for a mod with the same name as the one we created
- // previously.
- auto intent2 = CreateEmptyIntent("intent_action", "mod_url");
- AddJsonParameter(&intent2, "param_json", R"({"@type": "baz"})");
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name = {"parent_mod", "mod"};
- intent2.Clone(&add_mod.intent);
- fuchsia::modular::StoryCommand command2;
- command2.set_add_mod(std::move(add_mod));
-
- {
- fuchsia::modular::ModuleManifestPtr manifest_out;
- fidl::Clone(manifest, &manifest_out);
- fake_module_resolver_->SetManifest(std::move(manifest_out));
-
- fuchsia::modular::FindModulesResult res;
- res.module_id = "mod_url";
- res.manifest = std::move(manifest);
- fake_module_resolver_->AddFindModulesResult(std::move(res));
- }
-
- done = false;
- runner_->Execute(story_id_, story_storage_.get(), std::move(command2),
- [&](fuchsia::modular::ExecuteResult result) {
- ASSERT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- done = false;
- // Verify we updated an existing link.
- story_storage_->GetLinkValue(link_path)->Then(
- [&](StoryStorage::Status status, fidl::StringPtr v) {
- EXPECT_EQ(R"({"@type": "baz"})", *v);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/command_runner.cc b/bin/sessionmgr/puppet_master/command_runners/command_runner.cc
deleted file mode 100644
index a525f3a..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/command_runner.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/command_runner.h"
-
-namespace modular {
-
-CommandRunner::CommandRunner() {}
-
-CommandRunner::~CommandRunner() = default;
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/command_runner.h b/bin/sessionmgr/puppet_master/command_runners/command_runner.h
deleted file mode 100644
index 6d300c1..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/command_runner.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_COMMAND_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_COMMAND_RUNNER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-
-namespace modular {
-
-class CommandRunner {
- public:
- CommandRunner();
- virtual ~CommandRunner();
-
- virtual void Execute(
- fidl::StringPtr story_id, StoryStorage* story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) = 0;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_COMMAND_RUNNER_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.cc b/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.cc
deleted file mode 100644
index b91b0e8..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.h"
-
-namespace modular {
-
-FocusModCommandRunner::FocusModCommandRunner(
- fit::function<void(std::string, std::vector<std::string>)>
- module_focuser)
- : module_focuser_(std::move(module_focuser)) {}
-
-FocusModCommandRunner::~FocusModCommandRunner() = default;
-
-void FocusModCommandRunner::Execute(
- fidl::StringPtr story_id, StoryStorage* const story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- fuchsia::modular::ExecuteResult result;
-
- if (command.focus_mod().mod_name.empty()) {
- result.status = fuchsia::modular::ExecuteStatus::INVALID_COMMAND;
- result.error_message = "No mod_name provided.";
- done(std::move(result));
- return;
- }
-
- module_focuser_(story_id, std::move(command.focus_mod().mod_name));
-
- result.status = fuchsia::modular::ExecuteStatus::OK;
- done(std::move(result));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.h b/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.h
deleted file mode 100644
index 812e3ab..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_FOCUS_MOD_COMMAND_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_FOCUS_MOD_COMMAND_RUNNER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/command_runner.h"
-
-namespace modular {
-
-class FocusModCommandRunner : public CommandRunner {
- public:
- FocusModCommandRunner(
- fit::function<void(std::string, std::vector<std::string>)>
- module_focuser);
- ~FocusModCommandRunner();
-
- void Execute(
- fidl::StringPtr story_id, StoryStorage* story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override;
-
- private:
- fit::function<void(std::string, std::vector<std::string>)>
- module_focuser_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_FOCUS_MOD_COMMAND_RUNNER_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner_unittest.cc b/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner_unittest.cc
deleted file mode 100644
index 761c8ec..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner_unittest.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.h"
-
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class FocusModCommandRunnerTest : public gtest::TestLoopFixture {
- public:
- void SetUp() override {
- focused_called_ = false;
- runner_ = std::make_unique<FocusModCommandRunner>(
- [&](std::string story_id,
- std::vector<std::string> mod_name) {
- focused_called_ = true;
- });
- }
-
- bool focused_called_{};
- std::unique_ptr<FocusModCommandRunner> runner_;
-};
-
-TEST_F(FocusModCommandRunnerTest, Focus) {
- fuchsia::modular::FocusMod focus_mod;
- focus_mod.mod_name.push_back("mod");
- fuchsia::modular::StoryCommand command;
- command.set_focus_mod(std::move(focus_mod));
-
- fuchsia::modular::ExecuteResult result;
- runner_->Execute("story1", nullptr /* story_storage */, std::move(command),
- [&](fuchsia::modular::ExecuteResult execute_result) {
- result = std::move(execute_result);
- });
-
- RunLoopUntilIdle();
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK, result.status);
- EXPECT_TRUE(focused_called_);
-}
-
-TEST_F(FocusModCommandRunnerTest, FocusEmptyPath) {
- fuchsia::modular::FocusMod focus_mod;
- focus_mod.mod_name.resize(0);
- fuchsia::modular::StoryCommand command;
- command.set_focus_mod(std::move(focus_mod));
-
- fuchsia::modular::ExecuteResult result;
- runner_->Execute("story1", nullptr /* story_storage */, std::move(command),
- [&](fuchsia::modular::ExecuteResult execute_result) {
- result = std::move(execute_result);
- });
-
- RunLoopUntilIdle();
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND, result.status);
- EXPECT_EQ("No mod_name provided.", result.error_message);
- EXPECT_FALSE(focused_called_);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/BUILD.gn b/bin/sessionmgr/puppet_master/command_runners/operation_calls/BUILD.gn
deleted file mode 100644
index 3ed9d1c..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/BUILD.gn
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("operation_calls") {
- public_deps = [
- ":add_mod_call",
- ":find_modules_call",
- ":get_link_path_for_parameter_name_call",
- ":get_types_from_entity_call",
- ":initialize_chain_call",
- ]
-}
-
-source_set("add_mod_call") {
- sources = [
- "add_mod_call.cc",
- "add_mod_call.h",
- ]
-
- deps = [
- ":find_modules_call",
- ":get_link_path_for_parameter_name_call",
- ":get_types_from_entity_call",
- ":initialize_chain_call",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/module_manifest:module_facet_reader",
- "//peridot/public/lib/entity/cpp:json",
- ]
-
- public_deps = [
- "//peridot/bin/sessionmgr/storage:story_storage",
- "//peridot/lib/fidl:clone",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-source_set("find_modules_call") {
- sources = [
- "find_modules_call.cc",
- "find_modules_call.h",
- ]
-
- deps = [
- ":get_link_path_for_parameter_name_call",
- ":get_types_from_entity_call",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr/storage:story_storage",
- "//peridot/lib/fidl:clone",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- "//peridot/public/lib/entity/cpp:json",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular",
- ]
-}
-
-source_set("get_link_path_for_parameter_name_call") {
- sources = [
- "get_link_path_for_parameter_name_call.cc",
- "get_link_path_for_parameter_name_call.h",
- ]
-
- deps = [
- "//peridot/bin/sessionmgr/storage:story_storage",
- "//peridot/lib/fidl:clone",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-source_set("initialize_chain_call") {
- sources = [
- "initialize_chain_call.cc",
- "initialize_chain_call.h",
- ]
-
- deps = [
- ":set_link_value_call",
- "//peridot/bin/sessionmgr/storage:story_storage",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-source_set("get_types_from_entity_call") {
- sources = [
- "get_types_from_entity_call.cc",
- "get_types_from_entity_call.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-source_set("set_link_value_call") {
- sources = [
- "set_link_value_call.cc",
- "set_link_value_call.h",
- ]
-
- deps = [
- "//peridot/bin/sessionmgr/storage:story_storage",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.cc b/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.cc
deleted file mode 100644
index 3afea2f..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.cc
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h"
-
-#include <lib/entity/cpp/json.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h"
-#include "peridot/lib/fidl/clone.h"
-
-namespace modular {
-
-namespace {
-
-class AddModCall : public Operation<fuchsia::modular::ExecuteResult,
- fuchsia::modular::ModuleData> {
- public:
- AddModCall(StoryStorage* const story_storage,
- fuchsia::modular::ModuleResolver* const module_resolver,
- fuchsia::modular::EntityResolver* const entity_resolver,
- AddModParams add_mod_params, ResultCall done)
- : Operation("AddModCommandRunner::AddModCall", std::move(done)),
- story_storage_(story_storage),
- module_resolver_(module_resolver),
- entity_resolver_(entity_resolver),
- add_mod_params_(std::move(add_mod_params)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &out_result_, &out_module_data_};
-
- // Success status by default, it will be update it if an error state is
- // found.
- out_result_.status = fuchsia::modular::ExecuteStatus::OK;
-
- // If we have an action, we use the module resolver to type-check and
- // resolve the (action, parameter) and the supplied optional handler to a
- // module. If the module resolver doesn't recognize a supplied handler, we
- // forgivingly execute the handler anyway.
- if (!add_mod_params_.intent.action.is_null()) {
- AddFindModulesOperation(
- &operation_queue_, module_resolver_, entity_resolver_,
- CloneOptional(add_mod_params_.intent),
- add_mod_params_.parent_mod_path,
- [this, flow](fuchsia::modular::ExecuteResult result,
- fuchsia::modular::FindModulesResponse response) {
- if (result.status != fuchsia::modular::ExecuteStatus::OK) {
- out_result_ = std::move(result);
- return;
- // Operation finishes since |flow| goes out of scope.
- }
-
- // NOTE: leave this as a switch case and omit the default case; the
- // compiler will make sure we're handling all error cases.
- switch (response.status) {
- case fuchsia::modular::FindModulesStatus::SUCCESS: {
- if (response.results.empty()) {
- out_result_.status =
- fuchsia::modular::ExecuteStatus::NO_MODULES_FOUND;
- out_result_.error_message =
- "Resolution of intent gave zero results.";
- return;
- // Operation finishes since |flow| goes out of scope.
- }
-
- candidate_module_ = std::move(response.results.at(0));
- } break;
-
- case fuchsia::modular::FindModulesStatus::UNKNOWN_HANDLER: {
- candidate_module_.module_id = add_mod_params_.intent.handler;
- } break;
- }
-
- CreateLinks(flow);
- });
- } else {
- // We arrive here if the Intent has a handler, but no action.
- FXL_DCHECK(!add_mod_params_.intent.handler.is_null())
- << "Cannot start a module without an action or a handler";
- candidate_module_.module_id = add_mod_params_.intent.handler;
-
- CreateLinks(flow);
- }
- }
-
- // Create module parameters info and create links.
- void CreateLinks(FlowToken flow) {
- CreateModuleParameterMapInfo(flow, [this, flow] {
- if (out_result_.status != fuchsia::modular::ExecuteStatus::OK) {
- return;
- // Operation finishes since |flow| goes out of scope.
- }
- auto full_module_path = add_mod_params_.parent_mod_path;
- full_module_path.push_back(add_mod_params_.mod_name);
- AddInitializeChainOperation(
- &operation_queue_, story_storage_, std::move(full_module_path),
- std::move(parameter_info_),
- [this, flow](fuchsia::modular::ExecuteResult result,
- fuchsia::modular::ModuleParameterMapPtr map) {
- if (result.status != fuchsia::modular::ExecuteStatus::OK) {
- out_result_ = std::move(result);
- return;
- // Operation finishes since |flow| goes out of scope.
- }
- WriteModuleData(flow, std::move(map));
- });
- });
- }
-
- // On success, populates |parameter_info_|. On failure, |out_result_| contains
- // error reason. Calls |done()| on completion in either case.
- void CreateModuleParameterMapInfo(FlowToken flow,
- std::function<void()> done) {
- parameter_info_ = fuchsia::modular::CreateModuleParameterMapInfo::New();
-
- std::vector<FuturePtr<fuchsia::modular::CreateModuleParameterMapEntry>>
- did_get_entries;
- did_get_entries.reserve(add_mod_params_.intent.parameters->size());
-
- for (auto& param : *add_mod_params_.intent.parameters) {
- fuchsia::modular::CreateModuleParameterMapEntry entry;
- entry.key = param.name;
-
- switch (param.data.Which()) {
- case fuchsia::modular::IntentParameterData::Tag::kEntityReference: {
- fuchsia::modular::CreateLinkInfo create_link;
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(
- EntityReferenceToJson(param.data.entity_reference()), &vmo));
- create_link.initial_data = std::move(vmo).ToTransport();
- entry.value.set_create_link(std::move(create_link));
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::kEntityType: {
- // Create a link, but don't populate it. This is useful in the event
- // that the link is used as an 'output' link. Setting a valid JSON
- // value for null in the vmo.
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString("null", &vmo));
- fuchsia::modular::CreateLinkInfo create_link;
- create_link.initial_data = std::move(vmo).ToTransport();
- entry.value.set_create_link(std::move(create_link));
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::kJson: {
- fuchsia::modular::CreateLinkInfo create_link;
- param.data.json().Clone(&create_link.initial_data);
- entry.value.set_create_link(std::move(create_link));
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::Invalid: {
- out_result_.status = fuchsia::modular::ExecuteStatus::INVALID_COMMAND;
- out_result_.error_message =
- fxl::StringPrintf("Invalid data for parameter with name: %s",
- param.name.get().c_str());
- done();
- return;
- }
- }
-
- auto did_create_entry =
- Future<fuchsia::modular::CreateModuleParameterMapEntry>::
- CreateCompleted(
- "AddModCommandRunner::FindModulesCall.did_create_entry",
- std::move(entry));
- did_get_entries.emplace_back(std::move(did_create_entry));
- }
-
- Wait("AddModCommandRunner::AddModCall::Wait", did_get_entries)
- ->Then([this, done, flow](
- std::vector<fuchsia::modular::CreateModuleParameterMapEntry>
- entries) {
- parameter_info_->property_info.reset(std::move(entries));
- done();
- });
- }
-
- // Write module data
- void WriteModuleData(FlowToken flow,
- fuchsia::modular::ModuleParameterMapPtr map) {
- fidl::Clone(*map, &out_module_data_.parameter_map);
- out_module_data_.module_url = candidate_module_.module_id;
- out_module_data_.module_path = add_mod_params_.parent_mod_path;
- out_module_data_.module_path.push_back(add_mod_params_.mod_name);
- out_module_data_.module_source = add_mod_params_.module_source;
- out_module_data_.module_deleted = false;
- fidl::Clone(add_mod_params_.surface_relation,
- &out_module_data_.surface_relation);
- out_module_data_.is_embedded = add_mod_params_.is_embedded;
- out_module_data_.intent = std::make_unique<fuchsia::modular::Intent>(
- std::move(add_mod_params_.intent));
-
- // Operation stays alive until flow goes out of scope.
- fuchsia::modular::ModuleData module_data;
- out_module_data_.Clone(&module_data);
- story_storage_->WriteModuleData(std::move(module_data))->Then([this, flow] {
- });
- }
-
- StoryStorage* const story_storage_; // Not owned.
- fuchsia::modular::ModuleResolver* const module_resolver_; // Not owned.
- fuchsia::modular::EntityResolver* const entity_resolver_; // Not owned.
- modular::AddModParams add_mod_params_;
- fuchsia::modular::FindModulesResult candidate_module_;
- fuchsia::modular::CreateModuleParameterMapInfoPtr parameter_info_;
- fuchsia::modular::ModuleData out_module_data_;
- fuchsia::modular::ExecuteResult out_result_;
- // Used when creating the map info to execute an operation as soon as it
- // arrives.
- OperationCollection operations_;
- // Used to enqueue sub-operations that should be executed sequentially.
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AddModCall);
-}; // namespace
-
-} // namespace
-
-void AddAddModOperation(OperationContainer* const container,
- StoryStorage* const story_storage,
- fuchsia::modular::ModuleResolver* const module_resolver,
- fuchsia::modular::EntityResolver* const entity_resolver,
- AddModParams add_mod_params,
- std::function<void(fuchsia::modular::ExecuteResult,
- fuchsia::modular::ModuleData)>
- done) {
- container->Add(new AddModCall(story_storage, module_resolver, entity_resolver,
- std::move(add_mod_params), std::move(done)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h b/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h
deleted file mode 100644
index 752c35e..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_ADD_MOD_CALL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_ADD_MOD_CALL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-
-namespace modular {
-
-// This struct contains common parameters needed to add a module to a story,
-// useful as a single place to add more parameters that need shuffling around.
-// See story_command.fidl and module_data.fidl for a detailed description of
-// what these parameters mean.
-struct AddModParams {
- // This parent module's module path. If empty, this mod has no parent module.
- std::vector<std::string> parent_mod_path;
- // Module name given to this module path (parent_mod_path + mod_name is this
- // module's module path).
- std::string mod_name;
-
- // True if this is an embedded mod (as opposed to being arranged by the story
- // shell), in which case this mod's view will be embedded by its parent mod
- // (represented by parent_mod_path).
- bool is_embedded;
-
- // See |fuchsia::modular::ModuleData| (module_data.fidl) for a detailed
- // description of what these parameters mean.
- fuchsia::modular::Intent intent;
- fuchsia::modular::SurfaceRelationPtr surface_relation;
- fuchsia::modular::ModuleSource module_source;
-};
-
-void AddAddModOperation(OperationContainer* container,
- StoryStorage* story_storage,
- fuchsia::modular::ModuleResolver* module_resolver,
- fuchsia::modular::EntityResolver* entity_resolver,
- AddModParams add_mod_params,
- std::function<void(fuchsia::modular::ExecuteResult,
- fuchsia::modular::ModuleData)>
- done);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_ADD_MOD_CALL_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.cc b/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.cc
deleted file mode 100644
index 53c24f3..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.h"
-
-#include <lib/entity/cpp/json.h>
-#include <lib/fostr/fidl/fuchsia/modular/formatting.h>
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/type_converter.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.h"
-#include "peridot/lib/fidl/clone.h"
-
-namespace modular {
-
-namespace {
-
-class FindModulesCall
- : public Operation<fuchsia::modular::ExecuteResult,
- fuchsia::modular::FindModulesResponse> {
- public:
- FindModulesCall(fuchsia::modular::ModuleResolver* const module_resolver,
- fuchsia::modular::EntityResolver* const entity_resolver,
- fuchsia::modular::IntentPtr intent,
- std::vector<std::string> requesting_module_path,
- ResultCall result_call)
- : Operation("FindModulesCall", std::move(result_call)),
- module_resolver_(module_resolver),
- entity_resolver_(entity_resolver),
- intent_(std::move(intent)),
- requesting_module_path_(std::move(requesting_module_path)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &result_, &response_};
- // Default status. We'll update it and return if an error occurs.
- result_.status = fuchsia::modular::ExecuteStatus::OK;
-
- FXL_DCHECK(intent_->action) << intent_;
-
- constraint_futs_.reserve(intent_->parameters->size());
-
- resolver_query_.action = intent_->action;
- resolver_query_.handler = intent_->handler;
- resolver_query_.parameter_constraints.resize(0);
-
- for (auto& param : *intent_->parameters) {
- // TODO(MF-23): Deprecate parameter name nullability altogether.
- if (param.name.is_null() && intent_->handler.is_null()) {
- result_.error_message =
- "A null-named module parameter is not allowed "
- "when using fuchsia::modular::Intent.";
- result_.status = fuchsia::modular::ExecuteStatus::INVALID_COMMAND;
- return;
- // Operation finishes since |flow| goes out of scope.
- }
-
- // Skip processing null intent parameter names (these are generally
- // root/null link names).
- if (param.name.is_null()) {
- param.name = "";
- }
-
- constraint_futs_.push_back(
- GetTypesFromIntentParameter(std::move(param.data), param.name)
- ->Map([this, name = param.name](std::vector<std::string> types) {
- fuchsia::modular::FindModulesParameterConstraint constraint;
- constraint.param_name = name;
- constraint.param_types = std::move(types);
- return constraint;
- }));
- }
-
- Wait("FindModulesCall.Run.Wait", constraint_futs_)
- ->Then([this, flow](
- std::vector<fuchsia::modular::FindModulesParameterConstraint>
- constraint_params) {
- if (result_.status != fuchsia::modular::ExecuteStatus::OK) {
- // Operation finishes since |flow| goes out of scope.
- return;
- }
- resolver_query_.parameter_constraints = std::move(constraint_params);
- module_resolver_->FindModules(
- std::move(resolver_query_),
- [this, flow](fuchsia::modular::FindModulesResponse response) {
- response_ = std::move(response);
- // At this point, the only remaining |flow| is the one captured
- // in this lambda. This operation should end once |flow| goes
- // out of scope here.
- });
- });
- }
-
- // To avoid deadlocks, this function must not depend on anything that executes
- // on the story controller's operation queue.
- FuturePtr<std::vector<std::string>> GetTypesFromIntentParameter(
- fuchsia::modular::IntentParameterData input,
- const fidl::StringPtr& param_name) {
- auto fut = Future<std::vector<std::string>>::Create(
- "AddModCommandRunner::GetTypesFromIntentParameter");
- switch (input.Which()) {
- case fuchsia::modular::IntentParameterData::Tag::kEntityReference: {
- AddGetTypesFromEntityOperation(&operations_, entity_resolver_,
- input.entity_reference(),
- fut->Completer());
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::kEntityType: {
- fut->Complete(fxl::To<std::vector<std::string>>(input.entity_type()));
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::kJson: {
- std::string json_string;
- FXL_CHECK(fsl::StringFromVmo(input.json(), &json_string));
- if (auto result = GetTypesFromJson(json_string)) {
- fut->Complete(std::move(*result));
- } else {
- std::ostringstream stream;
- stream << "Mal-formed JSON in parameter: " << param_name;
- result_.error_message = stream.str();
- result_.status = fuchsia::modular::ExecuteStatus::INVALID_COMMAND;
- fut->Complete({});
- }
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::Invalid: {
- std::ostringstream stream;
- stream << "Invalid data for parameter with name: " << param_name;
- result_.error_message = stream.str();
- result_.status = fuchsia::modular::ExecuteStatus::INVALID_COMMAND;
- fut->Complete({});
- break;
- }
- }
- return fut;
- }
-
- std::optional<std::vector<std::string>> GetTypesFromJson(
- const fidl::StringPtr& input) {
- std::vector<std::string> types;
- if (ExtractEntityTypesFromJson(input, &types)) {
- return types;
- }
- return std::nullopt;
- }
-
- fuchsia::modular::ModuleResolver* const module_resolver_; // Not Owned
- fuchsia::modular::EntityResolver* const entity_resolver_; // Not owned.
- const fuchsia::modular::IntentPtr intent_;
- const std::vector<std::string> requesting_module_path_;
-
- fuchsia::modular::FindModulesQuery resolver_query_;
- std::vector<FuturePtr<fuchsia::modular::FindModulesParameterConstraint>>
- constraint_futs_;
- fuchsia::modular::ExecuteResult result_;
- fuchsia::modular::FindModulesResponse response_;
- OperationCollection operations_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FindModulesCall);
-};
-
-} // namespace
-
-void AddFindModulesOperation(
- OperationContainer* operation_container,
- fuchsia::modular::ModuleResolver* const module_resolver,
- fuchsia::modular::EntityResolver* const entity_resolver,
- fuchsia::modular::IntentPtr intent,
- std::vector<std::string> requesting_module_path,
- std::function<void(fuchsia::modular::ExecuteResult,
- fuchsia::modular::FindModulesResponse)>
- result_call) {
- operation_container->Add(new FindModulesCall(
- module_resolver, entity_resolver, std::move(intent),
- std::move(requesting_module_path), std::move(result_call)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.h b/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.h
deleted file mode 100644
index dcd34af..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_FIND_MODULES_CALL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_FIND_MODULES_CALL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-namespace modular {
-
-void AddFindModulesOperation(
- OperationContainer* operation_container,
- fuchsia::modular::ModuleResolver* module_resolver,
- fuchsia::modular::EntityResolver* entity_resolver,
- fuchsia::modular::IntentPtr intent,
- std::vector<std::string> requesting_module_path,
- std::function<void(fuchsia::modular::ExecuteResult,
- fuchsia::modular::FindModulesResponse)>
- result_call);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_FIND_MODULES_CALL_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.cc b/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.cc
deleted file mode 100644
index fc57d28..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.h"
-
-#include "peridot/lib/fidl/clone.h"
-
-namespace modular {
-
-namespace {
-
-class GetLinkPathForParameterNameCall
- : public Operation<fuchsia::modular::LinkPathPtr> {
- public:
- GetLinkPathForParameterNameCall(StoryStorage* const story_storage,
- std::vector<std::string> module_name,
- std::string link_name,
- ResultCall result_call)
- : Operation("AddModCommandRunner::GetLinkPathForParameterNameCall",
- std::move(result_call)),
- story_storage_(story_storage),
- module_name_(std::move(module_name)),
- link_name_(std::move(link_name)),
- link_path_(nullptr) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &link_path_};
- story_storage_->ReadModuleData(module_name_)
- ->Then([this, flow](fuchsia::modular::ModuleDataPtr module_data) {
- if (!module_data) {
- return;
- }
- auto& param_map = module_data->parameter_map;
- auto it = std::find_if(
- param_map.entries.begin(), param_map.entries.end(),
- [this](const fuchsia::modular::ModuleParameterMapEntry& entry) {
- return entry.name == link_name_;
- });
- if (it != param_map.entries.end()) {
- link_path_ = CloneOptional(it->link_path);
- }
-
- if (!link_path_) {
- link_path_ = fuchsia::modular::LinkPath::New();
- link_path_->module_path = module_name_;
- link_path_->link_name = link_name_;
- }
- // Flow goes out of scope, finish operation returning link_path.
- });
- }
-
- StoryStorage* const story_storage_; // Not owned.
- std::vector<std::string> module_name_;
- std::string link_name_;
- fuchsia::modular::LinkPathPtr link_path_;
-};
-
-} // namespace
-
-void AddGetLinkPathForParameterNameOperation(
- OperationContainer* const operation_container,
- StoryStorage* const story_storage,
- std::vector<std::string> module_name, std::string link_name,
- std::function<void(fuchsia::modular::LinkPathPtr)> result_call) {
- operation_container->Add(new GetLinkPathForParameterNameCall(
- story_storage, std::move(module_name), std::move(link_name),
- std::move(result_call)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.h b/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.h
deleted file mode 100644
index cbe901f..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_GET_LINK_PATH_FOR_PARAMETER_NAME_CALL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_GET_LINK_PATH_FOR_PARAMETER_NAME_CALL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-
-namespace modular {
-
-void AddGetLinkPathForParameterNameOperation(
- OperationContainer* operation_container, StoryStorage* const story_storage,
- std::vector<std::string> module_name, std::string link_name,
- std::function<void(fuchsia::modular::LinkPathPtr)> result_call);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_GET_LINK_PATH_FOR_PARAMETER_NAME_CALL_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.cc b/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.cc
deleted file mode 100644
index 7bf4020..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.h"
-
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fxl/type_converter.h>
-
-namespace modular {
-
-namespace {
-
-class GetTypesFromEntityCall : public Operation<std::vector<std::string>> {
- public:
- GetTypesFromEntityCall(
- fuchsia::modular::EntityResolver* const entity_resolver,
- const fidl::StringPtr& entity_reference, ResultCall result)
- : Operation("GetTypesFromEntityCall", std::move(result)),
- entity_resolver_(entity_resolver),
- entity_reference_(entity_reference) {}
-
- private:
- void Run() override {
- entity_resolver_->ResolveEntity(entity_reference_, entity_.NewRequest());
- entity_->GetTypes([this](const std::vector<std::string>& types) {
- Done(types);
- });
- }
-
- fuchsia::modular::EntityResolver* const entity_resolver_;
- fidl::StringPtr const entity_reference_;
- fuchsia::modular::EntityPtr entity_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(GetTypesFromEntityCall);
-};
-
-} // namespace
-
-void AddGetTypesFromEntityOperation(
- OperationContainer* const operation_container,
- fuchsia::modular::EntityResolver* const entity_resolver,
- const fidl::StringPtr& entity_reference,
- std::function<void(std::vector<std::string>)> result_call) {
- operation_container->Add(new GetTypesFromEntityCall(
- entity_resolver, entity_reference, std::move(result_call)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.h b/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.h
deleted file mode 100644
index 877da92..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_GET_TYPES_FROM_ENTITY_CALL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_GET_TYPES_FROM_ENTITY_CALL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-namespace modular {
-
-void AddGetTypesFromEntityOperation(
- OperationContainer* operation_container,
- fuchsia::modular::EntityResolver* entity_resolver,
- const fidl::StringPtr& entity_reference,
- std::function<void(std::vector<std::string>)> result_call);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_GET_TYPES_FROM_ENTITY_CALL_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.cc b/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.cc
deleted file mode 100644
index 0fd3d38..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.h"
-
-#include <lib/fsl/vmo/strings.h>
-
-namespace modular {
-
-namespace {
-
-// Populates a fuchsia::modular::ModuleParameterMap struct from a
-// fuchsia::modular::CreateModuleParameterMapInfo struct. May create new Links
-// for any fuchsia::modular::CreateModuleParameterMapInfo.property_info if
-// property_info[i].is_create_link_info().
-class InitializeChainCall
- : public Operation<fuchsia::modular::ExecuteResult,
- fuchsia::modular::ModuleParameterMapPtr> {
- public:
- InitializeChainCall(StoryStorage* const story_storage,
- std::vector<std::string> module_path,
- fuchsia::modular::CreateModuleParameterMapInfoPtr
- create_parameter_map_info,
- ResultCall result_call)
- : Operation("InitializeChainCall", std::move(result_call)),
- story_storage_(story_storage),
- module_path_(std::move(module_path)),
- create_parameter_map_info_(std::move(create_parameter_map_info)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &result_, ¶meter_map_};
-
- parameter_map_ = fuchsia::modular::ModuleParameterMap::New();
- parameter_map_->entries.resize(0);
-
- if (!create_parameter_map_info_) {
- return;
- }
-
- // For each property in |create_parameter_map_info_|, either:
- // a) Copy the |link_path| to |result_| directly or
- // b) Create & populate a new Link and add the correct mapping to
- // |result_|.
- for (auto& entry : *create_parameter_map_info_->property_info) {
- const auto& key = entry.key;
- const auto& info = entry.value;
-
- auto mapping = fuchsia::modular::ModuleParameterMapEntry::New();
- mapping->name = key;
- if (info.is_link_path()) {
- info.link_path().Clone(&mapping->link_path);
- } else { // info->is_create_link()
- mapping->link_path.module_path.resize(0);
- for (const auto& i : module_path_) {
- mapping->link_path.module_path.push_back(i);
- }
- mapping->link_path.link_name = key;
-
- // We issue N UpdateLinkValue calls and capture |flow| on each. We rely
- // on the fact that once all refcounted instances of |flow| are
- // destroyed, the InitializeChainCall will automatically finish.
- std::string initial_json;
- if (info.create_link().initial_data.size > 0) {
- FXL_CHECK(fsl::StringFromVmo(info.create_link().initial_data,
- &initial_json));
- }
- fuchsia::modular::LinkPath out_path;
- mapping->link_path.Clone(&out_path);
- AddSetLinkValueOperation(
- &operations_, story_storage_, std::move(out_path),
- [initial_json](fidl::StringPtr* value) { *value = initial_json; },
- [this, flow](fuchsia::modular::ExecuteResult result) {
- if (result.status != fuchsia::modular::ExecuteStatus::OK) {
- result_ = std::move(result);
- }
- });
- }
-
- parameter_map_->entries.push_back(std::move(*mapping));
- }
- }
-
- StoryStorage* const story_storage_;
- const std::vector<std::string> module_path_;
- const fuchsia::modular::CreateModuleParameterMapInfoPtr
- create_parameter_map_info_;
- fuchsia::modular::ModuleParameterMapPtr parameter_map_;
- fuchsia::modular::ExecuteResult result_;
- OperationCollection operations_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(InitializeChainCall);
-};
-
-} // namespace
-
-void AddInitializeChainOperation(
- OperationContainer* const operation_container,
- StoryStorage* const story_storage,
- std::vector<std::string> module_path,
- fuchsia::modular::CreateModuleParameterMapInfoPtr create_parameter_map_info,
- std::function<void(fuchsia::modular::ExecuteResult,
- fuchsia::modular::ModuleParameterMapPtr)>
- result_call) {
- operation_container->Add(new InitializeChainCall(
- story_storage, std::move(module_path),
- std::move(create_parameter_map_info), std::move(result_call)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h b/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h
deleted file mode 100644
index 9977376..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_INITIALIZE_CHAIN_CALL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_INITIALIZE_CHAIN_CALL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-
-namespace modular {
-
-void AddInitializeChainOperation(
- OperationContainer* operation_container, StoryStorage* story_storage,
- std::vector<std::string> module_path,
- fuchsia::modular::CreateModuleParameterMapInfoPtr create_parameter_map_info,
- std::function<void(fuchsia::modular::ExecuteResult,
- fuchsia::modular::ModuleParameterMapPtr)>
- result_call);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_INITIALIZE_CHAIN_CALL_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.cc b/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.cc
deleted file mode 100644
index 6b55dd7..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.h"
-
-namespace modular {
-
-namespace {
-
-class SetLinkValueCall : public Operation<fuchsia::modular::ExecuteResult> {
- public:
- SetLinkValueCall(StoryStorage* const story_storage,
- fuchsia::modular::LinkPath link_path,
- std::function<void(fidl::StringPtr*)> mutate_fn,
- ResultCall done)
- : Operation("SetLinkValueCall", std::move(done)),
- story_storage_(story_storage),
- link_path_(std::move(link_path)),
- mutate_fn_(std::move(mutate_fn)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &result_};
- auto did_update = story_storage_->UpdateLinkValue(link_path_, mutate_fn_,
- this /* context */);
- did_update->Then([this, flow](StoryStorage::Status status) {
- if (status == StoryStorage::Status::OK) {
- result_.status = fuchsia::modular::ExecuteStatus::OK;
- } else {
- result_.status = fuchsia::modular::ExecuteStatus::INTERNAL_ERROR;
- std::stringstream stream;
- stream << "StoryStorage error status: " << (uint32_t)status;
- result_.error_message = stream.str();
- }
- });
- }
-
- fidl::StringPtr story_id_;
- StoryStorage* const story_storage_;
- fuchsia::modular::LinkPath link_path_;
- std::function<void(fidl::StringPtr*)> mutate_fn_;
- fuchsia::modular::ExecuteResult result_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SetLinkValueCall);
-};
-
-} // namespace
-
-void AddSetLinkValueOperation(
- OperationContainer* const operation_container,
- StoryStorage* const story_storage, fuchsia::modular::LinkPath link_path,
- std::function<void(fidl::StringPtr*)> mutate_fn,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- operation_container->Add(
- new SetLinkValueCall(story_storage, std::move(link_path),
- std::move(mutate_fn), std::move(done)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.h b/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.h
deleted file mode 100644
index a20d666..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_SET_LINK_VALUE_CALL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_SET_LINK_VALUE_CALL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-
-namespace modular {
-
-void AddSetLinkValueOperation(
- OperationContainer* const operation_container,
- StoryStorage* const story_storage, fuchsia::modular::LinkPath link_path,
- std::function<void(fidl::StringPtr*)> mutate_fn,
- std::function<void(fuchsia::modular::ExecuteResult)> done);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_OPERATION_CALLS_SET_LINK_VALUE_CALL_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.cc b/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.cc
deleted file mode 100644
index 23f049f..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.h"
-
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-namespace {
-
-class RemoveModCall : public Operation<fuchsia::modular::ExecuteResult> {
- public:
- RemoveModCall(StoryStorage* const story_storage, fidl::StringPtr story_id,
- fuchsia::modular::RemoveMod command, ResultCall done)
- : Operation("RemoveModCommandRunner::RemoveModCall", std::move(done)),
- story_storage_(story_storage),
- story_id_(std::move(story_id)),
- command_(std::move(command)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &result_};
- // Set the module data stopped to true, this should notify story
- // controller and perform module teardown.
- story_storage_
- ->UpdateModuleData(
- command_.mod_name,
- [this, flow](fuchsia::modular::ModuleDataPtr* module_data) {
- if (!(*module_data)) {
- result_.status = fuchsia::modular::ExecuteStatus::INVALID_MOD;
- result_.error_message = "No module data for given name.";
- return;
- }
- (*module_data)->module_deleted = true;
- result_.status = fuchsia::modular::ExecuteStatus::OK;
- })
- ->Then([this, flow] {});
- }
-
- StoryStorage* const story_storage_;
- fidl::StringPtr story_id_;
- fuchsia::modular::RemoveMod command_;
- fuchsia::modular::ExecuteResult result_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(RemoveModCall);
-};
-
-} // namespace
-
-RemoveModCommandRunner::RemoveModCommandRunner() = default;
-RemoveModCommandRunner::~RemoveModCommandRunner() = default;
-
-void RemoveModCommandRunner::Execute(
- fidl::StringPtr story_id, StoryStorage* const story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- FXL_CHECK(command.is_remove_mod());
-
- operation_queue_.Add(new RemoveModCall(story_storage, std::move(story_id),
- std::move(command.remove_mod()),
- std::move(done)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.h b/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.h
deleted file mode 100644
index 99cbcb9..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_REMOVE_MOD_COMMAND_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_REMOVE_MOD_COMMAND_RUNNER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/command_runner.h"
-
-namespace modular {
-
-class RemoveModCommandRunner : public CommandRunner {
- public:
- RemoveModCommandRunner();
- ~RemoveModCommandRunner() override;
-
- void Execute(
- fidl::StringPtr story_id, StoryStorage* story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override;
-
- private:
- OperationQueue operation_queue_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_REMOVE_MOD_COMMAND_RUNNER_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner_unittest.cc b/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner_unittest.cc
deleted file mode 100644
index 302356e..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner_unittest.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.h"
-
-#include "gtest/gtest.h"
-#include "peridot/lib/testing/test_with_session_storage.h"
-
-namespace modular {
-namespace {
-
-class RemoveModCommandRunnerTest : public testing::TestWithSessionStorage {
- protected:
- std::unique_ptr<RemoveModCommandRunner> MakeRunner() {
- return std::make_unique<RemoveModCommandRunner>();
- }
-
- std::vector<std::string> MakeModulePath(std::string path) {
- std::vector<std::string> module_path;
- module_path.push_back(path);
- return module_path;
- }
-
- void InitModuleData(StoryStorage* const story_storage,
- std::vector<std::string> path) {
- fuchsia::modular::ModuleData module_data;
- module_data.module_path = std::move(path);
- module_data.intent = fuchsia::modular::Intent::New();
- module_data.module_deleted = false;
-
- WriteModuleData(story_storage, std::move(module_data));
- }
-};
-
-TEST_F(RemoveModCommandRunnerTest, Execute) {
- auto storage = MakeSessionStorage("page");
- auto runner = MakeRunner();
- auto story_id = CreateStory(storage.get());
- auto story_storage = GetStoryStorage(storage.get(), story_id);
-
- auto mod_name = MakeModulePath("mod");
- InitModuleData(story_storage.get(), mod_name);
-
- fuchsia::modular::RemoveMod remove_mod;
- remove_mod.mod_name = mod_name;
- fuchsia::modular::StoryCommand command;
- command.set_remove_mod(std::move(remove_mod));
-
- bool done{};
- runner->Execute(story_id, story_storage.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- done = false;
- story_storage->ReadModuleData(std::move(mod_name))
- ->Then([&](fuchsia::modular::ModuleDataPtr module_data) {
- EXPECT_TRUE(module_data->module_deleted);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(RemoveModCommandRunnerTest, ExecuteNoModuleData) {
- auto storage = MakeSessionStorage("page");
- auto runner = MakeRunner();
- auto story_id = CreateStory(storage.get());
- auto story_storage = GetStoryStorage(storage.get(), story_id);
-
- auto mod_name = MakeModulePath("mod");
- fuchsia::modular::RemoveMod remove_mod;
- remove_mod.mod_name = std::move(mod_name);
- fuchsia::modular::StoryCommand command;
- command.set_remove_mod(std::move(remove_mod));
-
- bool done{};
- runner->Execute(
- story_id, story_storage.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_MOD, result.status);
- EXPECT_EQ(result.error_message, "No module data for given name.");
- done = true;
- });
-
- RunLoopUntil([&] { return done; });
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.cc b/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.cc
deleted file mode 100644
index 71b7ed9..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.h"
-
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-SetFocusStateCommandRunner::SetFocusStateCommandRunner(
- fuchsia::modular::FocusProviderPtr focus_provider)
- : focus_provider_(std::move(focus_provider)) {}
-
-SetFocusStateCommandRunner::~SetFocusStateCommandRunner() = default;
-
-void SetFocusStateCommandRunner::Execute(
- fidl::StringPtr story_id, StoryStorage* const story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- FXL_CHECK(command.is_set_focus_state());
-
- fuchsia::modular::ExecuteResult result;
- result.status = fuchsia::modular::ExecuteStatus::OK;
-
- if (command.set_focus_state().focused) {
- focus_provider_->Request(story_id);
- } else {
- // According to FIDL docs a null |story_id| brings the timeline into
- // focus, defocusing any story.
- focus_provider_->Request(nullptr);
- }
-
- done(std::move(result));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.h b/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.h
deleted file mode 100644
index 512c0fb..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_FOCUS_STATE_COMMAND_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_FOCUS_STATE_COMMAND_RUNNER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/command_runner.h"
-
-namespace modular {
-
-class SetFocusStateCommandRunner : public CommandRunner {
- public:
- SetFocusStateCommandRunner(fuchsia::modular::FocusProviderPtr focus_provider);
- ~SetFocusStateCommandRunner() override;
-
- void Execute(
- fidl::StringPtr story_id, StoryStorage* story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override;
-
- private:
- fuchsia::modular::FocusProviderPtr focus_provider_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_FOCUS_STATE_COMMAND_RUNNER_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner_unittest.cc b/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner_unittest.cc
deleted file mode 100644
index ac3642b..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner_unittest.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.h"
-
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class FocusHandler : fuchsia::modular::FocusProvider {
- public:
- FocusHandler() {}
-
- void AddProviderBinding(
- fidl::InterfaceRequest<fuchsia::modular::FocusProvider> request) {
- provider_bindings_.AddBinding(this, std::move(request));
- };
-
- std::string request_called_with_story_id() {
- return request_called_with_story_id_;
- }
-
- // |fuchsia::modular::FocusProvider|
- void Request(fidl::StringPtr story_id) override {
- request_called_with_story_id_ = story_id;
- };
- void Query(QueryCallback callback) override{};
- void Watch(
- fidl::InterfaceHandle<fuchsia::modular::FocusWatcher> watcher) override{};
-
- private:
- std::string request_called_with_story_id_;
- fidl::BindingSet<fuchsia::modular::FocusProvider> provider_bindings_;
-};
-
-class SetFocusStateCommandRunnerTest : public gtest::TestLoopFixture {
- public:
- void SetUp() override {
- fidl::InterfacePtr<fuchsia::modular::FocusProvider> focus_provider;
- focus_handler_.AddProviderBinding(focus_provider.NewRequest());
- runner_ =
- std::make_unique<SetFocusStateCommandRunner>(std::move(focus_provider));
- }
-
- protected:
- FocusHandler focus_handler_;
- std::unique_ptr<SetFocusStateCommandRunner> runner_;
-};
-
-TEST_F(SetFocusStateCommandRunnerTest, Focus) {
- fuchsia::modular::SetFocusState set_focus_state;
- set_focus_state.focused = true;
- fuchsia::modular::StoryCommand command;
- command.set_set_focus_state(std::move(set_focus_state));
-
- runner_->Execute("story1", nullptr /* story_storage */, std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- });
-
- RunLoopUntilIdle();
- EXPECT_EQ("story1", focus_handler_.request_called_with_story_id());
-}
-
-TEST_F(SetFocusStateCommandRunnerTest, Unfocus) {
- fuchsia::modular::SetFocusState set_focus_state;
- set_focus_state.focused = false;
- fuchsia::modular::StoryCommand command;
- command.set_set_focus_state(std::move(set_focus_state));
-
- runner_->Execute(
- nullptr /* story_id */, nullptr /* story_storage */, std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK, result.status);
- });
-
- RunLoopUntilIdle();
- EXPECT_TRUE(focus_handler_.request_called_with_story_id().empty());
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.cc b/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.cc
deleted file mode 100644
index 72bdb44..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.h"
-
-namespace modular {
-
-class SetKindOfProtoStoryOptionCall
- : public Operation<fuchsia::modular::ExecuteResult> {
- public:
- SetKindOfProtoStoryOptionCall(SessionStorage* const session_storage,
- fidl::StringPtr story_id, bool value,
- ResultCall done)
- : Operation("SetKindOfProtoStoryOption::SetKindOfProtoStoryOptionCall",
- std::move(done)),
- session_storage_(session_storage),
- story_id_(story_id),
- value_(value) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &result_};
- result_.status = fuchsia::modular::ExecuteStatus::OK;
- session_storage_->GetStoryData(story_id_)->Then(
- [this, flow](fuchsia::modular::internal::StoryDataPtr data) {
- if (data->story_options.kind_of_proto_story == value_) {
- // Finish early since there's nothing to update.
- return;
- }
- data->story_options.Clone(&options_);
- UpdateOptions(flow);
- });
- }
-
- void UpdateOptions(FlowToken flow) {
- options_.kind_of_proto_story = value_;
- session_storage_->UpdateStoryOptions(story_id_, std::move(options_))
- ->Then([flow]() {}); // Operation finishes when flow goes out of scope.
- }
-
- SessionStorage* const session_storage_;
- fidl::StringPtr story_id_;
- bool value_;
- fuchsia::modular::StoryOptions options_;
- fuchsia::modular::ExecuteResult result_;
-};
-
-SetKindOfProtoStoryOptionCommandRunner::SetKindOfProtoStoryOptionCommandRunner(
- SessionStorage* const session_storage)
- : session_storage_(session_storage) {
- FXL_DCHECK(session_storage_);
-}
-
-SetKindOfProtoStoryOptionCommandRunner::
- ~SetKindOfProtoStoryOptionCommandRunner() = default;
-
-void SetKindOfProtoStoryOptionCommandRunner::Execute(
- fidl::StringPtr story_id, StoryStorage* const story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- FXL_CHECK(command.is_set_kind_of_proto_story_option());
-
- operation_queue_.Add(new SetKindOfProtoStoryOptionCall(
- session_storage_, story_id,
- command.set_kind_of_proto_story_option().value, std::move(done)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.h b/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.h
deleted file mode 100644
index 99ba15f..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_KIND_OF_PROTO_STORY_OPTION_COMMAND_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_KIND_OF_PROTO_STORY_OPTION_COMMAND_RUNNER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/command_runner.h"
-
-namespace modular {
-
-class SetKindOfProtoStoryOptionCommandRunner : public CommandRunner {
- public:
- SetKindOfProtoStoryOptionCommandRunner(SessionStorage* const session_storage);
- ~SetKindOfProtoStoryOptionCommandRunner() override;
-
- void Execute(
- fidl::StringPtr story_id, StoryStorage* story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override;
-
- private:
- OperationQueue operation_queue_;
- SessionStorage* const session_storage_; // Not owned.
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_KIND_OF_PROTO_STORY_OPTION_COMMAND_RUNNER_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner_unittest.cc b/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner_unittest.cc
deleted file mode 100644
index 84c2bc9..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner_unittest.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.h"
-
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/testing/test_with_session_storage.h"
-
-namespace modular {
-namespace {
-
-class SetKindOfProtoStoryOptionCommandRunnerTest
- : public testing::TestWithSessionStorage {
- public:
- void SetUp() override {
- testing::TestWithSessionStorage::SetUp();
- session_storage_ = MakeSessionStorage("page");
- runner_ = MakeRunner();
- story_id_ = CreateStory(session_storage_.get());
- }
-
- protected:
- std::unique_ptr<SetKindOfProtoStoryOptionCommandRunner> MakeRunner() {
- return std::make_unique<SetKindOfProtoStoryOptionCommandRunner>(
- session_storage_.get());
- }
-
- std::unique_ptr<SessionStorage> session_storage_;
- std::unique_ptr<SetKindOfProtoStoryOptionCommandRunner> runner_;
- std::string story_id_;
-};
-
-TEST_F(SetKindOfProtoStoryOptionCommandRunnerTest, Execute) {
- fuchsia::modular::StoryCommand command;
- fuchsia::modular::SetKindOfProtoStoryOption set_kind_of_proto_story_option;
- bool done{};
-
- // Set a value.
- {
- set_kind_of_proto_story_option.value = true;
- command.set_set_kind_of_proto_story_option(
- std::move(set_kind_of_proto_story_option));
- runner_->Execute(story_id_, nullptr /* story_storage */, std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
- }
-
- // Verify it was written.
- done = false;
- session_storage_->GetStoryData(story_id_)->Then(
- [&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_TRUE(data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // Update the value.
- {
- set_kind_of_proto_story_option.value = false;
- command.set_set_kind_of_proto_story_option(
- std::move(set_kind_of_proto_story_option));
- done = false;
- runner_->Execute(story_id_, nullptr /* story_storage */, std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
- }
-
- // Verify second value.
- done = false;
- session_storage_->GetStoryData(story_id_)->Then(
- [&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_FALSE(data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.cc b/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.cc
deleted file mode 100644
index 8ca7c7a..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.h"
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/set_link_value_call.h"
-
-namespace modular {
-
-SetLinkValueCommandRunner::SetLinkValueCommandRunner() = default;
-SetLinkValueCommandRunner::~SetLinkValueCommandRunner() = default;
-
-void SetLinkValueCommandRunner::Execute(
- fidl::StringPtr story_id, StoryStorage* const story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- FXL_CHECK(command.is_set_link_value());
-
- AddSetLinkValueOperation(
- &operation_queue_, story_storage,
- std::move(command.set_link_value().path),
- fxl::MakeCopyable(
- [this, new_value = std::move(command.set_link_value().value)](
- fidl::StringPtr* value) {
- std::string str_value;
- FXL_CHECK(fsl::StringFromVmo(*new_value, &str_value));
- *value = str_value;
- }),
- std::move(done));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.h b/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.h
deleted file mode 100644
index e59d314..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_LINK_VALUE_COMMAND_RUNNER_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_LINK_VALUE_COMMAND_RUNNER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/command_runner.h"
-
-namespace modular {
-
-class SetLinkValueCommandRunner : public CommandRunner {
- public:
- SetLinkValueCommandRunner();
- ~SetLinkValueCommandRunner() override;
-
- void Execute(
- fidl::StringPtr story_id, StoryStorage* story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override;
-
- private:
- OperationQueue operation_queue_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_COMMAND_RUNNERS_SET_LINK_VALUE_COMMAND_RUNNER_H_
diff --git a/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner_unittest.cc b/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner_unittest.cc
deleted file mode 100644
index abe6469..0000000
--- a/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner_unittest.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.h"
-
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/testing/test_with_session_storage.h"
-
-namespace modular {
-namespace {
-
-class SetLinkValueCommandRunnerTest : public testing::TestWithSessionStorage {
- public:
- void SetUp() override {
- testing::TestWithSessionStorage::SetUp();
- session_storage_ = MakeSessionStorage("page");
- runner_ = MakeRunner();
- story_id_ = CreateStory(session_storage_.get());
- story_storage_ = GetStoryStorage(session_storage_.get(), story_id_);
- }
-
- protected:
- std::unique_ptr<SetLinkValueCommandRunner> MakeRunner() {
- return std::make_unique<SetLinkValueCommandRunner>();
- }
-
- fuchsia::modular::StoryCommand MakeSetLinkValueCommand(
- const std::string& path_name, const std::string& value) {
- fsl::SizedVmo vmo;
- fsl::VmoFromString(value, &vmo);
- fuchsia::modular::SetLinkValue set_link_value;
- set_link_value.path = MakeLinkPath(path_name);
- set_link_value.value =
- std::make_unique<fuchsia::mem::Buffer>(std::move(vmo).ToTransport());
- fuchsia::modular::StoryCommand command;
- command.set_set_link_value(std::move(set_link_value));
- return command;
- }
-
- std::unique_ptr<SessionStorage> session_storage_;
- std::unique_ptr<StoryStorage> story_storage_;
- std::unique_ptr<SetLinkValueCommandRunner> runner_;
- std::string story_id_;
-};
-
-// On an empty story, it sets a link with a value, then updates it. Each time
-// verifying that the link value is the expected one.
-TEST_F(SetLinkValueCommandRunnerTest, Execute) {
- bool done{};
-
- // Let's set a value.
- auto command = MakeSetLinkValueCommand("link", "10");
- runner_->Execute(story_id_, story_storage_.get(), std::move(command),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
- done = false;
-
- // Let's get the value.
- EXPECT_EQ("10", GetLinkValue(story_storage_.get(), "link"));
-
- // Mutate again.
- auto command2 = MakeSetLinkValueCommand("link", "20");
- runner_->Execute(story_id_, story_storage_.get(), std::move(command2),
- [&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK,
- result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
- done = false;
-
- // Let's get the value again, we should see the new one.
- EXPECT_EQ("20", GetLinkValue(story_storage_.get(), "link"));
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/dispatch_story_command_executor.cc b/bin/sessionmgr/puppet_master/dispatch_story_command_executor.cc
deleted file mode 100644
index f1d245f..0000000
--- a/bin/sessionmgr/puppet_master/dispatch_story_command_executor.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/dispatch_story_command_executor.h"
-
-#include <map>
-
-#include <lib/async/cpp/future.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-namespace modular {
-
-namespace {
-
-class RunStoryCommandCall : public Operation<fuchsia::modular::ExecuteResult> {
- public:
- RunStoryCommandCall(const char* const command_name,
- CommandRunner* const runner,
- StoryStorage* const story_storage,
- fidl::StringPtr story_id,
- fuchsia::modular::StoryCommand command, ResultCall done)
- : Operation(command_name, std::move(done), ""),
- command_(std::move(command)),
- story_storage_(story_storage),
- story_id_(std::move(story_id)),
- runner_(runner) {}
-
- private:
- // |OperationBase|
- void Run() override {
- auto done = [this](fuchsia::modular::ExecuteResult result) {
- Done(std::move(result));
- };
- runner_->Execute(story_id_, story_storage_, std::move(command_),
- std::move(done));
- }
-
- fuchsia::modular::StoryCommand command_;
- StoryStorage* const story_storage_;
- const fidl::StringPtr story_id_;
- CommandRunner* runner_;
-};
-
-} // namespace
-
-class DispatchStoryCommandExecutor::ExecuteStoryCommandsCall
- : public Operation<fuchsia::modular::ExecuteResult> {
- public:
- ExecuteStoryCommandsCall(DispatchStoryCommandExecutor* const executor,
- fidl::StringPtr story_id,
- std::vector<fuchsia::modular::StoryCommand> commands,
- ResultCall done)
- : Operation("ExecuteStoryCommandsCall", std::move(done)),
- executor_(executor),
- story_id_(std::move(story_id)),
- commands_(std::move(commands)) {}
-
- ~ExecuteStoryCommandsCall() override = default;
-
- private:
- void Run() override {
- executor_->session_storage_->GetStoryStorage(story_id_)->WeakThen(
- GetWeakPtr(), [this](std::unique_ptr<StoryStorage> story_storage) {
- if (!story_storage) {
- fuchsia::modular::ExecuteResult result;
- result.status = fuchsia::modular::ExecuteStatus::INVALID_STORY_ID;
- Done(result);
- return;
- }
-
- story_storage_ = std::move(story_storage);
- Cont();
- });
- }
-
- void Cont() {
- // TODO(thatguy): Add a WeakPtr check on |executor_|.
-
- // Keep track of the number of commands we need to run. When they are all
- // done, we complete this operation.
- std::vector<FuturePtr<>> did_execute_commands;
- did_execute_commands.reserve(commands_.size());
-
- for (auto& command : commands_) {
- auto tag_string_it =
- executor_->story_command_tag_strings_.find(command.Which());
- FXL_CHECK(tag_string_it != executor_->story_command_tag_strings_.end())
- << "No fuchsia::modular::StoryCommand::Tag string for tag "
- << static_cast<int>(command.Which());
- const auto& tag_string = tag_string_it->second;
-
- auto it = executor_->command_runners_.find(command.Which());
- FXL_DCHECK(it != executor_->command_runners_.end())
- << "Could not find a fuchsia::modular::StoryCommand runner for tag "
- << static_cast<int>(command.Which()) << ": " << tag_string;
-
- auto* const command_runner = it->second.get();
- // NOTE: it is safe to capture |this| on the lambdas below because if
- // |this| goes out of scope, |queue_| will be deleted, and the callbacks
- // on |queue_| will not run.
-
- auto did_execute_command =
- Future<fuchsia::modular::ExecuteResult>::Create(
- "DispatchStoryCommandExecutor.ExecuteStoryCommandsCall.Run.did_"
- "execute_command");
- queue_.Add(new RunStoryCommandCall(
- tag_string, command_runner, story_storage_.get(), story_id_,
- std::move(command), did_execute_command->Completer()));
- auto did_execute_command_callback = did_execute_command->Then(
- [this](fuchsia::modular::ExecuteResult result) {
- // Check for error for this command. If there was an error, abort
- // early. All of the remaining operations (if any) in queue_ will
- // not be run.
- if (result.status != fuchsia::modular::ExecuteStatus::OK) {
- Done(std::move(result));
- }
- });
- did_execute_commands.emplace_back(did_execute_command_callback);
- }
-
- Wait("DispatchStoryCommandExecutor.ExecuteStoryCommandsCall.Run.Wait",
- did_execute_commands)
- ->Then([this] {
- fuchsia::modular::ExecuteResult result;
- result.status = fuchsia::modular::ExecuteStatus::OK;
- result.story_id = story_id_;
- Done(std::move(result));
- });
- }
-
- DispatchStoryCommandExecutor* const executor_;
- const fidl::StringPtr story_id_;
- std::vector<fuchsia::modular::StoryCommand> commands_;
-
- std::unique_ptr<StoryStorage> story_storage_;
-
- // All commands must be run in order so we use a queue.
- OperationQueue queue_;
-};
-
-DispatchStoryCommandExecutor::DispatchStoryCommandExecutor(
- SessionStorage* const session_storage,
- std::map<fuchsia::modular::StoryCommand::Tag,
- std::unique_ptr<CommandRunner>>
- command_runners)
- : session_storage_(session_storage),
- command_runners_(std::move(command_runners)),
- story_command_tag_strings_{
- {fuchsia::modular::StoryCommand::Tag::kAddMod,
- "StoryCommand::AddMod"},
- {fuchsia::modular::StoryCommand::Tag::kFocusMod,
- "StoryCommand::FocusMod"},
- {fuchsia::modular::StoryCommand::Tag::kRemoveMod,
- "StoryCommand::RemoveMod"},
- {fuchsia::modular::StoryCommand::Tag::kSetLinkValue,
- "StoryCommand::SetLinkValue"},
- {fuchsia::modular::StoryCommand::Tag::kSetFocusState,
- "StoryCommand::SetFocusState"},
- {fuchsia::modular::StoryCommand::Tag::kSetKindOfProtoStoryOption,
- "StoryCommand::SetKindOfProtoStoryOption"}} {
- FXL_DCHECK(session_storage_ != nullptr);
-}
-
-DispatchStoryCommandExecutor::~DispatchStoryCommandExecutor() {}
-
-void DispatchStoryCommandExecutor::ExecuteCommandsInternal(
- fidl::StringPtr story_id,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- operation_queues_[story_id].Add(new ExecuteStoryCommandsCall(
- this, std::move(story_id), std::move(commands), std::move(done)));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/dispatch_story_command_executor.h b/bin/sessionmgr/puppet_master/dispatch_story_command_executor.h
deleted file mode 100644
index 1387110..0000000
--- a/bin/sessionmgr/puppet_master/dispatch_story_command_executor.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_DISPATCH_STORY_COMMAND_EXECUTOR_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_DISPATCH_STORY_COMMAND_EXECUTOR_H_
-
-#include <lib/fidl/cpp/string.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/command_runner.h"
-#include "peridot/bin/sessionmgr/puppet_master/story_command_executor.h"
-
-namespace modular {
-
-class OperationContainer;
-
-// An implementation of StoryCommandExecutor which dispatches execution of
-// individual StoryCommands to CommandRunners for each union tag of
-// fuchsia::modular::StoryCommand.
-class DispatchStoryCommandExecutor : public StoryCommandExecutor {
- public:
- DispatchStoryCommandExecutor(SessionStorage* session_storage,
- std::map<fuchsia::modular::StoryCommand::Tag,
- std::unique_ptr<CommandRunner>>
- command_runners);
- ~DispatchStoryCommandExecutor() override;
-
- private:
- // |StoryCommandExecutor|
- void ExecuteCommandsInternal(
- fidl::StringPtr story_id,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override;
-
- class ExecuteStoryCommandsCall;
-
- SessionStorage* const session_storage_; // Not owned.
- const std::map<fuchsia::modular::StoryCommand::Tag,
- std::unique_ptr<CommandRunner>>
- command_runners_;
-
- // Lookup table from fuchsia::modular::StoryCommand union tag to a
- // human-readable string.
- const std::map<fuchsia::modular::StoryCommand::Tag, const char*>
- story_command_tag_strings_;
-
- std::map<fidl::StringPtr, OperationQueue> operation_queues_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_DISPATCH_STORY_COMMAND_EXECUTOR_H_
diff --git a/bin/sessionmgr/puppet_master/dispatch_story_command_executor_unittest.cc b/bin/sessionmgr/puppet_master/dispatch_story_command_executor_unittest.cc
deleted file mode 100644
index bd4182a..0000000
--- a/bin/sessionmgr/puppet_master/dispatch_story_command_executor_unittest.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/dispatch_story_command_executor.h"
-
-#include <map>
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fidl/cpp/string.h>
-#include "peridot/lib/testing/test_with_ledger.h"
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class TestCommandRunner : public CommandRunner {
- public:
- using ExecuteFunc = std::function<fuchsia::modular::ExecuteStatus(
- fidl::StringPtr, fuchsia::modular::StoryCommand)>;
- TestCommandRunner(ExecuteFunc func, bool delay_done = false)
- : func_(func), delay_done_(delay_done) {}
- ~TestCommandRunner() override = default;
-
- void Execute(
- fidl::StringPtr story_id, StoryStorage* const story_storage,
- fuchsia::modular::StoryCommand command,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override {
- // Post the task on the dispatcher loop to simulate a long-running task.
- async::PostTask(async_get_default_dispatcher(),
- [this, story_id, command = std::move(command),
- done = std::move(done)]() mutable {
- auto status = func_(story_id, std::move(command));
- fuchsia::modular::ExecuteResult result;
- result.status = status;
- if (delay_done_) {
- async::PostTask(async_get_default_dispatcher(),
- [result = std::move(result),
- done = std::move(done)]() {
- done(std::move(result));
- });
- } else {
- done(std::move(result));
- }
- });
- }
-
- ExecuteFunc func_;
- bool delay_done_;
-};
-
-class DispatchStoryCommandExecutorTest
- : public modular::testing::TestWithLedger {
- protected:
- void SetUp() override {
- TestWithLedger::SetUp();
- session_storage_ =
- std::make_unique<SessionStorage>(ledger_client(), LedgerPageId());
- }
-
- void Reset() {
- executor_ = std::make_unique<DispatchStoryCommandExecutor>(
- session_storage_.get(), std::move(command_runners_));
- }
-
- fidl::StringPtr CreateStory() {
- bool done{};
- fidl::StringPtr ret;
- session_storage_->CreateStory({} /* extra_info */, {} /* story_options */)
- ->Then([&](fidl::StringPtr story_id, fuchsia::ledger::PageId) {
- ret = story_id;
- done = true;
- });
-
- RunLoopUntil([&]() { return done; });
- return ret;
- }
-
- void AddCommandRunner(fuchsia::modular::StoryCommand::Tag tag,
- TestCommandRunner::ExecuteFunc func,
- bool delay_done = false) {
- command_runners_.emplace(tag, new TestCommandRunner(func, delay_done));
- }
-
- std::unique_ptr<SessionStorage> session_storage_;
- std::unique_ptr<StoryCommandExecutor> executor_;
- std::map<fuchsia::modular::StoryCommand::Tag, std::unique_ptr<CommandRunner>>
- command_runners_;
-};
-
-TEST_F(DispatchStoryCommandExecutorTest, InvalidStory) {
- Reset();
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::ExecuteResult result;
- bool done{false};
- executor_->ExecuteCommands("id", std::move(commands),
- [&](fuchsia::modular::ExecuteResult r) {
- done = true;
- result = std::move(r);
- });
-
- RunLoopUntil([&]() { return done; });
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_STORY_ID, result.status);
-}
-
-TEST_F(DispatchStoryCommandExecutorTest, Dispatching) {
- auto expected_story_id = CreateStory();
-
- // We expect that each command is dispatched to the command runner for that
- // command.
- int actual_execute_count{0};
- for (auto tag : {fuchsia::modular::StoryCommand::Tag::kAddMod,
- fuchsia::modular::StoryCommand::Tag::kRemoveMod,
- fuchsia::modular::StoryCommand::Tag::kSetLinkValue,
- fuchsia::modular::StoryCommand::Tag::kSetFocusState}) {
- AddCommandRunner(tag, [tag, &actual_execute_count, expected_story_id](
- fidl::StringPtr story_id,
- fuchsia::modular::StoryCommand command) {
- ++actual_execute_count;
- EXPECT_EQ(tag, command.Which());
- EXPECT_EQ(expected_story_id, story_id);
- return fuchsia::modular::ExecuteStatus::OK;
- });
- }
-
- Reset();
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.resize(4);
- commands[0].set_add_mod(fuchsia::modular::AddMod());
- commands[1].set_remove_mod(fuchsia::modular::RemoveMod());
- commands[2].set_set_link_value(fuchsia::modular::SetLinkValue());
- commands[3].set_set_focus_state(fuchsia::modular::SetFocusState());
-
- fuchsia::modular::ExecuteResult result;
- bool done{false};
- executor_->ExecuteCommands(expected_story_id, std::move(commands),
- [&](fuchsia::modular::ExecuteResult r) {
- done = true;
- result = std::move(r);
- });
-
- RunLoopUntil([&]() { return done; });
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK, result.status);
- EXPECT_EQ(expected_story_id, result.story_id);
- EXPECT_EQ(4, actual_execute_count);
-}
-
-TEST_F(DispatchStoryCommandExecutorTest, Sequential) {
- auto story_id = CreateStory();
-
- // Commands are run sequentially.
- std::vector<std::string> names;
- // We're going to run an fuchsia::modular::AddMod command first, but we'll
- // push the "logic" onto the async loop so that, if the implementation
- // posted all of our CommandRunner logic sequentially on the async loop, it
- // would run after the commands following this one. That's what |delay_done|
- // does.
- AddCommandRunner(
- fuchsia::modular::StoryCommand::Tag::kAddMod,
- [&](fidl::StringPtr story_id, fuchsia::modular::StoryCommand command) {
- names.push_back(command.add_mod().mod_name.at(0));
- return fuchsia::modular::ExecuteStatus::OK;
- },
- true /* delay_done */);
- AddCommandRunner(
- fuchsia::modular::StoryCommand::Tag::kRemoveMod,
- [&](fidl::StringPtr story_id, fuchsia::modular::StoryCommand command) {
- names.push_back(command.remove_mod().mod_name.at(0));
- return fuchsia::modular::ExecuteStatus::OK;
- });
-
- Reset();
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.resize(2);
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("one");
- commands[0].set_add_mod(std::move(add_mod));
- fuchsia::modular::RemoveMod remove_mod;
- remove_mod.mod_name.push_back("two");
- commands[1].set_remove_mod(std::move(remove_mod));
-
- bool done{false};
- executor_->ExecuteCommands(
- story_id, std::move(commands),
- [&](fuchsia::modular::ExecuteResult) { done = true; });
- RunLoopUntil([&]() { return done; });
-
- EXPECT_EQ(2u, names.size());
- EXPECT_EQ("one", names[0]);
- EXPECT_EQ("two", names[1]);
-}
-
-TEST_F(DispatchStoryCommandExecutorTest, ErrorsAbortEarly) {
- auto story_id = CreateStory();
-
- // Commands after those that report an error don't run. The reported error
- // code is returned.
- bool second_command_ran{false};
- AddCommandRunner(
- fuchsia::modular::StoryCommand::Tag::kAddMod,
- [](fidl::StringPtr story_id, fuchsia::modular::StoryCommand command) {
- return fuchsia::modular::ExecuteStatus::INVALID_COMMAND;
- });
- AddCommandRunner(
- fuchsia::modular::StoryCommand::Tag::kRemoveMod,
- [&](fidl::StringPtr story_id, fuchsia::modular::StoryCommand command) {
- second_command_ran = true;
- return fuchsia::modular::ExecuteStatus::OK;
- });
-
- Reset();
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.resize(2);
- commands[0].set_add_mod(fuchsia::modular::AddMod());
- commands[1].set_remove_mod(fuchsia::modular::RemoveMod());
-
- bool done{false};
- fuchsia::modular::ExecuteResult result;
- executor_->ExecuteCommands(story_id, std::move(commands),
- [&](fuchsia::modular::ExecuteResult r) {
- done = true;
- result = std::move(r);
- });
- RunLoopUntil([&]() { return done; });
-
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::INVALID_COMMAND, result.status);
- EXPECT_FALSE(second_command_ran);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/make_production_impl.cc b/bin/sessionmgr/puppet_master/make_production_impl.cc
deleted file mode 100644
index 0bcd27f..0000000
--- a/bin/sessionmgr/puppet_master/make_production_impl.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/make_production_impl.h"
-
-#include <memory>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/add_mod_command_runner.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/focus_mod_command_runner.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/remove_mod_command_runner.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_focus_state_command_runner.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_kind_of_proto_story_option_command_runner.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/set_link_value_command_runner.h"
-#include "peridot/bin/sessionmgr/puppet_master/dispatch_story_command_executor.h"
-
-namespace modular {
-
-class PuppetMasterImpl;
-
-using StoryControllerFactory =
- fit::function<fuchsia::modular::StoryControllerPtr(
- fidl::StringPtr story_id)>;
-
-std::unique_ptr<StoryCommandExecutor> MakeProductionStoryCommandExecutor(
- SessionStorage* const session_storage,
- fuchsia::modular::FocusProviderPtr focus_provider,
- fuchsia::modular::ModuleResolver* const module_resolver,
- fuchsia::modular::EntityResolver* const entity_resolver,
- // TODO(miguelfrde): we shouldn't create this dependency here. Instead
- // an interface similar to StoryStorage should be created for Runtime
- // use cases.
- fit::function<void(std::string, std::vector<std::string>)>
- module_focuser) {
- std::map<fuchsia::modular::StoryCommand::Tag, std::unique_ptr<CommandRunner>>
- command_runners;
- command_runners.emplace(
- fuchsia::modular::StoryCommand::Tag::kSetFocusState,
- new SetFocusStateCommandRunner(std::move(focus_provider)));
- command_runners.emplace(
- fuchsia::modular::StoryCommand::Tag::kAddMod,
- new AddModCommandRunner(module_resolver, entity_resolver));
- command_runners.emplace(fuchsia::modular::StoryCommand::Tag::kFocusMod,
- new FocusModCommandRunner(std::move(module_focuser)));
- command_runners.emplace(fuchsia::modular::StoryCommand::Tag::kRemoveMod,
- new RemoveModCommandRunner());
- command_runners.emplace(fuchsia::modular::StoryCommand::Tag::kSetLinkValue,
- new SetLinkValueCommandRunner());
- command_runners.emplace(
- fuchsia::modular::StoryCommand::Tag::kSetKindOfProtoStoryOption,
- new SetKindOfProtoStoryOptionCommandRunner(session_storage));
-
- auto executor = std::make_unique<DispatchStoryCommandExecutor>(
- session_storage, std::move(command_runners));
- return executor;
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/make_production_impl.h b/bin/sessionmgr/puppet_master/make_production_impl.h
deleted file mode 100644
index be9055b..0000000
--- a/bin/sessionmgr/puppet_master/make_production_impl.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_MAKE_PRODUCTION_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_MAKE_PRODUCTION_IMPL_H_
-
-#include <memory>
-
-#include "peridot/bin/sessionmgr/puppet_master/dispatch_story_command_executor.h"
-
-namespace modular {
-
-class StoryCommandExecutor;
-
-// Returns a StoryCommandExecutor suitable for use in production.
-std::unique_ptr<StoryCommandExecutor> MakeProductionStoryCommandExecutor(
- SessionStorage* session_storage,
- fuchsia::modular::FocusProviderPtr focus_provider,
- fuchsia::modular::ModuleResolver* module_resolver,
- fuchsia::modular::EntityResolver* entity_resolver,
- fit::function<void(std::string, std::vector<std::string>)>
- module_focuser);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_MAKE_PRODUCTION_IMPL_H_
diff --git a/bin/sessionmgr/puppet_master/meta/add_mod_command_runner_unittest.cmx b/bin/sessionmgr/puppet_master/meta/add_mod_command_runner_unittest.cmx
deleted file mode 100644
index d462cf7..0000000
--- a/bin/sessionmgr/puppet_master/meta/add_mod_command_runner_unittest.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/add_mod_command_runner_unittest"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/sessionmgr/puppet_master/meta/dispatch_story_command_executor_unittest.cmx b/bin/sessionmgr/puppet_master/meta/dispatch_story_command_executor_unittest.cmx
deleted file mode 100644
index cc547a3..0000000
--- a/bin/sessionmgr/puppet_master/meta/dispatch_story_command_executor_unittest.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/dispatch_story_command_executor_unittest"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/sessionmgr/puppet_master/meta/focus_mod_command_runner_unittest.cmx b/bin/sessionmgr/puppet_master/meta/focus_mod_command_runner_unittest.cmx
deleted file mode 100644
index 9379c10..0000000
--- a/bin/sessionmgr/puppet_master/meta/focus_mod_command_runner_unittest.cmx
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "program": {
- "binary": "test/focus_mod_command_runner_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
diff --git a/bin/sessionmgr/puppet_master/meta/puppet_master_impl_unittest.cmx b/bin/sessionmgr/puppet_master/meta/puppet_master_impl_unittest.cmx
deleted file mode 100644
index c2b6989..0000000
--- a/bin/sessionmgr/puppet_master/meta/puppet_master_impl_unittest.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/puppet_master_impl_unittest"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/sessionmgr/puppet_master/meta/remove_mod_command_runner_unittest.cmx b/bin/sessionmgr/puppet_master/meta/remove_mod_command_runner_unittest.cmx
deleted file mode 100644
index 81e7baf..0000000
--- a/bin/sessionmgr/puppet_master/meta/remove_mod_command_runner_unittest.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/remove_mod_command_runner_unittest"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/sessionmgr/puppet_master/meta/set_focus_state_command_runner_unittest.cmx b/bin/sessionmgr/puppet_master/meta/set_focus_state_command_runner_unittest.cmx
deleted file mode 100644
index e12dc99..0000000
--- a/bin/sessionmgr/puppet_master/meta/set_focus_state_command_runner_unittest.cmx
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "program": {
- "binary": "test/set_focus_state_command_runner_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
diff --git a/bin/sessionmgr/puppet_master/meta/set_kind_of_proto_story_option_command_runner_unittest.cmx b/bin/sessionmgr/puppet_master/meta/set_kind_of_proto_story_option_command_runner_unittest.cmx
deleted file mode 100644
index 31d38c7..0000000
--- a/bin/sessionmgr/puppet_master/meta/set_kind_of_proto_story_option_command_runner_unittest.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/set_kind_of_proto_story_option_command_runner_unittest"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/sessionmgr/puppet_master/meta/set_link_value_command_runner_unittest.cmx b/bin/sessionmgr/puppet_master/meta/set_link_value_command_runner_unittest.cmx
deleted file mode 100644
index aa605eb..0000000
--- a/bin/sessionmgr/puppet_master/meta/set_link_value_command_runner_unittest.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/set_link_value_command_runner_unittest"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/sessionmgr/puppet_master/meta/story_command_executor_unittest.cmx b/bin/sessionmgr/puppet_master/meta/story_command_executor_unittest.cmx
deleted file mode 100644
index a3c5f6e..0000000
--- a/bin/sessionmgr/puppet_master/meta/story_command_executor_unittest.cmx
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "program": {
- "binary": "test/story_command_executor_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
diff --git a/bin/sessionmgr/puppet_master/puppet_master_impl.cc b/bin/sessionmgr/puppet_master/puppet_master_impl.cc
deleted file mode 100644
index cb0f934..0000000
--- a/bin/sessionmgr/puppet_master/puppet_master_impl.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/puppet_master_impl.h"
-
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/story_puppet_master_impl.h"
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-
-namespace modular {
-
-PuppetMasterImpl::PuppetMasterImpl(SessionStorage* const session_storage,
- StoryCommandExecutor* const executor)
- : session_storage_(session_storage), executor_(executor) {
- FXL_DCHECK(session_storage_ != nullptr);
- FXL_DCHECK(executor_ != nullptr);
-}
-
-PuppetMasterImpl::~PuppetMasterImpl() = default;
-
-void PuppetMasterImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::PuppetMaster> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void PuppetMasterImpl::ControlStory(
- std::string story_name,
- fidl::InterfaceRequest<fuchsia::modular::StoryPuppetMaster> request) {
- auto controller = std::make_unique<StoryPuppetMasterImpl>(
- story_name, &operations_, session_storage_, executor_);
- story_puppet_masters_.AddBinding(std::move(controller), std::move(request));
-}
-
-void PuppetMasterImpl::DeleteStory(std::string story_name,
- DeleteStoryCallback done) {
- session_storage_->DeleteStory(story_name)->Then(std::move(done));
-}
-
-void PuppetMasterImpl::GetStories(GetStoriesCallback done) {
- session_storage_->GetAllStoryData()->Then(
- [done = std::move(done)](
- std::vector<fuchsia::modular::internal::StoryData>
- all_story_data) {
- std::vector<std::string> result;
- for (auto& story : all_story_data) {
- result.push_back(std::move(story.story_info.id));
- }
-
- done(std::move(result));
- });
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/puppet_master_impl.h b/bin/sessionmgr/puppet_master/puppet_master_impl.h
deleted file mode 100644
index 748e1f5..0000000
--- a/bin/sessionmgr/puppet_master/puppet_master_impl.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_PUPPET_MASTER_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_PUPPET_MASTER_IMPL_H_
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-namespace modular {
-
-class SessionStorage;
-class StoryCommandExecutor;
-class StoryPuppetMasterImpl;
-
-// An implementation of fuchsia::modular::PuppetMaster which owns and connect
-// clients to instances of StoryPuppetMasterImpl for story control.
-class PuppetMasterImpl : public fuchsia::modular::PuppetMaster {
- public:
- // Does not take ownership of |session_storage| or |executor|.
- explicit PuppetMasterImpl(SessionStorage* session_storage,
- StoryCommandExecutor* executor);
- ~PuppetMasterImpl() override;
-
- void Connect(fidl::InterfaceRequest<fuchsia::modular::PuppetMaster> request);
-
- private:
- // |PuppetMaster|
- void ControlStory(std::string story_name,
- fidl::InterfaceRequest<fuchsia::modular::StoryPuppetMaster>
- request) override;
-
- // |PuppetMaster|
- void DeleteStory(std::string story_name,
- DeleteStoryCallback done) override;
-
- // |PuppetMaster|
- void GetStories(GetStoriesCallback done) override;
-
- SessionStorage* const session_storage_; // Not owned.
- StoryCommandExecutor* const executor_; // Not owned.
-
- fidl::BindingSet<fuchsia::modular::PuppetMaster> bindings_;
- // There is a one-impl-per-connection relationship between
- // fuchsia::modular::StoryPuppetMaster and its bindings.
- fidl::BindingSet<fuchsia::modular::StoryPuppetMaster,
- std::unique_ptr<StoryPuppetMasterImpl>>
- story_puppet_masters_;
-
- OperationCollection operations_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PuppetMasterImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_PUPPET_MASTER_IMPL_H_
diff --git a/bin/sessionmgr/puppet_master/puppet_master_impl_unittest.cc b/bin/sessionmgr/puppet_master/puppet_master_impl_unittest.cc
deleted file mode 100644
index bd97653..0000000
--- a/bin/sessionmgr/puppet_master/puppet_master_impl_unittest.cc
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/puppet_master_impl.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/testing/test_story_command_executor.h"
-#include "peridot/lib/testing/test_with_session_storage.h"
-
-namespace modular {
-namespace {
-
-fuchsia::modular::StoryCommand MakeRemoveModCommand(std::string mod_name) {
- fuchsia::modular::StoryCommand command;
- fuchsia::modular::RemoveMod remove_mod;
- remove_mod.mod_name.push_back(mod_name);
- command.set_remove_mod(std::move(remove_mod));
- return command;
-}
-
-class PuppetMasterTest : public testing::TestWithSessionStorage {
- public:
- void SetUp() override {
- TestWithSessionStorage::SetUp();
- storage_ = MakeSessionStorage("page");
- impl_ = std::make_unique<PuppetMasterImpl>(storage_.get(), &executor_);
- impl_->Connect(ptr_.NewRequest());
- }
-
- fuchsia::modular::StoryPuppetMasterPtr ControlStory(
- fidl::StringPtr story_name) {
- fuchsia::modular::StoryPuppetMasterPtr ptr;
- ptr_->ControlStory(story_name, ptr.NewRequest());
- return ptr;
- }
-
- protected:
- testing::TestStoryCommandExecutor executor_;
- std::unique_ptr<SessionStorage> storage_;
- std::unique_ptr<PuppetMasterImpl> impl_;
- fuchsia::modular::PuppetMasterPtr ptr_;
-};
-
-TEST_F(PuppetMasterTest, CommandsAreSentToExecutor) {
- // This should create a new story in StoryStorage called "foo".
- auto story = ControlStory("foo");
-
- // Enqueue some commands. Do this twice and show that all the commands show
- // up as one batch.
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(MakeRemoveModCommand("one"));
- story->Enqueue(std::move(commands));
- commands.push_back(MakeRemoveModCommand("two"));
- commands.push_back(MakeRemoveModCommand("three"));
- story->Enqueue(std::move(commands));
-
- // Commands are not run until Execute() is called.
- RunLoopUntilIdle();
- EXPECT_EQ(0, executor_.execute_count());
-
- fuchsia::modular::ExecuteResult result;
- bool done{false};
- // Instruct our test executor to return an OK status.
- executor_.SetExecuteReturnResult(fuchsia::modular::ExecuteStatus::OK,
- nullptr);
- story->Execute([&](fuchsia::modular::ExecuteResult r) {
- result = std::move(r);
- done = true;
- });
- RunLoopUntil([&]() { return done; });
- EXPECT_EQ(1, executor_.execute_count());
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK, result.status);
-
- EXPECT_EQ("foo", executor_.last_story_id());
- ASSERT_EQ(3u, executor_.last_commands().size());
- EXPECT_EQ("one",
- executor_.last_commands().at(0).remove_mod().mod_name.at(0));
- EXPECT_EQ("two",
- executor_.last_commands().at(1).remove_mod().mod_name.at(0));
- EXPECT_EQ("three",
- executor_.last_commands().at(2).remove_mod().mod_name.at(0));
-}
-
-TEST_F(PuppetMasterTest, CommandsAreSentToExecutor_IfWeCloseStoryChannel) {
- // We're going to call Execute(), and then immediately drop the
- // StoryPuppetMaster connection. We won't get a callback, but we still
- // expect that the commands are executed.
- auto story = ControlStory("foo");
-
- // Enqueue some commands. Do this twice and show that all the commands show
- // up as one batch.
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(MakeRemoveModCommand("one"));
- story->Enqueue(std::move(commands));
-
- fuchsia::modular::ExecuteResult result;
- bool callback_called{false};
- // Instruct our test executor to return an OK status.
- executor_.SetExecuteReturnResult(fuchsia::modular::ExecuteStatus::OK,
- nullptr);
- story->Execute([&](fuchsia::modular::ExecuteResult r) {
- callback_called = true;
- });
- story.Unbind();
- RunLoopUntil([&]() { return executor_.execute_count() > 0; });
- EXPECT_FALSE(callback_called);
- EXPECT_EQ(1, executor_.execute_count());
-}
-
-TEST_F(PuppetMasterTest, MultipleExecuteCalls) {
- // Create a new story, and then execute some new commands on the same
- // connection. We should see that the StoryCommandExecutor receives the story
- // id that it reported after successful creation of the story on the last
- // execution.
- auto story = ControlStory("foo");
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(MakeRemoveModCommand("one"));
- executor_.SetExecuteReturnResult(fuchsia::modular::ExecuteStatus::OK,
- nullptr);
- bool done{false};
- story->Execute([&](fuchsia::modular::ExecuteResult r) { done = true; });
- RunLoopUntil([&]() { return done; });
- auto story_id = executor_.last_story_id();
-
- // Execute more commands.
- commands.push_back(MakeRemoveModCommand("three"));
- story->Enqueue(std::move(commands));
- done = false;
- story->Execute([&](fuchsia::modular::ExecuteResult r) { done = true; });
- RunLoopUntil([&]() { return done; });
- EXPECT_EQ(story_id, executor_.last_story_id());
-}
-
-TEST_F(PuppetMasterTest, NewStoriesAreKeptSeparate) {
- // Creating two new stories at the same time is OK and they are kept
- // separate.
- auto story1 = ControlStory("story1");
- auto story2 = ControlStory("story2");
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(MakeRemoveModCommand("one"));
- story1->Enqueue(std::move(commands));
- // We must run the loop to ensure that our message is dispatched.
- RunLoopUntilIdle();
-
- commands.push_back(MakeRemoveModCommand("two"));
- story2->Enqueue(std::move(commands));
- RunLoopUntilIdle();
-
- fuchsia::modular::ExecuteResult result;
- executor_.SetExecuteReturnResult(fuchsia::modular::ExecuteStatus::OK,
- nullptr);
- bool done{false};
- story1->Execute([&](fuchsia::modular::ExecuteResult r) {
- result = std::move(r);
- done = true;
- });
- RunLoopUntil([&]() { return done; });
- EXPECT_EQ(1, executor_.execute_count());
- auto story1_id = executor_.last_story_id();
- ASSERT_EQ(1u, executor_.last_commands().size());
- EXPECT_EQ("one",
- executor_.last_commands().at(0).remove_mod().mod_name.at(0));
-
- executor_.SetExecuteReturnResult(fuchsia::modular::ExecuteStatus::OK,
- nullptr);
- done = false;
- story2->Execute([&](fuchsia::modular::ExecuteResult r) {
- result = std::move(r);
- done = true;
- });
- RunLoopUntil([&]() { return done; });
- EXPECT_EQ(2, executor_.execute_count());
- auto story2_id = executor_.last_story_id();
- ASSERT_EQ(1u, executor_.last_commands().size());
- EXPECT_EQ("two",
- executor_.last_commands().at(0).remove_mod().mod_name.at(0));
-
- // The two IDs should be different, because we gave the two stories different
- // names.
- EXPECT_NE(story1_id, story2_id);
-}
-
-TEST_F(PuppetMasterTest, ControlExistingStory) {
- // Controlling the same story from two connections is OK. The first call to
- // Execute() will create the story, and the second will re-use the same story
- // record.
- auto story1 = ControlStory("foo");
- auto story2 = ControlStory("foo");
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(MakeRemoveModCommand("one"));
- story1->Enqueue(std::move(commands));
- // We must run the loop to ensure that our message is dispatched.
- RunLoopUntilIdle();
-
- commands.push_back(MakeRemoveModCommand("two"));
- story2->Enqueue(std::move(commands));
- RunLoopUntilIdle();
-
- fuchsia::modular::ExecuteResult result;
- executor_.SetExecuteReturnResult(fuchsia::modular::ExecuteStatus::OK,
- nullptr);
- bool done{false};
- story1->Execute([&](fuchsia::modular::ExecuteResult r) {
- result = std::move(r);
- done = true;
- });
- RunLoopUntil([&]() { return done; });
- EXPECT_EQ(1, executor_.execute_count());
- auto story_id = executor_.last_story_id();
- ASSERT_EQ(1u, executor_.last_commands().size());
- EXPECT_EQ("one",
- executor_.last_commands().at(0).remove_mod().mod_name.at(0));
-
- executor_.SetExecuteReturnResult(fuchsia::modular::ExecuteStatus::OK,
- nullptr);
- done = false;
- story2->Execute([&](fuchsia::modular::ExecuteResult r) {
- result = std::move(r);
- done = true;
- });
- RunLoopUntil([&]() { return done; });
- EXPECT_EQ(2, executor_.execute_count());
- EXPECT_EQ(story_id, executor_.last_story_id());
- ASSERT_EQ(1u, executor_.last_commands().size());
- EXPECT_EQ("two",
- executor_.last_commands().at(0).remove_mod().mod_name.at(0));
-}
-
-TEST_F(PuppetMasterTest, CreateStoryWithOptions) {
- // Verify that options are set when the story is created (as result of an
- // execution) and are not updated in future executions.
- auto story = ControlStory("foo");
-
- fuchsia::modular::StoryOptions options;
- options.kind_of_proto_story = true;
- story->SetCreateOptions(std::move(options));
-
- // Enqueue some commands.
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(MakeRemoveModCommand("one"));
- story->Enqueue(std::move(commands));
-
- // Options are not set until execute that triggers the creation of a story.
- bool done{};
- storage_->GetStoryData("foo")->Then(
- [&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_EQ(nullptr, data);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- done = false;
- story->Execute([&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK, result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
- auto story_id = executor_.last_story_id();
-
- // Options should have been set.
- done = false;
- storage_->GetStoryData("foo")->Then(
- [&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_TRUE(data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // Setting new options and executing again should have no effect.
- fuchsia::modular::StoryOptions options2;
- options2.kind_of_proto_story = false;
- story->SetCreateOptions(std::move(options2));
-
- // Enqueue some commands.
- std::vector<fuchsia::modular::StoryCommand> commands2;
- commands2.push_back(MakeRemoveModCommand("two"));
- story->Enqueue(std::move(commands2));
-
- done = false;
- story->Execute([&](fuchsia::modular::ExecuteResult result) {
- EXPECT_EQ(fuchsia::modular::ExecuteStatus::OK, result.status);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- EXPECT_EQ(story_id, executor_.last_story_id());
-
- // Options should have changed.
- done = false;
- storage_->GetStoryData("foo")->Then(
- [&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_TRUE(data->story_options.kind_of_proto_story);
- done = true;
- });
-
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(PuppetMasterTest, DeleteStory) {
- std::string story_id;
-
- // Create a story.
- storage_->CreateStory("foo", {} /* extra_info */, {} /* story_options */)
- ->Then([&](fidl::StringPtr id, fuchsia::ledger::PageId page_id) {
- story_id = id;
- });
-
- // Delete it
- bool done{};
- ptr_->DeleteStory("foo", [&] { done = true; });
- RunLoopUntil([&] { return done; });
-
- done = false;
- storage_->GetStoryData(story_id)->Then(
- [&](fuchsia::modular::internal::StoryDataPtr story_data) {
- EXPECT_EQ(story_data, nullptr);
- done = true;
- });
-
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(PuppetMasterTest, GetStories) {
- // Zero stories to should exist.
- bool done{};
- ptr_->GetStories([&](std::vector<std::string> story_names) {
- EXPECT_EQ(0u, story_names.size());
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // Create a story.
- storage_->CreateStory("foo", {} /* extra_info */, {} /* story_options */);
-
- // "foo" should be listed.
- done = false;
- ptr_->GetStories([&](std::vector<std::string> story_names) {
- ASSERT_EQ(1u, story_names.size());
- EXPECT_EQ("foo", story_names.at(0));
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/story_command_executor.cc b/bin/sessionmgr/puppet_master/story_command_executor.cc
deleted file mode 100644
index a5e93c8..0000000
--- a/bin/sessionmgr/puppet_master/story_command_executor.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/story_command_executor.h"
-
-#include <lib/fxl/functional/make_copyable.h>
-
-namespace modular {
-
-namespace {
-std::vector<fuchsia::modular::StoryCommand> CloneCommands(
- const std::vector<fuchsia::modular::StoryCommand>& commands) {
- std::vector<fuchsia::modular::StoryCommand> commands_copy;
- for (const auto& command : commands) {
- fuchsia::modular::StoryCommand clone;
- command.Clone(&clone);
- commands_copy.push_back(std::move(clone));
- }
-
- return commands_copy;
-}
-} // namespace
-
-StoryCommandExecutor::StoryCommandExecutor() : weak_factory_(this) {}
-StoryCommandExecutor::~StoryCommandExecutor() = default;
-
-void StoryCommandExecutor::ExecuteCommands(
- fidl::StringPtr story_id,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- // TODO(thatguy): Cloning the commands here is unforunate. We will want to
- // create a shared datastructure at some point, such as a
- // ExecuteCommandsContext struct that contains the commands, and also allows
- // command runners to make modifications to the commands so that observers get
- // commands that are more fully specified.
- //
- // For now, we make a copy.
- auto commands_copy = CloneCommands(commands);
- auto on_execute_done =
- [weak_this = weak_factory_.GetWeakPtr(),
- commands_copy = std::move(commands_copy),
- done = std::move(done)](fuchsia::modular::ExecuteResult result) {
- if (!weak_this)
- return;
-
- for (auto& listener : weak_this->listeners_) {
- listener(commands_copy, result);
- }
-
- done(result);
- };
-
- ExecuteCommandsInternal(std::move(story_id), std::move(commands),
- fxl::MakeCopyable(std::move(on_execute_done)));
-}
-
-StoryCommandExecutor::ListenerAutoCancel StoryCommandExecutor::AddListener(
- ListenerCallback listener) {
- auto it = listeners_.insert(listeners_.end(), std::move(listener));
-
- auto auto_remove = [weak_this = weak_factory_.GetWeakPtr(), it] {
- if (!weak_this)
- return;
-
- weak_this->listeners_.erase(it);
- };
- return ListenerAutoCancel(std::move(auto_remove));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/story_command_executor.h b/bin/sessionmgr/puppet_master/story_command_executor.h
deleted file mode 100644
index 770ba84..0000000
--- a/bin/sessionmgr/puppet_master/story_command_executor.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_STORY_COMMAND_EXECUTOR_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_STORY_COMMAND_EXECUTOR_H_
-
-#include <functional>
-#include <list>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-namespace modular {
-
-class StoryCommandExecutor {
- public:
- StoryCommandExecutor();
- virtual ~StoryCommandExecutor();
-
- // Executes |commands| on story identified by |story_id| and calls |done| when
- // complete. |story_id| is always non-null and refers to an existing Story.
- //
- // If an error occurs, fuchsia::modular::ExecuteResult.status will be set to
- // indicate the type of error, and a helpful error message must also be
- // provided in fuchsia::modular::ExecuteResult.error_message.
- //
- // On success fuchsia::modular::ExecuteResult.status will be set to
- // fuchsia::modular::ExecuteStatus.OK.
- void ExecuteCommands(
- fidl::StringPtr story_id,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::function<void(fuchsia::modular::ExecuteResult)> done);
-
- using ListenerCallback = fit::function<void(
- const std::vector<fuchsia::modular::StoryCommand>& commands,
- fuchsia::modular::ExecuteResult result)>;
- using ListenerAutoCancel = fit::deferred_action<std::function<void()>>;
-
- // Calls |listener| whenever StoryCommands are executed with the commands and
- // the execution result. Returns a scoped auto-cancel value. The returned
- // ListenerAutoCancel must be kept alive as long as the callee wishes to
- // receive notifications of StoryCommand execution.
- ListenerAutoCancel AddListener(ListenerCallback listener);
-
- private:
- virtual void ExecuteCommandsInternal(
- fidl::StringPtr story_id,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::function<void(fuchsia::modular::ExecuteResult)> done) = 0;
-
- std::list<ListenerCallback> listeners_;
- fxl::WeakPtrFactory<StoryCommandExecutor> weak_factory_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_STORY_COMMAND_EXECUTOR_H_
diff --git a/bin/sessionmgr/puppet_master/story_command_executor_unittest.cc b/bin/sessionmgr/puppet_master/story_command_executor_unittest.cc
deleted file mode 100644
index ca81f73..0000000
--- a/bin/sessionmgr/puppet_master/story_command_executor_unittest.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/story_command_executor.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-using fuchsia::modular::ExecuteResult;
-using fuchsia::modular::ExecuteStatus;
-using fuchsia::modular::StoryCommand;
-
-class TestStoryCommandExecutor : public StoryCommandExecutor {
- public:
- void SetExecuteReturnResult(ExecuteStatus status,
- fidl::StringPtr error_message) {
- result_.status = status;
- result_.error_message = error_message;
- }
-
- int execute_count{0};
- fidl::StringPtr last_story_id;
- std::vector<StoryCommand> last_commands;
-
- private:
- // |StoryCommandExecutor|
- void ExecuteCommandsInternal(
- fidl::StringPtr story_id, std::vector<StoryCommand> commands,
- std::function<void(ExecuteResult)> done) override {
- ++execute_count;
- last_story_id = story_id;
- last_commands = std::move(commands);
- ExecuteResult result;
- fidl::Clone(result_, &result);
- done(std::move(result));
- }
-
- ExecuteResult result_;
-};
-
-StoryCommand MakeRemoveModCommand(std::string mod_name) {
- StoryCommand command;
- fuchsia::modular::RemoveMod remove_mod;
- remove_mod.mod_name.push_back(mod_name);
- command.set_remove_mod(std::move(remove_mod));
- return command;
-}
-
-TEST(StoryCommandExecutorTest, ListenerSeesCommands) {
- TestStoryCommandExecutor executor;
- executor.SetExecuteReturnResult(ExecuteStatus::OK, "message");
-
- bool listener_called{false};
- auto auto_cancel = executor.AddListener(
- [&](const std::vector<StoryCommand>& commands, ExecuteResult result) {
- EXPECT_EQ(1lu, commands.size());
- EXPECT_EQ(ExecuteStatus::OK, result.status);
- EXPECT_EQ("message", result.error_message);
- listener_called = true;
- });
-
- bool execute_done{false};
- std::vector<StoryCommand> commands;
- commands.push_back(MakeRemoveModCommand("one"));
- executor.ExecuteCommands("story id", std::move(commands),
- [&](ExecuteResult result) {
- execute_done = true;
- EXPECT_EQ(ExecuteStatus::OK, result.status);
- EXPECT_EQ("message", result.error_message);
- });
- EXPECT_TRUE(listener_called);
- EXPECT_TRUE(execute_done);
-
- // Now unregister the listener.
- auto_cancel.call();
- listener_called = false;
- execute_done = false;
- commands.push_back(MakeRemoveModCommand("one"));
- executor.ExecuteCommands("story id", std::move(commands),
- [&](ExecuteResult result) { execute_done = true; });
- EXPECT_FALSE(listener_called);
- EXPECT_TRUE(execute_done);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/story_puppet_master_impl.cc b/bin/sessionmgr/puppet_master/story_puppet_master_impl.cc
deleted file mode 100644
index b20d652..0000000
--- a/bin/sessionmgr/puppet_master/story_puppet_master_impl.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/puppet_master/story_puppet_master_impl.h"
-
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/story_command_executor.h"
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-
-namespace modular {
-
-namespace {
-
-class ExecuteOperation : public Operation<fuchsia::modular::ExecuteResult> {
- public:
- ExecuteOperation(SessionStorage* const session_storage,
- StoryCommandExecutor* const executor,
- std::string story_name,
- fuchsia::modular::StoryOptions story_options,
- std::vector<fuchsia::modular::StoryCommand> commands,
- ResultCall done)
- : Operation("StoryPuppetMasterImpl.ExecuteOpreation", std::move(done)),
- session_storage_(session_storage),
- executor_(executor),
- story_name_(std::move(story_name)),
- story_options_(std::move(story_options)),
- commands_(std::move(commands)) {}
-
- private:
- void Run() override {
- session_storage_->GetStoryData(story_name_)
- ->WeakThen(GetWeakPtr(),
- [this](fuchsia::modular::internal::StoryDataPtr data) {
- if (data) {
- story_id_ = data->story_info.id;
- ExecuteCommands();
- return;
- }
-
- CreateStory();
- });
- }
-
- void CreateStory() {
- session_storage_
- ->CreateStory(story_name_, nullptr /* extra_info */,
- std::move(story_options_))
- ->WeakThen(GetWeakPtr(),
- [this](fidl::StringPtr story_id, auto /* ignored */) {
- story_id_ = story_id;
- ExecuteCommands();
- });
- }
-
- void ExecuteCommands() {
- executor_->ExecuteCommands(story_id_, std::move(commands_),
- [weak_ptr = GetWeakPtr(),
- this](fuchsia::modular::ExecuteResult result) {
- Done(std::move(result));
- });
- }
-
- SessionStorage* const session_storage_;
- StoryCommandExecutor* const executor_;
- std::string story_name_;
- fuchsia::modular::StoryOptions story_options_;
- std::vector<fuchsia::modular::StoryCommand> commands_;
-
- fidl::StringPtr story_id_;
-};
-
-} // namespace
-
-StoryPuppetMasterImpl::StoryPuppetMasterImpl(
- std::string story_name, OperationContainer* const operations,
- SessionStorage* const session_storage, StoryCommandExecutor* const executor)
- : story_name_(story_name),
- session_storage_(session_storage),
- executor_(executor),
- operations_(operations) {
- FXL_DCHECK(session_storage != nullptr);
- FXL_DCHECK(executor != nullptr);
-}
-
-StoryPuppetMasterImpl::~StoryPuppetMasterImpl() = default;
-
-void StoryPuppetMasterImpl::Enqueue(
- std::vector<fuchsia::modular::StoryCommand> commands) {
- enqueued_commands_.insert(enqueued_commands_.end(),
- make_move_iterator(commands.begin()),
- make_move_iterator(commands.end()));
-}
-
-void StoryPuppetMasterImpl::Execute(ExecuteCallback done) {
- // First ensure that the story is created.
- operations_->Add(new ExecuteOperation(session_storage_, executor_,
- story_name_, std::move(story_options_),
- std::move(enqueued_commands_), done));
-}
-
-void StoryPuppetMasterImpl::SetCreateOptions(
- fuchsia::modular::StoryOptions story_options) {
- story_options_ = std::move(story_options);
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/puppet_master/story_puppet_master_impl.h b/bin/sessionmgr/puppet_master/story_puppet_master_impl.h
deleted file mode 100644
index f9a0b09..0000000
--- a/bin/sessionmgr/puppet_master/story_puppet_master_impl.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_STORY_PUPPET_MASTER_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_STORY_PUPPET_MASTER_IMPL_H_
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-namespace modular {
-
-class SessionStorage;
-class StoryCommandExecutor;
-
-// An implementation of fuchsia::modular::StoryPuppetMaster which delegates
-// story command execution to a StoryCommandExecutor.
-class StoryPuppetMasterImpl : public fuchsia::modular::StoryPuppetMaster {
- public:
- StoryPuppetMasterImpl(std::string story_name,
- OperationContainer* operations,
- SessionStorage* session_storage,
- StoryCommandExecutor* executor);
- ~StoryPuppetMasterImpl() override;
-
- private:
- // |StoryPuppetMaster|
- void Enqueue(
- std::vector<fuchsia::modular::StoryCommand> commands) override;
-
- // |StoryPuppetMaster|
- void Execute(ExecuteCallback done) override;
-
- // |StoryPuppetMaster|
- void SetCreateOptions(fuchsia::modular::StoryOptions story_options) override;
-
- std::string story_name_;
- SessionStorage* const session_storage_; // Not owned.
- StoryCommandExecutor* const executor_; // Not owned.
-
- std::vector<fuchsia::modular::StoryCommand> enqueued_commands_;
-
- OperationContainer* const operations_; // Not owned.
-
- fuchsia::modular::StoryOptions story_options_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryPuppetMasterImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_PUPPET_MASTER_STORY_PUPPET_MASTER_IMPL_H_
diff --git a/bin/sessionmgr/session_ctl.cc b/bin/sessionmgr/session_ctl.cc
deleted file mode 100644
index 24adef7..0000000
--- a/bin/sessionmgr/session_ctl.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fs/service.h>
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/puppet_master_impl.h"
-#include "peridot/bin/sessionmgr/session_ctl.h"
-
-namespace modular {
-
-// Directory layout:
-//
-// puppet_master - fuchsia::modular::PuppetMaster service
-SessionCtl::SessionCtl(fbl::RefPtr<fs::PseudoDir> dir,
- const std::string& entry_name,
- PuppetMasterImpl* const puppet_master_impl)
- : dir_(dir),
- entry_name_(entry_name),
- puppet_master_impl_(puppet_master_impl) {
- auto ctl_dir = fbl::AdoptRef(new fs::PseudoDir());
- ctl_dir->AddEntry(
- fuchsia::modular::PuppetMaster::Name_,
- fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
- fidl::InterfaceRequest<fuchsia::modular::PuppetMaster> request(
- std::move(channel));
- puppet_master_impl_->Connect(std::move(request));
- return ZX_OK;
- })));
-
- auto status = dir_->AddEntry(entry_name_, ctl_dir);
- FXL_DCHECK(status == ZX_OK);
-}
-
-SessionCtl::~SessionCtl() {
- auto status = dir_->RemoveEntry(entry_name_);
- FXL_DCHECK(status == ZX_OK);
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/session_ctl.h b/bin/sessionmgr/session_ctl.h
deleted file mode 100644
index a1c4cdc..0000000
--- a/bin/sessionmgr/session_ctl.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_SESSION_CTL_H_
-#define PERIDOT_BIN_SESSIONMGR_SESSION_CTL_H_
-
-#include <fs/pseudo-dir.h>
-#include <string>
-
-#include "fbl/ref_ptr.h"
-
-namespace modular {
-
-class PuppetMasterImpl;
-
-// Builds a pseudo-directory for session inspection and control for debug and
-// developer tools.
-class SessionCtl {
- public:
- // Constructs a SessionCtl and adds an entry to |dir| under |entry_name|. The
- // entry is removed when destructed.
- //
- // |puppet_master_impl| is not owned and must outlive *this.
- SessionCtl(fbl::RefPtr<fs::PseudoDir> dir, const std::string& entry_name,
- PuppetMasterImpl* puppet_master_impl);
- ~SessionCtl();
-
- private:
- fbl::RefPtr<fs::PseudoDir> dir_;
- const std::string entry_name_;
-
- PuppetMasterImpl* const puppet_master_impl_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_SESSION_CTL_H_
diff --git a/bin/sessionmgr/sessionmgr.cc b/bin/sessionmgr/sessionmgr.cc
deleted file mode 100644
index 384a212..0000000
--- a/bin/sessionmgr/sessionmgr.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/split_string.h>
-#include <trace-provider/provider.h>
-
-#include "peridot/bin/basemgr/cobalt/cobalt.h"
-#include "peridot/bin/sessionmgr/sessionmgr_impl.h"
-
-fit::deferred_action<fit::closure> SetupCobalt(
- const bool disable_statistics, async_dispatcher_t* dispatcher,
- component::StartupContext* const startup_context) {
- if (disable_statistics) {
- return fit::defer<fit::closure>([] {});
- }
- return modular::InitializeCobalt(dispatcher, startup_context);
-}
-
-int main(int argc, const char** argv) {
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
-
- modular::SessionmgrImpl::Options opts;
- opts.test = command_line.HasOption("test");
- opts.use_memfs_for_ledger = command_line.HasOption("use_memfs_for_ledger");
- opts.no_cloud_provider_for_ledger =
- command_line.HasOption("no_cloud_provider_for_ledger");
-
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- trace::TraceProvider trace_provider(loop.dispatcher());
- std::unique_ptr<component::StartupContext> context =
- component::StartupContext::CreateFromStartupInfo();
-
- auto cobalt_cleanup =
- SetupCobalt(opts.test, std::move(loop.dispatcher()), context.get());
-
- auto startup_agents = fxl::SplitStringCopy(
- command_line.GetOptionValueWithDefault("startup_agents", ""), ",",
- fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
- auto session_agents = fxl::SplitStringCopy(
- command_line.GetOptionValueWithDefault("session_agents", ""), ",",
- fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
-
- for (const auto& startup_agent : startup_agents) {
- opts.startup_agents.push_back(startup_agent);
- }
- for (const auto& session_agent : session_agents) {
- opts.session_agents.push_back(session_agent);
- }
-
- modular::AppDriver<modular::SessionmgrImpl> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<modular::SessionmgrImpl>(context.get(), opts),
- [&loop, &cobalt_cleanup] {
- cobalt_cleanup.call();
- loop.Quit();
- });
-
- loop.Run();
- return 0;
-}
diff --git a/bin/sessionmgr/sessionmgr_impl.cc b/bin/sessionmgr/sessionmgr_impl.cc
deleted file mode 100644
index 5abe13c..0000000
--- a/bin/sessionmgr/sessionmgr_impl.cc
+++ /dev/null
@@ -1,950 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/sessionmgr_impl.h"
-
-#include <fcntl.h>
-#include <memory>
-#include <string>
-
-#include <fuchsia/ledger/cloud/firestore/cpp/fidl.h>
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/fsl/io/fd.h>
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/basemgr/cobalt/cobalt.h"
-#include "peridot/bin/sessionmgr/component_context_impl.h"
-#include "peridot/bin/sessionmgr/device_map_impl.h"
-#include "peridot/bin/sessionmgr/focus.h"
-#include "peridot/bin/sessionmgr/message_queue/message_queue_manager.h"
-#include "peridot/bin/sessionmgr/presentation_provider.h"
-#include "peridot/bin/sessionmgr/puppet_master/make_production_impl.h"
-#include "peridot/bin/sessionmgr/puppet_master/puppet_master_impl.h"
-#include "peridot/bin/sessionmgr/puppet_master/story_command_executor.h"
-#include "peridot/bin/sessionmgr/session_ctl.h"
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-#include "peridot/bin/sessionmgr/story_runner/link_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/story_provider_impl.h"
-#include "peridot/lib/common/names.h"
-#include "peridot/lib/common/teardown.h"
-#include "peridot/lib/common/xdr.h"
-#include "peridot/lib/device_info/device_info.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/environment.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/ledger_client/constants.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/ledger_client/status.h"
-#include "peridot/lib/module_manifest/module_facet_reader_impl.h"
-
-namespace modular {
-
-namespace {
-
-constexpr char kAppId[] = "modular_sessionmgr";
-
-constexpr char kMaxwellComponentNamespace[] = "maxwell";
-constexpr char kMaxwellUrl[] = "maxwell";
-
-constexpr char kContextEngineUrl[] =
- "fuchsia-pkg://fuchsia.com/context_engine#meta/context_engine.cmx";
-constexpr char kContextEngineComponentNamespace[] = "context_engine";
-
-constexpr char kModuleResolverUrl[] =
- "fuchsia-pkg://fuchsia.com/module_resolver#meta/module_resolver.cmx";
-
-constexpr char kUserEnvironmentLabelPrefix[] = "user-";
-
-constexpr char kMessageQueuePath[] = "/data/MESSAGE_QUEUES/v1/";
-
-constexpr char kSessionShellComponentNamespace[] = "user-shell-namespace";
-constexpr char kSessionShellLinkName[] = "user-shell-link";
-
-constexpr char kClipboardAgentUrl[] =
- "fuchsia-pkg://fuchsia.com/clipboard_agent#meta/clipboard_agent.cmx";
-
-constexpr char kLedgerRepositoryDirectory[] = "/data/LEDGER";
-
-// The name in the outgoing debug directory (hub) for developer session control
-// services.
-constexpr char kSessionCtlDir[] = "sessionctl";
-
-fuchsia::ledger::cloud::firestore::Config GetLedgerFirestoreConfig() {
- fuchsia::ledger::cloud::firestore::Config config;
- config.server_id = kFirebaseProjectId;
- config.api_key = kFirebaseApiKey;
- return config;
-}
-
-std::string GetAccountId(const fuchsia::modular::auth::AccountPtr& account) {
- return !account ? "GUEST" : account->id;
-}
-
-// Creates a function that can be used as termination action passed to AtEnd(),
-// which when called invokes the reset() method on the object pointed to by the
-// argument. Used to reset() fidl pointers and std::unique_ptr<>s fields.
-template <typename X>
-std::function<void(std::function<void()>)> Reset(
- std::unique_ptr<X>* const field) {
- return [field](std::function<void()> cont) {
- field->reset();
- cont();
- };
-}
-
-template <typename X>
-std::function<void(std::function<void()>)> Reset(
- fidl::InterfacePtr<X>* const field) {
- return [field](std::function<void()> cont) {
- field->Unbind();
- cont();
- };
-}
-
-// Creates a function that can be used as termination action passed to AtEnd(),
-// which when called asynchronously invokes the Teardown() method on the object
-// pointed to by the argument. Used to teardown AppClient and AsyncHolder
-// members.
-template <typename X>
-std::function<void(std::function<void()>)> Teardown(const zx::duration timeout,
- const char* const message,
- X* const field) {
- return [timeout, message, field](std::function<void()> cont) {
- field->Teardown(timeout, [message, cont] {
- if (message) {
- FXL_DLOG(INFO) << "- " << message << " down.";
- }
- cont();
- });
- };
-}
-
-} // namespace
-
-class SessionmgrImpl::PresentationProviderImpl : public PresentationProvider {
- public:
- PresentationProviderImpl(SessionmgrImpl* const impl) : impl_(impl) {}
- ~PresentationProviderImpl() override = default;
-
- private:
- // |PresentationProvider|
- void GetPresentation(fidl::StringPtr story_id,
- fidl::InterfaceRequest<fuchsia::ui::policy::Presentation>
- request) override {
- if (impl_->session_shell_app_) {
- fuchsia::modular::SessionShellPresentationProviderPtr provider;
- impl_->session_shell_app_->services().ConnectToService(
- provider.NewRequest());
- provider->GetPresentation(std::move(story_id), std::move(request));
- }
- }
-
- void WatchVisualState(
- fidl::StringPtr story_id,
- fidl::InterfaceHandle<fuchsia::modular::StoryVisualStateWatcher> watcher)
- override {
- if (impl_->session_shell_app_) {
- fuchsia::modular::SessionShellPresentationProviderPtr provider;
- impl_->session_shell_app_->services().ConnectToService(
- provider.NewRequest());
- provider->WatchVisualState(std::move(story_id), std::move(watcher));
- }
- }
-
- SessionmgrImpl* const impl_;
-};
-
-SessionmgrImpl::SessionmgrImpl(component::StartupContext* const startup_context,
- const Options& options)
- : startup_context_(startup_context),
- options_(options),
- story_provider_impl_("StoryProviderImpl"),
- agent_runner_("AgentRunner") {
- startup_context_->outgoing()
- .AddPublicService<fuchsia::modular::internal::Sessionmgr>(
- [this](fidl::InterfaceRequest<fuchsia::modular::internal::Sessionmgr>
- request) {
- bindings_.AddBinding(this, std::move(request));
- });
-}
-
-SessionmgrImpl::~SessionmgrImpl() = default;
-
-void SessionmgrImpl::Initialize(
- fuchsia::modular::auth::AccountPtr account,
- fuchsia::modular::AppConfig session_shell,
- fuchsia::modular::AppConfig story_shell,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> agent_token_manager,
- fidl::InterfaceHandle<fuchsia::modular::internal::UserContext> user_context,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request) {
- // This is called in the service connection factory callbacks for session
- // shell (see how RunSessionShell() initializes session_shell_services_) to
- // lazily initialize the following services only once they are requested
- // for the first time.
- finish_initialization_ =
- [this, called = false, session_shell_url = session_shell.url,
- ledger_token_manager = std::move(ledger_token_manager),
- story_shell = std::move(story_shell)]() mutable {
- if (called) {
- return;
- }
- called = true;
-
- InitializeLedger(std::move(ledger_token_manager));
- InitializeDeviceMap();
- InitializeMessageQueueManager();
- InitializeMaxwellAndModular(session_shell_url, std::move(story_shell));
- ConnectSessionShellToStoryProvider();
- AtEnd([this](std::function<void()> cont) {
- TerminateSessionShell(cont);
- });
- InitializeClipboard();
- ReportEvent(ModularEvent::BOOTED_TO_SESSIONMGR);
- };
-
- InitializeUser(std::move(account), std::move(agent_token_manager),
- std::move(user_context));
- InitializeSessionShell(
- std::move(session_shell),
- zx::eventpair(view_owner_request.TakeChannel().release()));
-}
-
-void SessionmgrImpl::ConnectSessionShellToStoryProvider() {
- fuchsia::modular::SessionShellPtr session_shell;
- session_shell_app_->services().ConnectToService(session_shell.NewRequest());
- story_provider_impl_->SetSessionShell(std::move(session_shell));
-}
-
-void SessionmgrImpl::InitializeUser(
- fuchsia::modular::auth::AccountPtr account,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> agent_token_manager,
- fidl::InterfaceHandle<fuchsia::modular::internal::UserContext>
- user_context) {
- agent_token_manager_ = agent_token_manager.Bind();
- AtEnd(Reset(&agent_token_manager_));
-
- user_context_ = user_context.Bind();
- AtEnd(Reset(&user_context_));
-
- account_ = std::move(account);
- AtEnd(Reset(&account_));
-
- static const auto* const kEnvServices = new std::vector<std::string>{
- fuchsia::modular::DeviceMap::Name_, fuchsia::modular::Clipboard::Name_};
- user_environment_ = std::make_unique<Environment>(
- startup_context_->environment(),
- std::string(kUserEnvironmentLabelPrefix) + GetAccountId(account_),
- *kEnvServices,
- /* kill_on_oom = */ true);
- AtEnd(Reset(&user_environment_));
-}
-
-zx::channel SessionmgrImpl::GetLedgerRepositoryDirectory() {
- if (options_.use_memfs_for_ledger) {
- FXL_DCHECK(!memfs_for_ledger_)
- << "An existing memfs for the Ledger has already been initialized.";
- FXL_LOG(INFO) << "Using memfs-backed storage for the ledger.";
- memfs_for_ledger_ = std::make_unique<scoped_tmpfs::ScopedTmpFS>();
- AtEnd(Reset(&memfs_for_ledger_));
-
- return fsl::CloneChannelFromFileDescriptor(memfs_for_ledger_->root_fd());
- }
- if (!files::CreateDirectory(kLedgerRepositoryDirectory)) {
- FXL_LOG(ERROR) << "Unable to create directory at "
- << kLedgerRepositoryDirectory;
- return zx::channel();
- }
- fxl::UniqueFD dir(open(kLedgerRepositoryDirectory, O_PATH));
- if (!dir.is_valid()) {
- FXL_LOG(ERROR) << "Unable to open directory at "
- << kLedgerRepositoryDirectory << ". errno: " << errno;
- return zx::channel();
- }
-
- return fsl::CloneChannelFromFileDescriptor(dir.get());
-}
-
-void SessionmgrImpl::InitializeLedger(
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager) {
- fuchsia::modular::AppConfig ledger_config;
- ledger_config.url = kLedgerAppUrl;
-
- ledger_app_ =
- std::make_unique<AppClient<fuchsia::ledger::internal::LedgerController>>(
- user_environment_->GetLauncher(), std::move(ledger_config), "",
- nullptr);
- ledger_app_->SetAppErrorHandler([this] {
- FXL_LOG(ERROR) << "Ledger seems to have crashed unexpectedly." << std::endl
- << "CALLING Logout() DUE TO UNRECOVERABLE LEDGER ERROR.";
- Logout();
- });
- AtEnd(Teardown(kBasicTimeout, "Ledger", ledger_app_.get()));
-
- fuchsia::ledger::cloud::CloudProviderPtr cloud_provider;
- std::string ledger_user_id;
- if (account_ && !options_.no_cloud_provider_for_ledger) {
- // If not running in Guest mode, spin up a cloud provider for Ledger to use
- // for syncing.
- fuchsia::modular::AppConfig cloud_provider_config;
- cloud_provider_config.url = kCloudProviderFirestoreAppUrl;
- cloud_provider_app_ =
- std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- user_environment_->GetLauncher(), std::move(cloud_provider_config));
- cloud_provider_app_->services().ConnectToService(
- cloud_provider_factory_.NewRequest());
-
- cloud_provider = GetCloudProvider(std::move(ledger_token_manager));
- ledger_user_id = account_->profile_id;
-
- // TODO(mesch): Teardown cloud_provider_app_ ?
- }
-
- ledger_repository_factory_.set_error_handler([this](zx_status_t status) {
- FXL_LOG(ERROR) << "LedgerRepositoryFactory.GetRepository() failed: "
- << LedgerEpitaphToString(status) << std::endl
- << "CALLING Logout() DUE TO UNRECOVERABLE LEDGER ERROR.";
- Logout();
- });
- ledger_app_->services().ConnectToService(
- ledger_repository_factory_.NewRequest());
- AtEnd(Reset(&ledger_repository_factory_));
-
- // The directory "/data" is the data root "/data/LEDGER" that the ledger app
- // client is configured to.
- ledger_repository_factory_->GetRepository(
- GetLedgerRepositoryDirectory(), std::move(cloud_provider), ledger_user_id,
- ledger_repository_.NewRequest());
-
- // If ledger state is erased from underneath us (happens when the cloud store
- // is cleared), ledger will close the connection to |ledger_repository_|.
- ledger_repository_.set_error_handler([this](zx_status_t status) {
- FXL_LOG(ERROR) << "LedgerRepository disconnected with epitaph: "
- << LedgerEpitaphToString(status) << std::endl
- << "CALLING Logout() DUE TO UNRECOVERABLE LEDGER ERROR.";
- Logout();
- });
- AtEnd(Reset(&ledger_repository_));
-
- ledger_client_ =
- std::make_unique<LedgerClient>(ledger_repository_.get(), kAppId, [this] {
- FXL_LOG(ERROR) << "CALLING Logout() DUE TO UNRECOVERABLE LEDGER ERROR.";
- Logout();
- });
- AtEnd(Reset(&ledger_client_));
-}
-
-void SessionmgrImpl::InitializeDeviceMap() {
- // fuchsia::modular::DeviceMap service
- const std::string device_id = LoadDeviceID(GetAccountId(account_));
- device_name_ = LoadDeviceName(GetAccountId(account_));
- const std::string device_profile = LoadDeviceProfile();
-
- device_map_impl_ = std::make_unique<DeviceMapImpl>(
- device_name_, device_id, device_profile, ledger_client_.get(),
- fuchsia::ledger::PageId());
- user_environment_->AddService<fuchsia::modular::DeviceMap>(
- [this](fidl::InterfaceRequest<fuchsia::modular::DeviceMap> request) {
- if (terminating_) {
- return;
- }
- // device_map_impl_ may be reset before user_environment_.
- if (device_map_impl_) {
- device_map_impl_->Connect(std::move(request));
- }
- });
- AtEnd(Reset(&device_map_impl_));
-}
-
-void SessionmgrImpl::InitializeClipboard() {
- agent_runner_->ConnectToAgent(kAppId, kClipboardAgentUrl,
- services_from_clipboard_agent_.NewRequest(),
- clipboard_agent_controller_.NewRequest());
- user_environment_->AddService<fuchsia::modular::Clipboard>(
- [this](fidl::InterfaceRequest<fuchsia::modular::Clipboard> request) {
- if (terminating_) {
- return;
- }
- services_from_clipboard_agent_->ConnectToService(
- fuchsia::modular::Clipboard::Name_, request.TakeChannel());
- });
-}
-
-void SessionmgrImpl::InitializeMessageQueueManager() {
- std::string message_queue_path = kMessageQueuePath;
- message_queue_path.append(GetAccountId(account_));
- if (!files::CreateDirectory(message_queue_path)) {
- FXL_LOG(FATAL) << "Failed to create message queue directory: "
- << message_queue_path;
- }
-
- message_queue_manager_ = std::make_unique<MessageQueueManager>(
- ledger_client_.get(), MakePageId(kMessageQueuePageId),
- message_queue_path);
- AtEnd(Reset(&message_queue_manager_));
-}
-
-void SessionmgrImpl::InitializeMaxwellAndModular(
- const fidl::StringPtr& session_shell_url,
- fuchsia::modular::AppConfig story_shell) {
- // NOTE: There is an awkward service exchange here between
- // AgentRunner, StoryProviderImpl, FocusHandler, VisibleStoriesHandler.
- //
- // AgentRunner needs a UserIntelligenceProvider. Initializing the
- // Maxwell process UserIntelligenceProvider requires a ComponentContext.
- // ComponentContext requires an AgentRunner, which creates a circular
- // dependency.
- //
- // Because of FIDL late bindings, we can get around this by creating a new
- // InterfaceRequest here (|intelligence_provider_request|), making the
- // InterfacePtr a valid proxy to be passed to AgentRunner and
- // StoryProviderImpl, even though it won't be bound to a real implementation
- // (provided by Maxwell) until later. It works, but it's not a good pattern.
-
- fidl::InterfaceHandle<fuchsia::modular::ContextEngine> context_engine;
- auto context_engine_request = context_engine.NewRequest();
-
- fidl::InterfaceHandle<fuchsia::modular::StoryProvider> story_provider;
- auto story_provider_request = story_provider.NewRequest();
-
- fidl::InterfaceHandle<fuchsia::modular::FocusProvider> focus_provider_maxwell;
- auto focus_provider_request_maxwell = focus_provider_maxwell.NewRequest();
-
- fidl::InterfaceHandle<fuchsia::modular::PuppetMaster> puppet_master;
- auto puppet_master_request = puppet_master.NewRequest();
-
- fidl::InterfaceHandle<fuchsia::modular::VisibleStoriesProvider>
- visible_stories_provider;
- auto visible_stories_provider_request = visible_stories_provider.NewRequest();
-
- user_intelligence_provider_impl_.reset(new UserIntelligenceProviderImpl(
- startup_context_, std::move(context_engine),
- [this](fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesProvider>
- request) {
- if (terminating_) {
- return;
- }
- visible_stories_handler_->AddProviderBinding(std::move(request));
- },
- [this](fidl::InterfaceRequest<fuchsia::modular::StoryProvider> request) {
- if (terminating_) {
- return;
- }
- story_provider_impl_->Connect(std::move(request));
- },
- [this](fidl::InterfaceRequest<fuchsia::modular::FocusProvider> request) {
- if (terminating_) {
- return;
- }
- focus_handler_->AddProviderBinding(std::move(request));
- },
- [this](fidl::InterfaceRequest<fuchsia::modular::PuppetMaster> request) {
- if (terminating_) {
- return;
- }
- puppet_master_impl_->Connect(std::move(request));
- }));
- AtEnd(Reset(&user_intelligence_provider_impl_));
-
- entity_provider_runner_ = std::make_unique<EntityProviderRunner>(
- static_cast<EntityProviderLauncher*>(this));
- AtEnd(Reset(&entity_provider_runner_));
-
- agent_runner_storage_ = std::make_unique<AgentRunnerStorageImpl>(
- ledger_client_.get(), MakePageId(kAgentRunnerPageId));
- AtEnd(Reset(&agent_runner_storage_));
-
- agent_runner_.reset(new AgentRunner(
- user_environment_->GetLauncher(), message_queue_manager_.get(),
- ledger_repository_.get(), agent_runner_storage_.get(),
- agent_token_manager_.get(), user_intelligence_provider_impl_.get(),
- entity_provider_runner_.get()));
- AtEnd(Teardown(kAgentRunnerTimeout, "AgentRunner", &agent_runner_));
-
- maxwell_component_context_bindings_ = std::make_unique<
- fidl::BindingSet<fuchsia::modular::ComponentContext,
- std::unique_ptr<ComponentContextImpl>>>();
- AtEnd(Reset(&maxwell_component_context_bindings_));
-
- ComponentContextInfo component_context_info{
- message_queue_manager_.get(), agent_runner_.get(),
- ledger_repository_.get(), entity_provider_runner_.get()};
- // Start kContextEngineUrl.
- {
- context_engine_ns_services_.AddService<fuchsia::modular::ComponentContext>(
- [this, component_context_info](
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext>
- request) {
- maxwell_component_context_bindings_->AddBinding(
- std::make_unique<ComponentContextImpl>(
- component_context_info, kContextEngineComponentNamespace,
- kContextEngineUrl, kContextEngineUrl),
- std::move(request));
- });
- auto service_list = fuchsia::sys::ServiceList::New();
- service_list->names.push_back(fuchsia::modular::ComponentContext::Name_);
- context_engine_ns_services_.AddBinding(service_list->provider.NewRequest());
-
- fuchsia::modular::AppConfig context_engine_config;
- context_engine_config.url = kContextEngineUrl;
-
- context_engine_app_ =
- std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- user_environment_->GetLauncher(), std::move(context_engine_config),
- "" /* data_origin */, std::move(service_list));
- context_engine_app_->services().ConnectToService(
- std::move(context_engine_request));
- AtEnd(Reset(&context_engine_app_));
- AtEnd(Teardown(kBasicTimeout, "ContextEngine", context_engine_app_.get()));
- }
-
- auto maxwell_app_component_context =
- maxwell_component_context_bindings_->AddBinding(
- std::make_unique<ComponentContextImpl>(component_context_info,
- kMaxwellComponentNamespace,
- kMaxwellUrl, kMaxwellUrl));
-
- user_intelligence_provider_impl_->StartAgents(
- std::move(maxwell_app_component_context), options_.session_agents,
- options_.startup_agents);
-
- // Setup for kModuleResolverUrl
- {
- module_resolver_ns_services_.AddService<
- fuchsia::modular::IntelligenceServices>(
- [this](fidl::InterfaceRequest<fuchsia::modular::IntelligenceServices>
- request) {
- fuchsia::modular::ComponentScope component_scope;
- component_scope.set_global_scope(fuchsia::modular::GlobalScope());
- fidl::InterfaceHandle<fuchsia::modular::IntelligenceServices>
- intelligence_services;
- if (user_intelligence_provider_impl_) {
- user_intelligence_provider_impl_->GetComponentIntelligenceServices(
- std::move(component_scope), std::move(request));
- }
- });
- module_resolver_ns_services_.AddService<fuchsia::modular::ComponentContext>(
- [this, component_context_info](
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext>
- request) {
- maxwell_component_context_bindings_->AddBinding(
- std::make_unique<ComponentContextImpl>(
- component_context_info, kMaxwellComponentNamespace,
- kModuleResolverUrl, kModuleResolverUrl),
- std::move(request));
- });
- auto service_list = fuchsia::sys::ServiceList::New();
- service_list->names.push_back(
- fuchsia::modular::IntelligenceServices::Name_);
- service_list->names.push_back(fuchsia::modular::ComponentContext::Name_);
- module_resolver_ns_services_.AddBinding(
- service_list->provider.NewRequest());
-
- fuchsia::modular::AppConfig module_resolver_config;
- module_resolver_config.url = kModuleResolverUrl;
- if (options_.test) {
- module_resolver_config.args.push_back("--test");
- }
- // For now, we want data_origin to be "", which uses our (parent process's)
- // /data. This is appropriate for the module_resolver. We can in the future
- // isolate the data it reads to a subdir of /data and map that in here.
- module_resolver_app_ =
- std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- user_environment_->GetLauncher(), std::move(module_resolver_config),
- "" /* data_origin */, std::move(service_list));
- AtEnd(Reset(&module_resolver_app_));
- AtEnd(Teardown(kBasicTimeout, "Resolver", module_resolver_app_.get()));
- }
-
- module_resolver_app_->services().ConnectToService(
- module_resolver_service_.NewRequest());
- AtEnd(Reset(&module_resolver_service_));
- // End kModuleResolverUrl
-
- session_shell_component_context_impl_ =
- std::make_unique<ComponentContextImpl>(
- component_context_info, kSessionShellComponentNamespace,
- session_shell_url, session_shell_url);
-
- AtEnd(Reset(&session_shell_component_context_impl_));
-
- fidl::InterfacePtr<fuchsia::modular::FocusProvider>
- focus_provider_story_provider;
- auto focus_provider_request_story_provider =
- focus_provider_story_provider.NewRequest();
-
- presentation_provider_impl_ =
- std::make_unique<PresentationProviderImpl>(this);
- AtEnd(Reset(&presentation_provider_impl_));
-
- // We create |story_provider_impl_| after |agent_runner_| so
- // story_provider_impl_ is terminated before agent_runner_, which will cause
- // all modules to be terminated before agents are terminated. Agents must
- // outlive the stories which contain modules that are connected to those
- // agents.
- session_storage_ = std::make_unique<SessionStorage>(
- ledger_client_.get(), fuchsia::ledger::PageId());
-
- module_facet_reader_.reset(new ModuleFacetReaderImpl(
- startup_context_->ConnectToEnvironmentService<fuchsia::sys::Loader>()));
-
- story_provider_impl_.reset(new StoryProviderImpl(
- user_environment_.get(), device_map_impl_->current_device_id(),
- session_storage_.get(), std::move(story_shell), component_context_info,
- std::move(focus_provider_story_provider),
- user_intelligence_provider_impl_.get(), module_resolver_service_.get(),
- entity_provider_runner_.get(), module_facet_reader_.get(),
- presentation_provider_impl_.get(),
- startup_context_
- ->ConnectToEnvironmentService<fuchsia::ui::viewsv1::ViewSnapshot>(),
- options_.test));
- story_provider_impl_->Connect(std::move(story_provider_request));
-
- AtEnd(
- Teardown(kStoryProviderTimeout, "StoryProvider", &story_provider_impl_));
-
- fuchsia::modular::FocusProviderPtr focus_provider_puppet_master;
- auto focus_provider_request_puppet_master =
- focus_provider_puppet_master.NewRequest();
- fuchsia::modular::StoryProviderPtr story_provider_puppet_master;
- auto story_provider_puppet_master_request =
- story_provider_puppet_master.NewRequest();
-
- // Initialize the PuppetMaster.
- // TODO(miguelfrde): there's no clean runtime interface we can inject to
- // puppet master. Hence, for now we inject this function to be able to focus
- // mods. Eventually we want to have a StoryRuntime and SessionRuntime classes
- // similar to Story/SessionStorage but for runtime management.
- auto module_focuser =
- [story_provider = std::move(story_provider_puppet_master)](
- std::string story_id, std::vector<std::string> mod_name) {
- fuchsia::modular::StoryControllerPtr story_controller;
- story_provider->GetController(story_id, story_controller.NewRequest());
-
- fuchsia::modular::ModuleControllerPtr module_controller;
- story_controller->GetModuleController(std::move(mod_name),
- module_controller.NewRequest());
- module_controller->Focus();
- };
- AtEnd(Reset(&session_storage_));
- story_command_executor_ = MakeProductionStoryCommandExecutor(
- session_storage_.get(), std::move(focus_provider_puppet_master),
- module_resolver_service_.get(), entity_provider_runner_.get(),
- std::move(module_focuser));
- story_provider_impl_->Connect(
- std::move(story_provider_puppet_master_request));
- puppet_master_impl_ = std::make_unique<PuppetMasterImpl>(
- session_storage_.get(), story_command_executor_.get());
- puppet_master_impl_->Connect(std::move(puppet_master_request));
-
- session_ctl_ =
- std::make_unique<SessionCtl>(startup_context_->outgoing().debug_dir(),
- kSessionCtlDir, puppet_master_impl_.get());
-
- AtEnd(Reset(&story_command_executor_));
- AtEnd(Reset(&puppet_master_impl_));
- AtEnd(Reset(&session_ctl_));
-
- focus_handler_ = std::make_unique<FocusHandler>(
- device_map_impl_->current_device_id(), ledger_client_.get(),
- fuchsia::ledger::PageId());
- focus_handler_->AddProviderBinding(std::move(focus_provider_request_maxwell));
- focus_handler_->AddProviderBinding(
- std::move(focus_provider_request_story_provider));
- focus_handler_->AddProviderBinding(
- std::move(focus_provider_request_puppet_master));
-
- visible_stories_handler_ = std::make_unique<VisibleStoriesHandler>();
- visible_stories_handler_->AddProviderBinding(
- std::move(visible_stories_provider_request));
-
- AtEnd(Reset(&focus_handler_));
- AtEnd(Reset(&visible_stories_handler_));
-}
-
-void SessionmgrImpl::InitializeSessionShell(
- fuchsia::modular::AppConfig session_shell, zx::eventpair view_token) {
- // We setup our own view and make the fuchsia::modular::SessionShell a child
- // of it.
- auto scenic =
- startup_context_
- ->ConnectToEnvironmentService<fuchsia::ui::scenic::Scenic>();
- scenic::ViewContext view_context = {
- .session_and_listener_request =
- scenic::CreateScenicSessionPtrAndListenerRequest(scenic.get()),
- .view_token = std::move(view_token),
- .startup_context = startup_context_,
- };
- session_shell_view_host_ =
- std::make_unique<ViewHost>(std::move(view_context));
- RunSessionShell(std::move(session_shell));
-}
-
-void SessionmgrImpl::RunSessionShell(
- fuchsia::modular::AppConfig session_shell_config) {
- // |session_shell_services_| is a ServiceProvider (aka a Directory) that
- // augments the session shell's namespace.
- //
- // |service_list| enumerates which services are made available to the session
- // shell.
- auto service_list = fuchsia::sys::ServiceList::New();
-
- service_list->names.push_back(fuchsia::modular::SessionShellContext::Name_);
- session_shell_services_.AddService<fuchsia::modular::SessionShellContext>(
- [this](auto request) {
- if (terminating_) {
- return;
- }
- finish_initialization_();
- session_shell_context_bindings_.AddBinding(this, std::move(request));
- });
-
- service_list->names.push_back(fuchsia::modular::ComponentContext::Name_);
- session_shell_services_.AddService<fuchsia::modular::ComponentContext>(
- [this](auto request) {
- if (terminating_) {
- return;
- }
- finish_initialization_();
- session_shell_component_context_impl_->Connect(std::move(request));
- });
-
- service_list->names.push_back(fuchsia::modular::PuppetMaster::Name_);
- session_shell_services_.AddService<fuchsia::modular::PuppetMaster>(
- [this](auto request) {
- if (terminating_) {
- return;
- }
- finish_initialization_();
- puppet_master_impl_->Connect(std::move(request));
- });
-
- service_list->names.push_back(fuchsia::modular::IntelligenceServices::Name_);
- session_shell_services_.AddService<fuchsia::modular::IntelligenceServices>(
- [this](auto request) {
- if (terminating_) {
- return;
- }
- finish_initialization_();
- fuchsia::modular::ComponentScope component_scope;
- component_scope.set_global_scope(fuchsia::modular::GlobalScope());
- user_intelligence_provider_impl_->GetComponentIntelligenceServices(
- std::move(component_scope), std::move(request));
- });
-
- // The services in |session_shell_services_| are provided through the
- // connection held in |session_shell_service_provider| connected to
- // |session_shell_services_|.
- {
- fuchsia::sys::ServiceProviderPtr session_shell_service_provider;
- session_shell_services_.AddBinding(
- session_shell_service_provider.NewRequest());
- service_list->provider = std::move(session_shell_service_provider);
- }
-
- session_shell_app_ = std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- user_environment_->GetLauncher(), std::move(session_shell_config),
- /* data_origin = */ "", std::move(service_list));
-
- session_shell_app_->SetAppErrorHandler([this] {
- FXL_LOG(ERROR) << "Session Shell seems to have crashed unexpectedly."
- << " Logging out.";
- Logout();
- });
-
- fuchsia::ui::viewsv1token::ViewOwnerPtr view_owner;
- fuchsia::ui::viewsv1::ViewProviderPtr view_provider;
- session_shell_app_->services().ConnectToService(view_provider.NewRequest());
- view_provider->CreateView(view_owner.NewRequest(), nullptr);
- session_shell_view_host_->ConnectView(std::move(view_owner));
-}
-
-void SessionmgrImpl::TerminateSessionShell(const std::function<void()>& done) {
- session_shell_app_->Teardown(kBasicTimeout, [this, done] {
- session_shell_app_.reset();
- done();
- });
-}
-
-class SessionmgrImpl::SwapSessionShellOperation : public Operation<> {
- public:
- SwapSessionShellOperation(SessionmgrImpl* const sessionmgr_impl,
- fuchsia::modular::AppConfig session_shell_config,
- ResultCall result_call)
- : Operation("SessionmgrImpl::SwapSessionShellOperation",
- std::move(result_call)),
- sessionmgr_impl_(sessionmgr_impl),
- session_shell_config_(std::move(session_shell_config)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- sessionmgr_impl_->story_provider_impl_->StopAllStories([this, flow] {
- sessionmgr_impl_->TerminateSessionShell([this, flow] {
- sessionmgr_impl_->RunSessionShell(std::move(session_shell_config_));
- sessionmgr_impl_->ConnectSessionShellToStoryProvider();
- });
- });
- }
-
- SessionmgrImpl* const sessionmgr_impl_;
- fuchsia::modular::AppConfig session_shell_config_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SwapSessionShellOperation);
-};
-
-void SessionmgrImpl::SwapSessionShell(
- fuchsia::modular::AppConfig session_shell_config,
- SwapSessionShellCallback callback) {
- operation_queue_.Add(new SwapSessionShellOperation(
- this, std::move(session_shell_config), callback));
-}
-
-void SessionmgrImpl::Terminate(std::function<void()> done) {
- FXL_LOG(INFO) << "Sessionmgr::Terminate()";
- terminating_ = true;
- at_end_done_ = std::move(done);
-
- TerminateRecurse(at_end_.size() - 1);
-}
-
-void SessionmgrImpl::GetAccount(
- std::function<void(::std::unique_ptr<::fuchsia::modular::auth::Account>)>
- callback) {
- callback(fidl::Clone(account_));
-}
-
-void SessionmgrImpl::GetAgentProvider(
- fidl::InterfaceRequest<fuchsia::modular::AgentProvider> request) {
- agent_runner_->Connect(std::move(request));
-}
-
-void SessionmgrImpl::GetComponentContext(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request) {
- session_shell_component_context_impl_->Connect(std::move(request));
-}
-
-void SessionmgrImpl::GetDeviceName(
- std::function<void(::std::string)> callback) {
- callback(device_name_);
-}
-
-void SessionmgrImpl::GetFocusController(
- fidl::InterfaceRequest<fuchsia::modular::FocusController> request) {
- focus_handler_->AddControllerBinding(std::move(request));
-}
-
-void SessionmgrImpl::GetFocusProvider(
- fidl::InterfaceRequest<fuchsia::modular::FocusProvider> request) {
- focus_handler_->AddProviderBinding(std::move(request));
-}
-
-void SessionmgrImpl::GetLink(
- fidl::InterfaceRequest<fuchsia::modular::Link> request) {
- if (!session_shell_storage_) {
- session_shell_storage_ = std::make_unique<StoryStorage>(
- ledger_client_.get(), fuchsia::ledger::PageId());
- }
-
- fuchsia::modular::LinkPath link_path;
- link_path.module_path.resize(0);
- link_path.link_name = kSessionShellLinkName;
- auto impl = std::make_unique<LinkImpl>(session_shell_storage_.get(),
- std::move(link_path));
- session_shell_link_bindings_.AddBinding(std::move(impl), std::move(request));
-}
-
-void SessionmgrImpl::GetPresentation(
- fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request) {
- user_context_->GetPresentation(std::move(request));
-}
-
-void SessionmgrImpl::GetSpeechToText(
- fidl::InterfaceRequest<fuchsia::speech::SpeechToText> request) {
- user_intelligence_provider_impl_->GetSpeechToText(std::move(request));
-}
-
-void SessionmgrImpl::GetStoryProvider(
- fidl::InterfaceRequest<fuchsia::modular::StoryProvider> request) {
- story_provider_impl_->Connect(std::move(request));
-}
-
-void SessionmgrImpl::GetSuggestionProvider(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionProvider> request) {
- user_intelligence_provider_impl_->GetSuggestionProvider(std::move(request));
-}
-
-void SessionmgrImpl::GetVisibleStoriesController(
- fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesController>
- request) {
- visible_stories_handler_->AddControllerBinding(std::move(request));
-}
-
-void SessionmgrImpl::Logout() { user_context_->Logout(); }
-
-// |EntityProviderLauncher|
-void SessionmgrImpl::ConnectToEntityProvider(
- const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) {
- FXL_DCHECK(agent_runner_.get());
- agent_runner_->ConnectToEntityProvider(agent_url,
- std::move(entity_provider_request),
- std::move(agent_controller_request));
-}
-
-void SessionmgrImpl::ConnectToStoryEntityProvider(
- const std::string& story_id,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request) {
- story_provider_impl_->ConnectToStoryEntityProvider(
- story_id, std::move(entity_provider_request));
-}
-
-fuchsia::ledger::cloud::CloudProviderPtr SessionmgrImpl::GetCloudProvider(
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager) {
- FXL_CHECK(ledger_token_manager);
-
- fuchsia::ledger::cloud::CloudProviderPtr cloud_provider;
- auto cloud_provider_config = GetLedgerFirestoreConfig();
-
- cloud_provider_factory_->GetCloudProvider(
- std::move(cloud_provider_config), std::move(ledger_token_manager),
- cloud_provider.NewRequest(), [](fuchsia::ledger::cloud::Status status) {
- if (status != fuchsia::ledger::cloud::Status::OK) {
- FXL_LOG(ERROR) << "Failed to create a cloud provider: "
- << fidl::ToUnderlying(status);
- }
- });
- return cloud_provider;
-}
-
-void SessionmgrImpl::AtEnd(std::function<void(std::function<void()>)> action) {
- at_end_.emplace_back(std::move(action));
-}
-
-void SessionmgrImpl::TerminateRecurse(const int i) {
- if (i >= 0) {
- at_end_[i]([this, i] { TerminateRecurse(i - 1); });
- } else {
- FXL_LOG(INFO) << "Sessionmgr::Terminate(): done";
- at_end_done_();
- }
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/sessionmgr_impl.h b/bin/sessionmgr/sessionmgr_impl.h
deleted file mode 100644
index 19cc922..0000000
--- a/bin/sessionmgr/sessionmgr_impl.h
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_SESSIONMGR_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_SESSIONMGR_IMPL_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-#include <fuchsia/ledger/cloud/firestore/cpp/fidl.h>
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <fuchsia/speech/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <zx/eventpair.h>
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner_storage_impl.h"
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_launcher.h"
-#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h"
-#include "peridot/bin/sessionmgr/user_intelligence_provider_impl.h"
-#include "peridot/lib/common/async_holder.h"
-#include "peridot/lib/fidl/app_client.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/environment.h"
-#include "peridot/lib/fidl/view_host.h"
-#include "peridot/lib/module_manifest/module_facet_reader.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace modular {
-
-class AgentRunner;
-class ComponentContextImpl;
-class DeviceMapImpl;
-class FocusHandler;
-class LedgerClient;
-class LinkImpl;
-class MessageQueueManager;
-class PuppetMasterImpl;
-class SessionCtl;
-class SessionStorage;
-class StoryCommandExecutor;
-class StoryProviderImpl;
-class StoryStorage;
-class VisibleStoriesHandler;
-
-class SessionmgrImpl : fuchsia::modular::internal::Sessionmgr,
- fuchsia::modular::SessionShellContext,
- EntityProviderLauncher {
- public:
- struct Options {
- // Tells the sessionmgr whether it is running as a part of an integration
- // test.
- bool test;
- // Tells the sessionmgr whether it should host+pass a memfs-backed
- // directory to the ledger for the user's repository, or to use
- // /data/LEDGER.
- bool use_memfs_for_ledger;
-
- // If set, DO NOT pass a cloud provider to the ledger.
- bool no_cloud_provider_for_ledger;
-
- // Sessionmgr passes args startup agents and session agent to maxwell.
- std::vector<std::string> startup_agents;
- std::vector<std::string> session_agents;
- };
-
- SessionmgrImpl(component::StartupContext* startup_context,
- const Options& options);
- ~SessionmgrImpl() override;
-
- // |AppDriver| calls this.
- void Terminate(std::function<void()> done);
-
- private:
- // |Sessionmgr|
- void Initialize(
- fuchsia::modular::auth::AccountPtr account,
- fuchsia::modular::AppConfig session_shell,
- fuchsia::modular::AppConfig story_shell,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> agent_token_manager,
- fidl::InterfaceHandle<fuchsia::modular::internal::UserContext>
- user_context,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request) override;
-
- // |Sessionmgr|
- void SwapSessionShell(fuchsia::modular::AppConfig session_shell_config,
- SwapSessionShellCallback callback) override;
-
- // Sequence of Initialize() broken up into steps for clarity.
- void InitializeUser(
- fuchsia::modular::auth::AccountPtr account,
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> agent_token_manager,
- fidl::InterfaceHandle<fuchsia::modular::internal::UserContext>
- user_context);
- void InitializeLedger(
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager);
- void InitializeDeviceMap();
- void InitializeClipboard();
- void InitializeMessageQueueManager();
- void InitializeMaxwellAndModular(const fidl::StringPtr& session_shell_url,
- fuchsia::modular::AppConfig story_shell);
- void InitializeSessionShell(fuchsia::modular::AppConfig session_shell,
- zx::eventpair view_token);
-
- void RunSessionShell(fuchsia::modular::AppConfig session_shell);
- // This is a termination sequence that may be used with |AtEnd()|, but also
- // may be executed to terminate the currently running session shell.
- void TerminateSessionShell(const std::function<void()>& done);
-
- // Returns the file descriptor that backs the ledger repository directory for
- // the user.
- zx::channel GetLedgerRepositoryDirectory();
-
- // |fuchsia::modular::SessionShellContext|
- void GetAccount(
- std::function<void(::std::unique_ptr<::fuchsia::modular::auth::Account>)>
- callback) override;
- void GetAgentProvider(
- fidl::InterfaceRequest<fuchsia::modular::AgentProvider> request) override;
- void GetComponentContext(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request)
- override;
- void GetDeviceName(std::function<void(::std::string)> callback) override;
- void GetFocusController(
- fidl::InterfaceRequest<fuchsia::modular::FocusController> request)
- override;
- void GetFocusProvider(
- fidl::InterfaceRequest<fuchsia::modular::FocusProvider> request) override;
- void GetLink(fidl::InterfaceRequest<fuchsia::modular::Link> request) override;
- void GetPresentation(fidl::InterfaceRequest<fuchsia::ui::policy::Presentation>
- request) override;
- void GetSpeechToText(
- fidl::InterfaceRequest<fuchsia::speech::SpeechToText> request) override;
- void GetStoryProvider(
- fidl::InterfaceRequest<fuchsia::modular::StoryProvider> request) override;
- void GetSuggestionProvider(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionProvider> request)
- override;
- void GetVisibleStoriesController(
- fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesController>
- request) override;
- void Logout() override;
-
- // |EntityProviderLauncher|
- void ConnectToEntityProvider(
- const std::string& agent_url,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) override;
-
- // |EntityProviderLauncher|
- void ConnectToStoryEntityProvider(
- const std::string& story_id,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request) override;
-
- fuchsia::sys::ServiceProviderPtr GetServiceProvider(
- fuchsia::modular::AppConfig config);
- fuchsia::sys::ServiceProviderPtr GetServiceProvider(const std::string& url);
-
- fuchsia::ledger::cloud::CloudProviderPtr GetCloudProvider(
- fidl::InterfaceHandle<fuchsia::auth::TokenManager> ledger_token_manager);
-
- // Called during initialization. Schedules the given action to be executed
- // during termination. This allows to create something like an asynchronous
- // destructor at initialization time. The sequence of actions thus scheduled
- // is executed in reverse in Terminate().
- //
- // The AtEnd() calls for a field should happen next to the calls that
- // initialize the field, for the following reasons:
- //
- // 1. It ensures the termination sequence corresponds to the initialization
- // sequence.
- //
- // 2. It is easy to audit that there is a termination action for every
- // initialization that needs one.
- //
- // 3. Conditional initialization also omits the termination (such as for
- // agents that are not started when runnign a test).
- //
- // See also the Reset() and Teardown() functions in the .cc file.
- void AtEnd(std::function<void(std::function<void()>)> action);
-
- // Recursively execute the termiation steps scheduled by AtEnd(). The
- // execution steps are stored in at_end_.
- void TerminateRecurse(int i);
-
- void ConnectSessionShellToStoryProvider();
-
- component::StartupContext* const startup_context_;
- const Options options_;
- std::unique_ptr<scoped_tmpfs::ScopedTmpFS> memfs_for_ledger_;
-
- fidl::BindingSet<fuchsia::modular::internal::Sessionmgr> bindings_;
- component::ServiceProviderImpl session_shell_services_;
-
- fidl::BindingSet<fuchsia::modular::SessionShellContext>
- session_shell_context_bindings_;
-
- fuchsia::auth::TokenManagerPtr agent_token_manager_;
- fuchsia::modular::internal::UserContextPtr user_context_;
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> cloud_provider_app_;
- fuchsia::ledger::cloud::firestore::FactoryPtr cloud_provider_factory_;
- std::unique_ptr<AppClient<fuchsia::ledger::internal::LedgerController>>
- ledger_app_;
- fuchsia::ledger::internal::LedgerRepositoryFactoryPtr
- ledger_repository_factory_;
- fuchsia::ledger::internal::LedgerRepositoryPtr ledger_repository_;
- std::unique_ptr<LedgerClient> ledger_client_;
- // Provides services to the Ledger
- component::ServiceProviderImpl ledger_service_provider_;
-
- std::unique_ptr<Environment> user_environment_;
-
- fuchsia::modular::auth::AccountPtr account_;
-
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> context_engine_app_;
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> module_resolver_app_;
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> session_shell_app_;
- std::unique_ptr<ViewHost> session_shell_view_host_;
-
- std::unique_ptr<EntityProviderRunner> entity_provider_runner_;
- std::unique_ptr<ModuleFacetReader> module_facet_reader_;
-
- std::unique_ptr<SessionStorage> session_storage_;
- AsyncHolder<StoryProviderImpl> story_provider_impl_;
- std::unique_ptr<MessageQueueManager> message_queue_manager_;
- std::unique_ptr<AgentRunnerStorage> agent_runner_storage_;
- AsyncHolder<AgentRunner> agent_runner_;
- std::unique_ptr<DeviceMapImpl> device_map_impl_;
- std::string device_name_;
-
- std::unique_ptr<StoryCommandExecutor> story_command_executor_;
- std::unique_ptr<PuppetMasterImpl> puppet_master_impl_;
-
- std::unique_ptr<SessionCtl> session_ctl_;
-
- // Services we provide to |context_engine_app_|.
- component::ServiceProviderImpl context_engine_ns_services_;
-
- // These component contexts are supplied to:
- // - the user intelligence provider so it can run agents and create message
- // queues
- // - |context_engine_app_| so it can resolve entity references
- // - |modular resolver_service_| so it can resolve entity references
- std::unique_ptr<fidl::BindingSet<fuchsia::modular::ComponentContext,
- std::unique_ptr<ComponentContextImpl>>>
- maxwell_component_context_bindings_;
-
- std::unique_ptr<UserIntelligenceProviderImpl>
- user_intelligence_provider_impl_;
-
- // Services we provide to the module resolver's namespace.
- component::ServiceProviderImpl module_resolver_ns_services_;
- fuchsia::modular::ModuleResolverPtr module_resolver_service_;
-
- class PresentationProviderImpl;
- std::unique_ptr<PresentationProviderImpl> presentation_provider_impl_;
-
- std::unique_ptr<FocusHandler> focus_handler_;
- std::unique_ptr<VisibleStoriesHandler> visible_stories_handler_;
-
- // Component context given to session shell so that it can run agents and
- // create message queues.
- std::unique_ptr<ComponentContextImpl> session_shell_component_context_impl_;
-
- // Given to the session shell so it can store its own data. These data are
- // shared between all session shells (so it's not private to the session shell
- // *app*).
- std::unique_ptr<StoryStorage> session_shell_storage_;
- fidl::BindingSet<fuchsia::modular::Link, std::unique_ptr<LinkImpl>>
- session_shell_link_bindings_;
-
- // Holds the actions scheduled by calls to the AtEnd() method.
- std::vector<std::function<void(std::function<void()>)>> at_end_;
-
- // Holds the done callback of Terminate() while the at_end_ actions are being
- // executed. We can rely on Terminate() only being called once. (And if not,
- // this could simply be made a vector as usual.)
- std::function<void()> at_end_done_;
-
- // The service provider used to connect to services advertised by the
- // clipboard agent.
- fuchsia::sys::ServiceProviderPtr services_from_clipboard_agent_;
-
- // The agent controller used to control the clipboard agent.
- fuchsia::modular::AgentControllerPtr clipboard_agent_controller_;
-
- class SwapSessionShellOperation;
-
- OperationQueue operation_queue_;
-
- // Part of Initialize() that is deferred until the first environment service
- // request is received from the session shell, in order to accelerate the
- // startup of session shell.
- fit::function<void()> finish_initialization_{[]{}};
-
- // Set to |true| when sessionmgr starts its terminating sequence; this flag
- // can be used to determine whether to reject vending FIDL services.
- bool terminating_ = false;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SessionmgrImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_SESSIONMGR_IMPL_H_
diff --git a/bin/sessionmgr/storage/BUILD.gn b/bin/sessionmgr/storage/BUILD.gn
deleted file mode 100644
index e7c02bb..0000000
--- a/bin/sessionmgr/storage/BUILD.gn
+++ /dev/null
@@ -1,158 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-tests_package("storage_unittests") {
- deps = [
- ":constants_and_utils_unittest",
- ":session_storage_unittest",
- ":story_storage_unittest",
- ]
-}
-
-group("storage") {
- public_deps = [
- ":session_storage",
- ":story_storage",
- ]
-}
-
-source_set("constants_and_utils") {
- sources = [
- "constants_and_utils.cc",
- "constants_and_utils.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/util",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- ]
-}
-
-executable("constants_and_utils_unittest") {
- testonly = true
-
- sources = [
- "constants_and_utils_unittest.cc",
- ]
-
- deps = [
- ":constants_and_utils",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//third_party/googletest:gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("session_storage") {
- sources = [
- "session_storage.cc",
- "session_storage.h",
- ]
-
- deps = [
- ":session_storage_xdr",
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/ledger_client:operations",
- ]
-
- public_deps = [
- ":story_storage",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/lib/async/cpp:future",
- ]
-}
-
-source_set("session_storage_xdr") {
- sources = [
- "session_storage_xdr.cc",
- "session_storage_xdr.h",
- ]
-
- deps = [
- "//peridot/lib/base64url",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- ]
-}
-
-executable("session_storage_unittest") {
- testonly = true
-
- sources = [
- "session_storage_unittest.cc",
- ]
-
- deps = [
- ":session_storage",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/testing:test_with_ledger",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/lib/async/cpp:future",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("story_storage") {
- sources = [
- "story_storage.cc",
- "story_storage.h",
- ]
-
- deps = [
- ":story_storage_xdr",
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/ledger_client:operations",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/lib/async/cpp:future",
- ]
-}
-
-source_set("story_storage_xdr") {
- sources = [
- "story_storage_xdr.cc",
- "story_storage_xdr.h",
- ]
-
- deps = [
- "//peridot/lib/base64url",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/module_manifest:json_xdr",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- ]
-}
-
-executable("story_storage_unittest") {
- testonly = true
-
- sources = [
- "story_storage_unittest.cc",
- ]
-
- deps = [
- ":story_storage",
- "//peridot/lib/entity:entity_watcher",
- "//peridot/lib/testing:test_with_ledger",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/lib/async/cpp:future",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/sessionmgr/storage/constants_and_utils.cc b/bin/sessionmgr/storage/constants_and_utils.cc
deleted file mode 100644
index 88e2793..0000000
--- a/bin/sessionmgr/storage/constants_and_utils.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-
-#include <string>
-#include <vector>
-
-#include <lib/fxl/strings/join_strings.h>
-
-#include "peridot/lib/util/string_escape.h"
-
-namespace modular {
-
-std::string MakeDeviceKey(const fidl::StringPtr& device_name) {
- // Not escaped, because only one component after the prefix.
- return kDeviceKeyPrefix + device_name.get();
-}
-
-std::string MakeFocusKey(const fidl::StringPtr& device_name) {
- // Not escaped, because only one component after the prefix.
- return kFocusKeyPrefix + device_name.get();
-}
-
-std::string MakeMessageQueuesPrefix(const std::string& component_namespace) {
- std::string key{kMessageQueueTokenKeyPrefix};
- key.append(StringEscape(component_namespace, kSeparator, kEscaper));
- key.append(kSeparator);
- return key;
-}
-
-std::string MakeMessageQueueTokenKey(const std::string& component_namespace,
- const std::string& component_instance_id,
- const std::string& queue_name) {
- std::string key{kMessageQueueTokenKeyPrefix};
- key.append(StringEscape(component_namespace, kSeparator, kEscaper));
- key.append(kSeparator);
- key.append(StringEscape(component_instance_id, kSeparator, kEscaper));
- key.append(kSeparator);
- key.append(StringEscape(queue_name, kSeparator, kEscaper));
- return key;
-}
-
-std::string MakeMessageQueueKey(const std::string& queue_token) {
- // Not escaped, because only one component after the prefix.
- return kMessageQueueKeyPrefix + queue_token;
-}
-
-std::string EncodeModulePath(
- const std::vector<std::string>& module_path) {
- std::vector<std::string> segments;
- segments.reserve(module_path.size());
- for (const auto& module_path_part : module_path) {
- segments.emplace_back(
- StringEscape(module_path_part, kCharsToEscape, kEscaper));
- }
- return fxl::JoinStrings(segments, kSubSeparator);
-}
-
-std::string EncodeLinkPath(const fuchsia::modular::LinkPath& link_path) {
- std::string output;
- output.append(EncodeModulePath(link_path.module_path));
- output.append(kSeparator);
- output.append(
- StringEscape(link_path.link_name.get(), kCharsToEscape, kEscaper));
- return output;
-}
-
-std::string EncodeModuleComponentNamespace(const std::string& story_id) {
- // TODO(mesch): Needs escaping, and must not be escaped when used as component
- // of a full key. Messy.
- return "story:" + story_id;
-}
-
-std::string MakeTriggerKey(const std::string& agent_url,
- const std::string& task_id) {
- std::string key{kTriggerKeyPrefix};
- key.append(StringEscape(agent_url, kCharsToEscape, kEscaper));
- key.append(kSeparator);
- key.append(StringEscape(task_id, kCharsToEscape, kEscaper));
- return key;
-}
-
-std::string MakeLinkKey(const fuchsia::modular::LinkPathPtr& link_path) {
- return MakeLinkKey(*link_path);
-}
-
-std::string MakeLinkKey(const fuchsia::modular::LinkPath& link_path) {
- std::string key{kLinkKeyPrefix};
- key.append(EncodeLinkPath(link_path));
- return key;
-}
-
-std::string MakeModuleKey(const std::vector<std::string>& module_path) {
- FXL_DCHECK(module_path.size() > 0)
- << EncodeModulePath(module_path);
- FXL_DCHECK(module_path.at(0).size() > 0) << EncodeModulePath(module_path);
- std::string key{kModuleKeyPrefix};
- key.append(EncodeModulePath(module_path));
- return key;
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/storage/constants_and_utils.h b/bin/sessionmgr/storage/constants_and_utils.h
deleted file mode 100644
index 5bf85da..0000000
--- a/bin/sessionmgr/storage/constants_and_utils.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is a description of the pages and keys used by the modular runtime.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORAGE_CONSTANTS_AND_UTILS_H_
-#define PERIDOT_BIN_SESSIONMGR_STORAGE_CONSTANTS_AND_UTILS_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/string.h>
-
-namespace modular {
-
-// There are four kinds of pages used by the modular runtime:
-//
-// 1. The user root page contains a list of all stories and of all devices.
-//
-//
-// 2. The message queue page lists all message queues that exist.
-//
-constexpr char kMessageQueuePageId[] = "MessageQueuePage"; // 16 chars
-//
-// 3. The trigger page contains the trigger conditions for all agents.
-//
-constexpr char kAgentRunnerPageId[] = "AgentRunnerPage_"; // 16 chars
-//
-// 4. Story pages (one per story) contain the story state expressed as link and
-// module data.
-
-// Keys in these pages are constructed as follows:
-//
-// 1. A prefix indicates the kind of information stored under the key. The
-// prefix ends in a slash. The prefix is used to construct keys for reading
-// and writing, and to filter keys for bulk reading and in change
-// notifications.
-//
-// Root page:
-constexpr char kStoryKeyPrefix[] = "Story/";
-constexpr char kDeviceKeyPrefix[] = "Device/";
-constexpr char kFocusKeyPrefix[] = "Focus/";
-
-// Keys under kStoryKeyPrefix
-constexpr char kStoryDataKeyPrefix[] = "Story/Data/";
-constexpr char kStorySnapshotKeyPrefix[] = "Story/Snapshot/";
-
-//
-// Message Queue page:
-constexpr char kMessageQueueKeyPrefix[] = "fuchsia::modular::MessageQueue/";
-constexpr char kMessageQueueTokenKeyPrefix[] = "MessageQueueToken/";
-//
-// fuchsia::modular::Agent Trigger page:
-constexpr char kTriggerKeyPrefix[] = "Trigger/";
-//
-// Story page:
-constexpr char kLinkKeyPrefix[] =
- "fuchsia::modular::Link|3/"; // version 3: no more incremental links
-constexpr char kModuleKeyPrefix[] = "Module/";
-constexpr char kEntityKeyPrefix[] = "Entity/";
-constexpr char kEntityNamePrefix[] = "EntityName/";
-
-// 2. ID values, separated by slashes, to identify the data item under this
-// key. The set of ID values under each key is defined by the arguments of
-// factory functions for the keys:
-//
-std::string MakeDeviceKey(const fidl::StringPtr& device_name);
-std::string MakeFocusKey(const fidl::StringPtr& device_name);
-std::string MakeMessageQueuesPrefix(const std::string& component_namespace);
-std::string MakeMessageQueueTokenKey(const std::string& component_namespace,
- const std::string& component_instance_id,
- const std::string& queue_name);
-std::string MakeMessageQueueKey(const std::string& queue_token);
-std::string MakeTriggerKey(const std::string& agent_url,
- const std::string& task_id);
-std::string MakeLinkKey(const fuchsia::modular::LinkPathPtr& link_path);
-std::string MakeLinkKey(const fuchsia::modular::LinkPath& link_path);
-std::string MakeModuleKey(const std::vector<std::string>& module_path);
-
-// 3. The slash separator is escaped by a backslash inside the ID
-// values. Backslashes inside the ID values are escaped by backslash too.
-//
-constexpr char kSeparator[] = "/";
-constexpr char kEscaper = '\\';
-constexpr char kCharsToEscape[] = ":/";
-
-// 4. The ID values may have internal structure on their own too, expressed by a
-// second sub separator character.
-//
-constexpr char kSubSeparator[] = ":";
-
-std::string EncodeLinkPath(const fuchsia::modular::LinkPath& link_path);
-std::string EncodeModulePath(
- const std::vector<std::string>& module_path);
-std::string EncodeModuleComponentNamespace(const std::string& story_id);
-
-// More notes:
-//
-// * Although keys can be parsed, the information encoded in the keys is usually
-// repeated in the value, and thus can be obtained without parsing the
-// key. This is the preferred way, as it leaves the possibility open to
-// replace key components with hashes.
-//
-// * The values under all keys are JSON. The structure of the JSON is defined by
-// Xdr*() functions to be found in the page access code.
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORAGE_CONSTANTS_AND_UTILS_H_
diff --git a/bin/sessionmgr/storage/constants_and_utils_unittest.cc b/bin/sessionmgr/storage/constants_and_utils_unittest.cc
deleted file mode 100644
index ed149ee..0000000
--- a/bin/sessionmgr/storage/constants_and_utils_unittest.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-
-#include <string>
-#include <vector>
-
-#include <lib/fxl/strings/string_view.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-TEST(Storage, EncodeModulePath) {
- std::vector<std::string> fidl_array = {"foo", ":bar", "/baz"};
- EXPECT_EQ("foo:\\:bar:\\/baz", EncodeModulePath(fidl_array));
-}
-
-TEST(Storage, EncodeLinkPath) {
- std::vector<std::string> fidl_array = {"foo", ":bar"};
- fuchsia::modular::LinkPath link_path;
- link_path.link_name = "Fred";
- link_path.module_path = std::move(fidl_array);
- EXPECT_EQ("foo:\\:bar/Fred", EncodeLinkPath(link_path));
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/storage/session_storage.cc b/bin/sessionmgr/storage/session_storage.cc
deleted file mode 100644
index 28c4db7..0000000
--- a/bin/sessionmgr/storage/session_storage.cc
+++ /dev/null
@@ -1,522 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/random/uuid.h>
-#include <unordered_set>
-
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/bin/sessionmgr/storage/session_storage_xdr.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/ledger_client/operations.h"
-
-namespace modular {
-
-SessionStorage::SessionStorage(LedgerClient* ledger_client,
- LedgerPageId page_id)
- : PageClient("SessionStorage", ledger_client, page_id, kStoryKeyPrefix),
- ledger_client_(ledger_client) {
- FXL_DCHECK(ledger_client_ != nullptr);
-}
-
-namespace {
-
-// TODO(rosswang): replace with |std::string::starts_with| after C++20
-bool StartsWith(const std::string& string, const std::string& prefix) {
- return string.compare(0, prefix.size(), prefix) == 0;
-}
-
-fidl::StringPtr StoryNameToStoryDataKey(fidl::StringPtr story_name) {
- // Not escaped, because only one component after the prefix.
- return kStoryDataKeyPrefix + story_name.get();
-}
-
-fidl::StringPtr StoryNameFromStoryDataKey(fidl::StringPtr key) {
- return key->substr(sizeof(kStoryDataKeyPrefix) - 1);
-}
-
-fidl::StringPtr StoryNameToStorySnapshotKey(fidl::StringPtr story_name) {
- // Not escaped, because only one component after the prefix.
- return kStorySnapshotKeyPrefix + story_name.get();
-}
-
-OperationBase* MakeGetStoryDataCall(
- fuchsia::ledger::Page* const page, fidl::StringPtr story_name,
- std::function<void(fuchsia::modular::internal::StoryDataPtr)> result_call) {
- return new ReadDataCall<fuchsia::modular::internal::StoryData>(
- page, StoryNameToStoryDataKey(story_name), true /* not_found_is_ok */,
- XdrStoryData, std::move(result_call));
-};
-
-OperationBase* MakeWriteStoryDataCall(
- fuchsia::ledger::Page* const page,
- fuchsia::modular::internal::StoryDataPtr story_data,
- std::function<void()> result_call) {
- return new WriteDataCall<fuchsia::modular::internal::StoryData>(
- page, StoryNameToStoryDataKey(story_data->story_info.id), XdrStoryData,
- std::move(story_data), std::move(result_call));
-};
-
-class CreateStoryCall
- : public LedgerOperation<fidl::StringPtr, fuchsia::ledger::PageId> {
- public:
- CreateStoryCall(
- fuchsia::ledger::Ledger* const ledger,
- fuchsia::ledger::Page* const root_page, fidl::StringPtr story_name,
- fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
- fuchsia::modular::StoryOptions story_options, ResultCall result_call)
- : LedgerOperation("SessionStorage::CreateStoryCall", ledger, root_page,
- std::move(result_call)),
- story_name_(std::move(story_name)),
- extra_info_(std::move(extra_info)),
- story_options_(std::move(story_options)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &story_name_, &story_page_id_};
- ledger()->GetPage(nullptr, story_page_.NewRequest(),
- Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "Ledger.GetPage() "
- << fidl::ToUnderlying(status);
- }
- }));
- story_page_->GetId([this, flow](fuchsia::ledger::PageId id) {
- story_page_id_ = std::move(id);
- Cont(flow);
- });
- }
-
- void Cont(FlowToken flow) {
- // TODO(security), cf. FW-174. This ID is exposed in public services
- // such as fuchsia::modular::StoryProvider.PreviousStories(),
- // fuchsia::modular::StoryController.GetInfo(),
- // fuchsia::modular::ModuleContext.GetStoryName(). We need to ensure this
- // doesn't expose internal information by being a page ID.
- // TODO(thatguy): Generate a GUID instead.
- if (!story_name_ || story_name_->empty()) {
- story_name_ = fxl::GenerateUUID();
- }
-
- story_data_ = fuchsia::modular::internal::StoryData::New();
- story_data_->story_name = story_name_;
- story_data_->story_options = std::move(story_options_);
- story_data_->story_page_id = CloneOptional(story_page_id_);
- story_data_->story_info.id = story_name_;
- story_data_->story_info.last_focus_time = 0;
- story_data_->story_info.extra = std::move(extra_info_);
-
- operation_queue_.Add(MakeWriteStoryDataCall(page(), std::move(story_data_),
- [this, flow] {}));
- }
-
- fidl::StringPtr story_name_;
- fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info_;
- fuchsia::modular::StoryOptions story_options_;
-
- fuchsia::ledger::PagePtr story_page_;
- fuchsia::modular::internal::StoryDataPtr story_data_;
-
- fuchsia::ledger::PageId story_page_id_;
-
- // Sub operations run in this queue.
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(CreateStoryCall);
-};
-
-} // namespace
-
-FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> SessionStorage::CreateStory(
- fidl::StringPtr story_name,
- fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
- fuchsia::modular::StoryOptions story_options) {
- auto ret = Future<fidl::StringPtr, fuchsia::ledger::PageId>::Create(
- "SessionStorage.CreateStory.ret");
- operation_queue_.Add(new CreateStoryCall(
- ledger_client_->ledger(), page(), std::move(story_name),
- std::move(extra_info), std::move(story_options), ret->Completer()));
- return ret;
-}
-
-FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> SessionStorage::CreateStory(
- fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
- fuchsia::modular::StoryOptions story_options) {
- return CreateStory(nullptr /* story_name */, std::move(extra_info),
- std::move(story_options));
-}
-
-namespace {
-class DeleteStoryCall : public Operation<> {
- public:
- DeleteStoryCall(fuchsia::ledger::Ledger* const ledger,
- fuchsia::ledger::Page* const session_page,
- fidl::StringPtr story_name, ResultCall result_call)
- : Operation("SessionStorage::DeleteStoryCall", std::move(result_call)),
- ledger_(ledger),
- session_page_(session_page),
- story_name_(story_name) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- operation_queue_.Add(MakeGetStoryDataCall(
- session_page_, story_name_, [this, flow](auto story_data) {
- if (!story_data)
- return;
- story_data_ = std::move(*story_data);
- Cont1(flow);
- }));
- }
-
- void Cont1(FlowToken flow) {
- // Get the story page so we can remove its contents.
- ledger_->GetPage(
- std::move(story_data_.story_page_id), story_page_.NewRequest(),
- [this, flow, story_name = story_data_.story_info.id](
- fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "Ledger.GetPage() for story " << story_name
- << ": " << fidl::ToUnderlying(status);
- return;
- }
- Cont2(flow);
- });
- }
-
- void Cont2(FlowToken flow) {
- story_page_->Clear([this, flow, story_name = story_data_.story_info.id](
- fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "Page.Clear() for story " << story_name << ": "
- << fidl::ToUnderlying(status);
- return;
- }
- Cont3(flow);
- });
- }
-
- void Cont3(FlowToken flow) {
- // Remove the story data in the session page.
- session_page_->Delete(
- to_array(StoryNameToStoryDataKey(story_data_.story_info.id)),
- [this, flow](fuchsia::ledger::Status status) {
- // Deleting a key that doesn't exist is OK, not
- // KEY_NOT_FOUND.
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "SessionStorage: Page.Delete() "
- << fidl::ToUnderlying(status);
- }
- Cont4(flow);
- });
- }
-
- void Cont4(FlowToken flow) {
- // Remove the story snapshot in the session page.
- session_page_->Delete(
- to_array(StoryNameToStorySnapshotKey(story_data_.story_info.id)),
- [this, flow](fuchsia::ledger::Status status) {
- // Deleting a key that doesn't exist is OK, not
- // KEY_NOT_FOUND.
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "SessionStorage: Page.Delete() "
- << fidl::ToUnderlying(status);
- }
- });
- }
-
- fuchsia::ledger::Ledger* const ledger_; // not owned
- fuchsia::ledger::Page* const session_page_; // not owned
- const fidl::StringPtr story_name_;
-
- // Intermediate state.
- OperationQueue operation_queue_;
- fuchsia::modular::internal::StoryData story_data_;
- fuchsia::ledger::PagePtr story_page_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DeleteStoryCall);
-};
-} // namespace
-
-FuturePtr<> SessionStorage::DeleteStory(fidl::StringPtr story_name) {
- auto ret = Future<>::Create("SessionStorage.DeleteStory.ret");
- operation_queue_.Add(new DeleteStoryCall(ledger_client_->ledger(), page(),
- story_name, ret->Completer()));
- return ret;
-}
-
-namespace {
-class MutateStoryDataCall : public Operation<> {
- public:
- MutateStoryDataCall(
- fuchsia::ledger::Page* const page, fidl::StringPtr story_name,
- std::function<bool(fuchsia::modular::internal::StoryData* story_data)>
- mutate,
- ResultCall result_call)
- : Operation("SessionStorage::MutateStoryDataCall",
- std::move(result_call)),
- page_(page),
- story_name_(story_name),
- mutate_(std::move(mutate)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- operation_queue_.Add(MakeGetStoryDataCall(
- page_, story_name_,
- [this, flow](fuchsia::modular::internal::StoryDataPtr story_data) {
- if (!story_data) {
- // If the story doesn't exist, it was deleted.
- return;
- }
- if (!mutate_(story_data.get())) {
- // If no mutation happened, we're done.
- return;
- }
-
- operation_queue_.Add(
- MakeWriteStoryDataCall(page_, std::move(story_data), [flow] {}));
- }));
- }
-
- fuchsia::ledger::Page* const page_; // not owned
- const fidl::StringPtr story_name_;
- std::function<bool(fuchsia::modular::internal::StoryData* story_data)>
- mutate_;
-
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(MutateStoryDataCall);
-};
-
-} // namespace
-
-FuturePtr<> SessionStorage::UpdateLastFocusedTimestamp(
- fidl::StringPtr story_name, const int64_t ts) {
- auto mutate = [ts](fuchsia::modular::internal::StoryData* const story_data) {
- if (story_data->story_info.last_focus_time == ts) {
- return false;
- }
- story_data->story_info.last_focus_time = ts;
- return true;
- };
-
- auto ret = Future<>::Create("SessionStorage.UpdateLastFocusedTimestamp.ret");
- operation_queue_.Add(
- new MutateStoryDataCall(page(), story_name, mutate, ret->Completer()));
- return ret;
-}
-
-FuturePtr<fuchsia::modular::internal::StoryDataPtr>
-SessionStorage::GetStoryData(fidl::StringPtr story_name) {
- auto ret = Future<fuchsia::modular::internal::StoryDataPtr>::Create(
- "SessionStorage.GetStoryData.ret");
- operation_queue_.Add(
- MakeGetStoryDataCall(page(), story_name, ret->Completer()));
- return ret;
-}
-
-// Returns a Future vector of StoryData for all stories in this session.
-FuturePtr<std::vector<fuchsia::modular::internal::StoryData>>
-SessionStorage::GetAllStoryData() {
- auto ret =
- Future<std::vector<fuchsia::modular::internal::StoryData>>::Create(
- "SessionStorage.GetAllStoryData.ret");
- operation_queue_.Add(
- new ReadAllDataCall<fuchsia::modular::internal::StoryData>(
- page(), kStoryDataKeyPrefix, XdrStoryData, ret->Completer()));
- return ret;
-}
-
-FuturePtr<> SessionStorage::UpdateStoryOptions(
- fidl::StringPtr story_name, fuchsia::modular::StoryOptions story_options) {
- auto ret = Future<>::Create("SessionStorage.SetOptions.ret");
- auto mutate = fxl::MakeCopyable(
- [story_options = std::move(story_options)](
- fuchsia::modular::internal::StoryData* story_data) mutable {
- if (story_data->story_options != story_options) {
- story_data->story_options = std::move(story_options);
- return true;
- }
- return false;
- });
- operation_queue_.Add(new MutateStoryDataCall(
- page(), story_name, std::move(mutate), ret->Completer()));
- return ret;
-}
-
-FuturePtr<std::unique_ptr<StoryStorage>> SessionStorage::GetStoryStorage(
- fidl::StringPtr story_name) {
- auto returned_future = Future<std::unique_ptr<StoryStorage>>::Create(
- "SessionStorage.GetStoryStorage.returned_future");
-
- operation_queue_.Add(MakeGetStoryDataCall(
- page(), story_name,
- [this, returned_future,
- story_name](fuchsia::modular::internal::StoryDataPtr story_data) {
- if (story_data) {
- auto story_storage = std::make_unique<StoryStorage>(
- ledger_client_, *story_data->story_page_id);
- returned_future->Complete(std::move(story_storage));
- } else {
- returned_future->Complete(nullptr);
- }
- }));
-
- return returned_future;
-}
-
-namespace {
-
-class WriteSnapshotCall : public Operation<> {
- public:
- WriteSnapshotCall(PageClient* page_client, fidl::StringPtr story_name,
- fuchsia::mem::Buffer snapshot, ResultCall result_call)
- : Operation("SessionStorage::WriteSnapshotCall", std::move(result_call)),
- page_client_(page_client),
- key_(StoryNameToStorySnapshotKey(story_name)),
- snapshot_(std::move(snapshot)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- page_client_->page()->CreateReferenceFromBuffer(
- std::move(snapshot_),
- [this, flow](fuchsia::ledger::Status status,
- std::unique_ptr<fuchsia::ledger::Reference> reference) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name()
- << " PageSnapshot.CreateReferenceFromBuffer() "
- << fidl::ToUnderlying(status);
- return;
- } else if (!reference) {
- return;
- }
-
- PutReference(std::move(reference), flow);
- });
- }
-
- void PutReference(std::unique_ptr<fuchsia::ledger::Reference> reference,
- FlowToken flow) {
- page_client_->page()->PutReference(
- to_array(key_), std::move(*reference),
- // TODO(MI4-1425): Experiment with declaring lazy priority.
- fuchsia::ledger::Priority::EAGER,
- [this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " PageSnapshot.PutReference() "
- << fidl::ToUnderlying(status);
- }
- });
- }
-
- PageClient* const page_client_;
- fidl::StringPtr key_;
- fuchsia::mem::Buffer snapshot_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(WriteSnapshotCall);
-};
-
-class ReadSnapshotCall : public Operation<fuchsia::mem::BufferPtr> {
- public:
- ReadSnapshotCall(PageClient* page_client, fidl::StringPtr story_name,
- ResultCall result_call)
- : Operation("SessionStorage::ReadSnapshotCall", std::move(result_call)),
- page_client_(page_client),
- key_(StoryNameToStorySnapshotKey(story_name)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &snapshot_};
-
- page_snapshot_ = page_client_->NewSnapshot(
- /* on_error = */ [this] { Done(nullptr); });
- page_snapshot_->Get(
- to_array(key_), [this, flow](fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr snapshot) {
- // TODO(MI4-1425): Handle NEEDS_FETCH status if using lazy priority.
- switch (status) {
- case fuchsia::ledger::Status::KEY_NOT_FOUND:
- return;
- case fuchsia::ledger::Status::OK:
- snapshot_ = std::move(snapshot);
- return;
- default:
- FXL_LOG(ERROR) << trace_name() << " PageSnapshot.Get() "
- << fidl::ToUnderlying(status);
- return;
- }
- });
- }
-
- // Input parameters.
- PageClient* const page_client_;
- fidl::StringPtr key_;
-
- // Intermediate state.
- fuchsia::ledger::PageSnapshotPtr page_snapshot_;
-
- // Return values.
- fuchsia::mem::BufferPtr snapshot_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ReadSnapshotCall);
-};
-} // namespace
-
-FuturePtr<> SessionStorage::WriteSnapshot(fidl::StringPtr story_name,
- fuchsia::mem::Buffer snapshot) {
- auto ret = Future<>::Create("SessionStorage.WriteSnapshot.ret");
- operation_queue_.Add(new WriteSnapshotCall(
- this, story_name, std::move(snapshot), ret->Completer()));
- return ret;
-}
-
-FuturePtr<fuchsia::mem::BufferPtr> SessionStorage::ReadSnapshot(
- fidl::StringPtr story_name) {
- auto ret = Future<fuchsia::mem::BufferPtr>::Create(
- "SessionStorage.ReadSnapshot.ret");
- operation_queue_.Add(
- new ReadSnapshotCall(this, story_name, ret->Completer()));
- return ret;
-}
-
-void SessionStorage::OnPageChange(const std::string& key,
- const std::string& value) {
- if (StartsWith(key, kStoryDataKeyPrefix)) {
- auto story_data = fuchsia::modular::internal::StoryData::New();
- if (!XdrRead(value, &story_data, XdrStoryData)) {
- FXL_LOG(ERROR)
- << "SessionStorage::OnPageChange : could not decode ledger "
- "value for key "
- << key << "\nvalue:\n"
- << value;
- return;
- }
-
- auto story_name = StoryNameFromStoryDataKey(key);
- if (on_story_updated_) {
- on_story_updated_(std::move(story_name), std::move(*story_data));
- }
- } else {
- // No-op.
- }
-}
-
-void SessionStorage::OnPageDelete(const std::string& key) {
- if (on_story_deleted_) {
- // Call to StoryNameFromStoryDataKey() needed because a deleted story is
- // modelled by deleting the key, and then the value is not available.
- // TODO(thatguy,mesch): Change PageClient to supply values of deleted keys
- // and/or change modeling of deleted stories.
- on_story_deleted_(StoryNameFromStoryDataKey(key));
- }
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/storage/session_storage.h b/bin/sessionmgr/storage/session_storage.h
deleted file mode 100644
index 5dc1323..0000000
--- a/bin/sessionmgr/storage/session_storage.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORAGE_SESSION_STORAGE_H_
-#define PERIDOT_BIN_SESSIONMGR_STORAGE_SESSION_STORAGE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/page_id.h"
-
-namespace modular {
-
-// This class has the following responsibilities:
-//
-// * Manage the persistence of metadata about what stories are part of a single
-// session.
-// * Observe the metadata and call clients back when changes initiated by other
-// Ledger clients appear.
-// * Manage the lifecycle of Ledger pages for storing individual story
-// metadata. The contents of these pages are governed by StoryStoage.
-//
-// All calls operate directly on the Ledger itself: no local caching is
-// performed.
-class SessionStorage : public PageClient {
- public:
- // Constructs a new SessionStorage with storage on |page_id| in the ledger
- // given by |ledger_client|.
- //
- // |ledger_client| must outlive *this.
- SessionStorage(LedgerClient* ledger_client, LedgerPageId page_id);
-
- // |callback| is notified whenever a story has been deleted. This
- // notification is either the result of:
- //
- // a) The story being deleted on another device.
- // b) The story having been deleted locally with DeleteStory().
- void set_on_story_deleted(
- std::function<void(fidl::StringPtr story_id)> callback) {
- on_story_deleted_ = std::move(callback);
- }
-
- // |callback| is notified whenever a story has been added or updated.
- // Currently we do not differentiate between the two, and it is up to the
- // client to make this distinction.
- //
- // The update could be the result of a local modification (ie, through
- // Update*()) or a modification on another device.
- void set_on_story_updated(
- std::function<void(fidl::StringPtr story_id,
- fuchsia::modular::internal::StoryData story_data)>
- callback) {
- on_story_updated_ = std::move(callback);
- }
-
- // Creates a new story and returns a tuple of (story id, story ledger page
- // id) on completion. |story_name| and |extra_info| may be null.
- //
- // If |story_name| is not provided, a UUID will be generated as the name.
- //
- // If |extra_info| is set, populates StoryData.story_info.extra with the
- // entries given.
- //
- // TODO(thatguy): Allowing for null story names is left in for backwards
- // compatibility with existing code. The intention is that all clients
- // outside the FW (through FIDL interfaces) use story names exclusively. It
- // is unclear if internal story IDs should be an implementation detail of
- // SessionStorage, or if they should be exposed to the story runtime
- // architecture.
- FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> CreateStory(
- fidl::StringPtr story_name,
- fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
- fuchsia::modular::StoryOptions story_options);
-
- // Same as above, but defaults |story_name| to nullptr.
- FuturePtr<fidl::StringPtr, fuchsia::ledger::PageId> CreateStory(
- fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_info,
- fuchsia::modular::StoryOptions story_options);
-
- // Deletes the |story_id| from the list of known stories and completes the
- // returned Future when done.
- //
- // Does not currently delete the story's page, so it is left dangling.
- //
- // TODO(thatguy): Deleting stories is a two-step process:
- // 1) Remove the story from the list of active stories (so it doesn't show
- // up on the timeline).
- // 2) Delete the underlying story storage page.
- //
- // We only do (1). Find a way to split (1) and (2): either have the client
- // pass in a Future that signals when it's OK to delete the story storage (ie,
- // once the story has shut down cleanly) or split the function into two calls.
- // MI4-1002
- FuturePtr<> DeleteStory(fidl::StringPtr story_id);
-
- // Sets the last focused timestamp for |story_id| to |ts|. Completes the
- // returned Future when done.
- FuturePtr<> UpdateLastFocusedTimestamp(fidl::StringPtr story_id, int64_t ts);
-
- // Returns a Future StoryDataPtr for |story_id|. If |story_id| is not a valid
- // story, the returned StoryDataPtr will be null.
- FuturePtr<fuchsia::modular::internal::StoryDataPtr> GetStoryData(
- fidl::StringPtr story_id);
-
- // Returns a Future vector of StoryData for all stories in this session.
- //
- // TODO(thatguy): If the return value grows large, an dispatcher stream would
- // be a more appropriate return value.
- FuturePtr<std::vector<fuchsia::modular::internal::StoryData>>
- GetAllStoryData();
-
- FuturePtr<> UpdateStoryOptions(fidl::StringPtr story_id,
- fuchsia::modular::StoryOptions story_options);
-
- // Gets the StoryStorage for the story with the given |story_id| to perform
- // operations on the story such as adding modules, updating links, etc.
- FuturePtr<std::unique_ptr<StoryStorage>> GetStoryStorage(
- fidl::StringPtr story_id);
-
- // Returns the snapshot for the story. If there is no snapshot for the story
- // or the read operation failed, the return value of |fuchsia::mem::BufferPtr|
- // will be nullptr.
- FuturePtr<fuchsia::mem::BufferPtr> ReadSnapshot(fidl::StringPtr story_id);
-
- // Writes the given |snapshot| to storage. The returned future will resolve
- // when the |snapshot| has been written to storage or when it has failed to
- // write to storage.
- FuturePtr<> WriteSnapshot(fidl::StringPtr story_id,
- fuchsia::mem::Buffer snapshot);
-
- private:
- // |PageClient|
- void OnPageChange(const std::string& key, const std::string& value) override;
-
- // |PageClient|
- void OnPageDelete(const std::string& key) override;
-
- LedgerClient* const ledger_client_;
- OperationQueue operation_queue_;
-
- std::function<void(fidl::StringPtr story_id)> on_story_deleted_;
- std::function<void(fidl::StringPtr story_id,
- fuchsia::modular::internal::StoryData story_data)>
- on_story_updated_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SessionStorage);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORAGE_SESSION_STORAGE_H_
diff --git a/bin/sessionmgr/storage/session_storage_unittest.cc b/bin/sessionmgr/storage/session_storage_unittest.cc
deleted file mode 100644
index 55ec518..0000000
--- a/bin/sessionmgr/storage/session_storage_unittest.cc
+++ /dev/null
@@ -1,532 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-
-#include <memory>
-
-#include <lib/async/cpp/future.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/testing/test_with_ledger.h"
-
-namespace modular {
-namespace {
-
-class SessionStorageTest : public testing::TestWithLedger {
- protected:
- std::unique_ptr<SessionStorage> CreateStorage(std::string page_id) {
- return std::make_unique<SessionStorage>(ledger_client(),
- MakePageId(page_id));
- }
-
- // Convenience method to create a story for the test cases where
- // we're not testing CreateStory().
- fidl::StringPtr CreateStory(
- SessionStorage* storage,
- fuchsia::modular::StoryOptions story_options = {}) {
- auto future_story = storage->CreateStory(
- nullptr /* name */, nullptr /* extra */, std::move(story_options));
- bool done{};
- fidl::StringPtr story_name;
- future_story->Then(
- [&](fidl::StringPtr name, fuchsia::ledger::PageId page_id) {
- done = true;
- story_name = std::move(name);
- });
- RunLoopUntil([&] { return done; });
-
- return story_name;
- }
-};
-
-TEST_F(SessionStorageTest, Create_VerifyData) {
- // Create a single story, and verify that the data we have stored about it is
- // correct.
- auto storage = CreateStorage("page");
-
- fidl::VectorPtr<fuchsia::modular::StoryInfoExtraEntry> extra_entries;
- fuchsia::modular::StoryInfoExtraEntry entry;
- entry.key = "key1";
- entry.value = "value1";
- extra_entries->push_back(std::move(entry));
-
- entry.key = "key2";
- entry.value = "value2";
- extra_entries->push_back(std::move(entry));
-
- fuchsia::modular::StoryOptions story_options;
- story_options.kind_of_proto_story = true;
- auto future_story = storage->CreateStory(
- "story_name", std::move(extra_entries), std::move(story_options));
- bool done{};
- fidl::StringPtr story_name;
- fuchsia::ledger::PageId page_id;
- future_story->Then([&](fidl::StringPtr name, fuchsia::ledger::PageId page) {
- done = true;
- story_name = std::move(name);
- page_id = std::move(page);
- });
- RunLoopUntil([&] { return done; });
-
- // Get the StoryData for this story.
- auto future_data = storage->GetStoryData(story_name);
- done = false;
- fuchsia::modular::internal::StoryData cached_data;
- future_data->Then([&](fuchsia::modular::internal::StoryDataPtr data) {
- ASSERT_TRUE(data);
-
- EXPECT_EQ("story_name", data->story_name);
- EXPECT_TRUE(data->story_options.kind_of_proto_story);
- EXPECT_EQ(story_name, data->story_info.id);
- ASSERT_TRUE(data->story_page_id);
- EXPECT_EQ(page_id, *data->story_page_id);
- EXPECT_TRUE(data->story_info.extra);
- EXPECT_EQ(2u, data->story_info.extra->size());
- EXPECT_EQ("key1", data->story_info.extra->at(0).key);
- EXPECT_EQ("value1", data->story_info.extra->at(0).value);
- EXPECT_EQ("key2", data->story_info.extra->at(1).key);
- EXPECT_EQ("value2", data->story_info.extra->at(1).value);
-
- done = true;
-
- cached_data = std::move(*data);
- });
- RunLoopUntil([&] { return done; });
-
- // Get the StoryData again, but this time by its name.
- future_data = storage->GetStoryData("story_name");
- done = false;
- future_data->Then([&](fuchsia::modular::internal::StoryDataPtr data) {
- ASSERT_TRUE(data);
- ASSERT_EQ(cached_data, *data);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // Verify that GetAllStoryData() also returns the same information.
- fidl::VectorPtr<fuchsia::modular::internal::StoryData> all_data;
- auto future_all_data = storage->GetAllStoryData();
- future_all_data->Then(
- [&](std::vector<fuchsia::modular::internal::StoryData> data) {
- all_data.reset(std::move(data));
- });
- RunLoopUntil([&] { return !!all_data; });
-
- EXPECT_EQ(1u, all_data->size());
- EXPECT_EQ(cached_data, all_data->at(0));
-}
-
-TEST_F(SessionStorageTest, CreateGetAllDelete) {
- // Create a single story, call GetAllStoryData() to show that it was created,
- // and then delete it.
- //
- // Pipeline all the calls such to show that we data consistency based on call
- // order.
- auto storage = CreateStorage("page");
- auto future_story = storage->CreateStory(
- "story_name", nullptr /* extra_info */, {} /* options */);
-
- // Immediately after creation is complete, delete it.
- FuturePtr<> delete_done;
- future_story->Then(
- [&](fidl::StringPtr story_name, fuchsia::ledger::PageId page_id) {
- delete_done = storage->DeleteStory(story_name);
- });
-
- auto future_all_data = storage->GetAllStoryData();
- fidl::VectorPtr<fuchsia::modular::internal::StoryData> all_data;
- future_all_data->Then(
- [&](std::vector<fuchsia::modular::internal::StoryData> data) {
- all_data.reset(std::move(data));
- });
-
- RunLoopUntil([&] { return !!all_data; });
-
- // Given the ordering, we expect the story we created to show up.
- EXPECT_EQ(1u, all_data->size());
-
- // But if we get all data again, we should see no stories.
- future_all_data = storage->GetAllStoryData();
- all_data.reset();
- future_all_data->Then(
- [&](std::vector<fuchsia::modular::internal::StoryData> data) {
- all_data.reset(std::move(data));
- });
- RunLoopUntil([&] { return !!all_data; });
- EXPECT_EQ(0u, all_data->size());
-}
-
-TEST_F(SessionStorageTest, CreateMultipleAndDeleteOne) {
- // Create two stories.
- //
- // * Their ids should be different.
- // * They should get different Ledger page ids.
- // * If we GetAllStoryData() we should see both of them.
- auto storage = CreateStorage("page");
-
- auto future_story1 = storage->CreateStory("story1", nullptr /* extra_info */,
- {} /* options */);
- auto future_story2 =
- storage->CreateStory("story2", nullptr /* extra_info */, {} /* options*/);
-
- fidl::StringPtr story1_name;
- fuchsia::ledger::PageId story1_pageid;
- fidl::StringPtr story2_name;
- fuchsia::ledger::PageId story2_pageid;
- bool done = false;
- Wait("SessionStorageTest.CreateMultipleAndDeleteOne.wait",
- {future_story1, future_story2})
- ->Then([&](auto results) {
- story1_name = std::move(std::get<0>(results[0]));
- story1_pageid = std::move(std::get<1>(results[0]));
- story2_name = std::move(std::get<0>(results[1]));
- story2_pageid = std::move(std::get<1>(results[1]));
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- EXPECT_NE(story1_name, story2_name);
- EXPECT_NE(story1_pageid, story2_pageid);
-
- auto future_all_data = storage->GetAllStoryData();
- fidl::VectorPtr<fuchsia::modular::internal::StoryData> all_data;
- future_all_data->Then(
- [&](std::vector<fuchsia::modular::internal::StoryData> data) {
- all_data.reset(std::move(data));
- });
- RunLoopUntil([&] { return !!all_data; });
-
- EXPECT_EQ(2u, all_data->size());
-
- // Now delete one of them, and we should see that GetAllStoryData() only
- // returns one entry.
- bool delete_done{};
- storage->DeleteStory("story1")->Then([&] { delete_done = true; });
-
- future_all_data = storage->GetAllStoryData();
- all_data.reset();
- future_all_data->Then(
- [&](std::vector<fuchsia::modular::internal::StoryData> data) {
- all_data.reset(std::move(data));
- });
- RunLoopUntil([&] { return !!all_data; });
-
- EXPECT_TRUE(delete_done);
- EXPECT_EQ(1u, all_data->size());
-
- // If we try to get the story by id, or by name, we expect both to return
- // null.
- auto future_data = storage->GetStoryData(story1_name);
- done = false;
- future_data->Then([&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_TRUE(data == nullptr);
- done = true;
- });
-
- future_data = storage->GetStoryData("story1");
- done = false;
- future_data->Then([&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_TRUE(data == nullptr);
- done = true;
- });
-
- // TODO(thatguy): Verify that the story's page was also deleted.
- // MI4-1002
-}
-
-TEST_F(SessionStorageTest, DeleteStoryDeletesStoryPage) {
- // When we call DeleteStory, we expect the story's page to be completely
- // emptied.
- auto storage = CreateStorage("page");
- auto future_story = storage->CreateStory(
- "story_name", nullptr /* extra_info */, {} /* options */);
-
- bool done{false};
- auto story_page_id = fuchsia::ledger::PageId::New();
- future_story->Then([&](fidl::StringPtr id, fuchsia::ledger::PageId page_id) {
- *story_page_id = std::move(page_id);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // Add some fake content to the story's page, so that we dan show that
- // it is deleted when we instruct SessionStorage to delete the story.
- fuchsia::ledger::PagePtr story_page;
- ledger_client()->ledger()->GetPage(
- std::move(story_page_id), story_page.NewRequest(),
- [&](fuchsia::ledger::Status status) {
- ASSERT_EQ(fuchsia::ledger::Status::OK, status);
- });
- done = false;
- story_page->Put(to_array("key"), to_array("value"),
- [&](fuchsia::ledger::Status status) { done = true; });
- RunLoopUntil([&] { return done; });
-
- // Delete the story.
- done = false;
- storage->DeleteStory("story_name")->Then([&] { done = true; });
- RunLoopUntil([&] { return done; });
-
- // Show that the underlying page is now empty.
- fuchsia::ledger::PageSnapshotPtr snapshot;
- story_page->GetSnapshot(snapshot.NewRequest(), to_array("") /* prefix */,
- nullptr /* watcher */,
- [&](fuchsia::ledger::Status status) {
- ASSERT_EQ(fuchsia::ledger::Status::OK, status);
- });
- done = false;
- snapshot->GetEntries(to_array("") /* key_start */, nullptr /* token */,
- [&](fuchsia::ledger::Status status,
- std::vector<fuchsia::ledger::Entry> entries,
- fuchsia::ledger::TokenPtr next_token) {
- ASSERT_EQ(fuchsia::ledger::Status::OK, status);
- EXPECT_EQ(nullptr, next_token);
- EXPECT_TRUE(entries.empty());
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SessionStorageTest, UpdateLastFocusedTimestamp) {
- auto storage = CreateStorage("page");
- auto story_name = CreateStory(storage.get());
-
- storage->UpdateLastFocusedTimestamp(story_name, 10);
- auto future_data = storage->GetStoryData(story_name);
- bool done{};
- future_data->Then([&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_EQ(10, data->story_info.last_focus_time);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SessionStorageTest, ObserveCreateUpdateDelete_Local) {
- auto storage = CreateStorage("page");
-
- bool updated{};
- fidl::StringPtr updated_story_name;
- fuchsia::modular::internal::StoryData updated_story_data;
- storage->set_on_story_updated(
- [&](fidl::StringPtr story_name,
- fuchsia::modular::internal::StoryData story_data) {
- updated_story_name = std::move(story_name);
- updated_story_data = std::move(story_data);
- updated = true;
- });
-
- bool deleted{};
- fidl::StringPtr deleted_story_name;
- storage->set_on_story_deleted([&](fidl::StringPtr story_name) {
- deleted_story_name = std::move(story_name);
- deleted = true;
- });
-
- auto created_story_name = CreateStory(storage.get());
- RunLoopUntil([&] { return updated; });
- EXPECT_EQ(created_story_name, updated_story_name);
- EXPECT_EQ(created_story_name, updated_story_data.story_info.id);
-
- // Update something and see a new notification.
- updated = false;
- storage->UpdateLastFocusedTimestamp(created_story_name, 42);
- RunLoopUntil([&] { return updated; });
- EXPECT_EQ(created_story_name, updated_story_name);
- EXPECT_EQ(42, updated_story_data.story_info.last_focus_time);
-
- // Update options and see a new notification.
- updated = false;
- fuchsia::modular::StoryOptions story_options;
- story_options.kind_of_proto_story = true;
- storage->UpdateStoryOptions(created_story_name, std::move(story_options));
- RunLoopUntil([&] { return updated; });
- EXPECT_EQ(created_story_name, updated_story_name);
- EXPECT_EQ(created_story_name, updated_story_data.story_info.id);
- EXPECT_TRUE(updated_story_data.story_options.kind_of_proto_story);
-
- // Delete the story and expect to see a notification.
- storage->DeleteStory(created_story_name);
- RunLoopUntil([&] { return deleted; });
- EXPECT_EQ(created_story_name, deleted_story_name);
-}
-
-TEST_F(SessionStorageTest, ObserveCreateUpdateDelete_Remote) {
- // Just like above, but we're going to trigger all of the operations that
- // would cause a chagne notification on a different Ledger page connection to
- // simulate them happening on another device.
- auto storage = CreateStorage("page");
- auto remote_storage = CreateStorage("page");
-
- bool updated{};
- fidl::StringPtr updated_story_name;
- fuchsia::modular::internal::StoryData updated_story_data;
- storage->set_on_story_updated(
- [&](fidl::StringPtr story_name,
- fuchsia::modular::internal::StoryData story_data) {
- updated_story_name = std::move(story_name);
- updated_story_data = std::move(story_data);
- updated = true;
- });
-
- bool deleted{};
- fidl::StringPtr deleted_story_name;
- storage->set_on_story_deleted([&](fidl::StringPtr story_name) {
- deleted_story_name = std::move(story_name);
- deleted = true;
- });
-
- auto created_story_name = CreateStory(remote_storage.get());
- RunLoopUntil([&] { return updated; });
- EXPECT_EQ(created_story_name, updated_story_name);
- EXPECT_EQ(created_story_name, updated_story_data.story_info.id);
-
- // Update something and see a new notification.
- updated = false;
- remote_storage->UpdateLastFocusedTimestamp(created_story_name, 42);
- RunLoopUntil([&] { return updated; });
- EXPECT_EQ(created_story_name, updated_story_name);
- EXPECT_EQ(42, updated_story_data.story_info.last_focus_time);
-
- // Update options and see a new notification.
- updated = false;
- fuchsia::modular::StoryOptions story_options;
- story_options.kind_of_proto_story = true;
- remote_storage->UpdateStoryOptions(created_story_name,
- std::move(story_options));
- RunLoopUntil([&] { return updated; });
- EXPECT_EQ(created_story_name, updated_story_name);
- EXPECT_EQ(created_story_name, updated_story_data.story_info.id);
- EXPECT_TRUE(updated_story_data.story_options.kind_of_proto_story);
-
- // Delete the story and expect to see a notification.
- remote_storage->DeleteStory(created_story_name);
- RunLoopUntil([&] { return deleted; });
- EXPECT_EQ(created_story_name, deleted_story_name);
-}
-
-TEST_F(SessionStorageTest, UpdateStoryOptions) {
- auto storage = CreateStorage("page");
- auto story_name = CreateStory(storage.get());
- bool done{};
-
- // Start by setting an option.
- fuchsia::modular::StoryOptions story_options;
- story_options.kind_of_proto_story = true;
- storage->UpdateStoryOptions(story_name, std::move(story_options))->Then([&] {
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // Read the options (we should only see 1 even when we added 2 since it's the
- // same).
- done = false;
- storage->GetStoryData(story_name)
- ->Then([&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_TRUE(data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // Update the option again.
- fuchsia::modular::StoryOptions story_options2;
- story_options.kind_of_proto_story = false;
- storage->UpdateStoryOptions(story_name, std::move(story_options2))->Then([&] {
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // We should see the last value we set.
- done = false;
- storage->GetStoryData(story_name)
- ->Then([&](fuchsia::modular::internal::StoryDataPtr data) {
- EXPECT_FALSE(data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SessionStorageTest, GetStoryStorage) {
- auto storage = CreateStorage("page");
- auto story_name = CreateStory(storage.get());
-
- bool done{};
- auto get_story_future = storage->GetStoryStorage(story_name);
- get_story_future->Then([&](std::unique_ptr<StoryStorage> result) {
- EXPECT_NE(nullptr, result);
- done = true;
- });
-
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SessionStorageTest, GetStoryStorageNoStory) {
- auto storage = CreateStorage("page");
- CreateStory(storage.get());
-
- bool done{};
- auto get_story_future = storage->GetStoryStorage("fake");
- get_story_future->Then([&](std::unique_ptr<StoryStorage> result) {
- EXPECT_EQ(nullptr, result);
- done = true;
- });
-
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SessionStorageTest, ReadSnapshot) {
- std::string kSnapshotData = "snapshot";
-
- auto storage = CreateStorage("page");
- auto story_name = CreateStory(storage.get());
- bool done{};
-
- fsl::SizedVmo snapshot;
- fsl::VmoFromString(kSnapshotData, &snapshot);
- storage->WriteSnapshot(story_name, std::move(snapshot).ToTransport())
- ->Then([&] { done = true; });
- RunLoopUntil([&] { return done; });
-
- done = false;
- storage->ReadSnapshot(story_name)
- ->Then([&](fuchsia::mem::BufferPtr snapshot_ptr) {
- std::string snapshot_string;
- fsl::StringFromVmo(*snapshot_ptr.get(), &snapshot_string);
- EXPECT_EQ(kSnapshotData, snapshot_string);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SessionStorageTest, DeleteStory_DeletesSnapshot) {
- std::string kSnapshotData = "snapshot";
-
- auto storage = CreateStorage("page");
- auto story_name = CreateStory(storage.get());
- bool done{};
-
- fsl::SizedVmo snapshot;
- fsl::VmoFromString(kSnapshotData, &snapshot);
- storage->WriteSnapshot(story_name, std::move(snapshot).ToTransport())
- ->Then([&] { done = true; });
- RunLoopUntil([&] { return done; });
-
- // Deleting the story should delete the snapshot.
- storage->DeleteStory(story_name)->Then([&] { done = true; });
- RunLoopUntil([&] { return done; });
-
- done = false;
- storage->ReadSnapshot(story_name)
- ->Then([&](fuchsia::mem::BufferPtr snapshot_ptr) {
- EXPECT_TRUE(snapshot_ptr == nullptr);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/storage/session_storage_xdr.cc b/bin/sessionmgr/storage/session_storage_xdr.cc
deleted file mode 100644
index b5a31c1..0000000
--- a/bin/sessionmgr/storage/session_storage_xdr.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/storage/session_storage_xdr.h"
-
-#include "peridot/lib/base64url/base64url.h"
-
-namespace modular {
-
-// Serialization and deserialization of fuchsia::modular::internal::StoryData
-// and fuchsia::modular::StoryInfo to and from JSON.
-
-namespace {
-
-fuchsia::ledger::PageId PageIdFromBase64(const std::string& base64) {
- // Both base64 libraries available to us require that we allocate an output
- // buffer large enough to decode any base64 string of the input length, which
- // for us it does not know contains padding since our target size is 16, so we
- // have to allocate an intermediate buffer. Hex would not require this but
- // results in a slightly larger transport size.
-
- std::string decoded;
- fuchsia::ledger::PageId page_id;
-
- if (base64url::Base64UrlDecode(base64, &decoded)) {
- size_t size;
- if (decoded.length() != page_id.id.count()) {
- FXL_LOG(ERROR) << "Unexpected page ID length for " << base64
- << " (decodes to " << decoded.length() << " bytes; "
- << page_id.id.count() << " expected)";
- size = std::min(decoded.length(), page_id.id.count());
- memset(page_id.id.mutable_data(), 0, page_id.id.count());
- } else {
- size = page_id.id.count();
- }
-
- memcpy(page_id.id.mutable_data(), decoded.data(), size);
- } else {
- FXL_LOG(ERROR) << "Unable to decode page ID " << base64;
- }
-
- return page_id;
-}
-
-std::string PageIdToBase64(const fuchsia::ledger::PageId& page_id) {
- return base64url::Base64UrlEncode(
- {reinterpret_cast<const char*>(page_id.id.data()), page_id.id.count()});
-}
-
-// Serialization and deserialization of fuchsia::modular::internal::StoryData
-// and fuchsia::modular::StoryInfo to and from JSON. We have different versions
-// for backwards compatibilty.
-//
-// Version 0: Before FIDL2 conversion. ExtraInfo fields are stored as "key"
-// and "value", page ids are stored as vector.
-void XdrStoryInfoExtraEntry_v0(
- XdrContext* const xdr, fuchsia::modular::StoryInfoExtraEntry* const data) {
- xdr->Field("key", &data->key);
- xdr->Field("value", &data->value);
-}
-
-void XdrStoryInfo_v0(XdrContext* const xdr,
- fuchsia::modular::StoryInfo* const data) {
- xdr->Field("last_focus_time", &data->last_focus_time);
- xdr->Field("url", &data->url);
- xdr->Field("id", &data->id);
- xdr->Field("extra", &data->extra, XdrStoryInfoExtraEntry_v0);
-}
-
-void XdrStoryData_v0(XdrContext* const xdr,
- fuchsia::modular::internal::StoryData* const data) {
- FXL_CHECK(xdr->op() == XdrOp::FROM_JSON)
- << "A back version is never used for writing.";
- data->story_page_id = fuchsia::ledger::PageId::New();
-
- xdr->Field("story_info", &data->story_info, XdrStoryInfo_v0);
- xdr->Field("story_page_id", &data->story_page_id->id);
-}
-
-// Version 1: During FIDL2 conversion. ExtraInfo fields are stored as "key"
-// and "value", page ids are stored as base64 string.
-void XdrStoryInfoExtraEntry_v1(
- XdrContext* const xdr, fuchsia::modular::StoryInfoExtraEntry* const data) {
- xdr->Field("key", &data->key);
- xdr->Field("value", &data->value);
-}
-
-void XdrStoryInfo_v1(XdrContext* const xdr,
- fuchsia::modular::StoryInfo* const data) {
- xdr->Field("last_focus_time", &data->last_focus_time);
- xdr->Field("url", &data->url);
- xdr->Field("id", &data->id);
- xdr->Field("extra", &data->extra, XdrStoryInfoExtraEntry_v1);
-}
-
-void XdrStoryData_v1(XdrContext* const xdr,
- fuchsia::modular::internal::StoryData* const data) {
- static constexpr char kStoryPageId[] = "story_page_id";
- xdr->Field("story_info", &data->story_info, XdrStoryInfo_v1);
- switch (xdr->op()) {
- case XdrOp::FROM_JSON: {
- std::string page_id;
- xdr->Field(kStoryPageId, &page_id);
- if (page_id.empty()) {
- data->story_page_id = nullptr;
- } else {
- data->story_page_id = fuchsia::ledger::PageId::New();
- *data->story_page_id = PageIdFromBase64(page_id);
- }
- break;
- }
- case XdrOp::TO_JSON: {
- std::string page_id;
- if (data->story_page_id) {
- page_id = PageIdToBase64(*data->story_page_id);
- }
- xdr->Field(kStoryPageId, &page_id);
- break;
- }
- }
-}
-
-// Version 2: After FIDL2 conversion was complete. ExtraInfo fields are stored
-// as @k and @v, page ids are stored as array wrapped in a struct.
-void XdrStoryInfoExtraEntry_v2(
- XdrContext* const xdr, fuchsia::modular::StoryInfoExtraEntry* const data) {
- xdr->Field("@k", &data->key);
- xdr->Field("@v", &data->value);
-}
-
-void XdrStoryInfo_v2(XdrContext* const xdr,
- fuchsia::modular::StoryInfo* const data) {
- xdr->Field("last_focus_time", &data->last_focus_time);
- xdr->Field("url", &data->url);
- xdr->Field("id", &data->id);
- xdr->Field("extra", &data->extra, XdrStoryInfoExtraEntry_v2);
-}
-
-void XdrPageId_v2(XdrContext* const xdr, fuchsia::ledger::PageId* const data) {
- xdr->Field("id", &data->id);
-}
-
-void XdrStoryData_v2(XdrContext* const xdr,
- fuchsia::modular::internal::StoryData* const data) {
- xdr->Field("story_info", &data->story_info, XdrStoryInfo_v2);
- xdr->Field("story_page_id", &data->story_page_id, XdrPageId_v2);
-}
-
-// Version 3: ExtraInfo fields are stored as @k and @v, page ids are stored as
-// array, and we set an explicit @version field.
-void XdrStoryData_v3(XdrContext* const xdr,
- fuchsia::modular::internal::StoryData* const data) {
- if (!xdr->Version(3)) {
- return;
- }
- // NOTE(mesch): We reuse subsidiary filters of previous versions as long as we
- // can. Only when they change too we create new versions of them.
- xdr->Field("story_info", &data->story_info, XdrStoryInfo_v2);
- xdr->Field("story_page_id", &data->story_page_id, XdrPageId_v2);
-}
-
-// Version 4: Includes is_kind_of_proto_story field.
-void XdrStoryData_v4(XdrContext* const xdr,
- fuchsia::modular::internal::StoryData* const data) {
- if (!xdr->Version(4)) {
- return;
- }
- // NOTE(mesch): We reuse subsidiary filters of previous versions as long as we
- // can. Only when they change too we create new versions of them.
- xdr->Field("story_info", &data->story_info, XdrStoryInfo_v2);
- xdr->Field("story_page_id", &data->story_page_id, XdrPageId_v2);
-}
-
-// Version 5: Includes story_name field.
-void XdrStoryData_v5(XdrContext* const xdr,
- fuchsia::modular::internal::StoryData* const data) {
- if (!xdr->Version(5)) {
- return;
- }
- // NOTE(mesch): We reuse subsidiary filters of previous versions as long as we
- // can. Only when they change too we create new versions of them.
- xdr->Field("story_info", &data->story_info, XdrStoryInfo_v2);
- xdr->Field("story_name", &data->story_name);
- xdr->Field("story_page_id", &data->story_page_id, XdrPageId_v2);
-}
-
-void XdrStoryOptions_v1(XdrContext* const xdr,
- fuchsia::modular::StoryOptions* const data) {
- xdr->Field("kind_of_proto_story", &data->kind_of_proto_story);
-}
-
-// Version 6: Includes story_options field.
-void XdrStoryData_v6(XdrContext* const xdr,
- fuchsia::modular::internal::StoryData* const data) {
- if (!xdr->Version(6)) {
- return;
- }
- // NOTE(mesch): We reuse subsidiary filters of previous versions as long as we
- // can. Only when they change too we create new versions of them.
- xdr->Field("story_info", &data->story_info, XdrStoryInfo_v2);
- xdr->Field("story_name", &data->story_name);
- xdr->Field("story_options", &data->story_options, XdrStoryOptions_v1);
- xdr->Field("story_page_id", &data->story_page_id, XdrPageId_v2);
-}
-
-} // namespace
-
-// clang-format off
-XdrFilterType<fuchsia::modular::internal::StoryData> XdrStoryData[] = {
- XdrStoryData_v6,
- XdrStoryData_v5,
- XdrStoryData_v4,
- XdrStoryData_v3,
- XdrStoryData_v2,
- XdrStoryData_v1,
- XdrStoryData_v0,
- nullptr,
-};
-// clang-format on
-
-} // namespace modular
diff --git a/bin/sessionmgr/storage/session_storage_xdr.h b/bin/sessionmgr/storage/session_storage_xdr.h
deleted file mode 100644
index 97c0b45..0000000
--- a/bin/sessionmgr/storage/session_storage_xdr.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORAGE_SESSION_STORAGE_XDR_H_
-#define PERIDOT_BIN_SESSIONMGR_STORAGE_SESSION_STORAGE_XDR_H_
-
-#include <fuchsia/modular/internal/cpp/fidl.h>
-
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace modular {
-
-extern XdrFilterType<fuchsia::modular::internal::StoryData> XdrStoryData[];
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORAGE_SESSION_STORAGE_XDR_H_
diff --git a/bin/sessionmgr/storage/story_storage.cc b/bin/sessionmgr/storage/story_storage.cc
deleted file mode 100644
index 070fb17..0000000
--- a/bin/sessionmgr/storage/story_storage.cc
+++ /dev/null
@@ -1,874 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/bin/sessionmgr/storage/story_storage_xdr.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/ledger_client/operations.h"
-
-namespace modular {
-
-namespace {
-
-// TODO(rosswang): replace with |std::string::starts_with| after C++20
-bool StartsWith(const std::string& string, const std::string& prefix) {
- return string.compare(0, prefix.size(), prefix) == 0;
-}
-
-std::string EntityKeyForCookie(const std::string& cookie) {
- return kEntityKeyPrefix + cookie;
-}
-
-std::string EntityTypeKeyForCookie(const std::string& cookie) {
- return kEntityKeyPrefix + cookie + "/type";
-}
-
-std::string CookieFromEntityKey(const std::string& key) {
- return key.substr(sizeof(kEntityKeyPrefix) - 1);
-}
-
-} // namespace
-
-StoryStorage::StoryStorage(LedgerClient* ledger_client,
- fuchsia::ledger::PageId page_id)
- : PageClient("StoryStorage", ledger_client, page_id, "" /* key_prefix */),
- ledger_client_(ledger_client),
- page_id_(page_id),
- weak_ptr_factory_(this) {
- FXL_DCHECK(ledger_client_ != nullptr);
-}
-
-FuturePtr<> StoryStorage::WriteModuleData(ModuleData module_data) {
- auto module_path = fidl::Clone(module_data.module_path);
- return UpdateModuleData(
- module_path, fxl::MakeCopyable([module_data = std::move(module_data)](
- ModuleDataPtr* module_data_ptr) {
- *module_data_ptr = ModuleData::New();
- module_data.Clone(module_data_ptr->get());
- }));
-}
-
-namespace {
-
-struct UpdateModuleDataState {
- std::vector<std::string> module_path;
- std::function<void(ModuleDataPtr*)> mutate_fn;
- OperationQueue sub_operations;
-};
-
-} // namespace
-
-FuturePtr<> StoryStorage::UpdateModuleData(
- const std::vector<std::string>& module_path,
- std::function<void(ModuleDataPtr*)> mutate_fn) {
- auto op_state = std::make_shared<UpdateModuleDataState>();
- op_state->module_path = module_path;
- op_state->mutate_fn = std::move(mutate_fn);
-
- auto key = MakeModuleKey(module_path);
- auto op_body = [this, op_state, key](OperationBase* op) {
- auto did_read =
- Future<ModuleDataPtr>::Create("StoryStorage.UpdateModuleData.did_read");
- op_state->sub_operations.Add(
- new ReadDataCall<ModuleData>(page(), key, true /* not_found_is_ok */,
- XdrModuleData, did_read->Completer()));
-
- auto did_mutate = did_read->AsyncMap(
- [this, op_state, key](ModuleDataPtr current_module_data) {
- auto new_module_data = CloneOptional(current_module_data);
- op_state->mutate_fn(&new_module_data);
-
- if (!new_module_data && !current_module_data) {
- return Future<>::CreateCompleted(
- "StoryStorage.UpdateModuleData.did_mutate");
- }
-
- auto module_data_copy = CloneOptional(new_module_data);
- std::string expected_value;
- XdrWrite(&expected_value, &module_data_copy, XdrModuleData);
-
- if (current_module_data) {
- FXL_DCHECK(new_module_data)
- << "StoryStorage::UpdateModuleData(): mutate_fn() must not "
- "set to null an existing ModuleData record.";
-
- // We complete this Future chain when the Ledger gives us the
- // notification that |module_data| has been written. The Ledger
- // won't do that if the current value for |key| won't change, so
- // we have to short-circuit here.
- // ModuleData contains VMOs, so doing a comparison
- // *new_module_data == *current_module_data won't be true even if
- // the data in the VMOs under the hood is the same. When this
- // happens the ledger won't notify us of any change, since the data
- // was actually the same. To overcome this we compare the raw
- // strings.
- auto current_data_copy = CloneOptional(current_module_data);
- std::string current_value;
- XdrWrite(¤t_value, ¤t_data_copy, XdrModuleData);
- if (current_value == expected_value) {
- return Future<>::CreateCompleted(
- "StoryStorage.UpdateModuleData.did_mutate");
- }
- }
-
- FXL_DCHECK(new_module_data->module_path == op_state->module_path)
- << "StorageStorage::UpdateModuleData(path, ...): mutate_fn() "
- "must set "
- "ModuleData.module_path to |path|.";
-
- op_state->sub_operations.Add(new WriteDataCall<ModuleData>(
- page(), key, XdrModuleData, std::move(module_data_copy), [] {}));
-
- return WaitForWrite(key, expected_value);
- });
-
- return did_mutate;
- };
-
- auto ret = Future<>::Create("StoryStorage.UpdateModuleData.ret");
- operation_queue_.Add(NewCallbackOperation(
- "StoryStorage::UpdateModuleData", std::move(op_body), ret->Completer()));
- return ret;
-}
-
-FuturePtr<ModuleDataPtr> StoryStorage::ReadModuleData(
- const std::vector<std::string>& module_path) {
- auto key = MakeModuleKey(module_path);
- auto ret = Future<ModuleDataPtr>::Create("StoryStorage.ReadModuleData.ret");
- operation_queue_.Add(
- new ReadDataCall<ModuleData>(page(), key, true /* not_found_is_ok */,
- XdrModuleData, ret->Completer()));
- return ret;
-}
-
-FuturePtr<std::vector<ModuleData>> StoryStorage::ReadAllModuleData() {
- auto ret = Future<std::vector<ModuleData>>::Create(
- "StoryStorage.ReadAllModuleData.ret");
- operation_queue_.Add(new ReadAllDataCall<ModuleData>(
- page(), kModuleKeyPrefix, XdrModuleData, ret->Completer()));
- return ret;
-}
-
-StoryStorage::LinkWatcherAutoCancel StoryStorage::WatchLink(
- const LinkPath& link_path, LinkUpdatedCallback callback) {
- auto it = link_watchers_.emplace(MakeLinkKey(link_path), std::move(callback));
-
- auto auto_remove = [weak_this = GetWeakPtr(), it] {
- if (!weak_this)
- return;
-
- weak_this->link_watchers_.erase(it);
- };
-
- return LinkWatcherAutoCancel(std::move(auto_remove));
-}
-
-namespace {
-
-constexpr char kJsonNull[] = "null";
-
-class ReadVmoCall
- : public Operation<fuchsia::ledger::Status, fuchsia::mem::BufferPtr> {
- public:
- ReadVmoCall(PageClient* page_client, fidl::StringPtr key,
- ResultCall result_call)
- : Operation("StoryStorage::ReadVmoCall", std::move(result_call)),
- page_client_(page_client),
- key_(std::move(key)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &status_, &value_};
-
- page_snapshot_ = page_client_->NewSnapshot([this, weak_ptr = GetWeakPtr()] {
- if (!weak_ptr) {
- return;
- }
- // An error occurred getting the snapshot. Resetting page_snapshot_
- // will ensure that the FlowToken it has captured below while waiting for
- // a connected channel will be destroyed, and the operation will be
- // complete.
- status_ = fuchsia::ledger::Status::UNKNOWN_ERROR;
- page_snapshot_ = fuchsia::ledger::PageSnapshotPtr();
- });
-
- page_snapshot_->Get(to_array(key_),
- [this, flow](fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr value) {
- status_ = status;
- value_ = std::move(value);
- });
- }
-
- // Input parameters.
- PageClient* const page_client_;
- const fidl::StringPtr key_;
-
- // Intermediate state.
- fuchsia::ledger::PageSnapshotPtr page_snapshot_;
-
- // Return values.
- fuchsia::ledger::Status status_;
- fuchsia::mem::BufferPtr value_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ReadVmoCall);
-};
-
-// TODO(rosswang): this is a temporary migration helper
-std::tuple<StoryStorage::Status, fidl::StringPtr> ToLinkValue(
- fuchsia::ledger::Status ledger_status,
- fuchsia::mem::BufferPtr ledger_value) {
- StoryStorage::Status link_value_status = StoryStorage::Status::OK;
- fidl::StringPtr link_value;
-
- switch (ledger_status) {
- case fuchsia::ledger::Status::KEY_NOT_FOUND:
- // Leave link_value as a null-initialized StringPtr.
- break;
- case fuchsia::ledger::Status::OK:
- if (!ledger_value) {
- link_value = kJsonNull;
- } else {
- std::string link_value_string;
- if (fsl::StringFromVmo(*ledger_value, &link_value_string)) {
- link_value = std::move(link_value_string);
- } else {
- FXL_LOG(ERROR) << "VMO could not be copied.";
- link_value_status = StoryStorage::Status::VMO_COPY_ERROR;
- }
- }
- break;
- default:
- FXL_LOG(ERROR) << "PageSnapshot.Get() "
- << fidl::ToUnderlying(ledger_status);
- link_value_status = StoryStorage::Status::LEDGER_ERROR;
- break;
- }
-
- return {link_value_status, link_value};
-}
-
-} // namespace
-
-FuturePtr<StoryStorage::Status, std::string> StoryStorage::GetLinkValue(
- const LinkPath& link_path) {
- auto key = MakeLinkKey(link_path);
- auto ret = Future<fuchsia::ledger::Status, fuchsia::mem::BufferPtr>::Create(
- "StoryStorage::GetLinkValue " + key);
- operation_queue_.Add(new ReadVmoCall(this, key, ret->Completer()));
-
- return ret->Map(ToLinkValue)->Map([](Status status, fidl::StringPtr value) {
- return std::make_tuple(status, value ? *value : kJsonNull);
- });
-}
-
-namespace {
-
-class WriteVmoCall : public Operation<StoryStorage::Status> {
- public:
- WriteVmoCall(PageClient* page_client, const std::string& key,
- fuchsia::mem::Buffer value, ResultCall result_call)
- : Operation("StoryStorage::WriteVmoCall", std::move(result_call)),
- page_client_(page_client),
- key_(key),
- value_(std::move(value)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &status_};
- status_ = StoryStorage::Status::OK;
-
- page_client_->page()->CreateReferenceFromBuffer(
- std::move(value_), [this, flow, weak_ptr = GetWeakPtr()](
- fuchsia::ledger::Status status,
- fuchsia::ledger::ReferencePtr reference) {
- if (weak_ptr) {
- if (status == fuchsia::ledger::Status::OK) {
- FXL_DCHECK(reference);
- PutReference(std::move(reference), flow);
- } else {
- FXL_LOG(ERROR) << "StoryStorage.WriteVmoCall " << key_ << " "
- << " Page.CreateReferenceFromBuffer() "
- << fidl::ToUnderlying(status);
- status_ = StoryStorage::Status::LEDGER_ERROR;
- }
- }
- });
- }
-
- void PutReference(fuchsia::ledger::ReferencePtr reference, FlowToken flow) {
- page_client_->page()->PutReference(
- to_array(key_), std::move(*reference), fuchsia::ledger::Priority::EAGER,
- [this, flow, weak_ptr = GetWeakPtr()](fuchsia::ledger::Status status) {
- if (weak_ptr && status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "StoryStorage.WriteVmoCall " << key_ << " "
- << " Page.PutReference() "
- << fidl::ToUnderlying(status);
- status_ = StoryStorage::Status::LEDGER_ERROR;
- }
- });
- }
-
- PageClient* const page_client_;
- std::string key_;
- fuchsia::mem::Buffer value_;
-
- StoryStorage::Status status_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(WriteVmoCall);
-};
-
-// Returns the type of the entity with the associated |cookie|.
-//
-// If no type is found for the given |cookie|, the returned status will be
-// |INVALID_ENTITY_COOKIE|.
-class GetEntityTypeCall
- : public PageOperation<StoryStorage::Status, std::string> {
- public:
- GetEntityTypeCall(PageClient* page_client, const std::string& cookie,
- ResultCall result_call)
- : PageOperation("StoryStorage::GetEntityTypeCall", page_client->page(),
- std::move(result_call)),
- page_client_(page_client),
- cookie_(cookie) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &status_, &type_};
- status_ = StoryStorage::Status::OK;
-
- operation_queue_.Add(new ReadVmoCall(
- page_client_, EntityTypeKeyForCookie(cookie_),
- [this, flow](fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr buffer) {
- if (status == fuchsia::ledger::Status::KEY_NOT_FOUND) {
- status_ = StoryStorage::Status::INVALID_ENTITY_COOKIE;
- return;
- }
-
- if (status != fuchsia::ledger::Status::OK) {
- status_ = StoryStorage::Status::LEDGER_ERROR;
- return;
- }
- if (buffer) {
- FXL_CHECK(fsl::StringFromVmo(*buffer, &type_));
- }
- }));
- }
-
- PageClient* const page_client_;
- const std::string cookie_;
- std::string type_;
- StoryStorage::Status status_;
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(GetEntityTypeCall);
-};
-
-class GetEntityDataCall
- : public PageOperation<StoryStorage::Status, fuchsia::mem::BufferPtr> {
- public:
- GetEntityDataCall(PageClient* page_client, const std::string& cookie,
- const std::string& type, ResultCall result_call)
- : PageOperation("StoryStorage::GetEntityDataCall", page_client->page(),
- std::move(result_call)),
- page_client_(page_client),
- cookie_(cookie),
- type_(type) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &status_, &result_};
- status_ = StoryStorage::Status::OK;
-
- operation_queue_.Add(new GetEntityTypeCall(
- page_client_, cookie_,
- [this, flow](StoryStorage::Status status, const std::string& type) {
- if (status != StoryStorage::Status::OK) {
- status_ = status;
- return;
- }
-
- if (type_ != type) {
- status_ = StoryStorage::Status::INVALID_ENTITY_TYPE;
- return;
- }
-
- operation_queue_.Add(
- new ReadVmoCall(page_client_, EntityKeyForCookie(cookie_),
- [this, flow](fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr buffer) {
- StoryStorage::Status story_status =
- status == fuchsia::ledger::Status::OK
- ? StoryStorage::Status::OK
- : StoryStorage::Status::LEDGER_ERROR;
- status_ = story_status;
- result_ = std::move(buffer);
- }));
- }));
- }
-
- PageClient* const page_client_;
- const std::string cookie_;
- std::string type_;
- fuchsia::mem::BufferPtr result_ = nullptr;
- StoryStorage::Status status_;
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(GetEntityDataCall);
-};
-
-// Sets the type and value of the Entity stored under |cookie|.
-//
-// The type and value are written to separate keys in a single transaction.
-//
-// The |result_call| is wrapped in a function which checks whether or not all
-// the writes were successfull prior to commiting the transaction.
-class SetEntityDataCall : public PageOperation<StoryStorage::Status> {
- public:
- SetEntityDataCall(PageClient* page_client, const std::string& cookie,
- const std::string& type, fuchsia::mem::Buffer value,
- ResultCall result_call)
- : PageOperation(
- "StoryStorage::SetEntityDataCall", page_client->page(),
- [result_call = std::move(result_call),
- page = page_client->page()](StoryStorage::Status status) {
- // The result callback is wrapped in order to commit/rollback the
- // transaction. It's important to note that the operation instance
- // will be deleted by the time this callback is executed.
- if (status == StoryStorage::Status::OK) {
- page->Commit([result_call = std::move(result_call)](
- fuchsia::ledger::Status status) {
- if (status == fuchsia::ledger::Status::OK) {
- result_call(StoryStorage::Status::OK);
- } else {
- result_call(StoryStorage::Status::LEDGER_ERROR);
- }
- });
- } else {
- page->Rollback([result_call = std::move(result_call)](
- fuchsia::ledger::Status status) {});
- result_call(status);
- }
- }),
- page_client_(page_client),
- cookie_(cookie),
- type_(type),
- value_(std::move(value)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &status_};
- status_ = StoryStorage::Status::OK;
- // This transaction will be either committed or rolled back in the wrapped
- // result call.
- page()->StartTransaction([](fuchsia::ledger::Status status) {});
-
- // First verify the type of the data to write matches the existing entity
- // type.
- operation_queue_.Add(new GetEntityTypeCall(
- page_client_, cookie_,
- [this, flow](StoryStorage::Status status, const std::string& type) {
- if (status == StoryStorage::Status::LEDGER_ERROR) {
- status_ = StoryStorage::Status::LEDGER_ERROR;
- return;
- }
-
- if (status == StoryStorage::Status::INVALID_ENTITY_COOKIE ||
- type == type_) {
- // If the type is empty it has never been written before (empty
- // types are not permitted so will not be written in the first
- // place).
- PerformWrites(flow);
- } else {
- status_ = StoryStorage::Status::INVALID_ENTITY_TYPE;
- return;
- }
- }));
- }
-
- void PerformWrites(FlowToken flow) {
- // Write the entity data.
- WriteVmo(std::move(value_), EntityKeyForCookie(cookie_), flow);
-
- // Write the entity type.
- fuchsia::mem::Buffer type_vmo;
- FXL_CHECK(fsl::VmoFromString(type_, &type_vmo));
- WriteVmo(std::move(type_vmo), EntityTypeKeyForCookie(cookie_), flow);
- }
-
- void WriteVmo(fuchsia::mem::Buffer data, const std::string& key,
- FlowToken flow) {
- page()->CreateReferenceFromBuffer(
- std::move(data),
- [this, key, flow](fuchsia::ledger::Status status,
- fuchsia::ledger::ReferencePtr reference) {
- if (status == fuchsia::ledger::Status::OK) {
- FXL_DCHECK(reference);
- PutReference(std::move(reference), key, flow);
- } else {
- FXL_LOG(ERROR) << trace_name() << " "
- << "SetEntityDataCall.CreateReferenceFromBuffer "
- << key << " " << fidl::ToUnderlying(status);
- status_ = StoryStorage::Status::LEDGER_ERROR;
- }
- });
- }
-
- void PutReference(fuchsia::ledger::ReferencePtr reference,
- const std::string& key, FlowToken flow) {
- page()->PutReference(
- to_array(key), std::move(*reference), fuchsia::ledger::Priority::EAGER,
- [this, key, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " "
- << "SetEntityDataCall.PutReference " << key << " "
- << fidl::ToUnderlying(status);
- status_ = StoryStorage::Status::LEDGER_ERROR;
- }
- });
- }
-
- PageClient* const page_client_;
- std::string cookie_;
- std::string type_;
- fuchsia::mem::Buffer value_;
-
- StoryStorage::Status status_;
-
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SetEntityDataCall);
-};
-
-// Returns: 1) if a mutation happened, 2) the status and 3) the new value.
-class UpdateLinkCall
- : public Operation<bool, StoryStorage::Status, fidl::StringPtr> {
- public:
- UpdateLinkCall(
- PageClient* page_client, std::string key,
- std::function<void(fidl::StringPtr*)> mutate_fn,
- std::function<FuturePtr<>(const std::string&, const std::string&)>
- wait_for_write_fn,
- ResultCall done)
- : Operation("StoryStorage::UpdateLinkCall", std::move(done)),
- page_client_(page_client),
- key_(std::move(key)),
- mutate_fn_(std::move(mutate_fn)),
- wait_for_write_fn_(std::move(wait_for_write_fn)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &did_update_, &status_, &new_value_};
-
- operation_queue_.Add(
- new ReadVmoCall(page_client_, key_,
- [this, flow](fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr current_value) {
- fidl::StringPtr json_current_value;
- std::tie(status_, json_current_value) =
- ToLinkValue(status, std::move(current_value));
-
- if (status_ == StoryStorage::Status::OK) {
- Mutate(flow, std::move(json_current_value));
- }
- }));
- }
-
- void Mutate(FlowToken flow, fidl::StringPtr current_value) {
- new_value_ = current_value;
- mutate_fn_(&new_value_);
-
- did_update_ = true;
- if (new_value_ == current_value) {
- did_update_ = false;
- return;
- }
-
- fuchsia::mem::Buffer vmo;
- if (!new_value_ || fsl::VmoFromString(*new_value_, &vmo)) {
- operation_queue_.Add(new WriteVmoCall(
- page_client_, key_, std::move(vmo),
- [this, flow](StoryStorage::Status status) {
- status_ = status;
-
- // If we succeeded AND we set a new value, we need to wait for
- // confirmation from the ledger.
- if (status == StoryStorage::Status::OK && new_value_) {
- wait_for_write_fn_(key_, new_value_)->Then([this, flow] {
- Done(true, std::move(status_), std::move(new_value_));
- });
- }
- }));
- } else {
- FXL_LOG(ERROR) << "VMO could not be copied.";
- status_ = StoryStorage::Status::VMO_COPY_ERROR;
- }
- }
-
- // Input parameters.
- PageClient* const page_client_;
- const std::string key_;
- std::function<void(fidl::StringPtr*)> mutate_fn_;
- std::function<FuturePtr<>(const std::string&, const std::string&)>
- wait_for_write_fn_;
-
- // Operation runtime state.
- OperationQueue operation_queue_;
-
- // Return values.
- bool did_update_;
- StoryStorage::Status status_;
- fidl::StringPtr new_value_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(UpdateLinkCall);
-};
-
-} // namespace
-
-FuturePtr<StoryStorage::Status> StoryStorage::UpdateLinkValue(
- const LinkPath& link_path, std::function<void(fidl::StringPtr*)> mutate_fn,
- const void* context) {
- // nullptr is reserved for updates that came from other instances of
- // StoryStorage.
- FXL_DCHECK(context != nullptr)
- << "StoryStorage::UpdateLinkValue(..., context) of nullptr is reserved.";
-
- auto key = MakeLinkKey(link_path);
- auto did_update = Future<bool, Status, fidl::StringPtr>::Create(
- "StoryStorage.UpdateLinkValue.did_update");
- operation_queue_.Add(new UpdateLinkCall(
- this, key, std::move(mutate_fn),
- std::bind(&StoryStorage::WaitForWrite, this, std::placeholders::_1,
- std::placeholders::_2),
- did_update->Completer()));
-
- // We can't chain this call to the parent future chain because we do
- // not want it to happen at all in the case of errors.
- return did_update->WeakMap(
- GetWeakPtr(),
- [this, key, context](bool did_update, StoryStorage::Status status,
- fidl::StringPtr new_value) {
- // if |new_value| is null, it means we didn't write any new data, even
- // if |status| == OK.
- if (status == StoryStorage::Status::OK && did_update) {
- NotifyLinkWatchers(key, new_value, context);
- }
-
- return status;
- });
-}
-
-FuturePtr<StoryStorage::Status> StoryStorage::SetEntityData(
- const std::string& cookie, const std::string& type,
- fuchsia::mem::Buffer data) {
- auto did_update = Future<StoryStorage::Status>::Create(
- "StoryStorage.CreateEntity.did_update");
- if (type.empty()) {
- did_update->Complete(StoryStorage::Status::INVALID_ENTITY_TYPE);
- } else if (cookie.empty()) {
- did_update->Complete(StoryStorage::Status::INVALID_ENTITY_COOKIE);
- } else {
- operation_queue_.Add(new SetEntityDataCall(
- this, cookie, type, std::move(data), did_update->Completer()));
- }
- return did_update;
-}
-
-FuturePtr<StoryStorage::Status, std::string> StoryStorage::GetEntityType(
- const std::string& cookie) {
- auto did_update = Future<StoryStorage::Status, std::string>::Create(
- "StoryStorage.GetEntityType.did_update");
- operation_queue_.Add(
- new GetEntityTypeCall(this, cookie, did_update->Completer()));
- return did_update;
-}
-
-FuturePtr<StoryStorage::Status, fuchsia::mem::BufferPtr>
-StoryStorage::GetEntityData(const std::string& cookie,
- const std::string& type) {
- auto did_update =
- Future<StoryStorage::Status, fuchsia::mem::BufferPtr>::Create(
- "StoryStorage.GetEntityData.did_update");
- operation_queue_.Add(
- new GetEntityDataCall(this, cookie, type, did_update->Completer()));
- return did_update;
-}
-
-void StoryStorage::WatchEntity(
- const std::string& cookie, const std::string& type,
- fuchsia::modular::EntityWatcherPtr entity_watcher) {
- operation_queue_.Add(new GetEntityDataCall(
- this, cookie, type,
- fxl::MakeCopyable(
- [this, cookie, entity_watcher = std::move(entity_watcher)](
- StoryStorage::Status status,
- std::unique_ptr<fuchsia::mem::Buffer> value) mutable {
- // Send the current value as the initial update.
- entity_watcher->OnUpdated(std::move(value));
-
- auto existing_watchers_it = entity_watchers_.try_emplace(cookie);
- existing_watchers_it.first->second.AddInterfacePtr(
- std::move(entity_watcher));
- })));
-}
-
-FuturePtr<StoryStorage::Status> StoryStorage::SetEntityName(
- const std::string& cookie, const std::string& entity_name) {
- auto did_set = Future<StoryStorage::Status>::Create(
- "StoryStorage.SetEntityName.did_set");
- fuchsia::mem::Buffer data;
- if (fsl::VmoFromString(cookie, &data)) {
- operation_queue_.Add(new WriteVmoCall(this, kEntityNamePrefix + entity_name,
- std::move(data),
- did_set->Completer()));
- } else {
- did_set->Complete(StoryStorage::Status::VMO_COPY_ERROR);
- }
- return did_set;
-}
-
-FuturePtr<StoryStorage::Status, std::string>
-StoryStorage::GetEntityCookieForName(const std::string& entity_name) {
- auto did_get = Future<StoryStorage::Status, std::string>::Create(
- "StoryStorage.GetEntityName.did_get");
- operation_queue_.Add(new ReadVmoCall(
- this, kEntityNamePrefix + entity_name,
- [did_get](fuchsia::ledger::Status status, fuchsia::mem::BufferPtr data) {
- if (status != fuchsia::ledger::Status::OK || !data) {
- did_get->Complete(StoryStorage::Status::LEDGER_ERROR, "");
- return;
- }
- std::string cookie;
- if (!fsl::StringFromVmo(*data, &cookie)) {
- did_get->Complete(StoryStorage::Status::VMO_COPY_ERROR, "");
- return;
- }
-
- did_get->Complete(StoryStorage::Status::OK, std::move(cookie));
- }));
- return did_get;
-}
-
-FuturePtr<> StoryStorage::Sync() {
- auto ret = Future<>::Create("StoryStorage::Sync.ret");
- operation_queue_.Add(NewCallbackOperation("StoryStorage::Sync",
- [](OperationBase* op) {
- return Future<>::CreateCompleted(
- "StoryStorage::Sync");
- },
- ret->Completer()));
- return ret;
-}
-
-void StoryStorage::OnPageChange(const std::string& key,
- fuchsia::mem::BufferPtr value) {
- if (StartsWith(key, kEntityKeyPrefix)) {
- NotifyEntityWatchers(CookieFromEntityKey(key), std::move(*value));
- return;
- }
-
- std::string value_string;
- if (!fsl::StringFromVmo(*value, &value_string)) {
- return;
- }
-
- // If there are any operations waiting on this particular write
- // having happened, tell them to continue.
- auto it = pending_writes_.find({key, value_string});
- bool notify_link_listeners = true;
- if (it != pending_writes_.end()) {
- auto local_futures = std::move(it->second);
- for (auto fut : local_futures) {
- fut->Complete();
- }
-
- // Since the above write originated from this StoryStorage instance,
- // we do not notify any link listeners.
- notify_link_listeners = false;
- }
-
- if (StartsWith(key, kLinkKeyPrefix)) {
- if (notify_link_listeners) {
- NotifyLinkWatchers(key, value_string, nullptr /* context */);
- }
- } else if (StartsWith(key, kModuleKeyPrefix)) {
- if (on_module_data_updated_) {
- auto module_data = ModuleData::New();
- if (!XdrRead(value_string, &module_data, XdrModuleData)) {
- FXL_LOG(ERROR) << "Unable to parse ModuleData " << key << " " << value;
- return;
- }
- on_module_data_updated_(std::move(*module_data));
- }
- } else if (!StartsWith(key, kEntityNamePrefix)) {
- // TODO(thatguy): We store some Link data on the root page (where
- // StoryData is stored) for the session shell to make use of. This means we
- // get notified in that instance of changes we don't care about.
- //
- // Consider putting all story-scoped data under a shared prefix, and use
- // that when initializing the PageClient.
- FXL_LOG(ERROR) << "Unexpected StoryStorage Ledger key prefix: " << key;
- }
-}
-
-void StoryStorage::OnPageDelete(const std::string& key) {
- // ModuleData and Link values are never deleted, although it is
- // theoretically possible that conflict resolution results in a key
- // disappearing. We do not currently do this.
-}
-
-void StoryStorage::OnPageConflict(Conflict* conflict) {
- // TODO(thatguy): Add basic conflict resolution. We can force a conflict for
- // link data in tests by using Page.StartTransaction() in UpdateLinkValue().
- FXL_LOG(WARNING) << "StoryStorage::OnPageConflict() for link key "
- << to_string(conflict->key);
-}
-
-void StoryStorage::NotifyLinkWatchers(const std::string& link_key,
- fidl::StringPtr value,
- const void* context) {
- auto range = link_watchers_.equal_range(link_key);
- for (auto it = range.first; it != range.second; ++it) {
- it->second(value, context);
- }
-}
-
-void StoryStorage::NotifyEntityWatchers(const std::string& cookie,
- fuchsia::mem::Buffer value) {
- auto range = entity_watchers_.equal_range(cookie);
- for (auto it = range.first; it != range.second; ++it) {
- for (const auto& watcher : it->second.ptrs()) {
- fuchsia::mem::Buffer clone;
- fuchsia::mem::Clone(value, &clone);
- (*watcher)->OnUpdated(
- std::make_unique<fuchsia::mem::Buffer>(std::move(clone)));
- }
- }
-}
-
-FuturePtr<> StoryStorage::WaitForWrite(const std::string& key,
- const std::string& value) {
- // TODO(thatguy): It is possible that through conflict resolution, the write
- // we expect to get will never arrive. We must have the conflict resolver
- // update |pending_writes_| with the result of conflict resolution.
- auto did_see_write =
- Future<>::Create("StoryStorage.WaitForWrite.did_see_write");
- pending_writes_[std::make_pair(key, value)].push_back(did_see_write);
- return did_see_write;
-}
-
-fxl::WeakPtr<StoryStorage> StoryStorage::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/storage/story_storage.h b/bin/sessionmgr/storage/story_storage.h
deleted file mode 100644
index 1ed370d..0000000
--- a/bin/sessionmgr/storage/story_storage.h
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_H_
-#define PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_H_
-
-#include <map>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fit/defer.h>
-
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/page_id.h"
-
-using fuchsia::modular::LinkPath;
-using fuchsia::modular::LinkPathPtr;
-using fuchsia::modular::ModuleData;
-using fuchsia::modular::ModuleDataPtr;
-
-namespace modular {
-
-// This class has the following responsibilities:
-//
-// * Manage the persistence of metadata about what mods are part of a single
-// story.
-// * Manage the persistence of link values in a single story.
-// * Observe the metadata and call clients back when changes initiated by other
-// Ledger clients appear.
-//
-// All calls operate directly on the Ledger itself: no local caching is
-// performed.
-class StoryStorage : public PageClient {
- public:
- // Constructs a new StoryStorage with storage on |page_id| in the ledger
- // given by |ledger_client|.
- //
- // |ledger_client| must outlive *this.
- StoryStorage(LedgerClient* ledger_client, fuchsia::ledger::PageId page_id);
-
- enum class Status {
- OK = 0,
- LEDGER_ERROR = 1,
- VMO_COPY_ERROR = 2,
- // Indicates the storage operation detected either an invalid or conflicting
- // entity type (e.g. an empty type string or a write with a mismatched
- // type).
- INVALID_ENTITY_TYPE = 3,
- // Indicates the storage operation detected an invalid entity cookie (e.g.
- // an empty cookie).
- INVALID_ENTITY_COOKIE = 4,
- };
-
- // =========================================================================
- // ModuleData
-
- // Sets the callback that is called whenever ModuleData is added or updated
- // in underlying storage. Excludes notifications for changes (such as with
- // WriteModuleData() or UpdateModuleData()) made on this instance of
- // StoryStorage.
- void set_on_module_data_updated(std::function<void(ModuleData)> callback) {
- on_module_data_updated_ = std::move(callback);
- }
-
- // Returns the current ModuleData for |module_path|. If not found, the
- // returned value is null.
- FuturePtr<ModuleDataPtr> ReadModuleData(
- const std::vector<std::string>& module_path);
-
- // Writes |module_data| to storage. The returned future is completed
- // once |module_data| has been written and a notification confirming the
- // write has been received.
- FuturePtr<> WriteModuleData(ModuleData module_data);
-
- // Reads the ModuleData for |module_path|, calls |mutate_fn| which may modify
- // the contents, and writes the resulting ModuleData back to storage.
- // Completes the returned future once a notification confirming the write has
- // been received.
- //
- // If there is no ModuleData for |module_path|, |mutate_fn| will be called
- // with a null ModuleDataPtr. |mutate_fn| may initialize the ModuleDataPtr,
- // in which case a new ModuleData record will be written.
- //
- // It is illegal to change ModuleDataPtr->module_path in |mutate_fn| or to
- // reset to null an otherwise initialized ModuleDataPtr.
- FuturePtr<> UpdateModuleData(
- const std::vector<std::string>& module_path,
- std::function<void(ModuleDataPtr*)> mutate_fn);
-
- // Returns all ModuleData entries for all mods.
- FuturePtr<std::vector<ModuleData>> ReadAllModuleData();
-
- // =========================================================================
- // Link data
-
- // Use with WatchLink below.
- //
- // Called whenever a change occurs to the link specified in
- // WatchLink(). The receiver gets the LinkPath, the current
- // |value| and whatever |context| was passed into the mutation call. If
- // the new value did not originate from a call on *this, |context| will be
- // given the special value of nullptr.
- using LinkUpdatedCallback =
- std::function<void(const fidl::StringPtr& value, const void* context)>;
- using LinkWatcherAutoCancel = fit::deferred_action<std::function<void()>>;
-
- // Registers |callback| to be invoked whenever a change to the link value at
- // |link_path| occurs. See documentation for LinkUpdatedCallback above. The
- // returned LinkWatcherAutoCancel must be kept alive as long as the callee
- // wishes to receive link updates on |callback|.
- LinkWatcherAutoCancel WatchLink(const LinkPath& link_path,
- LinkUpdatedCallback callback);
-
- // Returns the value for |link_path|.
- //
- // The returned value will be stringified JSON. If no value is found, returns
- // "null", the JSON string for a null value.
- FuturePtr<Status, std::string> GetLinkValue(const LinkPath& link_path);
-
- // Fetches the link value at |link_path| and passes it to |mutate_fn|.
- // |mutate_fn| must synchronously update the StringPtr with the desired new
- // value for the link and return. The new value will be written to storage
- // and the returned future completed with the status.
- //
- // |mutate_fn|'s |value| points to the current value for the link and may be
- // modified. If the link is new and has no value, value->is_null() will be
- // true. Otherwise, *value will be valid JSON and must remain valid JSON
- // after |mutate_fn| is done.
- //
- // |context| is carried with the mutation operation and passed to any
- // notifications about this change on this instance of StoryStorage. A value
- // of nullptr for |context| is illegal.
- FuturePtr<Status> UpdateLinkValue(
- const LinkPath& link_path,
- std::function<void(fidl::StringPtr* value)> mutate_fn,
- const void* context);
-
- // Sets the type and data for the Entity stored under |cookie|.
- //
- // |type| If Entity data has already been written, this type is expected to
- // match the type which was previously written.
- // |data| The data to write to the Entity.
- FuturePtr<Status> SetEntityData(const std::string& cookie,
- const std::string& type,
- fuchsia::mem::Buffer data);
-
- // Returns the type for the Entity stored under the provided |cookie|.
- //
- // If an error occurred the Status will indicate the error, and returned
- // string will be empty.
- FuturePtr<Status, std::string> GetEntityType(const std::string& cookie);
-
- // Returns the data for the Entity stored under the provided |cookie|.
- //
- // |type| The expected type of the data.
- //
- // If an error occurred the Status will indicate the error, and returned
- // fuchsia::mem::BufferPtr will be nullptr.
- FuturePtr<Status, fuchsia::mem::BufferPtr> GetEntityData(
- const std::string& cookie, const std::string& type);
-
- // Registers a watcher for an Entity. The EntityWatcher is notified of data
- // changes until it is closed.
- //
- // |cookie| The Entity cookie.
- // |type| The type of the observed entity data.
- // |watcher| The entity watcher which will get notified of updates to the
- // entity stored under |cookie|.
- void WatchEntity(const std::string& cookie, const std::string& type,
- fuchsia::modular::EntityWatcherPtr watcher);
-
- // Sets the |entity_name| of the Entity associated with |cookie|.
- //
- // Once an entity has been named, the associated |cookie| can be retrieved by
- // calling |GetEntityCookieForName|.
- FuturePtr<Status> SetEntityName(const std::string& cookie,
- const std::string& entity_name);
-
- // Gets the Entity cookie associated with the specified name.
- FuturePtr<Status, std::string> GetEntityCookieForName(
- const std::string& entity_name);
-
- // Completes the returned future after all prior methods have completed.
- FuturePtr<> Sync();
-
- private:
- // |PageClient|
- void OnPageChange(const std::string& key,
- fuchsia::mem::BufferPtr value) override;
-
- // |PageClient|
- void OnPageDelete(const std::string& key) override;
-
- // |PageClient|
- void OnPageConflict(Conflict* conflict) override;
-
- // Notifies any watchers in |link_watchers_|.
- //
- // |value| will never be a null StringPtr. |value| is always a JSON-encoded
- // string, so a null value will be presented as the string "null".
- void NotifyLinkWatchers(const std::string& link_key, fidl::StringPtr value,
- const void* context);
-
- // Notifies any watchers in |entity_watchers_[cookie]|.
- //
- // |value| is a valid fuchsia::mem::Buffer.
- void NotifyEntityWatchers(const std::string& cookie,
- fuchsia::mem::Buffer value);
-
- // Completes the returned Future when the ledger notifies us (through
- // OnPageChange()) of a write for |key| with |value|.
- FuturePtr<> WaitForWrite(const std::string& key, const std::string& value);
-
- fxl::WeakPtr<StoryStorage> GetWeakPtr();
-
- LedgerClient* const ledger_client_;
- const fuchsia::ledger::PageId page_id_;
- // NOTE: This operation queue serializes all link operations, even though
- // operations on different links do not have an impact on each other. Consider
- // adding an OperationQueue per link if we want to increase concurrency.
- OperationQueue operation_queue_;
-
- // Called when new ModuleData is encountered from the Ledger.
- std::function<void(ModuleData)> on_module_data_updated_;
-
- // A map of link ledger key -> watcher callback. Multiple clients can watch
- // the same Link.
- std::multimap<std::string, LinkUpdatedCallback> link_watchers_;
-
- // A map of Entity cookie (i.e. Ledger key) -> set of watchers. Multiple
- // watchers can watch the same entity.
- std::map<std::string, fidl::InterfacePtrSet<fuchsia::modular::EntityWatcher>>
- entity_watchers_;
-
- // A map of ledger (key, value) to (vec of future). When we see a
- // notification in OnPageChange() for a matching (key, value), we complete
- // all the respective futures.
- //
- // NOTE: we use a map<> of vector<> here instead of a multimap<> because we
- // complete all the Futures for a given key/value pair at once.
- std::map<std::pair<std::string, std::string>, std::vector<FuturePtr<>>>
- pending_writes_;
-
- fxl::WeakPtrFactory<StoryStorage> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryStorage);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_H_
diff --git a/bin/sessionmgr/storage/story_storage_unittest.cc b/bin/sessionmgr/storage/story_storage_unittest.cc
deleted file mode 100644
index 0e58dd9..0000000
--- a/bin/sessionmgr/storage/story_storage_unittest.cc
+++ /dev/null
@@ -1,771 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-
-#include <memory>
-
-#include <lib/async/cpp/future.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/entity/entity_watcher_impl.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/testing/test_with_ledger.h"
-
-using fuchsia::modular::ModuleData;
-using fuchsia::modular::ModuleDataPtr;
-
-namespace modular {
-namespace {
-
-class StoryStorageTest : public testing::TestWithLedger {
- protected:
- std::unique_ptr<StoryStorage> CreateStorage(std::string page_id) {
- return std::make_unique<StoryStorage>(ledger_client(), MakePageId(page_id));
- }
-};
-
-ModuleData Clone(const ModuleData& data) {
- ModuleData dup;
- data.Clone(&dup);
- return dup;
-}
-
-TEST_F(StoryStorageTest, ReadModuleData_NonexistentModule) {
- auto storage = CreateStorage("page");
-
- bool read_done{};
- std::vector<std::string> path;
- path.push_back("a");
- storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
- read_done = true;
- ASSERT_FALSE(data);
- });
-
- RunLoopUntil([&] { return read_done; });
-}
-
-TEST_F(StoryStorageTest, ReadAllModuleData_Empty) {
- auto storage = CreateStorage("page");
-
- bool read_done{};
- fidl::VectorPtr<ModuleData> all_module_data;
- storage->ReadAllModuleData()->Then([&](std::vector<ModuleData> data) {
- read_done = true;
- all_module_data.reset(std::move(data));
- });
-
- RunLoopUntil([&] { return read_done; });
- ASSERT_TRUE(all_module_data);
- EXPECT_EQ(0u, all_module_data->size());
-}
-
-TEST_F(StoryStorageTest, WriteReadModuleData) {
- // Write and then read some ModuleData entries. We expect to get the same data
- // back.
- auto storage = CreateStorage("page");
-
- int notification_count{0};
- storage->set_on_module_data_updated(
- [&](ModuleData) { notification_count++; });
-
- ModuleData module_data1;
- module_data1.module_url = "url1";
- module_data1.module_path.push_back("path1");
- storage->WriteModuleData(Clone(module_data1));
-
- ModuleData module_data2;
- module_data2.module_url = "url2";
- module_data2.module_path.push_back("path2");
- storage->WriteModuleData(Clone(module_data2));
-
- // We don't need to explicitly wait on WriteModuleData() because the
- // implementation: 1) serializes all storage operations and 2) guarantees the
- // WriteModuleData() action is finished only once the data has been written.
- ModuleData read_data1;
- bool read1_done{};
- storage->ReadModuleData(module_data1.module_path)
- ->Then([&](ModuleDataPtr data) {
- read1_done = true;
- ASSERT_TRUE(data);
- read_data1 = std::move(*data);
- });
-
- ModuleData read_data2;
- bool read2_done{};
- storage->ReadModuleData(module_data2.module_path)
- ->Then([&](ModuleDataPtr data) {
- read2_done = true;
- ASSERT_TRUE(data);
- read_data2 = std::move(*data);
- });
-
- RunLoopUntil([&] { return read1_done && read2_done; });
- EXPECT_EQ(module_data1, read_data1);
- EXPECT_EQ(module_data2, read_data2);
-
- // Read the same data back with ReadAllModuleData().
- fidl::VectorPtr<ModuleData> all_module_data;
- storage->ReadAllModuleData()->Then([&](std::vector<ModuleData> data) {
- all_module_data.reset(std::move(data));
- });
- RunLoopUntil([&] { return !!all_module_data; });
- EXPECT_EQ(2u, all_module_data->size());
- EXPECT_EQ(module_data1, all_module_data->at(0));
- EXPECT_EQ(module_data2, all_module_data->at(1));
-
- // We should get a notification every time module data is updated.
- EXPECT_EQ(2, notification_count);
-}
-
-TEST_F(StoryStorageTest, UpdateModuleData) {
- // Call UpdateModuleData() on a record that doesn't exist yet.
- auto storage = CreateStorage("page");
-
- // We're going to observe changes on another storage instance, which
- // simulates another device.
- auto other_storage = CreateStorage("page");
- bool got_notification{};
- ModuleData notified_module_data;
- other_storage->set_on_module_data_updated([&](ModuleData data) {
- got_notification = true;
- notified_module_data = std::move(data);
- });
-
- std::vector<std::string> path;
- path.push_back("a");
-
- // Case 1: Don't mutate anything.
- bool update_done{};
- storage
- ->UpdateModuleData(path, [](ModuleDataPtr* ptr) { EXPECT_FALSE(*ptr); })
- ->Then([&] { update_done = true; });
- RunLoopUntil([&] { return update_done; });
-
- bool read_done{};
- ModuleData read_data;
- storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
- read_done = true;
- EXPECT_FALSE(data);
- });
- RunLoopUntil([&] { return read_done; });
- // Since nothing changed, we should not have seen a notification.
- EXPECT_FALSE(got_notification);
-
- // Case 2: Initialize an otherwise empty record.
- update_done = false;
- storage
- ->UpdateModuleData(path,
- [&](ModuleDataPtr* ptr) {
- EXPECT_FALSE(*ptr);
-
- *ptr = ModuleData::New();
- (*ptr)->module_path = path;
- (*ptr)->module_url = "foobar";
- })
- ->Then([&] { update_done = true; });
- RunLoopUntil([&] { return update_done; });
-
- read_done = false;
- storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
- read_done = true;
- ASSERT_TRUE(data);
- EXPECT_EQ(path, data->module_path);
- EXPECT_EQ("foobar", data->module_url);
- });
- RunLoopUntil([&] { return read_done; });
- // Now something changed, so we should see a notification.
- EXPECT_TRUE(got_notification);
- EXPECT_EQ("foobar", notified_module_data.module_url);
-
- // Case 3: Leave alone an existing record.
- got_notification = false;
- storage->UpdateModuleData(path,
- [&](ModuleDataPtr* ptr) { EXPECT_TRUE(*ptr); });
-
- read_done = false;
- storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
- read_done = true;
- ASSERT_TRUE(data);
- EXPECT_EQ("foobar", data->module_url);
- });
- RunLoopUntil([&] { return read_done; });
- // Now something changed, so we should see a notification.
- EXPECT_FALSE(got_notification);
-
- // Case 4: Mutate an existing record.
- storage->UpdateModuleData(path, [&](ModuleDataPtr* ptr) {
- EXPECT_TRUE(*ptr);
- (*ptr)->module_url = "baz";
- });
-
- read_done = false;
- storage->ReadModuleData(path)->Then([&](ModuleDataPtr data) {
- read_done = true;
- ASSERT_TRUE(data);
- EXPECT_EQ("baz", data->module_url);
- });
- RunLoopUntil([&] { return read_done; });
- // Now something changed, so we should see a notification.
- EXPECT_TRUE(got_notification);
- EXPECT_EQ("baz", notified_module_data.module_url);
-}
-
-namespace {
-LinkPath MakeLinkPath(const std::string& name) {
- LinkPath path;
- path.link_name = name;
- return path;
-}
-} // namespace
-
-TEST_F(StoryStorageTest, GetLink_Null) {
- auto storage = CreateStorage("page");
-
- // Default for an un-set Link is to get a "null" back.
- bool get_done{};
- fidl::StringPtr value;
- storage->GetLinkValue(MakeLinkPath("link"))
- ->Then([&](StoryStorage::Status status, fidl::StringPtr v) {
- EXPECT_EQ(StoryStorage::Status::OK, status);
- value = v;
- get_done = true;
- });
- RunLoopUntil([&] { return get_done; });
- EXPECT_EQ("null", value);
-}
-
-TEST_F(StoryStorageTest, UpdateLinkValue) {
- auto storage = CreateStorage("page");
-
- // Let's set a value.
- int mutate_count{0};
- int context;
- storage
- ->UpdateLinkValue(MakeLinkPath("link"),
- [](fidl::StringPtr* current_value) {
- EXPECT_TRUE(current_value->is_null());
- *current_value = "10";
- },
- &context)
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(StoryStorage::Status::OK, status);
- ++mutate_count;
- });
-
- // If we mutate again, we should see the old value.
- storage
- ->UpdateLinkValue(MakeLinkPath("link"),
- [](fidl::StringPtr* current_value) {
- EXPECT_EQ("10", *current_value);
- *current_value = "20";
- },
- &context)
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(StoryStorage::Status::OK, status);
- ++mutate_count;
- });
-
- // Now let's fetch it and see the newest value.
- bool get_done{};
- fidl::StringPtr value;
- storage->GetLinkValue(MakeLinkPath("link"))
- ->Then([&](StoryStorage::Status status, fidl::StringPtr v) {
- EXPECT_EQ(StoryStorage::Status::OK, status);
- value = v;
- get_done = true;
- });
- RunLoopUntil([&] { return get_done; });
-
- EXPECT_EQ(2, mutate_count);
- EXPECT_EQ("20", value);
-}
-
-TEST_F(StoryStorageTest, WatchingLink_IgnoresOthers) {
- // When we watch a link, we should see changes only for that link.
- auto storage = CreateStorage("page");
-
- // We'll be watching "foo", but updating "bar".
- int notified_count{0};
- auto cancel =
- storage->WatchLink(MakeLinkPath("foo"),
- [&](const fidl::StringPtr& value,
- const void* /* context */) { ++notified_count; });
-
- bool mutate_done{};
- int context;
- storage
- ->UpdateLinkValue(MakeLinkPath("bar"),
- [](fidl::StringPtr* value) { *value = "10"; }, &context)
- ->Then([&](StoryStorage::Status status) { mutate_done = true; });
- RunLoopUntil([&] { return mutate_done; });
- EXPECT_EQ(0, notified_count);
-}
-
-TEST_F(StoryStorageTest, WatchingLink_IgnoresNoopUpdates) {
- // When we watch a link, we should see changes only for that link.
- auto storage = CreateStorage("page");
-
- int notified_count{0};
- auto cancel =
- storage->WatchLink(MakeLinkPath("foo"),
- [&](const fidl::StringPtr& value,
- const void* /* context */) { ++notified_count; });
-
- bool mutate_done{};
- int context;
- storage
- ->UpdateLinkValue(MakeLinkPath("foo"),
- [](fidl::StringPtr* value) { /* do nothing */ },
- &context)
- ->Then([&](StoryStorage::Status status) { mutate_done = true; });
- RunLoopUntil([&] { return mutate_done; });
- EXPECT_EQ(0, notified_count);
-}
-
-TEST_F(StoryStorageTest, WatchingLink_SeesUpdates) {
- // When we make changes to Link values, we should see those changes in our
- // observation functions. When we cancel the observer, we shouldn't see any
- // more notifications.
- auto storage = CreateStorage("page");
-
- // We'll tell StoryStorage to stop notifying us about "bar" later by using
- // |bar_cancel|.
- int notified_count{0};
- fidl::StringPtr notified_value;
- const void* notified_context;
- auto watch_cancel = storage->WatchLink(
- MakeLinkPath("bar"),
- [&](const fidl::StringPtr& value, const void* context) {
- ++notified_count;
- notified_value = value;
- notified_context = context;
- });
-
- // Change "bar"'s value to "10".
- bool mutate_done{};
- int context;
- storage
- ->UpdateLinkValue(MakeLinkPath("bar"),
- [](fidl::StringPtr* value) { *value = "10"; }, &context)
- ->Then([&](StoryStorage::Status status) { mutate_done = true; });
- RunLoopUntil([&] { return mutate_done; });
- EXPECT_EQ(1, notified_count);
- EXPECT_EQ("10", notified_value);
- EXPECT_EQ(&context, notified_context);
-
- // Change it two more times. We expect to be notified of the first one, but
- // not the second because we are going to cancel our watcher.
- storage
- ->UpdateLinkValue(MakeLinkPath("bar"),
- [](fidl::StringPtr* value) { *value = "20"; }, &context)
- ->Then([&](StoryStorage::Status status) {
- watch_cancel.call(); // Remove the watcher for bar.
- });
-
- mutate_done = false;
- storage
- ->UpdateLinkValue(MakeLinkPath("bar"),
- [](fidl::StringPtr* value) { *value = "30"; }, &context)
- ->Then([&](StoryStorage::Status status) { mutate_done = true; });
- RunLoopUntil([&] { return mutate_done; });
-
- EXPECT_EQ(2, notified_count);
- EXPECT_EQ("20", notified_value);
- EXPECT_EQ(&context, notified_context);
-}
-
-TEST_F(StoryStorageTest, WatchingOtherStorageInstance) {
- // Observations made on other StoryStorage instances get a special nullptr
- // context.
- auto storage = CreateStorage("page");
-
- auto other_storage = CreateStorage("page");
-
- int notified_count{0};
- fidl::StringPtr notified_value;
- const void* notified_context;
- auto watch_cancel = other_storage->WatchLink(
- MakeLinkPath("foo"),
- [&](const fidl::StringPtr& value, const void* context) {
- ++notified_count;
- notified_value = value;
- notified_context = context;
- return true;
- });
-
- int context;
- storage->UpdateLinkValue(MakeLinkPath("foo"),
- [](fidl::StringPtr* value) { *value = "10"; },
- &context);
-
- RunLoopUntil([&] { return notified_count > 0; });
- EXPECT_EQ(1, notified_count);
- EXPECT_EQ("10", notified_value);
- EXPECT_EQ(nullptr, notified_context);
-}
-
-// Creates an entity with a valid type and data and verifies they are returned
-// as expected.
-TEST_F(StoryStorageTest, CreateAndReadEntity) {
- auto storage = CreateStorage("page");
- std::string cookie = "cookie";
- std::string expected_type = "com.fuchsia.test.type";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- bool created_entity{};
- storage->SetEntityData(cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::OK);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
-
- bool read_entity_type{};
- storage->GetEntityType(cookie)->Then(
- [&](StoryStorage::Status status, std::string type) {
- EXPECT_EQ(type, expected_type);
- read_entity_type = true;
- });
- RunLoopUntil([&] { return read_entity_type; });
-
- bool read_entity_data{};
- storage->GetEntityData(cookie, expected_type)
- ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
- EXPECT_TRUE(buffer);
- std::string read_data;
- EXPECT_TRUE(fsl::StringFromVmo(*buffer, &read_data));
- EXPECT_EQ(read_data, data_string);
- read_entity_data = true;
- });
- RunLoopUntil([&] { return read_entity_data; });
-}
-
-// Creates an entity with a valid type and data and attempts to get the data of
-// a different type.
-TEST_F(StoryStorageTest, CreateAndReadEntityIncorrectType) {
- auto storage = CreateStorage("page");
- std::string cookie = "cookie";
- std::string expected_type = "com.fuchsia.test.type";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- bool created_entity{};
- storage->SetEntityData(cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::OK);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
-
- bool read_entity_data{};
- storage->GetEntityData(cookie, expected_type + expected_type)
- ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
- EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_TYPE);
- read_entity_data = true;
- });
- RunLoopUntil([&] { return read_entity_data; });
-}
-
-// Creates an entity with a valid type and data and attempts to get the data of
-// a different cookie.
-TEST_F(StoryStorageTest, CreateAndReadEntityIncorrectCookie) {
- auto storage = CreateStorage("page");
- std::string cookie = "cookie";
- std::string expected_type = "com.fuchsia.test.type";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- bool created_entity{};
- storage->SetEntityData(cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::OK);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
-
- bool read_entity_data{};
- storage->GetEntityData(cookie + cookie, expected_type)
- ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
- EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_COOKIE);
- read_entity_data = true;
- });
- RunLoopUntil([&] { return read_entity_data; });
-}
-
-// Attempts to create an entity with an empty type and verifies it fails.
-TEST_F(StoryStorageTest, CreateEntityWithEmptyType) {
- auto storage = CreateStorage("page");
- std::string cookie = "cookie";
- std::string expected_type = "";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- bool created_entity{};
- storage->SetEntityData(cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_TYPE);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
-}
-
-// Attempts to create an entity with an empty cookie and verifies it fails.
-TEST_F(StoryStorageTest, CreateEntityWithEmptyCookie) {
- auto storage = CreateStorage("page");
- std::string cookie = "";
- std::string expected_type = "com.fuchsia.test.type";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- bool created_entity{};
- storage->SetEntityData(cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_COOKIE);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
-}
-
-// Creates an entity and performs a second write with a different type, and
-// verifies the second write fails and that the second attempted write doesn't
-// corrupt the data.
-TEST_F(StoryStorageTest, WriteEntityDataWithIncorrectType) {
- auto storage = CreateStorage("page");
- std::string cookie = "cookie";
- std::string expected_type = "com.fuchsia.test.type";
- std::string incorrect_type = "com.fuchsia.test.incorrect.type";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- bool created_entity{};
- storage->SetEntityData(cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::OK);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
-
- bool wrote_entity{};
- storage->SetEntityData(cookie, incorrect_type, fuchsia::mem::Buffer())
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::INVALID_ENTITY_TYPE);
- wrote_entity = true;
- });
- RunLoopUntil([&] { return wrote_entity; });
-
- // Verify that the second write didn't mess up the data or type.
- bool read_entity_type{};
- storage->GetEntityType(cookie)->Then(
- [&](StoryStorage::Status status, std::string type) {
- EXPECT_EQ(type, expected_type);
- read_entity_type = true;
- });
- RunLoopUntil([&] { return read_entity_type; });
-
- bool read_entity_data{};
- storage->GetEntityData(cookie, expected_type)
- ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
- EXPECT_TRUE(buffer);
- std::string read_data;
- EXPECT_TRUE(fsl::StringFromVmo(*buffer, &read_data));
- EXPECT_EQ(read_data, data_string);
- read_entity_data = true;
- });
- RunLoopUntil([&] { return read_entity_data; });
-}
-
-// Creates an entity and performs a second write with the same type, and
-// verifies the data is written correctly.
-TEST_F(StoryStorageTest, WriteToEntityTwice) {
- auto storage = CreateStorage("page");
- std::string cookie = "cookie";
- std::string expected_type = "com.fuchsia.test.type";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- std::string second_data_string = "more_test_data";
- fuchsia::mem::Buffer second_buffer;
- FXL_CHECK(fsl::VmoFromString(second_data_string, &second_buffer));
-
- bool created_entity{};
- storage->SetEntityData(cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::OK);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
-
- bool wrote_entity{};
- storage->SetEntityData(cookie, expected_type, std::move(second_buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::OK);
- wrote_entity = true;
- });
- RunLoopUntil([&] { return wrote_entity; });
-
- // Verify that the second write successfully updated the data.
- bool read_entity_type{};
- storage->GetEntityType(cookie)->Then(
- [&](StoryStorage::Status status, std::string type) {
- EXPECT_EQ(type, expected_type);
- read_entity_type = true;
- });
- RunLoopUntil([&] { return read_entity_type; });
-
- bool read_entity_data{};
- storage->GetEntityData(cookie, expected_type)
- ->Then([&](StoryStorage::Status status, fuchsia::mem::BufferPtr buffer) {
- EXPECT_TRUE(buffer);
- std::string read_data;
- EXPECT_TRUE(fsl::StringFromVmo(*buffer, &read_data));
- EXPECT_EQ(read_data, second_data_string);
- read_entity_data = true;
- });
- RunLoopUntil([&] { return read_entity_data; });
-}
-
-// Creates an entity with a watcher and verifies that updates to the entity are
-// delivered to the watcher.
-TEST_F(StoryStorageTest, WatchEntityData) {
- auto storage = CreateStorage("page");
- std::string expected_cookie = "cookie";
- std::string expected_type = "com.fuchsia.test.type";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- bool saw_entity_update{};
- bool saw_entity_update_with_no_data{};
- auto watcher_impl =
- EntityWatcherImpl([&](std::unique_ptr<fuchsia::mem::Buffer> value) {
- // Verify that the first callback is called with no data, since the
- // entity data has yet to be set.
- if (!value && !saw_entity_update_with_no_data) {
- saw_entity_update_with_no_data = true;
- return;
- }
-
- ASSERT_TRUE(value) << "Saw multiple empty entity updates.";
-
- std::string read_data;
- EXPECT_TRUE(fsl::StringFromVmo(*value, &read_data));
- EXPECT_EQ(read_data, data_string);
-
- saw_entity_update = true;
- });
-
- fuchsia::modular::EntityWatcherPtr watcher_ptr;
- watcher_impl.Connect(watcher_ptr.NewRequest());
-
- storage->WatchEntity(expected_cookie, expected_type, std::move(watcher_ptr));
-
- bool created_entity{};
- storage->SetEntityData(expected_cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::OK);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
- RunLoopUntil([&] { return saw_entity_update; });
- EXPECT_TRUE(saw_entity_update_with_no_data);
-}
-
-// Creates an entity with multiple watchers and verifies that updates to the
-// entity are delivered to all watchers.
-TEST_F(StoryStorageTest, WatchEntityDataMultipleWatchers) {
- auto storage = CreateStorage("page");
- std::string expected_cookie = "cookie";
- std::string expected_type = "com.fuchsia.test.type";
-
- std::string data_string = "test_data";
- fuchsia::mem::Buffer buffer;
- FXL_CHECK(fsl::VmoFromString(data_string, &buffer));
-
- bool saw_entity_update{};
- auto watcher_impl =
- EntityWatcherImpl([&](std::unique_ptr<fuchsia::mem::Buffer> value) {
- if (!value) {
- // The first update may not contain any data, so skip it.
- return;
- }
-
- std::string read_data;
- EXPECT_TRUE(fsl::StringFromVmo(*value, &read_data));
- EXPECT_EQ(read_data, data_string);
-
- saw_entity_update = true;
- });
-
- fuchsia::modular::EntityWatcherPtr watcher_ptr;
- watcher_impl.Connect(watcher_ptr.NewRequest());
- storage->WatchEntity(expected_cookie, expected_type, std::move(watcher_ptr));
-
- bool saw_entity_update_too{};
- auto second_watcher_impl =
- EntityWatcherImpl([&](std::unique_ptr<fuchsia::mem::Buffer> value) {
- if (!value) {
- // The first update may not contain any data, so skip it.
- return;
- }
-
- std::string read_data;
- EXPECT_TRUE(fsl::StringFromVmo(*value, &read_data));
- EXPECT_EQ(read_data, data_string);
-
- saw_entity_update_too = true;
- });
-
- fuchsia::modular::EntityWatcherPtr second_watcher_ptr;
- second_watcher_impl.Connect(second_watcher_ptr.NewRequest());
- storage->WatchEntity(expected_cookie, expected_type,
- std::move(second_watcher_ptr));
-
- bool created_entity{};
- storage->SetEntityData(expected_cookie, expected_type, std::move(buffer))
- ->Then([&](StoryStorage::Status status) {
- EXPECT_EQ(status, StoryStorage::Status::OK);
- created_entity = true;
- });
- RunLoopUntil([&] { return created_entity; });
- RunLoopUntil([&] { return saw_entity_update && saw_entity_update_too; });
-}
-
-// Creates a name for a given Entity cookie and verifies it is retrieved
-// successfully.
-TEST_F(StoryStorageTest, NameEntity) {
- auto storage = CreateStorage("page");
- std::string expected_cookie = "cookie";
- std::string expected_name = "the best entity";
-
- storage->SetEntityName(expected_cookie, expected_name);
-
- bool did_get_cookie{};
- storage->GetEntityCookieForName(expected_name)
- ->Then([&](StoryStorage::Status status, const std::string& cookie) {
- EXPECT_EQ(cookie, expected_cookie);
- did_get_cookie = true;
- });
- RunLoopUntil([&] { return did_get_cookie; });
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/storage/story_storage_xdr.cc b/bin/sessionmgr/storage/story_storage_xdr.cc
deleted file mode 100644
index baed8c6..0000000
--- a/bin/sessionmgr/storage/story_storage_xdr.cc
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/storage/story_storage_xdr.h"
-#include "peridot/lib/module_manifest/module_manifest_xdr.h"
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fsl/vmo/strings.h>
-
-namespace modular {
-
-void XdrLinkPath(XdrContext* const xdr,
- fuchsia::modular::LinkPath* const data) {
- xdr->Field("module_path", &data->module_path);
- xdr->Field("link_name", &data->link_name);
-}
-
-void XdrModuleParameterMapEntry(
- XdrContext* const xdr,
- fuchsia::modular::ModuleParameterMapEntry* const data) {
- // NOTE: the JSON field naming doesn't match the FIDL struct naming because
- // the field names in FIDL were changed.
- xdr->Field("key", &data->name);
- xdr->Field("link_path", &data->link_path, XdrLinkPath);
-}
-
-void XdrModuleParameterMap(XdrContext* const xdr,
- fuchsia::modular::ModuleParameterMap* const data) {
- // NOTE: the JSON field naming doesn't match the FIDL struct naming because
- // the field names in FIDL were changed.
- xdr->Field("key_to_link_map", &data->entries, XdrModuleParameterMapEntry);
-}
-
-void XdrSurfaceRelation(XdrContext* const xdr,
- fuchsia::modular::SurfaceRelation* const data) {
- xdr->Field("arrangement", &data->arrangement);
- xdr->Field("dependency", &data->dependency);
- xdr->Field("emphasis", &data->emphasis);
-}
-
-void XdrIntentParameterData(XdrContext* const xdr,
- fuchsia::modular::IntentParameterData* const data) {
- static constexpr char kTag[] = "tag";
- static constexpr char kEntityReference[] = "entity_reference";
- static constexpr char kJson[] = "json";
- static constexpr char kEntityType[] = "entity_type";
-
- switch (xdr->op()) {
- case XdrOp::FROM_JSON: {
- std::string tag;
- xdr->Field(kTag, &tag);
-
- if (tag == kEntityReference) {
- fidl::StringPtr value;
- xdr->Field(kEntityReference, &value);
- data->set_entity_reference(std::move(value));
- } else if (tag == kJson) {
- fidl::StringPtr value;
- xdr->Field(kJson, &value);
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(*value, &vmo));
- data->set_json(std::move(vmo).ToTransport());
- } else if (tag == kEntityType) {
- ::std::vector<::std::string> value;
- xdr->Field(kEntityType, &value);
- data->set_entity_type(std::move(value));
- } else {
- FXL_LOG(ERROR) << "XdrIntentParameterData FROM_JSON unknown tag: "
- << tag;
- }
- break;
- }
-
- case XdrOp::TO_JSON: {
- std::string tag;
-
- switch (data->Which()) {
- case fuchsia::modular::IntentParameterData::Tag::kEntityReference: {
- tag = kEntityReference;
- fidl::StringPtr value = data->entity_reference();
- xdr->Field(kEntityReference, &value);
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::kJson: {
- tag = kJson;
- std::string json_string;
- FXL_CHECK(fsl::StringFromVmo(data->json(), &json_string));
- fidl::StringPtr value = json_string;
- xdr->Field(kJson, &value);
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::kEntityType: {
- tag = kEntityType;
- std::vector<std::string> value = data->entity_type();
- xdr->Field(kEntityType, &value);
- break;
- }
- case fuchsia::modular::IntentParameterData::Tag::Invalid:
- FXL_LOG(ERROR) << "XdrIntentParameterData TO_JSON unknown tag: "
- << static_cast<int>(data->Which());
- break;
- }
-
- xdr->Field(kTag, &tag);
- break;
- }
- }
-}
-
-void XdrIntentParameter(XdrContext* const xdr,
- fuchsia::modular::IntentParameter* const data) {
- xdr->Field("name", &data->name);
- xdr->Field("data", &data->data, XdrIntentParameterData);
-}
-
-void XdrIntent(XdrContext* const xdr, fuchsia::modular::Intent* const data) {
- xdr->Field("action_name", &data->action);
- xdr->Field("action_handler", &data->handler);
- xdr->Field("parameters", &data->parameters, XdrIntentParameter);
-}
-
-void XdrModuleData_v1(XdrContext* const xdr,
- fuchsia::modular::ModuleData* const data) {
- xdr->Field("url", &data->module_url);
- xdr->Field("module_path", &data->module_path);
- xdr->Field("module_source", &data->module_source);
- xdr->Field("surface_relation", &data->surface_relation, XdrSurfaceRelation);
- xdr->Field("module_stopped", &data->module_deleted);
- xdr->Field("intent", &data->intent, XdrIntent);
-
- // In previous versions we did not have these fields.
- data->parameter_map.entries.resize(0);
-}
-
-void XdrModuleData_v2(XdrContext* const xdr,
- fuchsia::modular::ModuleData* const data) {
- xdr->Field("url", &data->module_url);
- xdr->Field("module_path", &data->module_path);
- xdr->Field("module_source", &data->module_source);
- xdr->Field("surface_relation", &data->surface_relation, XdrSurfaceRelation);
- xdr->Field("module_stopped", &data->module_deleted);
- xdr->Field("intent", &data->intent, XdrIntent);
- // NOTE: the JSON field naming doesn't match the FIDL struct naming because
- // the field name in FIDL was changed.
- xdr->Field("chain_data", &data->parameter_map, XdrModuleParameterMap);
-}
-
-void XdrModuleData_v3(XdrContext* const xdr,
- fuchsia::modular::ModuleData* const data) {
- xdr->Field("url", &data->module_url);
- xdr->Field("module_path", &data->module_path);
- xdr->Field("module_source", &data->module_source);
- xdr->Field("surface_relation", &data->surface_relation, XdrSurfaceRelation);
- xdr->Field("module_stopped", &data->module_deleted);
- xdr->Field("intent", &data->intent, XdrIntent);
- // NOTE: the JSON field naming doesn't match the FIDL struct naming because
- // the field name in FIDL was changed.
- xdr->Field("chain_data", &data->parameter_map, XdrModuleParameterMap);
-}
-
-void XdrModuleData_v4(XdrContext* const xdr,
- fuchsia::modular::ModuleData* const data) {
- if (!xdr->Version(4)) {
- return;
- }
- xdr->Field("url", &data->module_url);
- xdr->Field("module_path", &data->module_path);
- xdr->Field("module_source", &data->module_source);
- xdr->Field("surface_relation", &data->surface_relation, XdrSurfaceRelation);
- xdr->Field("module_stopped", &data->module_deleted);
- xdr->Field("intent", &data->intent, XdrIntent);
- // NOTE: the JSON field naming doesn't match the FIDL struct naming because
- // the field name in FIDL was changed.
- xdr->Field("chain_data", &data->parameter_map, XdrModuleParameterMap);
-}
-
-void XdrModuleData_v5(XdrContext* const xdr,
- fuchsia::modular::ModuleData* const data) {
- if (!xdr->Version(5)) {
- return;
- }
- xdr->Field("url", &data->module_url);
- xdr->Field("module_path", &data->module_path);
- xdr->Field("module_source", &data->module_source);
- xdr->Field("surface_relation", &data->surface_relation, XdrSurfaceRelation);
- xdr->Field("module_deleted", &data->module_deleted);
- xdr->Field("intent", &data->intent, XdrIntent);
- // NOTE: the JSON field naming doesn't match the FIDL struct naming because
- // the field name in FIDL was changed.
- xdr->Field("chain_data", &data->parameter_map, XdrModuleParameterMap);
-}
-
-void XdrModuleData_v6(XdrContext* const xdr,
- fuchsia::modular::ModuleData* const data) {
- if (!xdr->Version(6)) {
- return;
- }
- xdr->Field("url", &data->module_url);
- xdr->Field("module_path", &data->module_path);
- xdr->Field("module_source", &data->module_source);
- xdr->Field("surface_relation", &data->surface_relation, XdrSurfaceRelation);
- xdr->Field("module_deleted", &data->module_deleted);
- xdr->Field("intent", &data->intent, XdrIntent);
- // NOTE: the JSON field naming doesn't match the FIDL struct naming because
- // the field name in FIDL was changed.
- xdr->Field("chain_data", &data->parameter_map, XdrModuleParameterMap);
- xdr->Field("is_embedded", &data->is_embedded);
-}
-
-XdrFilterType<fuchsia::modular::ModuleData> XdrModuleData[] = {
- XdrModuleData_v6, XdrModuleData_v5, XdrModuleData_v4, XdrModuleData_v3,
- XdrModuleData_v2, XdrModuleData_v1, nullptr,
-};
-
-} // namespace modular
diff --git a/bin/sessionmgr/storage/story_storage_xdr.h b/bin/sessionmgr/storage/story_storage_xdr.h
deleted file mode 100644
index 27fc99a..0000000
--- a/bin/sessionmgr/storage/story_storage_xdr.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_XDR_H_
-#define PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_XDR_H_
-
-#include <fuchsia/modular/internal/cpp/fidl.h>
-
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace modular {
-
-extern XdrFilterType<fuchsia::modular::ModuleData> XdrModuleData[];
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORAGE_STORY_STORAGE_XDR_H_
diff --git a/bin/sessionmgr/story/BUILD.gn b/bin/sessionmgr/story/BUILD.gn
deleted file mode 100644
index ac799f4..0000000
--- a/bin/sessionmgr/story/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-import("//peridot/build/tests_package.gni")
-
-source_set("system") {
- sources = [
- "system.cc",
- "system.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- ]
-}
diff --git a/bin/sessionmgr/story/model/BUILD.gn b/bin/sessionmgr/story/model/BUILD.gn
deleted file mode 100644
index 101721f..0000000
--- a/bin/sessionmgr/story/model/BUILD.gn
+++ /dev/null
@@ -1,177 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-# Convenience dep for most Systems.
-group("model") {
- public_deps = [
- ":story_mutator",
- ":story_observer",
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-}
-
-hermetic_tests_package("story_model_unittests") {
- deps = [
- ":apply_mutations_unittest",
- ":story_model_owner_unittest",
- ":ledger_story_model_storage_unittest",
- ]
-}
-
-source_set("story_observer") {
- sources = [
- "story_observer.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-}
-
-source_set("story_mutator") {
- sources = [
- "story_mutator.cc",
- "story_mutator.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-}
-
-source_set("story_model_storage") {
- sources = [
- "story_model_storage.cc",
- "story_model_storage.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-}
-
-source_set("apply_mutations") {
- sources = [
- "apply_mutations.cc",
- "apply_mutations.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular.storymodel",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- ]
-}
-
-executable("apply_mutations_unittest") {
- testonly = true
-
- sources = [
- "apply_mutations_unittest.cc",
- ]
-
- deps = [
- ":apply_mutations",
- "//third_party/googletest:gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("noop_story_model_storage") {
- sources = [
- "noop_story_model_storage.cc",
- "noop_story_model_storage.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-
- deps = [
- ":story_model_storage",
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("ledger_story_model_storage") {
- sources = [
- "ledger_story_model_storage.cc",
- "ledger_story_model_storage.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-
- deps = [
- ":apply_mutations",
- ":story_model_storage",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/ledger_client:promise",
- "//peridot/public/fidl/fuchsia.ledger",
- ]
-}
-
-executable("ledger_story_model_storage_unittest") {
- testonly = true
-
- sources = [
- "ledger_story_model_storage_unittest.cc",
- ]
-
- deps = [
- ":apply_mutations",
- ":ledger_story_model_storage",
- "testing",
- "//garnet/public/lib/async_promise",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/testing:test_with_ledger",
- "//third_party/googletest:gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("story_model_owner") {
- sources = [
- "story_model_owner.cc",
- "story_model_owner.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/async_promise",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-
- deps = [
- ":apply_mutations",
- ":story_model_storage",
- ":story_mutator",
- ":story_observer",
- ]
-}
-
-executable("story_model_owner_unittest") {
- testonly = true
-
- sources = [
- "story_model_owner_unittest.cc",
- ]
-
- deps = [
- ":story_model_owner",
- ":story_model_storage",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/sessionmgr/story/model/README.md b/bin/sessionmgr/story/model/README.md
deleted file mode 100644
index 72b7cd6..0000000
--- a/bin/sessionmgr/story/model/README.md
+++ /dev/null
@@ -1,103 +0,0 @@
-### StoryModel
-
-The `StoryModel` FIDL table is used to represent the state of a story.
-`sessionmgr` keeps a separate `StoryModel` in memory for each running story,
-and also persists changes to it onto storage. Mutations to `StoryModel` are
-done using the `StoryMutator` interface and changes from these mutations
-are notified to registered observers (using the `StoryObserver`
-interface).
-
-This directory defines classes that define the control flow for mutating a
-`StoryModel` FIDL table.
-
-The following interfaces are defined:
-
-* `StoryMutator`: Allows clients to issue a series of `StoryModelMutation`
- structs that describe mutations to a `StoryModel`.
-* `StoryObserver`: Used to ready `StoryModel` and observe changes to it.
- Changes to `StoryModel` may happen through `StoryMutator` or, in the
- case of a distributed storage implementation such as Ledger, from sync'ing
- with peers.
-interface. Allows clients to read the current `StoryModel` state, and register
-for updates when the `StoryModel` changes.
-
-Both of the above are abstract base classes to aid in testing: clients that
-wish to mutate and/or observe a `StoryModel` will accept a `StoryMutator`
-or `StoryObserver` as a constructor argument. Making them abstract allows
-injection of test implementations that do not require the full machinery
-introduced by `StoryModelOwner`.
-
-#### `StoryModelOwner` class
-
-`StoryModelOwner` is has its own implementations of `StoryMutator` and
-`StoryObserver`, and coordinates the flow of data from
-`StoryMutators` through a `StoryModelStorage`, applies those changes
-to a `StoryModel` and flows this new model to `StoryObserver` instances.
-It acts as a factory for its own implementations of `StoryMutators` and
-`StoryObservers`.
-
-#### `StoryModelStorage` interface
-
-Supplied to `StoryModelOwner` at the time of its creation, a
-`StoryModelStorage` is responsible for consuming mutation commands and
-updating its persistent storage layer by applying a set of mutation commands,
-as well as notifying of mutations that have been applied. A request to mutate
-does not necessary result in those exact mutations being observed (in the case
-of conflict resolution), nor do observed mutations imply a request was made (in
-the case of a `StoryModel` backed by distributed storage).
-
-A "no-op" StoryModelStorage (one that does not result in any disk-backed
-or other durable storage) would immediately notify of any incoming mutations
-without applying them anywhere. In this case the `StoryModel` would be resident
-in memory only.
-
-#### Flow of Control
-
-Mutation commands flow from anything that has a `StoryMutator` through a
-`StoryModelOwner`, `StoryModelStorage` and are translated into new
-`StoryModels`. From that point forward, observers see the new `StoryModel`
-values.
-
-```
-[some system] -> StoryMutator -> StoryModelOwner | commands
- | | "
- StoryModelStorage | "
- | | "
-[other system] <- StoryObserver <- StoryModelOwner $ model
-```
-
-### Example
-
-The constructor for your average System that both mutates and observes a
-`StoryModel` would look like:
-```
-class Foo : public System {
- public:
- Foo(std::unique_ptr<StoryMutator> mutator,
- std::unique_ptr<StoryObserver> observer, ...);
-};
-```
-
-In production, we will create this by leveraging the `StoryModelOwner` to
-create those dependencies:
-
-```
-// assume StoryModelOwner has already been defined.
-auto foo_system = std::make_unique<Foo>(owner->NewMutator(), owner->NewObserver(), ...);
-```
-
-For testing, we leverage test versions of both:
-```
-auto test_mutator = std::make_unique<TestStoryMutator>();
-auto test_observer = std::make_unique<TestStoryObserver>();
-
-// Retain pointers to both |test_mutator| and |test_observer| so we can trigger
-// behavior and validate side-effects.
-auto mutator_ptr = test_mutator.get();
-auto observer_ptr = test_observer.get();
-auto foo_system = std::make_unique<Foo>(std::move(test_mutator), std::move(test_observer));
-
-observer_ptr->NotifyOfModel(new_model); // Push a new model to observers!
-// |foo_system| should have generated new mutations as a side-effect.
-EXPECT_TRUE(3, mutator_ptr->GetNumCommandsIssued());
-```
\ No newline at end of file
diff --git a/bin/sessionmgr/story/model/apply_mutations.cc b/bin/sessionmgr/story/model/apply_mutations.cc
deleted file mode 100644
index d0308ee..0000000
--- a/bin/sessionmgr/story/model/apply_mutations.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/fxl/logging.h>
-
-#include "peridot/bin/sessionmgr/story/model/apply_mutations.h"
-
-#include "lib/fostr/fidl/fuchsia/modular/storymodel/formatting.h"
-
-using fuchsia::modular::StoryVisibilityState;
-using fuchsia::modular::StoryState;
-using fuchsia::modular::storymodel::StoryModel;
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-namespace modular {
-
-namespace {
-
-void ApplySetVisibilityState(const StoryVisibilityState visibility_state, StoryModel* story_model) {
- story_model->set_visibility_state(visibility_state);
-}
-
-void ApplySetRuntimeState(const StoryState story_state, StoryModel* story_model) {
- story_model->set_runtime_state(story_state);
-}
-
-} // namespace
-
-StoryModel ApplyMutations(const StoryModel& current_model,
- const std::vector<StoryModelMutation>& commands) {
- StoryModel new_model;
- fidl::Clone(current_model, &new_model);
-
- for (const auto& command : commands) {
- switch (command.Which()) {
- case StoryModelMutation::Tag::kSetVisibilityState:
- ApplySetVisibilityState(command.set_visibility_state(), &new_model);
- break;
- case StoryModelMutation::Tag::kSetRuntimeState:
- ApplySetRuntimeState(command.set_runtime_state(), &new_model);
- break;
- case StoryModelMutation::Tag::Invalid:
- FXL_LOG(FATAL) << "Encountered invalid StoryModelMutation: " << command;
- }
- }
-
- return new_model;
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/apply_mutations.h b/bin/sessionmgr/story/model/apply_mutations.h
deleted file mode 100644
index 230392a..0000000
--- a/bin/sessionmgr/story/model/apply_mutations.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_MODEL_APPLY_MUTATIONS_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_MODEL_APPLY_MUTATIONS_H_
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-
-namespace modular {
-
-// Returns a new StoryModel which is the result of applying |commands| to
-// |current_model|.
-fuchsia::modular::storymodel::StoryModel ApplyMutations(
- const fuchsia::modular::storymodel::StoryModel& current_model,
- const std::vector<fuchsia::modular::storymodel::StoryModelMutation>&
- commands);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_MODEL_APPLY_MUTATIONS_H_
diff --git a/bin/sessionmgr/story/model/apply_mutations_unittest.cc b/bin/sessionmgr/story/model/apply_mutations_unittest.cc
deleted file mode 100644
index fc4ba17..0000000
--- a/bin/sessionmgr/story/model/apply_mutations_unittest.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/fit/bridge.h>
-#include <lib/fit/function.h>
-#include <lib/fit/single_threaded_executor.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionmgr/story/model/apply_mutations.h"
-
-using fuchsia::modular::StoryState;
-using fuchsia::modular::StoryVisibilityState;
-using fuchsia::modular::storymodel::StoryModel;
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-namespace modular {
-namespace {
-
-// Test a single StoryModelMutation.set_runtimes_state command to change
-// StoryModel.runtime_state.
-TEST(ApplyMutationsTest, set_runtime_state) {
- StoryModel before;
- *before.mutable_runtime_state() = StoryState::STOPPED;
-
- std::vector<StoryModelMutation> commands(1);
- commands[0].set_set_runtime_state(StoryState::RUNNING);
- auto result = ApplyMutations(before, commands);
- EXPECT_EQ(StoryState::RUNNING, *result.runtime_state());
-}
-
-// Test a single StoryModelMutation.set_visibility_state command to change
-// StoryModel.visibility_state.
-TEST(ApplyMutationsTest, set_visibility_state) {
- StoryModel before;
- *before.mutable_visibility_state() = StoryVisibilityState::DEFAULT;
-
- std::vector<StoryModelMutation> commands(1);
- commands[0].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
- auto result = ApplyMutations(before, commands);
- EXPECT_EQ(StoryVisibilityState::IMMERSIVE, *result.visibility_state());
-}
-
-// Test two StoryModelMutation.set_visibility_state commands to change
-// StoryModel.visibility_state to one value and back. Tests that multiple
-// commands in a list are applied in order.
-TEST(ApplyMutationsTest,
- MultipleMutations_AppliedInOrder_set_visibility_state) {
- StoryModel before;
-
- std::vector<StoryModelMutation> commands(2);
- commands[0].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
- commands[1].set_set_visibility_state(StoryVisibilityState::DEFAULT);
- auto result = ApplyMutations(before, commands);
- EXPECT_EQ(StoryVisibilityState::DEFAULT, *result.visibility_state());
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/ledger_story_model_storage.cc b/bin/sessionmgr/story/model/ledger_story_model_storage.cc
deleted file mode 100644
index 25e3135..0000000
--- a/bin/sessionmgr/story/model/ledger_story_model_storage.cc
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story/model/ledger_story_model_storage.h"
-
-#include <lib/fit/bridge.h>
-#include <lib/fit/promise.h>
-#include <vector>
-#include <string>
-
-#include "lib/fidl/cpp/object_coding.h" // for EncodeObject()/DecodeObject()
-#include "lib/fsl/vmo/vector.h"
-#include "lib/fxl/logging.h"
-#include "peridot/bin/sessionmgr/story/model/apply_mutations.h"
-#include "peridot/lib/ledger_client/promise.h" // for fit::promise<> wrappers
-
-using fuchsia::modular::storymodel::StoryModel;
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-namespace modular {
-
-namespace {
-// Synopsis of Ledger page structure:
-//
-// storymodel/ - base prefix for all data for this story
-// device/<device id> - key for device data for <device id>
-// shared/ - prefix for data shared across devices
-
-const char kStoryModelKeyPrefix[] = "storymodel/";
-const char kDeviceKeyPrefix[] = "storymodel/device/";
-// const char kSharedKeyPrefix[] = "shared/";
-
-std::string MakeDeviceKey(const std::string& device_id) {
- return kDeviceKeyPrefix + device_id;
-}
-} // namespace
-
-namespace {
-// Encodes a FIDL table into a byte representation safe for persisting to
-// storage.
-template <class T>
-std::vector<uint8_t> EncodeForStorage(T* table) {
- std::vector<uint8_t> encoded;
- // This can only fail if |table| contains handles. StoryModel and its fields
- // do not.
- FXL_CHECK(fidl::EncodeObject(table, &encoded, nullptr /* error_msg_out */) ==
- ZX_OK);
- return encoded;
-}
-
-// Decodes bytes encoded by EncodeForStorage() into their corresponding FIDL
-// table.
-template <class T>
-void DecodeFromStorage(std::vector<uint8_t> encoded, T* table) {
- // DecodeObject() takes a non-const pointer, even though it doesn't
- // modify the data.
- FXL_CHECK(fidl::DecodeObject(encoded.data(), encoded.size(), table,
- nullptr /* error_msg_out */) == ZX_OK);
-}
-} // namespace
-
-LedgerStoryModelStorage::LedgerStoryModelStorage(
- LedgerClient* const ledger_client, fuchsia::ledger::PageId page_id,
- std::string device_id)
- : PageClient("LedgerStoryModelStorage", ledger_client, std::move(page_id),
- kStoryModelKeyPrefix),
- device_id_(std::move(device_id)) {}
-
-LedgerStoryModelStorage::~LedgerStoryModelStorage() = default;
-
-// Helper functions to support OnPageChange() and OnPageDelete().
-namespace {
-// Appends to |commands| StoryModelMutation objects that, when applied to a
-// StoryModel, reflect the device state in |device_state_bytes|.
-void GenerateObservedMutationsForDeviceState(
- std::vector<uint8_t> device_state_bytes,
- std::vector<StoryModelMutation>* commands) {
- StoryModel model;
- DecodeFromStorage(std::move(device_state_bytes), &model);
-
- if (model.has_runtime_state()) {
- commands->resize(commands->size() + 1);
- commands->back().set_set_runtime_state(*model.runtime_state());
- }
- if (model.has_visibility_state()) {
- commands->resize(commands->size() + 1);
- commands->back().set_set_visibility_state(*model.visibility_state());
- }
-}
-
-void GenerateObservedMutationsForDeviceState(
- const fuchsia::mem::Buffer& buffer,
- std::vector<StoryModelMutation>* commands) {
- std::vector<uint8_t> bytes;
- FXL_CHECK(fsl::VectorFromVmo(buffer, &bytes));
- GenerateObservedMutationsForDeviceState(std::move(bytes), commands);
-}
-} // namespace
-
-void LedgerStoryModelStorage::OnChange(
- fuchsia::ledger::PageChange page_change,
- fuchsia::ledger::ResultState result_state, OnChangeCallback callback) {
- switch (result_state) {
- case fuchsia::ledger::ResultState::COMPLETED:
- ProcessCompletePageChange(std::move(page_change));
- break;
- case fuchsia::ledger::ResultState::PARTIAL_STARTED:
- partial_page_change_ = fuchsia::ledger::PageChange();
- // Continue to merging of values with |partial_page_change_|.
- case fuchsia::ledger::ResultState::PARTIAL_CONTINUED:
- case fuchsia::ledger::ResultState::PARTIAL_COMPLETED:
- // Merge the entries in |page_change| with |partial_page_change_|.
- partial_page_change_.changed_entries.insert(
- partial_page_change_.changed_entries.end(),
- std::make_move_iterator(page_change.changed_entries.begin()),
- std::make_move_iterator(page_change.changed_entries.end()));
- partial_page_change_.deleted_keys.insert(
- partial_page_change_.deleted_keys.end(),
- std::make_move_iterator(page_change.deleted_keys.begin()),
- std::make_move_iterator(page_change.deleted_keys.end()));
-
- if (result_state == fuchsia::ledger::ResultState::PARTIAL_COMPLETED) {
- ProcessCompletePageChange(std::move(partial_page_change_));
- }
- }
-
- callback(nullptr /* snapshot request */);
-}
-
-void LedgerStoryModelStorage::ProcessCompletePageChange(
- fuchsia::ledger::PageChange page_change) {
- std::vector<StoryModelMutation> commands;
-
- for (auto& entry : page_change.changed_entries) {
- auto key = to_string(entry.key);
- if (key == MakeDeviceKey(device_id_)) {
- FXL_CHECK(entry.value)
- << key << ": This key should never be deleted. Something is wrong.";
- // Read the value and generate equivalent StoryModelMutation commands.
- GenerateObservedMutationsForDeviceState(std::move(*entry.value),
- &commands);
- } else if (key.find(kDeviceKeyPrefix) == 0) {
- // This is device data from another device!
- // TODO(thatguy): Store it in the local StoryModel when we care about
- // observing these data.
- } else {
- FXL_LOG(FATAL) << "LedgerStoryModelStorage::OnPageChange(): key " << key
- << " unexpected in the Ledger.";
- }
- }
-
- Observe(std::move(commands));
-
- // Don't do anything with deleted keys at this time.
-}
-
-void LedgerStoryModelStorage::OnPageConflict(Conflict* conflict) {
- // The default merge policy in LedgerClient is LEFT, meaning whatever value
- // was in the left branch for each key is taken.
- //
- // TODO(MF-157): LedgerClient breaks a single merge conflict for multiple
- // keys into on OnPageConflict() call per key. For a more advanced conflict
- // resolution policy, it is likely necessary to look at the conflict in full.
-}
-
-// Helper functions to support task construction in Execute().
-namespace {
-// Partitions |commands| into two vectors:
-//
-// 1) Those that mutate state that is device-local (ie, runtime state of the
-// story)
-//
-// 2) Those that mutate state that is shared among all devices (ie, the set
-// of mods)
-struct PartitionedCommands {
- // These commands represent mutations that apply only to device-local state.
- std::vector<StoryModelMutation> device_commands;
- // And these apply to shared (cross-device) state.
- std::vector<StoryModelMutation> shared_commands;
-};
-PartitionedCommands PartitionCommandsForDeviceAndShared(
- std::vector<StoryModelMutation> commands) {
- PartitionedCommands partitioned_commands;
-
- for (auto& i : commands) {
- switch (i.Which()) {
- case StoryModelMutation::Tag::kSetRuntimeState:
- case StoryModelMutation::Tag::kSetVisibilityState:
- partitioned_commands.device_commands.push_back(std::move(i));
- break;
- case StoryModelMutation::Tag::Invalid:
- FXL_LOG(FATAL) << "Encountered invalid StoryModelMutation.";
- break;
- }
- }
-
- return partitioned_commands;
-}
-
-// TODO(thatguy): Move these functions to ledger_client/promise.h
-
-// Reads the value in the given key and returns an object of type T. If |key|
-// does not have a value, returns a default-constructed T.
-template <class T>
-fit::promise<T> ReadObjectFromKey(fuchsia::ledger::PageSnapshot* snapshot,
- const std::string& key) {
- return PageSnapshotPromise::GetInline(snapshot, key)
- .and_then([](const std::unique_ptr<std::vector<uint8_t>>& value) {
- if (!value) {
- return fit::ok(T());
- }
-
- T object;
- DecodeFromStorage(std::move(*value), &object);
- return fit::ok(std::move(object));
- });
-}
-
-// Writes |value| to |key|.
-template <class T>
-fit::promise<> WriteObjectToKey(fuchsia::ledger::Page* page,
- const std::string& key, T value) {
- auto bytes = EncodeForStorage(&value);
- // TODO(thatguy): Calculate if this value is too big for a FIDL message. If
- // so, fall back on Page.CreateReferenceFromBuffer() and Page.PutReference().
- return PagePromise::Put(page, key, std::move(bytes));
-}
-
-// Reads the latest device-local state, applies |commands| to it, and then
-// writes it back to the Ledger.
-//
-// Store all the device-local state under a single key, and re-use
-// a sparsely populated StoryModel table as our data structure for simplicity.
-//
-// The returned promise is resolved once calls to mutate the Page have
-// returned.
-fit::promise<> UpdateDeviceState(fuchsia::ledger::Page* page,
- fuchsia::ledger::PageSnapshot* snapshot,
- const std::string& device_id,
- std::vector<StoryModelMutation> commands) {
- // Task synopsis:
- //
- // 1) Read the current contents at |key| from the page snapshot.
- // 2) Apply |commands| to those contents.
- // 3) Write the new contents back to |key|.
- auto key = MakeDeviceKey(device_id);
- return ReadObjectFromKey<StoryModel>(snapshot, key)
- .and_then([page, key, commands = std::move(commands)](
- const StoryModel& current_value) {
- auto new_value = ApplyMutations(current_value, commands);
- return WriteObjectToKey(page, key, std::move(new_value));
- });
-}
-
-// Updates the shared state section of the ledger based on |commands|.
-//
-// The returned promise is resolved once calls to mutate the Page have
-// returned.
-fit::promise<> UpdateSharedState(fuchsia::ledger::Page* page,
- fuchsia::ledger::PageSnapshot* snapshot,
- std::vector<StoryModelMutation> commands) {
- // There is no shared state yet.
- return fit::make_promise([] { return fit::ok(); });
-}
-} // namespace
-
-fit::promise<> LedgerStoryModelStorage::Load() {
- // Synopsis of Load() task:
- //
- // 1) Read from device-local state and build commands.
- // 2) Scan the shared state and build commands.
- // 3) Wait for the above tasks and then issue all of the commands to
- // Observe().
- //
- // NOTE: currently we don't have any shared state, so we skip (2).
-
- struct State {
- fuchsia::ledger::PageSnapshotPtr page_snapshot;
- std::vector<StoryModelMutation> commands;
- };
- auto state = std::make_unique<State>();
-
- return fit::make_promise([this, state = state.get()](fit::context& c) {
- // Get a snapshot. Join on the result later and take advantage of
- // pipelining instead.
- auto get_snapshot_promise = PagePromise::GetSnapshot(
- page(), state->page_snapshot.NewRequest());
-
- auto key = MakeDeviceKey(device_id_);
- auto read_promise =
- PageSnapshotPromise::GetInline(state->page_snapshot.get(), key)
- .and_then([state](
- const std::unique_ptr<std::vector<uint8_t>>&
- device_state_bytes) {
- if (device_state_bytes) {
- GenerateObservedMutationsForDeviceState(
- std::move(*device_state_bytes), &state->commands);
- }
- return fit::ok();
- });
-
- return fit::join_promises(std::move(get_snapshot_promise),
- std::move(read_promise));
- })
- .and_then([this, state = state.get()](
- std::tuple<fit::result<>, fit::result<>> results)
- -> fit::result<> {
- auto [get_snapshot_result, read_result] = results;
- if (get_snapshot_result.is_error() || read_result.is_error()) {
- return fit::error();
- }
-
- Observe(std::move(state->commands));
- return fit::ok();
- })
- // Keep |state| alive until execution reaches here.
- .inspect([state = std::move(state)](fit::result<>& r) {})
- .wrap_with(scope_);
-}
-
-fit::promise<> LedgerStoryModelStorage::Flush() {
- // The returned promise will block until all pending mutation opertaions have
- // resolved. These pending operations are also wrapped with |sequencer_| (in
- // Execute()), which applies this sequential behavior to promises it wraps.
- return fit::make_promise([] { return fit::ok(); }).wrap_with(sequencer_);
-}
-
-fit::promise<> LedgerStoryModelStorage::Execute(
- std::vector<StoryModelMutation> commands) {
- // Synopsis of the Execute() task:
- //
- // 1) Start a Page transaction.
- // 2) Get a PageSnapshot.
- // 3) Partition |commands| into those affecting per-device state and shared
- // state and then update each partition in storage in parallel.
- // 4) Commit() if successful, and Rollback() if not.
- //
- // To take maximum advantage of FIDL pipelining and concurrency, do (1), (2),
- // and (3). Before (4), join on all the results and fail if
- // any of 1-3 failed.
-
- // Some state must outlast several of the fit::promise callbacks below.
- // Capture it in a struct on the heap, and then move ownership to a point
- // late enough in our promise by calling
- // fit::promise.inspect().
- struct State {
- fuchsia::ledger::PageSnapshotPtr page_snapshot;
- };
- auto state = std::make_unique<State>();
-
- return fit::make_promise(
- [this, state = state.get(),
- commands = std::move(commands)]() mutable -> fit::promise<> {
- // Start the transaction, but don't block on its result. Rather,
- // join it later to ensure that a failed StartTransaction()
- // triggers a failure of the overall task.
- auto start_transaction_promise =
- PagePromise::StartTransaction(page());
-
- // Get a snapshot. As with StartTransaction(), join on the
- // result later and take advantage of pipelining instead.
- auto get_snapshot_promise = PagePromise::GetSnapshot(
- page(), state->page_snapshot.NewRequest());
-
- // Partition up the commands into those that affect device-only
- // state, and those that affect shared (among all devices) state.
- auto [device_commands, shared_commands] =
- PartitionCommandsForDeviceAndShared(std::move(commands));
-
- // Dispatch the update commands.
- auto update_device_state_promise =
- UpdateDeviceState(page(), state->page_snapshot.get(),
- device_id_, std::move(device_commands));
- auto update_shared_state_promise =
- UpdateSharedState(page(), state->page_snapshot.get(),
- std::move(shared_commands));
-
- // Wait on all four pending promises. Fail if any one of them
- // result in an error.
- return fit::join_promises(std::move(start_transaction_promise),
- std::move(get_snapshot_promise),
- std::move(update_device_state_promise),
- std::move(update_shared_state_promise))
- .and_then([](std::tuple<fit::result<>, fit::result<>,
- fit::result<>, fit::result<>>
- results) -> fit::result<> {
- auto [start_transaction_result, get_snapshot_result,
- device_result, shared_result] = results;
- if (start_transaction_result.is_error() ||
- get_snapshot_result.is_error() ||
- device_result.is_error() || shared_result.is_error()) {
- return fit::error();
- }
- return fit::ok();
- });
- })
- // Keep |state| alive until execution reaches here. It is not needed in
- // any subsequent continuation functions.
- .inspect([state = std::move(state)](fit::result<>& r) {})
- .and_then([page = page()] { return PagePromise::Commit(page); })
- .or_else([page = page()] {
- // Even if RollbackTransaction() succeeds, fail the overall task.
- return PagePromise::Rollback(page).and_then(
- [] { return fit::error(); });
- })
- .wrap_with(sequencer_) // Waits until last Execute() is done.
- .wrap_with(scope_); // Aborts if |this| is destroyed.
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/ledger_story_model_storage.h b/bin/sessionmgr/story/model/ledger_story_model_storage.h
deleted file mode 100644
index 690bafd..0000000
--- a/bin/sessionmgr/story/model/ledger_story_model_storage.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_MODEL_LEDGER_STORY_MODEL_STORAGE_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_MODEL_LEDGER_STORY_MODEL_STORAGE_H_
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/fit/scope.h>
-#include <lib/fit/sequencer.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/story/model/story_model_storage.h"
-
-#include "peridot/lib/ledger_client/page_client.h"
-
-namespace modular {
-
-class LedgerClient;
-
-// LedgerStoryModelStorage writes a StoryModel into a Ledger Page instance. It
-// partitions the StoryModel into two sections:
-//
-// 1) Values that are scoped to this device (such as the Story's runtime state)
-// 2) Values that are shared among all devices (such as the list of mod URLs)
-//
-// The two sections are stored in separate prefixes of the Ledger: (1) is
-// prefixed using the device's id, and (2) is prefixed in a shared location.
-class LedgerStoryModelStorage : public StoryModelStorage, PageClient {
- public:
- // Constructs a new instance which stores all data in |page_id| within
- // |ledger_client|'s Ledger. Scopes device-local state to a key namespace
- // therein with |device_id|.
- LedgerStoryModelStorage(LedgerClient* ledger_client,
- fuchsia::ledger::PageId page_id,
- std::string device_id);
- ~LedgerStoryModelStorage() override;
-
- private:
- // |PageWatcher|
- void OnChange(fuchsia::ledger::PageChange page,
- fuchsia::ledger::ResultState result_state,
- OnChangeCallback callback) override;
-
- // |PageClient|
- void OnPageConflict(Conflict* conflict) override;
-
- // |StoryModelStorage|
- fit::promise<> Load() override;
-
- // |StoryModelStorage|
- fit::promise<> Flush() override;
-
- // |StoryModelStorage|
- fit::promise<> Execute(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands)
- override;
-
- // Called from OnChange().
- void ProcessCompletePageChange(fuchsia::ledger::PageChange page_change);
-
- const std::string device_id_;
-
- // For very large changes to the Ledger page, OnChange() may be called
- // multiple times, each time with a partial representation of the change. The
- // changes are accumulated in |partial_page_change_| until OnChange() is
- // called with the final set (where |result_state| ==
- // ResultState::PARTIAL_COMPLETE).
- fuchsia::ledger::PageChange partial_page_change_;
-
- // With |scope_| is destroyed (which is when |this| is destructed), all
- // fit::promises created in Mutate() will be abandoned. This is important
- // because those promises capture |this| in their handler functions.
- fit::scope scope_;
-
- // All of the writes to the Ledger are sequenced: the fuchsia.ledger.Page API
- // dictates that only one transaction may be ongoing at a time. Each call to
- // Execute() results in a promise that calls StartTransaction() and Commit()
- // at its end. |sequencer_| is used to ensure that no subsequent Execute()
- // task begins before the previous has completed.
- fit::sequencer sequencer_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerStoryModelStorage);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_MODEL_LEDGER_STORY_MODEL_STORAGE_H_
diff --git a/bin/sessionmgr/story/model/ledger_story_model_storage_unittest.cc b/bin/sessionmgr/story/model/ledger_story_model_storage_unittest.cc
deleted file mode 100644
index b5f4db1..0000000
--- a/bin/sessionmgr/story/model/ledger_story_model_storage_unittest.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/async_promise/executor.h>
-#include <lib/fit/bridge.h>
-#include <lib/fit/function.h>
-#include <lib/fit/single_threaded_executor.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionmgr/story/model/apply_mutations.h"
-#include "peridot/bin/sessionmgr/story/model/ledger_story_model_storage.h"
-#include "peridot/bin/sessionmgr/story/model/testing/mutation_matchers.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/testing/test_with_ledger.h"
-
-using fuchsia::modular::StoryState;
-using fuchsia::modular::StoryVisibilityState;
-using fuchsia::modular::storymodel::StoryModel;
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-namespace modular {
-namespace {
-
-// TODO: there is no good candidate for testing conflict resolution in the
-// StoryModel as of yet. What would be good is, e.g.: setting a value on a
-// ModuleModel while simultaneously deleting the entire entry.
-
-class LedgerStoryModelStorageTest : public testing::TestWithLedger {
- public:
- async::Executor executor;
-
- LedgerStoryModelStorageTest() : executor(dispatcher()) {}
-
- // Creates a new LedgerStoryModelStorage instance and returns:
- //
- // 1) A unique_ptr to the new instance.
- // 2) A ptr to a vector of lists of StoryModelMutations observed from that
- // instance.
- // 3) A ptr to a StoryModel updated with the observed commands.
- std::tuple<std::unique_ptr<StoryModelStorage>,
- std::vector<std::vector<StoryModelMutation>>*, StoryModel*>
- Create(std::string page_id, std::string device_id) {
- auto storage = std::make_unique<LedgerStoryModelStorage>(
- ledger_client(), MakePageId(page_id), device_id);
-
- auto observed_commands =
- observed_mutations_.emplace(observed_mutations_.end());
- auto observed_model = observed_models_.emplace(observed_models_.end());
- storage->SetObserveCallback([=](std::vector<StoryModelMutation> commands) {
- *observed_model = ApplyMutations(*observed_model, commands);
- observed_commands->push_back(std::move(commands));
- });
- return std::make_tuple(std::move(storage), &*observed_commands,
- &*observed_model);
- }
-
- // This is broken out into its own function because we use C++ structured
- // bindings to capture the result of Create() above. These cannot be
- // implicitly captured in lambdas without more verbose syntax. This function
- // converts the binding into a real variable which is possible to capture.
- void RunLoopUntilNumMutationsObserved(
- std::vector<std::vector<StoryModelMutation>>* observed_mutations,
- uint32_t n) {
- RunLoopUntil([&] { return observed_mutations->size() >= n; });
- }
-
- private:
- // A list (per StoryModelStorage instance) of the commands issued to each call
- // to StoryModelStorage.Observe().
- std::list<std::vector<std::vector<StoryModelMutation>>> observed_mutations_;
- std::list<StoryModel> observed_models_;
-};
-
-// Store some device-local values (runtime state, visibility state), and
-// observe the values coming back to us.
-TEST_F(LedgerStoryModelStorageTest, DeviceLocal_RoundTrip) {
- auto [storage, observed_mutations, observed_model] =
- Create("page1", "device1");
-
- std::vector<StoryModelMutation> commands(2);
- commands[0].set_set_runtime_state(StoryState::RUNNING);
- commands[1].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
-
- fit::result<> result;
- executor.schedule_task(
- storage->Execute(std::move(commands)).then([&](fit::result<>& r) {
- result = std::move(r);
- }));
- RunLoopUntil([&] { return !!result; });
- EXPECT_TRUE(result.is_ok());
-
- // We expect to see these values resulting in a notification from the ledger
- // eventually.
- RunLoopUntilNumMutationsObserved(observed_mutations, 1);
- EXPECT_EQ(1lu, observed_mutations->size());
- EXPECT_THAT(observed_mutations->at(0),
- ::testing::ElementsAre(
- IsSetRuntimeStateMutation(StoryState::RUNNING),
- IsSetVisibilityMutation(StoryVisibilityState::IMMERSIVE)));
-
- // Now change only StoryState. We should see the result of our previous
- // change to StoryVisibilityState preserved.
- commands.resize(1);
- commands[0].set_set_runtime_state(StoryState::STOPPED);
-
- result = fit::result<>();
- executor.schedule_task(
- storage->Execute(std::move(commands)).then([&](fit::result<>& r) {
- result = std::move(r);
- }));
- RunLoopUntil([&] { return !!result; });
- EXPECT_TRUE(result.is_ok());
-
- RunLoopUntilNumMutationsObserved(observed_mutations, 2);
- EXPECT_EQ(2lu, observed_mutations->size());
- EXPECT_THAT(observed_mutations->at(1),
- ::testing::ElementsAre(
- IsSetRuntimeStateMutation(StoryState::STOPPED),
- IsSetVisibilityMutation(StoryVisibilityState::IMMERSIVE)));
-}
-
-// Show that when we store values for two different device IDs in the same
-// Ledger page, they do not cause any conflicts.
-TEST_F(LedgerStoryModelStorageTest, DeviceLocal_DeviceIsolation) {
- auto [storage1, observed_mutations1, observed_model1] =
- Create("page1", "device1");
- auto [storage2, observed_mutations2, observed_model2] =
- Create("page1", "device2");
-
- // Set runtime state to RUNNING on device1, and set visibility state to
- // IMMERSIVE on device2.
- {
- std::vector<StoryModelMutation> commands(1);
- commands[0].set_set_runtime_state(StoryState::RUNNING);
- executor.schedule_task(storage1->Execute(std::move(commands)));
- }
- {
- std::vector<StoryModelMutation> commands(1);
- commands[0].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
- executor.schedule_task(storage2->Execute(std::move(commands)));
- }
-
- RunLoopUntilNumMutationsObserved(observed_mutations1, 1);
- RunLoopUntilNumMutationsObserved(observed_mutations2, 1);
-
- EXPECT_TRUE(observed_model1->has_runtime_state());
- EXPECT_FALSE(observed_model1->has_visibility_state());
- EXPECT_TRUE(observed_model2->has_visibility_state());
- EXPECT_FALSE(observed_model2->has_runtime_state());
-}
-
-// Create two update tasks but schedule them out of order. We expect them to
-// run in order.
-TEST_F(LedgerStoryModelStorageTest, UpdatesAreSequential) {
- auto [storage, observed_mutations, observed_model] = Create("page", "device");
-
- std::vector<StoryModelMutation> commands(1);
- commands[0].set_set_runtime_state(StoryState::RUNNING);
- auto promise1 = storage->Execute(std::move(commands));
-
- commands.resize(1);
- commands[0].set_set_runtime_state(StoryState::STOPPING);
- auto promise2 = storage->Execute(std::move(commands));
-
- executor.schedule_task(std::move(promise2));
- RunLoopUntilIdle(); // For good measure.
- executor.schedule_task(std::move(promise1));
-
- RunLoopUntilNumMutationsObserved(observed_mutations, 2);
- EXPECT_EQ(StoryState::STOPPING, *observed_model->runtime_state());
-}
-
-// When Load() is called, read what is stored in the Ledger back out and
-// expect to see commands that represent that state through the storage
-// observer.
-TEST_F(LedgerStoryModelStorageTest, Load) {
- StoryModel expected_model;
- {
- auto [storage, observed_mutations, observed_model] =
- Create("page", "device");
-
- std::vector<StoryModelMutation> commands(2);
- commands[0].set_set_runtime_state(StoryState::RUNNING);
- commands[1].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
- // TODO(thatguy): As we add more StoryModelMutations, add more lines here.
- executor.schedule_task(storage->Execute(std::move(commands)));
- RunLoopUntilNumMutationsObserved(observed_mutations, 1);
- expected_model = std::move(*observed_model);
- }
-
- auto [storage, observed_mutations, observed_model] = Create("page", "device");
-
- bool done{false};
- executor.schedule_task(
- storage->Load().then([&](fit::result<>&) { done = true; }));
- RunLoopUntil([&] { return done; });
- EXPECT_EQ(expected_model, *observed_model);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/meta/apply_mutations_unittest.cmx b/bin/sessionmgr/story/model/meta/apply_mutations_unittest.cmx
deleted file mode 100644
index 8b1229c..0000000
--- a/bin/sessionmgr/story/model/meta/apply_mutations_unittest.cmx
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "program": {
- "binary": "test/apply_mutations_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
-
diff --git a/bin/sessionmgr/story/model/meta/ledger_story_model_storage_unittest.cmx b/bin/sessionmgr/story/model/meta/ledger_story_model_storage_unittest.cmx
deleted file mode 100644
index bb0807c..0000000
--- a/bin/sessionmgr/story/model/meta/ledger_story_model_storage_unittest.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/ledger_story_model_storage_unittest"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/sessionmgr/story/model/meta/story_model_owner_unittest.cmx b/bin/sessionmgr/story/model/meta/story_model_owner_unittest.cmx
deleted file mode 100644
index b0d07ca..0000000
--- a/bin/sessionmgr/story/model/meta/story_model_owner_unittest.cmx
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "program": {
- "binary": "test/story_model_owner_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
diff --git a/bin/sessionmgr/story/model/noop_story_model_storage.cc b/bin/sessionmgr/story/model/noop_story_model_storage.cc
deleted file mode 100644
index 0f143ad..0000000
--- a/bin/sessionmgr/story/model/noop_story_model_storage.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story/model/noop_story_model_storage.h"
-
-#include <lib/fit/promise.h>
-
-namespace modular {
-
-NoopStoryModelStorage::NoopStoryModelStorage() = default;
-NoopStoryModelStorage::~NoopStoryModelStorage() = default;
-
-fit::promise<> NoopStoryModelStorage::Load() {
- return fit::make_promise([] { return fit::ok(); });
-}
-
-fit::promise<> NoopStoryModelStorage::Flush() {
- return fit::make_promise([] { return fit::ok(); });
-}
-
-fit::promise<> NoopStoryModelStorage::Execute(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands) {
- return fit::make_promise([this, commands = std::move(commands)]() mutable {
- Observe(std::move(commands));
- return fit::ok();
- })
- .wrap_with(scope_);
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/noop_story_model_storage.h b/bin/sessionmgr/story/model/noop_story_model_storage.h
deleted file mode 100644
index a10f9a2..0000000
--- a/bin/sessionmgr/story/model/noop_story_model_storage.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_MODEL_NOOP_STORY_MODEL_STORAGE_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_MODEL_NOOP_STORY_MODEL_STORAGE_H_
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/fit/scope.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/story/model/story_model_storage.h"
-
-namespace modular {
-
-// Performs no persistence. Dispatch()es any requested mutations.
-class NoopStoryModelStorage : public StoryModelStorage {
- public:
- NoopStoryModelStorage();
- ~NoopStoryModelStorage() override;
-
- private:
- fit::promise<> Load() override;
- fit::promise<> Flush() override;
- fit::promise<> Execute(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands)
- override;
-
- // When |scope_| is destroyed (which is when |this| is destructed), all
- // fit::promises we created in Mutate() will be abandoned. This is important
- // because those promises capture |this| in their handler functions.
- fit::scope scope_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(NoopStoryModelStorage);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_MODEL_NOOP_STORY_MODEL_STORAGE_H_
diff --git a/bin/sessionmgr/story/model/story_model_owner.cc b/bin/sessionmgr/story/model/story_model_owner.cc
deleted file mode 100644
index 362bd1d..0000000
--- a/bin/sessionmgr/story/model/story_model_owner.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story/model/story_model_owner.h"
-
-#include <lib/fit/bridge.h>
-#include <lib/fit/defer.h>
-#include <lib/fxl/logging.h>
-#include "peridot/bin/sessionmgr/story/model/apply_mutations.h"
-#include "peridot/bin/sessionmgr/story/model/story_model_storage.h"
-#include "peridot/bin/sessionmgr/story/model/story_mutator.h"
-
-using fuchsia::modular::storymodel::ModuleModel;
-using fuchsia::modular::storymodel::StoryModel;
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-namespace modular {
-
-namespace {
-// Sets default values for all fields of a new StoryModel. Defaults are
-// documented in
-// peridot/lib/fidl/public/fuchsia.modular.storymodel/story_model.fidl.
-void InitializeModelDefaults(StoryModel* model) {
- model->set_runtime_state(fuchsia::modular::StoryState::STOPPED);
- model->set_visibility_state(fuchsia::modular::StoryVisibilityState::DEFAULT);
- model->set_modules({});
-}
-} // namespace
-
-// Delegates Execute() to the StoryModelOwner.
-class StoryModelOwner::Mutator : public StoryMutator {
- public:
- Mutator(fxl::WeakPtr<StoryModelOwner> weak_owner) : weak_owner_(weak_owner) {}
- ~Mutator() override = default;
-
- private:
- // |StoryMutator|
- fit::consumer<> ExecuteInternal(
- std::vector<StoryModelMutation> commands) override {
- if (!weak_owner_) {
- fit::bridge<> bridge;
- bridge.completer.complete_error();
- return std::move(bridge.consumer);
- }
- return weak_owner_->ExecuteCommands(std::move(commands));
- }
-
- fxl::WeakPtr<StoryModelOwner> weak_owner_;
-};
-
-// Manages the lifecycle of multiple listener callbacks. When Observer dies,
-// all callbacks registered with RegisterListener() are unregistered from the
-// backing StoryModelOwner.
-class StoryModelOwner::Observer : public StoryObserver {
- public:
- Observer(fxl::WeakPtr<StoryModelOwner> weak_owner)
- : weak_owner_(weak_owner) {}
- ~Observer() {
- // If our owner is gone, all of the listener functions have already been
- // cleaned up. We need to cancel all the deferred actions since they
- // capture and make a call on our owner.
- if (!weak_owner_) {
- for (auto& i : deferred_cleanup_) {
- i.cancel();
- }
- }
- }
-
- private:
- void RegisterListener(
- fit::function<void(const StoryModel&)> listener) override {
- if (!weak_owner_) {
- return;
- // |listener| is destroyed.
- }
-
- deferred_cleanup_.push_back(
- weak_owner_->RegisterListener(std::move(listener)));
- }
-
- const StoryModel& model() override {
- FXL_CHECK(weak_owner_);
- return weak_owner_->model_;
- }
-
- fxl::WeakPtr<StoryModelOwner> weak_owner_;
- // When we are destroyed, we want to clean up any listeners we've added to
- // |shared_state_->owner|.
- std::vector<fit::deferred_action<fit::function<void()>>> deferred_cleanup_;
-};
-
-StoryModelOwner::StoryModelOwner(
- const std::string& story_name, fit::executor* executor,
- std::unique_ptr<StoryModelStorage> model_storage)
- : model_storage_(std::move(model_storage)),
- weak_ptr_factory_(this),
- executor_(executor) {
- FXL_CHECK(model_storage_ != nullptr);
- model_.mutable_name()->assign(story_name);
- InitializeModelDefaults(&model_);
- model_storage_->SetObserveCallback(
- [this](std::vector<StoryModelMutation> commands) {
- HandleObservedMutations(std::move(commands));
- });
-}
-
-StoryModelOwner::~StoryModelOwner() = default;
-
-std::unique_ptr<StoryMutator> StoryModelOwner::NewMutator() {
- return std::make_unique<Mutator>(weak_ptr_factory_.GetWeakPtr());
-}
-
-std::unique_ptr<StoryObserver> StoryModelOwner::NewObserver() {
- return std::make_unique<Observer>(weak_ptr_factory_.GetWeakPtr());
-}
-
-void StoryModelOwner::LoadStorage() {
- FXL_CHECK(!seen_any_requests_to_execute_)
- << "Must call LoadStorage() before any calls to StoryMutator.Execute();";
- executor_->schedule_task(model_storage_->Load());
-}
-
-fit::consumer<> StoryModelOwner::FlushStorage() {
- fit::bridge<> bridge;
- executor_->schedule_task(model_storage_->Flush().then(
- [completer = std::move(bridge.completer)](fit::result<>& result) mutable {
- if (result.is_ok()) {
- completer.complete_ok();
- } else {
- completer.complete_error();
- }
- }));
- return std::move(bridge.consumer);
-}
-
-fit::deferred_action<fit::function<void()>> StoryModelOwner::RegisterListener(
- fit::function<void(const StoryModel&)> listener) {
- auto it = listeners_.insert(listeners_.end(), std::move(listener));
- return fit::defer(
- fit::function<void()>([this, it] { listeners_.erase(it); }));
-}
-
-fit::consumer<> StoryModelOwner::ExecuteCommands(
- std::vector<StoryModelMutation> commands) {
- seen_any_requests_to_execute_ = true;
- // fit::bridge allows this function to return (and eventually complete) a
- // promise that is owned by the caller and still schedule a promise as a task
- // to execute the model update locally.
- //
- // If the caller chooses to ignore the result, our local promise will still be
- // scheduled and executed.
- fit::bridge<> bridge;
- auto promise = model_storage_->Execute(std::move(commands))
- .then([completer = std::move(bridge.completer)](
- fit::result<>& result) mutable {
- if (result.is_ok()) {
- completer.complete_ok();
- } else {
- completer.complete_error();
- }
- });
-
- executor_->schedule_task(std::move(promise));
- return std::move(bridge.consumer);
-}
-
-void StoryModelOwner::HandleObservedMutations(
- std::vector<StoryModelMutation> commands) {
- // This is not thread-safe. We rely on the fact that
- // HandleObservedMutations() will only be called on a single thread.
- StoryModel old_model;
- FXL_CHECK(fidl::Clone(model_, &old_model) == ZX_OK);
- model_ = ApplyMutations(old_model, std::move(commands));
-
- // Don't notify anyone if the model didn't change.
- if (model_ == old_model) {
- return;
- }
-
- executor_->schedule_task(fit::make_promise([this] {
- for (auto& listener : listeners_) {
- listener(model_);
- }
- return fit::ok();
- }).wrap_with(scope_));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/story_model_owner.h b/bin/sessionmgr/story/model/story_model_owner.h
deleted file mode 100644
index 11fdbc0..0000000
--- a/bin/sessionmgr/story/model/story_model_owner.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MODEL_OWNER_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MODEL_OWNER_H_
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/async_promise/executor.h>
-#include <lib/fit/defer.h>
-#include <lib/fit/scope.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include <list>
-#include <memory>
-
-#include "peridot/bin/sessionmgr/story/model/story_mutator.h"
-#include "peridot/bin/sessionmgr/story/model/story_observer.h"
-
-namespace modular {
-
-class StoryModelStorage;
-
-// Owns a single instance of StoryModel and manages the flow of control from a
-// stream of mutations to observers.
-//
-// Clients do not depend on or have any direct knowledge of StoryModelOwner.
-// Rather, they depend on either or both a StoryObserver and
-// StoryMutator, depending on if they need to observe or mutate the model.
-//
-// See README.md.
-//
-// This class is not thread-safe.
-class StoryModelOwner {
- public:
- // |story_name| is applied to StoryModel.name.
- //
- // Uses |executor| to schedule internal mutation tasks. Delegates mutation
- // commands to and reacts to observation of applied mutations from
- // |model_storage|.
- explicit StoryModelOwner(const std::string& story_name,
- fit::executor* executor,
- std::unique_ptr<StoryModelStorage> model_storage);
- ~StoryModelOwner();
-
- // Instructs |model_storage| to load persisted data. After calling, clients
- // may begin to see notifications through any created StoryObservers.
- //
- // This method must be called no more than once and before any associated
- // calls to StoryMutator.Execute().
- void LoadStorage();
-
- // Returns a consumer which is completed when |model_storage| has
- // successfully executed any pending tasks to mutate its underlying storage.
- // Note this does not indicate that the storage layer has notifed |this| of
- // the application of those mutations.
- //
- // To avoid losing any pending changes to the model, it is recommended to
- // call Flush() and wait for completion before destroying |this|.
- fit::consumer<> FlushStorage();
-
- // Returns a mutator object that can be provided to a System that requires
- // the ability to issue commands to mutate the model. This can be provided to
- // Systems as a constructor argument.
- //
- // The returned StoryMutator may outlive |this|, but will return an
- // error for all attempts to mutate the model.
- std::unique_ptr<StoryMutator> NewMutator();
-
- // Returns an object that can be used to register observer callbacks to the
- // be notified of the model's current state when changes are made. This
- // should be provided to Systems as a constructor argument.
- //
- // The returned StoryObserver may outlive |this|. See the documentation
- // for StoryObserver for caveats.
- std::unique_ptr<StoryObserver> NewObserver();
-
- private:
- class Mutator;
- class Observer;
-
- // Registers |listener| to be called whenever mutation commands are applied
- // to |model_|. Returns a deferred action that will deregister |listener|
- // when it goes out of scope.
- //
- // Called by instances of Observer.
- fit::deferred_action<fit::function<void()>> RegisterListener(
- fit::function<void(const fuchsia::modular::storymodel::StoryModel&)>
- listener);
-
- // Calls |model_storage_| to execute |commands|.
- //
- // Called by instances of Mutator.
- fit::consumer<> ExecuteCommands(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands);
-
- // Applies |commands| to |model_| and notifies all |listeners_| with the
- // updated StoryModel.
- //
- // Called indirectly by |model_storage_| through a callback.
- void HandleObservedMutations(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands);
-
- // Set to true on the first call to ExecuteCommands().
- bool seen_any_requests_to_execute_{false};
-
- std::unique_ptr<StoryModelStorage> model_storage_;
-
- // The most recent StoryModel value. Accessed by StoryObservers at any
- // time. Updated by HandleObservedMutations().
- fuchsia::modular::storymodel::StoryModel model_;
-
- // Used to signal to instances of StoryMutator/Observer when |this| is
- // destroyed.
- fxl::WeakPtrFactory<StoryModelOwner> weak_ptr_factory_;
-
- // A list<> so that we can get stable iterators for cleanup purposes. See
- // RegisterListener().
- std::list<
- fit::function<void(const fuchsia::modular::storymodel::StoryModel&)>>
- listeners_;
-
- fit::executor* executor_; // Not owned.
-
- // Since we schedule our fit::promises for execution on |executor_|, which can
- // outlive |this|, we use this to wrap our fit::promises (using
- // fit::promise.wrap_with(scope_)) such that when |this| is destroyed, all
- // pending promises are abandoned.
- fit::scope scope_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryModelOwner);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MODEL_OWNER_H_
diff --git a/bin/sessionmgr/story/model/story_model_owner_unittest.cc b/bin/sessionmgr/story/model/story_model_owner_unittest.cc
deleted file mode 100644
index 5fa3112..0000000
--- a/bin/sessionmgr/story/model/story_model_owner_unittest.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/fit/bridge.h>
-#include <lib/fit/function.h>
-#include <lib/fit/single_threaded_executor.h>
-
-#include "lib/gtest/test_loop_fixture.h"
-#include "peridot/bin/sessionmgr/story/model/story_model_owner.h"
-#include "peridot/bin/sessionmgr/story/model/story_model_storage.h"
-
-using fuchsia::modular::StoryVisibilityState;
-using fuchsia::modular::storymodel::StoryModel;
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-namespace modular {
-namespace {
-
-// This persistence system acts as a mock for calls to Execute(), and promotes
-// Observe() from protected to public so that we can call it directly from the
-// test body.
-class TestModelStorage : public StoryModelStorage {
- public:
- struct ExecuteCall {
- std::vector<StoryModelMutation> commands;
-
- // Call this after a call to Execute() to complete the returned promise.
- fit::completer<> completer;
- };
- std::vector<ExecuteCall> calls;
-
- fit::promise<> Load() override {
- return fit::make_promise([] { return fit::ok(); });
- }
-
- fit::promise<> Flush() override {
- return fit::make_promise([] { return fit::ok(); });
- }
-
- fit::promise<> Execute(std::vector<StoryModelMutation> commands) override {
- fit::bridge<> bridge;
-
- // Store the arguments we got.
- ExecuteCall call{.commands = std::move(commands),
- .completer = std::move(bridge.completer)};
- calls.push_back(std::move(call));
-
- return bridge.consumer.promise();
- }
-
- using StoryModelStorage::Observe;
-};
-
-class StoryModelOwnerTest : public ::gtest::TestLoopFixture {
- public:
- StoryModelOwnerTest() : TestLoopFixture() { ResetExecutor(); }
-
- std::unique_ptr<StoryModelOwner> Create(const std::string& story_name) {
- auto model_storage = std::make_unique<TestModelStorage>();
- model_storage_ = model_storage.get();
-
- auto owner = std::make_unique<StoryModelOwner>(story_name, executor_.get(),
- std::move(model_storage));
- return owner;
- }
-
- void ResetExecutor() { executor_.reset(new async::Executor(dispatcher())); }
-
- TestModelStorage* model_storage() { return model_storage_; }
-
- private:
- std::unique_ptr<async::Executor> executor_;
- TestModelStorage* model_storage_;
-};
-
-TEST_F(StoryModelOwnerTest, SuccessfulMutate) {
- // Show that a single mutation flows through the StoryModelOwner to
- // StoryModelStorage, and then applies the resulting commands.
- auto owner = Create("test_name");
-
- auto mutator = owner->NewMutator();
- bool done{false};
- auto result_task =
- mutator->set_visibility_state(StoryVisibilityState::IMMERSIVE)
- .promise()
- .and_then([&] { done = true; })
- .or_else([] { FAIL(); });
- RunLoopUntilIdle();
-
- // The persistence system should have been called.
- ASSERT_EQ(1lu, model_storage()->calls.size());
- ASSERT_EQ(1lu, model_storage()->calls[0].commands.size());
- EXPECT_TRUE(model_storage()->calls[0].commands[0].is_set_visibility_state());
- EXPECT_EQ(StoryVisibilityState::IMMERSIVE,
- model_storage()->calls[0].commands[0].set_visibility_state());
-
- // Complete the pending persistence call.
- model_storage()->calls[0].completer.complete_ok();
- RunLoopUntilIdle();
- fit::run_single_threaded(std::move(result_task));
- EXPECT_TRUE(done);
-
- // The existing model hasn't changed, because the StoryModelStorage
- // has not heard back from its storage that the mutation occurred.
- auto observer = owner->NewObserver();
- EXPECT_EQ("test_name", *observer->model().name());
- EXPECT_EQ(StoryVisibilityState::DEFAULT,
- *observer->model().visibility_state());
-
- // Now dispatch mutations from the persistence system, and we should observe
- // that ApplyMutations() is invoked.
- model_storage()->Observe(std::move(model_storage()->calls[0].commands));
-
- // And the new model value that ApplyMutations returned should be reflected in
- // the owner.
- EXPECT_EQ(StoryVisibilityState::IMMERSIVE,
- *observer->model().visibility_state());
-}
-
-TEST_F(StoryModelOwnerTest, FailedMutate) {
- auto owner = Create("test");
- auto mutator = owner->NewMutator();
- bool task_executed{false};
- bool saw_error{false};
- auto result_task =
- mutator->set_visibility_state(StoryVisibilityState::IMMERSIVE)
- .promise()
- .and_then([&] { task_executed = true; })
- .or_else([&] { saw_error = true; });
- RunLoopUntilIdle();
- model_storage()->calls[0].completer.complete_error();
- RunLoopUntilIdle();
- fit::run_single_threaded(std::move(result_task));
- EXPECT_FALSE(task_executed);
- EXPECT_TRUE(saw_error);
-}
-
-TEST_F(StoryModelOwnerTest, AbandonedMutate) {
- // If for some reason the underlying mutation is abandoned, we should observe
- // an error.
- auto owner = Create("test");
- auto mutator = owner->NewMutator();
- bool task_executed{false};
- bool saw_error{false};
- auto result_task =
- mutator->set_visibility_state(StoryVisibilityState::IMMERSIVE)
- .promise_or(fit::error()) // turn abandonment into an error.
- .and_then([&] { task_executed = true; })
- .or_else([&] { saw_error = true; });
- RunLoopUntilIdle();
- // Clearing the list of calls will destroy the completer, which has the
- // side-effect of abandoning the returned task.
- model_storage()->calls.clear();
- RunLoopUntilIdle();
- fit::run_single_threaded(std::move(result_task));
- EXPECT_FALSE(task_executed);
- EXPECT_TRUE(saw_error);
-}
-
-TEST_F(StoryModelOwnerTest, MutatorLifecycle_OwnerDestroyed) {
- // When the StoryModelOwner is destroyed but someone is still holding onto a
- // StoryMutator that mutator should return an error on Execute().
- auto owner = Create("test");
- auto mutator = owner->NewMutator();
- owner.reset();
- bool task_executed{false};
- bool saw_error{false};
- auto result_task =
- mutator->set_visibility_state(StoryVisibilityState::IMMERSIVE)
- .promise()
- .and_then([&] { task_executed = true; })
- .or_else([&] { saw_error = true; });
- RunLoopUntilIdle();
- fit::run_single_threaded(std::move(result_task));
- EXPECT_FALSE(task_executed);
- EXPECT_TRUE(saw_error);
-}
-
-TEST_F(StoryModelOwnerTest, ObserversAreNotified) {
- // One can create an observer and learn of the new state.
- auto owner = Create("test");
- auto mutator = owner->NewMutator();
- auto observer = owner->NewObserver();
-
- bool got_update1{false};
- observer->RegisterListener([&](const StoryModel& model) {
- got_update1 = true;
- EXPECT_EQ(StoryVisibilityState::IMMERSIVE, *model.visibility_state());
- });
-
- // Another listener should also get the update!
- bool got_update2{false};
- observer->RegisterListener(
- [&](const StoryModel& model) { got_update2 = true; });
-
- // Also on another observer.
- auto observer2 = owner->NewObserver();
- bool got_update3{false};
- observer2->RegisterListener(
- [&](const StoryModel& model) { got_update3 = true; });
-
- std::vector<StoryModelMutation> commands;
- commands.resize(1);
- commands[0].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
- model_storage()->Observe(std::move(commands));
- RunLoopUntilIdle();
- EXPECT_TRUE(got_update1);
- EXPECT_TRUE(got_update2);
- EXPECT_TRUE(got_update3);
-}
-
-TEST_F(StoryModelOwnerTest, ObserversAreNotNotifiedOnNoChange) {
- // Observers aren't told when an observed mutation doesn't change the model.
- auto owner = Create("test");
- auto mutator = owner->NewMutator();
- auto observer = owner->NewObserver();
-
- bool got_update{false};
- observer->RegisterListener([&](const StoryModel& model) {
- got_update = true;
- });
-
- std::vector<StoryModelMutation> commands;
- commands.resize(1);
- commands[0].set_set_visibility_state(StoryVisibilityState::DEFAULT);
- model_storage()->Observe(std::move(commands));
- RunLoopUntilIdle();
- EXPECT_FALSE(got_update);
-}
-
-TEST_F(StoryModelOwnerTest, ObserversLifecycle_ClientDestroyed) {
- // When the client destroys its observer object, it no longer receives
- // updates.
- auto owner = Create("test");
- auto mutator = owner->NewMutator();
- auto observer = owner->NewObserver();
-
- bool got_update{false};
- observer->RegisterListener(
- [&](const StoryModel& model) { got_update = true; });
-
- std::vector<StoryModelMutation> commands;
- commands.resize(1);
- commands[0].set_set_visibility_state(StoryVisibilityState::IMMERSIVE);
- model_storage()->Observe(std::move(commands));
-
- observer.reset();
- RunLoopUntilIdle();
- EXPECT_FALSE(got_update);
-}
-
-TEST_F(StoryModelOwnerTest, ObserversLifecycle_OwnerDestroyed) {
- // When the StoryModelOwner is destroyed, clients can learn of the fact by
- // using a fit::defer on the listener callback.
- auto owner = Create("test");
- auto mutator = owner->NewMutator();
- auto observer = owner->NewObserver();
-
- bool destroyed{false};
- observer->RegisterListener([defer = fit::defer([&] { destroyed = true; })](
- const StoryModel& model) {});
-
- owner.reset();
- EXPECT_TRUE(destroyed);
-
- // Explicitly destroy |observer| to ensure that its cleanup isn't affected by
- // |owner| being destroyed.
- observer.reset();
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/story_model_storage.cc b/bin/sessionmgr/story/model/story_model_storage.cc
deleted file mode 100644
index b37a571..0000000
--- a/bin/sessionmgr/story/model/story_model_storage.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story/model/story_model_storage.h"
-
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-StoryModelStorage::StoryModelStorage() = default;
-StoryModelStorage::~StoryModelStorage() = default;
-
-void StoryModelStorage::SetObserveCallback(
- fit::function<
- void(std::vector<fuchsia::modular::storymodel::StoryModelMutation>)>
- callback) {
- observe_callback_ = std::move(callback);
-}
-
-void StoryModelStorage::Observe(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands) {
- FXL_DCHECK(observe_callback_);
- observe_callback_(std::move(commands));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/story_model_storage.h b/bin/sessionmgr/story/model/story_model_storage.h
deleted file mode 100644
index 24521f3..0000000
--- a/bin/sessionmgr/story/model/story_model_storage.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MODEL_STORAGE_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MODEL_STORAGE_H_
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/async_promise/executor.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include <list>
-#include <memory>
-
-namespace modular {
-
-// The purpose of a StoryModelStorage is to apply StoryModelMutations to a
-// persistent storage layer and flow observed changes from the storage layer to
-// Observe().
-//
-// Due to the nature of some storage systems (such as Ledger), a call to
-// Mutate() doesn't necessarily result in an equivalent Observe().
-//
-// A trivial example: two peers, A and B, both call Mutate() with conflicting
-// instructions. Peer A learns of peer B's mutation before calling Observe(),
-// and conflict resolution results in no change to the model. In this case,
-// Observe() will not be called.
-class StoryModelStorage {
- public:
- StoryModelStorage();
- virtual ~StoryModelStorage();
-
- // Registers a callback that is called when Observe() is called by
- // implementers.
- void SetObserveCallback(
- fit::function<
- void(std::vector<fuchsia::modular::storymodel::StoryModelMutation>)>
- callback);
-
- // Returns a task that, when executed, loads existing data in storage and
- // calls Observe() with mutations that will update a default-initialized
- // StoryModel to reflect the values in storage, THEN resolves the returned
- // promise.
- virtual fit::promise<> Load() = 0;
-
- // Returns a task that, when complete, guarantees all prior calls to Execute()
- // are complete. Any calls to Execute() that are issued after Flush() are not
- // guaranteed to be complete.
- virtual fit::promise<> Flush() = 0;
-
- // Returns a task that, when executed, applies |commands| to the underlying
- // storage system. Clients can expect that similar mutations will be observed
- // through SetObserveCallback()'s |callback| at some point in the future.
- // However, in the case of conflict resolution or a similar process, the set
- // of observed mutations may be different.
- virtual fit::promise<> Execute(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation>
- commands) = 0;
-
- protected:
- // Calls to Observe() must always be made from the same thread: ordering
- // of the observed mutations matters.
- void Observe(std::vector<fuchsia::modular::storymodel::StoryModelMutation>);
-
- private:
- fit::function<void(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation>)>
- observe_callback_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryModelStorage);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MODEL_STORAGE_H_
diff --git a/bin/sessionmgr/story/model/story_mutator.cc b/bin/sessionmgr/story/model/story_mutator.cc
deleted file mode 100644
index c91c1e0..0000000
--- a/bin/sessionmgr/story/model/story_mutator.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <vector>
-
-#include "peridot/bin/sessionmgr/story/model/story_mutator.h"
-
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-namespace modular {
-
-StoryMutator::StoryMutator() = default;
-StoryMutator::~StoryMutator() = default;
-
-fit::consumer<> StoryMutator::set_runtime_state(
- fuchsia::modular::StoryState state) {
- std::vector<StoryModelMutation> commands(1);
- commands[0].set_set_runtime_state(state);
- return ExecuteInternal(std::move(commands));
-}
-
-fit::consumer<> StoryMutator::set_visibility_state(
- fuchsia::modular::StoryVisibilityState state) {
- std::vector<StoryModelMutation> commands(1);
- commands[0].set_set_visibility_state(state);
- return ExecuteInternal(std::move(commands));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/story_mutator.h b/bin/sessionmgr/story/model/story_mutator.h
deleted file mode 100644
index 58f6943..0000000
--- a/bin/sessionmgr/story/model/story_mutator.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MUTATOR_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MUTATOR_H_
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/fit/bridge.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-// Implemented by and created by the StoryModelOwner.
-//
-// An instance of StoryMutator is provided to all clients that wish to perform
-// mutations on a StoryModel. It is responsible for consuming mutation commands
-// (exposed as methods publicly and converted to StoryModelMutation internally)
-// and dispatching them be applied to a shared StoryModel instance.
-//
-// This is an interface in order to aid in testing clients that depend on
-// StoryMutator.
-class StoryMutator {
- public:
- StoryMutator();
- virtual ~StoryMutator();
-
- // The following mutators issue a single mutation instruction to
- // change the StoryModel.
- //
- // The returned fit::consumer<> will eventually be completed with the result
- // of the mutation operation, HOWEVER success does not guarantee that
- // observers of the StoryModel will see those same changes reflected, and thus
- // clients should NOT perform side-effects under that assumption.
- //
- // It IS safe to perform side-effects once mutations have been observed
- // through StoryObserver.
- //
- // A failure guarantees that the mutation was not applied and it is safe to
- // retry.
-
- // Sets the value of |StoryModel.runtime_state|.
- fit::consumer<> set_runtime_state(
- fuchsia::modular::StoryState state);
-
- // Sets the value of |StoryModel.visibility_state|.
- fit::consumer<> set_visibility_state(
- fuchsia::modular::StoryVisibilityState state);
-
- private:
- // Executes |commands| in order and in a single transaction.
- virtual fit::consumer<> ExecuteInternal(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation>
- commands) = 0;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryMutator);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_MUTATOR_H_
diff --git a/bin/sessionmgr/story/model/story_observer.h b/bin/sessionmgr/story/model/story_observer.h
deleted file mode 100644
index f1eb211..0000000
--- a/bin/sessionmgr/story/model/story_observer.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_OBSERVER_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_OBSERVER_H_
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-// Implemented bv StoryModelOwner. A client of StoryObserver can query the
-// current state of a StoryModel or register a callback to be notified of
-// changes.
-class StoryObserver {
- public:
- StoryObserver() = default;
- virtual ~StoryObserver() = default;
-
- // Registers |listener| as a callback for StoryModel updates. If |this| is
- // destroyed, or the StoryModelOwner that created |this| is destroyed, all
- // registered listeners will also be destroyed.
- //
- // Clients may learn that the StoryModelOwner is destroyed by deferring
- // a callback in the capture list of |listener|. Example:
- //
- // auto on_abandoned = [] { /* do some cleanup */ };
- // observer.RegisterListener(
- // [on_destroy = fit::defer(on_abandoned)]
- // (const StoryModel& model) {
- // /* do something with the update */
- // });
- //
- // Note that the received StoryModel is only valid for the lifetime
- // of the call to |listener|.
- virtual void RegisterListener(
- fit::function<void(const fuchsia::modular::storymodel::StoryModel& model)>
- listener) = 0;
-
- // Returns the current state of the StoryModel.
- virtual const fuchsia::modular::storymodel::StoryModel& model() = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryObserver);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_MODEL_STORY_OBSERVER_H_
diff --git a/bin/sessionmgr/story/model/testing/BUILD.gn b/bin/sessionmgr/story/model/testing/BUILD.gn
deleted file mode 100644
index ab87913..0000000
--- a/bin/sessionmgr/story/model/testing/BUILD.gn
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("testing") {
- testonly = true
-
- public_deps = [
- ":mutation_matchers",
- ":test_mutator",
- ]
-}
-
-source_set("mutation_matchers") {
- testonly = true
-
- sources = [
- "mutation_matchers.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular.storymodel",
- "//third_party/googletest:gmock",
- ]
-}
-
-source_set("test_mutator") {
- testonly = true
-
- sources = [
- "test_mutator.cc",
- "test_mutator.h",
- ]
-
- deps = [
- "//peridot/bin/sessionmgr/story/model",
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-}
diff --git a/bin/sessionmgr/story/model/testing/mutation_matchers.h b/bin/sessionmgr/story/model/testing/mutation_matchers.h
deleted file mode 100644
index c9b8730..0000000
--- a/bin/sessionmgr/story/model/testing/mutation_matchers.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-
-#include "gmock/gmock.h" // For MATCHER macros.
-#include "lib/fostr/fidl/fuchsia/modular/formatting.h"
-#include "lib/fostr/fidl/fuchsia/modular/storymodel/formatting.h"
-
-namespace modular {
-
-// |arg| is a StoryModelMutation, |expected| is a StoryVisibilitystate.
-MATCHER_P(IsSetVisibilityMutation, expected, "") {
- *result_listener << "is set_visibility_state " << expected;
- if (!arg.is_set_visibility_state())
- return false;
- return expected == arg.set_visibility_state();
-}
-
-// |arg| is a StoryModelMutation, |expected| is a StoryState.
-MATCHER_P(IsSetRuntimeStateMutation, expected, "") {
- *result_listener << "is set_runtime_state " << expected;
- if (!arg.is_set_runtime_state())
- return false;
- return expected == arg.set_runtime_state();
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/testing/test_mutator.cc b/bin/sessionmgr/story/model/testing/test_mutator.cc
deleted file mode 100644
index 1ee3a2a..0000000
--- a/bin/sessionmgr/story/model/testing/test_mutator.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story/model/testing/test_mutator.h"
-
-namespace modular {
-
-
-std::unique_ptr<StoryMutator> TestMutator::Create(TestMutator** ptr) {
- auto mutator = std::make_unique<TestMutator>();
- *ptr = mutator.get();
- return mutator;
-}
-
-fit::consumer<> TestMutator::ExecuteInternal(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands) {
- fit::bridge<> bridge;
- ExecuteCall call{.completer = std::move(bridge.completer),
- .commands = std::move(commands)};
- execute_calls.push_back(std::move(call));
- return std::move(bridge.consumer);
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/model/testing/test_mutator.h b/bin/sessionmgr/story/model/testing/test_mutator.h
deleted file mode 100644
index 52f044c..0000000
--- a/bin/sessionmgr/story/model/testing/test_mutator.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <lib/fit/bridge.h>
-
-#include "peridot/bin/sessionmgr/story/model/story_mutator.h"
-
-namespace modular {
-
-// A version of StoryMutator for use in tests.
-//
-// Collects all calls to StoryMutator.Execute() in public member
-// |execute_calls|. Each element of |execute_calls| consists of:
-//
-// * |ExecuteCall.commands| are the StoryModelMutation commands that were
-// issued in the Execute() call.
-// * |ExecuteCall.completer| is used to complete the fit::promise<> that
-// Execute() returns. The test author must call |completer.complete_ok()| or
-// |completer.complete_error()| for any tasks blocked on the Execute() call to
-// unblock.
-class TestMutator : public StoryMutator {
- public:
- // Convenience factory allowing the caller to retain a pointer to the TestMutator
- // when constructing a class that accepts a StoryMutator as a constructor argument.
- //
- // Usage:
- //
- // TestMutator* test_mutator;
- // Foo foo(TestMutator::Create(&test_mutator));
- static std::unique_ptr<StoryMutator> Create(TestMutator** ptr);
-
- fit::consumer<> ExecuteInternal(
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands)
- override;
-
- struct ExecuteCall {
- fit::completer<> completer;
- std::vector<fuchsia::modular::storymodel::StoryModelMutation> commands;
- };
- std::vector<ExecuteCall> execute_calls;
-};
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/system.cc b/bin/sessionmgr/story/system.cc
deleted file mode 100644
index e740e48..0000000
--- a/bin/sessionmgr/story/system.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story/system.h"
-
-namespace modular {
-
-System::~System() {}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/system.h b/bin/sessionmgr/story/system.h
deleted file mode 100644
index 371c8e9..0000000
--- a/bin/sessionmgr/story/system.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_SYSTEM_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_SYSTEM_H_
-
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-// Common interface for all story runtime systems.
-class System {
- public:
- System() {}
- virtual ~System();
-
- // TODO(thatguy): Add lifecycle methods Initialize() and Teardown().
- // TODO(thatguy): Add Inspect API hooks for debug output.
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(System);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_SYSTEM_H_
diff --git a/bin/sessionmgr/story/systems/BUILD.gn b/bin/sessionmgr/story/systems/BUILD.gn
deleted file mode 100644
index a50db14..0000000
--- a/bin/sessionmgr/story/systems/BUILD.gn
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-hermetic_tests_package("story_systems_unittests") {
- deps = [
- ":story_visibility_system_unittest",
- ]
-}
-
-source_set("story_visibility_system") {
- sources = [
- "story_visibility_system.cc",
- "story_visibility_system.h",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- deps = [
- "//peridot/bin/sessionmgr/story:system",
- "//peridot/bin/sessionmgr/story/model",
- "//peridot/public/fidl/fuchsia.modular.storymodel",
- ]
-}
-
-executable("story_visibility_system_unittest") {
- testonly = true
-
- sources = [
- "story_visibility_system_unittest.cc",
- ]
-
- deps = [
- ":story_visibility_system",
- "//peridot/bin/sessionmgr/story/model",
- "//peridot/bin/sessionmgr/story/model/testing",
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/sessionmgr/story/systems/meta/story_visibility_system_unittest.cmx b/bin/sessionmgr/story/systems/meta/story_visibility_system_unittest.cmx
deleted file mode 100644
index 7a3c73c..0000000
--- a/bin/sessionmgr/story/systems/meta/story_visibility_system_unittest.cmx
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "program": {
- "binary": "test/story_visibility_system_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
diff --git a/bin/sessionmgr/story/systems/story_visibility_system.cc b/bin/sessionmgr/story/systems/story_visibility_system.cc
deleted file mode 100644
index 42f3d7d..0000000
--- a/bin/sessionmgr/story/systems/story_visibility_system.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-
-#include "peridot/bin/sessionmgr/story/systems/story_visibility_system.h"
-
-#include "peridot/bin/sessionmgr/story/model/story_mutator.h"
-
-namespace modular {
-
-using fuchsia::modular::StoryVisibilityState;
-using fuchsia::modular::storymodel::StoryModel;
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-StoryVisibilitySystem::StoryVisibilitySystem(
- std::unique_ptr<StoryMutator> mutator)
- : mutator_(std::move(mutator)) {}
-
-StoryVisibilitySystem::~StoryVisibilitySystem() {}
-
-void StoryVisibilitySystem::RequestStoryVisibilityStateChange(
- const StoryVisibilityState visibility_state) {
- // Ignore any error resulting from this operation.
- mutator_->set_visibility_state(visibility_state);
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story/systems/story_visibility_system.h b/bin/sessionmgr/story/systems/story_visibility_system.h
deleted file mode 100644
index 5b33c29..0000000
--- a/bin/sessionmgr/story/systems/story_visibility_system.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_SYSTEMS_STORY_VISIBILITY_SYSTEM_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_SYSTEMS_STORY_VISIBILITY_SYSTEM_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <memory>
-
-#include "peridot/bin/sessionmgr/story/system.h"
-
-namespace modular {
-
-class StoryMutator;
-
-// This sytem implements the policy for translating requests from Modules to
-// change the visibility state of the story into the final visibility state of
-// the story.
-//
-// The current policy is "allow all".
-class StoryVisibilitySystem : public System {
- public:
- StoryVisibilitySystem(std::unique_ptr<StoryMutator> model_mutator);
- ~StoryVisibilitySystem() override;
-
- void RequestStoryVisibilityStateChange(
- const fuchsia::modular::StoryVisibilityState visibility_state);
-
- private:
- std::unique_ptr<StoryMutator> mutator_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_SYSTEMS_STORY_VISIBILITY_SYSTEM_H_
diff --git a/bin/sessionmgr/story/systems/story_visibility_system_unittest.cc b/bin/sessionmgr/story/systems/story_visibility_system_unittest.cc
deleted file mode 100644
index 6dea661..0000000
--- a/bin/sessionmgr/story/systems/story_visibility_system_unittest.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-
-#include "gmock/gmock.h" // For EXPECT_THAT and matchers.
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionmgr/story/model/testing/mutation_matchers.h"
-#include "peridot/bin/sessionmgr/story/model/testing/test_mutator.h"
-#include "peridot/bin/sessionmgr/story/systems/story_visibility_system.h"
-
-using fuchsia::modular::storymodel::StoryModel;
-using fuchsia::modular::storymodel::StoryModelMutation;
-
-namespace modular {
-namespace {
-
-class StoryVisibilitySystemTest : public ::testing::Test {
- protected:
- StoryVisibilitySystemTest() {
- system_ =
- std::make_unique<StoryVisibilitySystem>(TestMutator::Create(&mutator_));
- }
-
- std::unique_ptr<StoryVisibilitySystem> system_;
- TestMutator* mutator_;
-};
-
-TEST_F(StoryVisibilitySystemTest, All) {
- system_->RequestStoryVisibilityStateChange(
- fuchsia::modular::StoryVisibilityState::IMMERSIVE);
-
- EXPECT_EQ(1lu, mutator_->execute_calls.size());
- EXPECT_THAT(mutator_->execute_calls[0].commands,
- testing::ElementsAre(IsSetVisibilityMutation(
- fuchsia::modular::StoryVisibilityState::IMMERSIVE)));
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/BUILD.gn b/bin/sessionmgr/story_runner/BUILD.gn
deleted file mode 100644
index bb689ee..0000000
--- a/bin/sessionmgr/story_runner/BUILD.gn
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-import("//peridot/build/tests_package.gni")
-
-hermetic_tests_package("story_runner_unittests") {
- deps = [
- ":link_impl_unittest",
- ":story_controller_impl_unittest", # incomplete, for now.
- ]
-}
-
-# NOTE: We are in the process of deconstructing story_runner into its
-# constituent components. Please see MF-85.
-source_set("story_runner") {
- sources = [
- "link_impl.cc",
- "link_impl.h",
- "module_context_impl.cc",
- "module_context_impl.h",
- "module_controller_impl.cc",
- "module_controller_impl.h",
- "ongoing_activity_impl.cc",
- "ongoing_activity_impl.h",
- "story_controller_impl.cc",
- "story_controller_impl.h",
- "story_entity_provider.cc",
- "story_entity_provider.h",
- "story_provider_impl.cc",
- "story_provider_impl.h",
- "story_shell_context_impl.cc",
- "story_shell_context_impl.h",
- ]
-
- public_deps = [
- "//garnet/bin/ui/snapshot:snapshot_loader",
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/bin/basemgr/cobalt",
- "//peridot/bin/ledger/fidl",
- "//peridot/bin/sessionmgr:component_context",
- "//peridot/bin/sessionmgr:focus",
- "//peridot/bin/sessionmgr:presentation_provider",
- "//peridot/bin/sessionmgr/agent_runner",
- "//peridot/bin/sessionmgr/message_queue",
- "//peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls:add_mod_call",
- "//peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls:find_modules_call",
- "//peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls:get_types_from_entity_call",
- "//peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls:initialize_chain_call",
- "//peridot/bin/sessionmgr/storage:constants_and_utils",
- "//peridot/bin/sessionmgr/story/model",
- "//peridot/bin/sessionmgr/story/systems:story_visibility_system",
- "//peridot/lib/common:names",
- "//peridot/lib/common:teardown",
- "//peridot/lib/fidl:app_client",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:environment",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/fidl:proxy",
- "//peridot/lib/ledger_client:operations",
- "//peridot/lib/ledger_client:page_client",
- "//peridot/lib/ledger_client:types",
- "//peridot/lib/module_manifest:module_facet_reader",
- "//peridot/lib/rapidjson",
- "//peridot/lib/util",
- "//peridot/lib/util:debug",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/lib/async/cpp:future",
- "//peridot/public/lib/async/cpp:operation",
- "//peridot/public/lib/context/cpp:context_helper",
- "//peridot/public/lib/entity/cpp:json",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular",
- ]
-
- deps = [
- "//peridot/bin/sessionmgr/storage",
- "//peridot/bin/sessionmgr/story:system",
- "//peridot/bin/sessionmgr/story/model",
- "//peridot/bin/sessionmgr/story/model:noop_story_model_storage",
- "//peridot/bin/sessionmgr/story/model:story_model_owner",
- "//peridot/lib/fidl:clone",
- "//peridot/public/fidl/fuchsia.modular",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("dev_story_shell") {
- meta = [
- {
- path = "meta/dev_story_shell.cmx"
- dest = "dev_story_shell.cmx"
- },
- ]
- sources = [
- "dev_story_shell.cc",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:single_service_app",
- "//peridot/lib/fidl:view_host",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable("story_controller_impl_unittest") {
- testonly = true
-
- sources = [
- "story_controller_impl_unittest.cc",
- ]
-
- deps = [
- ":story_runner",
- "//peridot/lib/fidl:clone",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-executable("link_impl_unittest") {
- testonly = true
-
- sources = [
- "link_impl_unittest.cc",
- ]
-
- deps = [
- ":story_runner",
- "//peridot/bin/sessionmgr/agent_runner",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/testing:test_with_ledger",
- "//peridot/public/lib/entity/cpp:json",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/sessionmgr/story_runner/README.md b/bin/sessionmgr/story_runner/README.md
deleted file mode 100644
index e0fc842..0000000
--- a/bin/sessionmgr/story_runner/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-NOTE: The contents of this directory will slowly migrate into:
-
-../story/model
-../story/system
-../story/fidl
-
-during the process of a refactor. Please avoid adding new contents
-here.
diff --git a/bin/sessionmgr/story_runner/dev_story_shell.cc b/bin/sessionmgr/story_runner/dev_story_shell.cc
deleted file mode 100644
index 3d1aca5..0000000
--- a/bin/sessionmgr/story_runner/dev_story_shell.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implementation of the fuchsia::modular::StoryShell service that just lays out
-// the views of all modules side by side.
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/fidl/single_service_app.h"
-#include "peridot/lib/fidl/view_host.h"
-
-namespace {
-
-class DevStoryShellApp
- : public modular::SingleServiceApp<fuchsia::modular::StoryShell> {
- public:
- DevStoryShellApp(component::StartupContext* const startup_context)
- : SingleServiceApp(startup_context) {}
-
- ~DevStoryShellApp() override = default;
-
- private:
- // |SingleServiceApp|
- void CreateView(
- zx::eventpair view_token,
- fidl::InterfaceRequest<
- fuchsia::sys::ServiceProvider> /*incoming_services*/,
- fidl::InterfaceHandle<
- fuchsia::sys::ServiceProvider> /*outgoing_services*/) override {
- view_owner_request_ =
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>(
- zx::channel(view_token.release()));
- Connect();
- }
-
- // |fuchsia::modular::StoryShell|
- void Initialize(fidl::InterfaceHandle<fuchsia::modular::StoryShellContext>
- story_shell_context) override {
- story_shell_context_.Bind(std::move(story_shell_context));
- Connect();
- }
-
- // |fuchsia::modular::StoryShell|
- void AddSurface(
- fuchsia::modular::ViewConnection view_connection,
- fuchsia::modular::SurfaceInfo /*surface_info*/) override {
- if (view_) {
- view_->ConnectView(std::move(view_connection.owner));
- } else {
- child_views_.push_back(std::move(view_connection.owner));
- }
- }
-
- // |fuchsia::modular::StoryShell|
- void FocusSurface(std::string /*surface_id*/) override {}
-
- // |fuchsia::modular::StoryShell|
- void DefocusSurface(std::string /*surface_id*/,
- DefocusSurfaceCallback callback) override {
- callback();
- }
-
- // |fuchsia::modular::StoryShell|
- void AddContainer(
- std::string /*container_name*/, fidl::StringPtr /*parent_id*/,
- fuchsia::modular::SurfaceRelation /* relation */,
- std::vector<fuchsia::modular::ContainerLayout> /*layout*/,
- std::vector<
- fuchsia::modular::ContainerRelationEntry> /* relationships */,
- std::vector<fuchsia::modular::ContainerView> /* views */) override {}
-
- // |fuchsia::modular::StoryShell|
- void RemoveSurface(std::string /*surface_id*/) override {}
-
- // |fuchsia::modular::StoryShell|
- void ReconnectView(fuchsia::modular::ViewConnection view_connection) override {}
-
- // |fuchsia::modular::StoryShell|
- void UpdateSurface(fuchsia::modular::ViewConnection view_connection,
- fuchsia::modular::SurfaceInfo /*surface_info*/) override {};
-
- void Connect() {
- if (story_shell_context_.is_bound() && view_owner_request_) {
- auto scenic =
- startup_context()
- ->ConnectToEnvironmentService<fuchsia::ui::scenic::Scenic>();
- scenic::ViewContext view_context = {
- .session_and_listener_request =
- scenic::CreateScenicSessionPtrAndListenerRequest(scenic.get()),
- .view_token =
- zx::eventpair(view_owner_request_.TakeChannel().release()),
- .startup_context = startup_context(),
- };
- view_ = std::make_unique<modular::ViewHost>(std::move(view_context));
-
- for (auto& view_owner : child_views_) {
- view_->ConnectView(std::move(view_owner));
- }
-
- child_views_.clear();
- }
- }
-
- std::unique_ptr<modular::ViewHost> view_;
- std::vector<fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner>>
- child_views_;
-
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request_;
- fuchsia::modular::StoryShellContextPtr story_shell_context_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DevStoryShellApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
-
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AppDriver<DevStoryShellApp> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<DevStoryShellApp>(context.get()),
- [&loop] { loop.Quit(); });
-
- loop.Run();
- return 0;
-}
diff --git a/bin/sessionmgr/story_runner/link_impl.cc b/bin/sessionmgr/story_runner/link_impl.cc
deleted file mode 100644
index b81780d..0000000
--- a/bin/sessionmgr/story_runner/link_impl.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/link_impl.h"
-
-#include <functional>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/entity/cpp/json.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fostr/fidl/fuchsia/modular/formatting.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/util/debug.h"
-
-using fuchsia::modular::LinkWatcherPtr;
-
-namespace modular {
-
-namespace {
-
-// Applies a JSON mutation operation using |apply_fn|. Its parameters are
-// references because we treat |apply_fn| as part of ApplyOp's body.
-void ApplyOp(
- fidl::StringPtr* value_str, const std::vector<std::string>& path,
- std::function<void(CrtJsonDoc& doc, CrtJsonPointer& pointer)> apply_fn) {
- CrtJsonDoc value;
- if (!value_str->is_null()) {
- value.Parse(*value_str);
- }
- auto pointer = CreatePointer(value, path);
- apply_fn(value, pointer);
- *value_str = JsonValueToString(value);
-}
-
-bool ApplySetOp(fidl::StringPtr* value_str,
- const fidl::VectorPtr<std::string>& path,
- const fidl::StringPtr& new_value_at_path_str) {
- CrtJsonDoc new_value_at_path;
- new_value_at_path.Parse(new_value_at_path_str);
- if (new_value_at_path.HasParseError()) {
- return false;
- }
-
- auto apply_fn = [&new_value_at_path](CrtJsonDoc& doc, CrtJsonPointer& p) {
- p.Set(doc, std::move(new_value_at_path));
- };
- ApplyOp(value_str, path, apply_fn);
- return true;
-}
-
-void ApplyEraseOp(fidl::StringPtr* value_str,
- const std::vector<std::string>& path) {
- auto apply_fn = [](CrtJsonDoc& doc, CrtJsonPointer& p) { p.Erase(doc); };
- ApplyOp(value_str, path, apply_fn);
-}
-
-fuchsia::mem::Buffer StringToVmo(const std::string& string) {
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(string, &vmo));
- return std::move(vmo).ToTransport();
-}
-
-} // namespace
-
-LinkImpl::LinkImpl(StoryStorage* const story_storage, LinkPath link_path)
- : story_storage_(story_storage),
- link_path_(std::move(link_path)),
- weak_factory_(this),
- link_watcher_auto_cancel_(nullptr) {
- FXL_DCHECK(story_storage != nullptr);
-
- // When |link_watcher_auto_cancel_| goes out of scope, |story_storage_| will
- // stop calling OnLinkValueChanged.
- link_watcher_auto_cancel_ = story_storage_->WatchLink(
- link_path_, [this](const fidl::StringPtr& value, const void* context) {
- OnLinkValueChanged(value, context);
- });
-}
-
-LinkImpl::~LinkImpl() = default;
-
-void LinkImpl::Get(fidl::VectorPtr<std::string> path,
- GetCallback callback) {
- // TODO: Need error reporting. MI4-1082
- story_storage_->GetLinkValue(link_path_)
- ->WeakMap(
- GetWeakPtr(),
- fxl::MakeCopyable([this /* for link_path_ */, path = std::move(path)](
- StoryStorage::Status status,
- fidl::StringPtr value) mutable {
- if (status != StoryStorage::Status::OK) {
- FXL_LOG(ERROR) << "Getting link " << link_path_
- << " failed: " << static_cast<int>(status);
-
- return std::string("null");
- }
-
- else if (!path || path->empty()) {
- // Common case requires no parsing of the JSON.
- return *value;
- } else {
- // Extract just the |path| portion of the value.
- CrtJsonDoc json;
- json.Parse(value);
- if (json.HasParseError()) {
- return std::string("null");
- }
- auto& value_at_path = CreatePointer(json, *path)
- .GetWithDefault(json, CrtJsonValue());
- return JsonValueToString(value_at_path);
- }
- }))
- ->WeakThen(GetWeakPtr(),
- [callback = std::move(callback)](std::string json) {
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(json, &vmo));
- auto vmo_ptr = std::make_unique<fuchsia::mem::Buffer>(
- std::move(vmo).ToTransport());
- callback(std::move(vmo_ptr));
- });
-}
-
-void LinkImpl::Set(fidl::VectorPtr<std::string> path,
- fuchsia::mem::Buffer json) {
- std::string json_string;
- FXL_CHECK(fsl::StringFromVmo(json, &json_string));
- Set(std::move(path), json_string);
-}
-
-void LinkImpl::Set(fidl::VectorPtr<std::string> path,
- const std::string& json) {
- // TODO: Need error reporting. MI4-1082
- story_storage_
- ->UpdateLinkValue(
- link_path_,
- fxl::MakeCopyable([this /* for link_path_ */, path = std::move(path),
- json = std::move(json)](fidl::StringPtr* value) {
- if (!ApplySetOp(value, path, json)) {
- FXL_LOG(ERROR) << "LinkImpl.Set failed for link " << link_path_
- << " with json " << json;
- }
- }),
- this /* context */)
- ->Then([](StoryStorage::Status status) {
- // TODO: Error reporting. MI4-1082
- });
-}
-
-void LinkImpl::Erase(std::vector<std::string> path) {
- // TODO: Need error reporting. MI4-1082
- story_storage_
- ->UpdateLinkValue(
- link_path_,
- fxl::MakeCopyable([this /* for link_path_ */,
- path = std::move(path)](fidl::StringPtr* value) {
- ApplyEraseOp(value, path);
- }),
- this /* context */)
- ->Then([](StoryStorage::Status status) {
- // TODO: Error reporting. MI4-1082
- });
-}
-
-void LinkImpl::GetEntity(GetEntityCallback callback) {
- // TODO: Need error reporting. MI4-1082
-
- story_storage_->GetLinkValue(link_path_)
- ->WeakThen(GetWeakPtr(), [this, callback](StoryStorage::Status status,
- fidl::StringPtr value) {
- if (status != StoryStorage::Status::OK) {
- FXL_LOG(ERROR) << "Getting link " << link_path_
- << " failed: " << static_cast<int>(status);
- callback(nullptr);
- }
- // Convert the contents to an Entity reference, if possible.
- std::string ref;
- if (!EntityReferenceFromJson(value, &ref)) {
- FXL_LOG(ERROR) << "Link value for " << link_path_
- << " is not an entity reference.";
- callback(nullptr);
- return;
- }
-
- callback(ref);
- });
-}
-
-void LinkImpl::SetEntity(fidl::StringPtr entity_reference) {
- // SetEntity() is just a variation on Set(), so delegate to Set().
- Set(nullptr, EntityReferenceToJson(entity_reference));
-}
-
-void LinkImpl::Sync(SyncCallback callback) {
- story_storage_->Sync()->WeakThen(GetWeakPtr(), callback);
-}
-
-void LinkImpl::OnLinkValueChanged(const fidl::StringPtr& value,
- const void* context) {
- // If context == this, the change came from us. Otherwise, it either came
- // from a different LinkImpl (in which case context != nullptr), or a
- // different StoryStorage altogether (even on a different device).
- if (context != this) {
- for (auto& dst : normal_watchers_.ptrs()) {
- (*dst)->Notify(StringToVmo(value));
- }
- }
-
- // No matter what, everyone in |everything_watchers_| sees everything.
- for (auto& dst : everything_watchers_.ptrs()) {
- (*dst)->Notify(StringToVmo(value));
- }
-}
-
-void LinkImpl::Watch(fidl::InterfaceHandle<LinkWatcher> watcher) {
- // Move |watcher| into the callback for Get(): we are guaranteed
- // that no other operation will run on |story_storage_| until our callback
- // is complete, which means the next mutation that happens will be sent to
- // |watcher|.
- Get(nullptr, fxl::MakeCopyable(
- [this, watcher = std::move(watcher)](
- std::unique_ptr<fuchsia::mem::Buffer> value) mutable {
- auto ptr = watcher.Bind();
- ptr->Notify(std::move(*value));
- normal_watchers_.AddInterfacePtr(std::move(ptr));
- }));
-}
-
-void LinkImpl::WatchAll(
- fidl::InterfaceHandle<fuchsia::modular::LinkWatcher> watcher) {
- Get(nullptr, fxl::MakeCopyable(
- [this, watcher = std::move(watcher)](
- std::unique_ptr<fuchsia::mem::Buffer> value) mutable {
- auto ptr = watcher.Bind();
- ptr->Notify(std::move(*value));
- everything_watchers_.AddInterfacePtr(std::move(ptr));
- }));
-}
-
-fxl::WeakPtr<LinkImpl> LinkImpl::GetWeakPtr() {
- return weak_factory_.GetWeakPtr();
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/link_impl.h b/bin/sessionmgr/story_runner/link_impl.h
deleted file mode 100644
index 8afbb87..0000000
--- a/bin/sessionmgr/story_runner/link_impl.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_LINK_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_LINK_IMPL_H_
-
-#include <set>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/types.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-
-using fuchsia::modular::Link;
-using fuchsia::modular::LinkPath;
-using fuchsia::modular::LinkWatcher;
-
-namespace modular {
-
-class StoryStorage;
-
-// Use the CrtAllocator and not the pool allocator so that merging doesn't
-// require deep copying.
-using CrtJsonDoc =
- rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator>;
-using CrtJsonValue = CrtJsonDoc::ValueType;
-using CrtJsonPointer = rapidjson::GenericPointer<CrtJsonValue>;
-
-// A Link is a mutable and observable value that is persistent across story
-// restarts, synchronized across devices, and can be shared between modules.
-//
-// When a module requests to run more modules using
-// ModuleContext::StartModule(), one or more Link instances are associated with
-// each such request (as specified in the Intent). Link instances can be shared
-// between multiple modules. The same Link instance can be used in multiple
-// StartModule() requests, so it can be shared between more than two modules.
-// Link instances have names that are local to each Module, and can be accessed
-// by calling ModuleContext.GetLink(name).
-//
-// If a watcher is registered through one handle using the Watch() method, it
-// only receives notifications for changes by requests through other handles.
-class LinkImpl : public Link {
- public:
- // The |link_path| contains the series of module names (where the last
- // element is the module that created this Link) that this Link is namespaced
- // under. If |create_link_info| is null, then this is a request to connect to
- // an existing link.
- LinkImpl(StoryStorage* story_storage, LinkPath link_path);
-
- ~LinkImpl() override;
-
- void Set(fidl::VectorPtr<std::string> path,
- fuchsia::mem::Buffer json) override;
- void Get(fidl::VectorPtr<std::string> path,
- GetCallback callback) override;
- void Erase(std::vector<std::string> path) override;
- void GetEntity(GetEntityCallback callback) override;
- void SetEntity(fidl::StringPtr entity_reference) override;
- void Watch(fidl::InterfaceHandle<LinkWatcher> watcher) override;
- void WatchAll(fidl::InterfaceHandle<LinkWatcher> watcher) override;
- void Sync(SyncCallback callback) override;
-
- // Used by StoryControllerImpl;
- const LinkPath& link_path() const { return link_path_; }
-
- private:
- // Called by |story_storage_|.
- void OnLinkValueChanged(const fidl::StringPtr& value, const void* context);
-
- // Convenience method which interacts with the story storage.
- void Set(fidl::VectorPtr<std::string> path, const std::string& json);
-
- fxl::WeakPtr<LinkImpl> GetWeakPtr();
-
- StoryStorage* const story_storage_;
- const LinkPath link_path_;
-
- // Bindings as a result from Watch() are stored in |normal_watchers_|, while
- // calls to WatchAll() are stored in |everything_watchers_|. They are separate
- // because Watch() bindings ignore any change notifications that originated
- // on this instance of LinkImpl.
- fidl::InterfacePtrSet<LinkWatcher> normal_watchers_;
- fidl::InterfacePtrSet<LinkWatcher> everything_watchers_;
-
- fxl::WeakPtrFactory<LinkImpl> weak_factory_;
- StoryStorage::LinkWatcherAutoCancel link_watcher_auto_cancel_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LinkImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_LINK_IMPL_H_
diff --git a/bin/sessionmgr/story_runner/link_impl_unittest.cc b/bin/sessionmgr/story_runner/link_impl_unittest.cc
deleted file mode 100644
index e23a838..0000000
--- a/bin/sessionmgr/story_runner/link_impl_unittest.cc
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/link_impl.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/entity/cpp/json.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/test_with_ledger.h"
-
-using fuchsia::modular::CreateLinkInfo;
-using fuchsia::modular::CreateLinkInfoPtr;
-using fuchsia::modular::Link;
-using fuchsia::modular::LinkPath;
-using fuchsia::modular::LinkPtr;
-using fuchsia::modular::LinkWatcher;
-using fuchsia::modular::LinkWatcherPtr;
-
-namespace modular {
-namespace {
-
-class TestLinkWatcher : public LinkWatcher {
- public:
- TestLinkWatcher(std::function<void(fidl::StringPtr)> fn) : fn_(fn) {}
-
- private:
- void Notify(fuchsia::mem::Buffer json) override {
- std::string json_string;
- FXL_CHECK(fsl::StringFromVmo(json, &json_string));
- fn_(json_string);
- }
-
- std::function<void(fidl::StringPtr)> fn_;
-};
-
-class LinkImplTest : public testing::TestWithLedger {
- public:
- std::unique_ptr<StoryStorage> MakeStorage(std::string ledger_page) {
- auto page_id = MakePageId(ledger_page);
- return std::make_unique<StoryStorage>(ledger_client(), page_id);
- }
-
- LinkPtr MakeLink(StoryStorage* const storage, std::string name) {
- LinkPath link_path;
- link_path.link_name = name;
-
- LinkPtr ptr;
- auto impl = std::make_unique<LinkImpl>(storage, std::move(link_path));
- links_.AddBinding(std::move(impl), ptr.NewRequest());
- return ptr;
- }
-
- void Watch(Link* link, std::function<void(fidl::StringPtr)> fn) {
- auto watcher = std::make_unique<TestLinkWatcher>(fn);
- LinkWatcherPtr ptr;
- watchers_.AddBinding(std::move(watcher), ptr.NewRequest());
- link->Watch(std::move(ptr));
- }
-
- void WatchAll(Link* link, std::function<void(fidl::StringPtr)> fn) {
- auto watcher = std::make_unique<TestLinkWatcher>(fn);
- LinkWatcherPtr ptr;
- watchers_.AddBinding(std::move(watcher), ptr.NewRequest());
- link->WatchAll(std::move(ptr));
- }
-
- void SetLink(Link* link, std::vector<std::string> path,
- const std::string& value) {
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(value, &vmo));
- link->Set(fidl::VectorPtr(std::move(path)), std::move(vmo).ToTransport());
- }
-
- fidl::BindingSet<Link, std::unique_ptr<LinkImpl>> links_;
- fidl::BindingSet<LinkWatcher, std::unique_ptr<TestLinkWatcher>> watchers_;
-};
-
-TEST_F(LinkImplTest, GetNull) {
- auto storage = MakeStorage("page");
- auto link = MakeLink(storage.get(), "foo");
-
- bool get_done{};
- link->Get(nullptr /* path */,
- [&](std::unique_ptr<fuchsia::mem::Buffer> value) {
- std::string content_string;
- FXL_CHECK(fsl::StringFromVmo(*value, &content_string));
- get_done = true;
- EXPECT_EQ("null", content_string);
- });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return get_done; }));
-
- get_done = false;
- fidl::VectorPtr<std::string> path;
- path->push_back("one");
- link->Get(std::move(path), [&](std::unique_ptr<fuchsia::mem::Buffer> value) {
- std::string content_string;
- FXL_CHECK(fsl::StringFromVmo(*value, &content_string));
- get_done = true;
- EXPECT_EQ("null", content_string);
- });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return get_done; }));
-}
-
-TEST_F(LinkImplTest, WatchDefaultBehavior) {
- // When we ask to watch a link, we should be notified immediately (on the
- // next iteration of the event loop) of its current value.
- auto storage = MakeStorage("page");
- auto link = MakeLink(storage.get(), "mylink");
-
- int notified_count{0};
- Watch(link.get(), [&](const fidl::StringPtr& value) {
- ++notified_count;
- EXPECT_EQ("null", value);
- });
- // We are only notified after the event loop runs.
- EXPECT_EQ(0, notified_count);
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return notified_count == 1; }));
-
- // Same for WatchAll.
- WatchAll(link.get(), [&](const fidl::StringPtr& value) {
- ++notified_count;
- EXPECT_EQ("null", value);
- });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return notified_count == 2; }));
-}
-
-TEST_F(LinkImplTest, SetAndWatch) {
- auto storage = MakeStorage("page");
- auto link = MakeLink(storage.get(), "mylink");
-
- // Watch for our own changes, which we shouldn't see. The initial value
- // ("null"), is sent immediately, though.
- Watch(link.get(),
- [&](const fidl::StringPtr& value) { EXPECT_EQ("null", value); });
-
- // Also use WatchAll(), on which we should see our own changes.
- fidl::StringPtr notified_value;
- int notified_count{0};
- WatchAll(link.get(), [&](const fidl::StringPtr& value) {
- notified_value = value;
- ++notified_count;
- });
-
- SetLink(link.get(), {}, "42");
-
- bool synced{};
- link->Sync([&synced] { synced = true; });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&synced] { return synced; }));
-
- EXPECT_EQ(2, notified_count);
- EXPECT_EQ("42", notified_value);
-}
-
-TEST_F(LinkImplTest, SetAndWatchAndGet) {
- auto storage = MakeStorage("page");
- auto link = MakeLink(storage.get(), "mylink");
-
- fidl::StringPtr notified_value;
- int notified_count{0};
- WatchAll(link.get(), [&](const fidl::StringPtr& value) {
- notified_value = value;
- ++notified_count;
- });
-
- SetLink(link.get(), {}, R"({
- "one": 1,
- "two": 2
- })");
- fidl::VectorPtr<std::string> path;
- path->push_back("two");
- SetLink(link.get(), std::move(path), R"("two")");
-
- path->clear();
- path->push_back("three");
- SetLink(link.get(), std::move(path), R"(3)");
-
- bool synced{};
- link->Sync([&synced] { synced = true; });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return synced; }));
-
- const std::string expected_value = R"({"one":1,"two":"two","three":3})";
- EXPECT_EQ(4, notified_count); // initial, 3x Set
- EXPECT_EQ(expected_value, notified_value);
-
- bool get_done{};
- link->Get(nullptr /* path */,
- [&](std::unique_ptr<fuchsia::mem::Buffer> value) {
- std::string content_string;
- FXL_CHECK(fsl::StringFromVmo(*value, &content_string));
- get_done = true;
- EXPECT_EQ(expected_value, content_string);
- });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return get_done; }));
-}
-
-TEST_F(LinkImplTest, SetNonJsonAndGetJsonPointer) {
- auto storage = MakeStorage("page");
- auto link = MakeLink(storage.get(), "mylink");
-
- SetLink(link.get(), {}, R"({
- "one": 1,
- "two": 2invalidjson
- })");
-
- bool synced{};
- link->Sync([&synced] { synced = true; });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return synced; }));
-
- fidl::VectorPtr<std::string> path;
- path->push_back("one");
- bool get_done{};
- link->Get(std::move(path), [&](std::unique_ptr<fuchsia::mem::Buffer> value) {
- std::string content_string;
- FXL_CHECK(fsl::StringFromVmo(*value, &content_string));
- get_done = true;
- EXPECT_EQ("null", content_string);
- });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return get_done; }));
-}
-
-TEST_F(LinkImplTest, Erase) {
- auto storage = MakeStorage("page");
- auto link = MakeLink(storage.get(), "mylink");
-
- SetLink(link.get(), {}, R"({
- "one": 1,
- "two": 2
- })");
- std::vector<std::string> path;
- path.push_back("two");
- link->Erase(std::move(path));
-
- const std::string expected_value = R"({"one":1})";
- bool get_done{};
- link->Get(nullptr /* path */,
- [&](std::unique_ptr<fuchsia::mem::Buffer> value) {
- std::string content_string;
- FXL_CHECK(fsl::StringFromVmo(*value, &content_string));
- get_done = true;
- EXPECT_EQ(expected_value, content_string);
- });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return get_done; }));
-}
-
-TEST_F(LinkImplTest, SetAndGetEntity) {
- auto storage = MakeStorage("page");
- auto link = MakeLink(storage.get(), "mylink");
-
- link->SetEntity("ref");
- bool done{};
- link->GetEntity([&](const fidl::StringPtr value) {
- EXPECT_EQ("ref", value);
- done = true;
- });
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return done; }));
-}
-
-TEST_F(LinkImplTest, MultipleConnections) {
- // Create two storage instances, where each one gets its own connection to
- // the Ledger. Then, create a LinkImpl on top of each, and test end-to-end.
- auto storage1 = MakeStorage("page");
- auto link1 = MakeLink(storage1.get(), "mylink");
-
- auto storage2 = MakeStorage("page");
- auto link2 = MakeLink(storage2.get(), "mylink");
-
- int notified_count{0};
- fidl::StringPtr last_value;
- WatchAll(link1.get(), [&](const fidl::StringPtr& value) {
- ++notified_count;
- last_value = value;
- });
-
- // Set two values on |link2|. On |link1|, we are guaranteed to get a
- // notification about the second value, eventually.
- SetLink(link2.get(), {}, "3");
- SetLink(link2.get(), {}, "4");
- EXPECT_TRUE(RunLoopWithTimeoutOrUntil([&] { return last_value == "4"; }));
- // There is always an initial notification of the current state, so we
- // will have been notified either 2 or 3 times: 2 if we only got a
- // notification about the set to "4", and 3 if we got both the set to "3" and
- // "4".
- EXPECT_TRUE(notified_count == 2 || notified_count == 3) << notified_count;
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/meta/dev_story_shell.cmx b/bin/sessionmgr/story_runner/meta/dev_story_shell.cmx
deleted file mode 100644
index 04707e9..0000000
--- a/bin/sessionmgr/story_runner/meta/dev_story_shell.cmx
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager"
- ]
- }
-}
diff --git a/bin/sessionmgr/story_runner/meta/link_impl_unittest.cmx b/bin/sessionmgr/story_runner/meta/link_impl_unittest.cmx
deleted file mode 100644
index e20c62c..0000000
--- a/bin/sessionmgr/story_runner/meta/link_impl_unittest.cmx
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "program": {
- "binary": "test/link_impl_unittest"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher"
- ]
- }
-}
diff --git a/bin/sessionmgr/story_runner/meta/story_controller_impl_unittest.cmx b/bin/sessionmgr/story_runner/meta/story_controller_impl_unittest.cmx
deleted file mode 100644
index 37abc5e..0000000
--- a/bin/sessionmgr/story_runner/meta/story_controller_impl_unittest.cmx
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "program": {
- "binary": "test/story_controller_impl_unittest"
- },
- "sandbox": {
- "services": []
- }
-}
diff --git a/bin/sessionmgr/story_runner/module_context_impl.cc b/bin/sessionmgr/story_runner/module_context_impl.cc
deleted file mode 100644
index ff78b8d..0000000
--- a/bin/sessionmgr/story_runner/module_context_impl.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/module_context_impl.h"
-
-#include <string>
-
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/strings/join_strings.h>
-
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/bin/sessionmgr/story/systems/story_visibility_system.h"
-#include "peridot/bin/sessionmgr/story_runner/story_controller_impl.h"
-#include "peridot/lib/fidl/clone.h"
-
-namespace modular {
-
-ModuleContextImpl::ModuleContextImpl(
- const ModuleContextInfo& info,
- const fuchsia::modular::ModuleData* const module_data,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- service_provider_request)
- : module_data_(module_data),
- story_controller_impl_(info.story_controller_impl),
- story_visibility_system_(info.story_visibility_system),
- component_context_impl_(info.component_context_info,
- EncodeModuleComponentNamespace(
- info.story_controller_impl->GetStoryId()),
- EncodeModulePath(module_data_->module_path),
- module_data_->module_url),
- user_intelligence_provider_(info.user_intelligence_provider) {
- service_provider_impl_.AddService<fuchsia::modular::ComponentContext>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request) {
- component_context_impl_.Connect(std::move(request));
- });
- service_provider_impl_.AddService<fuchsia::modular::ModuleContext>(
- [this](fidl::InterfaceRequest<fuchsia::modular::ModuleContext> request) {
- bindings_.AddBinding(this, std::move(request));
- });
- service_provider_impl_.AddService<fuchsia::modular::IntelligenceServices>(
- [this](fidl::InterfaceRequest<fuchsia::modular::IntelligenceServices>
- request) {
- auto module_scope = fuchsia::modular::ModuleScope::New();
- module_scope->module_path = module_data_->module_path;
- module_scope->url = module_data_->module_url;
- module_scope->story_id = story_controller_impl_->GetStoryId();
-
- auto scope = fuchsia::modular::ComponentScope::New();
- scope->set_module_scope(std::move(*module_scope));
- user_intelligence_provider_->GetComponentIntelligenceServices(
- std::move(*scope), std::move(request));
- });
- service_provider_impl_.AddBinding(std::move(service_provider_request));
-}
-
-ModuleContextImpl::~ModuleContextImpl() {}
-
-void ModuleContextImpl::GetLink(
- fidl::StringPtr name,
- fidl::InterfaceRequest<fuchsia::modular::Link> request) {
- fuchsia::modular::LinkPathPtr link_path;
- // See if there's a parameter mapping for this link.
- link_path = story_controller_impl_->GetLinkPathForParameterName(
- module_data_->module_path, name);
- story_controller_impl_->ConnectLinkPath(std::move(link_path),
- std::move(request));
-}
-
-void ModuleContextImpl::EmbedModule(
- std::string name, fuchsia::modular::Intent intent,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> view_owner,
- EmbedModuleCallback callback) {
- AddModParams params;
- params.parent_mod_path = module_data_->module_path;
- params.mod_name = name;
- params.intent = std::move(intent);
- params.module_source = fuchsia::modular::ModuleSource::INTERNAL;
- params.surface_relation = nullptr;
- params.is_embedded = true;
- story_controller_impl_->EmbedModule(std::move(params),
- std::move(module_controller),
- std::move(view_owner), callback);
-}
-
-void ModuleContextImpl::AddModuleToStory(
- std::string name, fuchsia::modular::Intent intent,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller,
- fuchsia::modular::SurfaceRelationPtr surface_relation,
- AddModuleToStoryCallback callback) {
- AddModParams params;
- params.parent_mod_path = module_data_->module_path;
- params.mod_name = name;
- params.intent = std::move(intent);
- params.module_source = fuchsia::modular::ModuleSource::INTERNAL;
- params.surface_relation = std::move(surface_relation);
- params.is_embedded = false;
- story_controller_impl_->AddModuleToStory(
- std::move(params), std::move(module_controller), callback);
-}
-
-void ModuleContextImpl::StartContainerInShell(
- std::string name, fuchsia::modular::SurfaceRelation parent_relation,
- std::vector<fuchsia::modular::ContainerLayout> layout,
- std::vector<fuchsia::modular::ContainerRelationEntry> relationships,
- std::vector<fuchsia::modular::ContainerNode> nodes) {
- FXL_LOG(ERROR) << "ModuleContext.StartContainerInShell() not implemented.";
-}
-
-void ModuleContextImpl::GetComponentContext(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext>
- context_request) {
- component_context_impl_.Connect(std::move(context_request));
-}
-
-void ModuleContextImpl::GetStoryId(GetStoryIdCallback callback) {
- callback(story_controller_impl_->GetStoryId());
-}
-
-void ModuleContextImpl::RequestFocus() {
- story_controller_impl_->FocusModule(module_data_->module_path);
- story_controller_impl_->RequestStoryFocus();
-}
-
-void ModuleContextImpl::Active() {}
-
-void ModuleContextImpl::RemoveSelfFromStory() {
- story_controller_impl_->RemoveModuleFromStory(module_data_->module_path);
-}
-
-void ModuleContextImpl::RequestStoryVisibilityState(
- fuchsia::modular::StoryVisibilityState visibility_state) {
- story_visibility_system_->RequestStoryVisibilityStateChange(visibility_state);
-}
-
-void ModuleContextImpl::StartOngoingActivity(
- fuchsia::modular::OngoingActivityType ongoing_activity_type,
- fidl::InterfaceRequest<fuchsia::modular::OngoingActivity> request) {
- story_controller_impl_->StartOngoingActivity(ongoing_activity_type,
- std::move(request));
-}
-
-void ModuleContextImpl::CreateEntity(
- std::string type, fuchsia::mem::Buffer data,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request,
- CreateEntityCallback callback) {
- story_controller_impl_->CreateEntity(
- type, std::move(data), std::move(entity_request), std::move(callback));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/module_context_impl.h b/bin/sessionmgr/story_runner/module_context_impl.h
deleted file mode 100644
index 35cb4ca..0000000
--- a/bin/sessionmgr/story_runner/module_context_impl.h
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_MODULE_CONTEXT_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_MODULE_CONTEXT_IMPL_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/component_context_impl.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h"
-
-namespace modular {
-
-class StoryControllerImpl;
-class StoryVisibilitySystem;
-
-// The dependencies of ModuleContextImpl common to all instances.
-struct ModuleContextInfo {
- const ComponentContextInfo component_context_info;
- StoryControllerImpl* const story_controller_impl;
- StoryVisibilitySystem* const story_visibility_system;
- fuchsia::modular::UserIntelligenceProvider* const user_intelligence_provider;
-};
-
-// ModuleContextImpl keeps a single connection from a module instance in
-// the story to a StoryControllerImpl. This way, requests that the module makes
-// on its Story handle can be associated with the Module instance.
-class ModuleContextImpl : fuchsia::modular::ModuleContext {
- public:
- // |module_data| identifies this particular module instance using the path of
- // modules that have ended up starting this module in the module_path
- // property. The last item in this list is this module's name. |module_path|
- // can be used to internally name resources that belong to this module
- // (message queues, Links).
- ModuleContextImpl(const ModuleContextInfo& info,
- const fuchsia::modular::ModuleData* module_data,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- service_provider_request);
-
- ~ModuleContextImpl() override;
-
- private:
- // |fuchsia::modular::ModuleContext|
- void GetLink(fidl::StringPtr name,
- fidl::InterfaceRequest<fuchsia::modular::Link> request) override;
-
- // |fuchsia::modular::ModuleContext|
- void EmbedModule(
- std::string name, fuchsia::modular::Intent intent,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> view_owner,
- EmbedModuleCallback callback) override;
-
- // |fuchsia::modular::ModuleContext|
- void AddModuleToStory(
- std::string name, fuchsia::modular::Intent intent,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller,
- fuchsia::modular::SurfaceRelationPtr surface_relation,
- AddModuleToStoryCallback callback) override;
-
- // |fuchsia::modular::ModuleContext|
- void StartContainerInShell(
- std::string name, fuchsia::modular::SurfaceRelation parent_relation,
- std::vector<fuchsia::modular::ContainerLayout> layout,
- std::vector<fuchsia::modular::ContainerRelationEntry> relationships,
- std::vector<fuchsia::modular::ContainerNode> nodes) override;
-
- // |fuchsia::modular::ModuleContext|
- void GetComponentContext(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext>
- context_request) override;
-
- // |fuchsia::modular::ModuleContext|
- void GetStoryId(GetStoryIdCallback callback) override;
-
- // |fuchsia::modular::ModuleContext|
- void RequestFocus() override;
-
- // |fuchsia::modular::ModuleContext|
- void Active() override;
-
- // |fuchsia::modular::ModuleContext|
- void RemoveSelfFromStory() override;
-
- // |fuchsia::modular::ModuleContext|
- void RequestStoryVisibilityState(
- fuchsia::modular::StoryVisibilityState visibility_state) override;
-
- // |fuchsia::modular::ModuleContext|
- void StartOngoingActivity(
- fuchsia::modular::OngoingActivityType ongoing_activity_type,
- fidl::InterfaceRequest<fuchsia::modular::OngoingActivity> request)
- override;
-
- // |fuchsia::modular::ModuleContext|
- void CreateEntity(
- std::string type, fuchsia::mem::Buffer data,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request,
- CreateEntityCallback callback) override;
-
- // Identifies the module by its path, holds the URL of the running module, and
- // the link it was started with.
- const fuchsia::modular::ModuleData* const module_data_;
-
- // Not owned. The StoryControllerImpl for the Story in which this Module
- // lives.
- StoryControllerImpl* const story_controller_impl_;
-
- StoryVisibilitySystem* const story_visibility_system_; // Not owned.
-
- ComponentContextImpl component_context_impl_;
-
- fuchsia::modular::UserIntelligenceProvider* const
- user_intelligence_provider_; // Not owned
-
- fidl::BindingSet<fuchsia::modular::ModuleContext> bindings_;
-
- // A service provider that represents the services to be added into an
- // application's namespace.
- component::ServiceProviderImpl service_provider_impl_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ModuleContextImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_MODULE_CONTEXT_IMPL_H_
diff --git a/bin/sessionmgr/story_runner/module_controller_impl.cc b/bin/sessionmgr/story_runner/module_controller_impl.cc
deleted file mode 100644
index 97efddd..0000000
--- a/bin/sessionmgr/story_runner/module_controller_impl.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/module_controller_impl.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/time/time_delta.h>
-
-#include "peridot/bin/sessionmgr/story_runner/story_controller_impl.h"
-#include "peridot/lib/common/teardown.h"
-#include "peridot/lib/fidl/clone.h"
-
-namespace modular {
-
-constexpr char kAppStoragePath[] = "/data/APP_DATA";
-
-namespace {
-
-// A stopgap solution to map a module's url to a directory name where the
-// module's /data is mapped. We need three properties here - (1) two module urls
-// that are the same get mapped to the same hash, (2) two modules urls that are
-// different don't get the same name (with very high probability) and (3) the
-// name is visually inspectable.
-std::string HashModuleUrl(const std::string& module_url) {
- std::size_t found = module_url.find_last_of('/');
- auto last_part =
- found == module_url.length() - 1 ? "" : module_url.substr(found + 1);
- return std::to_string(std::hash<std::string>{}(module_url)) + last_part;
-}
-
-}; // namespace
-
-ModuleControllerImpl::ModuleControllerImpl(
- StoryControllerImpl* const story_controller_impl,
- fuchsia::sys::Launcher* const launcher,
- fuchsia::modular::AppConfig module_config,
- const fuchsia::modular::ModuleData* const module_data,
- fuchsia::sys::ServiceListPtr service_list,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- view_provider_request)
- : story_controller_impl_(story_controller_impl),
- app_client_(
- launcher, CloneStruct(module_config),
- std::string(kAppStoragePath) + HashModuleUrl(module_config.url),
- std::move(service_list)),
- module_data_(module_data) {
- app_client_.SetAppErrorHandler([this] { OnAppConnectionError(); });
- app_client_.services().ConnectToService(std::move(view_provider_request));
-}
-
-ModuleControllerImpl::~ModuleControllerImpl() {}
-
-void ModuleControllerImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::ModuleController> request) {
- module_controller_bindings_.AddBinding(this, std::move(request));
- // Notify of initial state on connection.
- NotifyStateChange();
-}
-
-// If the ComponentController connection closes, it means the module cannot be
-// started. We indicate this by the ERROR state.
-void ModuleControllerImpl::OnAppConnectionError() {
- SetState(fuchsia::modular::ModuleState::ERROR);
-}
-
-void ModuleControllerImpl::SetState(
- const fuchsia::modular::ModuleState new_state) {
- if (state_ == new_state) {
- return;
- }
-
- state_ = new_state;
- NotifyStateChange();
-}
-
-void ModuleControllerImpl::Teardown(std::function<void()> done) {
- teardown_done_callbacks_.push_back(done);
-
- if (teardown_done_callbacks_.size() != 1) {
- // Not the first request, Stop() in progress.
- return;
- }
-
- auto cont = [this] {
- SetState(fuchsia::modular::ModuleState::STOPPED);
-
- // We take ownership of *this from |story_controller_impl_| so that
- // teardown happens in StoryControllerImpl but *this is still alive when we
- // call |teardown_done_callbacks_|. One or more of the callbacks may be a
- // result callback for fuchsia::modular::ModuleController::Stop() and since
- // *this owns the fidl::Binding for the channel on which the result message
- // will be sent, it must be alive when the message is posted.
- // TODO(thatguy,mesch): This point is reachable from two distinct
- // code-paths: originating from ModuleControllerImpl::Stop() or
- // StoryControllerImpl::Stop(). It is not clear whether ReleaseModule()
- // must be called *before* these done callbacks are called, or whether we
- // can move this call below the loop and have ReleaseModule also delete
- // *this.
- story_controller_impl_->ReleaseModule(this);
-
- for (auto& done : teardown_done_callbacks_) {
- done();
- }
-
- // |this| must be deleted after the callbacks so that the |done()| calls
- // above can be dispatched while the bindings still exist in case they are
- // FIDL method callbacks.
- //
- // The destructor of |this| deletes |app_client_|, which will kill the
- // related application if it's still running.
- delete this;
- };
-
- // At this point, it's no longer an error if the module closes its
- // connection, or the application exits.
- app_client_.SetAppErrorHandler(nullptr);
-
- // Tear down the module application through the normal procedure with timeout.
- app_client_.Teardown(kBasicTimeout, cont);
-}
-
-void ModuleControllerImpl::Focus() {
- story_controller_impl_->FocusModule(module_data_->module_path);
-}
-
-void ModuleControllerImpl::Defocus() {
- story_controller_impl_->DefocusModule(module_data_->module_path);
-}
-
-void ModuleControllerImpl::Stop(StopCallback done) {
- story_controller_impl_->StopModule(module_data_->module_path, done);
-}
-
-void ModuleControllerImpl::NotifyStateChange() {
- for (auto& binding : module_controller_bindings_.bindings()) {
- binding->events().OnStateChange(state_);
- }
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/module_controller_impl.h b/bin/sessionmgr/story_runner/module_controller_impl.h
deleted file mode 100644
index 62a2333..0000000
--- a/bin/sessionmgr/story_runner/module_controller_impl.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_MODULE_CONTROLLER_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_MODULE_CONTROLLER_IMPL_H_
-
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/fidl/app_client.h"
-
-namespace modular {
-
-class StoryControllerImpl;
-
-// Implements the fuchsia::modular::ModuleController interface, which is given
-// to the client that called
-// fuchsia::modular::ModuleContext.(Start|Embed)Module(). Exactly one
-// ModuleControllerImpl instance is associated with each
-// ModuleContextImpl instance.
-class ModuleControllerImpl : fuchsia::modular::ModuleController {
- public:
- ModuleControllerImpl(
- StoryControllerImpl* story_controller_impl,
- fuchsia::sys::Launcher* launcher,
- fuchsia::modular::AppConfig module_config,
- const fuchsia::modular::ModuleData* module_data,
- fuchsia::sys::ServiceListPtr service_list,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- view_provider_request);
-
- ~ModuleControllerImpl() override;
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::ModuleController> request);
-
- // Notifies of a state change of the module.
- void SetState(fuchsia::modular::ModuleState new_state);
-
- // Calls Teardown() on the AppClient of the module component instance,
- // notifies state change, then ReleaseModule()s the connection and finally
- // calls |done|.
- //
- // Multiple calls to Teardown() are allowed, and all |done| callbacks are run
- // in order when teardown is complete.
- void Teardown(std::function<void()> done);
-
- component::Services& services() { return app_client_.services(); }
-
- private:
- // |fuchsia::modular::ModuleController|
- void Focus() override;
-
- // |fuchsia::modular::ModuleController|
- void Defocus() override;
-
- // |fuchsia::modular::ModuleController|
- void Stop(StopCallback done) override;
-
- // Call to dispatch |ModuleController|'s OnStateChange event.
- void NotifyStateChange();
-
- // Used as application error handler on the Module app client.
- void OnAppConnectionError();
-
- // The story this Module instance runs in.
- StoryControllerImpl* const story_controller_impl_;
-
- AppClient<fuchsia::modular::Lifecycle> app_client_;
-
- // The Module path and other information about the module instance.
- const fuchsia::modular::ModuleData* const module_data_;
-
- // The service provided here.
- fidl::BindingSet<fuchsia::modular::ModuleController>
- module_controller_bindings_;
-
- // The state of this Module instance. Stored here to notify through events
- // when it changes.
- fuchsia::modular::ModuleState state_{fuchsia::modular::ModuleState::RUNNING};
-
- // Callbacks passed to Teardown() calls. If there is one Stop() request
- // pending, a second one is only queued, no second call to Stop() is made.
- std::vector<std::function<void()>> teardown_done_callbacks_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ModuleControllerImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_MODULE_CONTROLLER_IMPL_H_
diff --git a/bin/sessionmgr/story_runner/ongoing_activity_impl.cc b/bin/sessionmgr/story_runner/ongoing_activity_impl.cc
deleted file mode 100644
index 917b43e..0000000
--- a/bin/sessionmgr/story_runner/ongoing_activity_impl.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/ongoing_activity_impl.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace modular {
-
-using fuchsia::modular::OngoingActivityType;
-
-OngoingActivityImpl::OngoingActivityImpl(
- OngoingActivityType ongoing_activity_type, fit::closure on_destroy)
- : ongoing_activity_type_(ongoing_activity_type),
- on_destroy_(std::move(on_destroy)) {}
-
-OngoingActivityImpl::~OngoingActivityImpl() { on_destroy_(); }
-
-OngoingActivityType OngoingActivityImpl::GetType() {
- return ongoing_activity_type_;
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/ongoing_activity_impl.h b/bin/sessionmgr/story_runner/ongoing_activity_impl.h
deleted file mode 100644
index 298a009..0000000
--- a/bin/sessionmgr/story_runner/ongoing_activity_impl.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_ONGOING_ACTIVITY_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_ONGOING_ACTIVITY_IMPL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-class OngoingActivityImpl : public fuchsia::modular::OngoingActivity {
- public:
- OngoingActivityImpl(
- fuchsia::modular::OngoingActivityType ongoing_activity_type,
- fit::closure on_destroy);
-
- ~OngoingActivityImpl() override;
-
- fuchsia::modular::OngoingActivityType GetType();
-
- private:
- const fuchsia::modular::OngoingActivityType ongoing_activity_type_;
- fit::closure on_destroy_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(OngoingActivityImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_ONGOING_ACTIVITY_IMPL_H_
diff --git a/bin/sessionmgr/story_runner/story_controller_impl.cc b/bin/sessionmgr/story_runner/story_controller_impl.cc
deleted file mode 100644
index 3adaa11..0000000
--- a/bin/sessionmgr/story_runner/story_controller_impl.cc
+++ /dev/null
@@ -1,1581 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/story_controller_impl.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <fuchsia/modular/storymodel/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/entity/cpp/json.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/join_strings.h>
-#include <lib/fxl/strings/split_string.h>
-#include <lib/fxl/type_converter.h>
-
-#include "peridot/bin/basemgr/cobalt/cobalt.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.h"
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h"
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-#include "peridot/bin/sessionmgr/story/model/story_observer.h"
-#include "peridot/bin/sessionmgr/story_runner/link_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/module_context_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/module_controller_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/ongoing_activity_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/story_provider_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/story_shell_context_impl.h"
-#include "peridot/lib/common/names.h"
-#include "peridot/lib/common/teardown.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/ledger_client/operations.h"
-#include "peridot/lib/util/string_escape.h"
-
-// Used to create std::set<LinkPath>.
-namespace std {
-template <>
-struct less<fuchsia::modular::LinkPath> {
- bool operator()(const fuchsia::modular::LinkPath& left,
- const fuchsia::modular::LinkPath& right) const {
- if (left.module_path == right.module_path) {
- return left.link_name < right.link_name;
- }
- return left.module_path < right.module_path;
- }
-};
-} // namespace std
-
-namespace modular {
-
-constexpr char kStoryEnvironmentLabelPrefix[] = "story-";
-constexpr auto kUpdateSnapshotTimeout = zx::sec(1);
-
-namespace {
-
-constexpr char kSurfaceIDSeparator[] = ":";
-fidl::StringPtr ModulePathToSurfaceID(
- const std::vector<std::string>& module_path) {
- std::vector<std::string> path;
- // Sanitize all the |module_name|s that make up this |module_path|.
- for (const auto& module_name : module_path) {
- path.push_back(StringEscape(module_name, kSurfaceIDSeparator));
- }
- return fxl::JoinStrings(path, kSurfaceIDSeparator);
-}
-
-std::vector<std::string> ModulePathFromSurfaceID(
- const std::string& surface_id) {
- std::vector<std::string> path;
- for (const auto& parts : SplitEscapedString(fxl::StringView(surface_id),
- kSurfaceIDSeparator[0])) {
- path.push_back(parts.ToString());
- }
- return path;
-}
-
-std::vector<std::string> ParentModulePath(
- const std::vector<std::string>& module_path) {
- std::vector<std::string> ret;
-
- if (module_path.size() > 0) {
- for (size_t i = 0; i < module_path.size() - 1; i++) {
- ret.push_back(module_path.at(i));
- }
- }
- return ret;
-}
-
-} // namespace
-
-bool ShouldRestartModuleForNewIntent(
- const fuchsia::modular::Intent& old_intent,
- const fuchsia::modular::Intent& new_intent) {
- if (old_intent.handler != new_intent.handler) {
- return true;
- }
-
- return false;
-}
-
-// Launches (brings up a running instance) of a module.
-//
-// If the module is to be composed into the story shell, notifies the story
-// shell of the new module. If the module is composed internally, connects the
-// view owner request appropriately.
-class StoryControllerImpl::LaunchModuleCall : public Operation<> {
- public:
- LaunchModuleCall(StoryControllerImpl* const story_controller_impl,
- fuchsia::modular::ModuleData module_data,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- ResultCall result_call)
- : Operation("StoryControllerImpl::LaunchModuleCall",
- std::move(result_call)),
- story_controller_impl_(story_controller_impl),
- module_data_(std::move(module_data)),
- module_controller_request_(std::move(module_controller_request)),
- view_owner_request_(std::move(view_owner_request)),
- start_time_(zx_clock_get(ZX_CLOCK_UTC)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- RunningModInfo* const running_mod_info =
- story_controller_impl_->FindRunningModInfo(module_data_.module_path);
-
- // We launch the new module if it doesn't run yet.
- if (!running_mod_info) {
- Launch(flow);
- return;
- }
-
- // If the new module is already running, but with a different Intent, we
- // tear it down then launch a new instance.
- if (ShouldRestartModuleForNewIntent(*running_mod_info->module_data->intent,
- *module_data_.intent)) {
- running_mod_info->module_controller_impl->Teardown([this, flow] {
- // NOTE(mesch): |running_mod_info| is invalid at this point.
- Launch(flow);
- });
- return;
- }
-
- // Otherwise, the module is already running. Connect
- // |module_controller_request_| to the existing instance of
- // fuchsia::modular::ModuleController.
- if (module_controller_request_.is_valid()) {
- running_mod_info->module_controller_impl->Connect(
- std::move(module_controller_request_));
- }
-
- // Since the module is already running send it the new intent.
- NotifyModuleOfIntent(*running_mod_info);
- }
-
- void Launch(FlowToken /*flow*/) {
- FXL_LOG(INFO) << "StoryControllerImpl::LaunchModule() "
- << module_data_.module_url << " "
- << ModulePathToSurfaceID(module_data_.module_path);
- fuchsia::modular::AppConfig module_config;
- module_config.url = module_data_.module_url;
-
- fuchsia::ui::viewsv1::ViewProviderPtr view_provider;
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- view_provider_request = view_provider.NewRequest();
- view_provider->CreateView(std::move(view_owner_request_), nullptr);
-
- fuchsia::sys::ServiceProviderPtr module_context_provider;
- auto module_context_provider_request = module_context_provider.NewRequest();
- auto service_list = fuchsia::sys::ServiceList::New();
- service_list->names.push_back(fuchsia::modular::ComponentContext::Name_);
- service_list->names.push_back(fuchsia::modular::ModuleContext::Name_);
- service_list->names.push_back(
- fuchsia::modular::IntelligenceServices::Name_);
- service_list->provider = std::move(module_context_provider);
-
- RunningModInfo running_mod_info;
- running_mod_info.module_data = CloneOptional(module_data_);
-
- // ModuleControllerImpl's constructor launches the child application.
- running_mod_info.module_controller_impl =
- std::make_unique<ModuleControllerImpl>(
- story_controller_impl_,
- story_controller_impl_->story_environment_->GetLauncher(),
- std::move(module_config), running_mod_info.module_data.get(),
- std::move(service_list), std::move(view_provider_request));
-
- // Modules added/started through PuppetMaster don't have a module
- // controller request.
- if (module_controller_request_.is_valid()) {
- running_mod_info.module_controller_impl->Connect(
- std::move(module_controller_request_));
- }
-
- ModuleContextInfo module_context_info = {
- story_controller_impl_->story_provider_impl_->component_context_info(),
- story_controller_impl_,
- story_controller_impl_->story_visibility_system_,
- story_controller_impl_->story_provider_impl_
- ->user_intelligence_provider()};
-
- running_mod_info.module_context_impl = std::make_unique<ModuleContextImpl>(
- module_context_info, running_mod_info.module_data.get(),
- std::move(module_context_provider_request));
-
- NotifyModuleOfIntent(running_mod_info);
-
- story_controller_impl_->running_mod_infos_.emplace_back(
- std::move(running_mod_info));
-
- for (auto& i : story_controller_impl_->watchers_.ptrs()) {
- fuchsia::modular::ModuleData module_data;
- module_data_.Clone(&module_data);
- (*i)->OnModuleAdded(std::move(module_data));
- }
-
- ReportModuleLaunchTime(
- module_data_.module_url,
- zx::duration(zx_clock_get(ZX_CLOCK_UTC) - start_time_));
- }
-
- // Connects to the module's intent handler and sends it the intent from
- // |module_data_.intent|.
- void NotifyModuleOfIntent(const RunningModInfo& running_mod_info) {
- if (!module_data_.intent) {
- return;
- }
- fuchsia::modular::IntentHandlerPtr intent_handler;
- running_mod_info.module_controller_impl->services().ConnectToService(
- intent_handler.NewRequest());
- fuchsia::modular::Intent intent;
- module_data_.intent->Clone(&intent);
-
- intent_handler->HandleIntent(std::move(intent));
- }
-
- StoryControllerImpl* const story_controller_impl_; // not owned
- fuchsia::modular::ModuleData module_data_;
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request_;
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request_;
- const zx_time_t start_time_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LaunchModuleCall);
-};
-
-// KillModuleCall tears down the module by the given module_data. It is enqueued
-// when ledger confirms that the module was stopped, see OnModuleDataUpdated().
-class StoryControllerImpl::KillModuleCall : public Operation<> {
- public:
- KillModuleCall(StoryControllerImpl* const story_controller_impl,
- fuchsia::modular::ModuleData module_data,
- const std::function<void()>& done)
- : Operation("StoryControllerImpl::KillModuleCall", [] {}),
- story_controller_impl_(story_controller_impl),
- module_data_(std::move(module_data)),
- done_(done) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- // If the module is external, we also notify story shell about it going
- // away. An internal module is stopped by its parent module, and it's up to
- // the parent module to defocus it first. TODO(mesch): Why not always
- // defocus?
- auto future =
- Future<>::Create("StoryControllerImpl.KillModuleCall.Run.future");
- if (story_controller_impl_->story_shell_ &&
- module_data_.module_source ==
- fuchsia::modular::ModuleSource::EXTERNAL) {
- story_controller_impl_->story_shell_->DefocusSurface(
- ModulePathToSurfaceID(module_data_.module_path), future->Completer());
- } else {
- future->Complete();
- }
-
- future->Then([this, flow] {
- // Teardown the module, which discards the module controller. Since
- // multiple KillModuleCall operations can be queued by module data
- // updates, we must check whether the module has already been killed.
- auto* const running_mod_info =
- story_controller_impl_->FindRunningModInfo(module_data_.module_path);
- if (!running_mod_info) {
- FXL_LOG(INFO) << "No ModuleController for Module '"
- << ModulePathToSurfaceID(module_data_.module_path)
- << "'. Was ModuleController.Stop() called twice?";
- InvokeDone();
- return;
- }
-
- // The result callback |done_| must be invoked BEFORE the Teardown()
- // callback returns, just in case it is, or it invokes, a callback of a
- // FIDL method on ModuleController (happens in the case that this
- // Operation instance executes a ModuleController.Stop() FIDL method
- // invocation).
- //
- // After the Teardown() callback returns, the ModuleControllerImpl is
- // deleted, and any FIDL connections that have invoked methods on it are
- // closed.
- //
- // Be aware that done_ is NOT the Done() callback of the Operation.
- running_mod_info->module_controller_impl->Teardown(
- [this, flow] { InvokeDone(); });
- });
- }
-
- void InvokeDone() {
- // Whatever the done_ callback captures (specifically, a flow token) must be
- // released after the done_ callback has returned. Otherwise, the calling
- // operation will not call Done() and does not get deleted until this
- // Operation instance gets deleted. This is probably fine, but it's
- // different from calling operations without flow tokens, which call their
- // own Done() directly.
- //
- // Notice the StopCall doesn't use a flow token, but just calls Done()
- // directly from within done_, but the OnModuleDataUpadatedCall has a flow
- // token.
-
- // We must guard against the possibility that done_() causes this to be
- // deleted (happens when called from StopCall).
- auto weak_this = GetWeakPtr();
-
- done_();
-
- if (weak_this) {
- done_ = nullptr;
- }
- }
-
- StoryControllerImpl* const story_controller_impl_; // not owned
- fuchsia::modular::ModuleData module_data_;
- std::function<void()> done_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(KillModuleCall);
-};
-
-// Calls LaunchModuleCall to get a running instance, and delegates visual
-// composition to the story shell.
-class StoryControllerImpl::LaunchModuleInShellCall : public Operation<> {
- public:
- LaunchModuleInShellCall(
- StoryControllerImpl* const story_controller_impl,
- fuchsia::modular::ModuleData module_data,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request,
- ResultCall result_call)
- : Operation("StoryControllerImpl::LaunchModuleInShellCall",
- std::move(result_call), module_data.module_url),
- story_controller_impl_(story_controller_impl),
- module_data_(std::move(module_data)),
- module_controller_request_(std::move(module_controller_request)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- // TODO(mesch): The LaunchModuleCall may result in just a new
- // fuchsia::modular::ModuleController connection to an existing
- // ModuleControllerImpl. In that case, the view owner request is
- // closed, and the view owner should not be sent to the story
- // shell.
- operation_queue_.Add(new LaunchModuleCall(
- story_controller_impl_, fidl::Clone(module_data_),
- std::move(module_controller_request_), view_owner_.NewRequest(),
- [this, flow] { LoadModuleManifest(flow); }));
- view_owner_.set_error_handler([module_url =
- module_data_.module_url](zx_status_t) {
- FXL_LOG(ERROR) << "ViewOwner associated with module_url=" << module_url
- << " died. This module likely won't be able to display "
- "anything on the screen.";
- });
- }
-
- void LoadModuleManifest(FlowToken flow) {
- story_controller_impl_->story_provider_impl_->module_facet_reader()
- ->GetModuleManifest(
- module_data_.module_url,
- [this, flow](fuchsia::modular::ModuleManifestPtr manifest) {
- module_manifest_ = std::move(manifest);
- MaybeConnectViewToStoryShell(flow);
- });
- }
-
- // We only add a module to story shell if it's either a root module or its
- // anchor module is already known to story shell. Otherwise, we pend its view
- // (StoryControllerImpl::pending_story_shell_views_) and pass it to the story
- // shell once its anchor module is ready.
- void MaybeConnectViewToStoryShell(FlowToken flow) {
- // If this is called during Stop(), story_shell_ might already have been
- // reset. TODO(mesch): Then the whole operation should fail.
- if (!story_controller_impl_->story_shell_) {
- return;
- }
-
- if (module_data_.module_path.size() == 1) {
- // This is a root module; pass it's view on to the story shell.
- ConnectViewToStoryShell(flow, "");
- return;
- }
-
- auto* const running_mod_info =
- story_controller_impl_->FindRunningModInfo(module_data_.module_path);
- FXL_CHECK(running_mod_info); // This was just created in LaunchModuleCall.
-
- auto* const anchor = story_controller_impl_->FindAnchor(running_mod_info);
- if (anchor) {
- const auto anchor_surface_id =
- ModulePathToSurfaceID(anchor->module_data->module_path);
- if (story_controller_impl_->connected_views_.count(anchor_surface_id)) {
- ConnectViewToStoryShell(flow, anchor_surface_id);
- return;
- }
- }
-
- auto manifest_clone = fuchsia::modular::ModuleManifest::New();
- fidl::Clone(module_manifest_, &manifest_clone);
-
- fuchsia::modular::SurfaceRelationPtr surface_relation_clone;
- if (module_data_.surface_relation) {
- surface_relation_clone = fuchsia::modular::SurfaceRelation::New();
- module_data_.surface_relation->Clone(surface_relation_clone.get());
- }
-
- story_controller_impl_->pending_story_shell_views_.emplace(
- ModulePathToSurfaceID(module_data_.module_path),
- PendingViewForStoryShell{
- module_data_.module_path, std::move(manifest_clone),
- std::move(surface_relation_clone), module_data_.module_source,
- std::move(view_owner_)});
- }
-
- void ConnectViewToStoryShell(FlowToken flow,
- fidl::StringPtr anchor_surface_id) {
- const auto surface_id = ModulePathToSurfaceID(module_data_.module_path);
-
- fuchsia::modular::ViewConnection view_connection;
- view_connection.surface_id = surface_id;
- view_connection.owner = std::move(view_owner_);
-
- fuchsia::modular::SurfaceInfo surface_info;
- surface_info.parent_id = anchor_surface_id;
- surface_info.surface_relation = std::move(module_data_.surface_relation);
- surface_info.module_manifest = std::move(module_manifest_);
- surface_info.module_source = std::move(module_data_.module_source);
- story_controller_impl_->story_shell_->AddSurface(std::move(view_connection),
- std::move(surface_info));
-
- story_controller_impl_->connected_views_.emplace(surface_id);
- story_controller_impl_->ProcessPendingStoryShellViews();
- story_controller_impl_->story_shell_->FocusSurface(surface_id);
- }
-
- StoryControllerImpl* const story_controller_impl_;
- fuchsia::modular::ModuleData module_data_;
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request_;
-
- fuchsia::modular::ModuleControllerPtr module_controller_;
- fuchsia::ui::viewsv1token::ViewOwnerPtr view_owner_;
-
- fuchsia::modular::ModuleManifestPtr module_manifest_;
-
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LaunchModuleInShellCall);
-};
-
-class StoryControllerImpl::StopCall : public Operation<> {
- public:
- StopCall(StoryControllerImpl* const story_controller_impl, const bool bulk,
- std::function<void()> done)
- : Operation("StoryControllerImpl::StopCall", done),
- story_controller_impl_(story_controller_impl),
- bulk_(bulk) {}
-
- private:
- void Run() override {
- if (!story_controller_impl_->IsRunning()) {
- Done();
- return;
- }
-
- story_controller_impl_->SetRuntimeState(
- fuchsia::modular::StoryState::STOPPING);
-
- // If this StopCall is part of a bulk operation of story provider that stops
- // all stories at once, no DetachView() notification is given to the session
- // shell.
- if (bulk_) {
- StopStory();
- return;
- }
-
- // Invocation of DetachView() follows below.
- //
- // The following callback is scheduled twice, once as response from
- // DetachView(), and again as a timeout.
- //
- // The shared bool did_run keeps track of the number of invocations, and
- // allows to suppress the second one.
- //
- // The weak pointer is needed because the method invocation would not be
- // cancelled when the OperationQueue holding this Operation instance is
- // deleted, because the method is invoked on an instance outside of the
- // instance that owns the OperationQueue that holds this Operation instance.
- //
- // The argument from_timeout informs whether the invocation was from the
- // timeout or from the method callback. It's used only to log diagnostics.
- // If we would not want to have this diagnostic, we could use this callback
- // directly to schedule it twice. In that case, it would be important that
- // passing it to DetachView() has copy semantics, as it does now passing it
- // to the capture list of two separate lambdas, and not move semantics, i.e.
- // that the argument is of DetachView() is NOT a fit::function but a
- // std::function.
- //
- // Both weak and shared pointers are copyable, so we don't need to do
- // anything to make this lambda copyable. (But it will be copied when used
- // below.)
- auto cont = [this, weak_this = GetWeakPtr(),
- did_run = std::make_shared<bool>(false),
- story_id = story_controller_impl_->story_id_](
- const bool from_timeout) {
- if (*did_run) {
- return;
- }
-
- *did_run = true;
-
- if (from_timeout) {
- FXL_LOG(INFO) << "DetachView() timed out: story_id=" << story_id;
- }
-
- if (weak_this) {
- StopStory();
- }
- };
-
- story_controller_impl_->DetachView([cont] { cont(false); });
-
- async::PostDelayedTask(async_get_default_dispatcher(),
- [cont] { cont(true); }, kBasicTimeout);
- }
-
- void StopStory() {
- std::vector<FuturePtr<>> did_teardowns;
- did_teardowns.reserve(story_controller_impl_->running_mod_infos_.size());
-
- // Tear down all connections with a fuchsia::modular::ModuleController
- // first, then the links between them.
- for (auto& running_mod_info : story_controller_impl_->running_mod_infos_) {
- auto did_teardown =
- Future<>::Create("StoryControllerImpl.StopCall.Run.did_teardown");
- running_mod_info.module_controller_impl->Teardown(
- did_teardown->Completer());
- did_teardowns.emplace_back(did_teardown);
- }
-
- Wait("StoryControllerImpl.StopCall.Run.Wait", did_teardowns)
- ->AsyncMap([this] {
- auto did_teardown = Future<>::Create(
- "StoryControllerImpl.StopCall.Run.did_teardown2");
- // If StopCall runs on a story that's not running, there is no story
- // shell.
- if (story_controller_impl_->story_shell_) {
- story_controller_impl_->story_shell_app_->Teardown(
- kBasicTimeout, did_teardown->Completer());
- } else {
- did_teardown->Complete();
- }
-
- return did_teardown;
- })
- ->AsyncMap([this] {
- story_controller_impl_->story_shell_app_.reset();
- story_controller_impl_->story_shell_.Unbind();
-
- // Ensure every story storage operation has completed.
- return story_controller_impl_->story_storage_->Sync();
- })
- ->Then([this] {
- // Clear the remaining links and connections in case there are some
- // left. At this point, no DisposeLink() calls can arrive anymore.
- story_controller_impl_->link_impls_.CloseAll();
-
- // There should be no ongoing activities since all the modules have
- // been destroyed at this point.
- FXL_DCHECK(story_controller_impl_->ongoing_activities_.size() == 0);
-
- story_controller_impl_->SetRuntimeState(
- fuchsia::modular::StoryState::STOPPED);
-
- story_controller_impl_->DestroyStoryEnvironment();
-
- Done();
- });
- }
-
- StoryControllerImpl* const story_controller_impl_; // not owned
-
- // Whether this Stop operation is part of stopping all stories at once. In
- // that case, DetachView() is not called.
- const bool bulk_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StopCall);
-};
-
-class StoryControllerImpl::StopModuleCall : public Operation<> {
- public:
- StopModuleCall(StoryStorage* const story_storage,
- const std::vector<std::string>& module_path,
- const std::function<void()>& done)
- : Operation("StoryControllerImpl::StopModuleCall", done),
- story_storage_(story_storage),
- module_path_(module_path) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- // Mark this module as stopped, which is a global state shared between
- // machines to track when the module is explicitly stopped. The module will
- // stop when ledger notifies us back about the module state change,
- // see OnModuleDataUpdated().
- story_storage_->UpdateModuleData(
- module_path_, [flow](fuchsia::modular::ModuleDataPtr* module_data_ptr) {
- FXL_DCHECK(*module_data_ptr);
- (*module_data_ptr)->module_deleted = true;
- });
- }
-
- StoryStorage* const story_storage_; // not owned
- const std::vector<std::string> module_path_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StopModuleCall);
-};
-
-class StoryControllerImpl::StopModuleAndStoryIfEmptyCall : public Operation<> {
- public:
- StopModuleAndStoryIfEmptyCall(
- StoryControllerImpl* const story_controller_impl,
- const std::vector<std::string>& module_path,
- const std::function<void()>& done)
- : Operation("StoryControllerImpl::StopModuleAndStoryIfEmptyCall", done),
- story_controller_impl_(story_controller_impl),
- module_path_(module_path) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- // If this is the last module in the story, stop the whole story instead
- // (which will cause this mod to be stopped also).
- auto* const running_mod_info =
- story_controller_impl_->FindRunningModInfo(module_path_);
- if (running_mod_info &&
- story_controller_impl_->running_mod_infos_.size() == 1) {
- operation_queue_.Add(
- new StopCall(story_controller_impl_, false /* bulk */, [flow] {}));
- } else {
- // Otherwise, stop this one module.
- operation_queue_.Add(new StopModuleCall(
- story_controller_impl_->story_storage_, module_path_, [flow] {}));
- }
- }
-
- StoryControllerImpl* const story_controller_impl_; // not owned
- const std::vector<std::string> module_path_;
-
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StopModuleAndStoryIfEmptyCall);
-};
-
-class StoryControllerImpl::OnModuleDataUpdatedCall : public Operation<> {
- public:
- OnModuleDataUpdatedCall(StoryControllerImpl* const story_controller_impl,
- fuchsia::modular::ModuleData module_data)
- : Operation("StoryControllerImpl::LedgerNotificationCall", [] {}),
- story_controller_impl_(story_controller_impl),
- module_data_(std::move(module_data)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- if (!story_controller_impl_->IsRunning()) {
- return;
- }
-
- // Check for existing module at the given path.
- auto* const running_mod_info =
- story_controller_impl_->FindRunningModInfo(module_data_.module_path);
- if (module_data_.module_deleted) {
- // If the module is running, kill it.
- if (running_mod_info) {
- operation_queue_.Add(new KillModuleCall(
- story_controller_impl_, std::move(module_data_), [flow] {}));
- }
- return;
- }
-
- // We do not auto-start Modules that were added through ModuleContext on
- // other devices.
- //
- // TODO(thatguy): Revisit this decision. It seems wrong: we do not want
- // to auto-start mods added through ModuleContext.EmbedModule(), because
- // we do not have the necessary capabilities (the ViewOwner). However,
- // mods added through ModuleContext.AddModuleToStory() can be started
- // automatically.
- if (module_data_.module_source ==
- fuchsia::modular::ModuleSource::INTERNAL) {
- return;
- }
-
- // We reach this point only if we want to start or update an existing
- // external module.
- operation_queue_.Add(new LaunchModuleInShellCall(
- story_controller_impl_, std::move(module_data_),
- nullptr /* module_controller_request */, [flow] {}));
- }
-
- OperationQueue operation_queue_;
- StoryControllerImpl* const story_controller_impl_; // not owned
- fuchsia::modular::ModuleData module_data_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(OnModuleDataUpdatedCall);
-};
-
-class StoryControllerImpl::FocusCall : public Operation<> {
- public:
- FocusCall(StoryControllerImpl* const story_controller_impl,
- std::vector<std::string> module_path)
- : Operation("StoryControllerImpl::FocusCall", [] {}),
- story_controller_impl_(story_controller_impl),
- module_path_(std::move(module_path)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- if (!story_controller_impl_->story_shell_) {
- return;
- }
-
- story_controller_impl_->story_shell_->FocusSurface(
- ModulePathToSurfaceID(module_path_));
- }
-
- OperationQueue operation_queue_;
- StoryControllerImpl* const story_controller_impl_; // not owned
- const std::vector<std::string> module_path_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FocusCall);
-};
-
-class StoryControllerImpl::DefocusCall : public Operation<> {
- public:
- DefocusCall(StoryControllerImpl* const story_controller_impl,
- std::vector<std::string> module_path)
- : Operation("StoryControllerImpl::DefocusCall", [] {}),
- story_controller_impl_(story_controller_impl),
- module_path_(std::move(module_path)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- if (!story_controller_impl_->story_shell_) {
- return;
- }
-
- // NOTE(mesch): We don't wait for defocus to return. TODO(mesch): What is
- // the return callback good for anyway?
- story_controller_impl_->story_shell_->DefocusSurface(
- ModulePathToSurfaceID(module_path_), [] {});
- }
-
- OperationQueue operation_queue_;
- StoryControllerImpl* const story_controller_impl_; // not owned
- const std::vector<std::string> module_path_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DefocusCall);
-};
-
-// An operation that first performs module resolution with the provided
-// fuchsia::modular::Intent and subsequently starts the most appropriate
-// resolved module in the story shell.
-class StoryControllerImpl::AddIntentCall
- : public Operation<fuchsia::modular::StartModuleStatus> {
- public:
- AddIntentCall(StoryControllerImpl* const story_controller_impl,
- AddModParams add_mod_params,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- ResultCall result_call)
- : Operation("StoryControllerImpl::AddIntentCall", std::move(result_call)),
- story_controller_impl_(story_controller_impl),
- add_mod_params_(std::move(add_mod_params)),
- module_controller_request_(std::move(module_controller_request)),
- view_owner_request_(std::move(view_owner_request)) {}
-
- private:
- void Run() {
- FlowToken flow{this, &start_module_status_};
- AddAddModOperation(
- &operation_queue_, story_controller_impl_->story_storage_,
- story_controller_impl_->story_provider_impl_->module_resolver(),
- story_controller_impl_->story_provider_impl_->entity_resolver(),
- std::move(add_mod_params_),
- [this, flow](fuchsia::modular::ExecuteResult result,
- fuchsia::modular::ModuleData module_data) {
- if (result.status ==
- fuchsia::modular::ExecuteStatus::NO_MODULES_FOUND) {
- start_module_status_ =
- fuchsia::modular::StartModuleStatus::NO_MODULES_FOUND;
- return;
- }
- if (result.status != fuchsia::modular::ExecuteStatus::OK) {
- FXL_LOG(WARNING)
- << "StoryController::AddIntentCall::AddModCall returned "
- << "error response with message: " << result.error_message;
- }
- module_data_ = std::move(module_data);
- LaunchModuleIfStoryRunning(flow);
- });
- }
-
- void LaunchModuleIfStoryRunning(FlowToken flow) {
- if (story_controller_impl_->IsRunning()) {
- // TODO(thatguy): Should we be checking surface_relation also?
- if (!view_owner_request_) {
- operation_queue_.Add(new LaunchModuleInShellCall(
- story_controller_impl_, std::move(module_data_),
- std::move(module_controller_request_), [flow] {}));
- } else {
- operation_queue_.Add(new LaunchModuleCall(
- story_controller_impl_, std::move(module_data_),
- std::move(module_controller_request_),
- std::move(view_owner_request_), [this, flow] {
- // LaunchModuleInShellCall above already calls
- // ProcessPendingStoryShellViews(). NOTE(thatguy): This
- // cannot be moved into LaunchModuleCall, because
- // LaunchModuleInShellCall uses LaunchModuleCall
- // as the very first step of its operation. This
- // would inform the story shell of a new module
- // before we had told it about its
- // surface-relation parent (which we do as the
- // second part of LaunchModuleInShellCall). So
- // we must defer to here.
- story_controller_impl_->ProcessPendingStoryShellViews();
- }));
- }
- }
-
- start_module_status_ = fuchsia::modular::StartModuleStatus::SUCCESS;
- }
-
- OperationQueue operation_queue_;
- StoryControllerImpl* const story_controller_impl_;
-
- // Some of the fields in add_mod_params_ are used to initializel
- // module_data_ in AddModuleFromResult().
- AddModParams add_mod_params_;
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request_;
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request_;
-
- // Created by AddModuleFromResult, and ultimately written to story state.
- fuchsia::modular::ModuleData module_data_;
-
- fuchsia::modular::StartModuleStatus start_module_status_{
- fuchsia::modular::StartModuleStatus::NO_MODULES_FOUND};
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AddIntentCall);
-};
-
-class StoryControllerImpl::StartCall : public Operation<> {
- public:
- StartCall(StoryControllerImpl* const story_controller_impl,
- StoryStorage* const storage)
- : Operation("StoryControllerImpl::StartCall", [] {}),
- story_controller_impl_(story_controller_impl),
- storage_(storage) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- // If the story is running, we do nothing.
- if (story_controller_impl_->IsRunning()) {
- FXL_LOG(INFO)
- << "StoryControllerImpl::StartCall() while already running: ignored.";
- return;
- }
-
- story_controller_impl_->StartStoryShell();
-
- // Start all modules that were not themselves explicitly started by another
- // module.
- storage_->ReadAllModuleData()->Then(
- [this, flow](std::vector<fuchsia::modular::ModuleData> data) {
- story_controller_impl_->InitStoryEnvironment();
- for (auto& module_data : data) {
- // Don't start the module if it is embedded, or if it has been
- // marked deleted.
- if (module_data.module_deleted || module_data.is_embedded) {
- continue;
- }
- FXL_CHECK(module_data.intent);
- operation_queue_.Add(new LaunchModuleInShellCall(
- story_controller_impl_, std::move(module_data),
- nullptr /* module_controller_request */, [flow] {}));
- }
-
- story_controller_impl_->SetRuntimeState(
- fuchsia::modular::StoryState::RUNNING);
- });
- }
-
- StoryControllerImpl* const story_controller_impl_; // not owned
- StoryStorage* const storage_; // not owned
-
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StartCall);
-};
-
-class StoryControllerImpl::UpdateSnapshotCall : public Operation<> {
- public:
- UpdateSnapshotCall(StoryControllerImpl* const story_controller_impl,
- std::function<void()> done)
- : Operation("StoryControllerImpl::UpdateSnapshotCall", done),
- story_controller_impl_(story_controller_impl) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- // If the story shell is not running, we avoid updating the snapshot.
- if (!story_controller_impl_->IsRunning()) {
- FXL_LOG(INFO) << "StoryControllerImpl::UpdateSnapshotCall() called when "
- "story shell is not initialized.";
- return;
- }
-
- FlowTokenHolder branch{flow};
- // |flow| will branch into normal and timeout paths. |flow| must go out of
- // scope when either of the paths finishes. We pass a weak ptr of
- // story_controller_impl to the callback in case the operation goes out of
- // scope from timeout.
- story_controller_impl_->story_provider_impl_->TakeSnapshot(
- story_controller_impl_->story_id_,
- [weak_ptr = story_controller_impl_->weak_factory_.GetWeakPtr(),
- branch](fuchsia::mem::Buffer snapshot) {
- if (!weak_ptr) {
- return;
- }
-
- if (snapshot.size == 0) {
- FXL_LOG(INFO)
- << "TakeSnapshot returned an invalid snapshot for story: "
- << weak_ptr->story_id_;
- return;
- }
-
- // Even if the snapshot comes back after timeout, we attempt to
- // process it by loading the snapshot and saving it to storage. This
- // call assumes that the snapshot loader has already been connected.
- if (!weak_ptr->snapshot_loader_.is_bound()) {
- FXL_LOG(ERROR) << "UpdateSnapshotCall called when snapshot loader "
- "has not been connected for story: "
- << weak_ptr->story_id_;
- } else {
- fuchsia::mem::Buffer snapshot_copy;
- snapshot.Clone(&snapshot_copy);
- weak_ptr->snapshot_loader_->Load(std::move(snapshot_copy));
- }
-
- weak_ptr->session_storage_
- ->WriteSnapshot(weak_ptr->story_id_, std::move(snapshot))
- ->Then([weak_ptr, branch]() {
- auto flow = branch.Continue();
- if (!flow) {
- FXL_LOG(INFO) << "Saved snapshot for story after timeout: "
- << weak_ptr->story_id_;
- } else {
- FXL_LOG(INFO)
- << "Saved snapshot for story: " << weak_ptr->story_id_;
- }
- });
- });
-
- async::PostDelayedTask(
- async_get_default_dispatcher(),
- [this, branch] {
- auto flow = branch.Continue();
- if (flow) {
- FXL_LOG(INFO) << "Timed out while updating snapshot for story: "
- << story_controller_impl_->story_id_;
- }
- },
- kUpdateSnapshotTimeout);
- }
-
- StoryControllerImpl* const story_controller_impl_; // not owned
-
- FXL_DISALLOW_COPY_AND_ASSIGN(UpdateSnapshotCall);
-};
-
-class StoryControllerImpl::StartSnapshotLoaderCall : public Operation<> {
- public:
- StartSnapshotLoaderCall(
- StoryControllerImpl* const story_controller_impl,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request)
- : Operation("StoryControllerImpl::StartSnapshotLoaderCall", [] {}),
- story_controller_impl_(story_controller_impl),
- request_(std::move(request)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- story_controller_impl_->story_provider_impl_->StartSnapshotLoader(
- std::move(request_),
- story_controller_impl_->snapshot_loader_.NewRequest());
-
- story_controller_impl_->session_storage_
- ->ReadSnapshot(story_controller_impl_->story_id_)
- ->Then([this, flow](fuchsia::mem::BufferPtr snapshot) {
- if (!snapshot) {
- FXL_LOG(INFO)
- << "ReadSnapshot returned a null/invalid snapshot for story: "
- << story_controller_impl_->story_id_;
- return;
- }
-
- story_controller_impl_->snapshot_loader_->Load(
- std::move(*snapshot.get()));
- });
- }
-
- StoryControllerImpl* const story_controller_impl_; // not owned
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StartSnapshotLoaderCall);
-};
-
-StoryControllerImpl::StoryControllerImpl(
- SessionStorage* const session_storage, StoryStorage* const story_storage,
- std::unique_ptr<StoryMutator> story_mutator,
- std::unique_ptr<StoryObserver> story_observer,
- StoryVisibilitySystem* const story_visibility_system,
- StoryProviderImpl* const story_provider_impl)
- : story_id_(*story_observer->model().name()),
- story_provider_impl_(story_provider_impl),
- session_storage_(session_storage),
- story_storage_(story_storage),
- story_mutator_(std::move(story_mutator)),
- story_observer_(std::move(story_observer)),
- story_visibility_system_(story_visibility_system),
- story_shell_context_impl_{story_id_, story_provider_impl, this},
- weak_factory_(this) {
- auto story_scope = fuchsia::modular::StoryScope::New();
- story_scope->story_id = story_id_;
- auto scope = fuchsia::modular::ComponentScope::New();
- scope->set_story_scope(std::move(*story_scope));
- story_provider_impl_->user_intelligence_provider()
- ->GetComponentIntelligenceServices(std::move(*scope),
- intelligence_services_.NewRequest());
- story_storage_->set_on_module_data_updated(
- [this](fuchsia::modular::ModuleData module_data) {
- OnModuleDataUpdated(std::move(module_data));
- });
-
- story_observer_->RegisterListener(
- [this](const fuchsia::modular::storymodel::StoryModel& model) {
- NotifyStoryWatchers(model);
- });
-}
-
-StoryControllerImpl::~StoryControllerImpl() = default;
-
-void StoryControllerImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::StoryController> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-bool StoryControllerImpl::IsRunning() {
- switch (*story_observer_->model().runtime_state()) {
- case fuchsia::modular::StoryState::RUNNING:
- return true;
- case fuchsia::modular::StoryState::STOPPING:
- case fuchsia::modular::StoryState::STOPPED:
- return false;
- }
-}
-
-fidl::VectorPtr<fuchsia::modular::OngoingActivityType>
-StoryControllerImpl::GetOngoingActivities() {
- fidl::VectorPtr<fuchsia::modular::OngoingActivityType> ongoing_activities;
- ongoing_activities.resize(0);
- for (auto& entry : ongoing_activities_.bindings()) {
- ongoing_activities.push_back(entry->impl()->GetType());
- }
-
- return ongoing_activities;
-}
-
-void StoryControllerImpl::Sync(const std::function<void()>& done) {
- operation_queue_.Add(new SyncCall(done));
-}
-
-void StoryControllerImpl::FocusModule(
- const std::vector<std::string>& module_path) {
- operation_queue_.Add(new FocusCall(this, module_path));
-}
-
-void StoryControllerImpl::DefocusModule(
- const std::vector<std::string>& module_path) {
- operation_queue_.Add(new DefocusCall(this, module_path));
-}
-
-void StoryControllerImpl::StopModule(
- const std::vector<std::string>& module_path,
- const std::function<void()>& done) {
- operation_queue_.Add(new StopModuleCall(story_storage_, module_path, done));
-}
-
-void StoryControllerImpl::ReleaseModule(
- ModuleControllerImpl* const module_controller_impl) {
- auto fit = std::find_if(running_mod_infos_.begin(), running_mod_infos_.end(),
- [module_controller_impl](const RunningModInfo& c) {
- return c.module_controller_impl.get() ==
- module_controller_impl;
- });
- FXL_DCHECK(fit != running_mod_infos_.end());
- fit->module_controller_impl.release();
- pending_story_shell_views_.erase(
- ModulePathToSurfaceID(fit->module_data->module_path));
- running_mod_infos_.erase(fit);
-}
-
-fidl::StringPtr StoryControllerImpl::GetStoryId() const {
- return *story_observer_->model().name();
-}
-
-void StoryControllerImpl::RequestStoryFocus() {
- story_provider_impl_->RequestStoryFocus(story_id_);
-}
-
-// TODO(drees) Collapse functionality into GetLink.
-void StoryControllerImpl::ConnectLinkPath(
- fuchsia::modular::LinkPathPtr link_path,
- fidl::InterfaceRequest<fuchsia::modular::Link> request) {
- // Cache a copy of the current active links, because link_impls_.AddBinding()
- // will change the set to include the newly created link connection.
- auto active_links = GetActiveLinksInternal();
-
- LinkPath link_path_clone;
- link_path->Clone(&link_path_clone);
- link_impls_.AddBinding(
- std::make_unique<LinkImpl>(story_storage_, std::move(link_path_clone)),
- std::move(request));
-
- // TODO: remove this. MI4-1084
- if (active_links.count(*link_path) == 0) {
- // This is a new link: notify watchers.
- for (auto& i : links_watchers_.ptrs()) {
- LinkPath link_path_clone;
- link_path->Clone(&link_path_clone);
- (*i)->OnNewLink(std::move(link_path_clone));
- }
- }
-}
-
-fuchsia::modular::LinkPathPtr StoryControllerImpl::GetLinkPathForParameterName(
- const std::vector<std::string>& module_path, std::string name) {
- auto mod_info = FindRunningModInfo(module_path);
- // NOTE: |mod_info| will only be valid if the module at |module_path| is
- // running. Strictly speaking, this is unsafe. The source of truth is the
- // Ledger, accessible through StoryStorage, but the call would be dispatcher,
- // which would change the flow of all clients of this method. For now, we
- // leave as-is.
- FXL_DCHECK(mod_info) << ModulePathToSurfaceID(module_path);
-
- const auto& param_map = mod_info->module_data->parameter_map;
- auto it = std::find_if(
- param_map.entries.begin(), param_map.entries.end(),
- [&name](const fuchsia::modular::ModuleParameterMapEntry& data) {
- return data.name == name;
- });
-
- fuchsia::modular::LinkPathPtr link_path = nullptr;
- if (it != param_map.entries.end()) {
- link_path = CloneOptional(it->link_path);
- }
-
- if (!link_path) {
- link_path = fuchsia::modular::LinkPath::New();
- link_path->module_path = module_path;
- link_path->link_name = name;
- }
-
- return link_path;
-}
-
-void StoryControllerImpl::EmbedModule(
- AddModParams add_mod_params,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- std::function<void(fuchsia::modular::StartModuleStatus)> callback) {
- operation_queue_.Add(new AddIntentCall(
- this, std::move(add_mod_params), std::move(module_controller_request),
- std::move(view_owner_request), std::move(callback)));
-}
-
-void StoryControllerImpl::AddModuleToStory(
- AddModParams add_mod_params,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request,
- std::function<void(fuchsia::modular::StartModuleStatus)> callback) {
- operation_queue_.Add(new AddIntentCall(
- this, std::move(add_mod_params), std::move(module_controller_request),
- nullptr /* view_owner_request */, std::move(callback)));
-}
-
-void StoryControllerImpl::ProcessPendingStoryShellViews() {
- // NOTE(mesch): As it stands, this machinery to send modules in traversal
- // order to the story shell is N^3 over the lifetime of the story, where N
- // is the number of modules. This function is N^2, and it's called once for
- // each of the N modules. However, N is small, and moreover its scale is
- // limited my much more severe constraints. Eventually, we will address this
- // by changing story shell to be able to accomodate modules out of traversal
- // order.
- if (!story_shell_) {
- return;
- }
-
- std::vector<fidl::StringPtr> added_keys;
-
- for (auto& kv : pending_story_shell_views_) {
- auto* const running_mod_info = FindRunningModInfo(kv.second.module_path);
- if (!running_mod_info) {
- continue;
- }
-
- auto* const anchor = FindAnchor(running_mod_info);
- if (!anchor) {
- continue;
- }
-
- const auto anchor_surface_id =
- ModulePathToSurfaceID(anchor->module_data->module_path);
- if (!connected_views_.count(anchor_surface_id)) {
- continue;
- }
-
- const auto surface_id = ModulePathToSurfaceID(kv.second.module_path);
- fuchsia::modular::ViewConnection view_connection;
- view_connection.surface_id = surface_id;
- view_connection.owner = std::move(kv.second.view_owner);
- fuchsia::modular::SurfaceInfo surface_info;
- surface_info.parent_id = anchor_surface_id;
- surface_info.surface_relation = std::move(kv.second.surface_relation);
- surface_info.module_manifest = std::move(kv.second.module_manifest);
- surface_info.module_source = std::move(kv.second.module_source);
- story_shell_->AddSurface(std::move(view_connection),
- std::move(surface_info));
- connected_views_.emplace(surface_id);
-
- added_keys.push_back(kv.first);
- }
-
- if (added_keys.size()) {
- for (auto& key : added_keys) {
- pending_story_shell_views_.erase(key);
- }
- ProcessPendingStoryShellViews();
- }
-}
-
-std::set<fuchsia::modular::LinkPath>
-StoryControllerImpl::GetActiveLinksInternal() {
- std::set<fuchsia::modular::LinkPath> paths;
- for (auto& entry : link_impls_.bindings()) {
- LinkPath p;
- entry->impl()->link_path().Clone(&p);
- paths.insert(std::move(p));
- }
- return paths;
-}
-
-void StoryControllerImpl::OnModuleDataUpdated(
- fuchsia::modular::ModuleData module_data) {
- operation_queue_.Add(
- new OnModuleDataUpdatedCall(this, std::move(module_data)));
-}
-
-void StoryControllerImpl::GetInfo(GetInfoCallback callback) {
- // Synced such that if GetInfo() is called after Start() or Stop(), the
- // state after the previously invoked operation is returned.
- //
- // If this call enters a race with a StoryProvider.DeleteStory() call,
- // resulting in |this| being destroyed, |callback| will be dropped.
- operation_queue_.Add(new SyncCall([this, callback] {
- auto story_info = story_provider_impl_->GetCachedStoryInfo(story_id_);
- FXL_CHECK(story_info);
- callback(std::move(*story_info), *story_observer_->model().runtime_state());
- }));
-}
-
-void StoryControllerImpl::RequestStart() {
- operation_queue_.Add(new StartCall(this, story_storage_));
-}
-
-void StoryControllerImpl::Stop(StopCallback done) {
- operation_queue_.Add(new StopCall(this, false /* bulk */, done));
-}
-
-void StoryControllerImpl::StopBulk(const bool bulk, StopCallback done) {
- operation_queue_.Add(new StopCall(this, bulk, done));
-}
-
-void StoryControllerImpl::TakeAndLoadSnapshot(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request,
- TakeAndLoadSnapshotCallback done) {
- // Currently we start a new snapshot view on every TakeAndLoadSnapshot
- // invocation. We can optimize later by connecting the snapshot loader on
- // start and re-using it for the lifetime of the story.
- operation_queue_.Add(new StartSnapshotLoaderCall(this, std::move(request)));
- operation_queue_.Add(new UpdateSnapshotCall(this, done));
-}
-
-void StoryControllerImpl::Watch(
- fidl::InterfaceHandle<fuchsia::modular::StoryWatcher> watcher) {
- auto ptr = watcher.Bind();
- NotifyOneStoryWatcher(story_observer_->model(), ptr.get());
- watchers_.AddInterfacePtr(std::move(ptr));
-}
-
-void StoryControllerImpl::GetActiveModules(GetActiveModulesCallback callback) {
- // We execute this in a SyncCall so that we are sure we don't fall in a
- // crack between a module being created and inserted in the connections
- // collection during some Operation.
- operation_queue_.Add(
- new SyncCall(fxl::MakeCopyable([this, callback]() mutable {
- std::vector<fuchsia::modular::ModuleData> result;
-
- result.resize(running_mod_infos_.size());
- for (size_t i = 0; i < running_mod_infos_.size(); i++) {
- running_mod_infos_[i].module_data->Clone(&result.at(i));
- }
- callback(std::move(result));
- })));
-}
-
-void StoryControllerImpl::GetModules(GetModulesCallback callback) {
- auto on_run = Future<>::Create("StoryControllerImpl.GetModules.on_run");
- auto done =
- on_run->AsyncMap([this] { return story_storage_->ReadAllModuleData(); });
- operation_queue_.Add(WrapFutureAsOperation(
- "StoryControllerImpl.GetModules.op", on_run, done, callback));
-}
-
-void StoryControllerImpl::GetModuleController(
- std::vector<std::string> module_path,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController> request) {
- operation_queue_.Add(new SyncCall(
- fxl::MakeCopyable([this, module_path = std::move(module_path),
- request = std::move(request)]() mutable {
- for (auto& running_mod_info : running_mod_infos_) {
- if (module_path == running_mod_info.module_data->module_path) {
- running_mod_info.module_controller_impl->Connect(
- std::move(request));
- return;
- }
- }
-
- // Trying to get a controller for a module that is not active just
- // drops the connection request.
- })));
-}
-
-void StoryControllerImpl::GetActiveLinks(
- fidl::InterfaceHandle<fuchsia::modular::StoryLinksWatcher> watcher,
- GetActiveLinksCallback callback) {
- auto result = fidl::VectorPtr<fuchsia::modular::LinkPath>::New(0);
-
- std::set<fuchsia::modular::LinkPath> active_links = GetActiveLinksInternal();
- for (auto& p : active_links) {
- LinkPath clone;
- p.Clone(&clone);
- result.push_back(std::move(clone));
- }
-
- if (watcher) {
- links_watchers_.AddInterfacePtr(watcher.Bind());
- }
- callback(std::move(result));
-}
-
-void StoryControllerImpl::GetLink(
- fuchsia::modular::LinkPath link_path,
- fidl::InterfaceRequest<fuchsia::modular::Link> request) {
- ConnectLinkPath(fidl::MakeOptional(std::move(link_path)), std::move(request));
-}
-
-void StoryControllerImpl::StartStoryShell() {
- fuchsia::ui::viewsv1token::ViewOwnerPtr view_owner;
- auto request = view_owner.NewRequest();
- story_provider_impl_->AttachView(story_id_, std::move(view_owner));
-
- story_shell_app_ =
- story_provider_impl_->StartStoryShell(story_id_, std::move(request));
- story_shell_app_->services().ConnectToService(story_shell_.NewRequest());
- fuchsia::modular::StoryShellContextPtr story_shell_context;
- story_shell_context_impl_.Connect(story_shell_context.NewRequest());
- story_shell_->Initialize(std::move(story_shell_context));
- story_shell_.events().OnSurfaceFocused =
- fit::bind_member(this, &StoryControllerImpl::OnSurfaceFocused);
-}
-
-void StoryControllerImpl::DetachView(std::function<void()> done) {
- story_provider_impl_->DetachView(story_id_, std::move(done));
-}
-
-void StoryControllerImpl::SetRuntimeState(
- const fuchsia::modular::StoryState new_state) {
- story_mutator_->set_runtime_state(new_state);
-}
-
-void StoryControllerImpl::NotifyStoryWatchers(
- const fuchsia::modular::storymodel::StoryModel& model) {
- for (auto& i : watchers_.ptrs()) {
- NotifyOneStoryWatcher(model, (*i).get());
- }
-}
-
-void StoryControllerImpl::NotifyOneStoryWatcher(
- const fuchsia::modular::storymodel::StoryModel& model,
- fuchsia::modular::StoryWatcher* watcher) {
- watcher->OnStateChange(*model.runtime_state());
-}
-
-bool StoryControllerImpl::IsExternalModule(
- const std::vector<std::string>& module_path) {
- auto* const i = FindRunningModInfo(module_path);
- if (!i) {
- return false;
- }
-
- return i->module_data->module_source ==
- fuchsia::modular::ModuleSource::EXTERNAL;
-}
-
-StoryControllerImpl::RunningModInfo* StoryControllerImpl::FindRunningModInfo(
- const std::vector<std::string>& module_path) {
- for (auto& c : running_mod_infos_) {
- if (c.module_data->module_path == module_path) {
- return &c;
- }
- }
- return nullptr;
-}
-
-StoryControllerImpl::RunningModInfo* StoryControllerImpl::FindAnchor(
- RunningModInfo* running_mod_info) {
- if (!running_mod_info) {
- return nullptr;
- }
-
- auto* anchor = FindRunningModInfo(
- ParentModulePath(running_mod_info->module_data->module_path));
-
- // Traverse up until there is a non-embedded module.
- while (anchor && anchor->module_data->is_embedded) {
- anchor =
- FindRunningModInfo(ParentModulePath(anchor->module_data->module_path));
- }
-
- return anchor;
-}
-
-void StoryControllerImpl::RemoveModuleFromStory(
- const std::vector<std::string>& module_path) {
- operation_queue_.Add(
- new StopModuleAndStoryIfEmptyCall(this, module_path, [] {}));
-}
-
-void StoryControllerImpl::InitStoryEnvironment() {
- FXL_DCHECK(!story_environment_)
- << "Story scope already running for story_id = " << story_id_;
-
- static const auto* const kEnvServices =
- new std::vector<std::string>{fuchsia::modular::ContextWriter::Name_};
- story_environment_ = std::make_unique<Environment>(
- story_provider_impl_->user_environment(),
- kStoryEnvironmentLabelPrefix + story_id_.get(), *kEnvServices,
- /* kill_on_oom = */ false);
- story_environment_->AddService<fuchsia::modular::ContextWriter>(
- [this](fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request) {
- intelligence_services_->GetContextWriter(std::move(request));
- });
-}
-
-void StoryControllerImpl::DestroyStoryEnvironment() {
- story_environment_.reset();
-}
-
-void StoryControllerImpl::StartOngoingActivity(
- const fuchsia::modular::OngoingActivityType ongoing_activity_type,
- fidl::InterfaceRequest<fuchsia::modular::OngoingActivity> request) {
- // Newly created/destroyed ongoing activities should be dispatched to the
- // story provider.
- auto dispatch_to_story_provider = [this] {
- story_provider_impl_->NotifyStoryActivityChange(story_id_,
- GetOngoingActivities());
- };
-
- // When a connection is closed on the client-side, the OngoingActivityImpl is
- // destroyed after it is removed from the binding set, so we dispatch to the
- // story provider in the destructor of OngoingActivityImpl.
- ongoing_activities_.AddBinding(
- std::make_unique<OngoingActivityImpl>(
- ongoing_activity_type,
- /* on_destroy= */ dispatch_to_story_provider),
- std::move(request));
-
- // Conversely, when a connection is created, the OngoingActivityImpl is
- // initialized before added to the binding set, so we need to dispatch after
- // bind.
- dispatch_to_story_provider();
-}
-
-void StoryControllerImpl::CreateEntity(
- std::string type, fuchsia::mem::Buffer data,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request,
- std::function<void(std::string /* entity_reference */)> callback) {
- story_provider_impl_->CreateEntity(story_id_, type, std::move(data),
- std::move(entity_request),
- std::move(callback));
-}
-
-void StoryControllerImpl::OnSurfaceFocused(fidl::StringPtr surface_id) {
- auto module_path = ModulePathFromSurfaceID(surface_id);
-
- for (auto& watcher : watchers_.ptrs()) {
- (*watcher)->OnModuleFocused(std::move(module_path));
- }
-}
-
-} // namespace modular
\ No newline at end of file
diff --git a/bin/sessionmgr/story_runner/story_controller_impl.h b/bin/sessionmgr/story_runner/story_controller_impl.h
deleted file mode 100644
index dbd22b2..0000000
--- a/bin/sessionmgr/story_runner/story_controller_impl.h
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The Story service is the context in which a story executes. It
-// starts modules and provides them with a handle to itself, so they
-// can start more modules. It also serves as the factory for
-// fuchsia::modular::Link instances, which are used to share data between
-// modules.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_CONTROLLER_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_CONTROLLER_IMPL_H_
-
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/scenic/snapshot/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h"
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-#include "peridot/bin/sessionmgr/story/model/story_mutator.h"
-#include "peridot/bin/sessionmgr/story/model/story_observer.h"
-#include "peridot/bin/sessionmgr/story_runner/link_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/ongoing_activity_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/story_shell_context_impl.h"
-#include "peridot/lib/fidl/app_client.h"
-#include "peridot/lib/fidl/environment.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/types.h"
-
-namespace modular {
-
-class ModuleContextImpl;
-class ModuleControllerImpl;
-class StoryModelMutator;
-class StoryProviderImpl;
-class StoryStorage;
-class StoryVisibilitySystem;
-
-// The story runner, which holds all the links and runs all the modules as well
-// as the story shell. It also implements the StoryController service to give
-// clients control over the story.
-class StoryControllerImpl : fuchsia::modular::StoryController {
- public:
- StoryControllerImpl(SessionStorage* session_storage,
- StoryStorage* story_storage,
- std::unique_ptr<StoryMutator> story_mutator,
- std::unique_ptr<StoryObserver> story_observer,
- StoryVisibilitySystem* story_visibility_system,
- StoryProviderImpl* story_provider_impl);
- ~StoryControllerImpl() override;
-
- // Called by StoryProviderImpl.
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::StoryController> request);
-
- // Called by StoryProviderImpl.
- bool IsRunning();
-
- // Called by StoryProviderImpl.
- //
- // Returns a list of the ongoing activities in this story.
- fidl::VectorPtr<fuchsia::modular::OngoingActivityType> GetOngoingActivities();
-
- void Sync(const std::function<void()>& done);
-
- // Called by ModuleControllerImpl and ModuleContextImpl.
- void FocusModule(const std::vector<std::string>& module_path);
-
- // Called by ModuleControllerImpl.
- void DefocusModule(const std::vector<std::string>& module_path);
-
- // Called by ModuleControllerImpl.
- void StopModule(const std::vector<std::string>& module_path,
- const std::function<void()>& done);
-
- // Called by ModuleControllerImpl.
- //
- // Releases ownership of |controller| and cleans up any related internal
- // storage. It is the caller's responsibility to delete |controller|.
- void ReleaseModule(ModuleControllerImpl* module_controller_impl);
-
- // Called by ModuleContextImpl.
- fidl::StringPtr GetStoryId() const;
-
- // Called by ModuleContextImpl.
- void RequestStoryFocus();
-
- // Called by ModuleContextImpl.
- void ConnectLinkPath(fuchsia::modular::LinkPathPtr link_path,
- fidl::InterfaceRequest<fuchsia::modular::Link> request);
-
- // Called by ModuleContextImpl.
- fuchsia::modular::LinkPathPtr GetLinkPathForParameterName(
- const std::vector<std::string>& module_path, std::string name);
-
- // Called by ModuleContextImpl.
- void EmbedModule(
- AddModParams add_mod_params,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- std::function<void(fuchsia::modular::StartModuleStatus)> callback);
-
- // Called by ModuleContextImpl.
- void AddModuleToStory(
- AddModParams add_mod_params,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController>
- module_controller_request,
- std::function<void(fuchsia::modular::StartModuleStatus)> callback);
-
- // Stops the module at |module_path| in response to a call to
- // |ModuleContext.RemoveSelfFromStory|.
- void RemoveModuleFromStory(const std::vector<std::string>& module_path);
-
- // Called by ModuleContextImpl.
- void StartOngoingActivity(
- const fuchsia::modular::OngoingActivityType ongoing_activity_type,
- fidl::InterfaceRequest<fuchsia::modular::OngoingActivity> request);
-
- // Called by ModuleContextImpl.
- void CreateEntity(
- std::string type, fuchsia::mem::Buffer data,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request,
- std::function<void(std::string /* entity_reference */)> callback);
-
- // Stops the story as part of a story provider operation. The story provider
- // can indicate whether this is part of an operation where all stories are
- // stopped at once in order to stop the session shell, indicated by bulk being
- // true. Happens at logout or when session shells are swapped. In that
- // situation, DetachView() is not called for this story.
- void StopBulk(bool bulk, StopCallback done);
-
- private:
- // Operations implemented here.
- class AddIntentCall;
- class DefocusCall;
- class FocusCall;
- class KillModuleCall;
- class LaunchModuleCall;
- class LaunchModuleInShellCall;
- class OnModuleDataUpdatedCall;
- class ResolveParameterCall;
- class StartCall;
- class StopCall;
- class StopModuleCall;
- class StopModuleAndStoryIfEmptyCall;
- class StartSnapshotLoaderCall;
- class UpdateSnapshotCall;
-
- // For each *running* Module in the Story, there is one RunningModInfo.
- struct RunningModInfo {
- // NOTE: |module_data| is a cached copy of what is stored in
- // |story_storage_|, the source of truth. It is updated in two
- // places:
- //
- // 1) In LaunchModuleCall (used by LaunchModuleInShellCall) in the case
- // that either a) the module isn't running yet or b) ModuleData.intent
- // differs from what is cached.
- //
- // 2) Indirectly from OnModuleDataUpdated(), which is called when another
- // device updates the Module by calling LaunchModuleInShellCall. However,
- // this only happens if the Module is EXTERNAL (it was not explicitly added
- // by another Module).
- //
- // TODO(thatguy): we should ensure that the local cached copy is always
- // up to date no matter what.
- fuchsia::modular::ModuleDataPtr module_data;
- std::unique_ptr<ModuleContextImpl> module_context_impl;
- std::unique_ptr<ModuleControllerImpl> module_controller_impl;
- };
-
- // A module's story shell-related information that we pend until we are able
- // to pass it off to the story shell.
- struct PendingViewForStoryShell {
- std::vector<std::string> module_path;
- fuchsia::modular::ModuleManifestPtr module_manifest;
- fuchsia::modular::SurfaceRelationPtr surface_relation;
- fuchsia::modular::ModuleSource module_source;
- fuchsia::ui::viewsv1token::ViewOwnerPtr view_owner;
- };
-
- // |StoryController|
- void Stop(StopCallback done) override;
- void GetInfo(GetInfoCallback callback) override;
- void RequestStart() override;
- void TakeAndLoadSnapshot(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request,
- TakeAndLoadSnapshotCallback done) override;
- void Watch(
- fidl::InterfaceHandle<fuchsia::modular::StoryWatcher> watcher) override;
- void GetActiveModules(GetActiveModulesCallback callback) override;
- void GetModules(GetModulesCallback callback) override;
- void GetModuleController(
- std::vector<std::string> module_path,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController> request)
- override;
- void GetActiveLinks(
- fidl::InterfaceHandle<fuchsia::modular::StoryLinksWatcher> watcher,
- GetActiveLinksCallback callback) override;
- void GetLink(fuchsia::modular::LinkPath link_path,
- fidl::InterfaceRequest<fuchsia::modular::Link> request) override;
-
- // Communicates with SessionShell.
- void StartStoryShell();
- void DetachView(std::function<void()> done);
-
- // Called whenever |story_storage_| sees an updated ModuleData from another
- // device.
- void OnModuleDataUpdated(fuchsia::modular::ModuleData module_data);
-
- // Misc internal helpers.
- void SetRuntimeState(fuchsia::modular::StoryState new_state);
- void NotifyStoryWatchers(
- const fuchsia::modular::storymodel::StoryModel& model);
- void NotifyOneStoryWatcher(
- const fuchsia::modular::storymodel::StoryModel& model,
- fuchsia::modular::StoryWatcher* watcher);
- void ProcessPendingStoryShellViews();
- std::set<fuchsia::modular::LinkPath> GetActiveLinksInternal();
-
- bool IsExternalModule(const std::vector<std::string>& module_path);
-
- // Handles SessionShell OnModuleFocused event that indicates whether or not a
- // surface was focused.
- void OnSurfaceFocused(fidl::StringPtr surface_id);
-
- // Initializes the Environment under which all new processes in the story are
- // launched. Use |story_environment_| to manipulate the environment's
- // services.
- void InitStoryEnvironment();
-
- // Destroys the Environment created for this story, tearing down all
- // processes.
- void DestroyStoryEnvironment();
-
- // Finds the active RunningModInfo for a module at the given module path. May
- // return nullptr if the module at the path is not running, regardless of
- // whether a module at that path is known to the story.
- RunningModInfo* FindRunningModInfo(
- const std::vector<std::string>& module_path);
-
- // Finds the active RunningModInfo for the story shell anchor of a module
- // with the given |running_mod_info|. The anchor is the closest ancestor
- // module of the given module that is not embedded and actually known to the
- // story shell. This requires that it must be running, otherwise it cannot be
- // connected to the story shell. May return nullptr if the anchor module, or
- // any intermediate module, is not running, regardless of whether a module at
- // such path is known to the story.
- RunningModInfo* FindAnchor(RunningModInfo* running_mod_info);
-
- // The ID of the story, copied from |story_observer_| for convenience in
- // transitioning clients. TODO(thatguy): Remove users of this in favor of
- // reading from the |story_observer_| directly.
- const fidl::StringPtr story_id_;
-
- StoryProviderImpl* const story_provider_impl_; // Not owned.
- SessionStorage* const session_storage_; // Not owned.
- StoryStorage* const story_storage_; // Not owned.
-
- std::unique_ptr<StoryMutator> story_mutator_;
- std::unique_ptr<StoryObserver> story_observer_;
- StoryVisibilitySystem* const story_visibility_system_; // Not owned.
-
- // The application environment (which abstracts a zx::job) in which the
- // modules within this story run. This environment is only valid (not null) if
- // the story is running.
- std::unique_ptr<Environment> story_environment_;
-
- // Implements the primary service provided here:
- // fuchsia::modular::StoryController.
- fidl::BindingSet<fuchsia::modular::StoryController> bindings_;
-
- // Watcher for various aspects of the story.
- fidl::InterfacePtrSet<fuchsia::modular::StoryWatcher> watchers_;
- fidl::InterfacePtrSet<fuchsia::modular::StoryLinksWatcher> links_watchers_;
-
- // Everything for the story shell. Relationships between modules are conveyed
- // to the story shell using their instance IDs.
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> story_shell_app_;
- fuchsia::modular::StoryShellPtr story_shell_;
-
- StoryShellContextImpl story_shell_context_impl_;
-
- // The module instances (identified by their serialized module paths) already
- // known to story shell. Does not include modules whose views are pending and
- // not yet sent to story shell.
- std::set<fidl::StringPtr> connected_views_;
-
- // Since story shell cannot display views whose parents are not yet displayed,
- // |pending_story_shell_views_| holds the view of a non-embedded running
- // module (identified by its serialized module path) until its parent is
- // connected to story shell.
- std::map<std::string, PendingViewForStoryShell> pending_story_shell_views_;
-
- std::vector<RunningModInfo> running_mod_infos_;
-
- // The second ingredient of a story: Links. They connect Modules.
- fidl::BindingSet<Link, std::unique_ptr<LinkImpl>> link_impls_;
-
- // This is the source of truth on which activities are currently ongoing in
- // the story's modules.
- fidl::BindingSet<fuchsia::modular::OngoingActivity,
- std::unique_ptr<OngoingActivityImpl>>
- ongoing_activities_;
-
- // Used to load snapshots.
- fuchsia::scenic::snapshot::LoaderPtr snapshot_loader_;
-
- // A collection of services, scoped to this Story, for use by intelligent
- // Modules.
- fuchsia::modular::IntelligenceServicesPtr intelligence_services_;
-
- // Asynchronous operations are sequenced in a queue.
- OperationQueue operation_queue_;
-
- fxl::WeakPtrFactory<StoryControllerImpl> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryControllerImpl);
-};
-
-// NOTE: This is only exposed publicly for testing.
-bool ShouldRestartModuleForNewIntent(
- const fuchsia::modular::Intent& old_intent,
- const fuchsia::modular::Intent& new_intent);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_CONTROLLER_IMPL_H_
diff --git a/bin/sessionmgr/story_runner/story_controller_impl_unittest.cc b/bin/sessionmgr/story_runner/story_controller_impl_unittest.cc
deleted file mode 100644
index e9f2390..0000000
--- a/bin/sessionmgr/story_runner/story_controller_impl_unittest.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-////////////////////////////////////////////////////////////////////////////
-// NOTE: This is an incomplete test of StoryControllerImpl. We are closer now to
-// being able to construct a StoryControllerImpl without a StoryProviderImpl,
-// but not yet.
-//
-// Fow now this only tests one public function in story_controller_impl.cc
-// (ShouldRestartModuleForNewIntent).
-////////////////////////////////////////////////////////////////////////////
-
-#include "peridot/bin/sessionmgr/story_runner/story_controller_impl.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-
-using fuchsia::modular::Intent;
-
-namespace modular {
-namespace {
-
-TEST(StoryControllerImplTest, ShouldRestartModuleForNewIntent) {
- Intent one;
- Intent two;
-
- // Handler differs.
- one.handler = "handler1";
- two.handler = "handler2";
- EXPECT_TRUE(ShouldRestartModuleForNewIntent(one, two));
- two.handler = "handler1";
- EXPECT_FALSE(ShouldRestartModuleForNewIntent(one, two));
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/story_entity_provider.cc b/bin/sessionmgr/story_runner/story_entity_provider.cc
deleted file mode 100644
index 18b5d96..0000000
--- a/bin/sessionmgr/story_runner/story_entity_provider.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/story_entity_provider.h"
-
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/random/uuid.h>
-#include <utility>
-
-namespace modular {
-
-StoryEntityProvider::StoryEntityProvider(StoryStorage* story_storage)
- : story_storage_(story_storage) {}
-
-StoryEntityProvider::~StoryEntityProvider() = default;
-
-void StoryEntityProvider::CreateEntity(
- const std::string& type, fuchsia::mem::Buffer data,
- std::function<void(std::string /* cookie */)> callback) {
- const std::string cookie = fxl::GenerateUUID();
- story_storage_->SetEntityData(cookie, type, std::move(data))
- ->Then([this, cookie,
- callback = std::move(callback)](StoryStorage::Status status) {
- if (status == StoryStorage::Status::OK) {
- callback(cookie);
- } else {
- callback(nullptr);
- }
- });
-}
-
-void StoryEntityProvider::Connect(
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider> provider_request) {
- provider_bindings_.AddBinding(this, std::move(provider_request));
-}
-
-void StoryEntityProvider::GetTypes(std::string cookie,
- GetTypesCallback callback) {
- story_storage_->GetEntityType(cookie)->Then(
- [callback = std::move(callback)](StoryStorage::Status status,
- std::string type) {
- std::vector<std::string> types;
- types.push_back(type);
- callback(std::move(types));
- });
-}
-
-void StoryEntityProvider::GetData(std::string cookie, std::string type,
- GetDataCallback callback) {
- story_storage_->GetEntityData(cookie, type)
- ->Then([callback = std::move(callback)](StoryStorage::Status status,
- fuchsia::mem::BufferPtr data) {
- callback(std::move(data));
- });
-}
-
-void StoryEntityProvider::WriteData(std::string cookie,
- std::string type,
- fuchsia::mem::Buffer data,
- WriteDataCallback callback) {
- story_storage_->SetEntityData(cookie, type, std::move(data))
- ->Then([callback = std::move(callback)](StoryStorage::Status status) {
- switch (status) {
- case StoryStorage::Status::OK:
- callback(fuchsia::modular::EntityWriteStatus::OK);
- break;
- case StoryStorage::Status::INVALID_ENTITY_TYPE:
- // fallthrough
- case StoryStorage::Status::INVALID_ENTITY_COOKIE:
- // fallthrough
- case StoryStorage::Status::LEDGER_ERROR:
- // fallthrough
- case StoryStorage::Status::VMO_COPY_ERROR:
- callback(fuchsia::modular::EntityWriteStatus::ERROR);
- break;
- };
- });
-}
-
-void StoryEntityProvider::Watch(
- std::string cookie, std::string type,
- fidl::InterfaceHandle<fuchsia::modular::EntityWatcher> watcher) {
- fuchsia::modular::EntityWatcherPtr entity_watcher = watcher.Bind();
- story_storage_->WatchEntity(cookie, type, std::move(entity_watcher));
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/story_entity_provider.h b/bin/sessionmgr/story_runner/story_entity_provider.h
deleted file mode 100644
index b733141..0000000
--- a/bin/sessionmgr/story_runner/story_entity_provider.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_ENTITY_PROVIDER_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_ENTITY_PROVIDER_H_
-
-#include <map>
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-
-namespace modular {
-
-// The entity provider which is used to provide entities associated with a
-// particular story.
-class StoryEntityProvider : public fuchsia::modular::EntityProvider {
- public:
- // Creates a new StoryEntityProvider associated with the story backed by
- // |story_storage|.
- StoryEntityProvider(StoryStorage* story_storage);
-
- ~StoryEntityProvider();
-
- // Creates a new entity with the given |type| and |data|.
- //
- // |callback| will be called with the entity cookie, or an empty string if the
- // creation failed.
- void CreateEntity(const std::string& type, fuchsia::mem::Buffer data,
- std::function<void(std::string /* cookie */)> callback);
-
- void Connect(fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- provider_request);
-
- private:
- // |fuchsia::modular::EntityProvider|
- void GetTypes(std::string cookie, GetTypesCallback callback) override;
-
- // |fuchsia::modular::EntityProvider|
- void GetData(std::string cookie, std::string type,
- GetDataCallback callback) override;
-
- // |fuchsia::modular::EntityProvider|
- void WriteData(std::string cookie, std::string type,
- fuchsia::mem::Buffer data,
- WriteDataCallback callback) override;
-
- // |fuchsia::modular::EntityProvider|
- void Watch(
- std::string cookie, std::string type,
- fidl::InterfaceHandle<fuchsia::modular::EntityWatcher> watcher) override;
-
- const std::string story_id_;
- StoryStorage* story_storage_; // Not owned.
-
- fidl::BindingSet<fuchsia::modular::EntityProvider> provider_bindings_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_ENTITY_PROVIDER_H_
-
diff --git a/bin/sessionmgr/story_runner/story_provider_impl.cc b/bin/sessionmgr/story_runner/story_provider_impl.cc
deleted file mode 100644
index a46b29f..0000000
--- a/bin/sessionmgr/story_runner/story_provider_impl.cc
+++ /dev/null
@@ -1,798 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/story_provider_impl.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include <fuchsia/scenic/snapshot/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/handles/object_info.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/random/uuid.h>
-#include <lib/zx/time.h>
-
-#include "peridot/bin/basemgr/cobalt/cobalt.h"
-#include "peridot/bin/sessionmgr/focus.h"
-#include "peridot/bin/sessionmgr/presentation_provider.h"
-#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-#include "peridot/bin/sessionmgr/story/systems/story_visibility_system.h"
-#include "peridot/bin/sessionmgr/story_runner/link_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/story_controller_impl.h"
-#include "peridot/lib/common/names.h"
-#include "peridot/lib/common/teardown.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/fidl/proxy.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-
-// In tests prefetching mondrian saved ~30ms in story start up time.
-#define PREFETCH_MONDRIAN 1
-
-namespace modular {
-
-constexpr char kSnapshotLoaderUrl[] = "snapshot";
-
-class StoryProviderImpl::StopStoryCall : public Operation<> {
- public:
- using StoryRuntimesMap = std::map<std::string, struct StoryRuntimeContainer>;
-
- StopStoryCall(fidl::StringPtr story_id, const bool bulk,
- StoryRuntimesMap* const story_runtime_containers,
- MessageQueueManager* const message_queue_manager,
- ResultCall result_call)
- : Operation("StoryProviderImpl::DeleteStoryCall", std::move(result_call)),
- story_id_(story_id),
- bulk_(bulk),
- story_runtime_containers_(story_runtime_containers),
- message_queue_manager_(message_queue_manager) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- auto i = story_runtime_containers_->find(story_id_);
- if (i == story_runtime_containers_->end()) {
- FXL_LOG(WARNING) << "I was told to teardown story " << story_id_
- << ", but I can't find it.";
- return;
- }
-
- FXL_DCHECK(i->second.controller_impl != nullptr);
- i->second.controller_impl->StopBulk(bulk_,
- [this, flow] { CleanupRuntime(flow); });
- }
-
- void CleanupRuntime(FlowToken flow) {
- // Here we delete the instance from whose operation a result callback was
- // received. Thus we must assume that the callback returns to a method of
- // the instance. If we delete the instance right here, |this| would be
- // deleted not just for the remainder of this function here, but also for
- // the remainder of all functions above us in the callstack, including
- // functions that run as methods of other objects owned by |this| or
- // provided to |this|. To avoid such problems, the delete is invoked
- // through the run loop.
- //
- // TODO(thatguy); Understand the above comment, and rewrite it.
- async::PostTask(async_get_default_dispatcher(), [this, flow] {
- story_runtime_containers_->erase(story_id_);
- message_queue_manager_->DeleteNamespace(
- EncodeModuleComponentNamespace(story_id_), [flow] {});
- });
- }
-
- private:
- const fidl::StringPtr story_id_;
- const bool bulk_;
- StoryRuntimesMap* const story_runtime_containers_;
- MessageQueueManager* const message_queue_manager_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StopStoryCall);
-};
-
-// Loads a StoryRuntimeContainer object and stores it in
-// |story_provider_impl.story_runtime_containers_| so that the story is ready
-// to be run.
-class StoryProviderImpl::LoadStoryRuntimeCall
- : public Operation<StoryRuntimeContainer*> {
- public:
- LoadStoryRuntimeCall(StoryProviderImpl* const story_provider_impl,
- SessionStorage* const session_storage,
- fidl::StringPtr story_id, ResultCall result_call)
- : Operation("StoryProviderImpl::LoadStoryRuntimeCall",
- std::move(result_call)),
- story_provider_impl_(story_provider_impl),
- session_storage_(session_storage),
- story_id_(story_id) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &story_runtime_container_};
-
- // Use the existing controller, if possible.
- // This won't race against itself because it's managed by an operation
- // queue.
- auto i = story_provider_impl_->story_runtime_containers_.find(story_id_);
- if (i != story_provider_impl_->story_runtime_containers_.end()) {
- story_runtime_container_ = &i->second;
- return;
- }
-
- session_storage_->GetStoryData(story_id_)->WeakThen(
- GetWeakPtr(),
- [this, flow](fuchsia::modular::internal::StoryDataPtr story_data) {
- if (!story_data) {
- return;
- // Operation finishes since |flow| goes out of scope.
- }
- Cont(std::move(story_data), flow);
- });
- }
-
- void Cont(fuchsia::modular::internal::StoryDataPtr story_data,
- FlowToken flow) {
- session_storage_->GetStoryStorage(story_id_)->WeakThen(
- GetWeakPtr(),
- fxl::MakeCopyable(
- [this, story_data = std::move(story_data),
- flow](std::unique_ptr<StoryStorage> story_storage) mutable {
- struct StoryRuntimeContainer container {
- .executor = std::make_unique<async::Executor>(
- async_get_default_dispatcher()),
- .storage = std::move(story_storage),
- .current_data = std::move(story_data),
- };
-
- container.model_owner = std::make_unique<StoryModelOwner>(
- story_id_, container.executor.get(),
- std::make_unique<NoopStoryModelStorage>());
- container.model_observer = container.model_owner->NewObserver();
-
- // Create systems that are part of this story.
- auto story_visibility_system =
- std::make_unique<StoryVisibilitySystem>(
- container.model_owner->NewMutator());
-
- container.controller_impl = std::make_unique<StoryControllerImpl>(
- session_storage_, container.storage.get(),
- container.model_owner->NewMutator(),
- container.model_owner->NewObserver(),
- story_visibility_system.get(), story_provider_impl_);
- container.entity_provider = std::make_unique<StoryEntityProvider>(
- container.storage.get());
-
- // Hand ownership of systems over to |container|.
- container.systems.push_back(std::move(story_visibility_system));
-
- // Register a listener on the StoryModel so that we can signal
- // our watchers when relevant data changes.
- container.model_observer->RegisterListener(
- [id = story_id_, story_provider = story_provider_impl_](
- const fuchsia::modular::storymodel::StoryModel& model) {
- story_provider->NotifyStoryStateChange(id);
- });
-
- auto it = story_provider_impl_->story_runtime_containers_.emplace(
- story_id_, std::move(container));
- story_runtime_container_ = &it.first->second;
- }));
- }
-
- StoryProviderImpl* const story_provider_impl_; // not owned
- SessionStorage* const session_storage_; // not owned
- const fidl::StringPtr story_id_;
-
- // Return value.
- StoryRuntimeContainer* story_runtime_container_ = nullptr;
-
- // Sub operations run in this queue.
- OperationQueue operation_queue_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LoadStoryRuntimeCall);
-};
-
-class StoryProviderImpl::StopAllStoriesCall : public Operation<> {
- public:
- StopAllStoriesCall(StoryProviderImpl* const story_provider_impl,
- ResultCall result_call)
- : Operation("StoryProviderImpl::StopAllStoriesCall",
- std::move(result_call)),
- story_provider_impl_(story_provider_impl) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- for (auto& it : story_provider_impl_->story_runtime_containers_) {
- // Each callback has a copy of |flow| which only goes out-of-scope
- // once the story corresponding to |it| stops.
- //
- // TODO(thatguy): If the StoryControllerImpl is deleted before it can
- // complete StopWithoutNotifying(), we will never be called back and the
- // OperationQueue on which we're running will block. Moving over to
- // fit::promise will allow us to observe cancellation.
- operations_.Add(new StopStoryCall(
- it.first, true /* bulk */,
- &story_provider_impl_->story_runtime_containers_,
- story_provider_impl_->component_context_info_.message_queue_manager,
- [flow] {}));
- }
- }
-
- OperationCollection operations_;
-
- StoryProviderImpl* const story_provider_impl_; // not owned
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StopAllStoriesCall);
-};
-
-class StoryProviderImpl::StopStoryShellCall : public Operation<> {
- public:
- StopStoryShellCall(StoryProviderImpl* const story_provider_impl,
- ResultCall result_call)
- : Operation("StoryProviderImpl::StopStoryShellCall",
- std::move(result_call)),
- story_provider_impl_(story_provider_impl) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
- if (story_provider_impl_->preloaded_story_shell_app_) {
- // Calling Teardown() below will branch |flow| into normal and timeout
- // paths. |flow| must go out of scope when either of the paths
- // finishes.
- FlowTokenHolder branch{flow};
- story_provider_impl_->preloaded_story_shell_app_->Teardown(
- kBasicTimeout,
- [branch] { std::unique_ptr<FlowToken> flow = branch.Continue(); });
- }
- }
-
- StoryProviderImpl* const story_provider_impl_; // not owned
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StopStoryShellCall);
-};
-
-class StoryProviderImpl::GetStoryEntityProviderCall
- : public Operation<StoryEntityProvider*> {
- public:
- GetStoryEntityProviderCall(StoryProviderImpl* const story_provider_impl,
- const std::string& story_id,
- ResultCall result_call)
- : Operation("StoryProviderImpl::GetStoryEntityProviderCall",
- std::move(result_call)),
- story_provider_impl_(story_provider_impl),
- story_id_(story_id) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &story_entity_provider_};
-
- operation_queue_.Add(new LoadStoryRuntimeCall(
- story_provider_impl_, story_provider_impl_->session_storage_, story_id_,
- [this, flow](StoryRuntimeContainer* story_controller_container) {
- if (story_controller_container) {
- story_entity_provider_ =
- story_controller_container->entity_provider.get();
- }
- }));
- }
-
- StoryProviderImpl* const story_provider_impl_; // not owned
-
- // The returned story entity provider.
- StoryEntityProvider* story_entity_provider_ = nullptr;
-
- fuchsia::modular::StoryInfoPtr story_info_;
-
- OperationQueue operation_queue_;
-
- std::string story_id_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(GetStoryEntityProviderCall);
-};
-
-StoryProviderImpl::StoryProviderImpl(
- Environment* const user_environment, std::string device_id,
- SessionStorage* const session_storage,
- fuchsia::modular::AppConfig story_shell,
- const ComponentContextInfo& component_context_info,
- fuchsia::modular::FocusProviderPtr focus_provider,
- fuchsia::modular::UserIntelligenceProvider* const
- user_intelligence_provider,
- fuchsia::modular::ModuleResolver* const module_resolver,
- EntityProviderRunner* const entity_provider_runner,
- modular::ModuleFacetReader* const module_facet_reader,
- PresentationProvider* const presentation_provider,
- fuchsia::ui::viewsv1::ViewSnapshotPtr view_snapshot, const bool test)
- : user_environment_(user_environment),
- session_storage_(session_storage),
- device_id_(std::move(device_id)),
- story_shell_(std::move(story_shell)),
- test_(test),
- component_context_info_(component_context_info),
- user_intelligence_provider_(user_intelligence_provider),
- module_resolver_(module_resolver),
- entity_provider_runner_(entity_provider_runner),
- module_facet_reader_(module_facet_reader),
- presentation_provider_(presentation_provider),
- focus_provider_(std::move(focus_provider)),
- focus_watcher_binding_(this),
- view_snapshot_(std::move(view_snapshot)),
- weak_factory_(this) {
- session_storage_->set_on_story_deleted(
- [weak_ptr = weak_factory_.GetWeakPtr()](fidl::StringPtr story_id) {
- if (!weak_ptr)
- return;
- weak_ptr->OnStoryStorageDeleted(std::move(story_id));
- });
- session_storage_->set_on_story_updated(
- [weak_ptr = weak_factory_.GetWeakPtr()](
- fidl::StringPtr story_id,
- fuchsia::modular::internal::StoryData story_data) {
- if (!weak_ptr)
- return;
- weak_ptr->OnStoryStorageUpdated(std::move(story_id),
- std::move(story_data));
- });
-
- focus_provider_->Watch(focus_watcher_binding_.NewBinding());
- if (!test_) {
- // As an optimization, since app startup time is long, we optimistically
- // load a story shell instance even if there are no stories that need it
- // yet. This can reduce the time to first frame.
- MaybeLoadStoryShellDelayed();
- }
-}
-
-StoryProviderImpl::~StoryProviderImpl() = default;
-
-void StoryProviderImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::StoryProvider> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void StoryProviderImpl::StopAllStories(const std::function<void()>& callback) {
- operation_queue_.Add(new StopAllStoriesCall(this, callback));
-}
-
-void StoryProviderImpl::SetSessionShell(
- fuchsia::modular::SessionShellPtr session_shell) {
- // Not on operation queue, because it's called only after all stories have
- // been stopped or none are running yet, i.e. when no Operations that would
- // call this interface are scheduled. If there is an operation pending here,
- // then it would pertain to a story running in the new session shell started
- // by puppet master or an agent, so we must assign this now.
- //
- // TODO(mesch): It may well be that we need to revisit this when we support
- // starting stories, or swapping session shells, through puppet master, i.e.
- // from outside the session shell.
- //
- // TODO(mesch): Add a WARNING log if the operation is not empty.
- session_shell_ = std::move(session_shell);
-}
-
-void StoryProviderImpl::Teardown(const std::function<void()>& callback) {
- // Closing all binding to this instance ensures that no new messages come
- // in, though previous messages need to be processed. The stopping of
- // stories is done on |operation_queue_| since that must strictly happen
- // after all pending messgages have been processed.
- bindings_.CloseAll();
- operation_queue_.Add(new StopAllStoriesCall(this, [] {}));
- operation_queue_.Add(new StopStoryShellCall(this, callback));
-}
-
-// |fuchsia::modular::StoryProvider|
-void StoryProviderImpl::Watch(
- fidl::InterfaceHandle<fuchsia::modular::StoryProviderWatcher> watcher) {
- auto watcher_ptr = watcher.Bind();
- for (const auto& item : story_runtime_containers_) {
- const auto& container = item.second;
- watcher_ptr->OnChange(
- CloneStruct(container.current_data->story_info),
- *container.model_observer->model().runtime_state(),
- *container.model_observer->model().visibility_state());
- }
- watchers_.AddInterfacePtr(std::move(watcher_ptr));
-}
-
-// |fuchsia::modular::StoryProvider|
-void StoryProviderImpl::WatchActivity(
- fidl::InterfaceHandle<fuchsia::modular::StoryActivityWatcher> watcher) {
- auto watcher_ptr = watcher.Bind();
- for (const auto& item : story_runtime_containers_) {
- const auto& container = item.second;
- watcher_ptr->OnStoryActivityChange(
- *container.model_observer->model().name(),
- container.controller_impl->GetOngoingActivities());
- }
- activity_watchers_.AddInterfacePtr(std::move(watcher_ptr));
-}
-
-std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>>
-StoryProviderImpl::StartStoryShell(
- fidl::StringPtr story_id,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request) {
- MaybeLoadStoryShell();
-
- auto app_client = std::move(preloaded_story_shell_app_);
-
- // TODO(SCN-1019): This is a temporary hack to cache the endpoint ID of the
- // view so that framework can make snapshot requests.
- view_endpoints_[story_id] = fsl::GetKoid(request.channel().get());
-
- fuchsia::ui::viewsv1::ViewProviderPtr view_provider;
- app_client->services().ConnectToService(view_provider.NewRequest());
- view_provider->CreateView(std::move(request), nullptr);
-
- // Kickoff another fuchsia::modular::StoryShell, to make it faster for next
- // story. We optimize even further by delaying the loading of the next story
- // shell instance by waiting a few seconds.
- if (!test_) {
- MaybeLoadStoryShellDelayed();
- }
-
- return app_client;
-}
-
-void StoryProviderImpl::MaybeLoadStoryShellDelayed() {
-#if PREFETCH_MONDRIAN
- async::PostDelayedTask(
- async_get_default_dispatcher(),
- [weak_this = weak_factory_.GetWeakPtr()] {
- if (weak_this) {
- weak_this->operation_queue_.Add(new SyncCall([weak_this] {
- if (weak_this) {
- weak_this->MaybeLoadStoryShell();
- }
- }));
- }
- },
- zx::sec(5));
-#endif
-}
-
-void StoryProviderImpl::MaybeLoadStoryShell() {
- if (preloaded_story_shell_app_) {
- return;
- }
-
- preloaded_story_shell_app_ =
- std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- user_environment_->GetLauncher(), CloneStruct(story_shell_));
-}
-
-fuchsia::modular::StoryInfoPtr StoryProviderImpl::GetCachedStoryInfo(
- std::string story_id) {
- auto it = story_runtime_containers_.find(story_id);
- if (it == story_runtime_containers_.end()) {
- return nullptr;
- }
-
- return CloneOptional(it->second.current_data->story_info);
-}
-
-// |fuchsia::modular::StoryProvider|
-void StoryProviderImpl::GetStoryInfo(std::string story_id,
- GetStoryInfoCallback callback) {
- auto on_run = Future<>::Create("StoryProviderImpl.GetStoryInfo.on_run");
- auto done =
- on_run
- ->AsyncMap([this, story_id] {
- return session_storage_->GetStoryData(story_id);
- })
- ->Map([](fuchsia::modular::internal::StoryDataPtr story_data)
- -> fuchsia::modular::StoryInfoPtr {
- if (!story_data) {
- return nullptr;
- }
- return fidl::MakeOptional(std::move(story_data->story_info));
- });
- operation_queue_.Add(WrapFutureAsOperation("StoryProviderImpl::GetStoryInfo",
- on_run, done, callback));
-}
-
-// Called by StoryControllerImpl on behalf of ModuleContextImpl
-void StoryProviderImpl::RequestStoryFocus(fidl::StringPtr story_id) {
- FXL_LOG(INFO) << "RequestStoryFocus() " << story_id;
- focus_provider_->Request(story_id);
-}
-
-void StoryProviderImpl::AttachView(
- fidl::StringPtr story_id,
- fuchsia::ui::viewsv1token::ViewOwnerPtr view_owner) {
- FXL_CHECK(session_shell_);
- fuchsia::modular::ViewIdentifier view_id;
- view_id.story_id = std::move(story_id);
- session_shell_->AttachView(std::move(view_id), std::move(view_owner));
-}
-
-void StoryProviderImpl::DetachView(fidl::StringPtr story_id,
- std::function<void()> done) {
- FXL_CHECK(session_shell_);
- fuchsia::modular::ViewIdentifier view_id;
- view_id.story_id = std::move(story_id);
- session_shell_->DetachView(std::move(view_id), std::move(done));
-}
-
-void StoryProviderImpl::NotifyStoryStateChange(fidl::StringPtr story_id) {
- auto it = story_runtime_containers_.find(story_id);
- if (it == story_runtime_containers_.end()) {
- // If this call arrives while DeleteStory() is in
- // progress, the story controller might already be gone
- // from here.
- return;
- }
- NotifyStoryWatchers(it->second.current_data.get(),
- *it->second.model_observer->model().runtime_state(),
- *it->second.model_observer->model().visibility_state());
-}
-
-void StoryProviderImpl::NotifyStoryActivityChange(
- fidl::StringPtr story_id,
- fidl::VectorPtr<fuchsia::modular::OngoingActivityType> ongoing_activities) {
- for (const auto& i : activity_watchers_.ptrs()) {
- (*i)->OnStoryActivityChange(story_id, ongoing_activities.Clone());
- }
-}
-
-// |fuchsia::modular::StoryProvider|
-void StoryProviderImpl::GetController(
- std::string story_id,
- fidl::InterfaceRequest<fuchsia::modular::StoryController> request) {
- operation_queue_.Add(new LoadStoryRuntimeCall(
- this, session_storage_, story_id,
- fxl::MakeCopyable(
- [request = std::move(request)](
- StoryRuntimeContainer* story_controller_container) mutable {
- if (story_controller_container) {
- story_controller_container->controller_impl->Connect(
- std::move(request));
- }
- })));
-}
-
-// |fuchsia::modular::StoryProvider|
-void StoryProviderImpl::GetStories(
- fidl::InterfaceHandle<fuchsia::modular::StoryProviderWatcher> watcher,
- PreviousStoriesCallback callback) {
- auto watcher_ptr = watcher.Bind();
- auto on_run = Future<>::Create("StoryProviderImpl.GetStories.on_run");
- auto done =
- on_run->AsyncMap([this] { return session_storage_->GetAllStoryData(); })
- ->Map(fxl::MakeCopyable(
- [this, watcher_ptr = std::move(watcher_ptr)](
- std::vector<fuchsia::modular::internal::StoryData>
- all_story_data) mutable {
- std::vector<fuchsia::modular::StoryInfo> result;
-
- for (auto& story_data : all_story_data) {
- if (!story_data.story_options.kind_of_proto_story) {
- result.push_back(std::move(story_data.story_info));
- }
- }
-
- if (watcher_ptr) {
- watchers_.AddInterfacePtr(std::move(watcher_ptr));
- }
- return result;
- }));
-
- operation_queue_.Add(WrapFutureAsOperation("StoryProviderImpl::GetStories",
- on_run, done, callback));
-}
-
-// |fuchsia::modular::StoryProvider|
-void StoryProviderImpl::PreviousStories(PreviousStoriesCallback callback) {
- auto on_run = Future<>::Create("StoryProviderImpl.PreviousStories.on_run");
- auto done =
- on_run->AsyncMap([this] { return session_storage_->GetAllStoryData(); })
- ->Map([](std::vector<fuchsia::modular::internal::StoryData>
- all_story_data) {
- std::vector<fuchsia::modular::StoryInfo> result;
-
- for (auto& story_data : all_story_data) {
- if (!story_data.story_options.kind_of_proto_story) {
- result.push_back(std::move(story_data.story_info));
- }
- }
- return result;
- });
- operation_queue_.Add(WrapFutureAsOperation(
- "StoryProviderImpl::PreviousStories", on_run, done, callback));
-}
-
-void StoryProviderImpl::OnStoryStorageUpdated(
- fidl::StringPtr story_id,
- fuchsia::modular::internal::StoryData story_data) {
- // If we have a StoryRuntimeContainer for this story id, update our cached
- // StoryData and get runtime state available from it.
- //
- // Otherwise, use defaults for an unloaded story.
- fuchsia::modular::StoryState runtime_state = fuchsia::modular::StoryState::STOPPED;
- fuchsia::modular::StoryVisibilityState visibility_state =
- fuchsia::modular::StoryVisibilityState::DEFAULT;
- auto i = story_runtime_containers_.find(story_data.story_info.id);
- if (i != story_runtime_containers_.end()) {
- runtime_state = *i->second.model_observer->model().runtime_state();
- visibility_state = *i->second.model_observer->model().visibility_state();
- i->second.current_data = CloneOptional(story_data);
- }
- NotifyStoryWatchers(&story_data, runtime_state, visibility_state);
-}
-
-void StoryProviderImpl::OnStoryStorageDeleted(fidl::StringPtr story_id) {
- operation_queue_.Add(new StopStoryCall(
- story_id, false /* bulk */, &story_runtime_containers_,
- component_context_info_.message_queue_manager, [this, story_id] {
- for (const auto& i : watchers_.ptrs()) {
- (*i)->OnDelete(story_id);
- }
- }));
-}
-
-// |fuchsia::modular::FocusWatcher|
-void StoryProviderImpl::OnFocusChange(fuchsia::modular::FocusInfoPtr info) {
- operation_queue_.Add(
- new SyncCall(fxl::MakeCopyable([this, info = std::move(info)]() {
- if (info->device_id != device_id_) {
- return;
- }
-
- if (info->focused_story_id.is_null()) {
- return;
- }
-
- auto i = story_runtime_containers_.find(info->focused_story_id.get());
- if (i == story_runtime_containers_.end()) {
- FXL_LOG(ERROR) << "Story controller not found for focused story "
- << info->focused_story_id;
- return;
- }
-
- // Last focus time is recorded in the ledger, and story provider
- // watchers are notified through watching SessionStorage.
- auto on_run =
- Future<>::Create("StoryProviderImpl.OnFocusChange.on_run");
- auto done = on_run->AsyncMap([this, story_id = info->focused_story_id] {
- return session_storage_->UpdateLastFocusedTimestamp(
- story_id, zx_clock_get(ZX_CLOCK_UTC));
- });
- std::function<void()> callback = [] {};
- operation_queue_.Add(WrapFutureAsOperation(
- "StoryProviderImpl::OnFocusChange", on_run, done, callback));
- })));
-}
-
-void StoryProviderImpl::NotifyStoryWatchers(
- const fuchsia::modular::internal::StoryData* story_data,
- const fuchsia::modular::StoryState story_state,
- const fuchsia::modular::StoryVisibilityState story_visibility_state) {
- if (!story_data || story_data->story_options.kind_of_proto_story) {
- return;
- }
- for (const auto& i : watchers_.ptrs()) {
- (*i)->OnChange(CloneStruct(story_data->story_info), story_state,
- story_visibility_state);
- }
-}
-
-void StoryProviderImpl::CreateEntity(
- const std::string& story_id, fidl::StringPtr type,
- fuchsia::mem::Buffer data,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request,
- std::function<void(std::string /* entity_reference */)> callback) {
- operation_queue_.Add(new GetStoryEntityProviderCall(
- this, story_id,
- fxl::MakeCopyable([this, type, story_id, data = std::move(data),
- callback = std::move(callback),
- entity_request = std::move(entity_request)](
- StoryEntityProvider* entity_provider) mutable {
- // Once the entity provider for the given story is available, create
- // the entity.
- entity_provider->CreateEntity(
- type, std::move(data),
- fxl::MakeCopyable([this, entity_request = std::move(entity_request),
- callback = std::move(callback),
- story_id](std::string cookie) mutable {
- if (cookie.empty()) {
- // Return nullptr to indicate the entity creation failed.
- callback(nullptr);
- return;
- }
-
- std::string entity_reference =
- entity_provider_runner_->CreateStoryEntityReference(story_id,
- cookie);
-
- // Once the entity reference has been created, it can be
- // used to connect the entity request.
- fuchsia::modular::EntityResolverPtr resolver;
- entity_provider_runner_->ConnectEntityResolver(
- resolver.NewRequest());
- resolver->ResolveEntity(entity_reference,
- std::move(entity_request));
-
- callback(entity_reference);
- }));
- })));
-}
-
-void StoryProviderImpl::ConnectToStoryEntityProvider(
- const std::string& story_id,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request) {
- operation_queue_.Add(new GetStoryEntityProviderCall(
- this, story_id,
- fxl::MakeCopyable(
- [entity_provider_request = std::move(entity_provider_request)](
- StoryEntityProvider* entity_provider) mutable {
- entity_provider->Connect(std::move(entity_provider_request));
- })));
-}
-
-void StoryProviderImpl::GetPresentation(
- fidl::StringPtr story_id,
- fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request) {
- presentation_provider_->GetPresentation(std::move(story_id),
- std::move(request));
-}
-
-void StoryProviderImpl::WatchVisualState(
- fidl::StringPtr story_id,
- fidl::InterfaceHandle<fuchsia::modular::StoryVisualStateWatcher> watcher) {
- presentation_provider_->WatchVisualState(std::move(story_id),
- std::move(watcher));
-}
-
-void StoryProviderImpl::TakeSnapshot(
- fidl::StringPtr story_id,
- fit::function<void(fuchsia::mem::Buffer)> callback) {
- auto it = view_endpoints_.find(story_id);
- if (it != view_endpoints_.end()) {
- view_snapshot_->TakeSnapshot(it->second, [callback = std::move(callback)](
- fuchsia::mem::Buffer buffer) {
- callback(std::move(buffer));
- });
- } else {
- callback(fuchsia::mem::Buffer{});
- }
-}
-
-void StoryProviderImpl::StartSnapshotLoader(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- fidl::InterfaceRequest<fuchsia::scenic::snapshot::Loader> loader_request) {
- if (!snapshot_loader_app_) {
- fuchsia::modular::AppConfig snapshot_loader_config;
- snapshot_loader_config.url = kSnapshotLoaderUrl;
-
- snapshot_loader_app_ =
- std::make_unique<AppClient<fuchsia::modular::Lifecycle>>(
- user_environment_->GetLauncher(),
- std::move(snapshot_loader_config));
- }
-
- fuchsia::sys::ServiceProviderPtr service_provider;
- fuchsia::ui::viewsv1::ViewProviderPtr view_provider;
- snapshot_loader_app_->services().ConnectToService(view_provider.NewRequest());
- view_provider->CreateView(std::move(view_owner_request),
- service_provider.NewRequest());
-
- service_provider->ConnectToService(fuchsia::scenic::snapshot::Loader::Name_,
- loader_request.TakeChannel());
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/story_provider_impl.h b/bin/sessionmgr/story_runner/story_provider_impl.h
deleted file mode 100644
index e1b2ce4..0000000
--- a/bin/sessionmgr/story_runner/story_provider_impl.h
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_PROVIDER_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_PROVIDER_IMPL_H_
-
-#include <map>
-#include <memory>
-#include <set>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <fuchsia/scenic/snapshot/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner.h"
-#include "peridot/bin/sessionmgr/component_context_impl.h"
-#include "peridot/bin/sessionmgr/message_queue/message_queue_manager.h"
-#include "peridot/bin/sessionmgr/story/model/noop_story_model_storage.h"
-#include "peridot/bin/sessionmgr/story/model/story_model_owner.h"
-#include "peridot/bin/sessionmgr/story/system.h"
-#include "peridot/bin/sessionmgr/story_runner/story_entity_provider.h"
-#include "peridot/lib/fidl/app_client.h"
-#include "peridot/lib/fidl/environment.h"
-#include "peridot/lib/fidl/proxy.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/types.h"
-#include "peridot/lib/module_manifest/module_facet_reader.h"
-
-namespace modular {
-
-class PresentationProvider;
-class Resolver;
-class SessionStorage;
-class StoryControllerImpl;
-class StoryStorage;
-
-class StoryProviderImpl : fuchsia::modular::StoryProvider,
- fuchsia::modular::FocusWatcher {
- public:
- StoryProviderImpl(
- Environment* user_environment, std::string device_id,
- SessionStorage* session_storage, fuchsia::modular::AppConfig story_shell,
- const ComponentContextInfo& component_context_info,
- fuchsia::modular::FocusProviderPtr focus_provider,
- fuchsia::modular::UserIntelligenceProvider* user_intelligence_provider,
- fuchsia::modular::ModuleResolver* module_resolver,
- EntityProviderRunner* entity_provider_runner,
- modular::ModuleFacetReader* module_facet_reader,
- PresentationProvider* presentation_provider,
- fuchsia::ui::viewsv1::ViewSnapshotPtr view_snapshot, bool test);
-
- ~StoryProviderImpl() override;
-
- void Connect(fidl::InterfaceRequest<fuchsia::modular::StoryProvider> request);
-
- // Used when the session shell is swapped.
- void StopAllStories(const std::function<void()>& callback);
-
- // The session shell to send story views to. It is not a constructor argument
- // because it is updated when the session shell is swapped.
- void SetSessionShell(fuchsia::modular::SessionShellPtr session_shell);
-
- // Stops serving the fuchsia::modular::StoryProvider interface and stops all
- // stories.
- void Teardown(const std::function<void()>& callback);
-
- // Called by StoryControllerImpl.
- const Environment* user_environment() const { return user_environment_; }
-
- // The device ID for this user/device.
- const std::string device_id() const { return device_id_; }
-
- // Called by StoryControllerImpl.
- const ComponentContextInfo& component_context_info() {
- return component_context_info_;
- }
-
- // Called by StoryControllerImpl.
- fuchsia::modular::UserIntelligenceProvider* user_intelligence_provider() {
- return user_intelligence_provider_;
- }
-
- // Called by StoryControllerImpl.
- fuchsia::modular::ModuleResolver* module_resolver() {
- return module_resolver_;
- }
-
- fuchsia::modular::EntityResolver* entity_resolver() {
- return entity_provider_runner_;
- }
-
- modular::ModuleFacetReader* module_facet_reader() {
- return module_facet_reader_;
- }
-
- // Called by StoryControllerImpl.
- const fuchsia::modular::AppConfig& story_shell() const {
- return story_shell_;
- }
-
- // Called by StoryControllerImpl.
- //
- // Returns an AppClient rather than taking an interface request
- // as an argument because the application is preloaded.
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> StartStoryShell(
- fidl::StringPtr story_id,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request);
-
- // Called by StoryControllerImpl.
- //
- // Returns nullptr if the StoryInfo for |story_id| is not cached.
- fuchsia::modular::StoryInfoPtr GetCachedStoryInfo(std::string story_id);
-
- // |fuchsia::modular::StoryProvider|.
- void GetStoryInfo(std::string story_id,
- GetStoryInfoCallback callback) override;
-
- // Called by StoryControllerImpl. Sends request to
- // fuchsia::modular::FocusProvider
- void RequestStoryFocus(fidl::StringPtr story_id);
-
- // Called by StoryControllerImpl. Sends, using AttachView(), the view of the
- // story identified by |story_id| to the current session shell.
- void AttachView(fidl::StringPtr story_id,
- fuchsia::ui::viewsv1token::ViewOwnerPtr view_owner);
-
- // Called by StoryControllerImpl. Notifies, using DetachView(), the current
- // session shell that the view of the story identified by |story_id| is about
- // to close.
- void DetachView(fidl::StringPtr story_id, std::function<void()> done);
-
- // Called by StoryControllerImpl.
- void NotifyStoryActivityChange(
- fidl::StringPtr story_id,
- fidl::VectorPtr<fuchsia::modular::OngoingActivityType>
- ongoing_activities);
-
- // Called by StoryControllerImpl. Sends request to
- // fuchsia::modular::SessionShell through PresentationProvider.
- void GetPresentation(
- fidl::StringPtr story_id,
- fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request);
- void WatchVisualState(
- fidl::StringPtr story_id,
- fidl::InterfaceHandle<fuchsia::modular::StoryVisualStateWatcher> watcher);
-
- // Called by StoryControllerImpl. Takes a snapshot of the story by the given
- // |story_id|. Callback is returned with the snapshot of the story, or an
- // empty buffer (size == 0) if the snapshot could not be taken.
- void TakeSnapshot(fidl::StringPtr story_id,
- fit::function<void(fuchsia::mem::Buffer)> callback);
-
- // Called by StoryControllerImpl. Creates a new view with the given
- // |view_owner_request| and connects the snapshot loader with the given
- // |loader_request|.
- void StartSnapshotLoader(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- fidl::InterfaceRequest<fuchsia::scenic::snapshot::Loader> loader_request);
-
- // Creates an entity with the specified |type| and |data| in the story with
- // |story_id|.
- //
- // |callback| will be called with a reference to the created entity. If the
- // creation failed the |entity_request| is dropped.
- void CreateEntity(
- const std::string& story_id, fidl::StringPtr type,
- fuchsia::mem::Buffer data,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request,
- std::function<void(std::string /* entity_reference */)> callback);
-
- // Creates an entity with the specified |type| and |data| in the story with
- // |story_id|.
- //
- // The story provider guarantees the uniqueness of the EntityProvider
- // associated with any given story.
- void ConnectToStoryEntityProvider(
- const std::string& story_id,
- fidl::InterfaceRequest<fuchsia::modular::EntityProvider>
- entity_provider_request);
-
- private:
- // |fuchsia::modular::StoryProvider|
- void GetController(std::string story_id,
- fidl::InterfaceRequest<fuchsia::modular::StoryController>
- request) override;
-
- // |fuchsia::modular::StoryProvider|
- void GetStories(
- fidl::InterfaceHandle<fuchsia::modular::StoryProviderWatcher> watcher,
- PreviousStoriesCallback callback) override;
-
- // |fuchsia::modular::StoryProvider|
- void PreviousStories(PreviousStoriesCallback callback) override;
-
- // |fuchsia::modular::StoryProvider|
- void Watch(fidl::InterfaceHandle<fuchsia::modular::StoryProviderWatcher>
- watcher) override;
-
- // |fuchsia::modular::StoryProvider|
- void WatchActivity(
- fidl::InterfaceHandle<fuchsia::modular::StoryActivityWatcher> watcher)
- override;
-
- // |fuchsia::modular::FocusWatcher|
- void OnFocusChange(fuchsia::modular::FocusInfoPtr info) override;
-
- // Called by *session_storage_.
- void OnStoryStorageDeleted(fidl::StringPtr story_id);
- void OnStoryStorageUpdated(fidl::StringPtr story_id,
- fuchsia::modular::internal::StoryData story_data);
-
- // Called indirectly through observation of loaded StoryModels. Calls
- // NotifyStoryWatchers().
- void NotifyStoryStateChange(fidl::StringPtr story_id);
-
- void NotifyStoryWatchers(
- const fuchsia::modular::internal::StoryData* story_data,
- fuchsia::modular::StoryState story_state,
- fuchsia::modular::StoryVisibilityState story_visibility_state);
-
- void MaybeLoadStoryShell();
-
- void MaybeLoadStoryShellDelayed();
-
- Environment* const user_environment_;
-
- SessionStorage* session_storage_; // Not owned.
-
- // The service from the session shell run by the sessionmgr. Owned here
- // because only used from here.
- fuchsia::modular::SessionShellPtr session_shell_;
-
- // Unique ID generated for this user/device combination.
- const std::string device_id_;
-
- // The bindings for this instance.
- fidl::BindingSet<fuchsia::modular::StoryProvider> bindings_;
-
- // Used to preload story shell before it is requested.
- fuchsia::modular::AppConfig story_shell_;
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>>
- preloaded_story_shell_app_;
-
- // When running in a test, we don't preload story shells, because then the
- // preloaded next instance of the story doesn't pass its test points.
- const bool test_;
-
- fidl::InterfacePtrSet<fuchsia::modular::StoryProviderWatcher> watchers_;
- fidl::InterfacePtrSet<fuchsia::modular::StoryActivityWatcher>
- activity_watchers_;
-
- // The story controllers of the currently active stories, indexed by their
- // story IDs.
- //
- // Only user logout or delete story calls ever remove story controllers from
- // this collection, but controllers for stopped stories stay in it.
- //
- // Also keeps a cached version of the StoryData for every story so it does
- // not have to be loaded from disk when querying about this story.
- struct StoryRuntimeContainer {
- // The executor on which asynchronous tasks are scheduled for this story.
- //
- // TODO(thatguy): Migrate all operations under |controller_impl| to use
- // fit::promise and |executor|. MF-117
- // TODO(thatguy): Once fit::scope is complete, share one executor for the
- // whole process and take advantage of fit::scope to auto-cancel tasks when
- // |this| dies.
- std::unique_ptr<fit::executor> executor;
-
- // StoryRuntime itself contains a StoryModelOwner and manages systems with
- // asynchronous initialization and teardown operations.
- std::unique_ptr<StoryModelOwner> model_owner;
-
- // For ease of memory management, we store all runtime systems in
- // |systems|.
- std::vector<std::unique_ptr<System>> systems;
-
- // This allows us to observe changes to the StoryModel owned by |runtime|.
- std::unique_ptr<StoryObserver> model_observer;
-
- // NOTE: The following are transitioning to StoryModel and associated
- // classes above, as outlined in MF-85.
- std::unique_ptr<StoryControllerImpl> controller_impl;
- std::unique_ptr<StoryStorage> storage;
- std::unique_ptr<StoryEntityProvider> entity_provider;
- fuchsia::modular::internal::StoryDataPtr current_data;
- };
- std::map<std::string, StoryRuntimeContainer> story_runtime_containers_;
-
- const ComponentContextInfo component_context_info_;
-
- fuchsia::modular::UserIntelligenceProvider* const
- user_intelligence_provider_; // Not owned.
- fuchsia::modular::ModuleResolver* const module_resolver_; // Not owned.
- EntityProviderRunner* const entity_provider_runner_; // Not owned.
- modular::ModuleFacetReader* const module_facet_reader_; // Not owned.
- PresentationProvider* const presentation_provider_; // Not owned.
-
- // When a story gets created, or when it gets focused on this device, we write
- // a record of the current context in the story page. So we need to watch the
- // context and the focus. This serves to compute relative importance of
- // stories in the timeline, as determined by the current context.
- fuchsia::modular::FocusProviderPtr focus_provider_;
- fidl::Binding<fuchsia::modular::FocusWatcher> focus_watcher_binding_;
-
- // Service provided by scenic to take snapshots of stories.
- fuchsia::ui::viewsv1::ViewSnapshotPtr view_snapshot_;
-
- // Cached mapping of story ID's to the story view koids. Used as a token to
- // take snapshots of stories. This is a temporary hack because koids are
- // guessable. The intention is to have this hack until the framework is
- // provided with a more secure API from scenic to take snapshots, which is
- // TBD.
- std::map<fidl::StringPtr, zx_koid_t> view_endpoints_;
-
- // Snapshot loader component which is used to create new snapshot views. There
- // is only one instance of this component running per session.
- std::unique_ptr<AppClient<fuchsia::modular::Lifecycle>> snapshot_loader_app_;
-
- // This is a container of all operations that are currently enqueued to run in
- // a FIFO manner. All operations exposed via |fuchsia::modular::StoryProvider|
- // interface are queued here.
- //
- // The advantage of doing this is that if an operation consists of multiple
- // asynchronous calls then no state needs to be maintained for incomplete /
- // pending operations.
- //
- // TODO(mesch): If a story provider operation invokes a story operation that
- // causes the story updating its story info state, that update operation gets
- // scheduled on this queue again, after the current operation. It would be
- // better to be able to schedule such an operation on the story queue because
- // it's a per story operation even if it affects the per story key in the root
- // page, and then the update of story info is bounded by the outer operation.
- OperationQueue operation_queue_;
-
- fxl::WeakPtrFactory<StoryProviderImpl> weak_factory_;
-
- // Operations implemented here.
- class LoadStoryRuntimeCall;
- class StopStoryCall;
- class StopAllStoriesCall;
- class StopStoryShellCall;
- class GetStoryEntityProviderCall;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryProviderImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_PROVIDER_IMPL_H_
diff --git a/bin/sessionmgr/story_runner/story_shell_context_impl.cc b/bin/sessionmgr/story_runner/story_shell_context_impl.cc
deleted file mode 100644
index 83d5cdc..0000000
--- a/bin/sessionmgr/story_runner/story_shell_context_impl.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/story_runner/story_shell_context_impl.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/sessionmgr/story_runner/story_controller_impl.h"
-#include "peridot/bin/sessionmgr/story_runner/story_provider_impl.h"
-
-namespace modular {
-
-namespace {
-
-constexpr char kStoryShellLinkName[] = "story-shell-link";
-
-}; // namespace
-
-StoryShellContextImpl::StoryShellContextImpl(
- fidl::StringPtr story_id, StoryProviderImpl* const story_provider_impl,
- StoryControllerImpl* const story_controller_impl)
- : story_id_(story_id),
- story_provider_impl_(story_provider_impl),
- story_controller_impl_(story_controller_impl) {}
-
-StoryShellContextImpl::~StoryShellContextImpl() = default;
-
-void StoryShellContextImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::StoryShellContext> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void StoryShellContextImpl::GetPresentation(
- fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request) {
- story_provider_impl_->GetPresentation(story_id_, std::move(request));
-}
-
-void StoryShellContextImpl::WatchVisualState(
- fidl::InterfaceHandle<fuchsia::modular::StoryVisualStateWatcher> watcher) {
- story_provider_impl_->WatchVisualState(story_id_, std::move(watcher));
-}
-
-void StoryShellContextImpl::GetLink(
- fidl::InterfaceRequest<fuchsia::modular::Link> request) {
- fuchsia::modular::LinkPathPtr link_path = fuchsia::modular::LinkPath::New();
- link_path->module_path.resize(0);
- // Note: This will never clash with link references for links owned by
- // modules, because those will have a non-empty module path.
- link_path->link_name = kStoryShellLinkName;
- story_controller_impl_->ConnectLinkPath(std::move(link_path),
- std::move(request));
-}
-
-void StoryShellContextImpl::RequestView(std::string surface_id) {}
-
-void StoryShellContextImpl::OnSurfaceOffScreen(std::string surface_id) {}
-
-} // namespace modular
diff --git a/bin/sessionmgr/story_runner/story_shell_context_impl.h b/bin/sessionmgr/story_runner/story_shell_context_impl.h
deleted file mode 100644
index 7fa4099..0000000
--- a/bin/sessionmgr/story_runner/story_shell_context_impl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_SHELL_CONTEXT_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_SHELL_CONTEXT_IMPL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/string.h>
-
-namespace modular {
-
-class StoryControllerImpl;
-class StoryProviderImpl;
-
-class StoryShellContextImpl : fuchsia::modular::StoryShellContext {
- public:
- StoryShellContextImpl(fidl::StringPtr story_id,
- StoryProviderImpl* story_provider_impl,
- StoryControllerImpl* story_controller_impl);
- ~StoryShellContextImpl() override;
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::StoryShellContext> request);
-
- private:
- // |fuchsia::modular::StoryShellContext|
- void GetPresentation(fidl::InterfaceRequest<fuchsia::ui::policy::Presentation>
- request) override;
- void WatchVisualState(
- fidl::InterfaceHandle<fuchsia::modular::StoryVisualStateWatcher> watcher)
- override;
- void GetLink(fidl::InterfaceRequest<fuchsia::modular::Link> request) override;
- void RequestView(std::string surface_id) override;
- void OnSurfaceOffScreen(std::string surface_id) override;
-
- const fidl::StringPtr story_id_;
- // Not owned. The StoryProviderImpl corresponding to this context.
- StoryProviderImpl* const story_provider_impl_;
- // Not owned. The StoryControllerImpl for the Story corresponding to this
- // context.
- StoryControllerImpl* const story_controller_impl_;
-
- fidl::BindingSet<fuchsia::modular::StoryShellContext> bindings_;
-};
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_STORY_RUNNER_STORY_SHELL_CONTEXT_IMPL_H_
diff --git a/bin/sessionmgr/user_intelligence_provider_impl.cc b/bin/sessionmgr/user_intelligence_provider_impl.cc
deleted file mode 100644
index 7a99a00..0000000
--- a/bin/sessionmgr/user_intelligence_provider_impl.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/sessionmgr/user_intelligence_provider_impl.h"
-
-#include <fuchsia/bluetooth/le/cpp/fidl.h>
-#include <fuchsia/cobalt/cpp/fidl.h>
-#include <fuchsia/maxwell/internal/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/bin/basemgr/cobalt/cobalt.h"
-#include "peridot/bin/sessionmgr/intelligence_services_impl.h"
-
-namespace modular {
-
-namespace {
-
-constexpr char kUsageLogUrl[] =
- "fuchsia-pkg://fuchsia.com/usage_log#meta/usage_log.cmx";
-constexpr char kKronkUrl[] = "kronk";
-constexpr char kStoryInfoAgentUrl[] =
- "fuchsia-pkg://fuchsia.com/story_info#meta/story_info.cmx";
-static constexpr modular::RateLimitedRetry::Threshold kSessionAgentRetryLimit =
- {3, zx::sec(45)};
-
-fuchsia::modular::ComponentScope CloneScope(
- const fuchsia::modular::ComponentScope& scope) {
- fuchsia::modular::ComponentScope result;
- fidl::Clone(scope, &result);
- return result;
-}
-
-} // namespace
-
-template <class Interface>
-UserIntelligenceProviderImpl::SessionAgentData::DeferredInterfaceRequest::
- DeferredInterfaceRequest(fidl::InterfaceRequest<Interface> request)
- : name(Interface::Name_), channel(request.TakeChannel()) {}
-
-UserIntelligenceProviderImpl::SessionAgentData::SessionAgentData()
- : restart(kSessionAgentRetryLimit) {}
-
-template <class Interface>
-void UserIntelligenceProviderImpl::SessionAgentData::
- ConnectOrQueueServiceRequest(fidl::InterfaceRequest<Interface> request) {
- if (services) {
- component::ConnectToService(services.get(), std::move(request));
- } else {
- pending_service_requests.emplace_back(std::move(request));
- }
-}
-
-UserIntelligenceProviderImpl::UserIntelligenceProviderImpl(
- component::StartupContext* const context,
- fidl::InterfaceHandle<fuchsia::modular::ContextEngine>
- context_engine_handle,
- fit::function<
- void(fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesProvider>)>
- visible_stories_provider_connector,
- fit::function<void(fidl::InterfaceRequest<fuchsia::modular::StoryProvider>)>
- story_provider_connector,
- fit::function<void(fidl::InterfaceRequest<fuchsia::modular::FocusProvider>)>
- focus_provider_connector,
- fit::function<void(fidl::InterfaceRequest<fuchsia::modular::PuppetMaster>)>
- puppet_master_connector)
- : context_(context),
- visible_stories_provider_connector_(
- std::move(visible_stories_provider_connector)),
- story_provider_connector_(std::move(story_provider_connector)),
- focus_provider_connector_(std::move(focus_provider_connector)),
- puppet_master_connector_(std::move(puppet_master_connector)) {
- context_engine_.Bind(std::move(context_engine_handle));
-
- // Start dependent processes. We get some component-scope services from
- // these processes.
- StartSuggestionEngine();
-}
-
-void UserIntelligenceProviderImpl::GetComponentIntelligenceServices(
- fuchsia::modular::ComponentScope scope,
- fidl::InterfaceRequest<fuchsia::modular::IntelligenceServices> request) {
- intelligence_services_bindings_.AddBinding(
- std::make_unique<IntelligenceServicesImpl>(
- std::move(scope), context_engine_.get(), suggestion_engine_.get()),
- std::move(request));
-}
-
-void UserIntelligenceProviderImpl::GetSuggestionProvider(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionProvider> request) {
- suggestion_services_.ConnectToService(std::move(request));
-}
-
-void UserIntelligenceProviderImpl::GetSpeechToText(
- fidl::InterfaceRequest<fuchsia::speech::SpeechToText> request) {
- auto it = session_agents_.find(kKronkUrl);
- if (it != session_agents_.end()) {
- it->second.ConnectOrQueueServiceRequest(std::move(request));
- } else {
- FXL_LOG(WARNING) << "No speech-to-text agent loaded";
- }
-}
-
-void UserIntelligenceProviderImpl::StartAgents(
- fidl::InterfaceHandle<fuchsia::modular::ComponentContext>
- component_context_handle,
- std::vector<std::string> session_agents,
- std::vector<std::string> startup_agents) {
- component_context_.Bind(std::move(component_context_handle));
-
- FXL_LOG(INFO) << "Starting session_agents:";
- for (const auto& agent : session_agents) {
- FXL_LOG(INFO) << " " << agent;
- StartSessionAgent(agent);
- }
-
- FXL_LOG(INFO) << "Starting startup_agents:";
- for (const auto& agent : startup_agents) {
- FXL_LOG(INFO) << " " << agent;
- StartAgent(agent);
- }
-
- StartAgent(kStoryInfoAgentUrl);
-}
-
-void UserIntelligenceProviderImpl::GetServicesForAgent(
- std::string url, GetServicesForAgentCallback callback) {
- fuchsia::sys::ServiceList service_list;
- agent_namespaces_.emplace_back(service_list.provider.NewRequest());
- auto* agent_host = &agent_namespaces_.back();
- service_list.names = AddAgentServices(url, agent_host);
- callback(std::move(service_list));
-}
-
-void UserIntelligenceProviderImpl::StartSuggestionEngine() {
- auto service_list = fuchsia::sys::ServiceList::New();
-
- service_list->names.push_back(fuchsia::modular::ContextReader::Name_);
- suggestion_engine_service_provider_
- .AddService<fuchsia::modular::ContextReader>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) {
- fuchsia::modular::ComponentScope scope;
- scope.set_global_scope(fuchsia::modular::GlobalScope());
- context_engine_->GetReader(std::move(scope), std::move(request));
- });
-
- service_list->names.push_back(fuchsia::modular::PuppetMaster::Name_);
- suggestion_engine_service_provider_
- .AddService<fuchsia::modular::PuppetMaster>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::PuppetMaster> request) {
- puppet_master_connector_(std::move(request));
- });
-
- fuchsia::sys::ServiceProviderPtr service_provider;
- suggestion_engine_service_provider_.AddBinding(service_provider.NewRequest());
- service_list->provider = std::move(service_provider);
-
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = "fuchsia-pkg://fuchsia.com/suggestion_engine#meta/suggestion_engine.cmx";
- launch_info.directory_request = suggestion_services_.NewRequest();
- launch_info.additional_services = std::move(service_list);
- context_->launcher()->CreateComponent(std::move(launch_info), nullptr);
- suggestion_engine_ =
- suggestion_services_
- .ConnectToService<fuchsia::modular::SuggestionEngine>();
-}
-
-void UserIntelligenceProviderImpl::StartAgent(const std::string& url) {
- fuchsia::modular::AgentControllerPtr controller;
- fuchsia::sys::ServiceProviderPtr services;
- component_context_->ConnectToAgent(url, services.NewRequest(),
- controller.NewRequest());
- agent_controllers_.push_back(std::move(controller));
-}
-
-void UserIntelligenceProviderImpl::StartSessionAgent(const std::string& url) {
- SessionAgentData* const agent_data = &session_agents_[url];
-
- component_context_->ConnectToAgent(url, agent_data->services.NewRequest(),
- agent_data->controller.NewRequest());
-
- // complete any pending connection requests
- for (auto& request : agent_data->pending_service_requests) {
- agent_data->services->ConnectToService(request.name,
- std::move(request.channel));
- }
- agent_data->pending_service_requests.clear();
-
- // fuchsia::modular::Agent runner closes the agent controller connection when
- // the agent terminates. We restart the agent (up to a limit) when we notice
- // this.
- //
- // NOTE(rosswang,mesch): Although the interface we're actually interested in
- // is |data[url].services|, we still need to put the restart handler on the
- // controller. When the agent crashes, |data[url].services| often gets closed
- // quite a bit earlier (~1 second) than the agent runner notices via the
- // application controller (which it must use as opposed to any interface on
- // the agent itself since the agent is not required to implement any
- // interfaces itself, even though it is recommended that it does). If we try
- // to restart the agent at that time, the agent runner would attempt to simply
- // send the connection request to the crashed agent instance and not relaunch
- // the agent.
- //
- // It is also because of this delay that we must queue any pending service
- // connection requests until we can restart.
- agent_data->controller.set_error_handler([this, url](zx_status_t status) {
- auto it = session_agents_.find(url);
- FXL_DCHECK(it != session_agents_.end())
- << "Controller and services not registered for " << url;
- auto& agent_data = it->second;
- agent_data.services.Unbind();
- agent_data.controller.Unbind();
- ReportSessionAgentEvent(url, SessionAgentEvent::CRASH);
-
- if (agent_data.restart.ShouldRetry()) {
- FXL_LOG(INFO) << "Restarting " << url << "...";
- StartSessionAgent(url);
- } else {
- FXL_LOG(WARNING) << url << " failed to restart more than "
- << kSessionAgentRetryLimit.count << " times in "
- << kSessionAgentRetryLimit.period.to_secs()
- << " seconds.";
- ReportSessionAgentEvent(url, SessionAgentEvent::CRASH_LIMIT);
- // Erase so that incoming connection requests fail fast rather than
- // enqueue forever.
- session_agents_.erase(it);
- }
- });
-}
-
-std::vector<std::string> UserIntelligenceProviderImpl::AddAgentServices(
- const std::string& url, component::ServiceNamespace* agent_host) {
- fuchsia::modular::ComponentScope agent_info;
- fuchsia::modular::AgentScope agent_scope;
- agent_scope.url = url;
- agent_info.set_agent_scope(std::move(agent_scope));
- std::vector<std::string> service_names;
-
- service_names.push_back(fuchsia::modular::ContextWriter::Name_);
- agent_host->AddService<fuchsia::modular::ContextWriter>(fxl::MakeCopyable(
- [this, client_info = CloneScope(agent_info),
- url](fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request) {
- context_engine_->GetWriter(CloneScope(client_info), std::move(request));
- }));
-
- service_names.push_back(fuchsia::modular::ContextReader::Name_);
- agent_host->AddService<fuchsia::modular::ContextReader>(fxl::MakeCopyable(
- [this, client_info = CloneScope(agent_info),
- url](fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) {
- context_engine_->GetReader(CloneScope(client_info), std::move(request));
- }));
-
- service_names.push_back(fuchsia::modular::IntelligenceServices::Name_);
- agent_host->AddService<fuchsia::modular::IntelligenceServices>(
- fxl::MakeCopyable(
- [this, client_info = CloneScope(agent_info),
- url](fidl::InterfaceRequest<fuchsia::modular::IntelligenceServices>
- request) {
- this->GetComponentIntelligenceServices(CloneScope(client_info),
- std::move(request));
- }));
-
- service_names.push_back(fuchsia::modular::ProposalPublisher::Name_);
- agent_host->AddService<fuchsia::modular::ProposalPublisher>(
- [this, url](
- fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher> request) {
- suggestion_engine_->RegisterProposalPublisher(url, std::move(request));
- });
-
- if (url == kUsageLogUrl) {
- service_names.push_back(fuchsia::modular::ContextDebug::Name_);
- agent_host->AddService<fuchsia::modular::ContextDebug>(
- [this](fidl::InterfaceRequest<fuchsia::modular::ContextDebug> request) {
- context_engine_->GetContextDebug(std::move(request));
- });
-
- service_names.push_back(fuchsia::modular::SuggestionDebug::Name_);
- agent_host->AddService<fuchsia::modular::SuggestionDebug>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::SuggestionDebug> request) {
- suggestion_services_.ConnectToService(std::move(request));
- });
- }
-
- if (url == kStoryInfoAgentUrl) {
- service_names.push_back(fuchsia::modular::VisibleStoriesProvider::Name_);
- agent_host->AddService<fuchsia::modular::VisibleStoriesProvider>(
- [this](fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesProvider>
- request) {
- visible_stories_provider_connector_(std::move(request));
- });
-
- service_names.push_back(fuchsia::modular::StoryProvider::Name_);
- agent_host->AddService<fuchsia::modular::StoryProvider>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::StoryProvider> request) {
- story_provider_connector_(std::move(request));
- });
-
- service_names.push_back(fuchsia::modular::FocusProvider::Name_);
- agent_host->AddService<fuchsia::modular::FocusProvider>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::FocusProvider> request) {
- focus_provider_connector_(std::move(request));
- });
- }
-
- if (session_agents_.find(url) != session_agents_.end()) {
- // All services added below should be exclusive to session agents.
- service_names.push_back(fuchsia::modular::PuppetMaster::Name_);
- agent_host->AddService<fuchsia::modular::PuppetMaster>(
- [this](fidl::InterfaceRequest<fuchsia::modular::PuppetMaster> request) {
- puppet_master_connector_(std::move(request));
- });
-
- service_names.push_back(fuchsia::modular::FocusProvider::Name_);
- agent_host->AddService<fuchsia::modular::FocusProvider>(
- [this,
- url](fidl::InterfaceRequest<fuchsia::modular::FocusProvider> request) {
- focus_provider_connector_(std::move(request));
- });
- }
-
- return service_names;
-}
-
-} // namespace modular
diff --git a/bin/sessionmgr/user_intelligence_provider_impl.h b/bin/sessionmgr/user_intelligence_provider_impl.h
deleted file mode 100644
index cbf6779..0000000
--- a/bin/sessionmgr/user_intelligence_provider_impl.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SESSIONMGR_USER_INTELLIGENCE_PROVIDER_IMPL_H_
-#define PERIDOT_BIN_SESSIONMGR_USER_INTELLIGENCE_PROVIDER_IMPL_H_
-
-#include <deque>
-#include <string>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/svc/cpp/services.h>
-#include <lib/zx/channel.h>
-
-#include "peridot/lib/util/rate_limited_retry.h"
-
-namespace modular {
-
-class UserIntelligenceProviderImpl
- : public fuchsia::modular::UserIntelligenceProvider {
- public:
- // |context| is not owned and must outlive this instance.
- UserIntelligenceProviderImpl(
- component::StartupContext* context,
- fidl::InterfaceHandle<fuchsia::modular::ContextEngine>
- context_engine_handle,
- fit::function<void(
- fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesProvider>)>
- visible_stories_provider_connector,
- fit::function<
- void(fidl::InterfaceRequest<fuchsia::modular::StoryProvider>)>
- story_provider_connector,
- fit::function<
- void(fidl::InterfaceRequest<fuchsia::modular::FocusProvider>)>
- focus_provider_connector,
- fit::function<
- void(fidl::InterfaceRequest<fuchsia::modular::PuppetMaster>)>
- puppet_master_connector);
-
- ~UserIntelligenceProviderImpl() override = default;
-
- void GetComponentIntelligenceServices(
- fuchsia::modular::ComponentScope scope,
- fidl::InterfaceRequest<fuchsia::modular::IntelligenceServices> request)
- override;
-
- void GetSuggestionProvider(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionProvider> request)
- override;
-
- void GetSpeechToText(
- fidl::InterfaceRequest<fuchsia::speech::SpeechToText> request) override;
-
- void StartAgents(fidl::InterfaceHandle<fuchsia::modular::ComponentContext>
- component_context_handle,
- std::vector<std::string> session_agents,
- std::vector<std::string> startup_agents) override;
-
- void GetServicesForAgent(std::string url,
- GetServicesForAgentCallback callback) override;
-
- private:
- struct SessionAgentData {
- struct DeferredInterfaceRequest {
- template <class Interface>
- DeferredInterfaceRequest(fidl::InterfaceRequest<Interface> request);
-
- const char* name;
- zx::channel channel;
- };
-
- SessionAgentData();
-
- template <class Interface>
- void ConnectOrQueueServiceRequest(
- fidl::InterfaceRequest<Interface> request);
-
- fuchsia::modular::AgentControllerPtr controller;
-
- fuchsia::sys::ServiceProviderPtr services;
- // If an agent crashes, there is a period (~1 sec) where its |services|
- // interface is invalid before its controller is closed. During that
- // period, we should queue requests until we've restarted the agent.
- std::vector<DeferredInterfaceRequest> pending_service_requests;
-
- modular::RateLimitedRetry restart;
- };
-
- using ServiceProviderInitializer = std::function<void(
- const std::string& url, component::ServiceNamespace* agent_host)>;
- // A ServiceProviderInitializer that adds standard agent services, including
- // attributed context and suggestion service entry points. Returns the names
- // of the services added.
- std::vector<std::string> AddAgentServices(
- const std::string& url, component::ServiceNamespace* agent_host);
-
- // Starts suggestion engine.
- void StartSuggestionEngine();
-
- void StartAgent(const std::string& url);
-
- void StartActionLog(fuchsia::modular::SuggestionEngine* suggestion_engine);
- void StartSessionAgent(const std::string& url);
-
- component::StartupContext* context_; // Not owned.
-
- fuchsia::modular::ContextEnginePtr context_engine_;
-
- component::Services suggestion_services_;
- component::ServiceProviderImpl suggestion_engine_service_provider_;
- fuchsia::modular::SuggestionEnginePtr suggestion_engine_;
-
- std::map<std::string, SessionAgentData> session_agents_;
-
- fidl::BindingSet<fuchsia::modular::IntelligenceServices,
- std::unique_ptr<fuchsia::modular::IntelligenceServices>>
- intelligence_services_bindings_;
-
- fidl::InterfacePtr<fuchsia::modular::ComponentContext> component_context_;
- fidl::InterfacePtr<fuchsia::modular::StoryProvider> story_provider_;
- fidl::InterfacePtr<fuchsia::modular::FocusProvider> focus_provider_;
- fidl::InterfacePtr<fuchsia::modular::VisibleStoriesProvider>
- visible_stories_provider_;
-
- fit::function<void(
- fidl::InterfaceRequest<fuchsia::modular::VisibleStoriesProvider>)>
- visible_stories_provider_connector_;
- fit::function<void(fidl::InterfaceRequest<fuchsia::modular::StoryProvider>)>
- story_provider_connector_;
- fit::function<void(fidl::InterfaceRequest<fuchsia::modular::FocusProvider>)>
- focus_provider_connector_;
- fit::function<void(fidl::InterfaceRequest<fuchsia::modular::PuppetMaster>)>
- puppet_master_connector_;
-
- // Framework fuchsia::modular::Agent controllers. Hanging onto these tells the
- // Framework we want the Agents to keep running.
- std::vector<fuchsia::modular::AgentControllerPtr> agent_controllers_;
-
- // ServiceNamespace(s) backing the services provided to these agents via its
- // namespace.
- std::deque<component::ServiceNamespace> agent_namespaces_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SESSIONMGR_USER_INTELLIGENCE_PROVIDER_IMPL_H_
diff --git a/bin/suggestion_engine/BUILD.gn b/bin/suggestion_engine/BUILD.gn
deleted file mode 100644
index bbf2ae8..0000000
--- a/bin/suggestion_engine/BUILD.gn
+++ /dev/null
@@ -1,184 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-import("//peridot/build/tests_package.gni")
-
-executable_package("suggestion_engine") {
- meta = [
- {
- path = "meta/suggestion_engine.cmx"
- dest = "suggestion_engine.cmx"
- },
- ]
-
- resources = [
- {
- path = "resources/mod_pairs.json"
- dest = "ranking_data/mod_pairs.json"
- },
- ]
-
- sources = [
- "suggestion_engine_main.cc",
- ]
-
- deps = [
- ":debug",
- ":suggestion_engine_impl",
- "//garnet/public/lib/component/cpp",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-source_set("suggestion_engine_impl") {
- sources = [
- "media_player.cc",
- "media_player.h",
- "navigation_processor.cc",
- "navigation_processor.h",
- "next_processor.cc",
- "next_processor.h",
- "proposal_publisher_impl.cc",
- "proposal_publisher_impl.h",
- "query_processor.cc",
- "query_processor.h",
- "query_runner.cc",
- "query_runner.h",
- "suggestion_engine_helper.cc",
- "suggestion_engine_helper.h",
- "suggestion_engine_impl.cc",
- "suggestion_engine_impl.h",
- ]
-
- deps = [
- ":debug",
- ":interruption_processor",
- ":models",
- "//garnet/public/fidl/fuchsia.media",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/media/timeline",
- "//peridot/bin/suggestion_engine/decision_policies:all",
- "//peridot/bin/suggestion_engine/filters:all",
- "//peridot/bin/suggestion_engine/rankers:all",
- "//peridot/bin/suggestion_engine/ranking_features:all",
- "//peridot/lib/bound_set",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/util:rate_limited_retry",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/context/cpp:context_helper",
- ]
-
- public_deps = [
- ":state",
- ]
-}
-
-tests_package("suggestion_engine_unittests") {
- deps = [
- ":suggestion_engine_impl_unittest",
- "//peridot/bin/suggestion_engine/decision_policies:rank_over_threshold_decision_policy_unittest",
- "//peridot/bin/suggestion_engine/filters:conjugate_ranked_passive_filter_unittest",
- "//peridot/bin/suggestion_engine/filters:ranked_active_filter_unittest",
- "//peridot/bin/suggestion_engine/filters:ranked_passive_filter_unittest",
- "//peridot/bin/suggestion_engine/rankers:linear_ranker_unittest",
- "//peridot/bin/suggestion_engine/ranking_features:affinity_ranking_feature_unittest",
- "//peridot/bin/suggestion_engine/ranking_features:annoyance_ranking_feature_unittest",
- "//peridot/bin/suggestion_engine/ranking_features:dead_story_ranking_feature_unittest",
- "//peridot/bin/suggestion_engine/ranking_features:interrupting_ranking_feature_unittest",
- "//peridot/bin/suggestion_engine/ranking_features:kronk_ranking_feature_unittest",
- "//peridot/bin/suggestion_engine/ranking_features:mod_pair_ranking_feature_unittest",
- "//peridot/bin/suggestion_engine/ranking_features:proposal_hint_ranking_feature_unittest",
- "//peridot/bin/suggestion_engine/ranking_features:query_match_ranking_feature_unittest",
- ]
-}
-
-source_set("interruption_processor") {
- sources = [
- "interruptions_processor.cc",
- "interruptions_processor.h",
- ]
-
- deps = [
- ":models",
- "//peridot/bin/suggestion_engine/decision_policies:all",
- "//peridot/bin/suggestion_engine/ranking_features:ranking_feature",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("state") {
- sources = [
- "ranked_suggestions_list.cc",
- "ranked_suggestions_list.h",
- ]
-
- deps = [
- ":models",
- "//garnet/public/lib/fxl",
- "//peridot/bin/suggestion_engine/filters:base",
- "//peridot/bin/suggestion_engine/rankers:ranker",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/context/cpp:context_helper",
- ]
- public_deps = [
- "//peridot/bin/suggestion_engine/ranking_features:ranking_feature",
- ]
-}
-
-source_set("models") {
- sources = [
- "ranked_suggestion.cc",
- "ranked_suggestion.h",
- "suggestion_prototype.cc",
- "suggestion_prototype.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("debug") {
- sources = [
- "debug.cc",
- "debug.h",
- ]
-
- deps = [
- ":models",
- ":state",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- public_deps = [
- "//peridot/lib/util:idle_waiter",
- ]
-}
-
-executable("suggestion_engine_impl_unittest") {
- testonly = true
-
- sources = [
- "suggestion_engine_impl_unittest.cc",
- ]
-
- deps = [
- ":suggestion_engine_impl",
- "//garnet/public/lib/fsl",
- "//peridot/bin/sessionmgr/puppet_master:puppet_master_impl",
- "//peridot/lib/testing:test_story_command_executor",
- "//peridot/lib/testing:test_with_session_storage",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/suggestion_engine/debug.cc b/bin/suggestion_engine/debug.cc
deleted file mode 100644
index 98bbafa..0000000
--- a/bin/suggestion_engine/debug.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/debug.h"
-
-#include <functional>
-
-#include <lib/fidl/cpp/optional.h>
-
-namespace modular {
-
-SuggestionDebugImpl::SuggestionDebugImpl() : weak_ptr_factory_(this){};
-SuggestionDebugImpl::~SuggestionDebugImpl() = default;
-
-fxl::WeakPtr<SuggestionDebugImpl> SuggestionDebugImpl::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
-}
-
-void makeProposalSummary(const SuggestionPrototype* suggestion,
- fuchsia::modular::ProposalSummary* summary) {
- summary->id = suggestion->proposal.id;
- summary->publisher_url = suggestion->source_url;
- fidl::Clone(suggestion->proposal.display, &summary->display);
-}
-
-void makeProposalSummaries(
- const RankedSuggestionsList* suggestions,
- std::vector<fuchsia::modular::ProposalSummary>* summaries) {
- for (const auto& suggestion : suggestions->Get()) {
- fuchsia::modular::ProposalSummary summary;
- makeProposalSummary(suggestion->prototype, &summary);
- summaries->push_back(std::move(summary));
- }
-}
-
-void SuggestionDebugImpl::OnAskStart(std::string query,
- const RankedSuggestionsList* suggestions) {
- for (auto& listener : ask_proposal_listeners_.ptrs()) {
- std::vector<fuchsia::modular::ProposalSummary> proposals;
- makeProposalSummaries(suggestions, &proposals);
- (*listener)->OnAskStart(query, std::move(proposals));
- }
-}
-
-void SuggestionDebugImpl::OnSuggestionSelected(
- const SuggestionPrototype* selected_suggestion) {
- for (auto& listener : ask_proposal_listeners_.ptrs()) {
- if (selected_suggestion) {
- auto summary = fuchsia::modular::ProposalSummary::New();
- makeProposalSummary(selected_suggestion, summary.get());
- (*listener)->OnProposalSelected(std::move(summary));
- } else {
- (*listener)->OnProposalSelected(nullptr);
- }
- }
-}
-
-void SuggestionDebugImpl::OnInterrupt(
- const SuggestionPrototype* interrupt_suggestion) {
- for (auto& listener : interruption_proposal_listeners_.ptrs()) {
- fuchsia::modular::ProposalSummary summary;
- makeProposalSummary(interrupt_suggestion, &summary);
- (*listener)->OnInterrupt(std::move(summary));
- }
-}
-
-void SuggestionDebugImpl::OnNextUpdate(
- const RankedSuggestionsList* suggestions) {
- for (auto& listener : next_proposal_listeners_.ptrs()) {
- std::vector<fuchsia::modular::ProposalSummary> proposals;
- makeProposalSummaries(suggestions, &proposals);
- (*listener)->OnNextUpdate(std::move(proposals));
- cached_next_proposals_.reset(std::move(proposals));
- }
-}
-
-util::IdleWaiter* SuggestionDebugImpl::GetIdleWaiter() { return &idle_waiter_; }
-
-void SuggestionDebugImpl::WatchAskProposals(
- fidl::InterfaceHandle<fuchsia::modular::AskProposalListener> listener) {
- auto listener_ptr = listener.Bind();
- ask_proposal_listeners_.AddInterfacePtr(std::move(listener_ptr));
-}
-
-void SuggestionDebugImpl::WatchInterruptionProposals(
- fidl::InterfaceHandle<fuchsia::modular::InterruptionProposalListener>
- listener) {
- auto listener_ptr = listener.Bind();
- interruption_proposal_listeners_.AddInterfacePtr(std::move(listener_ptr));
-}
-
-void SuggestionDebugImpl::WatchNextProposals(
- fidl::InterfaceHandle<fuchsia::modular::NextProposalListener> listener) {
- auto listener_ptr = listener.Bind();
- next_proposal_listeners_.AddInterfacePtr(std::move(listener_ptr));
- if (cached_next_proposals_) {
- listener_ptr->OnNextUpdate(cached_next_proposals_.take());
- }
-}
-
-void SuggestionDebugImpl::WaitUntilIdle(WaitUntilIdleCallback callback) {
- idle_waiter_.WaitUntilIdle(callback);
-}
-
-void SuggestionDebugImpl::RunUntilIdle(RunUntilIdleCallback callback) {
- idle_waiter_.loop()->RunUntilIdle();
- callback();
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/debug.h b/bin/suggestion_engine/debug.h
deleted file mode 100644
index 9ebc951..0000000
--- a/bin/suggestion_engine/debug.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_DEBUG_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_DEBUG_H_
-
-#include <list>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/suggestion_engine/ranked_suggestions_list.h"
-#include "peridot/bin/suggestion_engine/suggestion_prototype.h"
-#include "peridot/lib/util/idle_waiter.h"
-
-namespace modular {
-
-// Provides a debug interface that is accessible through the MI dashboard.
-class SuggestionDebugImpl : public fuchsia::modular::SuggestionDebug {
- public:
- SuggestionDebugImpl();
- ~SuggestionDebugImpl() override;
-
- fxl::WeakPtr<SuggestionDebugImpl> GetWeakPtr();
-
- void OnAskStart(std::string query, const RankedSuggestionsList* suggestions);
- void OnSuggestionSelected(const SuggestionPrototype* selected_suggestion);
- void OnInterrupt(const SuggestionPrototype* interrupt_suggestion);
- void OnNextUpdate(const RankedSuggestionsList* suggestions);
-
- util::IdleWaiter* GetIdleWaiter();
-
- private:
- // |fuchsia::modular::SuggestionDebug|
- void WatchAskProposals(
- fidl::InterfaceHandle<fuchsia::modular::AskProposalListener> listener)
- override;
- // |fuchsia::modular::SuggestionDebug|
- void WatchInterruptionProposals(
- fidl::InterfaceHandle<fuchsia::modular::InterruptionProposalListener>
- listener) override;
- // |fuchsia::modular::SuggestionDebug|
- void WatchNextProposals(
- fidl::InterfaceHandle<fuchsia::modular::NextProposalListener> listener)
- override;
- // |fuchsia::modular::SuggestionDebug|
- void WaitUntilIdle(WaitUntilIdleCallback callback) override;
- // |fuchsia::modular::SuggestionDebug|
- void RunUntilIdle(RunUntilIdleCallback callback) override;
-
- fidl::InterfacePtrSet<fuchsia::modular::AskProposalListener>
- ask_proposal_listeners_;
- fidl::InterfacePtrSet<fuchsia::modular::InterruptionProposalListener>
- interruption_proposal_listeners_;
- fidl::InterfacePtrSet<fuchsia::modular::NextProposalListener>
- next_proposal_listeners_;
-
- // The cached set of next proposals.
- fidl::VectorPtr<fuchsia::modular::ProposalSummary> cached_next_proposals_;
-
- util::IdleWaiter idle_waiter_;
- fxl::WeakPtrFactory<SuggestionDebugImpl> weak_ptr_factory_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_DEBUG_H_
diff --git a/bin/suggestion_engine/decision_policies/BUILD.gn b/bin/suggestion_engine/decision_policies/BUILD.gn
deleted file mode 100644
index 47a3b59..0000000
--- a/bin/suggestion_engine/decision_policies/BUILD.gn
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-group("all") {
- public_deps = [
- ":decision_policy",
- ":rank_over_threshold_decision_policy",
- ]
-}
-
-source_set("decision_policy") {
- sources = [
- "decision_policy.cc",
- "decision_policy.h",
- ]
-
- deps = [
- "//peridot/bin/suggestion_engine:models",
- ]
-}
-
-source_set("rank_over_threshold_decision_policy") {
- sources = [
- "rank_over_threshold_decision_policy.cc",
- "rank_over_threshold_decision_policy.h",
- ]
-
- deps = [
- ":decision_policy",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- public_deps = [
- "//peridot/bin/suggestion_engine/rankers:ranker",
- ]
-}
-
-executable("rank_over_threshold_decision_policy_unittest") {
- testonly = true
-
- sources = [
- "rank_over_threshold_decision_policy_unittest.cc",
- ]
-
- deps = [
- ":rank_over_threshold_decision_policy",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/suggestion_engine/decision_policies/decision_policy.cc b/bin/suggestion_engine/decision_policies/decision_policy.cc
deleted file mode 100644
index 73f73b7..0000000
--- a/bin/suggestion_engine/decision_policies/decision_policy.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/decision_policies/decision_policy.h"
-
-namespace modular {
-
-DecisionPolicy::DecisionPolicy() = default;
-
-DecisionPolicy::~DecisionPolicy() = default;
-
-} // namespace modular
diff --git a/bin/suggestion_engine/decision_policies/decision_policy.h b/bin/suggestion_engine/decision_policies/decision_policy.h
deleted file mode 100644
index e8b5035..0000000
--- a/bin/suggestion_engine/decision_policies/decision_policy.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_DECISION_POLICIES_DECISION_POLICY_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_DECISION_POLICIES_DECISION_POLICY_H_
-
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-
-namespace modular {
-
-// Base class for performing a decision on some ranked suggestion.
-class DecisionPolicy {
- public:
- DecisionPolicy();
- virtual ~DecisionPolicy();
-
- // Decides if a value is valid given some policy.
- virtual bool Accept(const RankedSuggestion& value) = 0;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_DECISION_POLICIES_DECISION_POLICY_H_
diff --git a/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.cc b/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.cc
deleted file mode 100644
index 8651c26..0000000
--- a/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.h"
-
-namespace modular {
-
-RankOverThresholdDecisionPolicy::RankOverThresholdDecisionPolicy(
- std::unique_ptr<Ranker> ranker, double threshold)
- : ranker_(std::move(ranker)), threshold_(threshold) {}
-
-RankOverThresholdDecisionPolicy::~RankOverThresholdDecisionPolicy() = default;
-
-bool RankOverThresholdDecisionPolicy::Accept(
- const RankedSuggestion& suggestion) {
- double confidence = ranker_->Rank(suggestion);
- return confidence >= threshold_;
-};
-
-} // namespace modular
diff --git a/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.h b/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.h
deleted file mode 100644
index 8fc4b2d..0000000
--- a/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_DECISION_POLICIES_RANK_OVER_THRESHOLD_DECISION_POLICY_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_DECISION_POLICIES_RANK_OVER_THRESHOLD_DECISION_POLICY_H_
-
-#include "peridot/bin/suggestion_engine/decision_policies/decision_policy.h"
-#include "peridot/bin/suggestion_engine/rankers/ranker.h"
-
-namespace modular {
-
-namespace {
-constexpr double kDefaultThreshold = 1.0;
-} // namespace
-
-// Base class for performing a decision on some value.
-class RankOverThresholdDecisionPolicy : public DecisionPolicy {
- public:
- RankOverThresholdDecisionPolicy(std::unique_ptr<Ranker> ranker,
- double threshold = kDefaultThreshold);
- ~RankOverThresholdDecisionPolicy() override;
-
- bool Accept(const RankedSuggestion& suggestion) override;
-
- private:
- const std::unique_ptr<Ranker> ranker_;
-
- const double threshold_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_DECISION_POLICIES_RANK_OVER_THRESHOLD_DECISION_POLICY_H_
diff --git a/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy_unittest.cc b/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy_unittest.cc
deleted file mode 100644
index 49feb74..0000000
--- a/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy_unittest.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/suggestion_engine/rankers/ranker.h"
-
-namespace modular {
-namespace {
-
-class TestRanker : public Ranker {
- public:
- double Rank(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override {
- return suggestion.confidence;
- }
-};
-
-class RankOverThresholdDecisionPolicyTest : public ::testing::Test {
- public:
- void SetUp() override {
- decision_policy = std::make_unique<RankOverThresholdDecisionPolicy>(
- std::make_unique<TestRanker>(), 0.5);
- }
-
- protected:
- std::unique_ptr<RankOverThresholdDecisionPolicy> decision_policy;
-};
-
-TEST_F(RankOverThresholdDecisionPolicyTest, Accept) {
- RankedSuggestion suggestion;
- suggestion.confidence = 0.6;
- EXPECT_TRUE(decision_policy->Accept(suggestion));
- suggestion.confidence = 0.5;
- EXPECT_TRUE(decision_policy->Accept(suggestion));
-}
-
-TEST_F(RankOverThresholdDecisionPolicyTest, NotAccept) {
- RankedSuggestion suggestion;
- suggestion.confidence = 0.4;
- EXPECT_FALSE(decision_policy->Accept(suggestion));
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/BUILD.gn b/bin/suggestion_engine/filters/BUILD.gn
deleted file mode 100644
index 94e59b3..0000000
--- a/bin/suggestion_engine/filters/BUILD.gn
+++ /dev/null
@@ -1,135 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-group("all") {
- public_deps = [
- ":base",
- ":conjugate_ranked_passive_filter",
- ":ranked_active_filter",
- ":ranked_passive_filter",
- ]
-}
-
-group("base") {
- public_deps = [
- ":suggestion_active_filter",
- ":suggestion_passive_filter",
- ]
-}
-
-source_set("suggestion_passive_filter") {
- sources = [
- "suggestion_passive_filter.cc",
- "suggestion_passive_filter.h",
- ]
-
- deps = [
- "//peridot/bin/suggestion_engine:models",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("suggestion_active_filter") {
- sources = [
- "suggestion_active_filter.cc",
- "suggestion_active_filter.h",
- ]
-
- deps = [
- "//peridot/bin/suggestion_engine:models",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("conjugate_ranked_passive_filter") {
- sources = [
- "conjugate_ranked_passive_filter.cc",
- "conjugate_ranked_passive_filter.h",
- ]
-
- deps = [
- ":suggestion_passive_filter",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- public_deps = [
- "//peridot/bin/suggestion_engine/ranking_features:ranking_feature",
- ]
-}
-
-executable("conjugate_ranked_passive_filter_unittest") {
- testonly = true
-
- sources = [
- "conjugate_ranked_passive_filter_unittest.cc",
- ]
-
- deps = [
- ":conjugate_ranked_passive_filter",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("ranked_passive_filter") {
- sources = [
- "ranked_passive_filter.cc",
- "ranked_passive_filter.h",
- ]
-
- deps = [
- ":suggestion_passive_filter",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- public_deps = [
- "//peridot/bin/suggestion_engine/ranking_features:ranking_feature",
- ]
-}
-
-executable("ranked_passive_filter_unittest") {
- testonly = true
-
- sources = [
- "ranked_passive_filter_unittest.cc",
- ]
-
- deps = [
- ":ranked_passive_filter",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("ranked_active_filter") {
- sources = [
- "ranked_active_filter.cc",
- "ranked_active_filter.h",
- ]
-
- deps = [
- ":suggestion_active_filter",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- public_deps = [
- "//peridot/bin/suggestion_engine/ranking_features:ranking_feature",
- ]
-}
-
-executable("ranked_active_filter_unittest") {
- testonly = true
-
- sources = [
- "ranked_active_filter_unittest.cc",
- ]
-
- deps = [
- ":ranked_active_filter",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.cc b/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.cc
deleted file mode 100644
index 6489709..0000000
--- a/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.h"
-
-#include <list>
-
-namespace modular {
-
-ConjugateRankedPassiveFilter::ConjugateRankedPassiveFilter(
- std::shared_ptr<RankingFeature> ranking_feature)
- : ranking_feature_(ranking_feature) {}
-
-ConjugateRankedPassiveFilter::~ConjugateRankedPassiveFilter() = default;
-
-// If the confidence of the ranking feature is 0.0 then this filter returns
-// true.
-// Example usage with FocusedStoryRankingFeature. It should hide suggestions
-// with story affinity true that are not focused:
-// - StoryAffinity=false, Focused=... => 1.0 => false
-// - StoryAffinity=true, Focused=true => 1.0 => false
-// - StoryAffinity=true, Focused=false => 0.0 => true
-bool ConjugateRankedPassiveFilter::Filter(
- const std::unique_ptr<RankedSuggestion>& ranked_suggestion) {
- double confidence = ranking_feature_->ComputeFeature(
- fuchsia::modular::UserInput(), *ranked_suggestion);
- return confidence == kMinConfidence;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.h b/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.h
deleted file mode 100644
index 77ea8ed..0000000
--- a/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_CONJUGATE_RANKED_PASSIVE_FILTER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_CONJUGATE_RANKED_PASSIVE_FILTER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/filters/suggestion_passive_filter.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class ConjugateRankedPassiveFilter : public SuggestionPassiveFilter {
- public:
- ConjugateRankedPassiveFilter(std::shared_ptr<RankingFeature> ranking_feature);
- ~ConjugateRankedPassiveFilter() override;
-
- bool Filter(
- const std::unique_ptr<RankedSuggestion>& ranked_suggestion) override;
-
- private:
- std::shared_ptr<RankingFeature> ranking_feature_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_CONJUGATE_RANKED_PASSIVE_FILTER_H_
diff --git a/bin/suggestion_engine/filters/conjugate_ranked_passive_filter_unittest.cc b/bin/suggestion_engine/filters/conjugate_ranked_passive_filter_unittest.cc
deleted file mode 100644
index 155687f..0000000
--- a/bin/suggestion_engine/filters/conjugate_ranked_passive_filter_unittest.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-namespace {
-
-class ConfidenceRankingFeature : public RankingFeature {
- public:
- ConfidenceRankingFeature() {}
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override {
- return suggestion.confidence;
- }
-};
-
-class ConjugateRankedPassiveFilterTest : public ::testing::Test {
- public:
- void SetUp() override {
- filter = std::make_unique<ConjugateRankedPassiveFilter>(
- std::make_shared<ConfidenceRankingFeature>());
- }
-
- protected:
- std::unique_ptr<ConjugateRankedPassiveFilter> filter;
-};
-
-TEST_F(ConjugateRankedPassiveFilterTest, FilterMinConfidence) {
- auto suggestion = std::make_unique<RankedSuggestion>();
- suggestion->confidence = 0.0;
- EXPECT_TRUE(filter->Filter(suggestion));
-}
-
-TEST_F(ConjugateRankedPassiveFilterTest, FilterOtherConfidence) {
- auto suggestion = std::make_unique<RankedSuggestion>();
- suggestion->confidence = 0.5;
- EXPECT_FALSE(filter->Filter(suggestion));
-
- auto suggestion2 = std::make_unique<RankedSuggestion>();
- suggestion2->confidence = 1.0;
- EXPECT_FALSE(filter->Filter(suggestion2));
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/ranked_active_filter.cc b/bin/suggestion_engine/filters/ranked_active_filter.cc
deleted file mode 100644
index c0966ef..0000000
--- a/bin/suggestion_engine/filters/ranked_active_filter.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/filters/ranked_active_filter.h"
-
-#include <list>
-
-namespace modular {
-
-RankedActiveFilter::RankedActiveFilter(
- std::shared_ptr<RankingFeature> ranking_feature)
- : ranking_feature_(ranking_feature) {}
-
-RankedActiveFilter::~RankedActiveFilter() = default;
-
-void RankedActiveFilter::Filter(
- std::vector<std::unique_ptr<RankedSuggestion>>* const suggestions) {
- suggestions->erase(
- std::remove_if(
- suggestions->begin(), suggestions->end(),
- [this](const std::unique_ptr<RankedSuggestion>& ranked_suggestion) {
- double confidence = ranking_feature_->ComputeFeature(
- fuchsia::modular::UserInput(), *ranked_suggestion);
- return confidence >= kMaxConfidence;
- }),
- suggestions->end());
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/ranked_active_filter.h b/bin/suggestion_engine/filters/ranked_active_filter.h
deleted file mode 100644
index 2719ee6..0000000
--- a/bin/suggestion_engine/filters/ranked_active_filter.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_RANKED_ACTIVE_FILTER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_RANKED_ACTIVE_FILTER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/filters/suggestion_active_filter.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class RankedActiveFilter : public SuggestionActiveFilter {
- public:
- RankedActiveFilter(std::shared_ptr<RankingFeature> ranking_feature);
- ~RankedActiveFilter() override;
-
- void Filter(std::vector<std::unique_ptr<RankedSuggestion>>* const suggestions)
- override;
-
- private:
- std::shared_ptr<RankingFeature> ranking_feature_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_RANKED_ACTIVE_FILTER_H_
diff --git a/bin/suggestion_engine/filters/ranked_active_filter_unittest.cc b/bin/suggestion_engine/filters/ranked_active_filter_unittest.cc
deleted file mode 100644
index 790d52b..0000000
--- a/bin/suggestion_engine/filters/ranked_active_filter_unittest.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/filters/ranked_active_filter.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-namespace {
-
-class ConfidenceRankingFeature : public RankingFeature {
- public:
- ConfidenceRankingFeature() {}
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override {
- return suggestion.confidence;
- }
-};
-
-class RankedActiveFilterTest : public ::testing::Test {
- public:
- void SetUp() override {
- filter = std::make_unique<RankedActiveFilter>(
- std::make_shared<ConfidenceRankingFeature>());
- }
-
- protected:
- std::unique_ptr<RankedActiveFilter> filter;
-};
-
-void AddTestRankedSuggestion(
- std::vector<std::unique_ptr<RankedSuggestion>>* const list,
- double confidence) {
- auto suggestion = std::make_unique<RankedSuggestion>();
- suggestion->confidence = confidence;
- list->push_back(std::move(suggestion));
-}
-
-TEST_F(RankedActiveFilterTest, Filter) {
- // Should filter all ranked suggestions for which the ranking feature
- // evaluates to 1 (max confidence).
- std::vector<std::unique_ptr<RankedSuggestion>> list;
- AddTestRankedSuggestion(&list, 0.1);
- AddTestRankedSuggestion(&list, 1.0);
- AddTestRankedSuggestion(&list, 0.5);
- AddTestRankedSuggestion(&list, 1.0);
- AddTestRankedSuggestion(&list, 0.9);
- AddTestRankedSuggestion(&list, 1.0);
-
- filter->Filter(&list);
-
- EXPECT_EQ(list.size(), 3u);
- EXPECT_EQ(list[0]->confidence, 0.1);
- EXPECT_EQ(list[1]->confidence, 0.5);
- EXPECT_EQ(list[2]->confidence, 0.9);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/ranked_passive_filter.cc b/bin/suggestion_engine/filters/ranked_passive_filter.cc
deleted file mode 100644
index 36664c4..0000000
--- a/bin/suggestion_engine/filters/ranked_passive_filter.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/filters/ranked_passive_filter.h"
-
-#include <list>
-
-namespace modular {
-
-RankedPassiveFilter::RankedPassiveFilter(
- std::shared_ptr<RankingFeature> ranking_feature)
- : ranking_feature_(ranking_feature) {}
-
-RankedPassiveFilter::~RankedPassiveFilter() = default;
-
-// If the confidence of the ranking feature is 1.0 then this filter returns
-// true.
-bool RankedPassiveFilter::Filter(
- const std::unique_ptr<RankedSuggestion>& ranked_suggestion) {
- double confidence = ranking_feature_->ComputeFeature(
- fuchsia::modular::UserInput(), *ranked_suggestion);
- return confidence == kMaxConfidence;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/ranked_passive_filter.h b/bin/suggestion_engine/filters/ranked_passive_filter.h
deleted file mode 100644
index 6833f9b..0000000
--- a/bin/suggestion_engine/filters/ranked_passive_filter.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_RANKED_PASSIVE_FILTER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_RANKED_PASSIVE_FILTER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/filters/suggestion_passive_filter.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class RankedPassiveFilter : public SuggestionPassiveFilter {
- public:
- RankedPassiveFilter(std::shared_ptr<RankingFeature> ranking_feature);
- ~RankedPassiveFilter() override;
-
- bool Filter(const std::unique_ptr<RankedSuggestion>& suggestion) override;
-
- private:
- std::shared_ptr<RankingFeature> ranking_feature_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_RANKED_PASSIVE_FILTER_H_
diff --git a/bin/suggestion_engine/filters/ranked_passive_filter_unittest.cc b/bin/suggestion_engine/filters/ranked_passive_filter_unittest.cc
deleted file mode 100644
index a16932e..0000000
--- a/bin/suggestion_engine/filters/ranked_passive_filter_unittest.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/filters/ranked_passive_filter.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-namespace {
-
-class ConfidenceRankingFeature : public RankingFeature {
- public:
- ConfidenceRankingFeature() {}
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override {
- return suggestion.confidence;
- }
-};
-
-class RankedPassiveFilterTest : public ::testing::Test {
- public:
- void SetUp() override {
- filter = std::make_unique<RankedPassiveFilter>(
- std::make_shared<ConfidenceRankingFeature>());
- }
-
- protected:
- std::unique_ptr<RankedPassiveFilter> filter;
-};
-
-TEST_F(RankedPassiveFilterTest, FilterMaxConfidence) {
- auto suggestion = std::make_unique<RankedSuggestion>();
- suggestion->confidence = 1.0;
- EXPECT_TRUE(filter->Filter(suggestion));
-}
-
-TEST_F(RankedPassiveFilterTest, FilterOtherConfidence) {
- auto suggestion = std::make_unique<RankedSuggestion>();
- suggestion->confidence = 0.5;
- EXPECT_FALSE(filter->Filter(suggestion));
-
- auto suggestion2 = std::make_unique<RankedSuggestion>();
- suggestion2->confidence = 0.0;
- EXPECT_FALSE(filter->Filter(suggestion2));
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/suggestion_active_filter.cc b/bin/suggestion_engine/filters/suggestion_active_filter.cc
deleted file mode 100644
index e706ed7..0000000
--- a/bin/suggestion_engine/filters/suggestion_active_filter.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/filters/suggestion_active_filter.h"
-
-namespace modular {
-
-SuggestionActiveFilter::SuggestionActiveFilter() = default;
-
-SuggestionActiveFilter::~SuggestionActiveFilter() = default;
-
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/suggestion_active_filter.h b/bin/suggestion_engine/filters/suggestion_active_filter.h
deleted file mode 100644
index b226574..0000000
--- a/bin/suggestion_engine/filters/suggestion_active_filter.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_SUGGESTION_ACTIVE_FILTER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_SUGGESTION_ACTIVE_FILTER_H_
-
-#include <vector>
-
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-
-namespace modular {
-
-class SuggestionActiveFilter {
- public:
- SuggestionActiveFilter();
- virtual ~SuggestionActiveFilter();
-
- // Browse through the vector of ranked suggestions and remove/alter the
- // suggestions.
- virtual void Filter(
- std::vector<std::unique_ptr<RankedSuggestion>>* const suggestions) = 0;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_SUGGESTION_ACTIVE_FILTER_H_
diff --git a/bin/suggestion_engine/filters/suggestion_passive_filter.cc b/bin/suggestion_engine/filters/suggestion_passive_filter.cc
deleted file mode 100644
index 3542494..0000000
--- a/bin/suggestion_engine/filters/suggestion_passive_filter.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/filters/suggestion_passive_filter.h"
-
-namespace modular {
-
-SuggestionPassiveFilter::SuggestionPassiveFilter() = default;
-
-SuggestionPassiveFilter::~SuggestionPassiveFilter() = default;
-
-} // namespace modular
diff --git a/bin/suggestion_engine/filters/suggestion_passive_filter.h b/bin/suggestion_engine/filters/suggestion_passive_filter.h
deleted file mode 100644
index 2a55198..0000000
--- a/bin/suggestion_engine/filters/suggestion_passive_filter.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_SUGGESTION_PASSIVE_FILTER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_SUGGESTION_PASSIVE_FILTER_H_
-
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-
-namespace modular {
-
-class SuggestionPassiveFilter {
- public:
- SuggestionPassiveFilter();
- virtual ~SuggestionPassiveFilter();
-
- // Evaluate the suggestion based on the filter criteria and return a boolean
- // value.
- virtual bool Filter(const std::unique_ptr<RankedSuggestion>& suggestion) = 0;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_FILTERS_SUGGESTION_PASSIVE_FILTER_H_
diff --git a/bin/suggestion_engine/interruptions_processor.cc b/bin/suggestion_engine/interruptions_processor.cc
deleted file mode 100644
index 252b84a..0000000
--- a/bin/suggestion_engine/interruptions_processor.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/interruptions_processor.h"
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-InterruptionsProcessor::InterruptionsProcessor() = default;
-InterruptionsProcessor::~InterruptionsProcessor() = default;
-
-void InterruptionsProcessor::RegisterListener(
- fidl::InterfaceHandle<fuchsia::modular::InterruptionListener> listener) {
- listeners_.AddInterfacePtr(listener.Bind());
-}
-
-void InterruptionsProcessor::SetDecisionPolicy(
- std::unique_ptr<DecisionPolicy> decision_policy) {
- decision_policy_ = std::move(decision_policy);
-}
-
-bool InterruptionsProcessor::MaybeInterrupt(
- const RankedSuggestion& suggestion) {
- if (decision_policy_->Accept(suggestion)) {
- for (auto& listener : listeners_.ptrs()) {
- DispatchInterruption(listener->get(), suggestion);
- }
- return true;
- }
- return false;
-}
-
-void InterruptionsProcessor::DispatchInterruption(
- fuchsia::modular::InterruptionListener* const listener,
- const RankedSuggestion& ranked_suggestion) {
- fuchsia::modular::Suggestion suggestion = CreateSuggestion(ranked_suggestion);
- suggestion.confidence = kMaxConfidence;
- listener->OnInterrupt(std::move(suggestion));
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/interruptions_processor.h b/bin/suggestion_engine/interruptions_processor.h
deleted file mode 100644
index f2933e3..0000000
--- a/bin/suggestion_engine/interruptions_processor.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_INTERRUPTIONS_PROCESSOR_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_INTERRUPTIONS_PROCESSOR_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-
-#include "peridot/bin/suggestion_engine/decision_policies/decision_policy.h"
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-
-namespace modular {
-
-// The InterruptionProcessor determines whether a proposal should interrupt
-// the user. If the decision to interrupt is made, this processor also
-// determines when and how the interruption should occur.
-//
-// All interrupting suggestions remain stored as contextual "next"
-// suggestions.
-class InterruptionsProcessor {
- public:
- InterruptionsProcessor();
- ~InterruptionsProcessor();
-
- // Ranker that will be used to know if a suggestion should interrupt.
- void SetDecisionPolicy(std::unique_ptr<DecisionPolicy> decision_policy);
-
- // Add listener that will be notified when an interruption comes.
- void RegisterListener(
- fidl::InterfaceHandle<fuchsia::modular::InterruptionListener> listener);
-
- // Based on ranker confidence, dispatch an interruption for the given
- // suggestion
- bool MaybeInterrupt(const RankedSuggestion& suggestion);
-
- private:
- void DispatchInterruption(
- fuchsia::modular::InterruptionListener* const listener,
- const RankedSuggestion& ranked_suggestion);
-
- fidl::InterfacePtrSet<fuchsia::modular::InterruptionListener> listeners_;
-
- std::unique_ptr<DecisionPolicy> decision_policy_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_INTERRUPTIONS_PROCESSOR_H_
diff --git a/bin/suggestion_engine/media_player.cc b/bin/suggestion_engine/media_player.cc
deleted file mode 100644
index e39493a..0000000
--- a/bin/suggestion_engine/media_player.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/media_player.h"
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/media/timeline/timeline.h>
-#include <lib/media/timeline/timeline_rate.h>
-
-namespace modular {
-
-MediaPlayer::MediaPlayer(fuchsia::media::AudioPtr audio,
- std::shared_ptr<SuggestionDebugImpl> debug)
- : audio_(std::move(audio)), debug_(debug) {
- audio_.set_error_handler([this](zx_status_t status) {
- // TODO(miguelfrde): better error handling. If we observe this message it
- // means that the underlying channel was closed.
- FXL_LOG(WARNING) << "Audio connection error";
- audio_ = nullptr;
- });
-}
-
-MediaPlayer::~MediaPlayer() = default;
-
-void MediaPlayer::SetSpeechStatusCallback(SpeechStatusCallback callback) {
- speech_status_callback_ = std::move(callback);
-}
-
-void MediaPlayer::PlayAudioResponse(
- fidl::InterfaceRequest<fuchsia::media::AudioRenderer> audio_response) {
- if (!audio_) {
- FXL_LOG(ERROR) << "Not playing query audio response because our audio "
- "service connection died earlier.";
- return;
- }
-
- audio_->CreateAudioRenderer(audio_renderer_.NewRequest());
- audio_renderer_binding_ =
- std::make_unique<fidl::Binding<fuchsia::media::AudioRenderer>>(
- audio_renderer_.get());
- audio_renderer_binding_->set_error_handler([this](zx_status_t status) {
- speech_status_callback_(fuchsia::modular::SpeechStatus::IDLE);
- });
- audio_renderer_binding_->Bind(std::move(audio_response));
-
- speech_status_callback_(fuchsia::modular::SpeechStatus::RESPONDING);
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/media_player.h b/bin/suggestion_engine/media_player.h
deleted file mode 100644
index f559bf8..0000000
--- a/bin/suggestion_engine/media_player.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_MEDIA_PLAYER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_MEDIA_PLAYER_H_
-
-#include <vector>
-
-#include <fuchsia/media/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-
-#include "peridot/bin/suggestion_engine/debug.h"
-#include "peridot/lib/util/idle_waiter.h"
-
-namespace modular {
-
-using SpeechStatusCallback =
- std::function<void(fuchsia::modular::SpeechStatus)>;
-
-// Class in charge of playing media (speech) responses coming from query
-// responses.
-class MediaPlayer {
- public:
- // Instantiates a new MediaPlayer object.
- // |audio| is a binding to the audio service that will be used.
- // |debug| is used for debugging and testing purposes. Should be provided.
- MediaPlayer(fuchsia::media::AudioPtr audio,
- std::shared_ptr<SuggestionDebugImpl> debug);
- ~MediaPlayer();
-
- // Sets callback that is called whenever a change to
- // fuchsia::modular::SpeechStatus occurs.
- void SetSpeechStatusCallback(SpeechStatusCallback callback);
-
- // Plays audio response coming from a query response.
- void PlayAudioResponse(
- fidl::InterfaceRequest<fuchsia::media::AudioRenderer> audio_response);
-
- private:
- fuchsia::media::AudioPtr audio_;
-
- // Suggestion Engine maintains ownership of an |AudioRendererPtr| during
- // playback to enforce policy and have visibility into playback status (via
- // whether or not the channel is closed). Only one agent is allowed to play
- // responses at a time.
- fuchsia::media::AudioRendererPtr audio_renderer_;
- std::unique_ptr<fidl::Binding<fuchsia::media::AudioRenderer>>
- audio_renderer_binding_;
-
- std::shared_ptr<SuggestionDebugImpl> debug_;
- SpeechStatusCallback speech_status_callback_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_MEDIA_PLAYER_H_
diff --git a/bin/suggestion_engine/meta/suggestion_engine.cmx b/bin/suggestion_engine/meta/suggestion_engine.cmx
deleted file mode 100644
index 180b1e6..0000000
--- a/bin/suggestion_engine/meta/suggestion_engine.cmx
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.modular.ContextReader",
- "fuchsia.modular.PuppetMaster"
- ]
- }
-}
diff --git a/bin/suggestion_engine/navigation_processor.cc b/bin/suggestion_engine/navigation_processor.cc
deleted file mode 100644
index 035ddc3..0000000
--- a/bin/suggestion_engine/navigation_processor.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/navigation_processor.h"
-
-namespace modular {
-
-NavigationProcessor::NavigationProcessor() = default;
-NavigationProcessor::~NavigationProcessor() = default;
-
-void NavigationProcessor::RegisterListener(
- fidl::InterfaceHandle<fuchsia::modular::NavigationListener> listener) {
- listeners_.AddInterfacePtr(listener.Bind());
-}
-
-void NavigationProcessor::Navigate(
- fuchsia::modular::NavigationAction navigation) {
- for (const auto& listener : listeners_.ptrs()) {
- (*listener)->OnNavigation(navigation);
- }
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/navigation_processor.h b/bin/suggestion_engine/navigation_processor.h
deleted file mode 100644
index d143f18..0000000
--- a/bin/suggestion_engine/navigation_processor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_NAVIGATION_PROCESSOR_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_NAVIGATION_PROCESSOR_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "lib/fidl/cpp/interface_ptr_set.h"
-#include "lib/fxl/memory/weak_ptr.h"
-#include "peridot/bin/suggestion_engine/decision_policies/decision_policy.h"
-
-namespace modular {
-
-// The NavigationProcessor dispatches received navigation events.
-class NavigationProcessor {
- public:
- NavigationProcessor();
- ~NavigationProcessor();
-
- // Add listener that will be notified when a navigation event comes.
- void RegisterListener(
- fidl::InterfaceHandle<fuchsia::modular::NavigationListener> listener);
-
- // Immediately send the navigation event to listeners.
- void Navigate(fuchsia::modular::NavigationAction navigation);
-
- private:
- fidl::InterfacePtrSet<fuchsia::modular::NavigationListener> listeners_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_NAVIGATION_PROCESSOR_H_
diff --git a/bin/suggestion_engine/next_processor.cc b/bin/suggestion_engine/next_processor.cc
deleted file mode 100644
index 7d62689..0000000
--- a/bin/suggestion_engine/next_processor.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/next_processor.h"
-
-#include "peridot/bin/suggestion_engine/suggestion_engine_helper.h"
-
-namespace modular {
-
-NextProcessor::NextProcessor(std::shared_ptr<SuggestionDebugImpl> debug)
- : debug_(debug), processing_(false) {}
-
-NextProcessor::~NextProcessor() = default;
-
-void NextProcessor::RegisterListener(
- fidl::InterfaceHandle<fuchsia::modular::NextListener> listener,
- const size_t max_results) {
- auto listenerPtr = listener.Bind();
-
- // Notify the listener of the current next suggestions
- NotifyOfResults(listenerPtr, max_results);
-
- // Save the listener
- listeners_.emplace_back(std::move(listenerPtr), max_results);
-
- // Register connection error handler on new listener to remove from list
- // if connection drops. This code is mostly borrowed from InterfacePtrSet
- fuchsia::modular::NextListenerPtr& nextPtr = listeners_.back().first;
- fuchsia::modular::NextListener* pointer = nextPtr.get();
- nextPtr.set_error_handler([pointer, this](zx_status_t status) {
- auto it = std::find_if(
- listeners_.begin(), listeners_.end(),
- [pointer](const auto& p) { return (p.first.get() == pointer); });
- assert(it != listeners_.end());
- listeners_.erase(it);
- });
-}
-
-void NextProcessor::RegisterInterruptionListener(
- fidl::InterfaceHandle<fuchsia::modular::InterruptionListener> listener) {
- interruptions_processor_.RegisterListener(std::move(listener));
-}
-
-void NextProcessor::AddProposal(const std::string& component_url,
- fuchsia::modular::Proposal proposal) {
- AddProposal(component_url, "" /* preloaded_story_id */, std::move(proposal));
-}
-
-void NextProcessor::AddProposal(const std::string& component_url,
- const std::string& preloaded_story_id,
- fuchsia::modular::Proposal proposal) {
- NotifyOfProcessingChange(true);
- // The component_url and proposal ID form a unique identifier for a proposal.
- // If one already exists, remove it before adding the new one.
- RemoveProposal(component_url, proposal.id);
-
- auto prototype = CreateSuggestionPrototype(
- &prototypes_, component_url, preloaded_story_id, std::move(proposal));
-
- if (prototype->proposal.listener) {
- prototype->bound_listener = prototype->proposal.listener.Bind();
- prototype->bound_listener.set_error_handler(
- [this, proposal_id = prototype->proposal.id,
- component_url](zx_status_t status) {
- RemoveProposal(component_url, proposal_id);
- });
- }
-
- auto ranked_suggestion = RankedSuggestion::New(prototype);
-
- // TODO(miguelfrde): Make NextProcessor not depend on InterruptionsProcessor.
- if (interruptions_processor_.MaybeInterrupt(*ranked_suggestion)) {
- ranked_suggestion->interrupting = true;
- debug_->OnInterrupt(prototype);
- }
-
- suggestions_.AddSuggestion(std::move(ranked_suggestion));
- UpdateRanking();
-}
-
-void NextProcessor::RemoveProposal(const std::string& component_url,
- const std::string& proposal_id) {
- const auto key = std::make_pair(component_url, proposal_id);
- auto toRemove = prototypes_.find(key);
- if (toRemove != prototypes_.end()) {
- // can't erase right off the bat because the prototype must remain valid
- // until removed from the ranked list
- RemoveProposalFromList(component_url, proposal_id);
- prototypes_.erase(toRemove);
- }
-}
-
-SuggestionPrototype* NextProcessor::GetSuggestion(
- const std::string& component_url, const std::string& proposal_id) const {
- RankedSuggestion* ranked_suggestion =
- suggestions_.GetSuggestion(component_url, proposal_id);
- if (ranked_suggestion) {
- return ranked_suggestion->prototype;
- }
- return nullptr;
-}
-
-void NextProcessor::RemoveProposalFromList(const std::string& component_url,
- const std::string& proposal_id) {
- NotifyOfProcessingChange(true);
- if (suggestions_.RemoveProposal(component_url, proposal_id)) {
- UpdateRanking();
- }
-}
-
-void NextProcessor::SetActiveFilters(
- std::vector<std::unique_ptr<SuggestionActiveFilter>>&& active_filters) {
- suggestions_.SetActiveFilters(std::move(active_filters));
-}
-
-void NextProcessor::SetPassiveFilters(
- std::vector<std::unique_ptr<SuggestionPassiveFilter>>&& passive_filters) {
- suggestions_.SetPassiveFilters(std::move(passive_filters));
-}
-
-void NextProcessor::SetRanker(std::unique_ptr<Ranker> ranker) {
- suggestions_.SetRanker(std::move(ranker));
-}
-
-void NextProcessor::SetInterruptionDecisionPolicy(
- std::unique_ptr<DecisionPolicy> decision_policy) {
- interruptions_processor_.SetDecisionPolicy(std::move(decision_policy));
-}
-
-RankedSuggestion* NextProcessor::GetSuggestion(
- const std::string& suggestion_id) const {
- return suggestions_.GetSuggestion(suggestion_id);
-}
-
-void NextProcessor::UpdateRanking() {
- suggestions_.Refresh();
- NotifyAllOfResults();
- debug_->OnNextUpdate(&suggestions_);
- NotifyOfProcessingChange(false);
-}
-
-void NextProcessor::NotifyAllOfResults() {
- for (const auto& it : listeners_) {
- if (it.first) {
- NotifyOfResults(it.first, it.second);
- }
- }
-}
-
-void NextProcessor::NotifyOfProcessingChange(const bool processing) {
- if (processing_ != processing) {
- processing_ = processing;
- // Notify all listeners that the processing state has changed
- for (const auto& it : listeners_) {
- if (it.first) {
- it.first->OnProcessingChange(processing_);
- }
- }
- }
-}
-
-void NextProcessor::NotifyOfResults(
- const fuchsia::modular::NextListenerPtr& listener,
- const size_t max_results) {
- const auto& suggestion_vector = suggestions_.Get();
-
- std::vector<fuchsia::modular::Suggestion> window;
- for (size_t i = 0;
- window.size() < max_results && i < suggestion_vector.size(); i++) {
- if (!suggestion_vector[i]->hidden) {
- window.push_back(CreateSuggestion(*suggestion_vector[i]));
- }
- }
-
- listener->OnNextResults(std::move(window));
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/next_processor.h b/bin/suggestion_engine/next_processor.h
deleted file mode 100644
index 6a4ec29..0000000
--- a/bin/suggestion_engine/next_processor.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_NEXT_PROCESSOR_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_NEXT_PROCESSOR_H_
-
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-
-#include "peridot/bin/suggestion_engine/debug.h"
-#include "peridot/bin/suggestion_engine/decision_policies/decision_policy.h"
-#include "peridot/bin/suggestion_engine/filters/suggestion_active_filter.h"
-#include "peridot/bin/suggestion_engine/filters/suggestion_passive_filter.h"
-#include "peridot/bin/suggestion_engine/interruptions_processor.h"
-#include "peridot/bin/suggestion_engine/proposal_publisher_impl.h"
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-#include "peridot/bin/suggestion_engine/ranked_suggestions_list.h"
-#include "peridot/bin/suggestion_engine/rankers/ranker.h"
-#include "peridot/bin/suggestion_engine/suggestion_prototype.h"
-
-namespace modular {
-
-class ProposalPublisherImpl;
-class SuggestionEngineImpl;
-
-// The NextProcessor manages all contextual proposals for the suggestion
-// engine.
-class NextProcessor {
- public:
- NextProcessor(std::shared_ptr<SuggestionDebugImpl> debug);
- virtual ~NextProcessor();
-
- void RegisterListener(
- fidl::InterfaceHandle<fuchsia::modular::NextListener> listener,
- size_t max_results);
-
- void RegisterInterruptionListener(
- fidl::InterfaceHandle<fuchsia::modular::InterruptionListener> listener);
-
- // Adds a next suggestion created from the provided proposal.
- //
- // |component_url| The url of the component that created the proposal.
- // |proposal| The proposal to create the suggestion from.
- void AddProposal(const std::string& component_url,
- fuchsia::modular::Proposal proposal);
-
- // Adds a next suggestion created from the provided proposal. This method
- // allows the caller to specify a story that can be used to dynamically
- // preview the created suggestion.
- //
- // |component_url| The url of the component that created the proposal.
- // |preloaded_story_id| The identifier for a story that can be used to
- // display a dynamic suggestion for the proposal. If empty, no such
- // story exists.
- // |proposal| The proposal to create the suggestion from.
- void AddProposal(const std::string& component_url,
- const std::string& preloaded_story_id,
- fuchsia::modular::Proposal proposal);
-
- // Removes the identified proposal from the next processor.
- //
- // |component_url| The url of the component that created the proposal.
- // |proposal_id| The identifier for the proposal.
- void RemoveProposal(const std::string& component_url,
- const std::string& proposal_id);
-
- // Returns a pointer to the suggestion associated with the provided
- // |component_url| and |proposal_id|, or nullptr if no such suggestion exists.
- SuggestionPrototype* GetSuggestion(const std::string& component_url,
- const std::string& proposal_id) const;
-
- void SetActiveFilters(
- std::vector<std::unique_ptr<SuggestionActiveFilter>>&& active_filters);
-
- void SetPassiveFilters(
- std::vector<std::unique_ptr<SuggestionPassiveFilter>>&& passive_filters);
-
- void SetRanker(std::unique_ptr<Ranker> ranker);
-
- void SetInterruptionDecisionPolicy(
- std::unique_ptr<DecisionPolicy> decision_policy);
-
- // Gets a suggestion stored in the processor.
- RankedSuggestion* GetSuggestion(const std::string& suggestion_id) const;
-
- // Reranks suggestions if dirty and updates listeners
- void UpdateRanking();
-
- // Notify the listeners of new suggestions
- void NotifyAllOfResults();
-
- // Notifies the listeners that the processing state has changed.
- void NotifyOfProcessingChange(bool processing);
-
- private:
- // (proposer ID, proposal ID) => suggestion prototype
- using SuggestionPrototypeMap = std::map<std::pair<std::string, std::string>,
- std::unique_ptr<SuggestionPrototype>>;
-
- void NotifyOfResults(const fuchsia::modular::NextListenerPtr& listener,
- size_t max_results);
-
- void RemoveProposalFromList(const std::string& component_url,
- const std::string& proposal_id);
-
- InterruptionsProcessor interruptions_processor_;
- RankedSuggestionsList suggestions_;
- std::shared_ptr<SuggestionDebugImpl> debug_;
- SuggestionPrototypeMap prototypes_;
- bool processing_;
-
- std::vector<std::pair<fuchsia::modular::NextListenerPtr, size_t>> listeners_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_NEXT_PROCESSOR_H_
diff --git a/bin/suggestion_engine/proposal_publisher_impl.cc b/bin/suggestion_engine/proposal_publisher_impl.cc
deleted file mode 100644
index da03970..0000000
--- a/bin/suggestion_engine/proposal_publisher_impl.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/proposal_publisher_impl.h"
-
-#include "peridot/bin/suggestion_engine/suggestion_engine_impl.h"
-
-namespace modular {
-
-ProposalPublisherImpl::ProposalPublisherImpl(SuggestionEngineImpl* engine,
- const std::string& component_url)
- : engine_(engine),
- component_url_(component_url),
- bindings_(this),
- weak_ptr_factory_(this) {}
-
-ProposalPublisherImpl::~ProposalPublisherImpl() = default;
-
-void ProposalPublisherImpl::AddBinding(
- fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher> request) {
- bindings_.emplace(new fidl::Binding<fuchsia::modular::ProposalPublisher>(
- this, std::move(request)));
-}
-
-void ProposalPublisherImpl::Propose(fuchsia::modular::Proposal proposal) {
- engine_->AddNextProposal(this, std::move(proposal));
-}
-
-void ProposalPublisherImpl::ProposeNavigation(
- fuchsia::modular::NavigationAction navigation) {
- engine_->ProposeNavigation(navigation);
-}
-
-void ProposalPublisherImpl::Remove(std::string proposal_id) {
- engine_->RemoveNextProposal(component_url_, proposal_id);
-}
-
-ProposalPublisherImpl::BindingSet::BindingSet(ProposalPublisherImpl* impl)
- : impl_(impl) {}
-
-ProposalPublisherImpl::BindingSet::~BindingSet() = default;
-
-void ProposalPublisherImpl::BindingSet::OnConnectionError(
- fidl::Binding<fuchsia::modular::ProposalPublisher>* binding) {
- ::modular::BindingSet<fuchsia::modular::ProposalPublisher>::OnConnectionError(
- binding);
-
- if (impl_->ShouldEraseSelf())
- impl_->EraseSelf();
-}
-
-bool ProposalPublisherImpl::ShouldEraseSelf() const {
- return bindings_.empty() && !weak_ptr_factory_.HasWeakPtrs();
-}
-
-void ProposalPublisherImpl::EraseSelf() {
- engine_->RemoveSourceClient(component_url_);
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/proposal_publisher_impl.h b/bin/suggestion_engine/proposal_publisher_impl.h
deleted file mode 100644
index 8bd4cc0..0000000
--- a/bin/suggestion_engine/proposal_publisher_impl.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_PROPOSAL_PUBLISHER_IMPL_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_PROPOSAL_PUBLISHER_IMPL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/lib/bound_set/bound_set.h"
-
-namespace modular {
-
-class SuggestionEngineImpl;
-
-/*
- ProposalPublisherImpl tracks proposals and their resulting suggestions
- from a single suggestion agent. Source entries are created on demand and kept
- alive as long as any proposals or publisher bindings exist.
-
- TODO: The component_url should eventually be replaced with a more consistent
- identifier that's reused across components to identify specific executables.
-*/
-class ProposalPublisherImpl : public fuchsia::modular::ProposalPublisher {
- public:
- ProposalPublisherImpl(SuggestionEngineImpl* engine,
- const std::string& component_url);
-
- ~ProposalPublisherImpl() override;
-
- void AddBinding(
- fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher> request);
-
- void Propose(fuchsia::modular::Proposal proposal) override;
- void Remove(std::string proposal_id) override;
-
- void ProposeNavigation(
- fuchsia::modular::NavigationAction navigation) override;
-
- const std::string component_url() { return component_url_; }
-
- private:
- class BindingSet
- : public ::modular::BindingSet<fuchsia::modular::ProposalPublisher> {
- public:
- BindingSet(ProposalPublisherImpl* impl);
- ~BindingSet() override;
-
- protected:
- void OnConnectionError(
- fidl::Binding<fuchsia::modular::ProposalPublisher>* binding) override;
-
- private:
- ProposalPublisherImpl* const impl_;
- };
-
- bool ShouldEraseSelf() const;
- void EraseSelf();
-
- SuggestionEngineImpl* const engine_;
- const std::string component_url_;
- BindingSet bindings_;
-
- fxl::WeakPtrFactory<ProposalPublisherImpl> weak_ptr_factory_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_PROPOSAL_PUBLISHER_IMPL_H_
diff --git a/bin/suggestion_engine/query_processor.cc b/bin/suggestion_engine/query_processor.cc
deleted file mode 100644
index d0e72ed..0000000
--- a/bin/suggestion_engine/query_processor.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/query_processor.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-
-#include "peridot/bin/suggestion_engine/suggestion_engine_helper.h"
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace modular {
-
-namespace {
-
-constexpr char kQueryContextKey[] = "/suggestion_engine/current_query";
-
-} // namespace
-
-QueryProcessor::QueryProcessor(std::shared_ptr<SuggestionDebugImpl> debug)
- : debug_(debug) {}
-
-QueryProcessor::~QueryProcessor() = default;
-
-void QueryProcessor::Initialize(
- fidl::InterfaceHandle<fuchsia::modular::ContextWriter> context_writer) {
- context_writer_.Bind(std::move(context_writer));
-}
-
-void QueryProcessor::ExecuteQuery(
- fuchsia::modular::UserInput input, int count,
- fidl::InterfaceHandle<fuchsia::modular::QueryListener> listener) {
- // Process:
- // 1. Close out and clean up any existing query process
- // 2. Update the context engine with the new query
- // 3. Set up the ask variables in suggestion engine
- // 4. Get suggestions from each of the QueryHandlers
- // 5. Filter and Rank the suggestions as received
- // 6. Send "done" to SuggestionListener
-
- // Step 1
- CleanUpPreviousQuery();
-
- // Step 2
- std::string query = input.text;
- if (!query.empty() && context_writer_.is_bound()) {
- // Update context engine
- std::string formattedQuery;
-
- XdrFilterType<std::string> filter_list[] = {
- XdrFilter<std::string>,
- nullptr,
- };
-
- XdrWrite(&formattedQuery, &query, filter_list);
- context_writer_->WriteEntityTopic(kQueryContextKey, formattedQuery);
-
- // Update suggestion engine debug interface
- debug_->OnAskStart(query, &suggestions_);
- }
-
- // Steps 3 - 6
- activity_ = debug_->GetIdleWaiter()->RegisterOngoingActivity();
- active_query_ = std::make_unique<QueryRunner>(std::move(listener),
- std::move(input), count);
- active_query_->SetResponseCallback(
- [this, input](const std::string& handler_url,
- fuchsia::modular::QueryResponse response) {
- OnQueryResponse(input, handler_url, std::move(response));
- });
- active_query_->SetEndRequestCallback(
- [this, input] { OnQueryEndRequest(input); });
- active_query_->Run(query_handlers_);
-}
-
-void QueryProcessor::RegisterQueryHandler(
- fidl::StringPtr url, fidl::InterfaceHandle<fuchsia::modular::QueryHandler>
- query_handler_handle) {
- auto query_handler = query_handler_handle.Bind();
- query_handlers_.emplace_back(std::move(query_handler), url);
-
- fuchsia::modular::QueryHandlerPtr& handler = query_handlers_.back().handler;
- handler.set_error_handler([this, ptr = handler.get()](zx_status_t status) {
- auto it = std::find_if(query_handlers_.begin(), query_handlers_.end(),
- [ptr](const QueryHandlerRecord& record) {
- return record.handler.get() == ptr;
- });
-
- FXL_DCHECK(it != query_handlers_.end());
- auto to_erase = query_handlers_.end() - 1;
- std::iter_swap(it, to_erase);
- query_handlers_.erase(to_erase);
- });
-}
-
-void QueryProcessor::SetFilters(
- std::vector<std::unique_ptr<SuggestionActiveFilter>>&& active_filters,
- std::vector<std::unique_ptr<SuggestionPassiveFilter>>&& passive_filters) {
- suggestions_.SetActiveFilters(std::move(active_filters));
- suggestions_.SetPassiveFilters(std::move(passive_filters));
-}
-
-void QueryProcessor::SetRanker(std::unique_ptr<Ranker> ranker) {
- suggestions_.SetRanker(std::move(ranker));
-}
-
-RankedSuggestion* QueryProcessor::GetSuggestion(
- const std::string& suggestion_uuid) const {
- return suggestions_.GetSuggestion(suggestion_uuid);
-}
-
-void QueryProcessor::CleanUpPreviousQuery() {
- active_query_.reset();
- suggestions_.RemoveAllSuggestions();
-}
-
-void QueryProcessor::AddProposal(const std::string& source_url,
- fuchsia::modular::Proposal proposal) {
- suggestions_.RemoveProposal(source_url, proposal.id);
-
- SuggestionPrototype* suggestion =
- CreateSuggestionPrototype(&query_prototypes_, source_url,
- "" /* Emtpy story_id */, std::move(proposal));
- suggestions_.AddSuggestion(suggestion);
-}
-
-void QueryProcessor::OnQueryResponse(fuchsia::modular::UserInput input,
- const std::string& handler_url,
- fuchsia::modular::QueryResponse response) {
- // Ranking currently happens as each set of proposals are added.
- for (size_t i = 0; i < response.proposals.size(); ++i) {
- AddProposal(handler_url, std::move(response.proposals.at(i)));
- }
- suggestions_.Refresh(input);
-
- // Update the fuchsia::modular::QueryListener with new results
- NotifyOfResults();
-
- // Update the suggestion engine debug interface
- debug_->OnAskStart(input.text, &suggestions_);
-}
-
-void QueryProcessor::OnQueryEndRequest(fuchsia::modular::UserInput input) {
- debug_->OnAskStart(input.text, &suggestions_);
- // Idle immediately, we no longer handle audio responses here.
- activity_ = nullptr;
-}
-
-void QueryProcessor::NotifyOfResults() {
- const auto& suggestion_vector = suggestions_.Get();
-
- std::vector<fuchsia::modular::Suggestion> window;
- for (size_t i = 0;
- i < active_query_->max_results() && i < suggestion_vector.size(); i++) {
- window.push_back(CreateSuggestion(*suggestion_vector[i]));
- }
-
- if (!window.empty()) {
- active_query_->listener()->OnQueryResults(std::move(window));
- }
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/query_processor.h b/bin/suggestion_engine/query_processor.h
deleted file mode 100644
index 8a444cd..0000000
--- a/bin/suggestion_engine/query_processor.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_PROCESSOR_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_PROCESSOR_H_
-
-#include <set>
-
-#include <fuchsia/media/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/suggestion_engine/media_player.h"
-#include "peridot/bin/suggestion_engine/query_runner.h"
-#include "peridot/bin/suggestion_engine/rankers/ranker.h"
-#include "peridot/bin/suggestion_engine/suggestion_prototype.h"
-#include "peridot/lib/util/idle_waiter.h"
-
-namespace modular {
-
-class SuggestionEngineImpl;
-
-// The query processor handles the pull-based query suggestion process,
-// including requesting suggestions from QueryHandlers, collating and
-// ranking those suggestions, and then providing them to the user.
-class QueryProcessor {
- public:
- QueryProcessor(std::shared_ptr<SuggestionDebugImpl> debug);
- ~QueryProcessor();
-
- void Initialize(
- fidl::InterfaceHandle<fuchsia::modular::ContextWriter> context_writer);
-
- // Runs a query and notifies listener with results from it with the given
- // input and providing 'count' results. It also caches all query results for
- // future fetching using GetSuggestion(). Each time ExecuteQuery is called,
- // suggestions from the previous query are cleared by calling
- // CleanUpPreviousQuery() internally.
- void ExecuteQuery(
- fuchsia::modular::UserInput input, int count,
- fidl::InterfaceHandle<fuchsia::modular::QueryListener> listener);
-
- // Registers a handler that will be notified when a new query comes for its
- // fullfillment.
- void RegisterQueryHandler(
- fidl::StringPtr url, fidl::InterfaceHandle<fuchsia::modular::QueryHandler>
- query_handler_handle);
-
- void SetFilters(
- std::vector<std::unique_ptr<SuggestionActiveFilter>>&& active_filters,
- std::vector<std::unique_ptr<SuggestionPassiveFilter>>&& passive_filters);
-
- void SetRanker(std::unique_ptr<Ranker> ranker);
-
- // Returns a query suggestion with the given id.
- // While a query is being executed or if no query has been executed, nullptr
- // will be returned for any |suggestion_id|. If |suggestion_id| is not in the
- // set of results given to the |listener| provided to the most recent
- // invocation of ExecuteQuery(), return nullptr.
- RankedSuggestion* GetSuggestion(const std::string& suggestion_uuid) const;
-
- // Cleans up all resources associated with a query, including clearing
- // the previous ask suggestions, closing any still open SuggestionListeners,
- // etc.
- void CleanUpPreviousQuery();
-
- private:
- // (proposer ID, proposal ID) => suggestion prototype
- using SuggestionPrototypeMap = std::map<std::pair<std::string, std::string>,
- std::unique_ptr<SuggestionPrototype>>;
-
- void AddProposal(const std::string& source_url,
- fuchsia::modular::Proposal proposal);
-
- void OnQueryResponse(fuchsia::modular::UserInput input,
- const std::string& handler_url,
- fuchsia::modular::QueryResponse response);
-
- void OnQueryEndRequest(fuchsia::modular::UserInput input);
-
- void NotifyOfResults();
-
- std::shared_ptr<SuggestionDebugImpl> debug_;
- RankedSuggestionsList suggestions_;
- SuggestionPrototypeMap query_prototypes_;
-
- // Unique ptr for the query runner executing the query being processed.
- std::unique_ptr<QueryRunner> active_query_;
-
- // The fuchsia::modular::ContextWriter that publishes the current user query
- // to the fuchsia::modular::ContextEngine.
- fuchsia::modular::ContextWriterPtr context_writer_;
-
- // The set of all QueryHandlers that have been registered mapped to their
- // URLs (stored as strings).
- std::vector<QueryHandlerRecord> query_handlers_;
-
- util::IdleWaiter::ActivityToken activity_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_PROCESSOR_H_
diff --git a/bin/suggestion_engine/query_runner.cc b/bin/suggestion_engine/query_runner.cc
deleted file mode 100644
index c6a4100..0000000
--- a/bin/suggestion_engine/query_runner.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-#include "peridot/bin/suggestion_engine/query_runner.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/zx/time.h>
-
-namespace modular {
-
-namespace {
-
-// Force queries to complete after some delay for better UX until/unless we can
-// bring back staggered results in a way that isn't jarring and doesn't overly
-// complicate the API.
-constexpr zx::duration kQueryTimeout = zx::sec(9);
-
-} // namespace
-
-class QueryRunner::HandlerRequest {
- public:
- HandlerRequest(fxl::WeakPtr<QueryRunner> runner,
- const std::string& handler_url)
- : runner_(runner), handler_url_(handler_url) {}
-
- ~HandlerRequest() {
- if (!runner_)
- return;
-
- if (completed_) {
- FXL_VLOG(1) << "Handler " << handler_url_ << " complete";
- } else {
- FXL_LOG(WARNING) << "Handler " << handler_url_
- << " closed without completing for query \""
- << runner_->input_.text << "\".";
- }
-
- // find + erase rather than erase key to properly handle duplicate URLs
- // (only remove one)
- runner_->outstanding_handlers_.erase(
- runner_->outstanding_handlers_.find(handler_url_));
- FXL_VLOG(1) << runner_->outstanding_handlers_.size() << " remaining";
- if (runner_->outstanding_handlers_.empty()) {
- runner_->EndRequest();
- }
- }
-
- void Complete(fuchsia::modular::QueryResponse response) {
- if (runner_) {
- runner_->on_query_response_callback_(handler_url_, std::move(response));
- completed_ = true;
- }
- }
-
- private:
- fxl::WeakPtr<QueryRunner> runner_;
- std::string handler_url_;
- bool completed_ = false;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(HandlerRequest);
-};
-
-QueryRunner::QueryRunner(
- fidl::InterfaceHandle<fuchsia::modular::QueryListener> listener,
- fuchsia::modular::UserInput input, int count)
- : listener_(listener.Bind()),
- input_(input),
- max_results_(count),
- request_ended_(false),
- weak_ptr_factory_(this) {}
-
-// TODO(rosswang): Consider moving some of the cleanup logic into here, but
-// beware that this may not happen until after the next QueryProcessor has been
-// constructed (active_query_ = std::make_unique...).
-QueryRunner::~QueryRunner() {
- if (!request_ended_) {
- EndRequest();
- }
-}
-
-void QueryRunner::Run(const std::vector<QueryHandlerRecord>& query_handlers) {
- if (query_handlers.empty()) {
- EndRequest();
- } else {
- for (const auto& handler_record : query_handlers) {
- DispatchQuery(handler_record);
- }
-
- async::PostDelayedTask(async_get_default_dispatcher(),
- [w = weak_ptr_factory_.GetWeakPtr()] {
- if (w) {
- w->TimeOut();
- }
- },
- kQueryTimeout);
- }
-}
-
-void QueryRunner::SetEndRequestCallback(std::function<void()> callback) {
- on_end_request_callback_ = std::move(callback);
-}
-
-void QueryRunner::SetResponseCallback(
- std::function<void(std::string, fuchsia::modular::QueryResponse)>
- callback) {
- on_query_response_callback_ = std::move(callback);
-}
-
-void QueryRunner::DispatchQuery(const QueryHandlerRecord& handler_record) {
- FXL_DCHECK(!request_ended_);
-
- outstanding_handlers_.insert(handler_record.url);
-
- handler_record.handler->OnQuery(
- input_, [request = std::make_shared<HandlerRequest>(
- weak_ptr_factory_.GetWeakPtr(), handler_record.url)](
- fuchsia::modular::QueryResponse response) {
- request->Complete(std::move(response));
- });
-}
-
-void QueryRunner::EndRequest() {
- FXL_DCHECK(!request_ended_);
- listener_->OnQueryComplete();
- on_end_request_callback_();
- weak_ptr_factory_.InvalidateWeakPtrs();
- request_ended_ = true;
-}
-
-void QueryRunner::TimeOut() {
- if (!outstanding_handlers_.empty()) {
- FXL_LOG(WARNING) << "Query timeout for \"" << input_.text
- << "\". Still awaiting results from:";
- for (const std::string& handler_url : outstanding_handlers_) {
- FXL_LOG(WARNING) << " " << handler_url;
- }
- EndRequest();
- }
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/query_runner.h b/bin/suggestion_engine/query_runner.h
deleted file mode 100644
index 1c78d38..0000000
--- a/bin/suggestion_engine/query_runner.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_RUNNER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_RUNNER_H_
-
-#include <set>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-namespace modular {
-
-struct QueryHandlerRecord;
-
-// QueryRunner is in charge of executing a query and interacting with the query
-// handlers, making sure all of them return or timeout if the query takes too
-// long to resolve. Through its callbacks it notifies when a query response
-// arrives and when all handlers finish processing the query or it times out.
-class QueryRunner {
- public:
- QueryRunner(fidl::InterfaceHandle<fuchsia::modular::QueryListener> listener,
- fuchsia::modular::UserInput input, int count);
- ~QueryRunner();
-
- // Starts running a query notifying the provided handlers and processes their
- // responses.
- void Run(const std::vector<QueryHandlerRecord>& query_handlers);
-
- // Sets a callback that will be executed when a query request ends.
- void SetEndRequestCallback(std::function<void()> callback);
-
- // Sets a callback that will be executed when a response for the query in
- // execution is received.
- void SetResponseCallback(
- std::function<void(std::string, fuchsia::modular::QueryResponse)>
- callback);
-
- fuchsia::modular::QueryListener* listener() const { return listener_.get(); }
- size_t max_results() const { return max_results_; }
-
- private:
- class HandlerRequest;
-
- void DispatchQuery(const QueryHandlerRecord& handler_record);
- void TimeOut();
- void EndRequest();
-
- fuchsia::modular::QueryListenerPtr listener_;
- const fuchsia::modular::UserInput input_;
- const size_t max_results_;
- bool request_ended_;
- fxl::WeakPtrFactory<QueryRunner> weak_ptr_factory_;
-
- std::function<void(std::string, fuchsia::modular::QueryResponse)>
- on_query_response_callback_;
- std::function<void()> on_end_request_callback_;
-
- std::multiset<std::string> outstanding_handlers_;
-};
-
-struct QueryHandlerRecord {
- QueryHandlerRecord(fuchsia::modular::QueryHandlerPtr handler, std::string url)
- : handler(std::move(handler)), url(std::move(url)) {}
-
- fuchsia::modular::QueryHandlerPtr handler;
- std::string url;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_QUERY_RUNNER_H_
diff --git a/bin/suggestion_engine/ranked_suggestion.cc b/bin/suggestion_engine/ranked_suggestion.cc
deleted file mode 100644
index 5c349b4..0000000
--- a/bin/suggestion_engine/ranked_suggestion.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-
-namespace modular {
-
-std::unique_ptr<RankedSuggestion> RankedSuggestion::New(
- SuggestionPrototype* prototype) {
- std::unique_ptr<RankedSuggestion> ranked_suggestion =
- std::make_unique<RankedSuggestion>();
- ranked_suggestion->prototype = prototype;
- ranked_suggestion->hidden = false;
- ranked_suggestion->interrupting = false;
- return ranked_suggestion;
-}
-
-fuchsia::modular::Suggestion CreateSuggestion(
- const RankedSuggestion& suggestion_data) {
- fuchsia::modular::Suggestion suggestion =
- CreateSuggestion(*suggestion_data.prototype);
- suggestion.confidence = suggestion_data.confidence;
- return suggestion;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranked_suggestion.h b/bin/suggestion_engine/ranked_suggestion.h
deleted file mode 100644
index fe7ab87..0000000
--- a/bin/suggestion_engine/ranked_suggestion.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKED_SUGGESTION_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKED_SUGGESTION_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/suggestion_prototype.h"
-
-namespace modular {
-
-// |rank| and |adjusted_confidence| should satisfy the invariant that for any
-// sorted set of ranked suggestions, |rank| is increasing and
-// |adjusted_confidence| is nonincreasing.
-struct RankedSuggestion {
- // Metadata of the suggestion.
- SuggestionPrototype* prototype;
-
- // Confidence of the suggestion. Updated during ranking.
- double confidence;
-
- // Whether or not the suggestion should be hidden (filtered by passive
- // filters) in the list and not returned when fetching next suggestions.
- bool hidden;
-
- // Whether or not the suggesiton is currently being used as interruption. It
- // should be filtered from the list that returns next suggestions.
- bool interrupting;
-
- static std::unique_ptr<RankedSuggestion> New(SuggestionPrototype* prototype);
-};
-
-fuchsia::modular::Suggestion CreateSuggestion(
- const RankedSuggestion& suggestion_data);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKED_SUGGESTION_H_
diff --git a/bin/suggestion_engine/ranked_suggestions_list.cc b/bin/suggestion_engine/ranked_suggestions_list.cc
deleted file mode 100644
index b4d80be..0000000
--- a/bin/suggestion_engine/ranked_suggestions_list.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranked_suggestions_list.h"
-
-#include <algorithm>
-#include <string>
-
-#include <lib/context/cpp/context_helper.h>
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-MatchPredicate GetSuggestionMatcher(const std::string& component_url,
- const std::string& proposal_id) {
- return [component_url,
- proposal_id](const std::unique_ptr<RankedSuggestion>& suggestion) {
- return (suggestion->prototype->proposal.id == proposal_id) &&
- (suggestion->prototype->source_url == component_url);
- };
-}
-
-MatchPredicate GetSuggestionMatcher(const std::string& suggestion_id) {
- return [suggestion_id](const std::unique_ptr<RankedSuggestion>& suggestion) {
- return suggestion->prototype->suggestion_id == suggestion_id;
- };
-}
-
-RankedSuggestionsList::RankedSuggestionsList() {}
-
-RankedSuggestionsList::~RankedSuggestionsList() = default;
-
-void RankedSuggestionsList::SetActiveFilters(
- std::vector<std::unique_ptr<SuggestionActiveFilter>>&& active_filters) {
- suggestion_active_filters_ = std::move(active_filters);
-}
-
-void RankedSuggestionsList::SetPassiveFilters(
- std::vector<std::unique_ptr<SuggestionPassiveFilter>>&& passive_filters) {
- suggestion_passive_filters_ = std::move(passive_filters);
-}
-
-void RankedSuggestionsList::SetRanker(std::unique_ptr<Ranker> ranker) {
- ranker_ = std::move(ranker);
-}
-
-RankedSuggestion* RankedSuggestionsList::GetMatchingSuggestion(
- MatchPredicate matchFunction) const {
- auto findIter =
- std::find_if(suggestions_.begin(), suggestions_.end(), matchFunction);
- if (findIter != suggestions_.end()) {
- return findIter->get();
- }
- return nullptr;
-}
-
-bool RankedSuggestionsList::RemoveMatchingSuggestion(
- MatchPredicate matchFunction) {
- auto remove_iter =
- std::remove_if(suggestions_.begin(), suggestions_.end(), matchFunction);
- if (remove_iter == suggestions_.end()) {
- return false;
- } else {
- suggestions_.erase(remove_iter, suggestions_.end());
- return true;
- }
-}
-
-void RankedSuggestionsList::Rank(const fuchsia::modular::UserInput& query) {
- if (!ranker_) {
- FXL_LOG(WARNING)
- << "RankedSuggestionList.Rank ignored since no ranker was set.";
- return;
- }
- for (auto& suggestion : suggestions_) {
- suggestion->confidence = ranker_->Rank(query, *suggestion);
- FXL_VLOG(1) << "fuchsia::modular::Proposal "
- << suggestion->prototype->proposal.display.headline
- << " confidence " << suggestion->prototype->proposal.confidence
- << " => " << suggestion->confidence;
- }
- DoStableSort();
-}
-
-void RankedSuggestionsList::AddSuggestion(SuggestionPrototype* prototype) {
- suggestions_.push_back(RankedSuggestion::New(prototype));
-}
-
-void RankedSuggestionsList::AddSuggestion(
- std::unique_ptr<RankedSuggestion> ranked_suggestion) {
- suggestions_.push_back(std::move(ranked_suggestion));
-}
-
-bool RankedSuggestionsList::RemoveProposal(const std::string& component_url,
- const std::string& proposal_id) {
- return RemoveMatchingSuggestion(
- GetSuggestionMatcher(component_url, proposal_id));
-}
-
-RankedSuggestion* RankedSuggestionsList::GetSuggestion(
- const std::string& suggestion_id) const {
- return GetMatchingSuggestion(GetSuggestionMatcher(suggestion_id));
-}
-
-RankedSuggestion* RankedSuggestionsList::GetSuggestion(
- const std::string& component_url, const std::string& proposal_id) const {
- return GetMatchingSuggestion(
- GetSuggestionMatcher(component_url, proposal_id));
-}
-
-void RankedSuggestionsList::RemoveAllSuggestions() { suggestions_.clear(); }
-
-void RankedSuggestionsList::Refresh(const fuchsia::modular::UserInput& query) {
- // Apply the active filters that modify the entire suggestions list.
- // TODO(miguelfrde): Fix. Currently not WAI. For dead stories for example,
- // this will remove suggestions that belong to a story that is being created.
- for (const auto& active_filter : suggestion_active_filters_) {
- active_filter->Filter(&suggestions_);
- }
-
- // Apply the passive filters that hide some of the suggestions.
- for (auto& suggestion : suggestions_) {
- suggestion->hidden = std::any_of(
- suggestion_passive_filters_.begin(), suggestion_passive_filters_.end(),
- [&suggestion](const std::unique_ptr<SuggestionPassiveFilter>& f) {
- return f->Filter(suggestion);
- });
- }
-
- // Rerank and sort the updated suggestions_ list
- Rank(query);
-}
-
-// Start of private sorting methods.
-
-void RankedSuggestionsList::DoStableSort() {
- std::stable_sort(suggestions_.begin(), suggestions_.end(),
- [](const std::unique_ptr<RankedSuggestion>& a,
- const std::unique_ptr<RankedSuggestion>& b) {
- return a->confidence > b->confidence;
- });
-}
-
-// End of private sorting methods.
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranked_suggestions_list.h b/bin/suggestion_engine/ranked_suggestions_list.h
deleted file mode 100644
index d48923e..0000000
--- a/bin/suggestion_engine/ranked_suggestions_list.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKED_SUGGESTIONS_LIST_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKED_SUGGESTIONS_LIST_H_
-
-#include <functional>
-#include <queue>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/filters/suggestion_active_filter.h"
-#include "peridot/bin/suggestion_engine/filters/suggestion_passive_filter.h"
-#include "peridot/bin/suggestion_engine/rankers/ranker.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-#include "peridot/bin/suggestion_engine/suggestion_prototype.h"
-
-namespace modular {
-using MatchPredicate =
- std::function<bool(const std::unique_ptr<RankedSuggestion>& suggestion)>;
-
-// Stores a list of RankedSuggestion objects and the features by which they
-// should be ranked. Ranking must be explicitly triggered via the Rank
-// method.
-class RankedSuggestionsList {
- public:
- RankedSuggestionsList();
- ~RankedSuggestionsList();
-
- void SetRanker(std::unique_ptr<Ranker> ranker);
-
- void SetActiveFilters(
- std::vector<std::unique_ptr<SuggestionActiveFilter>>&& active_filters);
-
- void SetPassiveFilters(
- std::vector<std::unique_ptr<SuggestionPassiveFilter>>&& passive_filters);
-
- void AddSuggestion(SuggestionPrototype* const prototype);
-
- void AddSuggestion(std::unique_ptr<RankedSuggestion> ranked_suggestion);
-
- // Returns |true| if and only if the suggestion was present and is removed.
- bool RemoveProposal(const std::string& component_url,
- const std::string& proposal_id);
-
- void RemoveAllSuggestions();
-
- RankedSuggestion* GetSuggestion(const std::string& suggestion_id) const;
-
- RankedSuggestion* GetSuggestion(const std::string& component_url,
- const std::string& proposal_id) const;
-
- const std::vector<std::unique_ptr<RankedSuggestion>>& Get() const {
- return suggestions_;
- }
-
- void Refresh(
- const fuchsia::modular::UserInput& query = fuchsia::modular::UserInput());
-
- private:
- RankedSuggestion* GetMatchingSuggestion(MatchPredicate matchFunction) const;
- bool RemoveMatchingSuggestion(MatchPredicate matchFunction);
- void DoStableSort();
- void Rank(
- const fuchsia::modular::UserInput& query = fuchsia::modular::UserInput());
-
- // The sorted vector of RankedSuggestions, sorted by
- // |ranking_function_|. The vector is re-sorted whenever its
- // contents are modified or when |ranking_function_| is updated.
- // TODO(jwnichols): Should ranking happen automatically or specifically
- // when requested? I think I would lean toward the latter, since ranking
- // may be expensive.
- std::vector<std::unique_ptr<RankedSuggestion>> suggestions_;
-
- std::unique_ptr<Ranker> ranker_;
-
- // The fuchsia::modular::Suggestion Filters associated with this List of
- // Ranked Suggestions
- std::vector<std::unique_ptr<SuggestionActiveFilter>>
- suggestion_active_filters_;
- std::vector<std::unique_ptr<SuggestionPassiveFilter>>
- suggestion_passive_filters_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKED_SUGGESTIONS_LIST_H_
diff --git a/bin/suggestion_engine/rankers/BUILD.gn b/bin/suggestion_engine/rankers/BUILD.gn
deleted file mode 100644
index f84d05b..0000000
--- a/bin/suggestion_engine/rankers/BUILD.gn
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-group("all") {
- public_deps = [
- ":linear_ranker",
- ":ranker",
- ]
-}
-
-source_set("ranker") {
- sources = [
- "ranker.cc",
- "ranker.h",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- public_deps = [
- "//peridot/bin/suggestion_engine:models",
- ]
-}
-
-source_set("linear_ranker") {
- sources = [
- "linear_ranker.cc",
- "linear_ranker.h",
- ]
-
- deps = [
- ":ranker",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- public_deps = [
- "//peridot/bin/suggestion_engine/ranking_features:ranking_feature",
- ]
-}
-
-executable("linear_ranker_unittest") {
- testonly = true
-
- sources = [
- "linear_ranker_unittest.cc",
- ]
-
- deps = [
- ":linear_ranker",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/suggestion_engine/rankers/linear_ranker.cc b/bin/suggestion_engine/rankers/linear_ranker.cc
deleted file mode 100644
index e856702..0000000
--- a/bin/suggestion_engine/rankers/linear_ranker.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/rankers/linear_ranker.h"
-
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-LinearRanker::LinearRanker() : normalization_factor_(0.0) {}
-
-LinearRanker::~LinearRanker() = default;
-
-void LinearRanker::AddRankingFeature(
- double weight, std::shared_ptr<RankingFeature> ranking_feature) {
- ranking_features_.emplace_back(weight, ranking_feature);
- // Only incorporate positive weights into the normalization factor.
- if (weight > 0.0) {
- normalization_factor_ += weight;
- }
-}
-
-double LinearRanker::Rank(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) {
- double confidence = 0.0;
- for (auto& feature : ranking_features_) {
- confidence +=
- feature.first * feature.second->ComputeFeature(query, suggestion);
- }
- // TODO(jwnichols): Reconsider this normalization approach.
- // Weights may be negative, so there is some chance that the calculated
- // confidence score will be negative. We pull the calculated score up to
- // zero to guarantee final confidence values stay within the 0-1 range.
- FXL_CHECK(normalization_factor_ > 0.0);
- return std::max(confidence, 0.0) / normalization_factor_;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/rankers/linear_ranker.h b/bin/suggestion_engine/rankers/linear_ranker.h
deleted file mode 100644
index fbc4f3c..0000000
--- a/bin/suggestion_engine/rankers/linear_ranker.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKERS_LINEAR_RANKER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKERS_LINEAR_RANKER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-#include "peridot/bin/suggestion_engine/rankers/ranker.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-// Ranks based on a linear combination using the set ranking features and its
-// weights.
-// Rank(q, x) =
-class LinearRanker : public Ranker {
- public:
- LinearRanker();
- ~LinearRanker() override;
-
- // Computes the new confidence of the suggestion.
- // Rank(q, s) = w_1*f_1(q, s) + w_2*f_2(q, s) + ... + w_i*f_i(q, s) where
- // f_i is a ranking feature and w_i is its weight provided through
- // AddRankingFeature.
- // The data from |query| and |suggestion| needed depends on the data each
- // ranking feature needs.
- double Rank(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override;
-
- // Sets a ranking feature and associates it to the given weight for the linear
- // combination.
- void AddRankingFeature(double weight,
- std::shared_ptr<RankingFeature> ranking_feature);
-
- private:
- // Ranking features as a list of (weight, feature) pairs
- std::vector<std::pair<double, std::shared_ptr<RankingFeature>>>
- ranking_features_;
-
- // The sum of the weights stored in the ranking_features_ vector
- double normalization_factor_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKERS_LINEAR_RANKER_H_
diff --git a/bin/suggestion_engine/rankers/linear_ranker_unittest.cc b/bin/suggestion_engine/rankers/linear_ranker_unittest.cc
deleted file mode 100644
index d0e3699..0000000
--- a/bin/suggestion_engine/rankers/linear_ranker_unittest.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/rankers/linear_ranker.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-namespace {
-
-class ConstantRankingFeature : public RankingFeature {
- public:
- ConstantRankingFeature(double value) : value_(value) {}
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override {
- return value_;
- };
-
- double value_;
-};
-
-class LinearRankerTest : public ::testing::Test {
- protected:
- fuchsia::modular::UserInput query_;
- RankedSuggestion suggestion_;
- LinearRanker ranker_;
-};
-
-TEST_F(LinearRankerTest, Rank) {
- // Performs a simple ranking operation with all positive values.
- // Operation: (1*1 + 4*0.5)/(1 + 4) = 0.6
- ranker_.AddRankingFeature(1, std::make_shared<ConstantRankingFeature>(1.0));
- ranker_.AddRankingFeature(4, std::make_shared<ConstantRankingFeature>(0.5));
- EXPECT_EQ(ranker_.Rank(query_, suggestion_), 0.6);
-}
-
-TEST_F(LinearRankerTest, RankIgnoreNegativeWeigthsForNormalization) {
- // Checks that negative weights are ignored for the normalization factor.
- // Operation: (4*0.5 - 1*1) / 4;
- ranker_.AddRankingFeature(4, std::make_shared<ConstantRankingFeature>(0.5));
- ranker_.AddRankingFeature(-1, std::make_shared<ConstantRankingFeature>(1.0));
- EXPECT_EQ(ranker_.Rank(query_, suggestion_), 0.25);
-}
-
-TEST_F(LinearRankerTest, RankZeroIfNegative) {
- // Makes the linear combination of ranking features and weights zero if it is
- // less than zero.
- // Operation: (-1*0.5 + 2*0.1)/2 = -0.3 => 0
- ranker_.AddRankingFeature(-1, std::make_shared<ConstantRankingFeature>(0.5));
- ranker_.AddRankingFeature(2, std::make_shared<ConstantRankingFeature>(0.1));
- EXPECT_EQ(ranker_.Rank(query_, suggestion_), 0.0);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/rankers/ranker.cc b/bin/suggestion_engine/rankers/ranker.cc
deleted file mode 100644
index 10bf09c..0000000
--- a/bin/suggestion_engine/rankers/ranker.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/rankers/ranker.h"
-
-namespace modular {
-
-Ranker::Ranker() = default;
-
-Ranker::~Ranker() = default;
-
-double Ranker::Rank(const RankedSuggestion& suggestion) {
- return Rank(fuchsia::modular::UserInput(), suggestion);
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/rankers/ranker.h b/bin/suggestion_engine/rankers/ranker.h
deleted file mode 100644
index 64f2a65..0000000
--- a/bin/suggestion_engine/rankers/ranker.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKERS_RANKER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKERS_RANKER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-
-namespace modular {
-
-// Base class for performing ranking on a suggestion.
-class Ranker {
- public:
- Ranker();
- virtual ~Ranker();
-
- // Ranks a suggestion based on a given query (which might be empty) and
- // returns the confidence that would be the new suggestion.confidence.
- virtual double Rank(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) = 0;
-
- // Ranks a suggestion without any query input.
- double Rank(const RankedSuggestion& suggestion);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKERS_RANKER_H_
diff --git a/bin/suggestion_engine/ranking_features/BUILD.gn b/bin/suggestion_engine/ranking_features/BUILD.gn
deleted file mode 100644
index 130d50f..0000000
--- a/bin/suggestion_engine/ranking_features/BUILD.gn
+++ /dev/null
@@ -1,253 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-group("all") {
- public_deps = [
- ":affinity_ranking_feature",
- ":annoyance_ranking_feature",
- ":dead_story_ranking_feature",
- ":interrupting_ranking_feature",
- ":kronk_ranking_feature",
- ":mod_pair_ranking_feature",
- ":proposal_hint_ranking_feature",
- ":query_match_ranking_feature",
- ":ranking_feature",
- ]
-}
-
-source_set("ranking_feature") {
- sources = [
- "ranking_feature.cc",
- "ranking_feature.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- ]
-
- public_deps = [
- "//peridot/bin/suggestion_engine:models",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/rapidjson",
- ]
-}
-
-source_set("annoyance_ranking_feature") {
- sources = [
- "annoyance_ranking_feature.cc",
- "annoyance_ranking_feature.h",
- ]
-
- public_deps = [
- ":ranking_feature",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("annoyance_ranking_feature_unittest") {
- testonly = true
-
- sources = [
- "annoyance_ranking_feature_unittest.cc",
- ]
-
- deps = [
- ":annoyance_ranking_feature",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("affinity_ranking_feature") {
- sources = [
- "affinity_ranking_feature.cc",
- "affinity_ranking_feature.h",
- ]
-
- public_deps = [
- ":ranking_feature",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("affinity_ranking_feature_unittest") {
- testonly = true
-
- sources = [
- "affinity_ranking_feature_unittest.cc",
- ]
-
- deps = [
- ":affinity_ranking_feature",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("interrupting_ranking_feature") {
- sources = [
- "interrupting_ranking_feature.cc",
- "interrupting_ranking_feature.h",
- ]
-
- public_deps = [
- ":ranking_feature",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("interrupting_ranking_feature_unittest") {
- testonly = true
-
- sources = [
- "interrupting_ranking_feature_unittest.cc",
- ]
-
- deps = [
- ":interrupting_ranking_feature",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("kronk_ranking_feature") {
- sources = [
- "kronk_ranking_feature.cc",
- "kronk_ranking_feature.h",
- ]
-
- public_deps = [
- ":ranking_feature",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("kronk_ranking_feature_unittest") {
- testonly = true
-
- sources = [
- "kronk_ranking_feature_unittest.cc",
- ]
-
- deps = [
- ":kronk_ranking_feature",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("mod_pair_ranking_feature") {
- sources = [
- "mod_pair_ranking_feature.cc",
- "mod_pair_ranking_feature.h",
- ]
-
- public_deps = [
- ":ranking_feature",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/lib/context/cpp:context_helper",
- "//third_party/rapidjson",
- ]
-}
-
-executable("mod_pair_ranking_feature_unittest") {
- testonly = true
-
- sources = [
- "mod_pair_ranking_feature_unittest.cc",
- ]
-
- deps = [
- ":mod_pair_ranking_feature",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("proposal_hint_ranking_feature") {
- sources = [
- "proposal_hint_ranking_feature.cc",
- "proposal_hint_ranking_feature.h",
- ]
-
- public_deps = [
- ":ranking_feature",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("proposal_hint_ranking_feature_unittest") {
- testonly = true
-
- sources = [
- "proposal_hint_ranking_feature_unittest.cc",
- ]
-
- deps = [
- ":proposal_hint_ranking_feature",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("query_match_ranking_feature") {
- sources = [
- "query_match_ranking_feature.cc",
- "query_match_ranking_feature.h",
- ]
-
- public_deps = [
- ":ranking_feature",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("query_match_ranking_feature_unittest") {
- testonly = true
-
- sources = [
- "query_match_ranking_feature_unittest.cc",
- ]
-
- deps = [
- ":query_match_ranking_feature",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-source_set("dead_story_ranking_feature") {
- sources = [
- "dead_story_ranking_feature.cc",
- "dead_story_ranking_feature.h",
- ]
-
- public_deps = [
- ":ranking_feature",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-executable("dead_story_ranking_feature_unittest") {
- testonly = true
-
- sources = [
- "dead_story_ranking_feature_unittest.cc",
- ]
-
- deps = [
- ":dead_story_ranking_feature",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/bin/suggestion_engine/ranking_features/affinity_ranking_feature.cc b/bin/suggestion_engine/ranking_features/affinity_ranking_feature.cc
deleted file mode 100644
index 4b26092..0000000
--- a/bin/suggestion_engine/ranking_features/affinity_ranking_feature.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/affinity_ranking_feature.h"
-
-#include <lib/fsl/types/type_converters.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/join_strings.h>
-#include <lib/fxl/type_converter.h>
-
-namespace modular {
-
-namespace {
-
-bool MatchesMod(const fuchsia::modular::ModuleAffinity& affinity,
- const std::vector<std::string>& mod_path,
- const std::string& affinity_story) {
- // If the stories are not the same return early.
- if (affinity.story_name != affinity_story) {
- return false;
- }
-
- // Since module_paths are composed using the name of the parent view (note
- // this is how it's working today, but not how it should be expected to work.
- // Module names are opaque identifiers we shouldn't rely on for this kind of
- // logic), we compare the one in focused with the affinity we are interested.
- // Exmaple:
- // - In focus: a/b/c
- // - Affinity: a/b
- // Since the name is the same up to a/b, then we have higher confidence.
- // TODO(miguelfrde): rather than using this in a boolean fashion, return a
- // meaningful confidence that represents this behavior and supports cases such
- // as a/b/c vs a/d. For the case above it could be 0.66 and for the case of
- // a/d 0.33.
- for (uint32_t i = 0; i < mod_path.size(); i++) {
- if (i >= affinity.module_name.size()) {
- break;
- }
- if (mod_path.at(i) != affinity.module_name.at(i)) {
- return false;
- }
- }
-
- return true;
-}
-
-} // namespace
-
-AffinityRankingFeature::AffinityRankingFeature() {}
-
-AffinityRankingFeature::~AffinityRankingFeature() = default;
-
-double AffinityRankingFeature::ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) {
- const auto& proposal = suggestion.prototype->proposal;
- if (proposal.affinity.empty()) {
- return kMaxConfidence;
- }
- for (const auto& context_value : *ContextValues()) {
- const auto& affinity_story_id = context_value.meta.story->id;
- for (const auto& affinity : proposal.affinity) {
- if (affinity.is_story_affinity() &&
- affinity_story_id == affinity.story_affinity().story_name) {
- return kMaxConfidence;
- }
- if (affinity.is_module_affinity() &&
- MatchesMod(affinity.module_affinity(), context_value.meta.mod->path,
- affinity_story_id)) {
- return kMaxConfidence;
- }
- }
- }
- return kMinConfidence;
-}
-
-fuchsia::modular::ContextSelectorPtr
-AffinityRankingFeature::CreateContextSelectorInternal() {
- // Get currently focused mod and in focused story.
- auto selector = fuchsia::modular::ContextSelector::New();
- selector->type = fuchsia::modular::ContextValueType::MODULE;
- selector->meta = fuchsia::modular::ContextMetadata::New();
- selector->meta->story = fuchsia::modular::StoryMetadata::New();
- selector->meta->story->focused = fuchsia::modular::FocusedState::New();
- selector->meta->story->focused->state =
- fuchsia::modular::FocusedStateState::FOCUSED;
- selector->meta->mod = fuchsia::modular::ModuleMetadata::New();
- selector->meta->mod->focused = fuchsia::modular::FocusedState::New();
- selector->meta->mod->focused->state =
- fuchsia::modular::FocusedStateState::FOCUSED;
- return selector;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/affinity_ranking_feature.h b/bin/suggestion_engine/ranking_features/affinity_ranking_feature.h
deleted file mode 100644
index 90fc0e4..0000000
--- a/bin/suggestion_engine/ranking_features/affinity_ranking_feature.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_AFFINITY_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_AFFINITY_RANKING_FEATURE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class AffinityRankingFeature : public RankingFeature {
- public:
- AffinityRankingFeature();
- ~AffinityRankingFeature() override;
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override;
-
- fuchsia::modular::ContextSelectorPtr CreateContextSelectorInternal() override;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_AFFINITY_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/ranking_features/affinity_ranking_feature_unittest.cc b/bin/suggestion_engine/ranking_features/affinity_ranking_feature_unittest.cc
deleted file mode 100644
index e6978cc..0000000
--- a/bin/suggestion_engine/ranking_features/affinity_ranking_feature_unittest.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/affinity_ranking_feature.h"
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class AffinityRankingFeatureTest : public ::testing::Test {
- protected:
- AffinityRankingFeature affinity_feature;
- fuchsia::modular::UserInput query;
-};
-
-// Creates the values from a context query to mock the modules in a focused
-// story based on which this ranking feature computes its value.
-void SetStoryAffinityContextUpdate(
- fidl::VectorPtr<fuchsia::modular::ContextValue>& context_update,
- const std::string& story_id) {
- fuchsia::modular::ContextValue value;
- value.meta.story = fuchsia::modular::StoryMetadata::New();
- value.meta.story->id = story_id;
- context_update.push_back(std::move(value));
-}
-
-void SetModuleAffinityContextUpdate(
- fidl::VectorPtr<fuchsia::modular::ContextValue>& context_update,
- const std::string& story_id, std::vector<std::string> mod_path) {
- fuchsia::modular::ContextValue value;
- value.meta.story = fuchsia::modular::StoryMetadata::New();
- value.meta.story->id = story_id;
- value.meta.mod = fuchsia::modular::ModuleMetadata::New();
- value.meta.mod->focused = fuchsia::modular::FocusedState::New();
- value.meta.mod->focused->state = fuchsia::modular::FocusedStateState::FOCUSED;
- for (auto& mod_path_part : mod_path) {
- value.meta.mod->path.push_back(mod_path_part);
- }
- context_update.push_back(std::move(value));
-}
-
-SuggestionPrototype BuildSuggestionPrototype() {
- fuchsia::modular::Proposal proposal;
- SuggestionPrototype prototype;
- prototype.source_url = "fake_url";
- prototype.proposal = std::move(proposal);
- return prototype;
-}
-
-SuggestionPrototype BuildSuggestionPrototypeWithStoryAffinity(
- std::string story_name) {
- auto prototype = BuildSuggestionPrototype();
- auto& proposal = prototype.proposal;
- fuchsia::modular::StoryAffinity story_affinity;
- story_affinity.story_name = story_name;
- fuchsia::modular::ProposalAffinity affinity;
- affinity.set_story_affinity(std::move(story_affinity));
- proposal.affinity.push_back(std::move(affinity));
- return prototype;
-}
-
-SuggestionPrototype BuildSuggestionPrototypeWithModuleAffinity(
- std::string story_name, std::string mod_name) {
- auto prototype = BuildSuggestionPrototype();
- auto& proposal = prototype.proposal;
- fuchsia::modular::ModuleAffinity module_affinity;
- module_affinity.story_name = story_name;
- module_affinity.module_name.push_back(mod_name);
- fuchsia::modular::ProposalAffinity affinity;
- affinity.set_module_affinity(std::move(module_affinity));
- proposal.affinity.push_back(std::move(affinity));
- return prototype;
-}
-
-TEST_F(AffinityRankingFeatureTest, ComputeFeatureStoryAffinity) {
- auto prototype = BuildSuggestionPrototypeWithStoryAffinity("affinity");
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetStoryAffinityContextUpdate(context_update, "affinity");
- affinity_feature.UpdateContext(context_update);
-
- double value = affinity_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 1.0);
-}
-
-TEST_F(AffinityRankingFeatureTest, ComputeFeatureNonAffinity) {
- auto prototype = BuildSuggestionPrototypeWithStoryAffinity("other_story");
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetStoryAffinityContextUpdate(context_update, "affinity");
- affinity_feature.UpdateContext(context_update);
-
- double value = affinity_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 0.0);
-}
-
-TEST_F(AffinityRankingFeatureTest, ComputeFeatureNonAffinityNoStoryAffinity) {
- auto prototype = BuildSuggestionPrototype();
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetStoryAffinityContextUpdate(context_update, "affinity");
- affinity_feature.UpdateContext(context_update);
-
- double value = affinity_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 1.0);
-}
-
-TEST_F(AffinityRankingFeatureTest, ComputeFeatureModAffinity) {
- auto prototype =
- BuildSuggestionPrototypeWithModuleAffinity("affinity", "mod_a");
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetModuleAffinityContextUpdate(context_update, "affinity", {"mod_a"});
- affinity_feature.UpdateContext(context_update);
-
- double value = affinity_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 1.0);
-}
-
-TEST_F(AffinityRankingFeatureTest, ComputeFeatureModNonAffinity) {
- auto prototype =
- BuildSuggestionPrototypeWithModuleAffinity("affinity", "mod_a");
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetModuleAffinityContextUpdate(context_update, "affinity", {"other_mod"});
- affinity_feature.UpdateContext(context_update);
-
- double value = affinity_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 0.0);
-}
-
-TEST_F(AffinityRankingFeatureTest, ComputeFeatureParentModAffinity) {
- // TODO(miguelfrde): instead of returning 1.0 we should update this to return
- // 0.5. There's a relevant note in the implementation.
- auto prototype =
- BuildSuggestionPrototypeWithModuleAffinity("affinity", "mod_a");
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetModuleAffinityContextUpdate(context_update, "affinity",
- {"mod_a", "mod_b"});
- affinity_feature.UpdateContext(context_update);
-
- double value = affinity_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 1.0);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.cc b/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.cc
deleted file mode 100644
index 57c3664..0000000
--- a/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.h"
-
-namespace modular {
-
-AnnoyanceRankingFeature::AnnoyanceRankingFeature() = default;
-
-AnnoyanceRankingFeature::~AnnoyanceRankingFeature() = default;
-
-double AnnoyanceRankingFeature::ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) {
- if (suggestion.prototype->proposal.display.annoyance !=
- fuchsia::modular::AnnoyanceType::NONE) {
- return kMaxConfidence;
- }
- return kMinConfidence;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.h b/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.h
deleted file mode 100644
index 8898990..0000000
--- a/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_ANNOYANCE_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_ANNOYANCE_RANKING_FEATURE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class AnnoyanceRankingFeature : public RankingFeature {
- public:
- AnnoyanceRankingFeature();
- ~AnnoyanceRankingFeature() override;
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_ANNOYANCE_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/ranking_features/annoyance_ranking_feature_unittest.cc b/bin/suggestion_engine/ranking_features/annoyance_ranking_feature_unittest.cc
deleted file mode 100644
index 39bc471..0000000
--- a/bin/suggestion_engine/ranking_features/annoyance_ranking_feature_unittest.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.h"
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class AnnoyanceRankingFeatureTest : public ::testing::Test {
- protected:
- RankedSuggestion GetSuggestion(fuchsia::modular::AnnoyanceType annoyance) {
- fuchsia::modular::SuggestionDisplay display;
- display.annoyance = annoyance;
- fuchsia::modular::Proposal proposal;
- proposal.display = std::move(display);
- SuggestionPrototype prototype;
- prototype.proposal = std::move(proposal);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
- return suggestion;
- }
- AnnoyanceRankingFeature annoyance_ranking_feature;
- fuchsia::modular::UserInput query;
-};
-
-TEST_F(AnnoyanceRankingFeatureTest, ComputeFeatureAnnoyance) {
- auto suggestion = GetSuggestion(fuchsia::modular::AnnoyanceType::INTERRUPT);
- double value = annoyance_ranking_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, kMaxConfidence);
-}
-
-TEST_F(AnnoyanceRankingFeatureTest, ComputeFeatureNonAnnoyance) {
- auto suggestion = GetSuggestion(fuchsia::modular::AnnoyanceType::NONE);
- double value = annoyance_ranking_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, kMinConfidence);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.cc b/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.cc
deleted file mode 100644
index fcd99a7..0000000
--- a/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace modular {
-
-DeadStoryRankingFeature::DeadStoryRankingFeature() {}
-
-DeadStoryRankingFeature::~DeadStoryRankingFeature() = default;
-
-double DeadStoryRankingFeature::ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& ranked_suggestion) {
- const auto& proposal = ranked_suggestion.prototype->proposal;
-
- // Proposal not tied to any story.
- if (proposal.affinity.empty()) {
- return kMinConfidence;
- }
-
- // TODO(miguelfrde): cache ids of stories in context in an unordered_set for
- // average O(1) lookup.
- for (const auto& context_value : *ContextValues()) {
- const auto& story_name = context_value.meta.story->id;
- for (const auto& affinity : proposal.affinity) {
- switch (affinity.Which()) {
- case fuchsia::modular::ProposalAffinity::Tag::kModuleAffinity:
- if (story_name == affinity.module_affinity().story_name) {
- return kMinConfidence;
- }
- break;
- case fuchsia::modular::ProposalAffinity::Tag::kStoryAffinity:
- if (story_name == affinity.story_affinity().story_name) {
- return kMinConfidence;
- }
- break;
- default:
- break;
- }
- }
- }
- return kMaxConfidence;
-}
-
-fuchsia::modular::ContextSelectorPtr
-DeadStoryRankingFeature::CreateContextSelectorInternal() {
- // Get stories in context.
- auto selector = fuchsia::modular::ContextSelector::New();
- selector->type = fuchsia::modular::ContextValueType::STORY;
- return selector;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.h b/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.h
deleted file mode 100644
index 0a58171..0000000
--- a/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_DEAD_STORY_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_DEAD_STORY_RANKING_FEATURE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class DeadStoryRankingFeature : public RankingFeature {
- public:
- DeadStoryRankingFeature();
- ~DeadStoryRankingFeature() override;
-
- private:
- double ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& ranked_suggestion) override;
-
- fuchsia::modular::ContextSelectorPtr CreateContextSelectorInternal() override;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_DEAD_STORY_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/ranking_features/dead_story_ranking_feature_unittest.cc b/bin/suggestion_engine/ranking_features/dead_story_ranking_feature_unittest.cc
deleted file mode 100644
index cbb1d94..0000000
--- a/bin/suggestion_engine/ranking_features/dead_story_ranking_feature_unittest.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.h"
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class DeadStoryRankingFeatureTest : public ::testing::Test {
- protected:
- fuchsia::modular::UserInput query;
- DeadStoryRankingFeature dead_story_feature;
-};
-
-// Creates the values from a context query to mock the modules in a focused
-// story based on which this ranking feature computes its value.
-void SetRunningStoryContextUpdate(
- fidl::VectorPtr<fuchsia::modular::ContextValue>& context_update) {
- fuchsia::modular::ContextValue value;
- value.meta.story = fuchsia::modular::StoryMetadata::New();
- value.meta.story->id = "running_story";
- context_update.push_back(std::move(value));
-}
-
-SuggestionPrototype BuildSuggestionPrototype(std::string story_name,
- bool has_story_affinity) {
- fuchsia::modular::Proposal proposal;
- if (has_story_affinity) {
- fuchsia::modular::StoryAffinity story_affinity;
- story_affinity.story_name = story_name;
- fuchsia::modular::ProposalAffinity affinity;
- affinity.set_story_affinity(std::move(story_affinity));
- proposal.affinity.push_back(std::move(affinity));
- }
- SuggestionPrototype prototype;
- prototype.source_url = "fake_url";
- prototype.proposal = std::move(proposal);
- return prototype;
-}
-
-TEST_F(DeadStoryRankingFeatureTest, RunningStoryAndAffinity) {
- auto prototype = BuildSuggestionPrototype("running_story", true);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetRunningStoryContextUpdate(context_update);
- dead_story_feature.UpdateContext(context_update);
- double value = dead_story_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 0.0);
-}
-
-TEST_F(DeadStoryRankingFeatureTest, RunningButNoAffinity) {
- auto prototype = BuildSuggestionPrototype("running_story", false);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetRunningStoryContextUpdate(context_update);
- dead_story_feature.UpdateContext(context_update);
- double value = dead_story_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 0.0);
-}
-
-TEST_F(DeadStoryRankingFeatureTest, NotRunningAndNoAffinity) {
- auto prototype = BuildSuggestionPrototype("dead_story", false);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetRunningStoryContextUpdate(context_update);
- dead_story_feature.UpdateContext(context_update);
- double value = dead_story_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 0.0);
-}
-
-TEST_F(DeadStoryRankingFeatureTest, NotRunningStoryAndAffinity) {
- auto prototype = BuildSuggestionPrototype("dead_story", true);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- SetRunningStoryContextUpdate(context_update);
- dead_story_feature.UpdateContext(context_update);
- double value = dead_story_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 1.0);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.cc b/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.cc
deleted file mode 100644
index 2aedf41..0000000
--- a/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.h"
-
-namespace modular {
-
-InterruptingRankingFeature::InterruptingRankingFeature() {}
-
-InterruptingRankingFeature::~InterruptingRankingFeature() = default;
-
-double InterruptingRankingFeature::ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& ranked_suggestion) {
- if (ranked_suggestion.interrupting) {
- return kMaxConfidence;
- }
- return kMinConfidence;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.h b/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.h
deleted file mode 100644
index 7509ea9..0000000
--- a/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_INTERRUPTING_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_INTERRUPTING_RANKING_FEATURE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class InterruptingRankingFeature : public RankingFeature {
- public:
- InterruptingRankingFeature();
- ~InterruptingRankingFeature() override;
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_INTERRUPTING_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/ranking_features/interrupting_ranking_feature_unittest.cc b/bin/suggestion_engine/ranking_features/interrupting_ranking_feature_unittest.cc
deleted file mode 100644
index 7b8a926..0000000
--- a/bin/suggestion_engine/ranking_features/interrupting_ranking_feature_unittest.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.h"
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class InterruptingRankingFeatureTest : public ::testing::Test {
- protected:
- InterruptingRankingFeature ranking_feature;
- fuchsia::modular::UserInput query;
-};
-
-TEST_F(InterruptingRankingFeatureTest, ComputeFeatureInterrupting) {
- RankedSuggestion suggestion;
- suggestion.interrupting = true;
-
- double value = ranking_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 1.0);
-}
-
-TEST_F(InterruptingRankingFeatureTest, ComputeFeatureNonInterrupting) {
- RankedSuggestion suggestion;
- suggestion.interrupting = false;
-
- double value = ranking_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 0.0);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/kronk_ranking_feature.cc b/bin/suggestion_engine/ranking_features/kronk_ranking_feature.cc
deleted file mode 100644
index 1f7ddac..0000000
--- a/bin/suggestion_engine/ranking_features/kronk_ranking_feature.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/kronk_ranking_feature.h"
-
-namespace modular {
-
-KronkRankingFeature::KronkRankingFeature() = default;
-
-KronkRankingFeature::~KronkRankingFeature() = default;
-
-double KronkRankingFeature::ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) {
- if (suggestion.prototype->source_url.find("kronk") != std::string::npos) {
- return kMaxConfidence;
- } else {
- return kMinConfidence;
- }
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/kronk_ranking_feature.h b/bin/suggestion_engine/ranking_features/kronk_ranking_feature.h
deleted file mode 100644
index dcceede..0000000
--- a/bin/suggestion_engine/ranking_features/kronk_ranking_feature.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_KRONK_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_KRONK_RANKING_FEATURE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class KronkRankingFeature : public RankingFeature {
- public:
- KronkRankingFeature();
- ~KronkRankingFeature() override;
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_KRONK_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/ranking_features/kronk_ranking_feature_unittest.cc b/bin/suggestion_engine/ranking_features/kronk_ranking_feature_unittest.cc
deleted file mode 100644
index b24635a..0000000
--- a/bin/suggestion_engine/ranking_features/kronk_ranking_feature_unittest.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/kronk_ranking_feature.h"
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class KronkRankingFeatureTest : public ::testing::Test {
- protected:
- KronkRankingFeature kronk_ranking_feature;
- fuchsia::modular::UserInput query;
-};
-
-TEST_F(KronkRankingFeatureTest, TestComputeFeatureKronk) {
- SuggestionPrototype prototype;
- prototype.source_url = "kronk";
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
- double value = kronk_ranking_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, kMaxConfidence);
-}
-
-TEST_F(KronkRankingFeatureTest, TestComputeFeatureNonKronk) {
- SuggestionPrototype prototype;
- prototype.source_url = "chat";
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
- double value = kronk_ranking_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, kMinConfidence);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.cc b/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.cc
deleted file mode 100644
index 7064b61..0000000
--- a/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.h"
-
-#include <lib/context/cpp/context_helper.h>
-#include <lib/fxl/logging.h>
-
-#include "rapidjson/document.h"
-#include "rapidjson/schema.h"
-
-namespace modular {
-
-namespace {
-// Sample map using data collected between Feb 6-20, 2018
-constexpr char kDataFilePath[] = "/pkg/data/ranking_data/mod_pairs.json";
-} // namespace
-
-ModPairRankingFeature::ModPairRankingFeature(const bool init_data) {
- if (init_data) {
- LoadDataFromFile(kDataFilePath);
- }
-}
-
-ModPairRankingFeature::~ModPairRankingFeature() = default;
-
-void ModPairRankingFeature::LoadDataFromFile(const std::string& filepath) {
- auto maybe_result = FetchJsonObject(filepath);
- if (!maybe_result.has_value()) {
- FXL_LOG(WARNING) << "Failed to fetch mod pairs ranking feature data.";
- return;
- }
- auto& result = maybe_result.value();
- module_pairs_.clear();
- for (rapidjson::Value::ConstMemberIterator iter = result.MemberBegin();
- iter != result.MemberEnd(); ++iter) {
- const std::string existing_mod_url = iter->name.GetString();
- rapidjson::Value& other_mods = result[existing_mod_url.c_str()];
- for (rapidjson::Value::ConstMemberIterator iter2 = other_mods.MemberBegin();
- iter2 != other_mods.MemberEnd(); ++iter2) {
- const std::string added_mod_url = iter2->name.GetString();
- module_pairs_[existing_mod_url][added_mod_url] = iter2->value.GetDouble();
- }
- }
-}
-
-double ModPairRankingFeature::ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) {
- double prob = 0.0;
-
- for (auto& command : suggestion.prototype->proposal.on_selected) {
- fidl::StringPtr module_url;
- switch (command.Which()) {
- case fuchsia::modular::StoryCommand::Tag::kAddMod: {
- module_url = command.add_mod().intent.handler;
- break;
- }
- case fuchsia::modular::StoryCommand::Tag::kSetKindOfProtoStoryOption:
- case fuchsia::modular::StoryCommand::Tag::kSetFocusState:
- case fuchsia::modular::StoryCommand::Tag::kFocusMod:
- case fuchsia::modular::StoryCommand::Tag::kSetLinkValue:
- case fuchsia::modular::StoryCommand::Tag::kRemoveMod:
- case fuchsia::modular::StoryCommand::Tag::Invalid:
- continue;
- }
- if (module_url.is_null() || module_url->empty()) {
- continue;
- }
- // Currently computing: max{P(m|mi) for mi in modules_in_source_story}
- // TODO(miguelfrde): compute P(module_url | modules in source story)
- for (auto& context_value : *ContextValues()) {
- const std::string existing_mod_url = context_value.meta.mod->url;
- if (module_pairs_.count(existing_mod_url) &&
- module_pairs_[existing_mod_url].count(module_url)) {
- prob = std::max(prob, module_pairs_[existing_mod_url][module_url]);
- }
- }
- }
- return prob;
-}
-
-fuchsia::modular::ContextSelectorPtr
-ModPairRankingFeature::CreateContextSelectorInternal() {
- // Get modules in the currently focused story.
- auto selector = fuchsia::modular::ContextSelector::New();
- selector->type = fuchsia::modular::ContextValueType::MODULE;
- selector->meta = fuchsia::modular::ContextMetadata::New();
- selector->meta->story = fuchsia::modular::StoryMetadata::New();
- selector->meta->story->focused = fuchsia::modular::FocusedState::New();
- selector->meta->story->focused->state =
- fuchsia::modular::FocusedStateState::FOCUSED;
- return selector;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.h b/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.h
deleted file mode 100644
index 7dedf81..0000000
--- a/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_MOD_PAIR_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_MOD_PAIR_RANKING_FEATURE_H_
-
-#include <unordered_map>
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class ModPairRankingFeature : public RankingFeature {
- public:
- ModPairRankingFeature(bool init_data = true);
- ~ModPairRankingFeature() override;
-
- void LoadDataFromFile(const std::string& filepath);
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override;
-
- fuchsia::modular::ContextSelectorPtr CreateContextSelectorInternal() override;
-
- std::unordered_map<std::string, std::unordered_map<std::string, double>>
- module_pairs_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_MOD_PAIR_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature_unittest.cc b/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature_unittest.cc
deleted file mode 100644
index 74fadac..0000000
--- a/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature_unittest.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.h"
-
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/files/path.h>
-#include <lib/fxl/files/scoped_temp_dir.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-constexpr char kTestData[] = R"({
- "mod1": {
- "mod2": 0.5,
- "mod3": 0.5
- },
- "mod2": {
- "mod3": 1.0
- },
- "mod3": {
- "mod1": 0.2,
- "mod4": 0.8
- }
-})";
-
-class ModPairRankingFeatureTest : public ::testing::Test {
- public:
- void SetUp() override {
- std::string tmp_file;
- ASSERT_TRUE(CreateFile(kTestData, &tmp_file));
- mod_pair_feature.LoadDataFromFile(tmp_file);
- }
-
- protected:
- ModPairRankingFeature mod_pair_feature{false};
- fuchsia::modular::UserInput query;
-
- private:
- bool CreateFile(const std::string& content, std::string* const tmp_file) {
- if (!tmp_dir_.NewTempFile(tmp_file)) {
- return false;
- }
- return files::WriteFile(*tmp_file, content.c_str(), content.size());
- }
-
- files::ScopedTempDir tmp_dir_;
-};
-
-// Creates the values from a context query to mock the modules in a focused
-// story based on which this ranking feature computes its value.
-void AddValueToContextUpdate(
- fidl::VectorPtr<fuchsia::modular::ContextValue>& context_update,
- const std::string& mod) {
- fuchsia::modular::ContextValue value;
- value.meta.mod = fuchsia::modular::ModuleMetadata::New();
- value.meta.mod->url = mod;
- context_update.push_back(std::move(value));
-}
-
-TEST_F(ModPairRankingFeatureTest, ComputeFeatureAddModuleAction) {
- fuchsia::modular::Intent intent;
- intent.handler = "mod4";
- fuchsia::modular::AddMod add_mod;
- add_mod.intent = std::move(intent);
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- fuchsia::modular::Proposal proposal;
- proposal.on_selected.push_back(std::move(command));
- SuggestionPrototype prototype;
- prototype.proposal = std::move(proposal);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- AddValueToContextUpdate(context_update, "mod3");
- mod_pair_feature.UpdateContext(std::move(context_update));
- double value = mod_pair_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 0.8);
-}
-
-TEST_F(ModPairRankingFeatureTest, ComputeFeatureNoModule) {
- fuchsia::modular::Intent intent;
- intent.handler = "mod-fiction";
- fuchsia::modular::AddMod add_mod;
- add_mod.intent = std::move(intent);
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- fuchsia::modular::Proposal proposal;
- proposal.on_selected.push_back(std::move(command));
- SuggestionPrototype prototype;
- prototype.proposal = std::move(proposal);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- AddValueToContextUpdate(context_update, "mod1");
- mod_pair_feature.UpdateContext(std::move(context_update));
- double value = mod_pair_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, kMinConfidence);
-}
-
-TEST_F(ModPairRankingFeatureTest, ComputeFeatureMultipleActions) {
- fuchsia::modular::AddMod add_mod;
- add_mod.intent.handler = "mod-fiction";
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- fuchsia::modular::Proposal proposal;
- proposal.on_selected.push_back(std::move(command));
- SuggestionPrototype prototype;
- prototype.proposal = std::move(proposal);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- add_mod = fuchsia::modular::AddMod();
- add_mod.intent.handler = "mod3";
- fuchsia::modular::StoryCommand command2;
- command2.set_add_mod(std::move(add_mod));
- suggestion.prototype->proposal.on_selected.push_back(std::move(command2));
-
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_update;
- AddValueToContextUpdate(context_update, "mod1");
- AddValueToContextUpdate(context_update, "mod2");
- mod_pair_feature.UpdateContext(std::move(context_update));
- double value = mod_pair_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 1.0);
-}
-
-TEST_F(ModPairRankingFeatureTest, CreateContextSelector) {
- auto selector = mod_pair_feature.CreateContextSelector();
- EXPECT_NE(selector, nullptr);
- EXPECT_EQ(selector->type, fuchsia::modular::ContextValueType::MODULE);
- EXPECT_EQ(selector->meta->story->focused->state,
- fuchsia::modular::FocusedStateState::FOCUSED);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.cc b/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.cc
deleted file mode 100644
index 34c528b..0000000
--- a/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.h"
-
-namespace modular {
-
-ProposalHintRankingFeature::ProposalHintRankingFeature() = default;
-
-ProposalHintRankingFeature::~ProposalHintRankingFeature() = default;
-
-double ProposalHintRankingFeature::ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) {
- return suggestion.prototype->proposal.confidence;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.h b/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.h
deleted file mode 100644
index 3dbe514..0000000
--- a/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_PROPOSAL_HINT_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_PROPOSAL_HINT_RANKING_FEATURE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class ProposalHintRankingFeature : public RankingFeature {
- public:
- ProposalHintRankingFeature();
- ~ProposalHintRankingFeature() override;
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_PROPOSAL_HINT_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature_unittest.cc b/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature_unittest.cc
deleted file mode 100644
index 6e8fafd..0000000
--- a/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature_unittest.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.h"
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class ProposalHintRankingFeatureTest : public ::testing::Test {
- protected:
- ProposalHintRankingFeature proposal_hint_feature;
- fuchsia::modular::UserInput query;
-};
-
-TEST_F(ProposalHintRankingFeatureTest, TestComputeFeature) {
- fuchsia::modular::Proposal proposal;
- proposal.confidence = 0.5;
- SuggestionPrototype prototype;
- prototype.proposal = std::move(proposal);
- prototype.source_url = "chat";
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
- double value = proposal_hint_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, 0.5);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/query_match_ranking_feature.cc b/bin/suggestion_engine/ranking_features/query_match_ranking_feature.cc
deleted file mode 100644
index 3d3cc8f..0000000
--- a/bin/suggestion_engine/ranking_features/query_match_ranking_feature.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/query_match_ranking_feature.h"
-
-namespace modular {
-
-QueryMatchRankingFeature::QueryMatchRankingFeature() = default;
-
-QueryMatchRankingFeature::~QueryMatchRankingFeature() = default;
-
-double QueryMatchRankingFeature::ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) {
- std::string text = suggestion.prototype->proposal.display.headline;
- std::string norm_query = query.text;
-
- std::transform(text.begin(), text.end(), text.begin(), ::tolower);
- std::transform(norm_query.begin(), norm_query.end(), norm_query.begin(),
- ::tolower);
-
- // TODO(jwnichols): replace with a score based on Longest Common Substring
- auto pos = text.find(norm_query);
- if (pos == std::string::npos)
- return kMinConfidence;
-
- return static_cast<double>(norm_query.size()) /
- static_cast<double>(text.size());
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/query_match_ranking_feature.h b/bin/suggestion_engine/ranking_features/query_match_ranking_feature.h
deleted file mode 100644
index cc0130c..0000000
--- a/bin/suggestion_engine/ranking_features/query_match_ranking_feature.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_QUERY_MATCH_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_QUERY_MATCH_RANKING_FEATURE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-namespace modular {
-
-class QueryMatchRankingFeature : public RankingFeature {
- public:
- QueryMatchRankingFeature();
- ~QueryMatchRankingFeature() override;
-
- private:
- double ComputeFeatureInternal(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) override;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_QUERY_MATCH_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/ranking_features/query_match_ranking_feature_unittest.cc b/bin/suggestion_engine/ranking_features/query_match_ranking_feature_unittest.cc
deleted file mode 100644
index 02ef5e0..0000000
--- a/bin/suggestion_engine/ranking_features/query_match_ranking_feature_unittest.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/query_match_ranking_feature.h"
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class QueryMatchRankingFeatureTest : public ::testing::Test {
- protected:
- QueryMatchRankingFeature query_match_feature;
-};
-
-TEST_F(QueryMatchRankingFeatureTest, TestComputeFeatureRelated) {
- fuchsia::modular::SuggestionDisplay display;
- display.headline = "play bar by foo";
- fuchsia::modular::Proposal proposal;
- proposal.display = std::move(display);
- SuggestionPrototype prototype;
- prototype.proposal = std::move(proposal);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fuchsia::modular::UserInput query;
- query.text = "play bar";
-
- double value = query_match_feature.ComputeFeature(query, suggestion);
- EXPECT_NEAR(value, 0.533333, 0.00001);
-}
-
-TEST_F(QueryMatchRankingFeatureTest, TestComputeFeatureUnrelated) {
- fuchsia::modular::SuggestionDisplay display;
- display.headline = "play bar by foo";
- fuchsia::modular::Proposal proposal;
- proposal.display = std::move(display);
- SuggestionPrototype prototype;
- prototype.proposal = std::move(proposal);
- RankedSuggestion suggestion;
- suggestion.prototype = &prototype;
-
- fuchsia::modular::UserInput query;
- query.text = "open chat";
-
- double value = query_match_feature.ComputeFeature(query, suggestion);
- EXPECT_EQ(value, kMinConfidence);
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/ranking_feature.cc b/bin/suggestion_engine/ranking_features/ranking_feature.cc
deleted file mode 100644
index f5a81e2..0000000
--- a/bin/suggestion_engine/ranking_features/ranking_feature.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-
-#include "rapidjson/document.h"
-#include "rapidjson/error/en.h"
-#include "rapidjson/schema.h"
-#include "rapidjson/stringbuffer.h"
-
-namespace modular {
-
-int RankingFeature::instances_ = 0;
-
-RankingFeature::RankingFeature() : id_(instances_++) {}
-
-RankingFeature::~RankingFeature() = default;
-
-double RankingFeature::ComputeFeature(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) {
- const double feature = ComputeFeatureInternal(query, suggestion);
- FXL_CHECK(feature <= kMaxConfidence);
- FXL_CHECK(feature >= kMinConfidence);
- return feature;
-}
-
-fuchsia::modular::ContextSelectorPtr RankingFeature::CreateContextSelector() {
- return CreateContextSelectorInternal();
-}
-
-void RankingFeature::UpdateContext(
- const std::vector<fuchsia::modular::ContextValue>&
- context_update_values) {
- context_values_.reset(fidl::Clone(context_update_values));
-}
-
-fuchsia::modular::ContextSelectorPtr
-RankingFeature::CreateContextSelectorInternal() {
- // By default we return a nullptr, meaning that the ranking feature doesn't
- // require context. If a ranking feature requires context, it should create a
- // context selector, set the values it needs and return it.
- return nullptr;
-}
-
-fidl::VectorPtr<fuchsia::modular::ContextValue>&
-RankingFeature::ContextValues() {
- return context_values_;
-}
-
-std::optional<rapidjson::Document> RankingFeature::FetchJsonObject(
- const std::string& path) {
- // Load data file to string.
- std::string data;
- if (!files::ReadFileToString(path, &data)) {
- FXL_LOG(WARNING) << "Missing ranking feature data file: " << path;
- return std::nullopt;
- }
-
- // Parse json data string.
- rapidjson::Document data_doc;
- data_doc.Parse(data);
- if (data_doc.HasParseError()) {
- FXL_LOG(WARNING) << "Invalid JSON (" << path << " at "
- << data_doc.GetErrorOffset() << "): "
- << rapidjson::GetParseError_En(data_doc.GetParseError());
- return std::nullopt;
- }
-
- return std::move(data_doc);
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/ranking_features/ranking_feature.h b/bin/suggestion_engine/ranking_features/ranking_feature.h
deleted file mode 100644
index 91074c9..0000000
--- a/bin/suggestion_engine/ranking_features/ranking_feature.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_RANKING_FEATURE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_RANKING_FEATURE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/suggestion_engine/ranked_suggestion.h"
-#include "rapidjson/document.h"
-
-namespace modular {
-
-constexpr double kMaxConfidence = 1.0;
-constexpr double kMinConfidence = 0.0;
-
-class RankingFeature {
- public:
- RankingFeature();
- virtual ~RankingFeature();
-
- // Compute the numeric value for a feature, ensuring bounds on the result
- // in the range of [0.0,1.0]
- double ComputeFeature(const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion);
-
- // Fills the context selector with the values and meta the feature needs to
- // request from the context. Returns true if it filled anything, false
- // otherwise.
- fuchsia::modular::ContextSelectorPtr CreateContextSelector();
-
- // Updates the context that the feature needs.
- void UpdateContext(const std::vector<fuchsia::modular::ContextValue>&
- context_update_values);
-
- protected:
- // Compute the numeric feature for a feature, to be overridden by subclasses
- virtual double ComputeFeatureInternal(
- const fuchsia::modular::UserInput& query,
- const RankedSuggestion& suggestion) = 0;
-
- // Create the context selector. Returns nullptr if the feature doesn't require
- // context.
- virtual fuchsia::modular::ContextSelectorPtr CreateContextSelectorInternal();
-
- // Loads a json file into the second value of the pair. The first value
- // indicates if the file could be loaded and parsed.
- std::optional<rapidjson::Document> FetchJsonObject(const std::string& path);
-
- // Returns current context values the ranking feature has.
- fidl::VectorPtr<fuchsia::modular::ContextValue>& ContextValues();
-
- private:
- static int instances_;
- fidl::VectorPtr<fuchsia::modular::ContextValue> context_values_;
- const int id_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_RANKING_FEATURES_RANKING_FEATURE_H_
diff --git a/bin/suggestion_engine/resources/mod_pairs.json b/bin/suggestion_engine/resources/mod_pairs.json
deleted file mode 100644
index e22ccea..0000000
--- a/bin/suggestion_engine/resources/mod_pairs.json
+++ /dev/null
@@ -1,76 +0,0 @@
-{
- "/system/apps/restaurant/restaurant_list": {
- "file:///system/apps/restaurant/restaurant_review_list": 1.0
- },
- "chat_conversation": {
- "contacts_picker": 0.3333333333333333,
- "file:///system/apps/web_view": 0.3333333333333333,
- "gallery": 0.3333333333333333
- },
- "chat_conversation_list": {
- "chat_conversation": 0.3333333333333333,
- "contacts_picker": 0.6,
- "gallery": 0.06666666666666667
- },
- "contact_list": {
- "contact_card": 1.0
- },
- "contacts_picker": {
- "chat_conversation": 1.0
- },
- "dashboard": {
- "chat_conversation": 0.4444444444444444,
- "file:///system/apps/web_view": 0.2222222222222222,
- "web_view": 0.3333333333333333
- },
- "documents_browser": {
- "documents_info": 1.0
- },
- "example_manual_relationships": {
- "Captions": 1.0
- },
- "file:///system/apps/concert_event_list": {
- "concert_event_page": 1.0
- },
- "file:///system/apps/map": {
- "file:///system/apps/weather_forecast": 1.0
- },
- "file:///system/apps/web_view": {
- "chat_conversation": 1.0
- },
- "file:///system/apps/youtube_related_videos": {
- "video": 1.0
- },
- "file:///system/apps/youtube_video": {
- "file:///system/apps/youtube_related_videos": 0.64,
- "video": 0.36
- },
- "gallery": {
- "chat_conversation": 0.5,
- "contacts_picker": 0.5
- },
- "restaurant/restaurant_list": {
- "file:///system/apps/restaurant/restaurant_page": 1.0
- },
- "video": {
- "file:///system/apps/youtube_related_videos": 0.5,
- "file:///system/apps/youtube_video": 0.5
- },
- "web_view": {
- "chat_conversation": 1.0
- },
- "youtube_related_videos": {
- "video": 1.0
- },
- "youtube_story": {
- "file:///system/apps/youtube_related_videos": 0.1507537688442211,
- "file:///system/apps/youtube_video": 0.15577889447236182,
- "video": 0.27638190954773867,
- "youtube_related_videos": 0.20603015075376885,
- "youtube_video": 0.21105527638190955
- },
- "youtube_video": {
- "video": 0.4533333333333333,
- "youtube_related_videos": 0.5466666666666666
- }
-}
diff --git a/bin/suggestion_engine/suggestion_engine_helper.cc b/bin/suggestion_engine/suggestion_engine_helper.cc
deleted file mode 100644
index ed22db2..0000000
--- a/bin/suggestion_engine/suggestion_engine_helper.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/suggestion_engine_helper.h"
-
-#include <lib/fxl/random/uuid.h>
-
-namespace modular {
-
-SuggestionPrototype* CreateSuggestionPrototype(
- SuggestionPrototypeMap* owner, const std::string& source_url,
- fuchsia::modular::Proposal proposal) {
- return CreateSuggestionPrototype(owner, source_url, "", std::move(proposal));
-}
-
-SuggestionPrototype* CreateSuggestionPrototype(
- SuggestionPrototypeMap* owner, const std::string& source_url,
- const std::string& preloaded_story_id,
- fuchsia::modular::Proposal proposal) {
- auto prototype_pair = owner->emplace(std::make_pair(source_url, proposal.id),
- std::make_unique<SuggestionPrototype>());
-
- SuggestionPrototype* suggestion_prototype =
- prototype_pair.first->second.get();
- suggestion_prototype->preloaded_story_id = preloaded_story_id;
- suggestion_prototype->suggestion_id = fxl::GenerateUUID();
- suggestion_prototype->source_url = source_url;
- suggestion_prototype->timestamp = zx::clock::get_monotonic();
- suggestion_prototype->proposal = std::move(proposal);
-
- return suggestion_prototype;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/suggestion_engine_helper.h b/bin/suggestion_engine/suggestion_engine_helper.h
deleted file mode 100644
index e8d63be..0000000
--- a/bin/suggestion_engine/suggestion_engine_helper.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_ENGINE_HELPER_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_ENGINE_HELPER_H_
-
-#include "peridot/bin/suggestion_engine/suggestion_prototype.h"
-
-namespace modular {
-
-// (proposer ID, proposal ID) => suggestion prototype
-using SuggestionPrototypeMap = std::map<std::pair<std::string, std::string>,
- std::unique_ptr<SuggestionPrototype>>;
-
-SuggestionPrototype* CreateSuggestionPrototype(
- SuggestionPrototypeMap* owner, const std::string& source_url,
- const std::string& story_id, fuchsia::modular::Proposal proposal);
-
-SuggestionPrototype* CreateSuggestionPrototype(
- SuggestionPrototypeMap* owner, const std::string& source_url,
- const std::string& story_id, const std::string& preloaded_story_id,
- fuchsia::modular::Proposal proposal);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_ENGINE_HELPER_H_
diff --git a/bin/suggestion_engine/suggestion_engine_impl.cc b/bin/suggestion_engine/suggestion_engine_impl.cc
deleted file mode 100644
index e1e98e2..0000000
--- a/bin/suggestion_engine/suggestion_engine_impl.cc
+++ /dev/null
@@ -1,401 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/suggestion_engine_impl.h"
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/context/cpp/context_helper.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/time/time_delta.h>
-#include <lib/fxl/time/time_point.h>
-#include "lib/fidl/cpp/clone.h"
-#include "lib/fxl/random/uuid.h"
-
-#include "peridot/bin/suggestion_engine/decision_policies/rank_over_threshold_decision_policy.h"
-#include "peridot/bin/suggestion_engine/filters/conjugate_ranked_passive_filter.h"
-#include "peridot/bin/suggestion_engine/filters/ranked_active_filter.h"
-#include "peridot/bin/suggestion_engine/filters/ranked_passive_filter.h"
-#include "peridot/bin/suggestion_engine/rankers/linear_ranker.h"
-#include "peridot/bin/suggestion_engine/ranking_features/affinity_ranking_feature.h"
-#include "peridot/bin/suggestion_engine/ranking_features/annoyance_ranking_feature.h"
-#include "peridot/bin/suggestion_engine/ranking_features/dead_story_ranking_feature.h"
-#include "peridot/bin/suggestion_engine/ranking_features/interrupting_ranking_feature.h"
-#include "peridot/bin/suggestion_engine/ranking_features/kronk_ranking_feature.h"
-#include "peridot/bin/suggestion_engine/ranking_features/mod_pair_ranking_feature.h"
-#include "peridot/bin/suggestion_engine/ranking_features/proposal_hint_ranking_feature.h"
-#include "peridot/bin/suggestion_engine/ranking_features/query_match_ranking_feature.h"
-#include "peridot/bin/suggestion_engine/ranking_features/ranking_feature.h"
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace modular {
-
-SuggestionEngineImpl::SuggestionEngineImpl(
- fuchsia::modular::ContextReaderPtr context_reader,
- fuchsia::modular::PuppetMasterPtr puppet_master)
- : debug_(std::make_shared<SuggestionDebugImpl>()),
- next_processor_(debug_),
- query_processor_(debug_),
- context_reader_(std::move(context_reader)),
- puppet_master_(std::move(puppet_master)),
- context_listener_binding_(this) {
- RegisterRankingFeatures();
-}
-
-SuggestionEngineImpl::~SuggestionEngineImpl() = default;
-
-fxl::WeakPtr<SuggestionDebugImpl> SuggestionEngineImpl::debug() {
- return debug_->GetWeakPtr();
-}
-
-void SuggestionEngineImpl::AddNextProposal(
- ProposalPublisherImpl* source, fuchsia::modular::Proposal proposal) {
- if (proposal.wants_rich_suggestion) {
- if (ComponentCanUseRichSuggestions(source->component_url())) {
- AddProposalWithRichSuggestion(source, std::move(proposal));
- return;
- }
- FXL_LOG(INFO) << "Attempt to add rich suggestion for unallowed component "
- << source->component_url();
- }
- next_processor_.AddProposal(source->component_url(), std::move(proposal));
-}
-
-void SuggestionEngineImpl::ProposeNavigation(
- const fuchsia::modular::NavigationAction navigation) {
- navigation_processor_.Navigate(navigation);
-}
-
-void SuggestionEngineImpl::AddProposalWithRichSuggestion(
- ProposalPublisherImpl* source, fuchsia::modular::Proposal proposal) {
- if (!proposal.story_name) {
- // Puppet master will generate a story name on execution of the
- // proposal actions.
- proposal.story_name = "";
- }
-
- SuggestionPrototype* suggestion =
- next_processor_.GetSuggestion(source->component_url(), proposal.id);
-
- // We keep track of the previous story since a new one will be created for a
- // existing proposal.
- // TODO(miguelfrde): this logic should probably belong in NextProcessor. We
- // should also allow clients to reuse the story_name and mod_name to update
- // the mod in the suggestion directly rather than creating a new one, however
- // this is not working yet.
- std::string existing_story;
- if (suggestion && !suggestion->preloaded_story_id.empty()) {
- existing_story = suggestion->preloaded_story_id;
- }
-
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master;
- puppet_master_->ControlStory(proposal.story_name,
- story_puppet_master.NewRequest());
- fuchsia::modular::StoryOptions story_options;
- story_options.kind_of_proto_story = true;
- story_puppet_master->SetCreateOptions(std::move(story_options));
-
- auto fut = modular::Future<fuchsia::modular::ExecuteResult>::Create(
- "SuggestionEngine::AddProposalWithRichSuggestion.fut");
- story_puppet_master->Enqueue(std::move(proposal.on_selected));
- story_puppet_master->Execute(fut->Completer());
- fut->Then(fxl::MakeCopyable(
- [this, fut, source_url = source->component_url(),
- proposal = std::move(proposal), sp = std::move(story_puppet_master),
- existing_story](fuchsia::modular::ExecuteResult result) mutable {
- if (result.status != fuchsia::modular::ExecuteStatus::OK) {
- FXL_LOG(WARNING) << "Preloading of rich suggestion actions resulted "
- << "non successful status="
- << (uint32_t)result.status
- << " message=" << result.error_message;
- }
- if (proposal.story_name->empty()) {
- proposal.story_name = result.story_id;
- }
-
- if (existing_story.empty()) {
- next_processor_.AddProposal(source_url, result.story_id,
- std::move(proposal));
- }
- }));
-}
-
-void SuggestionEngineImpl::RemoveNextProposal(const std::string& component_url,
- const std::string& proposal_id) {
- SuggestionPrototype* suggestion =
- next_processor_.GetSuggestion(component_url, proposal_id);
- if (suggestion && !suggestion->preloaded_story_id.empty()) {
- auto story_name = suggestion->proposal.story_name;
- puppet_master_->DeleteStory(
- story_name, [this, story_name, component_url, proposal_id] {
- next_processor_.RemoveProposal(component_url, proposal_id);
- });
- } else {
- next_processor_.RemoveProposal(component_url, proposal_id);
- }
-}
-
-void SuggestionEngineImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionEngine> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void SuggestionEngineImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionProvider> request) {
- suggestion_provider_bindings_.AddBinding(this, std::move(request));
-}
-
-void SuggestionEngineImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionDebug> request) {
- debug_bindings_.AddBinding(debug_.get(), std::move(request));
-}
-
-// |fuchsia::modular::SuggestionProvider|
-void SuggestionEngineImpl::Query(
- fidl::InterfaceHandle<fuchsia::modular::QueryListener> listener,
- fuchsia::modular::UserInput input, int count) {
- query_processor_.ExecuteQuery(std::move(input), count, std::move(listener));
-}
-
-// |fuchsia::modular::SuggestionProvider|
-void SuggestionEngineImpl::SubscribeToInterruptions(
- fidl::InterfaceHandle<fuchsia::modular::InterruptionListener> listener) {
- next_processor_.RegisterInterruptionListener(std::move(listener));
-}
-
-// |fuchsia::modular::SuggestionProvider|
-void SuggestionEngineImpl::SubscribeToNavigation(
- fidl::InterfaceHandle<fuchsia::modular::NavigationListener> listener) {
- navigation_processor_.RegisterListener(std::move(listener));
-}
-
-// |fuchsia::modular::SuggestionProvider|
-void SuggestionEngineImpl::SubscribeToNext(
- fidl::InterfaceHandle<fuchsia::modular::NextListener> listener, int count) {
- next_processor_.RegisterListener(std::move(listener), count);
-}
-
-// |fuchsia::modular::SuggestionProvider|
-void SuggestionEngineImpl::NotifyInteraction(
- std::string suggestion_uuid,
- fuchsia::modular::Interaction interaction) {
- // Find the suggestion
- bool suggestion_in_ask = false;
- RankedSuggestion* suggestion = next_processor_.GetSuggestion(suggestion_uuid);
- if (!suggestion) {
- suggestion = query_processor_.GetSuggestion(suggestion_uuid);
- suggestion_in_ask = true;
- }
-
- if (!suggestion) {
- FXL_LOG(WARNING) << "Requested suggestion in notify interaction not found. "
- << "UUID: " << suggestion_uuid;
- return;
- }
-
- // If it exists (and it should), perform the action and clean up
- auto component_url = suggestion->prototype->source_url;
- std::string log_detail = suggestion->prototype
- ? short_proposal_str(*suggestion->prototype)
- : "invalid";
-
- FXL_LOG(INFO) << (interaction.type ==
- fuchsia::modular::InteractionType::SELECTED
- ? "Accepted"
- : "Dismissed")
- << " suggestion " << suggestion_uuid << " (" << log_detail
- << ")";
-
- debug_->OnSuggestionSelected(suggestion->prototype);
-
- auto& proposal = suggestion->prototype->proposal;
- auto proposal_id = proposal.id;
- auto preloaded_story_id = suggestion->prototype->preloaded_story_id;
- suggestion->interrupting = false;
-
- switch (interaction.type) {
- case fuchsia::modular::InteractionType::SELECTED: {
- HandleSelectedInteraction(
- component_url, preloaded_story_id, proposal,
- std::move(suggestion->prototype->bound_listener), suggestion_in_ask);
- break;
- }
- case fuchsia::modular::InteractionType::DISMISSED: {
- if (suggestion_in_ask) {
- query_processor_.CleanUpPreviousQuery();
- } else {
- RemoveNextProposal(component_url, proposal_id);
- }
- break;
- }
- case fuchsia::modular::InteractionType::EXPIRED:
- case fuchsia::modular::InteractionType::SNOOZED: {
- // No need to remove since it was either expired by a timeout in
- // session shell or snoozed by the user, however we should still refresh
- // the next processor (if not in ask) given that `interrupting=false` set
- // above.
- if (!suggestion_in_ask) {
- next_processor_.UpdateRanking();
- }
- break;
- }
- }
-}
-
-// |fuchsia::modular::SuggestionEngine|
-void SuggestionEngineImpl::RegisterProposalPublisher(
- std::string url,
- fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher> publisher) {
- // Check to see if a fuchsia::modular::ProposalPublisher has already been
- // created for the component with this url. If not, create one.
- std::unique_ptr<ProposalPublisherImpl>& source = proposal_publishers_[url];
- if (!source) { // create if it didn't already exist
- source = std::make_unique<ProposalPublisherImpl>(this, url);
- }
-
- source->AddBinding(std::move(publisher));
-}
-
-// |fuchsia::modular::SuggestionEngine|
-void SuggestionEngineImpl::RegisterQueryHandler(
- std::string url, fidl::InterfaceHandle<fuchsia::modular::QueryHandler>
- query_handler_handle) {
- query_processor_.RegisterQueryHandler(url, std::move(query_handler_handle));
-}
-
-// end fuchsia::modular::SuggestionEngine
-
-void SuggestionEngineImpl::RegisterRankingFeatures() {
- // Create common ranking features
- ranking_features["proposal_hint_rf"] =
- std::make_shared<ProposalHintRankingFeature>();
- ranking_features["kronk_rf"] = std::make_shared<KronkRankingFeature>();
- ranking_features["mod_pairs_rf"] = std::make_shared<ModPairRankingFeature>();
- ranking_features["query_match_rf"] =
- std::make_shared<QueryMatchRankingFeature>();
- ranking_features["affinity_rf"] = std::make_shared<AffinityRankingFeature>();
- ranking_features["annoyance_rf"] =
- std::make_shared<AnnoyanceRankingFeature>();
- ranking_features["dead_story_rf"] =
- std::make_shared<DeadStoryRankingFeature>();
- ranking_features["is_interrupting_rf"] =
- std::make_shared<InterruptingRankingFeature>();
-
- // Get context updates every time a story is focused to rerank suggestions
- // based on the story that is focused at the moment.
- fuchsia::modular::ContextQuery query;
- for (auto const& it : ranking_features) {
- fuchsia::modular::ContextSelectorPtr selector =
- it.second->CreateContextSelector();
- if (selector) {
- AddToContextQuery(&query, it.first, std::move(*selector));
- }
- }
- context_reader_->Subscribe(std::move(query),
- context_listener_binding_.NewBinding());
-
- // TODO(jwnichols): Replace the code configuration of the ranking features
- // with a configuration file
-
- // Set up the next ranking features
- auto next_ranker = std::make_unique<LinearRanker>();
- next_ranker->AddRankingFeature(1.0, ranking_features["proposal_hint_rf"]);
- next_ranker->AddRankingFeature(-0.1, ranking_features["kronk_rf"]);
- next_ranker->AddRankingFeature(0, ranking_features["mod_pairs_rf"]);
- next_ranker->AddRankingFeature(1.0, ranking_features["affinity_rf"]);
- next_processor_.SetRanker(std::move(next_ranker));
-
- // Set up the query ranking features
- auto query_ranker = std::make_unique<LinearRanker>();
- query_ranker->AddRankingFeature(1.0, ranking_features["proposal_hint_rf"]);
- query_ranker->AddRankingFeature(-0.1, ranking_features["kronk_rf"]);
- query_ranker->AddRankingFeature(0, ranking_features["mod_pairs_rf"]);
- query_ranker->AddRankingFeature(0, ranking_features["query_match_rf"]);
- query_processor_.SetRanker(std::move(query_ranker));
-
- // Set up the interrupt ranking features
- auto interrupt_ranker = std::make_unique<LinearRanker>();
- interrupt_ranker->AddRankingFeature(1.0, ranking_features["annoyance_rf"]);
- auto decision_policy = std::make_unique<RankOverThresholdDecisionPolicy>(
- std::move(interrupt_ranker));
- next_processor_.SetInterruptionDecisionPolicy(std::move(decision_policy));
-
- // Set up passive filters
- std::vector<std::unique_ptr<SuggestionPassiveFilter>> passive_filters;
- passive_filters.push_back(std::make_unique<ConjugateRankedPassiveFilter>(
- ranking_features["affinity_rf"]));
- passive_filters.push_back(std::make_unique<RankedPassiveFilter>(
- ranking_features["is_interrupting_rf"]));
- next_processor_.SetPassiveFilters(std::move(passive_filters));
-}
-
-void SuggestionEngineImpl::OnContextUpdate(
- fuchsia::modular::ContextUpdate update) {
- for (auto& entry : update.values) {
- for (const auto& rf_it : ranking_features) {
- if (entry.key == rf_it.first) { // Update key == rf key
- rf_it.second->UpdateContext(entry.value);
- }
- }
- }
- next_processor_.UpdateRanking();
-}
-
-bool SuggestionEngineImpl::ComponentCanUseRichSuggestions(
- const std::string& component_url) {
- // Only kronk is allowed to preload stories in suggestions to make
- // rich suggestions.
- // Proposinator is used for testing.
- return component_url.find("kronk") != std::string::npos ||
- component_url.find("krohnkite") != std::string::npos ||
- component_url.find("Proposinator") != std::string::npos;
-}
-
-void SuggestionEngineImpl::HandleSelectedInteraction(
- const std::string& component_url, const std::string& preloaded_story_id,
- fuchsia::modular::Proposal& proposal,
- fuchsia::modular::ProposalListenerPtr listener, bool suggestion_in_ask) {
- // Rich suggestions are only in Next, so we don't check suggestion_in_ask.
- if (!preloaded_story_id.empty()) {
- if (listener) {
- listener->OnProposalAccepted(proposal.id, preloaded_story_id);
- }
- // TODO(miguelfrde): eventually we should promote stories here. For now rich
- // suggestions aren't removed or promoted.
- return;
- }
-
- if (!proposal.story_name) {
- // Puppet master will generate a story name.
- proposal.story_name = "";
- }
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master;
- puppet_master_->ControlStory(proposal.story_name,
- story_puppet_master.NewRequest());
- auto fut = modular::Future<fuchsia::modular::ExecuteResult>::Create(
- "SuggestionEngine::HandleSelectedInteraction.fut");
- // TODO(miguelfred): break up |commands| if it is too large of a list for one
- // FIDL message.
- story_puppet_master->Enqueue(std::move(proposal.on_selected));
- story_puppet_master->Execute(fut->Completer());
- fut->Then(fxl::MakeCopyable(
- [this, proposal_id = proposal.id, suggestion_in_ask, component_url,
- listener = std::move(listener), sp = std::move(story_puppet_master),
- fut](fuchsia::modular::ExecuteResult result) mutable {
- // TODO(miguelfrde): check status.
- if (listener) {
- listener->OnProposalAccepted(proposal_id, result.story_id);
- }
- if (suggestion_in_ask) {
- query_processor_.CleanUpPreviousQuery();
- } else {
- next_processor_.RemoveProposal(component_url, proposal_id);
- }
- }));
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/suggestion_engine_impl.h b/bin/suggestion_engine/suggestion_engine_impl.h
deleted file mode 100644
index 1ac62e9..0000000
--- a/bin/suggestion_engine/suggestion_engine_impl.h
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_ENGINE_IMPL_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_ENGINE_IMPL_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/future.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/suggestion_engine/debug.h"
-#include "peridot/bin/suggestion_engine/interruptions_processor.h"
-#include "peridot/bin/suggestion_engine/navigation_processor.h"
-#include "peridot/bin/suggestion_engine/next_processor.h"
-#include "peridot/bin/suggestion_engine/proposal_publisher_impl.h"
-#include "peridot/bin/suggestion_engine/query_processor.h"
-#include "peridot/bin/suggestion_engine/ranked_suggestions_list.h"
-#include "peridot/lib/bound_set/bound_set.h"
-
-namespace modular {
-
-class ProposalPublisherImpl;
-
-// This class is currently responsible for 3 things:
-//
-// 1) Maintaining repositories of ranked Suggestions (stored inside
-// the RankedSuggestionsList class) for both Query and Next proposals.
-// a) Queries are handled by the QueryProcessor. QueryProcessor executes the
-// queries and stores their results. QueryProcessor only executes one query
-// at a time and stores results for only the last query.
-//
-// b) Next suggestions are issued by ProposalPublishers through the
-// Propose method, and can be issued at any time. The NextProcessor
-// handles all processing and notification of these proposals and stores
-// them.
-//
-// c) New next proposals are also considered for interruption. The
-// InterruptionProcessor examines proposals, decides whether they
-// should interruption, and, if so, makes further decisions about
-// when and how those interruptions should take place.
-//
-// 2) Storing the FIDL bindings for QueryHandlers and ProposalPublishers.
-//
-// a) ProposalPublishers (for Next Suggestions) can be registered via the
-// RegisterProposalPublisher method.
-//
-// b) QueryHandlers are currently registered through the
-// RegisterQueryHandler method.
-//
-// 3) Acts as a fuchsia::modular::SuggestionProvider for those wishing to
-// subscribe to
-// Suggestions.
-class SuggestionEngineImpl : public fuchsia::modular::ContextListener,
- public fuchsia::modular::SuggestionEngine,
- public fuchsia::modular::SuggestionProvider {
- public:
- SuggestionEngineImpl(fuchsia::modular::ContextReaderPtr context_reader,
- fuchsia::modular::PuppetMasterPtr puppet_master);
- ~SuggestionEngineImpl() override;
-
- fxl::WeakPtr<SuggestionDebugImpl> debug();
-
- // TODO(andrewosh): The following two methods should be removed. New
- // ProposalPublishers should be created whenever they're requested, and they
- // should be erased automatically when the client disconnects (they should be
- // stored in a BindingSet with an error handler that performs removal).
- void RemoveSourceClient(const std::string& component_url) {
- proposal_publishers_.erase(component_url);
- }
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionEngine> request);
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionDebug> request);
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::SuggestionProvider> request);
-
- // Should only be called from ProposalPublisherImpl.
- void AddNextProposal(ProposalPublisherImpl* source,
- fuchsia::modular::Proposal proposal);
-
- // Should only be called from ProposalPublisherImpl.
- void RemoveNextProposal(const std::string& component_url,
- const std::string& proposal_id);
-
- // Should only be called from ProposalPublisherImpl.
- void ProposeNavigation(fuchsia::modular::NavigationAction navigation);
-
- // |fuchsia::modular::SuggestionProvider|
- void SubscribeToInterruptions(
- fidl::InterfaceHandle<fuchsia::modular::InterruptionListener> listener)
- override;
-
- // |fuchsia::modular::SuggestionProvider|
- void SubscribeToNavigation(
- fidl::InterfaceHandle<fuchsia::modular::NavigationListener> listener)
- override;
-
- // |fuchsia::modular::SuggestionProvider|
- void SubscribeToNext(
- fidl::InterfaceHandle<fuchsia::modular::NextListener> listener,
- int count) override;
-
- // |fuchsia::modular::SuggestionProvider|
- void Query(fidl::InterfaceHandle<fuchsia::modular::QueryListener> listener,
- fuchsia::modular::UserInput input, int count) override;
-
- // When a user interacts with a fuchsia::modular::Suggestion, the suggestion
- // engine will be notified of consumed suggestion's ID. With this, we will do
- // two things:
- //
- // 1) Perform the fuchsia::modular::Action contained in the
- // fuchsia::modular::Suggestion
- // (suggestion->proposal.on_selected)
- //
- // fuchsia::modular::Action handling should be extracted into separate
- // classes to simplify SuggestionEngineImpl (i.e. an ActionManager which
- // delegates action execution to ActionHandlers based on the
- // fuchsia::modular::Action's tag).
- //
- // 2) Remove consumed fuchsia::modular::Suggestion from the next_suggestions_
- // repository,
- // if it came from there. Clear the ask_suggestions_ repository if
- // it came from there.
- //
- // |fuchsia::modular::SuggestionProvider|
- void NotifyInteraction(std::string suggestion_uuid,
- fuchsia::modular::Interaction interaction) override;
-
- // |fuchsia::modular::SuggestionEngine|
- void RegisterProposalPublisher(
- std::string url,
- fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher> publisher)
- override;
-
- // |fuchsia::modular::SuggestionEngine|
- void RegisterQueryHandler(
- std::string url, fidl::InterfaceHandle<fuchsia::modular::QueryHandler>
- query_handler_handle) override;
-
- void Terminate(std::function<void()> done) { done(); }
-
- private:
- friend class NavigationProcessor;
- friend class NextProcessor;
- friend class QueryProcessor;
-
- // Used by AddNextProposal to create a kind-of-proto-story and pre execute
- // actions when |proposal.preload| is true.
- void AddProposalWithRichSuggestion(ProposalPublisherImpl* source,
- fuchsia::modular::Proposal proposal);
-
- void RegisterRankingFeatures();
-
- // |fuchsia::modular::ContextListener|
- void OnContextUpdate(fuchsia::modular::ContextUpdate update) override;
-
- // Returns true iff the component at |component_url| is allowed to make rich
- // suggestions (i.e. pre-load stories to be displayed as suggestions).
- bool ComponentCanUseRichSuggestions(const std::string& component_url);
-
- // Executes the Interaction::SELECTED operation. If a |preloaded_story_id| is
- // provided, it will be promoted. Otherwise the actions will be executed.
- // Also notifies of OnProposalAccepted on the |proposal.listener|.
- // If |suggestion_in_ask| is true means that the proposal belongs to a query
- // suggestion. If false, to a next suggestion. This is information is used to
- // know from which list to delete.
- void HandleSelectedInteraction(const std::string& component_url,
- const std::string& preloaded_story_id,
- fuchsia::modular::Proposal& proposal,
- fuchsia::modular::ProposalListenerPtr listener,
- bool suggestion_in_ask);
-
- fidl::BindingSet<fuchsia::modular::SuggestionEngine> bindings_;
- fidl::BindingSet<fuchsia::modular::SuggestionProvider>
- suggestion_provider_bindings_;
- fidl::BindingSet<fuchsia::modular::SuggestionDebug> debug_bindings_;
-
- // The debugging interface for all Suggestions.
- std::shared_ptr<SuggestionDebugImpl> debug_;
-
- // TODO(thatguy): All Channels also get a ReevaluateFilters method, which
- // would remove Suggestions that are now filtered or add
- // new ones that are no longer filtered.
-
- // next and interruptions share the same backing
- NextProcessor next_processor_;
-
- // query execution and processing
- QueryProcessor query_processor_;
-
- // executes navigation actions
- NavigationProcessor navigation_processor_;
-
- std::map<std::string, std::shared_ptr<RankingFeature>> ranking_features;
-
- // The ProposalPublishers that have registered with the
- // fuchsia::modular::SuggestionEngine.
- std::map<std::string, std::unique_ptr<ProposalPublisherImpl>>
- proposal_publishers_;
-
- // The context reader that is used to rank suggestions using the current
- // context.
- fuchsia::modular::ContextReaderPtr context_reader_;
-
- // The puppet master connection that is used to execute actions.
- fuchsia::modular::PuppetMasterPtr puppet_master_;
-
- fidl::Binding<fuchsia::modular::ContextListener> context_listener_binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SuggestionEngineImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_ENGINE_IMPL_H_
diff --git a/bin/suggestion_engine/suggestion_engine_impl_unittest.cc b/bin/suggestion_engine/suggestion_engine_impl_unittest.cc
deleted file mode 100644
index e474cab..0000000
--- a/bin/suggestion_engine/suggestion_engine_impl_unittest.cc
+++ /dev/null
@@ -1,904 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/suggestion_engine_impl.h"
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionmgr/puppet_master/puppet_master_impl.h"
-#include "peridot/bin/suggestion_engine/proposal_publisher_impl.h"
-#include "peridot/lib/testing/test_story_command_executor.h"
-#include "peridot/lib/testing/test_with_session_storage.h"
-
-namespace modular {
-namespace {
-
-class TestNextListener : public fuchsia::modular::NextListener {
- public:
- void OnNextResults(
- std::vector<fuchsia::modular::Suggestion> suggestions) override {
- last_suggestions_ = std::move(suggestions);
- }
-
- void Reset() { last_suggestions_.clear(); }
-
- void OnProcessingChange(bool processing) override{};
-
- std::vector<fuchsia::modular::Suggestion>& last_suggestions() {
- return last_suggestions_;
- }
-
- private:
- std::vector<fuchsia::modular::Suggestion> last_suggestions_;
-};
-
-class TestInterruptionListener : public fuchsia::modular::InterruptionListener {
- public:
- void OnInterrupt(fuchsia::modular::Suggestion suggestion) override {
- last_suggestion_ = std::move(suggestion);
- }
-
- fuchsia::modular::Suggestion& last_suggestion() { return last_suggestion_; }
-
- private:
- fuchsia::modular::Suggestion last_suggestion_;
-};
-
-class TestNavigationListener : public fuchsia::modular::NavigationListener {
- public:
- void OnNavigation(fuchsia::modular::NavigationAction navigation) override {
- last_navigation_action_ = std::move(navigation);
- }
-
- fuchsia::modular::NavigationAction last_navigation_action() {
- return last_navigation_action_;
- }
-
- private:
- fuchsia::modular::NavigationAction last_navigation_action_;
-};
-
-class TestContextReaderImpl : public fuchsia::modular::ContextReader {
- public:
- TestContextReaderImpl(
- fidl::InterfaceRequest<fuchsia::modular::ContextReader> request)
- : binding_(this, std::move(request)) {}
-
- private:
- // |fuchsia::modular::ContextReader|
- void Subscribe(fuchsia::modular::ContextQuery query,
- fidl::InterfaceHandle<fuchsia::modular::ContextListener>
- listener) override {}
-
- // |fuchsia::modular::ContextReader|
- void Get(fuchsia::modular::ContextQuery query,
- fuchsia::modular::ContextReader::GetCallback callback) override {}
-
- fidl::Binding<fuchsia::modular::ContextReader> binding_;
-};
-
-class SuggestionEngineTest : public testing::TestWithSessionStorage {
- public:
- SuggestionEngineTest()
- : next_listener_binding_(&next_listener_),
- interruption_listener_binding_(&interruption_listener_),
- navigation_listener_binding_(&navigation_listener_) {}
-
- void SetUp() override {
- TestWithSessionStorage::SetUp();
-
- // Get an unbound handles. We won't make use of these interfaces during the
- // test except for our mock puppet master.
- fuchsia::modular::ContextReaderPtr context_reader;
- context_reader_impl_ =
- std::make_unique<TestContextReaderImpl>(context_reader.NewRequest());
-
- session_storage_ = MakeSessionStorage("page");
- puppet_master_impl_ = std::make_unique<PuppetMasterImpl>(
- session_storage_.get(), &test_executor_);
- fuchsia::modular::PuppetMasterPtr puppet_master;
- puppet_master_impl_->Connect(puppet_master.NewRequest());
-
- suggestion_engine_impl_ = std::make_unique<SuggestionEngineImpl>(
- std::move(context_reader), std::move(puppet_master));
- suggestion_engine_impl_->Connect(engine_ptr_.NewRequest());
- suggestion_engine_impl_->Connect(provider_ptr_.NewRequest());
- suggestion_engine_impl_->Connect(debug_ptr_.NewRequest());
-
- proposal_publisher_ = std::make_unique<ProposalPublisherImpl>(
- suggestion_engine_impl_.get(), "Proposinator");
- }
-
- protected:
- void StartListeningForNext(int max_suggestions) {
- suggestion_engine_impl_->SubscribeToNext(
- next_listener_binding_.NewBinding(), max_suggestions);
- next_listener_.Reset();
- }
-
- void StartListeningForInterruptions() {
- suggestion_engine_impl_->SubscribeToInterruptions(
- interruption_listener_binding_.NewBinding());
- }
-
- void StartListeningForNavigation() {
- suggestion_engine_impl_->SubscribeToNavigation(
- navigation_listener_binding_.NewBinding());
- }
-
- fuchsia::modular::Proposal MakeProposal(const std::string& id,
- const std::string& headline) {
- fuchsia::modular::SuggestionDisplay display;
- display.headline = headline;
- fuchsia::modular::Proposal proposal;
- proposal.id = id;
- proposal.display = std::move(display);
- return proposal;
- }
-
- fuchsia::modular::Proposal MakeInterruptionProposal(
- const std::string id, const std::string& headline,
- fuchsia::modular::AnnoyanceType annoyance =
- fuchsia::modular::AnnoyanceType::INTERRUPT) {
- auto proposal = MakeProposal(id, headline);
- proposal.display.annoyance = annoyance;
- return proposal;
- }
-
- fuchsia::modular::Proposal MakeRichProposal(const std::string id,
- const std::string& headline) {
- auto proposal = MakeProposal(id, headline);
- proposal.wants_rich_suggestion = true;
- return proposal;
- }
-
- void AddAddModuleAction(fuchsia::modular::Proposal* proposal,
- const std::string& mod_name,
- const std::string& mod_url,
- const std::string& parent_mod = "",
- fuchsia::modular::SurfaceArrangement arrangement =
- fuchsia::modular::SurfaceArrangement::NONE) {
- fuchsia::modular::Intent intent;
- intent.handler = mod_url;
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back(mod_name);
- add_mod.intent = std::move(intent);
- if (!parent_mod.empty()) {
- add_mod.surface_parent_mod_name.push_back(parent_mod);
- }
- add_mod.surface_relation.arrangement = arrangement;
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- proposal->on_selected.push_back(std::move(command));
- }
-
- void AddFocusStoryAction(fuchsia::modular::Proposal* proposal) {
- fuchsia::modular::SetFocusState focus_story;
- focus_story.focused = true;
- fuchsia::modular::StoryCommand command;
- command.set_set_focus_state(std::move(focus_story));
- proposal->on_selected.push_back(std::move(command));
- }
-
- void AddFocusModuleAction(fuchsia::modular::Proposal* proposal,
- const std::string& mod_name) {
- fuchsia::modular::FocusMod focus_mod;
- focus_mod.mod_name.push_back(mod_name);
- fuchsia::modular::StoryCommand command;
- command.set_focus_mod(std::move(focus_mod));
- proposal->on_selected.push_back(std::move(command));
- }
-
- void AddSetLinkValueAction(fuchsia::modular::Proposal* proposal,
- const std::string& mod_name,
- const std::string& link_name,
- const std::string& link_value) {
- fuchsia::modular::LinkPath link_path;
- link_path.module_path.push_back(mod_name);
- link_path.link_name = link_name;
- fuchsia::modular::SetLinkValue set_link_value;
- set_link_value.path = std::move(link_path);
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(link_value, &vmo));
- set_link_value.value =
- std::make_unique<fuchsia::mem::Buffer>(std::move(vmo).ToTransport());
-
- fuchsia::modular::StoryCommand command;
- command.set_set_link_value(std::move(set_link_value));
- proposal->on_selected.push_back(std::move(command));
- }
-
- std::unique_ptr<ProposalPublisherImpl> proposal_publisher_;
- std::unique_ptr<SessionStorage> session_storage_;
- std::unique_ptr<PuppetMasterImpl> puppet_master_impl_;
- std::unique_ptr<SuggestionEngineImpl> suggestion_engine_impl_;
- std::unique_ptr<TestContextReaderImpl> context_reader_impl_;
- fuchsia::modular::SuggestionEnginePtr engine_ptr_;
- fuchsia::modular::SuggestionProviderPtr provider_ptr_;
- fuchsia::modular::SuggestionDebugPtr debug_ptr_;
- testing::TestStoryCommandExecutor test_executor_;
-
- TestNextListener next_listener_;
- fidl::Binding<fuchsia::modular::NextListener> next_listener_binding_;
-
- TestInterruptionListener interruption_listener_;
- fidl::Binding<fuchsia::modular::InterruptionListener>
- interruption_listener_binding_;
-
- TestNavigationListener navigation_listener_;
- fidl::Binding<fuchsia::modular::NavigationListener>
- navigation_listener_binding_;
-};
-
-TEST_F(SuggestionEngineTest, AddNextProposal) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeProposal("1", "test_proposal");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntilIdle();
-
- // We should see proposal in listener.
- auto& results = next_listener_.last_suggestions();
- ASSERT_EQ(1u, results.size());
- EXPECT_EQ("test_proposal", results.at(0).display.headline);
-}
-
-TEST_F(SuggestionEngineTest, OnlyGetsMaxProposals) {
- StartListeningForNext(2);
-
- // Add three proposals.
- proposal_publisher_->Propose(MakeProposal("1", "foo"));
- proposal_publisher_->Propose(MakeProposal("2", "bar"));
- proposal_publisher_->Propose(MakeProposal("3", "baz"));
-
- RunLoopUntilIdle();
-
- // We should see 2 proposals in listener.
- auto& results = next_listener_.last_suggestions();
- ASSERT_EQ(2u, results.size());
- EXPECT_EQ("foo", results.at(0).display.headline);
- EXPECT_EQ("bar", results.at(1).display.headline);
-}
-
-TEST_F(SuggestionEngineTest, AddNextProposalInterruption) {
- StartListeningForNext(10);
- StartListeningForInterruptions();
-
- // Add interruptive proposal.
- proposal_publisher_->Propose(MakeInterruptionProposal("1", "foo"));
-
- RunLoopUntilIdle();
-
- // Ensure notification.
- auto& last_interruption = interruption_listener_.last_suggestion();
- EXPECT_EQ("foo", last_interruption.display.headline);
-
- // Suggestion shouldn't be in NEXT yet since it's interrupting.
- auto& results = next_listener_.last_suggestions();
- EXPECT_TRUE(results.empty());
-}
-
-TEST_F(SuggestionEngineTest, AddNextProposalRichNotAllowed) {
- StartListeningForNext(10);
-
- // Register publisher that can't submit rich proposals (see the url) and add
- // proposal.
- auto publisher = std::make_unique<ProposalPublisherImpl>(
- suggestion_engine_impl_.get(), "foo");
- publisher->Propose(MakeRichProposal("1", "foo"));
-
- RunLoopUntilIdle();
-
- // Suggestion shouldn't be rich: it has no preloaded story_id.
- auto& results = next_listener_.last_suggestions();
- ASSERT_EQ(1u, results.size());
- EXPECT_EQ("foo", results.at(0).display.headline);
- EXPECT_TRUE(results.at(0).preloaded_story_id->empty());
-}
-
-TEST_F(SuggestionEngineTest, AddNextProposalRich) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeRichProposal("1", "foo_rich");
- AddAddModuleAction(&proposal, "mod_name", "mod_url", "parent_mod",
- fuchsia::modular::SurfaceArrangement::ONTOP);
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntil([&] { return next_listener_.last_suggestions().size() == 1; });
-
- // Suggestion should be rich: it has a preloaded story_id.
- auto& results = next_listener_.last_suggestions();
- EXPECT_EQ("foo_rich", results.at(0).display.headline);
- EXPECT_FALSE(results.at(0).preloaded_story_id->empty());
- auto story_name = results.at(0).preloaded_story_id;
-
- // The executor should have been called with a command to add a mod and
- // created a story.
- EXPECT_EQ(1, test_executor_.execute_count());
- EXPECT_FALSE(test_executor_.last_story_id()->empty());
- auto& commands = test_executor_.last_commands();
- ASSERT_EQ(1u, commands.size());
- ASSERT_TRUE(commands.at(0).is_add_mod());
-
- auto& command = commands.at(0).add_mod();
- ASSERT_EQ(1u, command.mod_name.size());
- EXPECT_EQ("mod_name", command.mod_name.at(0));
- EXPECT_EQ("mod_url", command.intent.handler);
- EXPECT_EQ(fuchsia::modular::SurfaceArrangement::ONTOP,
- command.surface_relation.arrangement);
- ASSERT_EQ(1u, command.surface_parent_mod_name->size());
- EXPECT_EQ("parent_mod", command.surface_parent_mod_name->at(0));
-
- // Ensure the story was created as kind-of-proto story.
- bool done{};
- session_storage_->GetStoryData(story_name)
- ->Then([&](fuchsia::modular::internal::StoryDataPtr story_data) {
- ASSERT_NE(nullptr, story_data);
- EXPECT_TRUE(story_data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SuggestionEngineTest, AddNextProposalRichReusesStory) {
- StartListeningForNext(10);
- auto story_name = "rich_story";
-
- // Add proposal.
- {
- auto proposal = MakeRichProposal("1", "foo_rich");
- proposal.story_name = story_name;
- AddAddModuleAction(&proposal, "mod_name", "mod_url", "parent_mod",
- fuchsia::modular::SurfaceArrangement::ONTOP);
- proposal_publisher_->Propose(std::move(proposal));
- }
-
- RunLoopUntil([&] { return next_listener_.last_suggestions().size() == 1; });
-
- // Up to here we expect the same as in the previous test (AddNextProposalRich)
- // Submitting a new proposal with the same story_name should result on its
- // story being directly updated and no notifications of new suggestions.
- next_listener_.Reset();
- test_executor_.Reset();
- {
- auto proposal = MakeRichProposal("1", "foo_rich");
- proposal.story_name = story_name;
- AddAddModuleAction(&proposal, "mod_name", "mod_url", "parent_mod",
- fuchsia::modular::SurfaceArrangement::COPRESENT);
- proposal_publisher_->Propose(std::move(proposal));
- }
-
- RunLoopUntil([&] { return test_executor_.execute_count() == 1; });
- EXPECT_TRUE(next_listener_.last_suggestions().empty());
-
- // The executor should have been called with a command to add a mod and
- // created a story.
- EXPECT_EQ(1, test_executor_.execute_count());
- EXPECT_FALSE(test_executor_.last_story_id()->empty());
- auto& commands = test_executor_.last_commands();
- ASSERT_EQ(1u, commands.size());
- ASSERT_TRUE(commands.at(0).is_add_mod());
-
- auto& command = commands.at(0).add_mod();
- ASSERT_EQ(1u, command.mod_name.size());
- EXPECT_EQ("mod_name", command.mod_name.at(0));
- EXPECT_EQ("mod_url", command.intent.handler);
- EXPECT_EQ(fuchsia::modular::SurfaceArrangement::COPRESENT,
- command.surface_relation.arrangement);
- ASSERT_EQ(1u, command.surface_parent_mod_name->size());
- EXPECT_EQ("parent_mod", command.surface_parent_mod_name->at(0));
-
- // Ensure the story is there.
- bool done{};
- session_storage_->GetStoryData(story_name)
- ->Then([&](fuchsia::modular::internal::StoryDataPtr story_data) {
- ASSERT_NE(nullptr, story_data);
- EXPECT_TRUE(story_data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SuggestionEngineTest, AddNextProposalRichRespectsStoryName) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeRichProposal("1", "foo_rich");
- proposal.story_name = "foo_story";
- AddAddModuleAction(&proposal, "mod_name", "mod_url", "parent_mod",
- fuchsia::modular::SurfaceArrangement::ONTOP);
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntil([&] { return next_listener_.last_suggestions().size() == 1; });
-
- // Suggestion should be rich: it has a preloaded story_id.
- auto& results = next_listener_.last_suggestions();
- EXPECT_EQ("foo_story", results.at(0).preloaded_story_id);
-
- // The executor should have been called with a command to add a mod and
- // created a story.
- EXPECT_EQ(1, test_executor_.execute_count());
- EXPECT_EQ("foo_story", test_executor_.last_story_id());
-
- // Ensure the story was created as kind-of-proto story.
- bool done{};
- session_storage_->GetStoryData("foo_story")
- ->Then([&](fuchsia::modular::internal::StoryDataPtr story_data) {
- ASSERT_NE(nullptr, story_data);
- EXPECT_TRUE(story_data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SuggestionEngineTest, RemoveNextProposal) {
- StartListeningForNext(10);
-
- // Add proposal
- proposal_publisher_->Propose(MakeProposal("1", "foo"));
-
- // Remove proposal
- proposal_publisher_->Remove("1");
-
- RunLoopUntilIdle();
-
- auto& results = next_listener_.last_suggestions();
- EXPECT_TRUE(results.empty());
-}
-
-TEST_F(SuggestionEngineTest, RemoveNextProposalRich) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeRichProposal("1", "foo_rich");
- proposal.story_name = "foo_story";
- proposal_publisher_->Propose(std::move(proposal));
-
- // TODO(miguelfrde): add an operation queue in the suggestion engine and
- // remove this wait.
- RunLoopUntil([&] { return next_listener_.last_suggestions().size() == 1; });
-
- // Remove proposal.
- proposal_publisher_->Remove("1");
-
- RunLoopUntil([&] { return next_listener_.last_suggestions().empty(); });
-
- // The story that at some point was created when adding the rich suggestion
- // (not tested since other tests already cover it) should have been deleted.
- bool done{};
- session_storage_->GetStoryData("foo_story")
- ->Then([&](fuchsia::modular::internal::StoryDataPtr story_data) {
- EXPECT_EQ(nullptr, story_data);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionSelected) {
- StartListeningForNext(10);
-
- // Add proposal. One action of each action we support that translates to
- // StoryCommand is added. This set of actions doesn't really make sense in an
- // actual use case.
- auto proposal = MakeProposal("1", "foo");
- AddAddModuleAction(&proposal, "mod_name", "mod_url");
- AddFocusStoryAction(&proposal);
- AddFocusModuleAction(&proposal, "mod_name");
- AddSetLinkValueAction(&proposal, "mod_name", "foo_link_name", "foo_value");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntilIdle();
-
- // Get id of the resulting suggestion.
- auto& results = next_listener_.last_suggestions();
- ASSERT_EQ(1u, results.size());
- auto suggestion_id = results.at(0).uuid;
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::SELECTED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntil([&] { return test_executor_.execute_count() == 1; });
-
- // The executor should have been called with the right commands.
- auto story_id = test_executor_.last_story_id();
-
- auto& commands = test_executor_.last_commands();
- ASSERT_EQ(4u, commands.size());
- EXPECT_TRUE(commands.at(0).is_add_mod());
- EXPECT_TRUE(commands.at(1).is_set_focus_state());
- EXPECT_TRUE(commands.at(2).is_focus_mod());
- EXPECT_TRUE(commands.at(3).is_set_link_value());
-
- auto& add_mod = commands.at(0).add_mod();
- ASSERT_EQ(1u, add_mod.mod_name.size());
- EXPECT_EQ("mod_name", add_mod.mod_name.at(0));
- EXPECT_EQ("mod_url", add_mod.intent.handler);
-
- auto& set_focus_state = commands.at(1).set_focus_state();
- EXPECT_TRUE(set_focus_state.focused);
-
- auto& focus_mod = commands.at(2).focus_mod();
- ASSERT_EQ(1u, focus_mod.mod_name.size());
- EXPECT_EQ("mod_name", focus_mod.mod_name.at(0));
-
- auto& set_link_value = commands.at(3).set_link_value();
- ASSERT_EQ(1u, set_link_value.path.module_path.size());
- EXPECT_EQ("mod_name", set_link_value.path.module_path.at(0));
- EXPECT_EQ("foo_link_name", set_link_value.path.link_name);
- std::string link_value;
- FXL_CHECK(fsl::StringFromVmo(*set_link_value.value, &link_value));
- EXPECT_EQ("foo_value", link_value);
-
- // Ensure a regular story was created when we executed the proposal.
- bool done{};
- session_storage_->GetStoryData(story_id)->Then(
- [&](fuchsia::modular::internal::StoryDataPtr story_data) {
- EXPECT_NE(nullptr, story_data);
- EXPECT_FALSE(story_data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // We should have been notified with no suggestions after selecting this
- // suggestion.
- auto& listener_results = next_listener_.last_suggestions();
- EXPECT_TRUE(listener_results.empty());
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionSelectedWithStoryName) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeProposal("1", "foo");
- proposal.story_name = "foo_story";
- AddFocusModuleAction(&proposal, "mod_name");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntilIdle();
-
- // Get id of the resulting suggestion.
- auto& results = next_listener_.last_suggestions();
- ASSERT_EQ(1u, results.size());
- auto suggestion_id = results.at(0).uuid;
-
- // Select suggestion.
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::SELECTED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntil([&] { return test_executor_.execute_count() == 1; });
-
- // The executor should have been called with the command associated to the
- // action added above.
- EXPECT_EQ("foo_story", test_executor_.last_story_id());
-
- auto& commands = test_executor_.last_commands();
- ASSERT_EQ(1u, commands.size());
- EXPECT_TRUE(commands.at(0).is_focus_mod());
- auto& focus_mod = commands.at(0).focus_mod();
- ASSERT_EQ(1u, focus_mod.mod_name.size());
- EXPECT_EQ("mod_name", focus_mod.mod_name.at(0));
-
- // Ensure a regular story was created when we executed the proposal.
- bool done{};
- session_storage_->GetStoryData("foo_story")
- ->Then([&](fuchsia::modular::internal::StoryDataPtr story_data) {
- EXPECT_NE(nullptr, story_data);
- EXPECT_FALSE(story_data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // We should have been notified with no suggestions after selecting this
- // suggestion.
- auto& listener_results = next_listener_.last_suggestions();
- EXPECT_TRUE(listener_results.empty());
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionDismissed) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeProposal("1", "foo");
- AddFocusModuleAction(&proposal, "mod_name");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntilIdle();
-
- // Get id of the resulting suggestion.
- auto& results = next_listener_.last_suggestions();
- ASSERT_EQ(1u, results.size());
- auto suggestion_id = results.at(0).uuid;
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::DISMISSED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntilIdle();
-
- // The executor shouldn't have been called.
- EXPECT_EQ(0, test_executor_.execute_count());
-
- // We should have been notified with no suggestions after dismissing this
- // suggestion.
- auto& listener_results = next_listener_.last_suggestions();
- EXPECT_TRUE(listener_results.empty());
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionDismissedWithStoryName) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeProposal("1", "foo");
- proposal.story_name = "foo_story";
- AddFocusModuleAction(&proposal, "mod_name");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntilIdle();
-
- // Get id of the resulting suggestion.
- auto& results = next_listener_.last_suggestions();
- ASSERT_EQ(1u, results.size());
- auto suggestion_id = results.at(0).uuid;
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::DISMISSED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntilIdle();
-
- // The executor shouldn't have been called.
- EXPECT_EQ(0, test_executor_.execute_count());
-
- // We should have been notified with no suggestions after dismissing this
- // suggestion.
- auto& listener_results = next_listener_.last_suggestions();
- EXPECT_TRUE(listener_results.empty());
-
- // Ensure no story was created when we executed the proposal.
- bool done{};
- session_storage_->GetStoryData("foo_story")
- ->Then([&](fuchsia::modular::internal::StoryDataPtr story_data) {
- EXPECT_EQ(nullptr, story_data);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionSelectedRich) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeRichProposal("1", "foo_rich");
- AddFocusModuleAction(&proposal, "mod_name");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntil([&] { return next_listener_.last_suggestions().size() == 1; });
-
- // Get id of the resulting suggestion.
- auto& results = next_listener_.last_suggestions();
- auto suggestion_id = results.at(0).uuid;
- EXPECT_FALSE(results.at(0).preloaded_story_id->empty());
- auto story_name = results.at(0).preloaded_story_id;
-
- test_executor_.Reset();
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::SELECTED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntilIdle();
-
- // The executor should have been called for a second time with a command to
- // promote the story that the adding of the the proposal created.
- EXPECT_EQ(test_executor_.execute_count(), 0);
-
- // Ensure the story that was created when we adedd the rich proposal still
- // exists.
- bool done{};
- session_storage_->GetStoryData(story_name)
- ->Then([&](fuchsia::modular::internal::StoryDataPtr story_data) {
- EXPECT_NE(nullptr, story_data);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionDismissedRich) {
- StartListeningForNext(10);
-
- // Add proposal.
- auto proposal = MakeRichProposal("1", "foo_rich");
- AddFocusModuleAction(&proposal, "mod_name");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntil([&] { return next_listener_.last_suggestions().size() == 1; });
-
- // Get id and story of the resulting suggestion.
- auto& results = next_listener_.last_suggestions();
- EXPECT_EQ(1, test_executor_.execute_count());
- auto suggestion_id = results.at(0).uuid;
-
- EXPECT_FALSE(results.at(0).preloaded_story_id->empty());
- auto story_name = results.at(0).preloaded_story_id;
-
- test_executor_.Reset();
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::DISMISSED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntil([&] { return next_listener_.last_suggestions().empty(); });
-
- // The executor shouldn't have been called again.
- EXPECT_EQ(0, test_executor_.execute_count());
-
- // Ensure the story that was created when we added the rich proposal is gone.
- bool done{};
- session_storage_->GetStoryData(story_name)
- ->Then([&](fuchsia::modular::internal::StoryDataPtr story_data) {
- EXPECT_EQ(nullptr, story_data);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionSnoozedInterruption) {
- StartListeningForInterruptions();
- StartListeningForNext(10);
-
- // Add interruptive proposal.
- proposal_publisher_->Propose(MakeInterruptionProposal("1", "foo"));
-
- RunLoopUntilIdle();
-
- // Get id of the resulting suggestion.
- auto& suggestion = interruption_listener_.last_suggestion();
- EXPECT_FALSE(suggestion.uuid.empty());
- auto suggestion_id = suggestion.uuid;
-
- EXPECT_TRUE(next_listener_.last_suggestions().empty());
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::SNOOZED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntil([&] { return next_listener_.last_suggestions().size() == 1; });
-
- // The suggestion should still be there after being notified.
- auto& listener_results = next_listener_.last_suggestions();
- EXPECT_EQ(suggestion_id, listener_results.at(0).uuid);
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionExpiredInterruption) {
- StartListeningForInterruptions();
- StartListeningForNext(10);
-
- // Add interruptive proposal.
- proposal_publisher_->Propose(MakeInterruptionProposal("1", "foo"));
-
- RunLoopUntilIdle();
-
- // Get id of the resulting suggestion.
- auto& suggestion = interruption_listener_.last_suggestion();
- EXPECT_FALSE(suggestion.uuid.empty());
- auto suggestion_id = suggestion.uuid;
-
- EXPECT_TRUE(next_listener_.last_suggestions().empty());
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::EXPIRED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntilIdle();
-
- // The suggestion should still be there after being notified.
- auto& listener_results = next_listener_.last_suggestions();
- EXPECT_EQ(1u, listener_results.size());
- EXPECT_EQ(suggestion_id, listener_results.at(0).uuid);
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionSelectedInterruption) {
- StartListeningForInterruptions();
- StartListeningForNext(10);
-
- // Add interruptive proposal.
- auto proposal = MakeInterruptionProposal("1", "foo");
- AddFocusModuleAction(&proposal, "mod_name");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntilIdle();
-
- auto& suggestion = interruption_listener_.last_suggestion();
- EXPECT_FALSE(suggestion.uuid.empty());
- auto suggestion_id = suggestion.uuid;
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::SELECTED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntil([&] { return test_executor_.execute_count() == 1; });
-
- // The executor should have been called with a command to add a mod and
- // created a story.
- auto story_id = test_executor_.last_story_id();
- auto& commands = test_executor_.last_commands();
- ASSERT_EQ(1u, commands.size());
- auto& focus_mod = commands.at(0).focus_mod();
- ASSERT_EQ(1u, focus_mod.mod_name.size());
- EXPECT_EQ("mod_name", focus_mod.mod_name.at(0));
-
- // Ensure a regular story was created when we executed the proposal.
- bool done{};
- session_storage_->GetStoryData(story_id)->Then(
- [&](fuchsia::modular::internal::StoryDataPtr story_data) {
- EXPECT_NE(nullptr, story_data);
- EXPECT_FALSE(story_data->story_options.kind_of_proto_story);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- // The suggestion shouldn't be there anymore.
- EXPECT_TRUE(next_listener_.last_suggestions().empty());
-}
-
-TEST_F(SuggestionEngineTest, NotifyInteractionDismissedInterruption) {
- StartListeningForInterruptions();
- StartListeningForNext(10);
-
- // Add interruptive proposal.
- auto proposal = MakeInterruptionProposal("1", "foo");
- AddFocusModuleAction(&proposal, "mod_name");
- proposal_publisher_->Propose(std::move(proposal));
-
- RunLoopUntilIdle();
-
- auto& suggestion = interruption_listener_.last_suggestion();
- EXPECT_FALSE(suggestion.uuid.empty());
- auto suggestion_id = suggestion.uuid;
-
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::DISMISSED;
- suggestion_engine_impl_->NotifyInteraction(suggestion_id,
- std::move(interaction));
-
- RunLoopUntilIdle();
-
- // The executor shouldn't have been called.
- EXPECT_EQ(0, test_executor_.execute_count());
-
- // The suggestion shouldn't be there anymore.
- EXPECT_TRUE(next_listener_.last_suggestions().empty());
-}
-
-TEST_F(SuggestionEngineTest, ProposeNavigation) {
- StartListeningForNavigation();
-
- proposal_publisher_->ProposeNavigation(
- fuchsia::modular::NavigationAction::HOME);
- RunLoopUntilIdle();
-
- EXPECT_EQ(fuchsia::modular::NavigationAction::HOME,
- navigation_listener_.last_navigation_action());
-}
-
-} // namespace
-} // namespace modular
diff --git a/bin/suggestion_engine/suggestion_engine_main.cc b/bin/suggestion_engine/suggestion_engine_main.cc
deleted file mode 100644
index 1dcbedf..0000000
--- a/bin/suggestion_engine/suggestion_engine_main.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/bin/suggestion_engine/debug.h"
-#include "peridot/bin/suggestion_engine/suggestion_engine_impl.h"
-
-namespace modular {
-
-class SuggestionEngineApp {
- public:
- SuggestionEngineApp(component::StartupContext* const context) {
- fuchsia::modular::ContextReaderPtr context_reader;
- fuchsia::modular::PuppetMasterPtr puppet_master;
-
- context->ConnectToEnvironmentService(context_reader.NewRequest());
- context->ConnectToEnvironmentService(puppet_master.NewRequest());
-
- engine_impl_ = std::make_unique<modular::SuggestionEngineImpl>(
- std::move(context_reader), std::move(puppet_master));
-
- context->outgoing().AddPublicService<fuchsia::modular::SuggestionEngine>(
- [this](fidl::InterfaceRequest<fuchsia::modular::SuggestionEngine>
- request) { engine_impl_->Connect(std::move(request)); });
- context->outgoing().AddPublicService<fuchsia::modular::SuggestionProvider>(
- [this](fidl::InterfaceRequest<fuchsia::modular::SuggestionProvider>
- request) { engine_impl_->Connect(std::move(request)); });
- context->outgoing().AddPublicService<fuchsia::modular::SuggestionDebug>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::SuggestionDebug> request) {
- engine_impl_->Connect(std::move(request));
- });
- }
-
- void Terminate(const std::function<void()>& done) { done(); }
-
- fxl::WeakPtr<SuggestionDebugImpl> debug() { return engine_impl_->debug(); }
-
- private:
- std::unique_ptr<SuggestionEngineImpl> engine_impl_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SuggestionEngineApp);
-};
-
-} // namespace modular
-
-int main(int argc, const char** argv) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- auto suggestion_engine =
- std::make_unique<modular::SuggestionEngineApp>(context.get());
-
- fxl::WeakPtr<modular::SuggestionDebugImpl> debug = suggestion_engine->debug();
- debug->GetIdleWaiter()->SetLoop(&loop);
-
- modular::AppDriver<modular::SuggestionEngineApp> driver(
- context->outgoing().deprecated_services(), std::move(suggestion_engine),
- [&loop] { loop.Quit(); });
-
- // The |WaitUntilIdle| debug functionality escapes the main message loop to
- // perform its test.
- do {
- loop.Run();
- loop.ResetQuit();
- } while (debug && debug->GetIdleWaiter()->FinishIdleCheck());
-
- return 0;
-}
diff --git a/bin/suggestion_engine/suggestion_prototype.cc b/bin/suggestion_engine/suggestion_prototype.cc
deleted file mode 100644
index 1139698..0000000
--- a/bin/suggestion_engine/suggestion_prototype.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/bin/suggestion_engine/suggestion_prototype.h"
-
-#include <sstream>
-
-#include <lib/fidl/cpp/clone.h>
-
-namespace modular {
-
-std::string short_proposal_str(const SuggestionPrototype& prototype) {
- std::ostringstream str;
- str << "proposal " << prototype.proposal.id << " from "
- << prototype.source_url;
- return str.str();
-}
-
-fuchsia::modular::Suggestion CreateSuggestion(
- const SuggestionPrototype& prototype) {
- fuchsia::modular::Suggestion suggestion;
- suggestion.uuid = prototype.suggestion_id;
- if (!prototype.preloaded_story_id.empty()) {
- suggestion.preloaded_story_id = prototype.preloaded_story_id;
- }
- fidl::Clone(prototype.proposal.display, &suggestion.display);
- return suggestion;
-}
-
-} // namespace modular
diff --git a/bin/suggestion_engine/suggestion_prototype.h b/bin/suggestion_engine/suggestion_prototype.h
deleted file mode 100644
index 9a94ce0..0000000
--- a/bin/suggestion_engine/suggestion_prototype.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_PROTOTYPE_H_
-#define PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_PROTOTYPE_H_
-
-#include <strstream>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/zx/time.h>
-
-namespace modular {
-
-struct SuggestionPrototype {
- std::string suggestion_id;
- std::string preloaded_story_id;
- std::string source_url;
- zx::time timestamp;
- fuchsia::modular::Proposal proposal;
- fidl::InterfacePtr<fuchsia::modular::ProposalListener> bound_listener;
-};
-
-std::string short_proposal_str(const SuggestionPrototype& prototype);
-
-// Creates a partial suggestion from a prototype. Confidence will not be set.
-fuchsia::modular::Suggestion CreateSuggestion(
- const SuggestionPrototype& prototype);
-
-} // namespace modular
-
-#endif // PERIDOT_BIN_SUGGESTION_ENGINE_SUGGESTION_PROTOTYPE_H_
diff --git a/bin/test_driver/BUILD.gn b/bin/test_driver/BUILD.gn
deleted file mode 100644
index f64191c..0000000
--- a/bin/test_driver/BUILD.gn
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("test_driver_module") {
- testonly = true
-
- sources = [
- "test_driver_module.cc",
- ]
- deps = [
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:test_driver",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//peridot/public/lib/integration_testing/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-
- meta = [
- {
- path = "meta/test_driver_module.cmx"
- dest = "test_driver_module.cmx"
- },
- ]
-}
diff --git a/bin/test_driver/README.md b/bin/test_driver/README.md
deleted file mode 100644
index e848635..0000000
--- a/bin/test_driver/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# test driver integration test
-
-This test executes a submodule as passed through a link, along with a test
-driver component used to run end-to-end tests on said submodule
-
-The submodule can be any arbitrary mod to test, so long as it is packaged on the
-system
-
-Here is an example test file that runs the `driver_example_mod`:
-
-```json
-{
- "tests": [
- {
- "name": "driver_example_mod_tap_tests",
- "exec": "basemgr --test --enable_presenter --account_provider=dev_token_manager --base_shell=dev_base_shell --base_shell_args=--test_timeout_ms=60000 --session_shell=dev_session_shell --session_shell_args=--root_module=test_driver_module,--module_under_test_url=driver_example_mod_wrapper,--test_driver_url=driver_example_mod_target_tests --story_shell=dev_story_shell"
- }
- ]
-}
-```
diff --git a/bin/test_driver/meta/test_driver_module.cmx b/bin/test_driver/meta/test_driver_module.cmx
deleted file mode 100644
index 779b010..0000000
--- a/bin/test_driver/meta/test_driver_module.cmx
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [
- "shell"
- ],
- "services": [
- "fuchsia.modular.ModuleContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore"
- ]
- }
-}
diff --git a/bin/test_driver/test_driver_module.cc b/bin/test_driver/test_driver_module.cc
deleted file mode 100644
index 2580de3..0000000
--- a/bin/test_driver/test_driver_module.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fdio/limits.h>
-#include <lib/fdio/util.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/test_driver.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// The name of the test driver's child module.
-constexpr char kSubModuleName[] = "test_driver_sub_module";
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"test driver module initialized"};
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : module_host_(module_host) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- initialized_.Pass();
- sub_module_url_path_.push_back(modular::testing::kModuleUnderTestPath);
- test_driver_url_path_.push_back(modular::testing::kTestDriverPath);
- SetUp();
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called via ModuleDriver.
- TestPoint stopped_{"test driver module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- void SetUp() {
- module_host_->module_context()->GetLink(
- modular::testing::kTestDriverLinkName, link_.NewRequest());
- link_->Get(fidl::VectorPtr(sub_module_url_path_),
- [this](std::unique_ptr<fuchsia::mem::Buffer> link_data) {
- std::string sub_module_url;
- FXL_CHECK(fsl::StringFromVmo(*link_data, &sub_module_url));
- if (!RunSubModule(sub_module_url)) {
- Signal(modular::testing::kTestShutdown);
- return;
- };
- });
- }
-
- TestPoint test_sub_module_launched_{"sub module launched"};
-
- // Launches the module which is under test by the test driver.
- bool RunSubModule(const std::string& sub_module_url) {
- if (sub_module_url.empty()) {
- modular::testing::Fail("No sub_module_url supplied.");
- return false;
- }
- rapidjson::Document document;
- document.Parse(sub_module_url.c_str());
- fuchsia::modular::Intent intent;
- intent.handler = document.GetString();
- module_host_->module_context()->AddModuleToStory(
- kSubModuleName, std::move(intent), sub_module_.NewRequest(), nullptr,
- [this](const fuchsia::modular::StartModuleStatus status) {
- if (status == fuchsia::modular::StartModuleStatus::SUCCESS) {
- test_sub_module_launched_.Pass();
- RunTestDriver();
- }
- });
- return true;
- }
-
- void CreateTestDriverComponent(const std::string& url) {
- module_host_->startup_context()->environment()->GetLauncher(
- test_driver_launcher_.NewRequest());
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = url;
- launch_info.directory_request = test_driver_services_.NewRequest();
- test_driver_launcher_->CreateComponent(
- std::move(launch_info), test_driver_component_controller_.NewRequest());
- }
-
- TestPoint test_driver_completed_{"test driver completed execution"};
-
- // Checks the return value of the test driver component after it runs to
- // completion, setting the status of the test based on the exit code: non-zero
- // is a failure, whereas zero is a success.
- void RunTestDriver() {
- link_->Get(
- fidl::VectorPtr(test_driver_url_path_),
- [this](std::unique_ptr<fuchsia::mem::Buffer> link_data) {
- if (link_data == nullptr) {
- Signal(modular::testing::kTestShutdown);
- return;
- }
- std::string json;
- FXL_CHECK(fsl::StringFromVmo(*link_data, &json));
- rapidjson::Document document;
- document.Parse(json.c_str());
- std::string test_driver_url = document.GetString();
- FXL_LOG(INFO) << "TestDriverModule launching test driver for URL: "
- << test_driver_url;
-
- CreateTestDriverComponent(test_driver_url);
- test_driver_component_controller_.events().OnTerminated =
- [this](int64_t return_code,
- fuchsia::sys::TerminationReason reason) {
- FXL_LOG(INFO)
- << "TestDriverModule test driver returned with code : "
- << return_code;
- if (return_code) {
- modular::testing::Fail("Test driver failed.");
- } else {
- test_driver_completed_.Pass();
- }
- Signal(modular::testing::kTestShutdown);
- };
- });
- }
-
- modular::ModuleHost* const module_host_;
-
- component::Services test_driver_services_;
- fuchsia::modular::LinkPtr link_;
- fuchsia::sys::LauncherPtr test_driver_launcher_;
- fuchsia::sys::ComponentControllerPtr test_driver_component_controller_;
-
- std::vector<std::string> sub_module_url_path_;
- std::vector<std::string> test_driver_url_path_;
-
- fuchsia::modular::ModuleControllerPtr sub_module_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/bin/token_manager/BUILD.gn b/bin/token_manager/BUILD.gn
deleted file mode 100644
index b632f45..0000000
--- a/bin/token_manager/BUILD.gn
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("dev_token_manager") {
- meta = [
- {
- path = "meta/dev_token_manager.cmx"
- dest = "dev_token_manager.cmx"
- },
- ]
-
- sources = [
- "dev_token_manager.cc",
- ]
-
- deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-}
diff --git a/bin/token_manager/README.md b/bin/token_manager/README.md
deleted file mode 100644
index 730757f..0000000
--- a/bin/token_manager/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# dev_token_manager
-
-This implementation of the `TokenManager` and related services is used in all
-integration tests. See `//peridot/tests/modular_tests.json` for how.
diff --git a/bin/token_manager/dev_token_manager.cc b/bin/token_manager/dev_token_manager.cc
deleted file mode 100644
index babb2f0..0000000
--- a/bin/token_manager/dev_token_manager.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/auth/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/log_settings_command_line.h>
-#include <lib/fxl/macros.h>
-#include <trace-provider/provider.h>
-
-namespace fuchsia {
-namespace modular {
-namespace auth {
-
-class AccountProviderImpl : AccountProvider {
- public:
- AccountProviderImpl(async::Loop* loop);
-
- private:
- // |AccountProvider| implementation:
- void Terminate() override;
- void AddAccount(fuchsia::modular::auth::IdentityProvider identity_provider,
- AddAccountCallback callback) override;
- void RemoveAccount(fuchsia::modular::auth::Account account, bool revoke_all,
- RemoveAccountCallback callback) override;
-
- std::string GenerateAccountId();
-
- async::Loop* const loop_;
- std::shared_ptr<component::StartupContext> startup_context_;
- fidl::Binding<AccountProvider> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AccountProviderImpl);
-};
-
-AccountProviderImpl::AccountProviderImpl(async::Loop* loop)
- : loop_(loop),
- startup_context_(component::StartupContext::CreateFromStartupInfo()),
- binding_(this) {
- FXL_DCHECK(loop);
- startup_context_->outgoing().AddPublicService<AccountProvider>(
- [this](fidl::InterfaceRequest<AccountProvider> request) {
- binding_.Bind(std::move(request));
- });
-}
-
-void AccountProviderImpl::Terminate() { loop_->Quit(); }
-
-std::string AccountProviderImpl::GenerateAccountId() {
- uint32_t random_number = 0;
- zx_cprng_draw(&random_number, sizeof random_number);
- return std::to_string(random_number);
-}
-
-void AccountProviderImpl::AddAccount(
- fuchsia::modular::auth::IdentityProvider identity_provider,
- AddAccountCallback callback) {
- auto account = fuchsia::modular::auth::Account::New();
- account->id = GenerateAccountId();
- account->identity_provider = identity_provider;
- account->display_name = "";
- account->url = "";
- account->image_url = "";
-
- switch (identity_provider) {
- case fuchsia::modular::auth::IdentityProvider::DEV:
- callback(std::move(account), nullptr);
- return;
- default:
- callback(nullptr, "Unrecognized Identity Provider");
- }
-}
-
-void AccountProviderImpl::RemoveAccount(fuchsia::modular::auth::Account account,
- bool revoke_all,
- RemoveAccountCallback callback) {}
-
-} // namespace auth
-} // namespace modular
-} // namespace fuchsia
-
-int main(int argc, const char** argv) {
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- if (!fxl::SetLogSettingsFromCommandLine(command_line)) {
- return 1;
- }
-
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- trace::TraceProvider trace_provider(loop.dispatcher());
-
- fuchsia::modular::auth::AccountProviderImpl app(&loop);
- loop.Run();
- return 0;
-}
diff --git a/bin/token_manager/meta/dev_token_manager.cmx b/bin/token_manager/meta/dev_token_manager.cmx
deleted file mode 100644
index f242a93..0000000
--- a/bin/token_manager/meta/dev_token_manager.cmx
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/boards/arm64.gni b/boards/arm64.gni
deleted file mode 100644
index 6440ec5..0000000
--- a/boards/arm64.gni
+++ /dev/null
@@ -1 +0,0 @@
-import("//garnet/boards/arm64.gni")
diff --git a/boards/x64.gni b/boards/x64.gni
deleted file mode 100644
index 59e066f..0000000
--- a/boards/x64.gni
+++ /dev/null
@@ -1 +0,0 @@
-import("//garnet/boards/x64.gni")
diff --git a/build/executable_package.gni b/build/executable_package.gni
deleted file mode 100644
index 94a9753..0000000
--- a/build/executable_package.gni
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-
-# A package() that just contains a single binary created as an executable()
-# under the name of the rule. We currently prefer packages with single binaries,
-# because only such binaries can be executed directly from the package name in
-# appmgr.
-template("executable_package") {
- binary_rule = "${target_name}_bin"
- binary_name = target_name
-
- executable(binary_rule) {
- output_name = "${binary_name}"
- forward_variables_from(invoker,
- [
- "sources",
- "deps",
- "public_deps",
- "testonly",
- ])
- }
-
- package(target_name) {
- forward_variables_from(invoker,
- [
- "deps",
- "deprecated_system_image",
- "public_deps",
- "testonly",
- "meta",
- "tests",
- "resources",
- "deprecated_bare_package_url",
- ])
- if (defined(deps)) {
- deps += [ ":${binary_rule}" ]
- } else {
- deps = [
- ":${binary_rule}",
- ]
- }
-
- if (!defined(deprecated_system_image) || !deprecated_system_image) {
- binary = binary_name
- } else {
- binaries = [
- {
- name = binary_name
- },
- ]
- }
- }
-}
diff --git a/build/module_manifest.gni b/build/module_manifest.gni
deleted file mode 100644
index 56d63ee..0000000
--- a/build/module_manifest.gni
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-
-# This is a rule used to generate an index of module packages that should be
-# indexed by the on-device module resolver when it starts up. This template is
-# meant to be used only once for each layer, but multiple may exist for
-# different device package sets. This target generates a system package, so
-# this target *must* be included in your layer's build image.
-#
-# The following must be true for each of the listed packages:
-#
-# 0) Make sure this module package is built and included on the device image.
-# E.g: For an index of all topaz modules, make sure all module packages are
-# transitively included from //topaz/packages/topaz.
-# 1) Create a Module manifest file as per //peridot/docs/modular/manifests/module.md
-# and include it in your module package. The flutter_app() template from
-# topaz includes the specified module manifest in the package for you.
-# 2) Point the 'binary' attribute in your manifest to the module's package name.
-#
-# Example:
-#
-# import("//peridot/build/module_manifest.gni")
-#
-# initial_module_packages("manifests") {
-# packages = [ "my_module_package1", "my_module_package2" ]
-# }
-template("initial_module_packages") {
- assert(defined(invoker.packages),
- "'packages' must be defined for $target_name")
-
- # NOTE: The fully resolved path will be
- # /system/data/module_manifest_repository
- # This must match that given in bin/module_resolver/module_resolver_main.cc
- module_index_filename = "$root_build_dir/module_package_index/$target_name"
- write_file(module_index_filename, invoker.packages)
-
- package(target_name) {
- deprecated_system_image = true
- resources = [
- {
- path = rebase_path(module_index_filename)
- dest = "initial_module_packages/$target_name"
- },
- ]
- }
-}
\ No newline at end of file
diff --git a/build/tests_package.gni b/build/tests_package.gni
deleted file mode 100644
index 63018e7..0000000
--- a/build/tests_package.gni
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-import("//build/test/test_package.gni")
-
-# A variant of package() that only contains test executables. The test
-# executables are specified as the build products of the deps. A tests_package()
-# is always testonly = true. The deps are expected to be executable()s.
-#
-# Additional parameters
-#
-# environments (optional, default: [ { dimensions = { device_type = "QEMU" } } ])
-# [list of scopes] Device environments in which the tests should run. See
-# //build/package.gni for more details.
-#
-template("tests_package") {
- computed_tests = []
- foreach(dep, invoker.deps) {
- computed_tests += [
- {
- name = get_label_info(dep, "name")
- if (defined(invoker.environments)) {
- environments = invoker.environments
- }
- },
- ]
- }
-
- package(target_name) {
- testonly = true
-
- forward_variables_from(invoker,
- [
- "deps",
- "meta",
- "resources",
- ])
- tests = computed_tests
- }
-}
-
-# A variant of test_package() that only contains test executables. It computes
-# the value of the 'tests' paremeter from 'deps'.
-#
-# This variant, as described in
-# https://fuchsia.git.corp.google.com/docs/+/master/development/tests/test_component.md,
-# requires a .cmx file for each test.
-#
-#
-# Additional parameters
-#
-# environments (optional, default: [ { dimensions = { device_type = "QEMU" } } ])
-# [list of scopes] Device environments in which the tests should run. See
-# //build/package.gni for more details.
-#
-template("hermetic_tests_package") {
- computed_tests = []
- foreach(dep, invoker.deps) {
- computed_tests += [
- {
- name = get_label_info(dep, "name")
- if (defined(invoker.environments)) {
- environments = invoker.environments
- }
- },
- ]
- }
-
- test_package(target_name) {
- forward_variables_from(invoker,
- [
- "deps",
- "meta",
- "resources",
- ])
- tests = computed_tests
- }
-}
diff --git a/cloud/go/src/remote_module_resolver/BUILD.gn b/cloud/go/src/remote_module_resolver/BUILD.gn
deleted file mode 100644
index 043d147..0000000
--- a/cloud/go/src/remote_module_resolver/BUILD.gn
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/go/go_binary.gni")
-import("//build/go/go_library.gni")
-import("//build/go/go_test.gni")
-import("//build/host.gni")
-import("//build/package.gni")
-
-go_library("remote_module_resolver_lib") {
- name = "remote_module_resolver"
-
- deps = [
- ":gojsonpointer",
- ":gojsonreference",
- ":gojsonschema",
- ]
-}
-
-go_library("gojsonpointer") {
- name = "github.com/xeipuuv/gojsonpointer"
- source_dir =
- "//peridot/cloud/third_party/golibs/github.com/xeipuuv/gojsonpointer"
-}
-go_library("gojsonreference") {
- name = "github.com/xeipuuv/gojsonreference"
- source_dir =
- "//peridot/cloud/third_party/golibs/github.com/xeipuuv/gojsonreference"
-}
-go_library("gojsonschema") {
- name = "github.com/xeipuuv/gojsonschema"
- source_dir =
- "//peridot/cloud/third_party/golibs/github.com/xeipuuv/gojsonschema"
-}
-
-go_binary("remote_module_resolver") {
- gopackage = "remote_module_resolver"
- output_name = "remote_module_resolver"
- deps = [
- ":remote_module_resolver_lib",
- ]
-}
-
-go_test("remote_module_resolver_test") {
- gopackage = "remote_module_resolver/repository"
- deps = [
- ":remote_module_resolver_lib",
- ]
-}
-
-install_host_tools("host") {
- deps = [
- ":remote_module_resolver",
- ]
- outputs = [
- "remote_module_resolver",
- ]
-}
-
-install_host_tools("host_tests") {
- deps = [
- ":remote_module_resolver_test",
- ]
- outputs = [
- "remote_module_resolver_test",
- ]
-}
diff --git a/cloud/go/src/remote_module_resolver/main.go b/cloud/go/src/remote_module_resolver/main.go
deleted file mode 100644
index 9370171..0000000
--- a/cloud/go/src/remote_module_resolver/main.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package main
-
-import (
- "encoding/json"
- "flag"
- "fmt"
- "io/ioutil"
- "log"
- "net/http"
- "remote_module_resolver/repository"
-)
-
-var (
- usage = "Starts the module resolver HTTP service."
- manifestDir = flag.String("manifests-directory", "/tmp/module_manifests", "Path to the directory containing module manifests.")
- httpPort = flag.Int("port", 15321, "TCP Port to run the resolver HTTP server on.")
-)
-
-func main() {
- flag.CommandLine.Usage = func() {
- fmt.Println(usage)
- flag.CommandLine.PrintDefaults()
- }
- flag.Parse()
- log.SetPrefix("remote module resolver: ")
- log.SetFlags(log.Ltime & log.LstdFlags)
- log.Println("Resolver listening to port ", *httpPort, " with manifest directory ", *manifestDir)
-
- repo := repository.NewRepository(*manifestDir)
- // /addmodule
- // POST body: JSON module manifest contents
- http.HandleFunc("/addmodule", func(writer http.ResponseWriter,
- request *http.Request) {
- if request.Method != "POST" {
- writer.WriteHeader(http.StatusBadRequest)
- writer.Write(nil)
- return
- }
-
- defer request.Body.Close()
- bytes, err := ioutil.ReadAll(request.Body)
- if err != nil {
- log.Println(err)
- writer.WriteHeader(http.StatusBadRequest)
- return
- }
- log.Println("/addmodule: ", string(bytes))
- if err = repo.SaveAndIndexManifest(bytes); err != nil {
- log.Println(err)
- writer.WriteHeader(http.StatusBadRequest)
- return
- }
- writer.WriteHeader(http.StatusOK)
- })
-
- // /findmodules
- // POST request body: json-encoded |repository.FindModulesRequest|
- // POST response body: json-encoded |repository.ModuleResolution|
- http.HandleFunc("/findmodules", func(writer http.ResponseWriter,
- request *http.Request) {
- if request.Method != "POST" {
- writer.WriteHeader(http.StatusBadRequest)
- return
- }
-
- defer request.Body.Close()
- bytes, err := ioutil.ReadAll(request.Body)
- if err != nil {
- writer.WriteHeader(http.StatusBadRequest)
- log.Println(err)
- return
- }
-
- log.Println("/findmodules: ", string(bytes))
- var reqInJson map[string]interface{}
- if err = json.Unmarshal(bytes, &reqInJson); err != nil {
- writer.WriteHeader(http.StatusBadRequest)
- log.Println(err)
- return
- }
-
- paramsMap := make(map[repository.ParameterName][]repository.ParameterType)
- for _, kv := range reqInJson["parameters"].([]interface{}) {
- kv := kv.(map[string]interface{})
- paramsMap[kv["@k"].(repository.ParameterName)] = kv["@v"].([]repository.ParameterType)
- }
- results, err := repo.FindModules(repository.FindModulesRequest{Action: repository.ActionName(reqInJson["action"].(string)), Parameters: paramsMap})
- if err != nil {
- writer.WriteHeader(http.StatusBadRequest)
- log.Println(err)
- return
- }
-
- encoded, err := json.Marshal(results)
- if err != nil {
- writer.WriteHeader(http.StatusBadRequest)
- log.Println(err)
- return
- }
- writer.WriteHeader(http.StatusOK)
- writer.Write(encoded)
- return
- })
-
- log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *httpPort), nil))
-}
diff --git a/cloud/go/src/remote_module_resolver/repository/manifest_set.go b/cloud/go/src/remote_module_resolver/repository/manifest_set.go
deleted file mode 100644
index 42059a1..0000000
--- a/cloud/go/src/remote_module_resolver/repository/manifest_set.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package repository
-
-// set of manifests ID'd by their moduleUrl.
-type ManifestSet map[ModuleUrl]struct{}
-
-// This modifies |dest| by leaving only the keys that are both in |dest| *and*
-// |source|. |source| is left unchanged.
-func (dest ManifestSet) intersect(source ManifestSet) {
- for moduleUrl := range dest {
- if _, ok := source[moduleUrl]; !ok {
- delete(dest, moduleUrl)
- }
- }
-}
-
-// This modifies |dest| by including all things in |source|.
-func (dest ManifestSet) merge(source ManifestSet) {
- for moduleUrl := range source {
- dest[moduleUrl] = struct{}{}
- }
-}
-
-func listToManifestSet(l []ModuleUrl) ManifestSet {
- set := make(ManifestSet)
- for _, item := range l {
- set[item] = struct{}{}
- }
- return set
-}
diff --git a/cloud/go/src/remote_module_resolver/repository/module_manifest_schema.go b/cloud/go/src/remote_module_resolver/repository/module_manifest_schema.go
deleted file mode 100644
index 2ae26ea..0000000
--- a/cloud/go/src/remote_module_resolver/repository/module_manifest_schema.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package repository
-
-// TODO(vardhan): Use a flag to pass in path-to-manifest-schema that overrides
-// this default schema.
-const ModuleManifestSchema = `{
- "$schema": "http://json-schema.org/schema#",
- "title": "Schema for 'action_template' metadata file",
- "definitions": {
- "parameterArray": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/parameter"
- },
- "additionalItems": false,
- "uniqueItems": true,
- "minItems": 1
- },
- "parameter": {
- "type": "object",
- "properties": {
- "name": {
- "$ref": "#/definitions/alphaNumString"
- },
- "type": {
- "type": "string"
- },
- "required": {
- "type": "boolean"
- }
- },
- "required": [
- "name",
- "type"
- ],
- "additionalProperties": false
- },
- "alphaNumString": {
- "type": "string",
- "pattern": "^[a-zA-Z0-9_]+$"
- },
- "compositionPattern": {
- "type": "string",
- "enum": [
- "ticker",
- "comments-right"
- ]
- }
- },
- "type": "object",
- "properties": {
- "binary": {
- "type": "string"
- },
- "suggestion_headline": {
- "type": "string"
- },
- "action": {
- "type": "string"
- },
- "parameters": {
- "$ref": "#/definitions/parameterArray"
- },
- "composition_pattern": {
- "$ref": "#/definitions/compositionPattern"
- }
- },
- "required": [
- "binary",
- "action"
- ],
- "additionalProperties": false
-}`
diff --git a/cloud/go/src/remote_module_resolver/repository/repository.go b/cloud/go/src/remote_module_resolver/repository/repository.go
deleted file mode 100644
index f035374..0000000
--- a/cloud/go/src/remote_module_resolver/repository/repository.go
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package repository
-
-import (
- "crypto/sha256"
- "encoding/hex"
- "encoding/json"
- "errors"
- "fmt"
- "github.com/xeipuuv/gojsonschema"
- "io/ioutil"
- "log"
- "os"
- "path"
-)
-
-type ParameterName string
-type ParameterType string
-type ModuleUrl string
-type ActionName string
-type FindModulesRequest struct {
- Action ActionName
- // The ability to accept multiple types per named parameter allows the
- // requestor to specify additional polymorphic types.
- Parameters map[ParameterName][]ParameterType
-}
-
-type ManifestContent struct {
- Url ModuleUrl
- Content ParsedManifest
-}
-
-type ModuleResolution struct {
- // [0, 1], 1 being most relevant.
- Score float32
- Manifest ManifestContent
-}
-
-type ModuleResolver interface {
- FindModules(req FindModulesRequest) ([]ModuleResolution, error)
- SaveAndIndexManifest(rawModuleManifest []byte) error
- IndexManifest(rawModuleManifest []byte) (ModuleUrl, error)
- UnIndexManifest(moduleUrl ModuleUrl) error
-}
-
-type ParameterNameToManifestSet map[ParameterName]ManifestSet
-type ParsedManifest map[string]interface{}
-type Repository struct {
- // Implements |ModuleResolver|.
- // TODO(vardhan): Use a persistent DB for indexing and searching.
-
- // The directory where module manifest files are located and where new
- // ones will be stored.
- manifestDir string
-
- // The following are different indices pointing to a parsed manifest.
- manifestsByModuleUrl map[ModuleUrl]ParsedManifest
- moduleUrlsByParameter map[ParameterType]ParameterNameToManifestSet
- moduleUrlsByAction map[ActionName]ManifestSet
-}
-
-func NewRepository(manifestDir string) *Repository {
- repo := Repository{
- manifestDir: manifestDir,
- manifestsByModuleUrl: make(map[ModuleUrl]ParsedManifest),
- moduleUrlsByParameter: make(map[ParameterType]ParameterNameToManifestSet),
- moduleUrlsByAction: make(map[ActionName]ManifestSet),
- }
- if manifestFiles, err := ioutil.ReadDir(manifestDir); err == nil {
- for _, file := range manifestFiles {
- if file.IsDir() {
- continue
- }
- if bytes, err := ioutil.ReadFile(path.Join(manifestDir, file.Name())); err == nil {
- _, err := repo.IndexManifest(bytes)
- if err != nil {
- log.Println("Could not index manifest file ", file.Name(), err)
- }
- } else {
- log.Println("Could not read manifest file: ", err)
- }
- }
- } else {
- log.Println("Could not open manifest directory ", manifestDir, ":", err)
- }
-
- log.Println("Indexed ", len(repo.manifestsByModuleUrl), " manifests")
- return &repo
-}
-
-func (r *Repository) SaveAndIndexManifest(rawModuleManifest []byte) error {
- moduleUrl, err := r.IndexManifest(rawModuleManifest)
- if err != nil {
- return err
- }
-
- if stat, err := os.Stat(r.manifestDir); err != nil || !stat.IsDir() {
- if err := os.Mkdir(r.manifestDir, 0755); err != nil {
- return fmt.Errorf("Could not create manifest directory: %s", err)
- }
- if err := os.Chmod(r.manifestDir, 0755); err != nil {
- return fmt.Errorf("Could not set manifest directory permissions: %s", err)
- }
- }
-
- shaUrl := sha256.Sum256([]byte(moduleUrl))
- fileName := hex.EncodeToString(shaUrl[:])
- if err = ioutil.WriteFile(path.Join(r.manifestDir, fileName), rawModuleManifest, os.ModePerm); err != nil {
- return fmt.Errorf("Could not save manifest to file: %s", err)
- }
-
- return nil
-}
-
-// On success, returns the module's Url.
-func (r *Repository) IndexManifest(rawModuleManifest []byte) (ModuleUrl, error) {
- jsonManifest := make(ParsedManifest)
- err := json.Unmarshal(rawModuleManifest, &jsonManifest)
-
- schema := gojsonschema.NewStringLoader(ModuleManifestSchema)
- manifest := gojsonschema.NewStringLoader(string(rawModuleManifest))
- result, err := gojsonschema.Validate(schema, manifest)
- if err != nil {
- // The |schema| or |manifest| could not be parsed.
- return "", err
- }
- if !result.Valid() {
- // |manifest| does not follow the module manifest schema.
- return "", errors.New("invalid module manifest schema")
- }
-
- action := ActionName(jsonManifest["action"].(string))
- moduleUrl := ModuleUrl(jsonManifest["binary"].(string))
-
- r.UnIndexManifest(moduleUrl)
-
- // Index the manifest
- r.manifestsByModuleUrl[moduleUrl] = jsonManifest
- if _, ok := r.moduleUrlsByAction[action]; !ok {
- r.moduleUrlsByAction[action] = make(ManifestSet)
- }
- r.moduleUrlsByAction[action][moduleUrl] = struct{}{}
-
- for _, parameter := range jsonManifest["parameters"].([]interface{}) {
- parameterMap := ParsedManifest(parameter.(map[string]interface{}))
- paramName := ParameterName(parameterMap["name"].(string))
- paramType := ParameterType(parameterMap["type"].(string))
-
- if _, ok := r.moduleUrlsByParameter[paramType]; !ok {
- r.moduleUrlsByParameter[paramType] = make(ParameterNameToManifestSet)
- }
- if _, ok := r.moduleUrlsByParameter[paramType][paramName]; !ok {
- r.moduleUrlsByParameter[paramType][paramName] = make(ManifestSet)
- }
- r.moduleUrlsByParameter[paramType][paramName][moduleUrl] = struct{}{}
- }
- return moduleUrl, nil
-}
-
-func (r *Repository) UnIndexManifest(moduleUrl ModuleUrl) error {
- if jsonManifest, ok := r.manifestsByModuleUrl[moduleUrl]; ok {
- if parameters, ok := jsonManifest["parameters"]; ok {
- for _, parameter := range parameters.([]interface{}) {
- paramName := ParameterName(ParsedManifest(parameter.(map[string]interface{}))["name"].(string))
- paramType := ParameterType(ParsedManifest(parameter.(map[string]interface{}))["type"].(string))
- delete(r.moduleUrlsByParameter[paramType][paramName], moduleUrl)
- if len(r.moduleUrlsByParameter[paramType][paramName]) == 0 {
- delete(r.moduleUrlsByParameter[paramType], paramName)
- }
- if len(r.moduleUrlsByParameter[paramType]) == 0 {
- delete(r.moduleUrlsByParameter, paramType)
- }
- }
- }
-
- delete(r.moduleUrlsByAction, jsonManifest["action"].(ActionName))
- delete(r.manifestsByModuleUrl, moduleUrl)
- return nil
- }
- return fmt.Errorf("could not remove manifest: none exists for %s", moduleUrl)
-}
-
-func (r *Repository) findManifestsByParameter(paramName ParameterName, paramType ParameterType) ManifestSet {
- if nameMap, ok := r.moduleUrlsByParameter[paramType]; ok {
- if manifests, ok := nameMap[paramName]; ok {
- return manifests
- }
- }
- return nil
-}
-
-func hasAllRequiredParameters(req FindModulesRequest, moduleManifest ParsedManifest) bool {
- if parameters, ok := moduleManifest["parameters"]; ok {
- for _, constraint := range parameters.([]interface{}) {
- constraintKeys := constraint.(map[string]interface{})
- paramName := ParameterName(constraintKeys["name"].(string))
- // Parameters are required by default. Check if this was marked optional.
- if isRequired, found := constraintKeys["required"]; !found || (found && isRequired.(bool)) {
- // It is required. Check that it was specified in the request
- if _, found := req.Parameters[paramName]; !found {
- return false
- }
- }
- }
- }
- return true
-}
-
-// TODO(vardhan): Make this a separate exported API, and rename |FindModules| ->
-// |FindModulesByAction|
-func (r *Repository) findModulesByParamTypes(req FindModulesRequest) ([]ModuleResolution, error) {
- return []ModuleResolution{}, nil
-}
-
-func (r *Repository) FindModules(req FindModulesRequest) ([]ModuleResolution, error) {
- if req.Action == "" {
- return r.findModulesByParamTypes(req)
- }
-
- // 1. Find all module manifests that contain the action in the request.
- candidateModules := make(ManifestSet)
- for moduleUrl := range r.moduleUrlsByAction[req.Action] {
- candidateModules[moduleUrl] = struct{}{}
- }
-
- // 2. Find all module manifests that contain the parameters in request.
- // 3. Intersect the 1) and 2) to get the possible candidate manifests.
- for paramName, paramTypes := range req.Parameters {
- manifests := make(ManifestSet)
- for _, paramType := range paramTypes {
- manifests.merge(r.findManifestsByParameter(paramName, paramType))
- }
- candidateModules.intersect(manifests)
- }
-
- // 4. Filter through the candidates to make sure their required parameters are
- // provided in the request.
- results := []ModuleResolution{}
- for candidateModuleUrl := range candidateModules {
- if !hasAllRequiredParameters(req, r.manifestsByModuleUrl[candidateModuleUrl]) {
- continue
- }
-
- results = append(results, ModuleResolution{
- Manifest: ManifestContent{
- Url: candidateModuleUrl,
- Content: r.manifestsByModuleUrl[candidateModuleUrl]},
- Score: 1.0})
- }
- return results, nil
-}
diff --git a/cloud/go/src/remote_module_resolver/repository/repository_test.go b/cloud/go/src/remote_module_resolver/repository/repository_test.go
deleted file mode 100644
index a77bf4b..0000000
--- a/cloud/go/src/remote_module_resolver/repository/repository_test.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package repository
-
-import (
- "reflect"
- "testing"
-)
-
-var moduleManifestsRepo = map[ModuleUrl][]byte{
- "module_url1": []byte(`
- {
- "binary": "module_url1",
- "action": "com.fuchsia.action",
- "parameters": [
- {
- "name": "ParamName",
- "type": "ParamType"
- }
- ]
- }`),
-
- "module_url2": []byte(`
- {
- "binary": "module_url2",
- "action": "com.fuchsia.action",
- "parameters": [
- {
- "name": "ParamName",
- "type": "ParamType"
- }
- ]
- }`),
-
- "module_url3": []byte(`
- {
- "binary": "module_url3",
- "action": "com.fuchsia.action",
- "parameters": [
- {
- "name": "ParamName",
- "type": "DifferentParamType"
- }
- ]
- }`),
-}
-
-// |FindModulesTestCase| describes a single test case that involves issuing a
-// FindModules query against a repository of modules, with an expected set of
-// modules as the result.
-type FindModulesTestCase struct {
- // Which modules to index from |moduleManifestRepo| for this particular test?
- IndexedModules []ModuleUrl
- Query FindModulesRequest
- // Which expected set of modules should return from the |Query| above? This
- // list is treated like a set.
- ExpectedResults []ModuleUrl
-}
-
-func (testCase FindModulesTestCase) run(t *testing.T) {
- var resolver ModuleResolver = NewRepository("")
- for _, moduleUrl := range testCase.IndexedModules {
- _, err := resolver.IndexManifest(moduleManifestsRepo[moduleUrl])
- if err != nil {
- t.Errorf("FAIL: Could not index module manifest '%s': %s", moduleUrl, err)
- return
- }
- }
- results, err := resolver.FindModules(testCase.Query)
- if err != nil {
- t.Errorf("FAIL: Could not execute query: %s", err)
- return
- }
-
- resultUrls := []ModuleUrl{}
- for _, result := range results {
- resultUrls = append(resultUrls, result.Manifest.Url)
- }
-
- if !reflect.DeepEqual(listToManifestSet(resultUrls), listToManifestSet(testCase.ExpectedResults)) {
- t.Errorf("FAIL: Did not get expected results. #expected = %d, #actual = %d",
- len(testCase.ExpectedResults),
- len(results))
- }
-}
-
-func TestExactMatchSingleModule(t *testing.T) {
- FindModulesTestCase{
- IndexedModules: []ModuleUrl{"module_url1"},
- Query: FindModulesRequest{
- Action: "com.fuchsia.action",
- Parameters: map[ParameterName][]ParameterType{
- "ParamName": []ParameterType{"ParamType"},
- },
- },
- ExpectedResults: []ModuleUrl{"module_url1"},
- }.run(t)
-}
-
-func TestExactMatchMultipleModules(t *testing.T) {
- FindModulesTestCase{
- IndexedModules: []ModuleUrl{"module_url1", "module_url2"},
- Query: FindModulesRequest{
- Action: "com.fuchsia.action",
- Parameters: map[ParameterName][]ParameterType{
- "ParamName": []ParameterType{"ParamType", "UnknownParamType"},
- },
- },
- ExpectedResults: []ModuleUrl{"module_url1", "module_url2"},
- }.run(t)
-}
-
-func TestNoMatchUnknownParamType(t *testing.T) {
- FindModulesTestCase{
- IndexedModules: []ModuleUrl{"module_url1"},
- Query: FindModulesRequest{
- Action: "com.fuchsia.action",
- Parameters: map[ParameterName][]ParameterType{
- "ParamName": []ParameterType{"UnknownParamType"},
- },
- },
- ExpectedResults: []ModuleUrl{},
- }.run(t)
-}
-
-func TestDifferentParamTypes(t *testing.T) {
- FindModulesTestCase{
- IndexedModules: []ModuleUrl{"module_url1", "module_url3"},
- Query: FindModulesRequest{
- Action: "com.fuchsia.action",
- Parameters: map[ParameterName][]ParameterType{
- "ParamName": []ParameterType{"ParamType"},
- },
- },
- ExpectedResults: []ModuleUrl{"module_url1"},
- }.run(t)
-}
diff --git a/docs/conventions.md b/docs/conventions.md
deleted file mode 100644
index f61dc9d..0000000
--- a/docs/conventions.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Conventions
-
-This document tracks layer-wide conventions for Peridot code.
-
-## Testing helpers
-
-Test-only utils (but not the tests themselves) related to a given library should
-be placed under the directory of the library itself, in a subdirectory called
-`testing` (and not `test`).
-
-The test-only symbols should be declared in the same namespace as the library
-the test helpers are related to (and not in a `test` or `testing` subnamespace).
-
-The build targets containing test-only utils should be marked as such using the
-GN `testonly = true` annotation.
diff --git a/docs/gen/build_arguments.md b/docs/gen/build_arguments.md
deleted file mode 100644
index e21b6a0..0000000
--- a/docs/gen/build_arguments.md
+++ /dev/null
@@ -1,1159 +0,0 @@
-# GN Build Arguments
-
-## All builds
-
-### host_os
-
-**Current value (from the default):** `"linux"`
-
-### icu_use_data_file
-Tells icu to load an external data file rather than rely on the icudata
-being linked directly into the binary.
-
-This flag is a bit confusing. As of this writing, icu.gyp set the value to
-0 but common.gypi sets the value to 1 for most platforms (and the 1 takes
-precedence).
-
-TODO(GYP) We'll probably need to enhance this logic to set the value to
-true or false in similar circumstances.
-
-**Current value (from the default):** `true`
-
-From [//third_party/icu/config.gni:15](https://fuchsia.googlesource.com/third_party/icu/+/15006476e9d2f5c7d6691f3658fecff4929aaf68/config.gni#15)
-
-### magma_enable_developer_build
-Enable this to have the msd include a suite of tests and invoke them
-automatically when the driver starts.
-
-**Current value (from the default):** `false`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:19](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#19)
-
-### use_goma
-Set to true to enable distributed compilation using Goma.
-
-**Current value (from the default):** `false`
-
-From [//build/toolchain/goma.gni:9](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/toolchain/goma.gni#9)
-
-### build_libvulkan
-This is a list of targets that will be built as vulkan ICDS. If more than one
-target is given then use_vulkan_loader_for_tests must be set to true, as
-otherwise tests won't know which libvulkan to use.
-
-**Current value (from the default):** `[]`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:38](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#38)
-
-### build_vsl_gc
-
-**Current value (from the default):** `true`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:22](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#22)
-
-### extra_variants
-Additional variant toolchain configs to support.
-This is just added to [`known_variants`](#known_variants).
-
-**Current value (from the default):** `[]`
-
-From [//build/config/BUILDCONFIG.gn:393](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILDCONFIG.gn#393)
-
-### host_byteorder
-
-**Current value (from the default):** `"undefined"`
-
-From [//build/config/host_byteorder.gni:7](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/host_byteorder.gni#7)
-
-### scenic_ignore_vsync
-
-**Current value (from the default):** `false`
-
-From [//garnet/lib/ui/gfx/BUILD.gn:16](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/ui/gfx/BUILD.gn#16)
-
-### select_variant
-List of "selectors" to request variant builds of certain targets.
-Each selector specifies matching criteria and a chosen variant.
-The first selector in the list to match a given target determines
-which variant is used for that target.
-
-Each selector is either a string or a scope. A shortcut selector is
-a string; it gets expanded to a full selector. A full selector is a
-scope, described below.
-
-A string selector can match a name in
-[`select_variant_shortcuts`](#select_variant_shortcuts). If it's not a
-specific shortcut listed there, then it can be the name of any variant
-described in [`known_variants`](#known_variants) and
-[`universal_variants`](#universal_variants) (and combinations thereof).
-A `selector` that's a simple variant name selects for every binary
-built in the target toolchain: `{ host=false variant=selector }`.
-
-If a string selector contains a slash, then it's `"shortcut/filename"`
-and selects only the binary in the target toolchain whose `output_name`
-matches `"filename"`, i.e. it adds `output_name=["filename"]` to each
-selector scope that the shortcut's name alone would yield.
-
-The scope that forms a full selector defines some of these:
-
- variant (required)
- [string or `false`] The variant that applies if this selector
- matches. This can be `false` to choose no variant, or a string
- that names the variant. See
- [`known_variants`](#known_variants) and
- [`universal_variants`](#universal_variants).
-
-The rest below are matching criteria. All are optional.
-The selector matches if and only if all of its criteria match.
-If none of these is defined, then the selector always matches.
-
-The first selector in the list to match wins and then the rest of
-the list is ignored. So construct more complex rules by using a
-"blacklist" selector with `variant=false` before a catch-all or
-"whitelist" selector that names a variant.
-
-Each "[strings]" criterion is a list of strings, and the criterion
-is satisfied if any of the strings matches against the candidate string.
-
- host
- [boolean] If true, the selector matches in the host toolchain.
- If false, the selector matches in the target toolchain.
-
- testonly
- [boolean] If true, the selector matches targets with testonly=true.
- If false, the selector matches in targets without testonly=true.
-
- target_type
- [strings]: `"executable"`, `"loadable_module"`, or `"driver_module"`
-
- output_name
- [strings]: target's `output_name` (default: its `target name`)
-
- label
- [strings]: target's full label with `:` (without toolchain suffix)
-
- name
- [strings]: target's simple name (label after last `/` or `:`)
-
- dir
- [strings]: target's label directory (`//dir` for `//dir:name`).
-
-**Current value (from the default):** `[]`
-
-From [//build/config/BUILDCONFIG.gn:613](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILDCONFIG.gn#613)
-
-### synthesize_packages
-List of extra packages to synthesize on the fly. This is only for
-things that do not appear normally in the source tree. Synthesized
-packages can contain build artifacts only if they already exist in some
-part of the build. They can contain arbitrary verbatim files.
-Synthesized packages can't express dependencies on other packages.
-
-Each element of this list is a scope that is very much like the body of
-a package() template invocation (see [//build/package.gni](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/package.gni)). That scope
-must set `name` to the string naming the package, as would be the name
-in the package() target written in a GN file. This must be unique
-among all package names.
-
-**Current value (from the default):** `[]`
-
-From [//build/gn/packages.gni:43](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/gn/packages.gni#43)
-
-### universal_variants
-
-**Current value (from the default):**
-```
-[{
- configs = []
- name = "release"
- toolchain_args = {
- is_debug = false
-}
-}]
-```
-
-From [//build/config/BUILDCONFIG.gn:413](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILDCONFIG.gn#413)
-
-### always_zedboot
-Build boot images that prefer Zedboot over local boot (only for EFI).
-
-**Current value (from the default):** `false`
-
-From [//build/images/BUILD.gn:609](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#609)
-
-### amber_keys_dir
-Directory containing signing keys used by pm publish.
-
-**Current value (from the default):** `"//garnet/go/src/amber/keys"`
-
-From [//garnet/go/src/pm/pm.gni:14](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/go/src/pm/pm.gni#14)
-
-### current_cpu
-
-**Current value (from the default):** `""`
-
-### goma_dir
-Absolute directory containing the Goma source code.
-
-**Current value (from the default):** `"/home/swarming/goma"`
-
-From [//build/toolchain/goma.gni:12](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/toolchain/goma.gni#12)
-
-### data_partition_manifest
-Path to manifest file containing data to place into the initial /data
-partition.
-
-**Current value (from the default):** `""`
-
-From [//build/images/BUILD.gn:29](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#29)
-
-### scudo_default_options
-Default [Scudo](https://llvm.org/docs/ScudoHardenedAllocator.html)
-options (before the `SCUDO_OPTIONS` environment variable is read at
-runtime). *NOTE:* This affects only components using the `scudo`
-variant (see GN build argument `select_variant`), and does not affect
-anything when the `use_scudo` build flag is set instead.
-
-**Current value (from the default):** `["abort_on_error=1", "QuarantineSizeKb=0", "ThreadLocalQuarantineSizeKb=0", "DeallocationTypeMismatch=false", "DeleteSizeMismatch=false", "allocator_may_return_null=true"]`
-
-From [//build/config/scudo/scudo.gni:15](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/scudo/scudo.gni#15)
-
-### toolchain_variant
-*This should never be set as a build argument.*
-It exists only to be set in `toolchain_args`.
-See [//build/toolchain/clang_toolchain.gni](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/toolchain/clang_toolchain.gni) for details.
-This variable is a scope giving details about the current toolchain:
- `toolchain_variant.base`
- [label] The "base" toolchain for this variant, *often the
- right thing to use in comparisons, not `current_toolchain`.*
- This is the toolchain actually referenced directly in GN
- source code. If the current toolchain is not
- `shlib_toolchain` or a variant toolchain, this is the same
- as `current_toolchain`. In one of those derivative
- toolchains, this is the toolchain the GN code probably
- thought it was in. This is the right thing to use in a test
- like `toolchain_variant.base == target_toolchain`, rather
- rather than comparing against `current_toolchain`.
- `toolchain_variant.name`
- [string] The name of this variant, as used in `variant` fields
- in [`select_variant`](#select_variant) clauses. In the base
- toolchain and its `shlib_toolchain`, this is `""`.
- `toolchain_variant.suffix`
- [string] This is "-${toolchain_variant.name}", "" if name is empty.
- `toolchain_variant.is_pic_default`
- [bool] This is true in `shlib_toolchain`.
-The other fields are the variant's effects as defined in
-[`known_variants`](#known_variants).
-
-**Current value (from the default):**
-```
-{
- base = "//build/toolchain/fuchsia:arm64"
-}
-```
-
-From [//build/config/BUILDCONFIG.gn:71](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILDCONFIG.gn#71)
-
-### use_lto
-Use link time optimization (LTO).
-
-**Current value (from the default):** `false`
-
-From [//build/config/lto/config.gni:7](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/lto/config.gni#7)
-
-### zedboot_cmdline_files
-Files containing additional kernel command line arguments to bake into
-the Zedboot image. The contents of these files (in order) come after any
-arguments directly in [`zedboot_cmdline_args`](#zedboot_cmdline_args).
-These can be GN `//` source pathnames or absolute system pathnames.
-
-**Current value (from the default):** `[]`
-
-From [//build/images/zedboot/BUILD.gn:21](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/zedboot/BUILD.gn#21)
-
-### dart_pool_depth
-Maximum number of Dart processes to run in parallel.
-
-Dart analyzer uses a lot of memory which may cause issues when building
-with many parallel jobs e.g. when using goma. To avoid out-of-memory
-errors we explicitly reduce the number of jobs.
-
-**Current value (from the default):** `16`
-
-From [//build/dart/toolchain.gni:11](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/dart/toolchain.gni#11)
-
-### enable_sketchy_subsystem
-
-**Current value (from the default):** `true`
-
-From [//garnet/bin/ui/scenic/BUILD.gn:13](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/bin/ui/scenic/BUILD.gn#13)
-
-### escher_use_null_vulkan_config_on_host
-Using Vulkan on host (i.e. Linux) is an involved affair that involves
-downloading the Vulkan SDK, setting environment variables, and so forth...
-all things that are difficult to achieve in a CQ environment. Therefore,
-by default we use a stub implementation of Vulkan which fails to create a
-VkInstance. This allows everything to build, and also allows running Escher
-unit tests which don't require Vulkan.
-
-**Current value (from the default):** `true`
-
-From [//garnet/public/lib/escher/BUILD.gn:15](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/public/lib/escher/BUILD.gn#15)
-
-### toolchain_manifests
-Manifest files describing target libraries from toolchains.
-Can be either // source paths or absolute system paths.
-
-**Current value (from the default):** `["/b/s/w/ir/kitchen-workdir/buildtools/linux-x64/clang/lib/aarch64-fuchsia.manifest"]`
-
-From [//build/images/manifest.gni:11](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/manifest.gni#11)
-
-### is_debug
-Debug build.
-
-**Current value (from the default):** `true`
-
-From [//build/config/BUILDCONFIG.gn:11](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILDCONFIG.gn#11)
-
-### ledger_sync_credentials_file
-
-**Current value (from the default):** `""`
-
-From [//peridot/bin/ledger/testing/sync_params.gni:6](https://fuchsia.googlesource.com/peridot/+/2c5f509749861d23597bf7d8bde2172179938765/bin/ledger/testing/sync_params.gni#6)
-
-### zircon_system_groups
-Groups to include from the Zircon /boot manifest into /system
-(instead of into /boot like Zircon's own bootdata.bin does).
-Should not include any groups that are also in zircon_boot_groups,
-which see. If zircon_boot_groups is "all" then this should be "".
-**TODO(mcgrathr)**: _Could default to "" for `!is_debug`, or "production
-build". Note including `"test"` here places all of Zircon's tests into
-`/system/test`, which means that Fuchsia bots run those tests too._
-
-**Current value (from the default):** `"misc,test"`
-
-From [//build/images/BUILD.gn:40](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#40)
-
-### sdk_dirs
-The directories to search for parts of the SDK.
-
-By default, we search the public directories for the various layers.
-In the future, we'll search a pre-built SDK as well.
-
-**Current value (from the default):** `["//garnet/public", "//peridot/public", "//topaz/public"]`
-
-From [//build/config/fuchsia/sdk.gni:10](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/fuchsia/sdk.gni#10)
-
-### target_sysroot
-The absolute path of the sysroot that is used with the target toolchain.
-
-**Current value (from the default):** `""`
-
-From [//build/config/sysroot.gni:7](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/sysroot.gni#7)
-
-### zircon_asan_build_dir
-Zircon `USE_ASAN=true` build directory for `target_cpu` containing
-`bootfs.manifest` with libraries and `devhost.asan`.
-
-If left `""` (the default), then this is computed from
-[`zircon_build_dir`](#zircon_build_dir) and
-[`zircon_use_asan`](#zircon_use_asan).
-
-**Current value (from the default):** `""`
-
-From [//build/config/fuchsia/zircon.gni:32](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/fuchsia/zircon.gni#32)
-
-### zircon_tools_dir
-Where to find Zircon's host-side tools that are run as part of the build.
-
-**Current value (from the default):** `"//out/build-zircon/tools"`
-
-From [//build/config/fuchsia/zircon.gni:9](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/fuchsia/zircon.gni#9)
-
-### enable_frame_pointers
-Controls whether the compiler emits full stack frames for function calls.
-This reduces performance but increases the ability to generate good
-stack traces, especially when we have bugs around unwind table generation.
-It applies only for Fuchsia targets (see below where it is unset).
-
-TODO(ZX-2361): Theoretically unwind tables should be good enough so we can
-remove this option when the issues are addressed.
-
-**Current value (from the default):** `true`
-
-From [//build/config/BUILD.gn:16](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILD.gn#16)
-
-### extra_authorized_keys_file
-Additional SSH authorized_keys file to include in the build.
-For example:
- extra_authorized_keys_file=\"$HOME/.ssh/id_rsa.pub\"
-
-**Current value (from the default):** `""`
-
-From [//third_party/openssh-portable/fuchsia/developer-keys/BUILD.gn:11](https://fuchsia.googlesource.com/third_party/openssh-portable/+/06e7ff1f5cc2f48f85255ea20127746cd6fce423/fuchsia/developer-keys/BUILD.gn#11)
-
-### rustc_prefix
-Sets a custom base directory for `rustc` and `cargo`.
-This can be used to test custom Rust toolchains.
-
-**Current value (from the default):** `"//buildtools/linux-x64/rust/bin"`
-
-From [//build/rust/config.gni:17](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/rust/config.gni#17)
-
-### scenic_enable_vulkan_validation
-Include the vulkan validation layers in scenic even in release builds
-TODO(SCN-1003): Set the default to false once we know why disabling
-validation layers causes a display swapchain setup issue.
-
-**Current value (from the default):** `true`
-
-From [//garnet/bin/ui/BUILD.gn:12](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/bin/ui/BUILD.gn#12)
-
-### update_kernels
-List of kernel images to include in the update (OTA) package.
-If no list is provided, all built kernels are included. The names in the
-list are strings that must match the filename to be included in the update
-package.
-
-**Current value (from the default):** `[]`
-
-From [//build/images/BUILD.gn:364](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#364)
-
-### use_ccache
-Set to true to enable compiling with ccache
-
-**Current value (from the default):** `false`
-
-From [//build/toolchain/ccache.gni:9](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/toolchain/ccache.gni#9)
-
-### enable_crashpad
-When this is set, Crashpad will be used to handle exceptions (which uploads
-crashes to the crash server), rather than crashanalyzer in Zircon (which
-prints the crash log to the the system log).
-
-**Current value (from the default):** `false`
-
-From [//build/images/crashpad.gni:9](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/crashpad.gni#9)
-
-### kernel_cmdline_files
-Files containing additional kernel command line arguments to bake into
-the boot image. The contents of these files (in order) come after any
-arguments directly in [`kernel_cmdline_args`](#kernel_cmdline_args).
-These can be GN `//` source pathnames or absolute system pathnames.
-
-**Current value (from the default):** `[]`
-
-From [//build/images/BUILD.gn:352](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#352)
-
-### known_variants
-List of variants that will form the basis for variant toolchains.
-To make use of a variant, set [`select_variant`](#select_variant).
-
-Normally this is not set as a build argument, but it serves to
-document the available set of variants.
-See also [`universal_variants`](#universal_variants).
-Only set this to remove all the default variants here.
-To add more, set [`extra_variants`](#extra_variants) instead.
-
-Each element of the list is one variant, which is a scope defining:
-
- `configs` (optional)
- [list of labels] Each label names a config that will be
- automatically used by every target built in this variant.
- For each config `${label}`, there must also be a target
- `${label}_deps`, which each target built in this variant will
- automatically depend on. The `variant()` template is the
- recommended way to define a config and its `_deps` target at
- the same time.
-
- `remove_common_configs` (optional)
- `remove_shared_configs` (optional)
- [list of labels] This list will be removed (with `-=`) from
- the `default_common_binary_configs` list (or the
- `default_shared_library_configs` list, respectively) after
- all other defaults (and this variant's configs) have been
- added.
-
- `deps` (optional)
- [list of labels] Added to the deps of every target linked in
- this variant (as well as the automatic `${label}_deps` for
- each label in configs).
-
- `name` (required if configs is omitted)
- [string] Name of the variant as used in
- [`select_variant`](#select_variant) elements' `variant` fields.
- It's a good idea to make it something concise and meaningful when
- seen as e.g. part of a directory name under `$root_build_dir`.
- If name is omitted, configs must be nonempty and the simple names
- (not the full label, just the part after all `/`s and `:`s) of these
- configs will be used in toolchain names (each prefixed by a "-"),
- so the list of config names forming each variant must be unique
- among the lists in `known_variants + extra_variants`.
-
- `toolchain_args` (optional)
- [scope] Each variable defined in this scope overrides a
- build argument in the toolchain context of this variant.
-
- `host_only` (optional)
- `target_only` (optional)
- [scope] This scope can contain any of the fields above.
- These values are used only for host or target, respectively.
- Any fields included here should not also be in the outer scope.
-
-
-**Current value (from the default):**
-```
-[{
- configs = ["//build/config/lto"]
-}, {
- configs = ["//build/config/lto:thinlto"]
-}, {
- configs = ["//build/config/profile"]
-}, {
- configs = ["//build/config/scudo"]
-}, {
- configs = ["//build/config/sanitizers:ubsan"]
-}, {
- configs = ["//build/config/sanitizers:ubsan", "//build/config/sanitizers:sancov"]
-}, {
- configs = ["//build/config/sanitizers:asan"]
- host_only = {
- remove_shared_configs = ["//build/config:symbol_no_undefined"]
-}
- toolchain_args = {
- use_scudo = false
-}
-}, {
- configs = ["//build/config/sanitizers:asan", "//build/config/sanitizers:sancov"]
- host_only = {
- remove_shared_configs = ["//build/config:symbol_no_undefined"]
-}
- toolchain_args = {
- use_scudo = false
-}
-}, {
- configs = ["//build/config/sanitizers:asan"]
- host_only = {
- remove_shared_configs = ["//build/config:symbol_no_undefined"]
-}
- name = "asan_no_detect_leaks"
- toolchain_args = {
- asan_default_options = "detect_leaks=0"
- use_scudo = false
-}
-}, {
- configs = ["//build/config/sanitizers:asan", "//build/config/sanitizers:fuzzer"]
- host_only = {
- remove_shared_configs = ["//build/config:symbol_no_undefined"]
-}
- remove_shared_configs = ["//build/config:symbol_no_undefined"]
- toolchain_args = {
- use_scudo = false
-}
-}, {
- configs = ["//build/config/sanitizers:ubsan", "//build/config/sanitizers:fuzzer"]
- remove_shared_configs = ["//build/config:symbol_no_undefined"]
-}]
-```
-
-From [//build/config/BUILDCONFIG.gn:334](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILDCONFIG.gn#334)
-
-### scenic_vulkan_swapchain
-
-**Current value (from the default):** `1`
-
-From [//garnet/lib/ui/gfx/BUILD.gn:12](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/ui/gfx/BUILD.gn#12)
-
-### target_cpu
-
-**Current value for `target_cpu = "arm64"`:** `"arm64"`
-
-From //root_build_dir/args.gn:1
-
-**Overridden from the default:** `""`
-
-**Current value for `target_cpu = "x64"`:** `"x64"`
-
-From //root_build_dir/args.gn:1
-
-**Overridden from the default:** `""`
-
-### use_prebuilt_ffmpeg
-Use a prebuilt ffmpeg binary rather than building it locally. See
-[//garnet/bin/mediaplayer/ffmpeg/README.md](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/bin/mediaplayer/ffmpeg/README.md) for details. This is
-ignored when building media_player in variant builds (e.g. sanitizers);
-in that case, ffmpeg is always built from source so as to be built with
-the selected variant's config. When this is false (either explicitly
-or because media_player is a variant build) then //third_party/ffmpeg
-must be in the source tree, which requires:
-`jiri import -name garnet manifest/ffmpeg https://fuchsia.googlesource.com/garnet`
-
-**Current value (from the default):** `true`
-
-From [//garnet/bin/mediaplayer/ffmpeg/BUILD.gn:14](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/bin/mediaplayer/ffmpeg/BUILD.gn#14)
-
-### zircon_asserts
-
-**Current value (from the default):** `true`
-
-From [//build/config/fuchsia/BUILD.gn:138](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/fuchsia/BUILD.gn#138)
-
-### zircon_boot_manifests
-Manifest files describing files to go into the `/boot` filesystem.
-Can be either // source paths or absolute system paths.
-`zircon_boot_groups` controls which files are actually selected.
-
-Since Zircon manifest files are relative to a Zircon source directory
-rather than to the directory containing the manifest, these are assumed
-to reside in a build directory that's a direct subdirectory of the
-Zircon source directory and thus their contents can be taken as
-relative to `get_path_info(entry, "dir") + "/.."`.
-
-**Current value (from the default):** `["//out/build-zircon/build-arm64/bootfs.manifest"]`
-
-From [//build/images/manifest.gni:44](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/manifest.gni#44)
-
-### rust_lto
-Sets the default LTO type for rustc bulids.
-
-**Current value (from the default):** `"unset"`
-
-From [//build/rust/config.gni:20](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/rust/config.gni#20)
-
-### select_variant_canonical
-*This should never be set as a build argument.*
-It exists only to be set in `toolchain_args`.
-See [//build/toolchain/clang_toolchain.gni](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/toolchain/clang_toolchain.gni) for details.
-
-**Current value (from the default):** `[]`
-
-From [//build/config/BUILDCONFIG.gn:618](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILDCONFIG.gn#618)
-
-### symbol_level
-How many symbols to include in the build. This affects the performance of
-the build since the symbols are large and dealing with them is slow.
- 2 means regular build with symbols.
- 1 means minimal symbols, usually enough for backtraces only. Symbols with
-internal linkage (static functions or those in anonymous namespaces) may not
-appear when using this level.
- 0 means no symbols.
-
-**Current value (from the default):** `2`
-
-From [//build/config/compiler.gni:13](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/compiler.gni#13)
-
-### zircon_boot_groups
-Groups to include from the Zircon /boot manifest into /boot.
-This is either "all" or a comma-separated list of one or more of:
- core -- necessary to boot
- misc -- utilities in /bin
- test -- test binaries in /bin and /test
-
-**Current value (from the default):** `"core"`
-
-From [//build/images/BUILD.gn:25](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#25)
-
-### bootfs_extra
-List of extra manifest entries for files to add to the BOOTFS.
-Each entry can be a "TARGET=SOURCE" string, or it can be a scope
-with `sources` and `outputs` in the style of a copy() target:
-`outputs[0]` is used as `TARGET` (see `gn help source_expansion`).
-
-**Current value (from the default):** `[]`
-
-From [//build/images/BUILD.gn:358](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#358)
-
-### crashpad_dependencies
-
-**Current value (from the default):** `"fuchsia"`
-
-From [//third_party/crashpad/build/crashpad_buildconfig.gni:22](https://chromium.googlesource.com/crashpad/crashpad/+/411f0ae41d96518dfa9b75f58424d5d26eb7c75c/build/crashpad_buildconfig.gni#22)
-
-### enable_value_subsystem
-
-**Current value (from the default):** `false`
-
-From [//garnet/bin/ui/scenic/BUILD.gn:11](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/bin/ui/scenic/BUILD.gn#11)
-
-### host_cpu
-
-**Current value (from the default):** `"x64"`
-
-### select_variant_shortcuts
-List of short names for commonly-used variant selectors. Normally this
-is not set as a build argument, but it serves to document the available
-set of short-cut names for variant selectors. Each element of this list
-is a scope where `.name` is the short name and `.select_variant` is a
-a list that can be spliced into [`select_variant`](#select_variant).
-
-**Current value (from the default):**
-```
-[{
- name = "host_asan"
- select_variant = [{
- dir = ["//third_party/yasm", "//third_party/vboot_reference", "//garnet/tools/vboot_reference"]
- host = true
- variant = "asan_no_detect_leaks"
-}, {
- host = true
- variant = "asan"
-}]
-}, {
- name = "asan"
- select_variant = [{
- target_type = ["driver_module"]
- variant = false
-}, {
- host = false
- variant = "asan"
-}]
-}]
-```
-
-From [//build/config/BUILDCONFIG.gn:439](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/BUILDCONFIG.gn#439)
-
-### thinlto_cache_dir
-ThinLTO cache directory path.
-
-**Current value (from the default):** `"thinlto-cache"`
-
-From [//build/config/lto/config.gni:16](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/lto/config.gni#16)
-
-### use_vulkan_loader_for_tests
-Mesa doesn't properly handle loader-less operation;
-their GetInstanceProcAddr implementation returns 0 for some interfaces.
-On ARM there may be multiple libvulkan_arms, so they can't all be linked
-to.
-
-**Current value (from the default):** `true`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:33](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#33)
-
-### amlogic_decoder_tests
-
-**Current value (from the default):** `false`
-
-From [//garnet/drivers/video/amlogic-decoder/BUILD.gn:10](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/drivers/video/amlogic-decoder/BUILD.gn#10)
-
-### enable_gfx_subsystem
-
-**Current value (from the default):** `true`
-
-From [//garnet/bin/ui/scenic/BUILD.gn:12](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/bin/ui/scenic/BUILD.gn#12)
-
-### expat_build_root
-
-**Current value (from the default):** `"//third_party/expat"`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:7](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#7)
-
-### rust_toolchain_triple_suffix
-Sets the fuchsia toolchain target triple suffix (after arch)
-
-**Current value (from the default):** `"fuchsia"`
-
-From [//build/rust/config.gni:23](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/rust/config.gni#23)
-
-### target_os
-
-**Current value (from the default):** `""`
-
-### zircon_use_asan
-Set this if [`zircon_build_dir`](#zircon_build_dir) was built with
-`USE_ASAN=true`, e.g. `[//scripts/build-zircon.sh](https://fuchsia.googlesource.com/scripts/+/29d2c8a30ee569575151a6fd55617d05b25612c1/build-zircon.sh) -A`. This mainly
-affects the defaults for [`zircon_build_dir`](#zircon_build_dir) and
-[`zircon_build_abi_dir`](#zircon_build_abi_dir). It also gets noticed
-by [//scripts/fx](https://fuchsia.googlesource.com/scripts/+/29d2c8a30ee569575151a6fd55617d05b25612c1/fx) commands that rebuild Zircon so that they use `-A`
-again next time.
-
-**Current value (from the default):** `false`
-
-From [//build/config/fuchsia/zircon.gni:40](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/fuchsia/zircon.gni#40)
-
-### build_sdk_archives
-Whether to build SDK tarballs.
-
-**Current value (from the default):** `false`
-
-From [//build/sdk/sdk.gni:11](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/sdk/sdk.gni#11)
-
-### glm_build_root
-
-**Current value (from the default):** `"//third_party/glm"`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:9](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#9)
-
-### magma_python_path
-
-**Current value (from the default):** `"/b/s/w/ir/kitchen-workdir/third_party/mako"`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:12](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#12)
-
-### system_package_key
-The package key to use for signing Fuchsia packages made by the
-`package()` template (and the `system_image` packge). If this
-doesn't exist yet when it's needed, it will be generated. New
-keys can be generated with the `pm -k FILE genkey` host command.
-
-**Current value (from the default):** `"//build/development.key"`
-
-From [//build/package.gni:16](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/package.gni#16)
-
-### prebuilt_libvulkan_arm_path
-
-**Current value (from the default):** `""`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:25](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#25)
-
-### use_thinlto
-Use ThinLTO variant of LTO if use_lto = true.
-
-**Current value (from the default):** `true`
-
-From [//build/config/lto/config.gni:10](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/lto/config.gni#10)
-
-### zircon_build_abi_dir
-Zircon build directory for `target_cpu`, containing link-time `.so.abi`
-files that GN `deps` on [//zircon/public](https://fuchsia.googlesource.com/zircon/+/9f5f424a60876c51d94d82f44c5a8820ecd3db51/public) libraries will link against.
-This should not be a sanitizer build.
-
-**Current value (from the default):** `"//out/build-zircon/build-arm64"`
-
-From [//build/config/fuchsia/zircon.gni:14](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/fuchsia/zircon.gni#14)
-
-### zircon_build_dir
-Zircon build directory for `target_cpu`, containing `.manifest` and
-`.zbi` files for Zircon's BOOTFS and kernel. This provides the kernel
-and Zircon components used in the boot image. It also provides the
-Zircon shared libraries used at runtime in Fuchsia packages.
-
-If left `""` (the default), then this is computed from
-[`zircon_build_abi_dir`](#zircon_build_abi_dir) and
-[`zircon_use_asan`](#zircon_use_asan).
-
-**Current value (from the default):** `""`
-
-From [//build/config/fuchsia/zircon.gni:24](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/fuchsia/zircon.gni#24)
-
-### crashpad_use_boringssl_for_http_transport_socket
-
-**Current value (from the default):** `true`
-
-From [//third_party/crashpad/util/net/tls.gni:18](https://chromium.googlesource.com/crashpad/crashpad/+/411f0ae41d96518dfa9b75f58424d5d26eb7c75c/util/net/tls.gni#18)
-
-### enable_input_subsystem
-
-**Current value (from the default):** `true`
-
-From [//garnet/bin/ui/scenic/BUILD.gn:14](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/bin/ui/scenic/BUILD.gn#14)
-
-### fuchsia_packages
-List of packages (a GN list of strings).
-This list of packages is added to the set of "available" packages, see
-`products` for more information.
-
-**Current value for `target_cpu = "arm64"`:** `["peridot/packages/buildbot"]`
-
-From //root_build_dir/args.gn:2
-
-**Overridden from the default:** `[]`
-
-From [//build/gn/packages.gni:30](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/gn/packages.gni#30)
-
-**Current value for `target_cpu = "x64"`:** `["peridot/packages/buildbot"]`
-
-From //root_build_dir/args.gn:2
-
-**Overridden from the default:** `[]`
-
-From [//build/gn/packages.gni:30](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/gn/packages.gni#30)
-
-### msd_intel_gen_build_root
-
-**Current value (from the default):** `"//garnet/drivers/gpu/msd-intel-gen"`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:8](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#8)
-
-### kernel_cmdline_args
-List of kernel command line arguments to bake into the boot image.
-See also [//zircon/docs/kernel_cmdline.md](https://fuchsia.googlesource.com/zircon/+/9f5f424a60876c51d94d82f44c5a8820ecd3db51/docs/kernel_cmdline.md) and
-[`devmgr_config`](#devmgr_config).
-
-**Current value (from the default):** `[]`
-
-From [//build/images/BUILD.gn:346](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#346)
-
-### magma_enable_tracing
-Enable this to include fuchsia tracing capability
-
-**Current value (from the default):** `true`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:15](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#15)
-
-### thinlto_jobs
-Number of parallel ThinLTO jobs.
-
-**Current value (from the default):** `8`
-
-From [//build/config/lto/config.gni:13](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/lto/config.gni#13)
-
-### vk_loader_debug
-
-**Current value (from the default):** `"warn,error"`
-
-From [//third_party/vulkan_loader_and_validation_layers/loader/BUILD.gn:26](https://fuchsia.googlesource.com/third_party/vulkan_loader_and_validation_layers/+/3106666ca09bdab1a0f3c4c5d4d614bf4dab1f3d/loader/BUILD.gn#26)
-
-### data_image_size
-The size of the minfs data partition image to create. Normally this image
-is added to FVM, and can therefore expand as needed. It must be at least
-10mb (the default) in order to be succesfully initialized.
-
-**Current value (from the default):** `"10m"`
-
-From [//build/images/BUILD.gn:593](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#593)
-
-### fuchsia_products
-List of product definition files describing the packages to build, and
-where they are to be installed in images and updates.
-
-A product definition file is a JSON file containing:
-monolith:
- a list of packages included in OTA images, base system images, and the
- distribution repository.
-preinstall:
- a list of packages pre-installed on the system (also added to the
- distribution repository)
-available:
- a list of packages only added to the distribution repository)
-
-If a package is referenced in monolith and in preinstall, monolith takes
-priority, and the package will be added to OTA images as part of the
-verified boot set of static packages.
-
-If unset, layer will be guessed using //.jiri_manifest and
-//{layer}/products/default will be used.
-
-**Current value (from the default):** `[]`
-
-From [//build/gn/packages.gni:25](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/gn/packages.gni#25)
-
-### fvm_slice_size
-The size of the FVM partition images "slice size". The FVM slice size is a
-minimum size of a particular chunk of a partition that is stored within
-FVM. A very small slice size may lead to decreased throughput. A very large
-slice size may lead to wasted space. The selected default size of 8mb is
-selected for conservation of space, rather than performance.
-
-**Current value (from the default):** `"8388608"`
-
-From [//build/images/BUILD.gn:606](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#606)
-
-### host_tools_dir
-This is the directory where host tools intended for manual use by
-developers get installed. It's something a developer might put
-into their shell's $PATH. Host tools that are just needed as part
-of the build do not get copied here. This directory is only for
-things that are generally useful for testing or debugging or
-whatnot outside of the GN build itself. These are only installed
-by an explicit install_host_tools() rule (see [//build/host.gni](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/host.gni)).
-
-**Current value (from the default):** `"//root_build_dir/tools"`
-
-From [//build/host.gni:13](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/host.gni#13)
-
-### zedboot_devmgr_config
-List of arguments to populate /boot/config/devmgr in the Zedboot image.
-
-**Current value (from the default):** `["netsvc.netboot=true"]`
-
-From [//build/images/zedboot/BUILD.gn:24](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/zedboot/BUILD.gn#24)
-
-### amber_repository_blobs_dir
-
-**Current value (from the default):** `"//root_build_dir/amber-files/repository/blobs"`
-
-From [//garnet/go/src/pm/pm.gni:16](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/go/src/pm/pm.gni#16)
-
-### build_msd_arm_mali
-
-**Current value (from the default):** `true`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:21](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#21)
-
-### clang_prefix
-
-**Current value (from the default):** `"../buildtools/linux-x64/clang/bin"`
-
-From [//build/config/clang/clang.gni:9](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/clang/clang.gni#9)
-
-### extra_manifest_args
-Extra args to globally apply to the manifest generation script.
-
-**Current value (from the default):** `[]`
-
-From [//build/images/manifest.gni:47](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/manifest.gni#47)
-
-### zedboot_cmdline_args
-List of kernel command line arguments to bake into the Zedboot image.
-See [//zircon/docs/kernel_cmdline.md](https://fuchsia.googlesource.com/zircon/+/9f5f424a60876c51d94d82f44c5a8820ecd3db51/docs/kernel_cmdline.md) and
-[`zedboot_devmgr_config`](#zedboot_devmgr_config).
-
-**Current value (from the default):** `[]`
-
-From [//build/images/zedboot/BUILD.gn:15](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/zedboot/BUILD.gn#15)
-
-### cloudkms_key_dir
-
-**Current value (from the default):** `"projects/fuchsia-infra/locations/global/keyRings/test-secrets/cryptoKeys"`
-
-From [//build/testing/secret_spec.gni:8](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/testing/secret_spec.gni#8)
-
-### custom_signing_script
-If non-empty, the given script will be invoked to produce a signed ZBI
-image. The given script must accept -z for the input zbi path, and -o for
-the output signed zbi path. The path must be in GN-label syntax (i.e.
-starts with //).
-
-**Current value (from the default):** `""`
-
-From [//build/images/custom_signing.gni:10](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/custom_signing.gni#10)
-
-### devmgr_config
-List of arguments to add to /boot/config/devmgr.
-These come after synthesized arguments to configure blobfs and pkgfs,
-and the one generated for [`enable_crashpad`](#enable_crashpad).
-
-**Current value (from the default):** `[]`
-
-From [//build/images/BUILD.gn:341](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#341)
-
-### magma_build_root
-
-**Current value (from the default):** `"//garnet/lib/magma"`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:6](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#6)
-
-### use_scudo
-Enable the [Scudo](https://llvm.org/docs/ScudoHardenedAllocator.html)
-memory allocator.
-
-**Current value (from the default):** `true`
-
-From [//build/config/scudo/scudo.gni:8](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/scudo/scudo.gni#8)
-
-### zircon_aux_manifests
-
-**Current value (from the default):** `["//out/build-zircon/build-arm64-asan/bootfs.manifest"]`
-
-From [//build/images/manifest.gni:32](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/manifest.gni#32)
-
-### zircon_build_root
-
-**Current value (from the default):** `"//zircon"`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:10](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#10)
-
-### amber_repository_dir
-Directory containing files named by their merkleroot content IDs in
-ASCII hex. The [//build/image](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/image):pm_publish_blobs target populates
-this with copies of build products, but never removes old files.
-
-**Current value (from the default):** `"//root_build_dir/amber-files"`
-
-From [//garnet/go/src/pm/pm.gni:11](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/go/src/pm/pm.gni#11)
-
-### build_intel_gen
-
-**Current value (from the default):** `false`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:23](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#23)
-
-### current_os
-
-**Current value (from the default):** `""`
-
-### fvm_image_size
-The size in bytes of the FVM partition image to create. Normally this is
-computed to be just large enough to fit the blob and data images. The
-default value is "", which means to size based on inputs. Specifying a size
-that is too small will result in build failure.
-
-**Current value (from the default):** `""`
-
-From [//build/images/BUILD.gn:599](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/images/BUILD.gn#599)
-
-## `target_cpu = "arm64"`
-
-### arm_tune
-The ARM variant-specific tuning mode. This will be a string like "armv6"
-or "cortex-a15". An empty string means to use the default for the
-arm_version.
-
-**Current value (from the default):** `""`
-
-From [//build/config/arm.gni:25](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/arm.gni#25)
-
-### arm_use_neon
-Whether to use the neon FPU instruction set or not.
-
-**Current value (from the default):** `true`
-
-From [//build/config/arm.gni:28](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/arm.gni#28)
-
-### arm_version
-
-**Current value (from the default):** `8`
-
-From [//build/config/arm.gni:12](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/arm.gni#12)
-
-### msd_arm_enable_all_cores
-Enable all 8 cores, which is faster but emits more heat.
-
-**Current value (from the default):** `true`
-
-From [//garnet/drivers/gpu/msd-arm-mali/src/BUILD.gn:9](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/drivers/gpu/msd-arm-mali/src/BUILD.gn#9)
-
-### msd_arm_enable_cache_coherency
-With this flag set the system tries to use cache coherent memory if the
-GPU supports it.
-
-**Current value (from the default):** `true`
-
-From [//garnet/drivers/gpu/msd-arm-mali/src/BUILD.gn:13](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/drivers/gpu/msd-arm-mali/src/BUILD.gn#13)
-
-### arm_float_abi
-The ARM floating point mode. This is either the string "hard", "soft", or
-"softfp". An empty string means to use the default one for the
-arm_version.
-
-**Current value (from the default):** `""`
-
-From [//build/config/arm.gni:20](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/arm.gni#20)
-
-### arm_optionally_use_neon
-Whether to enable optional NEON code paths.
-
-**Current value (from the default):** `false`
-
-From [//build/config/arm.gni:31](https://fuchsia.googlesource.com/build/+/fb9b46cbb98da8b92fdfd2dc1a8beba0836807e8/config/arm.gni#31)
-
-## `target_cpu = "x64"`
-
-### use_mock_magma
-
-**Current value (from the default):** `false`
-
-From [//third_party/mesa/src/intel/vulkan/BUILD.gn:25](https://fuchsia.googlesource.com/third_party/mesa/+/2f2abaa7aa5ab971d80c831f077df11747790d1f/src/intel/vulkan/BUILD.gn#25)
-
-### mesa_build_root
-
-**Current value (from the default):** `"//third_party/mesa"`
-
-From [//garnet/lib/magma/gnbuild/magma.gni:41](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/lib/magma/gnbuild/magma.gni#41)
-
-### msd_intel_enable_mapping_cache
-
-**Current value (from the default):** `false`
-
-From [//garnet/drivers/gpu/msd-intel-gen/src/BUILD.gn:8](https://fuchsia.googlesource.com/garnet/+/6dd381288512e11bfda06566bf15d5a6cc69a390/drivers/gpu/msd-intel-gen/src/BUILD.gn#8)
-
diff --git a/docs/images/fuchsia-logo-32x32.png b/docs/images/fuchsia-logo-32x32.png
deleted file mode 100644
index 72f753f..0000000
--- a/docs/images/fuchsia-logo-32x32.png
+++ /dev/null
Binary files differ
diff --git a/docs/ledger/README.md b/docs/ledger/README.md
deleted file mode 100644
index 0448ff7..0000000
--- a/docs/ledger/README.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# Ledger
-
-[TOC]
-
-## What is Ledger?
-
-Ledger is a distributed storage system for Fuchsia.
-
-Each application (or more precisely, each [component]) running on behalf of a
-particular user has a separate data store provided and managed by Ledger, and
-vended to a client application by Fuchsia framework through its [component
-context].
-
-The data store for the particular component/user combination is private - not
-accessible to other apps of the same user, and not accessible to other users of
-the same app.
-
-Each data store is transparently **synchronized** across devices of its user
-through a [cloud provider]. Any data operations are made **offline-first** with
-no coordination with the cloud. If concurrent modifications result in a data
-conflict, the conflict is resolved using an app-configurable merge policy.
-
-Each data store is organized into collections exposing a **key-value store** API
-called *pages*. Page API supports storing data of arbitrary size, atomic changes
-across multiple keys, snapshots and modification observers.
-
-## Documentation
-
-Documentation for using Ledger:
-
- - [User Guide](user_guide.md)
-
-Documentation for integrating with Ledger in client apps:
-
- - [API Guide](api_guide.md)
- - [Data Organization](data_organization.md)
- - [Examples](examples.md)
-
-Documentation for setting up a remote Cloud sync provider:
-
- - [Firestore]
-
-Documentation for developing Ledger:
-
- - [Field Data](field_data.md)
- - [Style Guide](style_guide.md)
- - [Testing](testing.md)
-
-Design documentation:
-
- - [Architecture](architecture.md)
- - [Conflict Resolution](conflict_resolution.md)
- - [Data in Storage](data_in_storage.md)
- - [Life of a Put](life_of_a_put.md)
-
-
-[cloud provider]: /public/fidl/fuchsia.ledger.cloud/cloud_provider.fidl
-[component context]: /public/fidl/fuchsia.modular/component/component_context.fidl
-[Firestore]: /bin/cloud_provider_firestore/README.md
diff --git a/docs/ledger/api_guide.md b/docs/ledger/api_guide.md
deleted file mode 100644
index 376b5d5..0000000
--- a/docs/ledger/api_guide.md
+++ /dev/null
@@ -1,266 +0,0 @@
-# API Guide
-
-This document describes how to use Ledger for synchronized application storage
-in a client application. The goal of the document is to explain the key concepts
-and the most common operations, not necessarily to cover the entire API surface.
-
-[TOC]
-
-## Connecting to Ledger
-
-The Ledger API is exposed through a [FIDL interface].
-
-Access to Ledger is vended from the `fuchsia::modular::ComponentContext` of the running
-application. Each application component has a separate private data store for
-each user on behalf of which it runs.
-
-|||---|||
-#### C++
-
-``` cpp
-module_context->GetComponentContext(
- component_context_.NewRequest());
-fuchsia::ledger::LedgerPtr ledger;
-ledger.set_error_handler([](zx_status_t status) {
- // Handle ledger and connection errors.
-});
-component_context_->GetLedger(ledger.NewRequest());
-```
-
-#### Dart
-
-``` dart
-moduleContext.getComponentContext(
- componentContext.ctrl.request());
-final LedgerProxy ledger = new LedgerProxy();
-ledger.ctrl.error.then((ProxyError error) {
- // Handle ledger and connection errors.
-});
-componentContext.getLedger(ledger.ctrl.request());
-```
-|||---|||
-
-*** aside
-Note that the Ledger connection is provided through a FIDL *interface request*,
-so it can be immediately used to make requests.
-***
-
-## Working with pages
-
-Data stored in Ledger is grouped into separate independent key-value stores
-called *pages*.
-
-Pages are identified by ids of 16 bytes each. When creating a page, the
-application can pick its id (for example, to create/access a page with a name
-that is fixed and known in advance), or can request a new unique id to be
-generated by Ledger (for example, to create pages that correspond 1-1 to
-business logic objects). Ledger also offers a convenience method `GetRootPage()`
-which retrieves the page with id `[0, 0 ... , 0]`.
-
-|||---|||
-#### C++
-
-``` cpp
-fuchsia::ledger::PagePtr page;
-ledger->GetRootPage(page.NewRequest(),
- [] (fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- // Handle errors.
- }
-});
-page.set_error_handler([] (zx_status_t status) {
- // Handle connection errors.
-});
-```
-
-#### Dart
-
-``` dart
-final PageProxy page = new PageProxy();
-_ledger.getRootPage(
- page.ctrl.request(), (Status status) {
- if (status != Status.ok) {
- // Handle errors.
- }
-});
-page.ctrl.error.then((ProxyError error) {
- // Handle connection errors.
-}
-```
-|||---|||
-
-## Page API
-
-Each page exposes a key-value store API.
-
-The state of each page changes in commits which form a DAG. This DAG is not
-directly exposed to the developer through the Ledger API, but we mention it as
-it helps to understand how the page operations described below behave.
-
-*** promo
-History of a page can and does diverge when the page is modified concurrently on
-multiple devices (or even locally on separate connections to the same page).
-However, it's important to note that any given local page connection (/page
-proxy) always tracks **one path** through the commit history and only advances
-forward.
-***
-
-### Writing
-
-Values can be written/modified using mutation methods of the Page interface.
-
-There are two ways to write a value into a page:
-
- - directly, passing the value in a FIDL message (that's `Put()` and
- `PutWithPriority()` methods). This is handy, but note that the developer
- needs to ensure that the value does not exceed the maximum payload size of a
- FIDL message.
- - in two steps: first streaming the data to be written to a "reference", and
- then setting the value using the reference. (through a combination of
- `CreateReferenceFromSocket()`, `CreateReferenceFromBuffer()` and
- `PutReference()`. Note that the created reference is temporary and not
- persisted through app restarts - it must be set through `PutReference()`, or
- discarded.
-
-### Reading
-
-In order to ensure that reads across multiple entries (key-value pairs) are
-consistent, read operations are exposed through a snapshot API. Snapshot of the
-page can be obtained:
-
- - directly from the page interface (`GetSnapshot()`), yielding a snapshot
- corresponding to the state of the page tracked by this page connection
- - through the [watcher](#Watch) interface, which when delivering each
- notification allows to also request the snapshot corresponding to the state
- associated with the notification
-
-Once the snapshot is obtained, data can be read using the `GetEntries()` method
-which retrieves multiple entries, or the `Get()` method which retrieves the
-value associated with the particular key.
-
-#### Range queries
-
-The `GetEntries()` method takes a `key_start` argument, allowing the app to
-perform a *range query*. In order to retrieve all entries between two keys, we
-need to call `GetEntries()` with the first key passed as `key_start`, and
-continue reading the paginated response as long as the returned values are in
-the desired range.
-
-### Lazy values
-
-`PutWithPriority()` and `PutReference()` methods allow the app to write a value
-as a *lazy value*. Compared with the default *eager values*, lazy values are not
-guaranteed to be proactively fetched to the local device when the Page syncs to
-the state that contains them. The **keys** of the lazy values are always synced
-eagerly, but the value itself might be missing.
-
-To ensure predictable performance of read operations, `Get()` and `GetEntries`
-methods never retrieve the missing lazy values from the network - these must be
-explicitly requested through a dedicated `Fetch()` method.
-
-### Watch
-
-The client application can register a watcher to be notified of changes to the
-state tracked by the local page connection. As typically we are interested in
-retrieving the initial base state at the moment of registering the watcher,
-the watchers are registered using the `GetSnapshot()` method.
-
-[C++ watcher example], [Dart watcher example].
-
-`GetSnapshot()` takes an optional `key_prefix` parameter, which allows the
-client app to register specifically for change notifications within a particular
-prefix of keys.
-
-### Transactions
-
-Transactions allow the application to make a set of changes that are guaranteed
-to be synced and surfaced atomically. A client application would typically:
-
- - start a transaction
- - get a snapshot of the page state through `GetSnapshot()` or a watcher (see
- below), and read the data
- - make changes through the Page interface
- - commit the transaction
-
-Once a transaction is started, the state of the page tracked on the page
-connection is pinned and won't advance until the transaction is either committed
-or aborted - this ensures that the transaction writes affect precisely the state
-visible on the page snapshot.
-
-There can be only one transaction in progress per `Page` connection, but
-clients can create multiple connections to the same page. Each of these
-connections can run a transaction independently from the others.
-
-*** note
-*Watch and transactions*: As starting a transaction pins the state of the page
-visible on the particular page connection, the client app won't receive any
-watch notifications (for watchers registered on this page connection) while the
-transaction is in progress.
-
-Conversely, on a page connection with registered watchers, a
-`StartTransaction()` call will only return when the app finishes processing all
-pending change notification. This ensures the app knows the base state of the
-page when performing a transaction.
-***
-
-## Conflict resolution
-
-If the page history has diverged and has more than one head, conflict resolution
-will be invoked to merge the heads.
-
-*** aside
-Note that this condition is not associated with any particular local page
-connection - there could be multiple local page connections on different
-divergent heads. Conflict resolution is therefore configured through the Ledger
-connection.
-***
-
-By default, a key-by-key last-one-wins policy is used to merge divergent
-commits, based on best-effort, not-guaranteed-to-be-right, timestamps of each
-commit.
-
-The client might opt for a different merge policy by implementing the
-`ConflictResolverFactory` interface and setting it through a Ledger connection.
-
-Available conflict resolution policies:
-
- - last-one-wins (the default): `LAST_ONE_WINS`
-
- For each entry modified on both sides, `LAST_ONE_WINS` takes the entry from
- the most recent commit; for each entry modified only on one side (e.g.:
- when adding a new key, or when modifying an existing one), the modification
- is carried over. The most recent commit is determined using timestamps
- assigned to the commits by the devices that created them. Note, however that
- these timestamps are not guaranteed to be accurate.
- - custom, invoked only for conflicting (modified on both branches being
- merged) entries: `AUTOMATIC_WITH_FALLBACK`
-
- For all modified keys, if either they are modified only on one side, or
- changed in the same way (added/updated with the same value, or deleted) in
- both sides, `AUTOMATIC_WITH_FALLBACK` applies the change automatically. If,
- however any key is modified on both sides with a non identical change, the
- app gets a callback with all changed entries from both sides (not just the
- conflicting ones).
- - custom, invoked for all merges (even if the entries modified by each branch
- are non-conflicting): `CUSTOM`
-
- Conflicting changes are ignored and there are no merges performed.
-
-
-See also [Conflict Resolution](conflict_resolution.md).
-
-## Synchronization
-
-Synchronization is configured at the Ledger level as described in the [user
-guide](user_guide.md). Once configured, the Ledger will upload local changes,
-and download changes made by other devices. These operations will happen
-automatically in the background, and clients do not have to manage them.
-
-## See also
-
- - [Data Organization](data_organization.md)
- - [Examples of client apps](examples.md)
-
-[FIDL interface]: /public/fidl/fuchsia.ledger/ledger.fidl
-[C++ watcher example]: /examples/todo_cpp/todo.h
-[Dart watcher example]: https://fuchsia.googlesource.com/topaz/+/master/examples/ledger/todo_list/lib/src/models/todo_list_model.dart
diff --git a/docs/ledger/architecture.md b/docs/ledger/architecture.md
deleted file mode 100644
index 773ad24..0000000
--- a/docs/ledger/architecture.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# Architecture
-
-This document explains the internal architecture of Ledger.
-
-[TOC]
-
-## Overview
-
-The Ledger implementation is logically composed of the following components:
-
- - **Storage** that stores and provides access to the data locally,
- - client components that interact with storage:
- - **Local client** that exposes Ledger FIDL API to locally running apps,
- - **Cloud sync** that synchronizes the Ledger state across devices
-
-![architecture diagram](architecture.png)
-
-All of these components run together within the Ledger process.
-
-## Storage
-
-*** promo
-Ledger stores data in key-value stores called pages. A page changes in atomic
-commits, each commit adding, removing or modifying one or more entries in the
-key-value store.
-
-The commit history of each page forms a DAG in which each commit has either no
-parents (initial commit), 1 parent (regular commit) or 2 parents (merge commit).
-***
-
-The Storage component persists:
-
- - the commit history of each page
- - immutable storage objects holding the state of each page
- - sync metadata, including synchronization state of each object
-
-The contents of each commit are key-value pairs (entries), stored in a
-B-Tree-like structure with the following main properties:
-
- - entries are ordered by the keys, permitting efficient evaluation of range
- queries
- - tree nodes are immutable, allowing referencing the same node from two (or
- more) different commits and thus avoiding duplicating the state among
- different commits with similar content
- - the B-Tree is history-independent, i.e. given the same set of entries, the
- resulting structure of the tree will be the same, independently of the
- insertion order. This property permits to efficiently compute the diff
- between two given commits.
-
-Storage exposes a key-value API to Local client and creates new storage objects
-and commits in response to modifications the Local client makes. Similarly,
-Storage receives commits and storage objects synced from other devices from
-Cloud Sync.
-
-Code:
-
- - [/bin/ledger/storage], in particular:
- - [/bin/ledger/storage/public] contains the public (exposed to other components) API
- - [/bin/ledger/storage/impl] contains the implementation
- - [/bin/ledger/storage/impl/btree] contains the implementation of the B-tree
-
-## Local client
-
-Local Client exposes a FIDL API to apps running on the device. In response to
-modifications to the key-value store requested by apps connecting to Ledger, it
-makes corresponding calls to Storage.
-
-When notified about a conflict by Storage, Local client resolves it according to
-the policy selected by the client app, calling back to it if necessary - see
-[Conflict resolution](api_guide.md#Conflict-resolution) in the API Guide.
-
-Code:
-
- - [/bin/ledger/app], in particular:
- - [/bin/ledger/app/merging] implements conflict resolution
-
-## Cloud sync
-
-Cloud sync is notified by Storage about new locally-produced commits and is
-responsible for pushing them, along with the associated storage objects, to the
-cloud. Conversely, Cloud sync also tracks new commits being synced to the cloud
-by other devices, downloads them and registers them with Storage.
-
-Code:
-
- - [/bin/ledger/cloud_sync] implements high-level cloud sync logic, in particular:
- - [/bin/ledger/cloud_sync/public] contains the public (exposed to other components) API
- - [/bin/ledger/cloud_sync/impl] contains the implementation
- - [/bin/cloud_provider_firestore] implements integration with cloud services
-
-[/bin/ledger/storage]: /bin/ledger/storage/
-[/bin/ledger/storage/public]: /bin/ledger/storage/public/
-[/bin/ledger/storage/impl]: /bin/ledger/storage/impl/
-[/bin/ledger/storage/impl/btree]: /bin/ledger/storage/impl/btree/
-[/bin/ledger/app]: /bin/ledger/app/
-[/bin/ledger/app/merging]: /bin/ledger/app/merging/
-[/bin/ledger/cloud_sync]: /bin/ledger/cloud_sync/
-[/bin/ledger/cloud_sync/public]: /bin/ledger/cloud_sync/public/
-[/bin/ledger/cloud_sync/impl]: /bin/ledger/cloud_sync/impl/
-[/bin/cloud_provider_firestore]: /bin/ledger/cloud_provider_firestore/
diff --git a/docs/ledger/architecture.png b/docs/ledger/architecture.png
deleted file mode 100644
index 62bfc9c..0000000
--- a/docs/ledger/architecture.png
+++ /dev/null
Binary files differ
diff --git a/docs/ledger/conflict_resolution.md b/docs/ledger/conflict_resolution.md
deleted file mode 100644
index 2828d30..0000000
--- a/docs/ledger/conflict_resolution.md
+++ /dev/null
@@ -1,176 +0,0 @@
-# Conflict Resolution
-
-This document explains how Ledger handles conflicts.
-
-[TOC]
-
-## Conflicts
-
-Ledger is an offline-first database - devices can naturally diverge when making
-concurrent changes and thus, the change history forms a directed acyclic graph
-(DAG) of [commits](architecture.md#Storage). Whenever the local history DAG has
-more than one head commit, i.e. more than one leaf in the DAG, we call this
-state a **conflict**.
-
-*** aside
-A conflict can be created by **two devices** making a concurrent modification of
-the Ledger state, but also by a **single device** making two concurrent changes
-to the local state - this is usually not desirable, but certainly possible.
-***
-
-Whenever a conflict arises, Ledger by default merges the local heads
-automatically, using an entry-by-entry last-one-wins policy based on
-non-reliable timestamps of the two commits being merged. See the [Merge
-Strategies](#Merge-Strategies) section for more details.
-
-Client apps that want to override this behavior can opt for either one of the
-predefined merging policies or use a custom policy and handle the merges
-themselves, see [Conflict Resolution](api_guide.md#Conflict-resolution) in the
-API Guide.
-
-## Convergence
-
-As the same conflict can be resolved concurrently on two devices, the resulting
-state can once more be different between devices. This can potentially create a
-situation where two or more devices keep creating merge commits that are then
-synced and merged again. This situation is called a **merge storm**.
-
-Ledger employs a number of strategies in order to prevent merge storms:
-
- - a device uploads local changes **only** when the local state is resolved
- (there is a single local head). If the local state is divergent, the device
- first resolves the conflicts and only later uploads the result.
- - identical merge of two commits made concurrently on multiple devices results
- in the exact same commit (as long as the conflict resolver makes the same
- decisions, i.e. is deterministic). This is ensured because commits are
- content-addressed based on the B-tree content and the commit metadata; and
- commit metadata of a merge commit, including the commit timestamp, depends
- only on the parent commits - the timestamp is selected as the biggest of two
- parent timestamps.
- - when merging **two merge commits**, Ledger waits with exponential backoff,
- allowing one device to win the race and have a final say on the resolved state.
- The exponential backoff should occur only if the two devices create
- conflicting merge commits, e.g. if the conflict resolution is not
- deterministic (see below).
-
-## Merge Strategies
-
-For each [page](data_organization.md#Pages), client apps can define a *merge
-strategy*. These strategies determine the behavior of Ledger when a conflict is
-detected, and are appropriate for different situations.
-
-To avoid merge storms (as described above), we ensure that any automatic merge
-strategy is **deterministic**, so that two devices seeing the same conflict
-reach the same resolution.
-
-### Last-one-wins
-
-The *last-one-wins* merge strategy is the default one, i.e. the one applied if
-the client app didn't configure any other strategy. When using this strategy,
-the client app delegates all merging to Ledger and doesn't have to handle
-merges.
-
-The last-one-wins strategy operates by taking, for each conflicting key/value
-pair, the one present in the latest commit, ordered by creation timestamp.
-However, if a key/value pair is modified by one commit only (added, removed, or
-changed value), the modification is taken, regardless of the timestamp.
-
-This strategy is very convenient for applications that use Ledger to store
-independent key/value pairs, as it removes the burden of merging from the
-client application entirely. Storing independent key/value user preferences
-would be a good case for this strategy.
-
-*** aside
-The creation timestamps are generated on each device. Thus, unsynchronized
-clocks or clock drift between devices may result in older values taking
-precedence over new ones.
-
-We think this is fine because:
-* We want a fully automatic merge strategy for developers who don't have
-cross-key consistency needs and want to keep their app simple. Others should
-use the more advanced policies with custom mergers.
-* We could do an "arbitrary-one wins" merge policy and use the ordering of an
-internal ID other than a timestamp. As long as this ID (as the timestamp) is
-fixed for a given commit, then the merge is deterministic and we can have a
-valid merge. It seemed better to us to use a policy that makes sense to users
-in the usual case, rather than a random-looking policy.
-* This merge policy operates per key/value pair. This means that the timestamp
-is used only when a value has been changed on both sides: any merge strategy
-must discard at least one of the two values. We think this case is narrow
-enough that clock synchronization issues would be very limited.
-* This is only at the merge level. No other part of Ledger uses these
-timestamps. In particular, if a user ends up in a case of doing a merge with
-last-one-wins, drifted clocks, and conflicting keys, nothing in Ledger would
-break.
-
-***
-
-### Automatic with fallback
-
-The *automatic with fallback* merge strategy attempts to automatically merge
-commits when no key/value pair conflicts, and defer to a [custom conflict
-resolver](#Custom-conflict-resolvers) when at least one key/value pair
-conflicts.
-
-When using this strategy, client applications need to write a custom conflict
-resolver, but its usage is limited: if the client application modified
-disjointed (different) parts of a page on two devices, the modifications of
-each device will be applied automatically and the custom conflict resolver will
-not be called. However, if an entry was modified on both sides to contain
-different values, then the custom conflict resolver will be called.
-
-This strategy is convenient if a client application stores independent
-key/value pairs, but wants to control how the values are merged when modified on
-both places. For example, when storing a list as value, a client app may want
-to merge the list as to keep the modifications of both sides instead of picking
-only one. This strategy can also be used to prompt the user to choose the
-resolution they want.
-
-### Custom
-
-The *Custom* merge strategy defers to the client app each time there is a
-conflict. Remember, however, that Ledger does not consider a change from
-another device to be conflicting if there were no local changes during the same
-period, and will simply fast-forward the Ledger state.
-
-This strategy is useful when the client app is storing key/value pairs that
-have dependencies that need to be enforced by business-logic.
-
-### Custom conflict resolvers
-
-In order to facilitate convergence, any custom conflict resolution implemented
-by the client app should be **deterministic** - that is, the resulting merge
-commit should depend only on the two commits being merged. This ensures that the
-same conflict resolved concurrently on two devices yields the very same result.
-
-The pair of commits passed to the conflict resolver is ordered deterministically
-by Ledger, so the conflict resolver doesn’t need to be **commutative**.
-
-## Case studies
-
-This section discusses conflict resolution behavior in a number of scenarios.
-
-### Offline
-
-When a device that has been making modifications offline goes back online, the
-device downloads remote modifications first, then resolves any conflicts, and
-only after that uploads its own changes to the cloud. This way the other devices
-that are online and in sync with each other only need to fast-forward to catch
-up with remote changes. We sacrifice sync latency (it takes longer for changes
-from the offline device to be visible to others) for faster convergence and less
-bandwidth spend.
-
-![conflict_resolution_offline](conflict_resolution_offline.png)
-
-### Online
-
-When two online devices make a concurrent change (that is, both make their
-changes before seeing changes from the other device), the convergence is ensured
-as long as the conflict resolver is deterministic (see [Custom conflict
-resolvers](#Custom-conflict-resolvers)). When two devices concurrently resolve
-the same conflict, they produce the same resulting merge commit. This commit can
-be then uploaded to the cloud twice, once by each device, but any extra
-occurrences will be ignored by each participant and will not trigger further
-merges.
-
-![conflict_resolution_two_devices](conflict_resolution_two_devices.png)
diff --git a/docs/ledger/conflict_resolution_offline.png b/docs/ledger/conflict_resolution_offline.png
deleted file mode 100644
index b785e9c..0000000
--- a/docs/ledger/conflict_resolution_offline.png
+++ /dev/null
Binary files differ
diff --git a/docs/ledger/conflict_resolution_two_devices.png b/docs/ledger/conflict_resolution_two_devices.png
deleted file mode 100644
index 0d4eb47..0000000
--- a/docs/ledger/conflict_resolution_two_devices.png
+++ /dev/null
Binary files differ
diff --git a/docs/ledger/data_in_storage.md b/docs/ledger/data_in_storage.md
deleted file mode 100644
index c356228..0000000
--- a/docs/ledger/data_in_storage.md
+++ /dev/null
@@ -1,191 +0,0 @@
-# Data in Storage
-
-Storage implements persistent representation of data held in Ledger. Such data
-include:
-
-- commit, value and tree node objects
-- journal entries and metadata
-- information on head commits
-- information on which objects have been synced to the cloud
-- other synchronization metadata, such as the time of the last synchronization
- to the cloud
-
-All data and metadata added in storage are persisted using LevelDB. For each
-[page](data_organization.md#Pages) a separate LevelDB instance is created in a
-dedicated filesystem path of the form:
-`{repo_dir}/{serialization_version}/ledgers/{ledger_dir}/{page_id_base64}/leveldb`.
-
-Additionally, metadata about all pages of a single user are persisted in a
-separate LevelDB instance. This includes information such as the last time a
-page was used.
-
-The rest of the document describes the key and value representation for each row
-created in LevelDB to store each data type.
-
-[TOC]
-
-# Per Page data storage
-
-## Commit objects
-
-- Row key: `commits/{commit_id}`
-- Row value: Contains the creation `timestamp`, `generation` (i.e. length of the
- longest path to the first commit created for this page), `root_node_id` and
- `parent_ids`, as serialized by Flatbuffers (see [commit.fbs]).
-
-## Value and tree node objects
-
-In storage there is no difference in the representation of value and node
-objects. Since these two types of objects can be quite big, they might be split
-in multiple pieces. Each **piece** is serialized in LevelDB as follows:
-
-- Row key: `objects/{object_digest}`
-- Row value: `{object_content}`
-
-For value objects, `{object_content}` is the actual user defined content, while
-for tree nodes, it is the list of node entries (key, object_id and priority),
-references to child nodes, and the node level. Tree node content is serialized
-using Flatbuffers (see [tree_node.fbs]).
-
-Note that when a Ledger user inserts a key-value pair, the key is stored in a
-tree node, while the value is stored separately, as described above.
-
-### Splitting objects in pieces
-
-Value or tree node objects might be split into smaller pieces that are stored
-separately. When processing a large object, its content is fed into a rolling
-hash which determines how the object should be split into chunks. For each such
-chunk, whose size is always between 4KiB and 64KiB, an identifier is computed
-and added in a list. Based on the rolling hash algorithm this list is split into
-index files, containing references (identifiers) towards either chunks of the
-original object's content, or other index files. At the end of the algorithm,
-the data chunks and index files form a tree, where the content of the object is
-stored on the leaves.
-
-See also [split.h] and [split.cc] for more details.
-
-## Journals
-
-Changes in Page (Put entry, Delete entry, Clear page) that have not yet been
-committed are organized in [journals]. A journal can be explicit, when it is
-part of an explicitly created transaction or part of a merge commit, or
-implicit, for any other case. On a system crash all explicit journals are
-considered invalid and once the system restarts they are removed from the
-storage. Implicit ones on the other hand, are immediately committed on system
-restart.
-
-A common prefix for all explicit journal entries (`journals/E`) helps remove
-them all together when necessary, and an additional metadata row, for implicit
-journals only, helps retrieve the ids of the not-yet-committed journals.
-
-Journal entry keys (for both implicit and explicit journals) are serialized in
-LevelDB as:
-
-Row key: `journals/{journal_id}/entry/{user_defined_key}`
-
-`{journal_id}` has an `E` prefix if the journal is explicit or an `I` prefix if
-it's implicit.
-
-- If the journal entry is about adding a new or updating an existing Ledger
-key-value pair, then:
-
- Row value: `A{priority_byte}{object_identifier}`
-
- Where `{priority_byte}` is either `E` if the priority is Eager, or `L` if it's
- Lazy.
-
-- If the journal entry is about removing and existing key-value pair, the value
- is:
-
- Row value: `D`
-
-Moreover, if a journal contains a page clear operation, a row with an empty
-value is added to the journal. If it is present, when the journal is commited,
-the previous state of the page must be discarded.
-
-- Row key: `journals/{journal_id}/C`
-- Row value: (empty value)
-
-### Metadata row for implicit journals
-
-For every implicit journal an additional row is kept in LevelDB:
-- Row key: `journals/implicit_metadata/{journal-id}`
-- Row value: `{base_commit_id}`
-
-`{base_commit_id}` is the parent commit of this journal. Note that implicit
-journals always have a single parent (merge commits cannot be implicit
-journals).
-
-## Head commits
-
-The list of head commits is updated and maintained in storage. For each head a
-separate row is created:
-- Row key: `heads/{commit_id}`
-- Row value: `{creation_timestamp}`
-
-## Synchronization status
-
-### Commits
-A row is added for each commit that has been created locally, but is not yet
-synced to the cloud:
-- Row key: `unsynced/commits/{commit_id}`
-- Row value: `{generation}`
-
-### Value and Tree Node Objects
-Each piece, i.e. part of a value or tree node object, can be in any of the
-following states:
-
-- transient: the object piece has been used in a journal that is not yet committed
-- local: the object piece has been used in a commit, but is still not synced
-- synced: the object piece has been synced to the cloud
-
-For each piece, a status row is stored:
-
-- Row key: `{status}/object_digests/{object_piece_identifier}`
-- Row value: (empty value)
-
-Where status is one of `transient`, `local`, or `synced`.
-
-## Cloud sync metadata
-
-The cloud sync component persists in storage rows with some metadata.
-
-- Row key: `sync_metadata/{metadata_type}`
-- Row value: `{metadata_value}`
-
-Currently, cloud sync only stores a single such line, which contains the
-server-side timestamp of the last commit fetched from the cloud.
-
-
-# Pages metadata storage
-
-Additionally to user-created content and metadata on this content, Ledger
-persists information on Page usage, such as the timestamp of when each page was
-last used. This information is used for page eviction, i.e. removing local
-copies of pages, in order to free up device storage when that is necessary.
-
-Page usage information is stored in a dedicated path: `{repo_dir}/page_usage_db`
-using LevelDB.
-
-## Timestamp of last usage
-For each page that is locally stored on the device a row is created in the
-underlying database:
-
-- Row key: `opened/{ledger_name}{page_id}`
-- Row value: `{timestamp}` or `{0}`
-
-`{timestamp}` is the timestamp from when the given page was last closed. If the
-page is currently open, the value is a 0 timestamp.
-
-# See also
-
-For more information see also:
- - [Life of a Put](life_of_a_put.md)
- - [Ledger Architecture - Storage](architecture.md#Storage)
-
-
-[commit.fbs]: /bin/ledger/storage/impl/commit.fbs
-[split.cc]: /bin/ledger/storage/impl/split.cc
-[split.h]: /bin/ledger/storage/impl/split.h
-[tree_node.fbs]: /bin/ledger/storage/impl/btree/tree_node.fbs
-[journals]: life_of_a_put.md#Journals
diff --git a/docs/ledger/data_organization.md b/docs/ledger/data_organization.md
deleted file mode 100644
index 74250ae..0000000
--- a/docs/ledger/data_organization.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# Data Organization
-
-This document describes recommended practices for structuring data that is
-stored in Ledger. We assume that the reader is already familiar with Ledger [API
-surface](api_guide.md).
-
-[TOC]
-
-## Pages
-
-Data stored in Ledger is grouped into separate independent key-value stores
-called *pages*.
-
-Deciding how to split data into pages has the following implications:
-
- - atomic changes across multiple values are possible only within one page, so
- if there's data that has to be modified together, it must belong to the
- same page
- - the current state of each page is either entirely present or entirely absent
- on disk (save for [lazy values](api_guide.md#lazy-values)), hence splitting
- data into multiple pages allows granular optimization of which data to keep
- on disk on each device
-
-There are no restrictions on how many pages a client application can use.
-
-## Entries
-
-Each page stores an ordered list of key-value pairs, also called *entries*.
-
-Both keys and values are arbitrary byte arrays - the client application is free
-to construct the keys and values as needed based on their needs, but see some
-guidance below.
-
-### Key ordering
-
-Entries are sorted by key in the lexicographic order of the byte array. Entry
-retrieval methods always return them in order, it is also possible to use a
-range query to retrieve only a part of the ordered list.
-
-The lexicographic byte array ordering of the keys implies the following caveats:
-
- - **number ordering**: a key of `[1, 0, 0]` is ordered before the key of `[2]`.
- If ordering between the items is important, it is essential to add padding to
- any numbers that are part of the key, so that their width is fixed
- - **string ordering**: ordering of unicode strings in a way that matches human
- expectations is non-trivial and byte-array ordering of utf8/16/32 strings is
- unlikely to yield good results.
-
-### Range queries
-
-The entries stored in a page are sorted by keys, and can be retrieved using
-either exact matching or [range queries](api_guide.md#range-queries).
-
-Because of the range query support, it might be desirable to construct the keys
-in a way that matches the querying needs of the application. For example, a
-messaging application which needs to retrieve only the messages not older than a
-week might wish to structure the data as follows:
-
- - **key**: {timestamp}-{message UUID}
- - **value**: {message content}
-
-*** note
-**Caveat**: as the range queries can currently only yield results in the
-increasing order, in order to retrieve the newest messages, the timestamp needs
-to be constructed as (BIG NUMBER minus the current time).
-***
-
-Then, a [range query](api_guide.md#range-queries) can be used to retrieve the
-messages after the given timestamp.
-
-*** note
-Ledger does not support custom indexes and queries by value. Please do let us
-know about your use cases if this limitation prevents you from adopting Ledger.
-***
-
-### Avoiding collisions
-
-[UUIDs] should be used as part of the entry key in order to avoid unintended
-collisions, where needed. For example, a messaging application might want to
-include an UUID of a message stored in a Ledger entry as part of the entry key,
-in order to avoid collisions between two messages of the same timestamp:
-
- - **key**: {timestamp}-**{message UUID}**
- - **value**: {message content}
-
-## Granularity
-
-Deciding how to split page data into entries has implications on querying
-ability and [conflict resolution](api_guide.md#Conflict-resolution).
-
-If two pieces of data can change **independently** (for example: a name and an
-email of a contact in a contacts app), it is beneficial to put these pieces of
-data in separate entries. Because conflicts are resolved entry-by-entry,
-concurrent modifications of different entries can be automatically merged by the
-default conflict resolution policy.
-
-On the other hand, if two pieces of data are **related** (when one changes, the
-other piece of data needs to change accordingly), we need to either:
-
- - put them in the same entry (and serialize them in the application)
- - put them in separate entries, but use a custom conflict resolution policy
- to preserve the invariants
- - put them in separate entries, but consistently always modify both of them
- together within a [transaction](api_guide.md#transactions)
-
-[UUIDs]: https://en.wikipedia.org/wiki/Universally_unique_identifier
diff --git a/docs/ledger/examples.md b/docs/ledger/examples.md
deleted file mode 100644
index 8963b74..0000000
--- a/docs/ledger/examples.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Examples
-
-List of example apps that directly integrate with Ledger - this does not include
-apps that use Ledger through Framework fuchsia::modular::Link objects.
-
-## C++
-
- * [clipboard] - system clipboard agent which stores state in Ledger
- * [Ledger benchmarks] - benchmarks that exercise Ledger APIs and capture
- performance traces
- * [story runner] - framework facility that stores the state of user stories in
- Ledger
-
-## Dart
-
- * [chat] - a chat agent that uses Ledger to store messages
- * [contacts] - Ledger-based contacts agent
- * [todo list] - a todo-list module that uses Ledger to store the todo items
- * this is a minimal working example of a Ledger-based app
-
-[chat]: https://fuchsia.googlesource.com/topaz/+/master/app/chat/
-[clipboard]: /bin/agents/clipboard/
-[contacts]: https://fuchsia.googlesource.com/topaz/+/master/app/contacts/
-[Ledger benchmarks]: /bin/ledger/tests/benchmark
-[story runner]: /bin/sessionmgr/story_runner/
-[todo list]: https://fuchsia.googlesource.com/topaz/+/master/examples/ledger/todo_list/
diff --git a/docs/ledger/field_data.md b/docs/ledger/field_data.md
deleted file mode 100644
index 74892fd..0000000
--- a/docs/ledger/field_data.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Field Data
-
-Ledger uses [Cobalt] to record field data.
-
-In order to add more events:
-
- - edit Ledger code under [/bin/ledger/cobalt]
- - register the new events, see documentation for [Cobalt client]
-
-In order to view the recorded data, run:
-
-```
-cd garnet/bin/cobalt
-./download_report_client.py
-./report_client -project_id=100
-```
-
-Then, follow `report_client` hints to extract the data. For example, run the
-following to extract Ledger event counters from the last 5 days:
-
-```
-Command or 'help': run range -4 0 2
-```
-
-[Cobalt]: https://fuchsia.googlesource.com/cobalt
-[/bin/ledger/cobalt]: /bin/ledger/cobalt/
-[Cobalt client]: https://fuchsia.googlesource.com/garnet/+/master/bin/cobalt/
diff --git a/docs/ledger/firebase.md b/docs/ledger/firebase.md
deleted file mode 100644
index ac24d16..0000000
--- a/docs/ledger/firebase.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# Firebase Configuration
-
-This document describes how to configure a Firebase project so that it can be
-used for cloud sync by Ledger.
-
-## Create the Firebase project
-
-You can create a new Firebase project at https://firebase.google.com/.
-
-Take note of your *project ID* - this information is needed to configure a
-Fuchsia device to use your instance of Firebase. You can find out what the
-project ID is by looking at the console URL, which takes the form of:
-`https://console.firebase.google.com/project/<project id>`.
-
-## Configuration
-Go to the [Firebase Console](https://console.firebase.google.com/), and open
-your project.
-
-In `Database / Rules`, paste the rules below and click "Publish".
-
-```
-{
- "rules": {
- ".read": false,
- ".write": false,
- "$prefix": {
- "$user": {
- ".read": "$user === auth.uid",
- ".write": "$user === auth.uid",
- "$version": {
- "$app": {
- "$page": {
- "commits": {
- ".indexOn": ["timestamp"],
- "$id": {
- ".validate": "!data.exists()"
- }
- }
- }
- }
- }
- }
- }
- }
-}
-```
-
-In `Storage / Rules`, change the line starting with "allow" to match the example
-below and click "Publish".
-
-```
-service firebase.storage {
- match /b/{bucket}/o {
- match /{prefix}/{user} {
- match /{allPaths=**} {
- allow read, write: if request.auth.uid == user;
- }
- }
- }
-}
-```
diff --git a/docs/ledger/life_of_a_put.md b/docs/ledger/life_of_a_put.md
deleted file mode 100644
index 1117dc2..0000000
--- a/docs/ledger/life_of_a_put.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# Life of a Put
-
-This document explains how Ledger works by following the mechanics of a single
-Put operation.
-
-The Putting of a value happens in 2 major stages:
-1. Locally updating the btree to take into account the new key-value.
-2. Synchronizing the new key-value with the cloud and other devices.
-
-## 1. Local update
-The client facing API of Ledger is defined in [ledger.fidl].
-There are multiple methods to do put operations, with slightly different
-semantics. For this example we can use the FIDL method
-``Put(array<uint8> key, array<uint8> value) => (Status status);``.
-
-This FIDL interface is implemented by PageImpl, which takes a generated callback
-type (PutCallback) used to pass the completion status back to the client.
-
-### Storing the Value to disk
-The first step to handling the FIDL call is storing the *value* (which can be
-large, e.g. multiple GB) onto the disk. The value (which can be passed as a byte
-array, a [VMO], or a socket) is wrapped in a DataSource.
-The data in the DataSource is cut in chunks (see [dynamic chunking] for an
-explanation of the idea, and the [splitting implementation] for details).
-The chunks not already on disks are then written to disk.
-
-*** note
-**A note regarding writing to disk:** Ledger writes all its data to disk using
-[LevelDB]. LevelDB's cache makes reading and writing data faster than when using
-the filesystem.
-***
-
-### Draining the pending PageWatcher updates
-Clients can register PageWatchers to observe changes to Pages. Before creating
-the [commit], we drain the pending updates to the PageWatchers registered for
-the given Page connection. After draining the pending updates, we stop the
-BranchTracker from sending new updates until we've handled the change.
-
-If the Put is part of a transaction, we wait for all PageWatchers to have
-handled the updates before continuing to the next step. The PageWatchers say
-that they've handled the OnChange by calling the (generated) OnChangeCallback.
-
-### Journals
-All changes are first written in a Journal before being committed. There are two
-types of journals: *explicit* journals when clients starts a transaction, and
-*implicit* journals when clients do a change without having started a
-transaction first.
-
-Changes in explicit journals are guaranteed to be seen together: a PageSnapshot
-and/or a PageWatcher will either contain/see **all** the changes, or none. If
-for some reason Ledger is unexpectedly closed, any non completed explicit
-transaction is dropped.
-
-In contrast, PageSnapshots and/or PageWatchers may see the individual changes
-from an implicit journal, and if Ledger is unexpectedly closed any in-progress
-implicit journal will be committed during the next startup.
-
-### Finishing a transaction
-When a transaction is completed, a commit is appended to one of the Page's
-heads.
-
-The BranchTracker of the Page connection is informed of this new commit as to
-make sure it tracks that branch and not some other branch. Not doing so would
-make changes seem to “disappear” as clients would see a different branch than
-the one with their change. The BranchTracker then notifies the relevant
-registered Watchers of the change.
-If there are multiple heads, the MergeResolver starts the process of merging the
-heads.
-
-## 2. Synchronization
-TODO
-### Cloud sync
-### P2P sync
-
-[ledger.fidl]: /public/fidl/fuchsia.ledger/ledger.fidl
-[VMO]: https://fuchsia.googlesource.com/zircon/+/master/docs/objects/vm_object.md
-[dynamic chunking]: https://github.com/YADL/yadl/wiki/Rabin-Karp-for-Variable-Chunking
-[splitting implementation]: /bin/ledger/storage/impl/split.cc
-[LevelDB]: https://en.wikipedia.org/wiki/LevelDB
-[commit]: architecture.md#storage
diff --git a/docs/ledger/style_guide.md b/docs/ledger/style_guide.md
deleted file mode 100644
index 996b05b..0000000
--- a/docs/ledger/style_guide.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# Style Guide
-
-This document describes the conventions adopted in Ledger for the relevant
-languages: English and C++.
-
-[TOC]
-
-## English
-
-This section applies to written communication in docs, code comments, commit
-messages, emails, etc.
-
-### ledger vs Ledger vs the ledger vs ...
-
-The project and the resulting application are called "Ledger". It is a proper
-name, hence it is not preceded by an article.
-
-**Do**: *Ledger synchronizes user data across devices*
-
-**Don't**: *~~the Ledger~~ synchronizes user data across devices*
-
-**Don't**: *~~ledger~~ synchronizes user data across devices*
-
-All of the data stored in Ledger on behalf of a user is sometimes referred to as
-this user's ledger. In that case "ledger" is a common name - not capitalized and
-preceded by an article.
-
-**Do**: *each user has a separate ledger*
-
-**Don't**: *each user has ~~separate Ledger~~*
-
-## C++
-
-Ledger, like the rest of Fuchsia, follows [Google C++ Style Guide]. In a few
-cases not covered there, we choose a convention.
-
-### Naming of callback parameters
-
-If there is a need to distinguish callback parameters of a method or a class,
-call them `on_<event>`.
-
-**Do**: `std::function<void(int)> on_done`
-
-**Don't**: ~~`std::function<void(int)> done_callback`~~
-
-### Usage of fxl::StringView vs std::string
-
-This section discusses which string types to use for C++ API arguments.
-
-Use a `fxl::StringView` (non-ref) if the functionality just reads the string:
-`fxl::StringView` can handle any stream of bytes without copies.
-
-Use a `std::string` (non-ref) if:
-
- - the functionality needs to take ownership of the string (it allows users of
- the functionality to `std::move` the string if they don't reuse it
- afterwards), or
- - you need to pass the string over to a function that requires an
- `std::string`.
-
-You might want to use a `const std:string&` (const ref), if you need to call a
-function that itself takes a `const std:string&` (and you cannot or don't want
-to change it to take an `fxl::StringView`).
-
-[Google C++ Style Guide]: https://google.github.io/styleguide/cppguide.html
diff --git a/docs/ledger/testing.md b/docs/ledger/testing.md
deleted file mode 100644
index bc92a3f..0000000
--- a/docs/ledger/testing.md
+++ /dev/null
@@ -1,180 +0,0 @@
-# Testing
-
-This document describes different test types used in Ledger.
-
-*** note
-All of the tests run on a Fuchsia device (real or emulated). For the tests below
-we indicate the commands to trigger the execution from the host machine, but the
-execution itself happens on the target.
-***
-
-[TOC]
-
-## TL;DR
-
-```sh
-fx run-test ledger_tests
-```
-
-This command will run the following tests, that are enabled by default:
-
-* [unit tests](#unit-tests)
-* [integration tests](#integration-tests)
-* [local end-to-end tests](#local-e2e)
-* [Firestore cloud provider] unit tests
-
-It will not run the following tests, that need to be configured and executed
-manually:
-
-* [synchronization end-to-end tests](#sync-e2e)
-* [performance tests][benchmarks]
-* [fuzz tests](#fuzz-tests)
-* [Firestore cloud provider] end-to-end tests
-
-## Unit tests
-
-**Unit tests** are low-level tests written against the smallest testable parts
-of the code. Tests for `some_class.{h,cc}` are placed side-by-side the code
-being tested, in a `some_class_unittest.cc` file.
-
-Unit tests are regular [Google Test] tests. Most of them use our own
-[TestLoopFixture] base class to conveniently run them with a fake clock, and
-simulated multi-thread, in order to know when nothing will ever happen again.
-
-All unit tests in the Ledger tree are built into a single `ledger_unittests`
-binary. The binary is self-contained: it contains both the tests and the Ledger
-logic under test linked into a single Google Test binary.
-
-You can run it from the host with:
-
-```sh
-fx run-test -t ledger_unittests ledger_tests
-```
-
-## Integration tests
-
-**Integration tests** are written against client-facing FIDL services exposed by
-Ledger, although these services still run in the same process as the test code.
-
-Integration tests inherit from [IntegrationTest] and are placed under
-[/bin/ledger/tests/integration].
-
-All integration tests in the Ledger tree are built into a single
-`ledger_integration_tests` binary. You can run it from the host:
-
-```sh
-fx run-test -t ledger_integration_tests ledger_tests
-```
-
-*** aside
-Some of the integration tests emulate multiple Ledger instances synchronizing
-data with each other. Through advanced build magic and [testing abstractions],
-these are run both as integration tests (against fake in-memory implementation
-of the cloud provider interface), and as end-to-end synchronization tests
-(against a real server).
-***
-
-## End-to-end tests
-
-**End-to-end tests** are also written against client-facing FIDL services
-exposed by Ledger, but in this case the test code runs in a separate process,
-and connects to Ledger the same way any other client application would do. This
-is the highest-level way of testing that exercises all of the Ledger stack.
-
-### Local tests {#local-e2e}
-
-End-to-end tests not depending on cross-device synchronization are called "local
-end-to-end tests" and are defined in [/bin/ledger/tests/e2e_local]. All local
-end-to-end tests are built into a single `ledger_e2e_local` binary. You can run
-it from the host:
-
-```sh
-fx run-test -t ledger_e2e_local ledger_tests
-```
-
-### Synchronization tests {#sync-e2e}
-
-Synchronization end-to-end tests create multiple local Ledger instances
-configured to synchronize using a cloud provider backed by a real server. The
-cloud provider instances are set up to represent the same virtual user,
-therefore emulating multiple devices synchronizing their Ledger data through the
-real server.
-
-*** note
-Those tests exercise cloud sync against a real server. They are not run by
-default, and you need to follow the instructions below to set up server access
-and run them manually.
-***
-
-<a name="cloud-sync"></a>
-First, ensure you have an instance of the server configured and take note of the
-configuration params (service account credentials file and API key) - in order
-to obtain those, follow the [server configuration] instructions.
-
-Then, create a json sync credentials file file of the following format:
-```javascript
-{
- "api-key": "<API_KEY>",
- "service-account": <SERVICE_ACCOUNT_FILE_CONTENT>
-}
-```
-where <API_KEY> is the api key retrieved from the firebase console, and
-<SERVICE_ACCOUNT_FILE_CONTENT> is the content of the service account credentials
-file.
-
-Then, put the sync credentials file whenever you like, and set the full path to
-it in the GN variable:
-
-```sh
-fx set x64 --args ledger_sync_credentials_file=\"/full/path/to/sync_credentials.json\"
-```
-
-After rebuilding, the credentials file will be automatically embedded in the
-relevant sync test binaries. You will still need to pass the remaining
-parameters (server ID and API key) as command line parameters.
-
-You can now run the tests from the host as follows:
-
-```sh
-fx run-test -t ledger_e2e_sync ledger_tests
-```
-
-## Performance tests
-
-For performance tests, see [benchmarks].
-
-## Fuzz tests
-
-Ledger uses LibFuzzer for fuzz tests. We have a single fuzz package called
-`ledger_fuzzers`. It can be built as follows:
-
-```sh
-fx set x64 --monolith peridot/packages/tests/ledger --fuzz-with asan
-fx full-build
-```
-
-And then run:
-
-```sh
-fx fuzz start ledger
-```
-
-You can refer to the full [fuzzing] instructions for details.
-
-## See also
-
- - [Firestore cloud provider] has its own suite of tests, including unit tests
- and end-to-end validation tests
-
-[Google Test]: https://github.com/google/googletest
-[TestLoopFixture]: https://fuchsia.googlesource.com/garnet/+/master/public/lib/gtest/test_loop_fixture.h
-[IntegrationTest]: /bin/ledger/tests/integration/integration_test.h
-[/bin/ledger/tests/integration]: /bin/ledger/tests/integration
-[Synchronization end-to-end tests]: /bin/ledger/tests/e2e_sync/README.md
-[/bin/ledger/tests/e2e_local]: /bin/ledger/tests/e2e_local
-[/bin/ledger/tests/e2e_sync]: /bin/ledger/tests/e2e_sync
-[server configuration]: /bin/cloud_provider_firestore/docs/configuration.md
-[testing abstractions]: /bin/ledger/testing/ledger_app_instance_factory.h
-[benchmarks]: /bin/ledger/tests/benchmark/README.md
-[Firestore cloud provider]: /bin/cloud_provider_firestore/README.md#testing
-[fuzzing]: https://fuchsia.googlesource.com/docs/+/master/development/workflows/libfuzzer.md
diff --git a/docs/ledger/user_guide.md b/docs/ledger/user_guide.md
deleted file mode 100644
index 3408430..0000000
--- a/docs/ledger/user_guide.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# User Guide
-
-[TOC]
-
-## Prerequisites
-
-### Disk Storage
-
-Ledger writes all data under `/data/modular/<USER_ID>/LEDGER`. In order for data
-to be persisted, ensure that a persistent partition is mounted under /data. See
-[minfs setup](https://fuchsia.googlesource.com/zircon/+/master/docs/minfs.md).
-
-### Networking
-
-Follow the instructions in
-[netstack](https://fuchsia.googlesource.com/netstack/+/d24151e74c745358b102f4f33a3c5f4d720ddc52/README.md)
-to ensure that your Fuchsia has Internet access.
-
-Run `curl` to verify that it worked:
-
-```
-curl http://example.com
-```
-
-You should see the HTML content of the `example.com` placeholder page.
-
-## Cloud sync
-
-When running in the guest mode, Ledger works locally but does not synchronize data
-with the cloud.
-
-When running in the regular mode, Ledger automatically synchronizes user data
-using a communal cloud instance.
-
-## Reset
-
-Deleting persistent storage (e.g. `rm -rf /data`) does not erase the Ledger
-state in the cloud, which will be synced back the next time a user signs in.
-
-In order to reset the Ledger state in the cloud, visit
-https://fuchsia-ledger.firebaseapp.com/ , sign in with the account you want to
-reset and hit the erase button.
-
-Any device that has local account state synced with the cloud before the erase
-becomes at this point incompatible with the cloud. Ledger will detect this on
-each device upon the next attempt to sync, erase all local data and log the user
-out. The account is usable again immediately after logging back in.
-
-## Debug and inspect
-
-The **Ledger Debug Dashboard** allows you to inspect the local state of the Ledger.
-
-You need to point your browser to the port 4001 of the Fuchsia machine to access
-the dashboard of the current user.
-The dashboard is also accessible from any device connected to the fuchsia machine
-on the same local network.
-
-The dashboard exposes the instances for the current user. When you select an instance,
-it displays its pages. When you select a page, it displays the commits graph, where the root node is
-colored in a different color than the other nodes. When you select a commit,
-it displays its entries (keys, values, priorities), generation (internal Ledger counter)
-and timestamp.
diff --git a/docs/lint.md b/docs/lint.md
deleted file mode 100644
index 451d06e..0000000
--- a/docs/lint.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Lint
-
-We use clang-tidy to lint C++ code and aim to keep the repository warning-clean.
-The linter is configured in the [.clang-tidy](../.clang-tidy) file.
-
-## How to lint
-
-In order to run the current CL through the linter (assuming the current
-directory is `//peridot`), run:
-
-```
-../scripts/git-file-tidy [--out-dir out/debug-x64]
-```
-
-In order to run the entire repository through the linter, add `--all`. You can
-also add `--fix` in order to automatically generate fixes for some (but not all)
-of the warnings.
-
-## Suppressing warnings
-
-Any warning can be suppressed by adding a `// NOLINT` comment on the line on
-which it occurs. It is also possible to disable the check entirely within Ledger
-repository by editing the [.clang-tidy](../.clang-tidy) file.
-
-## Disabled checks
-
-This list tracks the reasons for which we disabled particular [checks]:
-
- - `clang-analyzer-core.NullDereference`, `clang-analyzer-unix.Malloc` - these
- checks are triggering memory access warnings at rapidjson callsites (despite
- the header filter regex) and we didn't find a more granular way to disable
- them
- - `clang-diagnostic-unused-command-line-argument` - ninja-generated compilation
- database contains the linker argument which ends up unused and triggers this
- warning for every file
- - `misc-noexcept*` - Fuchsia doesn't use C++ exceptions
- - `modernize-deprecated-headers` - Fuchsia uses old-style C headers
- - `modernize-raw-string-literal` - the check was suggesting to convert `\xFF`
- literals, which we'd rather keep in the escaped form.
- - `modernize-return-braced-init-list` - concerns about readability of returning
- braced initialization list for constructor arguments, prefer to use a
- constructor explicitly
- - `modernize-use-auto` - not all flagged callsites seemed worth converting to
- `auto`
- - `modernize-use-equals-delete` - flagging all gtest TEST_F
- - `modernize-use-equals-default` - Ledger chose not to impose a preference for
- "= default"
- - `performance-unnecessary-value-param` - it was flagging view classes
- which we prefer to pass by value
- - `readability-implicit-bool-conversion` - Fuchsia C++ code commonly uses implicit
- bool cast of pointers and numbers
-
-[checks]: https://clang.llvm.org/extra/clang-tidy/checks/list.html
diff --git a/docs/modular/agent.md b/docs/modular/agent.md
deleted file mode 100644
index 27c9401..0000000
--- a/docs/modular/agent.md
+++ /dev/null
@@ -1,85 +0,0 @@
-## Agents
-
-An `Agent` is a singleton-per-session component which runs outside of
-the scope of a Story without any graphical UI.
-
-Agents can schedule tasks (i.e. they can register to be woken up by the
-framework to perform work), and provide services to other modular components.
-
-Any modular component can connect to an agent and access its services (including
-modules, shells, and other agents).
-
-### Environment
-
-An agent is given access to two services provided by the modular framework in
-its incoming namespace:
-
-* `fuchsia.modular.ComponentContext` which gives the agent access to
- functionality which is shared across components run under the modular
- framework (e.g. modules, shells, agents).
-* `fuchsia.modular.AgentContext` which gives agents access to agent specific
- functionality, like creating entity references and scheduling tasks.
-
-An agent is expected to provide two services to the modular framework in its
-outgoing namespace:
-
-* `fuchsia.modular.Agent` which allows the framework to forward connection
- requests from other components and tell the agent to run tasks.
-* `fuchsia.modular.Lifecycle` which allows the framework to signal the agent
- to terminate gracefully.
-
-The aforementioned services enable communication between agents and the modular
-framework, but agents can also expose custom FIDL services to components. For a
-more detailed explanation of the mechanism which enables this service exchange
-see Communication Mechanisms below.
-
-### Lifecycle
-
-For most agents, when a component connects to an agent the framework will give
-the component an `AgentController`. When the connecting component drops the
-`AgentController` connection, and there are no outstanding connections, the
-agent will be killed by the framework.
-
-There are some agents for which the `sessionmgr` maintains an `AgentController`,
-and thus the agent remains alive for the duration of the session. These
-"session" agents also get access to `fuchsia.modular.PuppetMaster` in their
-incoming namespace.
-
-### Communication mechanisms
-
-Components can communicate with agents in two different ways: either by
-connecting to a FIDL service exposed by the agent, or over a `MessageQueue`.
-
-Which communication method is appropriate depends on the semantics of the
-messages being passed. FIDL requires both agent and client to be running,
-whereas message queues allow the life cycles of the sender and receiver to be
-different.
-
-#### FIDL Services
-
-The modular framework will forward a `fuchsia.sys.ServiceProvider` request via
-`fuchsia::modular::Agent.Connect` call, and will also provide the agent with an
-identifier for the client which is requesting the service provider.
-
-Any services added to the service provider will be exposed directly to the
-connecting component.
-
-To illustrate this, consider a module connecting to an agent:
-
-The module calls `ConnectToAgent` on its `ComponentContext`, which contains a
-`ServiceProvider` request as well as an `AgentController` request.
-
-The agent controller request is used by the framework to keep the agent alive
-until the agent controller is closed by the client. If more than one client is
-connected to the same agent, the agent will be kept alive until all agent
-controllers have been closed.
-
-The service provider request is forwarded to the agent, along with a string
-which identifies the client connecting to the agent.
-
-#### Message Queues
-
-Messages sent over message queues are untyped, but allow the life cycles of the
-reader and writer to be decoupled. For example, an agent may provide a module
-with a message queue which it can use to send messages to the agent. The agent
-can then register to be woken up when a message is delivered on the queue.
diff --git a/docs/modular/entity.md b/docs/modular/entity.md
deleted file mode 100644
index 4079235..0000000
--- a/docs/modular/entity.md
+++ /dev/null
@@ -1,70 +0,0 @@
-## Entities
-
-The Fuchsia entity model facilitates information interchange by defining a
-common interface for _describing_, _referencing_, _accessing_, and _mutating_
-data objects (entities) which are shared between components (modules, agents,
-shells) running in the modular framework. It consists of the following major
-concepts:
-
-* Entities: the data objects shared between components.
-* Entity references: a serializable token which can be used to retrieve an
- `Entity` handle.
-* `Entity`: An interface which gives access to a shared data object.
-* `EntityProvider`: the interface which allows agents to expose entities to
- the system.
-* `EntityResolver`: the Fuchsia API for requesting an `Entity` handle for a
- given reference.
-
-### Lifecycle
-
-The lifecycle of the data backing an `Entity` is controlled by the
-`EntityProvider`. The lifecycle of the `Entity` handle is controlled by
-`sessionmgr`.
-
-#### Entities owned by Agents
-
-Agents don't create `Entity` handles directly. Agents connect to the
-`EntityReferenceFactory` which provides the agent with an entity reference in
-exchange for a `cookie`. The entity reference can then be shared with other
-modular components which can use their `EntityResolver` to dereference it into
-an `Entity` interface.
-
-Calls on that `Entity` interface will then be forwarded to the agent, along with
-the associated cookie.
-
-The agent is thus responsible for storing and providing the entity data,
-associating it with the correct cookie, and optionally handling requests for
-mutating the entity data.
-
-#### Entities owned by a Story
-
-Modules can create entities explicitly via their `ModuleContext` by providing a
-`fuchsia.mem.Buffer` and an associated type. The framework manages the lifecycle
-of such entities by storing them in the story's record. For this reason, when
-the story is deleted, so is the entity. Agents and modules outside the story can
-dereference the entity so long as the story still exists.
-
-#### Entity Resolution
-
-This section describes the internals of entity resolution.
-
-`EntityProviderRunner` implements the `fuchsia::modular::EntityResolver`
-interface, and is also responsible for creating entity references by
-implementing the `fuchsia::modular::EntityReferenceFactory` interface. A single
-instance of the `EntityProviderRunner` manages all the entity providers running
-in the system.
-
-The first step in entity resolution (i.e. the first thing which happens when
-`ResolveEntity` is called) is the runner determines whether the entity is
-provided by an agent or by the modular framework by inspecting the entity
-reference. The runner then asks an `EntityProviderLauncher` to launch the
-appropriate entity provider.
-
-If the entity provider is an agent, an `AgentController` is passed to the
-launcher, and the runner keeps the agent controller alive until the client
-closes the `Entity`.
-
-Each `Entity` request has an associated `EntityController` which the entity
-runner owns. The `EntityController` owns the `AgentController` if the entity
-provider was an agent, and is responsible for forwarding the entity interface
-methods to the entity provider.
diff --git a/docs/modular/intent.md b/docs/modular/intent.md
deleted file mode 100644
index 74be6e2..0000000
--- a/docs/modular/intent.md
+++ /dev/null
@@ -1,54 +0,0 @@
-## Intents
-
-An `Intent` is used to instruct a module to perform an action. The intent
-contains the action name, the arguments for the action parameters, and an
-optional handler which explicitly specifies which module is meant to perform the
-action.
-
-### Declaring Actions
-
-Modules can declare which actions they handle, and their associated parameters
-in their [module facet](module_facet.md). The modular framework will then index
-the module and treat it as a candidate for any incoming intents which contain
-the specified action, and don't have an explicit handler set.
-
-### Handling Intents
-
-When an intent is resolved the framework determines which module instance will
-handle it.
-
-The framework then connects to the module's `fuchsia::modular::IntentHandler`
-service, and calls `HandleIntent()`. The framework will connect to the intent
-handler interface each time a new intent is seen for a particular module
-instance, and intents can be sent to modules which are already running. Modules
-are expected to handle the transition between different intents gracefully.
-
-### Example
-
-To illustrate the intended use of intents, consider the following fictional
-example: a new story has been created with a module displaying a list of
-restaurants and the module wants to show directions to the currently selected
-restaurant.
-
-The restaurant module creates an intent with a `com.fuchsia.navigate` action
-with two parameters `start` and `end`, both of type `com.fuchsia.geolocation`
-and passes it to the modular framework via `ModuleContext.AddModuleToStory`.
-
-At this point, the framework will search for a module which has declared support
-for the `com.fuchsia.navigate` action. Once such a module is found, it is added
-to the story and started. The framework then connects to the started module's
-`IntentHandler` service and provides it with the intent.
-
-At this point, the restaurant list module's selected restaurant changes. It
-again creates an intent, with the same action as before but with new location
-arguments and calls `ModuleContext.AddModuleToStory`.
-
-The framework now knows there is already a module instance running (in this case
-`AddModuleToStory` uses the `name` parameter to identify module instances)o
-explicitly specify a which can handle the given action, and connects to its
-`IntentHandler` interface and provides it with the new intent. The navigation
-module can then update its UI to display directions to the new restaurant.
-
-If the restaurant module wanted a specific module (e.g. `Fuchsia Maps`) to
-handle the intent, it would set the `Intent.handler` to the component URL for
-the module.
diff --git a/docs/modular/module.md b/docs/modular/module.md
deleted file mode 100644
index 4d16564..0000000
--- a/docs/modular/module.md
+++ /dev/null
@@ -1,42 +0,0 @@
-## Modules
-
-A `Module` is a component which displays UI and runs as part of a `Story`.
-
-Multiple modules can be composed into a single story, and modules can add other
-modules to the story they are part of. Module's can either embed other modules
-within their own content, or they can delegate visual composition to the
-`StoryShell`.
-
-### Environment
-
-A module is given access to two services provided by the modular framework in
-its incoming namespace:
-
-* `fuchsia.modular.ComponentContext` which gives the agent access to
- functionality which is shared across components run under the modular
- framework (e.g. modules, shells, agents).
-* `fuchsia.modular.ModuleContext` which gives modules access to module
- specific functionality, like adding other modules to its story and creating
- entities.
-
-A module is expected to provide two services to the modular framework in its
-outgoing namespace:
-
-* `fuchsia.ui.app.ViewProvider` which is used to display the module's UI.
-* `fuchsia.modular.Lifecycle` which allows the framework to signal the module
- to terminate gracefully.
-* `fuchsia.modular.IntentHandler` which allows the framework to send
- [intents](intent.md) to the module.
-
-### Lifecycle
-
-A module's lifecycle is bound to the lifecycle of the story it is part of. In
-addition, a given module can have multiple running instances in a single story.
-
-When a module starts another module it is given a module controller which it can
-use to control the lifecycle of the started module.
-
-### Communication Mechanisms
-
-Modules communicate with other modules via intents and entities, and with agents
-via FIDL and message queues.
diff --git a/docs/modular/module_facet.md b/docs/modular/module_facet.md
deleted file mode 100644
index 9657e2d..0000000
--- a/docs/modular/module_facet.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# Module Facet
-
-Modules declare their run-time capabilities (e.g. which Intent actions they
-handle) in the module facet of their [component manifest][component-manifest]
-(i.e. their `.cmx` file).
-
-## What is a facet?
-
-Component facets are sections in the component manifest which aren't consumed
-directly by the component manager, but are left to be defined and consumed by
-other parts of Fuchsia. The Modular framework defines a `fuchsia.module` facet
-which module authors use to define module specific properties.
-
-This document describes how to declare a module facet in your component
-manifest.
-
-## Example
-
-The following is an excerpt of a component manifest that defines a module facet.
-
-```
-{
- "facets": {
- "fuchsia.module": {
- "@version": 2,
- "suggestion_headline": "See details about person",
- "intent_filters": [
- {
- "action": "com.google.fuchsia.preview.v1",
- "parameters": [
- {
- "name": "entityToPreview",
- "type": "https://fuchsia.com/types/Friend"
- }
- ]
- }
- ],
- "composition_pattern": "ticker"
- }
- }
-}
-```
-
-This module can be launched using an Intent with the action
-`com.google.fuchsia.preview.v1` action, and a `entityToPreview` parameter of
-type `https://fuchsia.com/types/Friend`.
-
-## Module Facet fields
-
-The module facet is defined under the `fuchsia.module` facet in a component
-manifest. See [example](#example).
-
-* `@version` **unsigned integer** *(required)*
- - Describes the version of the module facet. The fields below indicate
- which minimum `@version` they require.
- - **example**: `2`
-* `composition_pattern`: **string** *(optional)*
- - **minimum `@version`**: 1
- - **possible values:**
- * `ticker`: Show the module at the bottom of the screen underneath another
- module.
- * `comments-right`: show the module to the right of other modules.
- - **example**: `"ticker"`
- - Specifies the compositional pattern that will be used by the story shell
- to display this module along-side other modules in the story. For
- example, the ticker pattern gives a signal to the story shell that the
- module should be placed below another module that it may share a link
- with.
-* `suggestion_headline`: **string** *(optional)*
- - **minimum `@version`**: 2
- - **possible values**: UTF-8 string
- - **example**: `"See details about this person"`
- - A human-readable string that may be used when suggesting this Module.
-* `placeholder_color`: **string** *(optional)*
- - **minimum `@version`**: 2
- - **possible values**: hex color code, leading with a hashtag (`#`)
- - **example**: `"#ff00ff"`
- - Defines the color of the placeholder widget used while the module loads.
-* `intent_filters`: **IntentFilter[]** *(optional)*
- - **minimum `@version`**: 2
- - **possible values**: JSON list of [IntentFilter](#IntentFilter)
- - **example**: See [example](#example).
- - A list of different Intent types this Module is able to handle. An
- action dictates a semantic function this Module implements, as well as
- the role of each of its parameters. When resolving an intent to a
- module, the intent resolver uses an index of these intent filter lists
- to determine which modules can handle an intent.
-
-### IntentFilter
-
-`IntentFilter` is a JSON object used to describe an intent type that a module is
-able to handle. The following describes the fields of the IntentFilter JSON
-object:
-
-* `action`: **string** *(required)*
- - **minimum `@version`**: 2
- - **possible values**: ASCII string
- - The action this module is able to handle.
-* `parameters`: **ParameterConstraint[]** *(required)*
- - **minimum `@version`**: 2
- - **possible values**: JSON List of
- [ParameterConstraint](#ParameterConstraint)
- - Describes the names and types of the parameters required to execute the
- specified action. Parameters are typically passed in as Entities.
-
-### ParameterConstraint
-
-`ParameterConstraint` describes a particular intent parameter's name, and it's
-acceptable type.
-
-* `name`: **string** *(required)*
- - **minimum `@version`**: 2
-* `type`: **string** *(required)*
- - **minimum `@version`**: 2
- - Type that is valid for this parameter.
-
-See [example](#example).
-
-[component-manifest]: https://fuchsia.googlesource.com/docs/+/master/the-book/package_metadata.md#Component-manifest
diff --git a/docs/modular/overview.md b/docs/modular/overview.md
deleted file mode 100644
index 4672439..0000000
--- a/docs/modular/overview.md
+++ /dev/null
@@ -1,43 +0,0 @@
-## Overview
-
-Modular is the application framework for Fuchsia. It manages user experiences by
-composing UI, data, and users from a diverse set of components into logical and
-visual containers called Stories.
-
-The framework defines classes of components to extend user experiences and
-provides software primitives for component composition, communication, task
-delegation, state management and data sharing.
-
-### Requirements to use Modular
-
-Modular supports software written in any language (e.g. Flutter, C++) for any
-Fuchsia supported runtime, as long as it is a Fuchsia Component.
-
-The Modular Framework communicates with components it launches via FIDL, the
-standard IPC mechanism for Fuchsia.
-
-### Extension Points
-
-The framework defines several different classes of components which can be
-implemented by developers to extend the behavior of user experiences:
-
-1. [Modules](module.md) are components which display UI and are visually
- composed in a [Story](story.md).
-1. [Agents](agent.md) are components which run in the background to provide
- services and data to Modules and other Agents.
-1. [Shells](shell.md) manage system UI and mediate user interactions.
-1. [EntityProviders](entity.md) are components which provide access to data
- object (entities) which are shared between components running in modular.
-
-### `basemgr` and `sessionmgr`
-
-After Fuchsia device startup, `basemgr` and `sessionmgr` are processes that
-provide session management, component lifecycle management and state management.
-
-* [`basemgr`](basemgr.md) is responsible for user authentication and
- authorization. It leverages the Base Shell to present UI.
-
-* [`sessionmgr`](sessionmgr.md) is responsible for the lifecycle of Stories,
- Modules and Agents, as well as service and state coordination between them.
- It leverages Session and Story Shells to manage the visual composition of
- these components.
diff --git a/docs/modular/shell.md b/docs/modular/shell.md
deleted file mode 100644
index 6452ffb..0000000
--- a/docs/modular/shell.md
+++ /dev/null
@@ -1,40 +0,0 @@
-## Shells
-
-Shells are components which are responsible for composing UI. There are three
-shells:
-
-* `BaseShell` displays UI associated with a device, prior to a session being
- started.
-* `SessionShell` displays the UI associated with a given session (e.g. list of
- stories, settings UI).
-* `StoryShell` displays a single story (i.e. the composition of the modules in
- a story, each story gets its own `StoryShell` instance).
-
-### Environment
-
-A shell is given access to two services provided by the modular framework in its
-incoming namespace:
-
-* `fuchsia.modular.ComponentContext` gives the agent access to functionality
- which is shared across components run under the modular framework (e.g.
- modules, shells, agents).
-* `fuchsia.modular.[Base,Session,Story]ShellContext` gives access to shell
- specific functionality for each type of shell, respectively.
-
-A shell is expected to provide two services to the modular framework in its
-outgoing namespace:
-
-* `fuchsia.modular.[Base,Session,Story]Shell` the modular framework uses to
- communicate requests to display UI.
-* `fuchsia.modular.Lifecycle` allows the framework to signal the shell to
- terminate gracefully.
-
-### Lifecycle
-
-The three shells have varying lifecycles:
-
-* `BaseShell` runs between the time `basemgr` starts up until a session has
- been established, and on demand thereafter to faciliate authentication
- requests.
-* `SessionShell` runs for the duration of a session.
-* `StoryShell` runs while its associated story is running.
diff --git a/docs/modular/story.md b/docs/modular/story.md
deleted file mode 100644
index ad3e8e7..0000000
--- a/docs/modular/story.md
+++ /dev/null
@@ -1,16 +0,0 @@
-## Stories
-
-A story is a logical container for composing a set of modules.
-
-Stories and their associated state are stored in the user's Ledger.
-
-### Presentation
-
-The modular framework uses the `fuchsia.modular.StoryShell` interface to display
-the UI for stories.
-
-### Lifecycle
-
-Stories can be created, deleted, started, and stopped. Created and deleted refer
-to the existence of the story in the ledger, whereas started and stopped refer
-to whether or not the story and its associated modules are currently running.
diff --git a/docs/repository_structure.md b/docs/repository_structure.md
deleted file mode 100644
index 37c6a15..0000000
--- a/docs/repository_structure.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Peridot directory structure
-
-This document describes the directory structure of this repository.
-
-[TOC]
-
-## Common parts
-
-Peridot follows the common aspects of layer repository structure defined in
-[Layer repository structure](https://fuchsia.googlesource.com/docs/+/master/layer_repository_structure.md).
-
-This file documents the Peridot-specific pieces.
-
-## TODO
diff --git a/docs/standalone_build.md b/docs/standalone_build.md
deleted file mode 100644
index 848b10d..0000000
--- a/docs/standalone_build.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Peridot Standalone Build
-
-To get the source code for the Peridot layer, using the following commands
-(see [Getting Source](https://fuchsia.googlesource.com/docs/+/master/getting_source.md)
-for more information):
-
-```
-curl -s "https://fuchsia.googlesource.com/scripts/+/master/bootstrap?format=TEXT" | base64 --decode | bash -s peridot
-```
-
-To build the Peridot layer, use the following commands:
-
-## x64
-
-```
-fx set x64
-fx full-build
-```
-
-## arm64
-
-```
-fx set arm64
-fx full-build
-```
diff --git a/examples/.gitignore b/examples/.gitignore
deleted file mode 100644
index 16a1724..0000000
--- a/examples/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.packages
diff --git a/examples/README.md b/examples/README.md
deleted file mode 100644
index f3d9cbc..0000000
--- a/examples/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Example applications that use the modular runtime for composition.
-
-Code in this directory is not in the modular namespace because it's meant to
-demonstrate how it looks like to be a client of the modular codebase.
-
-These examples are all in C++. For examples in dart/flutter, see
-[//topaz/examples/ui/](https://fuchsia.googlesource.com/topaz/+/HEAD/examples/ui/)
diff --git a/examples/cloud_components/index.json b/examples/cloud_components/index.json
deleted file mode 100644
index e68719e..0000000
--- a/examples/cloud_components/index.json
+++ /dev/null
@@ -1 +0,0 @@
-["https://storage.googleapis.com/maxwell-agents/web_view_component.json"]
diff --git a/examples/guides/how_to_write_a_module_cc.md b/examples/guides/how_to_write_a_module_cc.md
deleted file mode 100644
index 4b20e1b..0000000
--- a/examples/guides/how_to_write_a_module_cc.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# How-To: Write a Module in C++
-
-## Overview
-
-A `Module` is a UI component that can participate in a [Story](link to story doc),
-potentially composed of many different `Module`s. A `Module`'s lifecycle is tightly
-bound to the story to which it was added. In addition to the capabilities
-provided to all Peridot components via `fuchsia::modular::ComponentContext`, a `Module` is given
-additional capabilities via its `fuchsia::modular::ModuleContext`.
-
-## `SimpleMod`
-
-`SimpleMod` is a `Module` communicates with `SimpleAgent` via a `fuchsia::modular::MessageQueue`, and
-displays the messages from `SimpleAgent` on screen.
-
-### Mod Initialization
-
-The first step to writing a `Module` is implementing the initializer.
-
-```c++
-#include <lib/component/cpp/startup_context.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <ui/cpp/fidl.h>
-
-namespace simple {
-
-class SimpleModule : fuchsia::ui::viewsv1::ViewProvider {
- public:
- SimpleModule(
- modular::ModuleHost* module_host,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider> view_provider_request)
- : view_provider_binding_(this) {
- view_provider_binding_.Bind(std::move(view_provider_request));
-}
-
- private:
- modular::ModuleHost* module_host_;
- fidl::Binding<fuchsia::ui::viewsv1::ViewProvider> view_provider_binding_;
- std::set<std::unique_ptr<SimpleView>> views_;
-};
-
-} // namespace simple
-```
-
-The `ModuleHost` provides `SimpleModule` with its `StartupContext` and
-`fuchsia::modular::ModuleContext`.
-
-The `ViewProvider` request allows the system to connect to `SimpleModule`'s view.
-TODO: Update guide to explain view connections.
-
-### Connecting to `SimpleAgent`
-
-In order to provide `SimpleAgent` with a message queue `SimpleModule` first
-needs to connect to the agent via its `fuchsia::modular::ComponentContext`.
-
-```c++
-// Get the component context from the module context.
-modular::fuchsia::modular::ComponentContextPtr component_context;
-module_host->module_context()->GetComponentContext(
- component_context.NewRequest());
-
-// Connect to the agent to retrieve it's outgoing services.
-modular::fuchsia::modular::AgentControllerPtr agent_controller;
-fuchsia::sys::ServiceProviderPtr agent_services;
-component_context->ConnectToAgent("system/bin/simple_agent",
- agent_services.NewRequest(),
- agent_controller.NewRequest());
-```
-
-### Creating a `fuchsia::modular::MessageQueue`
-
-`SimpleModule` needs to create a message queue and retrieve its token to hand
-it over to `SimpleAgent` so it can write messages to it.
-
-```c++
-// Request a new message queue from the component context.
-modular::MessageQueueClient message_queue;
-component_context->ObtainMessageQueue("agent_queue",
- message_queue.NewRequest());
-
-// Get the token for the message queue and send it to the agent.
-message_queue.GetToken(fxl::MakeCopyable(
- [agent_service = std::move(agent_service)](fidl::StringPtr token) {
- agent_service->SetMessageQueue(token);
- }));
-```
-
-### Communicating with `SimpleAgent
-
-In order to receive messages on the newly created message queue, `SimpleModule`
-registers a receiver callback with `MessageQueueClient`. Here, the receiver is a
-lambda that gets called with new messages.
-
-```c++
-// Register a callback with a message queue client that logs any
-// messages that SimpleAgent sends
-message_queue.RegsiterReceiver(
- [](std::string msg, fit::function<void()> ack) {
- ack();
- FXL_LOG(INFO) << "New message: " << msg;
- });
-```
-
-### Running the Module
-
-```c++
-int main(int argc, const char** argv) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<simple::SimpleModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
-```
-
-`ModuleDriver` is a helper class that manages the `Module`'s lifecyle. Here it is
-given a newly created `StartupContext` and a callback that will be executed
-when the `Module` exits. `ModuleDriver` requires `SimpleModule` to implement the
-constructor shown above, as well as a `Terminate`:
-
-```c++
-void Terminate(const std::function<void()>& done);
-```
-
-The module is responsible for calling `done` once its shutdown sequence is complete.
-
diff --git a/examples/guides/how_to_write_an_agent_cc.md b/examples/guides/how_to_write_an_agent_cc.md
deleted file mode 100644
index f17e4e2..0000000
--- a/examples/guides/how_to_write_an_agent_cc.md
+++ /dev/null
@@ -1,187 +0,0 @@
-# How-To: Write an fuchsia::modular::Agent in C++
-
-## Overview
-
-An `fuchsia::modular::Agent` is a Peridot component that runs without any direct user interaction.
-The lifetime of a single fuchsia::modular::Agent instance is bounded by its session. It can be
-shared by mods across many stories. In addition to the capabilities provided to all
-Peridot components via `fuchsia::modular::ComponentContext`, an `fuchsia::modular::Agent` is given additional
-capabilities via its `fuchsia::modular::AgentContext`.
-
-See [the simple directory](../simple/) for a complete implementation of
-the `fuchsia::modular::Agent` described here.
-
-## SimpleAgent
-
-`SimpleAgent` is an `fuchsia::modular::Agent` that periodically writes a simple message to
-a `fuchsia::modular::MessageQueue` (a common communication channel).
-
-`SimpleAgent` implements the `Simple` FIDL interface which exposes the
-ability to control which `fuchsia::modular::MessageQueue` the messages will be sent to.
-
-```
-library simple;
-
-[Discoverable]
-interface Simple {
- // Provides the Simple interface with a message queue to which
- // messages will be written periodically.
- 1: SetMessageQueue(string queue_token);
-};
-```
-
-### fuchsia::modular::Agent Initialization
-
-The first step to writing an `fuchsia::modular::Agent` is implementing the initializer:
-
-```c++
-#include <lib/app_driver/cpp/agent_driver.h>
-
-class SimpleAgent {
- public:
- SimpleAgent(AgentHost* const agent_host) {
- ...
- }
-};
-```
-
-The `AgentHost` parameter provides the `fuchsia::modular::Agent` with an `StartupContext`
-and an `fuchsia::modular::AgentContext`.
-
-#### `StartupContext`
-
-`StartupContext` gives the `fuchsia::modular::Agent` access to services provided to it by
-other system components via `incoming_services`. It also allows the `fuchsia::modular::Agent`
-to provide services to other components via `outgoing_services`.
-
-#### `fuchsia::modular::AgentContext`
-
-`fuchsia::modular::AgentContext` is an interface that is exposed to all `Agents`.
-For example, it allows agents to schedule `Task`s that will be executed at
-specific intervals.
-
-`fuchsia::modular::AgentContext` also gives `fuchsia::modular::Agent`s access to `fuchsia::modular::ComponentContext` which is an
-interface that is exposed to all Peridot components (i.e. `fuchsia::modular::Agent` and `Module`).
-For example, `fuchsia::modular::ComponentContext` provides access to `Ledger`, Peridot's cross-device
-storage solution.
-
-### Advertising the `Simple` Interface
-
-In order for the `SimpleAgent` to advertise the `Simple` interface to the system
-it needs to provide it in its `outgoing_services`.
-
-```c++
- SimpleAgent(AgentHost* const agent_host) {
- services_.AddService<Simple>(
- [this](fidl::InterfaceRequest<Simple> request) {
- simple_impl_->Connect(std::move(request));
- });
- }
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> outgoing_services) {
- services_.AddBinding(std::move(outgoing_services));
- }
-
- private:
- // The services namespace that the `Simple` service is added to.
- component::ServiceNamespace services_;
-
- // The implementation of the Simple service.
- std::unique_ptr<SimpleImpl> simple_impl_;
-```
-
-In the initializer above, `SimpleAgent` adds the `Simple` service to its `ServiceNamespace`.
- When `SimpleAgent` receives a `Connect` call, it needs to bind the handle held by `request`
- to the concrete implementation in `services_`. It does this by calling
-`AddBinding(std::move(outgoing_services))`.
-
-Now, when a component connects to the `SimpleAgent`, it will be able to connect
-to the `SimpleInterface` and call methods on it. Those method calls will be
-delegated to the `simple_impl_` per the callback given to `AddService()`.
-
-```c++
-class SimpleImpl : Simple {
- SimpleImpl();
- ~SimpleImpl();
-
- void Connect(fidl::InterfaceRequest<Simple> request);
-
- std::string message_queue_token() const { return token_; }
-
- private:
- // |Simple| interface method.
- void SetMessageQueue(fidl::StringPtr queue_token);
-
- // The bindings to the Simple service.
- fidl::BindingSet<Simple> bindings_;
-
- // The current message queue token.
- std::string token_;
-};
-```
-
-The `SimpleImpl` could be part of the `SimpleAgent` class, but it's good practice
-to separate out the implementation of an `fuchsia::modular::Agent` from the implementation(s) of the
-interface(s) it provides.
-
-## Running the fuchsia::modular::Agent
-
-```c++
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<simple_agent::SimpleAgent> driver(
- context.get(), [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
-```
-
-`AgentDriver` is a helper class that helps manage the `fuchsia::modular::Agent` lifecycle. Here
-it is given a newly created `StartupContext` and a callback that will be
-executed when the `fuchsia::modular::Agent` exits. `AgentDriver` requires `SimpleAgent` to
-implement three methods, one of which is `Connect` which was shown above.
-
-The other two are:
-
-```c++
-void RunTask(const fidl::StringPtr& task_id,
- const std::function<void()>& done) {
- done();
-}
-
-void Terminate(const std::function<void()>& done) { done(); }
-```
-
-`RunTask` is called when a task, scheduled through `fuchsia::modular::AgentContext`'s `ScheduleTask`,
-is triggered.
-
-`Terminate` is called when the framework requests `fuchsia::modular::Agent` to
-exit gracefully.
-
-## Connecting to SimpleAgent
-
-To connect to the `SimpleAgent` from a different component:
-
-```c++
-// The agent is guaranteed to stay alive as long as |agent_controller| stays in scope.
-fuchsia::modular::AgentControllerPtr agent_controller;
-fuchsia::sys::ServiceProviderPtr agent_services;
-SimpleServicePtr agent_service;
-component_context->ConnectToAgent(agent_url,
- agent_services.NewRequest(),
- agent_controller.NewRequest());
-ConnectToService(agent_services.get(), agent_service.NewRequest());
-agent_service->SetMessageQueue(...);
-```
-
-Here the component context is asked to connect to the fuchsia::modular::Agent at `agent_url`, and is
-given a request for the services that the `SimpleAgent` will provide via `agent_services`,
-and a controller for the `fuchsia::modular::Agent` via `agent_controller`.
-
-Then the client connects to the `Simple` interface by invoking `ConnectToService` with
-a request for a new `SimpleServicePtr`. This interface pointer can be used immediately
-to provide the agent with the token for the `fuchsia::modular::MessageQueue` to send messages to.
-
-See the [SimpleModule](how_to_write_a_mod.md) guide for a more in-depth example.
diff --git a/examples/simple/BUILD.gn b/examples/simple/BUILD.gn
deleted file mode 100644
index 278c4b4..0000000
--- a/examples/simple/BUILD.gn
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-import("//peridot/build/executable_package.gni")
-
-executable_package("simple_agent") {
-
- meta = [
- {
- path = "meta/simple_agent.cmx"
- dest = "simple_agent.cmx"
- },
- ]
-
- sources = [
- "simple_agent.cc",
- "simple_impl.cc",
- "simple_impl.h",
- ]
-
- deps = [
- ":interfaces",
- "//garnet/public/lib/component/cpp",
- "//peridot/public/lib/app_driver/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("simple_module") {
-
- meta = [
- {
- path = "meta/simple_module.cmx"
- dest = "simple_module.cmx"
- },
- ]
-
- sources = [
- "simple_module.cc",
- ]
-
- deps = [
- ":interfaces",
- "//garnet/public/lib/component/cpp",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/message_queue/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-fidl("interfaces") {
- cpp_legacy_callbacks = true
-
- name = "fuchsia.modular.examples.simple"
-
- sources = [
- "simple.fidl",
- ]
-}
diff --git a/examples/simple/meta/simple_agent.cmx b/examples/simple/meta/simple_agent.cmx
deleted file mode 100644
index cddecbc..0000000
--- a/examples/simple/meta/simple_agent.cmx
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.examples.simple",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.netconnector.NetConnector",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/examples/simple/meta/simple_module.cmx b/examples/simple/meta/simple_module.cmx
deleted file mode 100644
index ece9e0f..0000000
--- a/examples/simple/meta/simple_module.cmx
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.netconnector.NetConnector",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/examples/simple/simple.fidl b/examples/simple/simple.fidl
deleted file mode 100644
index f789cff..0000000
--- a/examples/simple/simple.fidl
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.examples.simple;
-
-[Discoverable]
-interface Simple {
- // Provides the Simple interface with a message queue to which
- // messages will be written periodically.
- 1: SetMessageQueue(string queue_token);
-};
diff --git a/examples/simple/simple_agent.cc b/examples/simple/simple_agent.cc
deleted file mode 100644
index 2c6a050..0000000
--- a/examples/simple/simple_agent.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-
-#include "peridot/examples/simple/simple_impl.h"
-
-using ::fuchsia::modular::examples::simple::Simple;
-
-namespace simple {
-
-class SimpleAgent {
- public:
- SimpleAgent(modular::AgentHost* const agent_host)
- : simple_impl_(new SimpleImpl) {
- services_.AddService<Simple>(
- [this](fidl::InterfaceRequest<Simple> request) {
- simple_impl_->Connect(std::move(request));
- });
- }
-
- // Called by |AgentDriver| to expose the agent's outgoing services.
- void Connect(
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> outgoing_services) {
- services_.AddBinding(std::move(outgoing_services));
- }
-
- // Called by |AgentDriver| to perform the task with |task_id|.
- void RunTask(const fidl::StringPtr& task_id,
- const std::function<void()>& done) {
- done();
- }
-
- // Called by |AgentDriver| when the agent is to terminate.
- void Terminate(const std::function<void()>& done) { done(); }
-
- private:
- // The services namespace that the `Simple` service is added to.
- component::ServiceNamespace services_;
-
- // The implementation of the Simple service.
- std::unique_ptr<SimpleImpl> simple_impl_;
-};
-
-} // namespace simple
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<simple::SimpleAgent> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/examples/simple/simple_impl.cc b/examples/simple/simple_impl.cc
deleted file mode 100644
index db8f0c0..0000000
--- a/examples/simple/simple_impl.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/examples/simple/simple_impl.h"
-
-using ::fuchsia::modular::examples::simple::Simple;
-
-namespace simple {
-
-SimpleImpl::SimpleImpl() = default;
-
-SimpleImpl::~SimpleImpl() = default;
-
-void SimpleImpl::Connect(fidl::InterfaceRequest<Simple> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void SimpleImpl::SetMessageQueue(std::string queue_token) {
- token_ = queue_token;
-}
-
-} // namespace simple
diff --git a/examples/simple/simple_impl.h b/examples/simple/simple_impl.h
deleted file mode 100644
index cfa3771..0000000
--- a/examples/simple/simple_impl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_EXAMPLES_SIMPLE_SIMPLE_IMPL_H_
-#define PERIDOT_EXAMPLES_SIMPLE_SIMPLE_IMPL_H_
-
-#include <string>
-
-#include <fuchsia/modular/examples/simple/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/macros.h>
-
-namespace simple {
-
-// An implementation of the Simple interface exposed by |SimpleAgent|.
-class SimpleImpl : ::fuchsia::modular::examples::simple::Simple {
- public:
- using Simple = ::fuchsia::modular::examples::simple::Simple;
-
- SimpleImpl();
- ~SimpleImpl() override;
-
- void Connect(fidl::InterfaceRequest<Simple> request);
-
- std::string message_queue_token() const { return token_; }
-
- private:
- // |Simple| interface method.
- void SetMessageQueue(std::string queue_token) override;
-
- // The bindings to the Simple service.
- fidl::BindingSet<Simple> bindings_;
-
- // The current message queue token.
- std::string token_;
-};
-
-} // namespace simple
-
-#endif // PERIDOT_EXAMPLES_SIMPLE_SIMPLE_IMPL_H_
diff --git a/examples/simple/simple_module.cc b/examples/simple/simple_module.cc
deleted file mode 100644
index ab8faab..0000000
--- a/examples/simple/simple_module.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/examples/simple/cpp/fidl.h>
-#include <fuchsia/ui/scenic/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/message_queue/cpp/message_queue_client.h>
-
-using ::fuchsia::modular::examples::simple::SimplePtr;
-
-namespace simple {
-
-class SimpleModule : public fuchsia::ui::app::ViewProvider,
- public fuchsia::ui::viewsv1::ViewProvider {
- public:
- SimpleModule(modular::ModuleHost* const module_host)
- : old_view_provider_binding_(this), view_provider_binding_(this) {
- // Get the component context from the module context.
- fuchsia::modular::ComponentContextPtr component_context;
- module_host->module_context()->GetComponentContext(
- component_context.NewRequest());
-
- // Connect to the agent to retrieve it's outgoing services.
- fuchsia::modular::AgentControllerPtr agent_controller;
- fuchsia::sys::ServiceProviderPtr agent_services;
- component_context->ConnectToAgent("simple_agent",
- agent_services.NewRequest(),
- agent_controller.NewRequest());
-
- // Connect to the SimpleService in the agent's services.
- SimplePtr agent_service;
- component::ConnectToService(agent_services.get(),
- agent_service.NewRequest());
-
- // Request a new message queue from the component context.
- component_context->ObtainMessageQueue("agent_queue",
- message_queue_.NewRequest());
-
- // Register a callback that receives new messages that SimpleAgent sends.
- message_queue_.RegisterReceiver(
- [](std::string msg, fit::function<void()> ack) {
- ack();
- FXL_LOG(INFO) << "new message: " << msg;
- });
-
- // Get the token for the message queue and send it to the agent.
- message_queue_.GetToken(fxl::MakeCopyable(
- [agent_service = std::move(agent_service)](fidl::StringPtr token) {
- agent_service->SetMessageQueue(token);
- }));
- FXL_LOG(INFO) << "Initialized Simple Module.";
- }
-
- SimpleModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>
- view_provider_request)
- : SimpleModule(module_host) {
- view_provider_binding_.Bind(std::move(view_provider_request));
- }
-
- SimpleModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- view_provider_request)
- : SimpleModule(module_host) {
- old_view_provider_binding_.Bind(std::move(view_provider_request));
- }
-
- // Called by ModuleDriver.
- void Terminate(const std::function<void()>& done) { done(); }
-
- private:
- // |fuchsia::ui::app::ViewProvider|
- void CreateView(
- zx::eventpair view_token,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services,
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services)
- override {}
-
- // |fuchsia::ui::viewsv1::ViewProvider|
- void CreateView(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> view_owner,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services) override {
- }
-
- fidl::Binding<fuchsia::ui::viewsv1::ViewProvider> old_view_provider_binding_;
- fidl::Binding<fuchsia::ui::app::ViewProvider> view_provider_binding_;
-
- modular::MessageQueueClient message_queue_;
-};
-
-} // namespace simple
-
-int main(int argc, const char** argv) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<simple::SimpleModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/examples/swap_cpp/BUILD.gn b/examples/swap_cpp/BUILD.gn
deleted file mode 100644
index 4446eab..0000000
--- a/examples/swap_cpp/BUILD.gn
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("swap_module1") {
-
- meta = [
- {
- path = "meta/swap_module1.cmx"
- dest = "swap_module1.cmx"
- },
- ]
-
- sources = [
- "swap_module1.cc",
- ]
- deps = [
- ":module",
- "//peridot/public/lib/app_driver/cpp:app_driver",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-}
-
-executable_package("swap_module2") {
-
- meta = [
- {
- path = "meta/swap_module2.cmx"
- dest = "swap_module2.cmx"
- },
- ]
-
- sources = [
- "swap_module2.cc",
- ]
- deps = [
- ":module",
- "//peridot/public/lib/app_driver/cpp:app_driver",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-}
-
-source_set("module") {
- sources = [
- "module.cc",
- "module.h",
- ]
-
- public_deps = [
- "//peridot/lib/fidl:single_service_app",
- ]
-
- deps = [
- "//garnet/public/lib/ui/base_view/cpp",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- ]
-}
-
-executable_package("swap_recipe") {
-
- meta = [
- {
- path = "meta/swap_recipe.cmx"
- dest = "swap_recipe.cmx"
- },
- ]
-
- sources = [
- "swap_recipe.cc",
- ]
- deps = [
- "//garnet/public/lib/ui/base_view/cpp",
- "//peridot/lib/fidl:single_service_app",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/trace-provider",
- ]
-}
diff --git a/examples/swap_cpp/meta/swap_module1.cmx b/examples/swap_cpp/meta/swap_module1.cmx
deleted file mode 100644
index ece9e0f..0000000
--- a/examples/swap_cpp/meta/swap_module1.cmx
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.netconnector.NetConnector",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/examples/swap_cpp/meta/swap_module2.cmx b/examples/swap_cpp/meta/swap_module2.cmx
deleted file mode 100644
index ece9e0f..0000000
--- a/examples/swap_cpp/meta/swap_module2.cmx
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.netconnector.NetConnector",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/examples/swap_cpp/meta/swap_recipe.cmx b/examples/swap_cpp/meta/swap_recipe.cmx
deleted file mode 100644
index ece9e0f..0000000
--- a/examples/swap_cpp/meta/swap_recipe.cmx
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.netconnector.NetConnector",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/examples/swap_cpp/module.cc b/examples/swap_cpp/module.cc
deleted file mode 100644
index 415bfbd..0000000
--- a/examples/swap_cpp/module.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/examples/swap_cpp/module.h"
-
-#include <lib/component/cpp/startup_context.h>
-#include <utility>
-
-namespace modular_example {
-
-ModuleView::ModuleView(scenic::ViewContext view_context, uint32_t color)
- : V1BaseView(std::move(view_context), "ModuleView"),
- background_node_(session()) {
- scenic::Material background_material(session());
- background_material.SetColor((color >> 16) & 0xff, (color >> 8) & 0xff,
- color & 0xff, (color >> 24) & 0xff);
- background_node_.SetMaterial(background_material);
- parent_node().AddChild(background_node_);
-}
-
-void ModuleView::OnPropertiesChanged(fuchsia::ui::viewsv1::ViewProperties) {
- scenic::Rectangle background_shape(session(), logical_size().width,
- logical_size().height);
- background_node_.SetShape(background_shape);
- background_node_.SetTranslation(logical_size().width * .5f,
- logical_size().height * .5f, 0.f);
- InvalidateScene();
-}
-
-ModuleApp::ModuleApp(component::StartupContext* const startup_context,
- CreateViewCallback create)
- : ViewApp(startup_context), create_(std::move(create)) {}
-
-void ModuleApp::CreateView(
- zx::eventpair view_token,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services,
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services) {
- auto scenic =
- startup_context()
- ->ConnectToEnvironmentService<fuchsia::ui::scenic::Scenic>();
- scenic::ViewContext context = {
- .session_and_listener_request =
- scenic::CreateScenicSessionPtrAndListenerRequest(scenic.get()),
- .view_token = std::move(view_token),
- .incoming_services = std::move(incoming_services),
- .outgoing_services = std::move(outgoing_services),
- .startup_context = startup_context(),
- };
-
- view_.reset(create_(std::move(context)));
-}
-
-} // namespace modular_example
diff --git a/examples/swap_cpp/module.h b/examples/swap_cpp/module.h
deleted file mode 100644
index 40f275f..0000000
--- a/examples/swap_cpp/module.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_EXAMPLES_SWAP_CPP_MODULE_H_
-#define PERIDOT_EXAMPLES_SWAP_CPP_MODULE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/ui/base_view/cpp/v1_base_view.h>
-#include <zx/eventpair.h>
-
-#include "peridot/lib/fidl/single_service_app.h"
-
-namespace modular_example {
-
-class ModuleView : public scenic::V1BaseView {
- public:
- explicit ModuleView(scenic::ViewContext view_context, uint32_t color);
-
- private:
- // |scenic::V1BaseView|
- void OnPropertiesChanged(
- fuchsia::ui::viewsv1::ViewProperties old_properties) override;
-
- scenic::ShapeNode background_node_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ModuleView);
-};
-
-class ModuleApp : public modular::ViewApp {
- public:
- using CreateViewCallback =
- std::function<scenic::V1BaseView*(scenic::ViewContext view_context)>;
-
- explicit ModuleApp(component::StartupContext* const startup_context,
- CreateViewCallback create);
-
- private:
- // |ViewApp|
- void CreateView(
- zx::eventpair view_token,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services,
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services)
- override;
-
- CreateViewCallback create_;
- std::unique_ptr<scenic::V1BaseView> view_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ModuleApp);
-};
-
-} // namespace modular_example
-
-#endif // PERIDOT_EXAMPLES_SWAP_CPP_MODULE_H_
diff --git a/examples/swap_cpp/swap_module1.cc b/examples/swap_cpp/swap_module1.cc
deleted file mode 100644
index af6f889..0000000
--- a/examples/swap_cpp/swap_module1.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <trace-provider/provider.h>
-
-#include "peridot/examples/swap_cpp/module.h"
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- trace::TraceProvider trace_provider(loop.dispatcher());
-
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AppDriver<modular_example::ModuleApp> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<modular_example::ModuleApp>(
- context.get(),
- [](scenic::ViewContext view_context) {
- return new modular_example::ModuleView(std::move(view_context),
- 0xFF00FFFF);
- }),
- [&loop] { loop.Quit(); });
-
- loop.Run();
- return 0;
-}
diff --git a/examples/swap_cpp/swap_module2.cc b/examples/swap_cpp/swap_module2.cc
deleted file mode 100644
index 2f4ed3b..0000000
--- a/examples/swap_cpp/swap_module2.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <trace-provider/provider.h>
-
-#include "peridot/examples/swap_cpp/module.h"
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- trace::TraceProvider trace_provider(loop.dispatcher());
-
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AppDriver<modular_example::ModuleApp> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<modular_example::ModuleApp>(
- context.get(),
- [](scenic::ViewContext view_context) {
- return new modular_example::ModuleView(std::move(view_context),
- 0xFFFF00FF);
- }),
- [&loop] { loop.Quit(); });
-
- loop.Run();
- return 0;
-}
diff --git a/examples/swap_cpp/swap_recipe.cc b/examples/swap_cpp/swap_recipe.cc
deleted file mode 100644
index abee4e3..0000000
--- a/examples/swap_cpp/swap_recipe.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <array>
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/ui/base_view/cpp/v1_base_view.h>
-#include <trace-provider/provider.h>
-#include <zx/eventpair.h>
-
-#include "peridot/lib/fidl/single_service_app.h"
-
-namespace {
-
-constexpr uint32_t kChildKey = 1;
-constexpr int kSwapSeconds = 5;
-constexpr std::array<const char*, 2> kModuleQueries{
- {"swap_module1", "swap_module2"}};
-
-class RecipeView : public scenic::V1BaseView {
- public:
- explicit RecipeView(scenic::ViewContext view_context)
- : V1BaseView(std::move(view_context), "RecipeView") {}
-
- ~RecipeView() override = default;
-
- void SetChild(zx::eventpair view_token) {
- if (host_node_) {
- GetViewContainer()->RemoveChild2(kChildKey, zx::eventpair());
- host_node_->Detach();
- host_node_.reset();
- }
-
- if (view_token) {
- host_node_ = std::make_unique<scenic::EntityNode>(session());
-
- zx::eventpair host_import_token;
- host_node_->ExportAsRequest(&host_import_token);
- parent_node().AddChild(*host_node_);
-
- GetViewContainer()->AddChild2(kChildKey, std::move(view_token),
- std::move(host_import_token));
- }
- }
-
- private:
- // |scenic::V1BaseView|
- void OnPropertiesChanged(fuchsia::ui::viewsv1::ViewProperties) override {
- if (host_node_) {
- auto child_properties = fuchsia::ui::viewsv1::ViewProperties::New();
- fidl::Clone(properties(), child_properties.get());
- GetViewContainer()->SetChildProperties(kChildKey,
- std::move(child_properties));
- }
- }
-
- std::unique_ptr<scenic::EntityNode> host_node_;
-};
-
-class RecipeApp : public modular::ViewApp {
- public:
- RecipeApp(component::StartupContext* const startup_context)
- : ViewApp(startup_context) {
- startup_context->ConnectToEnvironmentService(module_context_.NewRequest());
- SwapModule();
- }
-
- ~RecipeApp() override = default;
-
- private:
- // |ViewApp|
- void CreateView(
- zx::eventpair view_token,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services,
- fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services)
- override {
- auto scenic =
- startup_context()
- ->ConnectToEnvironmentService<fuchsia::ui::scenic::Scenic>();
- scenic::ViewContext view_context = {
- .session_and_listener_request =
- scenic::CreateScenicSessionPtrAndListenerRequest(scenic.get()),
- .view_token = std::move(view_token),
- .incoming_services = std::move(incoming_services),
- .outgoing_services = std::move(outgoing_services),
- .startup_context = startup_context(),
- };
- view_ = std::make_unique<RecipeView>(std::move(view_context));
- SetChild();
- }
-
- void SwapModule() {
- StartModule(kModuleQueries[query_index_]);
- query_index_ = (query_index_ + 1) % kModuleQueries.size();
- async::PostDelayedTask(async_get_default_dispatcher(),
- [this] { SwapModule(); }, zx::sec(kSwapSeconds));
- }
-
- void StartModule(const std::string& module_query) {
- if (module_) {
- module_->Stop([this, module_query] {
- module_.Unbind();
- module_view_.Unbind();
- StartModule(module_query);
- });
- return;
- }
-
- // This module is named after its URL.
- fuchsia::modular::Intent intent;
- intent.handler = module_query;
- module_context_->EmbedModule(
- module_query, std::move(intent), module_.NewRequest(),
- module_view_.NewRequest(),
- [](const fuchsia::modular::StartModuleStatus&) {});
- SetChild();
- }
-
- void SetChild() {
- if (view_ && module_view_) {
- view_->SetChild(
- zx::eventpair(module_view_.Unbind().TakeChannel().release()));
- }
- }
-
- fuchsia::modular::ModuleContextPtr module_context_;
- fuchsia::modular::ModuleControllerPtr module_;
- fuchsia::ui::viewsv1token::ViewOwnerPtr module_view_;
- std::unique_ptr<RecipeView> view_;
-
- int query_index_ = 0;
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- trace::TraceProvider trace_provider(loop.dispatcher());
-
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AppDriver<RecipeApp> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<RecipeApp>(context.get()), [&loop] { loop.Quit(); });
-
- loop.Run();
- return 0;
-}
diff --git a/examples/todo_cpp/BUILD.gn b/examples/todo_cpp/BUILD.gn
deleted file mode 100644
index 206ad3c..0000000
--- a/examples/todo_cpp/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("todo_cpp") {
-
- meta = [
- {
- path = "meta/todo_cpp.cmx"
- dest = "todo_cpp.cmx"
- },
- ]
-
- deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/fit",
- ]
-
- sources = [
- "generator.cc",
- "generator.h",
- "todo.cc",
- "todo.h",
- ]
-}
diff --git a/examples/todo_cpp/README.md b/examples/todo_cpp/README.md
deleted file mode 100644
index 36ef755..0000000
--- a/examples/todo_cpp/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# todo (headless)
-
-Example module that uses Ledger to store internal data.
-
-To run the module, run:
-
-```
-basemgr --base_shell=dev_base_shell --session_shell=dev_session_shell --session_shell_args=--root_module=example_todo_headless
-```
-
-This is a headless module, taking no input and writing the output to stdout.
-
-The module keeps a list of todo items in a Ledger page, randomly adds and
-removes items, and prints the state after each modification. Items generated by
-each instance are tagged with a unique tag. To observe the application running
-on multiple devices and synchronizing the state using Ledger, [set up Cloud
-Sync](https://fuchsia.googlesource.com/ledger/+/HEAD/docs/user_guide.md#Setup)
-and run the module on each device.
-
-Example output:
-
-```
-[00053.199] 02933.02949> --- To Do ---
-[00053.199] 02933.02949> [ 18355 ] write a spec for the law of gravity
-[00053.199] 02933.02949> [ 24673 ] celebrate hipster bars south of Pigalle
-[00053.200] 02933.02949> [ 24673 ] solve the society
-[00053.200] 02933.02949> [ 18355 ] draw the pyramids
-[00053.200] 02933.02949> [ 24673 ] evaluate a better way forward
-```
diff --git a/examples/todo_cpp/generator.cc b/examples/todo_cpp/generator.cc
deleted file mode 100644
index 396d7aa..0000000
--- a/examples/todo_cpp/generator.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/examples/todo_cpp/generator.h"
-
-#include <iostream>
-
-#include <lib/fxl/strings/concatenate.h>
-
-namespace todo {
-Generator::Generator(std::default_random_engine* rng) : rng_(rng) {
- actions_ = {
- "acquire", "cancel", "consider",
- "draw", "evaluate", "celebrate",
- "find", "identify", "meet with",
- "plan", "solve", "study",
- "talk to", "think about", "write an article about",
- "check out", "order", "write a spec for",
- "order", "track down", "memorize",
- "git checkout",
- };
- action_distribution_ =
- std::uniform_int_distribution<>(0, actions_.size() - 1);
-
- objects_ = {
- "Christopher Columbus",
- "PHP",
- "a better way forward",
- "a glass of wine",
- "a good book on C++",
- "a huge simulation we are all part of",
- "a nice dinner out",
- "a sheep",
- "an AZERTY keyboard",
- "hipster bars south of Pigalle",
- "kittens",
- "manganese",
- "more cheese",
- "some bugs",
- "staticly-typed programming languages",
- "the cryptographic primitives",
- "the espresso machine",
- "the law of gravity",
- "the neighbor",
- "the pyramids",
- "the society",
- "velocity",
- };
- object_distribution_ =
- std::uniform_int_distribution<>(0, objects_.size() - 1);
-
- auto tag_distribution = std::uniform_int_distribution<>(10'000, 99'999);
- tag_ =
- fxl::Concatenate({"[ ", std::to_string(tag_distribution(*rng_)), " ] "});
- std::cout << "Items generated by this instace are tagged with: " << tag_
- << std::endl;
-}
-Generator::~Generator() {}
-
-std::string Generator::Generate() {
- return fxl::Concatenate({tag_, actions_[action_distribution_(*rng_)], " ",
- objects_[object_distribution_(*rng_)]});
-}
-
-} // namespace todo
diff --git a/examples/todo_cpp/generator.h b/examples/todo_cpp/generator.h
deleted file mode 100644
index 169890a..0000000
--- a/examples/todo_cpp/generator.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_EXAMPLES_TODO_CPP_GENERATOR_H_
-#define PERIDOT_EXAMPLES_TODO_CPP_GENERATOR_H_
-
-#include <random>
-#include <string>
-#include <vector>
-
-#include <lib/fxl/macros.h>
-
-namespace todo {
-
-class Generator {
- public:
- explicit Generator(std::default_random_engine* rng);
- ~Generator();
-
- std::string Generate();
-
- private:
- std::default_random_engine* rng_;
- std::uniform_int_distribution<> action_distribution_;
- std::vector<std::string> actions_;
- std::uniform_int_distribution<> object_distribution_;
- std::vector<std::string> objects_;
- std::string tag_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(Generator);
-};
-
-} // namespace todo
-
-#endif // PERIDOT_EXAMPLES_TODO_CPP_GENERATOR_H_
diff --git a/examples/todo_cpp/meta/todo_cpp.cmx b/examples/todo_cpp/meta/todo_cpp.cmx
deleted file mode 100644
index ece9e0f..0000000
--- a/examples/todo_cpp/meta/todo_cpp.cmx
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "features": [],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.net.oldhttp.HttpService",
- "fuchsia.netconnector.NetConnector",
- "fuchsia.sys.Launcher",
- "fuchsia.tracelink.Registry"
- ]
- }
-}
diff --git a/examples/todo_cpp/todo.cc b/examples/todo_cpp/todo.cc
deleted file mode 100644
index 993ebee..0000000
--- a/examples/todo_cpp/todo.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/examples/todo_cpp/todo.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <algorithm>
-#include <iostream>
-
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_printf.h>
-#include <lib/fxl/time/time_delta.h>
-
-namespace todo {
-
-namespace {
-
-const double kMeanListSize = 7.0;
-const double kListSizeStdDev = 2.0;
-const int kMinDelaySeconds = 1;
-const int kMaxDelaySeconds = 5;
-
-std::string ToString(const fuchsia::mem::Buffer& vmo) {
- std::string ret;
- if (!fsl::StringFromVmo(vmo, &ret)) {
- FXL_DCHECK(false);
- }
- return ret;
-}
-
-fidl::VectorPtr<uint8_t> ToArray(const std::string& val) {
- auto ret = fidl::VectorPtr<uint8_t>::New(val.size());
- memcpy(ret->data(), val.data(), val.size());
- return ret;
-}
-
-Key MakeKey() {
- return ToArray(fxl::StringPrintf("%120ld-%u", time(nullptr), rand()));
-}
-
-std::function<void(zx_status_t)> NewErrorHandler(fit::closure quit_callback,
- std::string description) {
- return [description, &quit_callback](zx_status_t status) {
- FXL_LOG(ERROR) << description << " diconnected: " << status;
- quit_callback();
- };
-}
-
-std::function<void(fuchsia::ledger::Status)> HandleResponse(
- fit::closure quit_callback, std::string description) {
- return [description, &quit_callback](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << description << " failed";
- quit_callback();
- }
- };
-}
-
-void GetEntries(fuchsia::ledger::PageSnapshotPtr snapshot,
- std::vector<fuchsia::ledger::Entry> entries,
- std::unique_ptr<fuchsia::ledger::Token> token,
- std::function<void(fuchsia::ledger::Status,
- std::vector<fuchsia::ledger::Entry>)>
- callback) {
- fuchsia::ledger::PageSnapshot* snapshot_ptr = snapshot.get();
- snapshot_ptr->GetEntries(
- fidl::VectorPtr<uint8_t>::New(0), std::move(token),
- fxl::MakeCopyable(
- [snapshot = std::move(snapshot), entries = std::move(entries),
- callback = std::move(callback)](fuchsia::ledger::Status status,
- auto new_entries,
- auto next_token) mutable {
- if (status != fuchsia::ledger::Status::OK &&
- status != fuchsia::ledger::Status::PARTIAL_RESULT) {
- callback(status, {});
- return;
- }
- for (size_t i = 0; i < new_entries.size(); ++i) {
- entries.push_back(std::move(new_entries.at(i)));
- }
- if (status == fuchsia::ledger::Status::OK) {
- callback(fuchsia::ledger::Status::OK, std::move(entries));
- return;
- }
- GetEntries(std::move(snapshot), std::move(entries),
- std::move(next_token), std::move(callback));
- }));
-}
-
-void GetEntries(fuchsia::ledger::PageSnapshotPtr snapshot,
- std::function<void(fuchsia::ledger::Status,
- std::vector<fuchsia::ledger::Entry>)>
- callback) {
- GetEntries(std::move(snapshot), {}, nullptr, std::move(callback));
-}
-
-} // namespace
-
-TodoApp::TodoApp(async::Loop* loop)
- : loop_(loop),
- rng_(time(nullptr)),
- size_distribution_(kMeanListSize, kListSizeStdDev),
- delay_distribution_(kMinDelaySeconds, kMaxDelaySeconds),
- generator_(&rng_),
- context_(component::StartupContext::CreateFromStartupInfo()),
- page_watcher_binding_(this) {
- context_->ConnectToEnvironmentService(module_context_.NewRequest());
- module_context_->GetComponentContext(component_context_.NewRequest());
- ledger_.set_error_handler(
- NewErrorHandler([this] { loop_->Quit(); }, "Ledger"));
- component_context_->GetLedger(ledger_.NewRequest());
- ledger_->GetRootPage(
- page_.NewRequest(),
- HandleResponse([this] { loop_->Quit(); }, "GetRootPage"));
-
- fuchsia::ledger::PageSnapshotPtr snapshot;
- page_->GetSnapshot(snapshot.NewRequest(), fidl::VectorPtr<uint8_t>::New(0),
- page_watcher_binding_.NewBinding(),
- HandleResponse([this] { loop_->Quit(); }, "Watch"));
- List(std::move(snapshot));
-
- async::PostTask(loop_->dispatcher(), [this] { Act(); });
-}
-
-void TodoApp::Terminate() { loop_->Quit(); }
-
-void TodoApp::OnChange(fuchsia::ledger::PageChange /*page_change*/,
- fuchsia::ledger::ResultState result_state,
- OnChangeCallback callback) {
- if (result_state != fuchsia::ledger::ResultState::PARTIAL_STARTED &&
- result_state != fuchsia::ledger::ResultState::COMPLETED) {
- // Only request the entries list once, on the first OnChange call.
- callback(nullptr);
- return;
- }
-
- fuchsia::ledger::PageSnapshotPtr snapshot;
- callback(snapshot.NewRequest());
- List(std::move(snapshot));
-}
-
-void TodoApp::List(fuchsia::ledger::PageSnapshotPtr snapshot) {
- GetEntries(std::move(snapshot),
- [this](fuchsia::ledger::Status status, auto entries) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "GetEntries failed";
- loop_->Quit();
- return;
- }
-
- std::cout << "--- To Do ---" << std::endl;
- for (auto& entry : entries) {
- std::cout << (entry.value ? ToString(*entry.value) : "<empty>")
- << std::endl;
- }
- std::cout << "---" << std::endl;
- });
-}
-
-void TodoApp::GetKeys(std::function<void(std::vector<Key>)> callback) {
- fuchsia::ledger::PageSnapshotPtr snapshot;
- page_->GetSnapshot(snapshot.NewRequest(), {}, nullptr,
- HandleResponse([this] { loop_->Quit(); }, "GetSnapshot"));
-
- fuchsia::ledger::PageSnapshot* snapshot_ptr = snapshot.get();
- snapshot_ptr->GetKeys({}, nullptr,
- fxl::MakeCopyable([snapshot = std::move(snapshot), callback](
- fuchsia::ledger::Status status, auto keys,
- auto next_token) { callback(std::move(keys)); }));
-}
-
-void TodoApp::AddNew() {
- page_->Put(MakeKey(), ToArray(generator_.Generate()),
- HandleResponse([this] { loop_->Quit(); }, "Put"));
-}
-
-void TodoApp::DeleteOne(std::vector<Key> keys) {
- FXL_DCHECK(keys.size());
- std::uniform_int_distribution<> distribution(0, keys.size() - 1);
- page_->Delete(std::move(keys.at(distribution(rng_))),
- HandleResponse([this] { loop_->Quit(); }, "Delete"));
-}
-
-void TodoApp::Act() {
- GetKeys([this](std::vector<Key> keys) {
- size_t target_size = std::round(size_distribution_(rng_));
- if (keys.size() > std::max(static_cast<size_t>(0), target_size)) {
- DeleteOne(std::move(keys));
- } else {
- AddNew();
- }
- });
- zx::duration delay = zx::sec(delay_distribution_(rng_));
- async::PostDelayedTask(
- loop_->dispatcher(), [this] { Act(); }, delay);
-}
-
-} // namespace todo
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- todo::TodoApp app(&loop);
- loop.Run();
- return 0;
-}
diff --git a/examples/todo_cpp/todo.h b/examples/todo_cpp/todo.h
deleted file mode 100644
index 2bd129c..0000000
--- a/examples/todo_cpp/todo.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_EXAMPLES_TODO_CPP_TODO_H_
-#define PERIDOT_EXAMPLES_TODO_CPP_TODO_H_
-
-#include <random>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/examples/todo_cpp/generator.h"
-
-namespace todo {
-
-using Key = std::vector<uint8_t>;
-
-class TodoApp : public fuchsia::ledger::PageWatcher,
- fuchsia::modular::Lifecycle {
- public:
- TodoApp(async::Loop* loop);
-
- // fuchsia::ledger::PageWatcher:
- void OnChange(fuchsia::ledger::PageChange page_change,
- fuchsia::ledger::ResultState result_state,
- OnChangeCallback callback) override;
-
- private:
- // |modular.fuchsia::modular::Lifecycle|
- void Terminate() override;
-
- void List(fuchsia::ledger::PageSnapshotPtr snapshot);
-
- void GetKeys(std::function<void(std::vector<Key>)> callback);
-
- void AddNew();
-
- void DeleteOne(std::vector<Key> keys);
-
- void Act();
-
- async::Loop* const loop_;
- std::default_random_engine rng_;
- std::normal_distribution<> size_distribution_;
- std::uniform_int_distribution<> delay_distribution_;
- Generator generator_;
- std::unique_ptr<component::StartupContext> context_;
- fidl::InterfacePtr<fuchsia::modular::ModuleContext> module_context_;
- fuchsia::modular::ComponentContextPtr component_context_;
- fuchsia::ledger::LedgerPtr ledger_;
- fidl::Binding<fuchsia::ledger::PageWatcher> page_watcher_binding_;
- fuchsia::ledger::PagePtr page_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TodoApp);
-};
-
-} // namespace todo
-
-#endif // PERIDOT_EXAMPLES_TODO_CPP_TODO_H_
diff --git a/infra/config/README.md b/infra/config/README.md
deleted file mode 100644
index c036d61..0000000
--- a/infra/config/README.md
+++ /dev/null
@@ -1 +0,0 @@
-This directory contains configuration files for infra services.
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg
deleted file mode 100644
index 96a4d82..0000000
--- a/infra/config/cq.cfg
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# See http://luci-config.appspot.com/schemas/projects/refs:cq.cfg for the
-# documentation of this file format.
-
-version: 1
-cq_name: "modular"
-cq_status_url: "https://fuchsia-cq-status.appspot.com"
-git_repo_url: "https://fuchsia.googlesource.com/modular"
-
-gerrit {}
-
-verifiers {
- try_job {
- buckets {
- name: "luci.modular.ci",
- builders {
- name: "Linux x86-64 Debug"
- }
- builders {
- name: "Linux x86-64 Release"
- }
- builders {
- name: "Linux arm64 Debug"
- }
- builders {
- name: "Linux arm64 Release"
- }
- }
- }
- gerrit_cq_ability {
- committer_list: "project-fuchsia-committers"
- dry_run_access_list: "project-fuchsia-tryjob-access"
- }
- sign_cla {}
-}
diff --git a/lib/BUILD.gn b/lib/BUILD.gn
deleted file mode 100644
index 7b61a8b..0000000
--- a/lib/BUILD.gn
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-import("//build/package.gni")
-
-executable("peridot_lib_unittests") {
- testonly = true
-
- deps = [
- "//peridot/lib/commit_pack:unittests",
- "//peridot/lib/convert:unittests",
- "//peridot/lib/fidl:unittests",
- "//peridot/lib/firebase:unittests",
- "//peridot/lib/firebase_auth:unittests",
- "//peridot/lib/firebase_auth/testing:unittests",
- "//peridot/lib/ledger_client:unittests",
- "//peridot/lib/module_manifest:unittests",
- "//peridot/lib/rng:unittests",
- "//peridot/lib/scoped_tmpfs:unittests",
- "//peridot/lib/session_shell_settings:unittests",
- "//peridot/lib/socket:unittests",
- "//peridot/lib/util:unittests",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-fidl("maxwell_internal") {
- cpp_legacy_callbacks = true
-
- name = "fuchsia.maxwell.internal"
-
- sources = [
- "module_manifest_source/fidl/module_package_indexer.fidl",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
diff --git a/lib/MAINTAINERS b/lib/MAINTAINERS
deleted file mode 100644
index d0dd525..0000000
--- a/lib/MAINTAINERS
+++ /dev/null
@@ -1,3 +0,0 @@
-mesch@google.com
-qsr@google.com
-thatguy@google.com
diff --git a/lib/base64url/BUILD.gn b/lib/base64url/BUILD.gn
deleted file mode 100644
index a85417a..0000000
--- a/lib/base64url/BUILD.gn
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- "//peridot/bin/*",
- "//peridot/lib/*",
-]
-
-source_set("base64url") {
- sources = [
- "base64url.cc",
- "base64url.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- ]
-
- deps = [
- "//peridot/third_party/modp_b64",
- ]
-}
diff --git a/lib/base64url/base64url.cc b/lib/base64url/base64url.cc
deleted file mode 100644
index 8a5fe41..0000000
--- a/lib/base64url/base64url.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/base64url/base64url.h"
-
-#include <lib/fxl/logging.h>
-
-#include "peridot/third_party/modp_b64/modp_b64.h"
-
-namespace base64url {
-
-std::string Base64UrlEncode(fxl::StringView input) {
- std::string output;
- size_t output_length = modp_b64_encode_strlen(input.size());
- // In C++11, std::string guarantees that output[output.size()] is
- // legal and points to a '\0' character. The last byte of modp_b64_encode() is
- // a '\0' that will override output[output.size()].
- output.resize(output_length);
- size_t written = modp_b64_encode(&output[0], input.data(), input.size());
- FXL_DCHECK(output_length == written);
- return output;
-}
-
-bool Base64UrlDecode(fxl::StringView input, std::string* output) {
- std::string tmp_output;
- size_t output_maxlength = modp_b64_decode_len(input.size());
- tmp_output.resize(output_maxlength);
- size_t output_length =
- modp_b64_decode(&tmp_output[0], input.data(), input.size());
- if (output_length == MODP_B64_ERROR) {
- return false;
- }
- tmp_output.resize(output_length);
- output->swap(tmp_output);
- return true;
-}
-
-} // namespace base64url
diff --git a/lib/base64url/base64url.h b/lib/base64url/base64url.h
deleted file mode 100644
index 363adcb..0000000
--- a/lib/base64url/base64url.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_BASE64URL_BASE64URL_H_
-#define PERIDOT_LIB_BASE64URL_BASE64URL_H_
-
-#include <string>
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace base64url {
-
-// Encodes the input string in base64url.
-std::string Base64UrlEncode(fxl::StringView input);
-
-// Decodes the base64url input string. Returns true if successful and false
-// otherwise. The output string is only modified if successful. The decoding can
-// be done in-place.
-bool Base64UrlDecode(fxl::StringView input, std::string* output);
-
-} // namespace base64url
-
-#endif // PERIDOT_LIB_BASE64URL_BASE64URL_H_
diff --git a/lib/bound_set/BUILD.gn b/lib/bound_set/BUILD.gn
deleted file mode 100644
index d466527..0000000
--- a/lib/bound_set/BUILD.gn
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("bound_set") {
- sources = [
- "bound_set.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- ]
-}
diff --git a/lib/bound_set/bound_set.h b/lib/bound_set/bound_set.h
deleted file mode 100644
index ee83781..0000000
--- a/lib/bound_set/bound_set.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_BOUND_SET_BOUND_SET_H_
-#define PERIDOT_LIB_BOUND_SET_BOUND_SET_H_
-
-#include <vector>
-
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-// "Specialization" (overload) covering unique_ptr.
-template <typename T>
-T* GetFidlType(std::unique_ptr<T>* p) {
- return p->get();
-}
-
-// General implementation intended to cover Binding and StrongBinding.
-template <typename FidlType, typename UniqueType = FidlType*>
-UniqueType Identify(FidlType* binding) {
- return binding;
-}
-
-// An extensible/derivable InterfacePtrSet/(Strong)BindingSet that contains a
-// collection of objects of type T that contain FidlTypes (e.g. InterfacePtr,
-// Binding, or StrongBinding). Elements are automatically removed from the
-// collection and destroyed when their associated Channel experiences a
-// connection error. When the set is destroyed all of the Channels will be
-// closed.
-//
-// Unlike the Fidl library InterfacePtrSet and (Strong)BindingSet, this class
-// does not prevent further mutations to the underlying Fidl type. For well-
-// defined behavior, the Fidl types should not be modified after being added to
-// the set.
-//
-// Template parameters:
-// * FidlType - the Fidl type governing each element of the collection, e.g.
-// InterfacePtr, Binding, or StrongBinding
-// * T - the element type of the collection
-// * GetFidlType - a function that extracts the FidlType from an element of the
-// collection. Defaults to the identity function, which only works if T =
-// FidlType.
-// * UniqueType - a type that uniquely identifies a FidlType in the collection.
-// For InterfacePtrs, this is a pointer to the interface. For bindings, this is
-// the pointer to the binding.
-// * Identify - a function that derives a UniqueType from a FidlType. Defaults
-// behave as described at UniqueType.
-template <typename FidlType, typename T = FidlType,
- FidlType* GetFidlType(T*) = GetFidlType, typename UniqueType = void*,
- UniqueType Identify(FidlType*) = Identify>
-class BoundSet {
- public:
- typedef typename std::vector<T>::iterator iterator;
- BoundSet() {}
- virtual ~BoundSet() {}
-
- // |ptr| must be bound to a channel.
- template <typename... _Args>
- T* emplace(_Args&&... __args) {
- elements_.emplace_back(std::forward<_Args>(__args)...);
- T* const c = &elements_.back();
- FidlType* const m = GetFidlType(c);
- FXL_CHECK(m->is_bound());
- UniqueType const id = Identify(m);
- // Set the connection error handler for the newly added item to be a
- // function that will erase it from the vector.
- m->set_error_handler(
- [this, id](zx_status_t status) { OnConnectionError(id); });
- return c;
- }
-
- UniqueType GetId(T* object) { return Identify(GetFidlType(object)); }
-
- // Removes the element at the given iterator. This effectively closes the pipe
- // there if open, but it does not call OnConnectionError.
- iterator erase(iterator it) { return elements_.erase(it); }
- iterator erase(UniqueType id) {
- auto it = Find(id);
- FXL_CHECK(it != elements_.end());
- return elements_.erase(it);
- }
-
- // Closes the Channel associated with each of the items in this set and
- // clears the set. This does not call OnConnectionError for every interface in
- // the set.
- void clear() { elements_.clear(); }
- bool empty() const { return elements_.empty(); }
- size_t size() const { return elements_.size(); }
-
- iterator begin() { return elements_.begin(); }
- iterator end() { return elements_.end(); }
-
- protected:
- virtual void OnConnectionError(UniqueType id) { erase(id); }
-
- private:
- iterator Find(UniqueType id) {
- return std::find_if(elements_.begin(), elements_.end(), [this, id](T& e) {
- return Identify(GetFidlType(&e)) == id;
- });
- }
-
- std::vector<T> elements_;
-};
-
-// Convenience alias of BoundSet to handle non-movable FIDL types, like Bindings
-// (and the mythical StrongBinding).
-//
-// Note that the default T here must be a unique_ptr rather than the FIDL type
-// itself since these FIDL types are not movable.
-template <typename FidlType, typename T = std::unique_ptr<FidlType>,
- FidlType* GetFidlType(T*) = GetFidlType>
-using BoundNonMovableSet = BoundSet<FidlType, T, GetFidlType, FidlType*>;
-
-template <typename Interface,
- typename T = std::unique_ptr<fidl::InterfacePtr<Interface>>,
- fidl::InterfacePtr<Interface>* GetFidlType(T*) = GetFidlType>
-using BoundPtrSet =
- BoundNonMovableSet<fidl::InterfacePtr<Interface>, T, GetFidlType>;
-
-// Convenience alias of BoundSet to handle Binding containers.
-template <typename Interface,
- typename T = std::unique_ptr<fidl::Binding<Interface>>,
- fidl::Binding<Interface>* GetFidlType(T*) = GetFidlType>
-using BindingSet = BoundNonMovableSet<fidl::Binding<Interface>, T, GetFidlType>;
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_BOUND_SET_BOUND_SET_H_
diff --git a/lib/commit_pack/BUILD.gn b/lib/commit_pack/BUILD.gn
deleted file mode 100644
index 2c785e6..0000000
--- a/lib/commit_pack/BUILD.gn
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-flatbuffer("commit_pack_flatbuffer") {
- sources = [
- "//peridot/public/fidl/fuchsia.ledger.cloud/serialized_commits.fbs",
- ]
-}
-
-source_set("commit_pack") {
- sources = [
- "commit_pack.cc",
- "commit_pack.h",
- ]
-
- deps = [
- ":commit_pack_flatbuffer",
- "//peridot/lib/convert",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.ledger.cloud",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "commit_pack_unittest.cc",
- ]
-
- deps = [
- ":commit_pack",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/commit_pack/commit_pack.cc b/lib/commit_pack/commit_pack.cc
deleted file mode 100644
index 1b00de5..0000000
--- a/lib/commit_pack/commit_pack.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/lib/convert/convert.h"
-#include "peridot/public/fidl/fuchsia.ledger.cloud/serialized_commits_generated.h"
-
-namespace cloud_provider {
-
-bool operator==(const CommitPackEntry& lhs, const CommitPackEntry& rhs) {
- return lhs.id == rhs.id && lhs.data == rhs.data;
-}
-
-bool EncodeCommitPack(std::vector<CommitPackEntry> commits,
- CommitPack* commit_pack) {
- FXL_DCHECK(commit_pack);
- flatbuffers::FlatBufferBuilder builder;
-
- auto entries_offsets = builder.CreateVector(
- commits.size(),
- static_cast<std::function<flatbuffers::Offset<SerializedCommit>(size_t)>>(
- [&builder, &commits](size_t i) {
- const auto& entry = commits[i];
- return CreateSerializedCommit(
- builder, convert::ToFlatBufferVector(&builder, entry.id),
- convert::ToFlatBufferVector(&builder, entry.data));
- }));
-
- builder.Finish(CreateSerializedCommits(builder, entries_offsets));
- return fsl::VmoFromString(convert::ToStringView(builder),
- &commit_pack->buffer);
-}
-
-bool DecodeCommitPack(const CommitPack& commit_pack,
- std::vector<CommitPackEntry>* commits) {
- FXL_DCHECK(commits);
- std::string data;
- if (!fsl::StringFromVmo(commit_pack.buffer, &data)) {
- return false;
- }
-
- flatbuffers::Verifier verifier(
- reinterpret_cast<const unsigned char*>(data.data()), data.size());
- if (!VerifySerializedCommitsBuffer(verifier)) {
- return false;
- }
-
- const SerializedCommits* serialized_commits =
- GetSerializedCommits(reinterpret_cast<const unsigned char*>(data.data()));
-
- std::vector<CommitPackEntry> result;
- result.reserve(serialized_commits->commits()->size());
-
- for (const auto* serialized_commit : *(serialized_commits->commits())) {
- result.push_back({convert::ToString(serialized_commit->id()),
- convert::ToString(serialized_commit->data())});
- }
-
- commits->swap(result);
- return true;
-}
-
-} // namespace cloud_provider
diff --git a/lib/commit_pack/commit_pack.h b/lib/commit_pack/commit_pack.h
deleted file mode 100644
index f303fc1..0000000
--- a/lib/commit_pack/commit_pack.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_COMMIT_PACK_COMMIT_PACK_H_
-#define PERIDOT_LIB_COMMIT_PACK_COMMIT_PACK_H_
-
-#include <string>
-#include <vector>
-
-#include <fuchsia/ledger/cloud/cpp/fidl.h>
-
-namespace cloud_provider {
-
-using CommitPack = fuchsia::ledger::cloud::CommitPack;
-
-// Represents a single commit to be encoded in the commit pack.
-struct CommitPackEntry {
- std::string id;
- std::string data;
-};
-
-bool operator==(const CommitPackEntry& lhs, const CommitPackEntry& rhs);
-
-bool EncodeCommitPack(std::vector<CommitPackEntry> commits,
- CommitPack* commit_pack);
-
-bool DecodeCommitPack(const CommitPack& commit_pack,
- std::vector<CommitPackEntry>* commits);
-
-} // namespace cloud_provider
-
-#endif // PERIDOT_LIB_COMMIT_PACK_COMMIT_PACK_H_
diff --git a/lib/commit_pack/commit_pack_unittest.cc b/lib/commit_pack/commit_pack_unittest.cc
deleted file mode 100644
index 4d76edb..0000000
--- a/lib/commit_pack/commit_pack_unittest.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/commit_pack/commit_pack.h"
-
-#include <gtest/gtest.h>
-
-namespace cloud_provider {
-namespace {
-
-using CommitPackTest = ::testing::TestWithParam<std::vector<CommitPackEntry>>;
-
-TEST_P(CommitPackTest, BackAndForth) {
- const std::vector<CommitPackEntry> commits = GetParam();
- CommitPack commit_pack;
- ASSERT_TRUE(EncodeCommitPack(commits, &commit_pack));
- std::vector<CommitPackEntry> result;
- ASSERT_TRUE(DecodeCommitPack(commit_pack, &result));
- EXPECT_EQ(commits, result);
-}
-
-INSTANTIATE_TEST_CASE_P(CommitPackTest, CommitPackTest,
- ::testing::Values(std::vector<CommitPackEntry>(),
- std::vector<CommitPackEntry>{
- {"id_0", "data_0"},
- {"id_1", "data_1"}}));
-
-} // namespace
-} // namespace cloud_provider
diff --git a/lib/common/BUILD.gn b/lib/common/BUILD.gn
deleted file mode 100644
index 7244fc4..0000000
--- a/lib/common/BUILD.gn
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("common") {
- deps = [
- ":async_holder",
- ":names",
- ":story_provider_watcher_base",
- ":teardown",
- ]
-}
-
-source_set("async_holder") {
- sources = [
- "async_holder.cc",
- "async_holder.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("names") {
- sources = [
- "names.h",
- ]
-}
-
-source_set("story_provider_watcher_base") {
- sources = [
- "story_provider_watcher_base.cc",
- "story_provider_watcher_base.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("teardown") {
- sources = [
- "teardown.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("xdr") {
- sources = [
- "xdr.cc",
- "xdr.h",
- ]
-
- public_deps = [
- "//peridot/lib/fidl:json_xdr",
- "//peridot/public/fidl/fuchsia.modular.auth",
- ]
-}
diff --git a/lib/common/MAINTAINERS b/lib/common/MAINTAINERS
deleted file mode 100644
index 91100a6..0000000
--- a/lib/common/MAINTAINERS
+++ /dev/null
@@ -1 +0,0 @@
-mesch@google.com
diff --git a/lib/common/async_holder.cc b/lib/common/async_holder.cc
deleted file mode 100644
index 68e88dc..0000000
--- a/lib/common/async_holder.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/common/async_holder.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-AsyncHolderBase::AsyncHolderBase(std::string name)
- : name_(std::move(name)), down_(std::make_shared<bool>(false)) {}
-
-AsyncHolderBase::~AsyncHolderBase() {
- if (!*down_) {
- // This is not a warning because it happens because of an outer timeout, for
- // which there already is a warning issued.
- FXL_DLOG(INFO) << "Delete without teardown: " << name_;
- }
- *down_ = true;
-}
-
-void AsyncHolderBase::Teardown(zx::duration timeout,
- std::function<void()> done) {
- auto cont = [this, down = down_,
- done = std::move(done)](const bool from_timeout) {
- if (*down) {
- return;
- }
-
- *down = true;
-
- if (from_timeout) {
- FXL_LOG(WARNING) << "Teardown() timed out for " << name_;
- }
-
- ImplReset();
-
- done();
- };
-
- auto cont_timeout = [cont] { cont(true); };
-
- auto cont_normal = [cont] { cont(false); };
-
- async::PostDelayedTask(async_get_default_dispatcher(), cont_timeout, timeout);
- ImplTeardown(cont_normal);
-}
-
-} // namespace modular
diff --git a/lib/common/async_holder.h b/lib/common/async_holder.h
deleted file mode 100644
index ef4e0f3..0000000
--- a/lib/common/async_holder.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_COMMON_ASYNC_HOLDER_H_
-#define PERIDOT_LIB_COMMON_ASYNC_HOLDER_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-
-#include <lib/fxl/macros.h>
-#include <lib/zx/time.h>
-
-namespace modular {
-
-// A smart pointer that holds on to an implementation class and is able to
-// invoke Teardown() on the implementation with a timeout.
-//
-// TODO(mesch): The name is a bit of a mouthful. It's very similar to AppClient
-// and should align with that, but it owns impl and isn't a client of it.
-class AsyncHolderBase {
- public:
- AsyncHolderBase(std::string name);
- virtual ~AsyncHolderBase();
-
- // Timeout is the first argument because: (1) the second argument can be very
- // long, and it's incongruent to have the timeout dangling after it, (2) the
- // timeout happens first, the done callback after that, so this ordering is
- // actually quite natural.
- void Teardown(zx::duration timeout, std::function<void()> done);
-
- private:
- // Called by Teardown(). A timeout callback is scheduled simultaneously.
- // Eventually ImplReset() is called, either when done() is invoked, or when
- // the timeout elapses.
- virtual void ImplTeardown(std::function<void()> done) = 0;
-
- // Called after either the done callback of ImplTeardown() is invoked, or the
- // timeout elapses. The timeout is the reason ImplReset() is separate from
- // ImplTeardown().
- virtual void ImplReset() = 0;
-
- // For log messages only.
- const std::string name_;
-
- // This is the flag shared with the done and timeout callbacks of Teardown()
- // that prevents double invocation. The destructor sets it to true to prevent
- // pending callbacks from executing if the instance is deleted while a
- // teardown is pending. This may happen when the Teardown() of the instance
- // this holder is a member of runs into a timeout on its own.
- std::shared_ptr<bool> down_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AsyncHolderBase);
-};
-
-template <class Impl>
-class AsyncHolder : public AsyncHolderBase {
- public:
- AsyncHolder(const char* const name) : AsyncHolderBase(name) {}
- ~AsyncHolder() override = default;
-
- void reset(Impl* const impl) { impl_.reset(impl); }
-
- // Must not be used to invoke Impl::Teardown().
- Impl* operator->() {
- FXL_DCHECK(impl_.get());
- return impl_.get();
- }
-
- // Must not be used to invoke Impl::Teardown().
- Impl* get() { return impl_.get(); }
-
- private:
- void ImplTeardown(std::function<void()> done) override {
- FXL_DCHECK(impl_.get());
- impl_->Teardown(done);
- }
-
- void ImplReset() override { impl_.reset(); }
-
- std::unique_ptr<Impl> impl_;
- FXL_DISALLOW_COPY_AND_ASSIGN(AsyncHolder);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_COMMON_ASYNC_HOLDER_H_
diff --git a/lib/common/names.h b/lib/common/names.h
deleted file mode 100644
index 9c9fd22..0000000
--- a/lib/common/names.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_COMMON_NAMES_H_
-#define PERIDOT_LIB_COMMON_NAMES_H_
-
-namespace modular {
-
-// A framework-assigned name for the first module of a story (aka root mod)
-// created when using StoryProvider.CreateStory() or
-// StoryProvider.CreateStoryWithInfo() with a non-null |module_url| parameter.
-constexpr char kRootModuleName[] = "root";
-
-// The service name of the Presentation service that is routed between
-// BaseShell and SessionShell. The same service exchange between SessionShell
-// and StoryShell uses the SessionShellPresentationProvider service, which is
-// discoverable.
-// TODO(SCN-595): mozart.Presentation is being renamed to ui.Presenter.
-constexpr char kPresentationService[] = "mozart.Presentation";
-
-// TODO(MF-134): This key is duplicated in
-// topaz/lib/settings/lib/device_info.dart. Remove this key once factory reset
-// is provided to topaz as a service.
-// The key for factory reset toggles.
-constexpr char kFactoryResetKey[] = "FactoryReset";
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_COMMON_NAMES_H_
diff --git a/lib/common/story_provider_watcher_base.cc b/lib/common/story_provider_watcher_base.cc
deleted file mode 100644
index 529192a..0000000
--- a/lib/common/story_provider_watcher_base.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "story_provider_watcher_base.h"
-
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/string.h>
-
-namespace modular {
-
-StoryProviderWatcherBase::StoryProviderWatcherBase()
- : continue_([] {}), binding_(this) {}
-
-StoryProviderWatcherBase::~StoryProviderWatcherBase() = default;
-
-void StoryProviderWatcherBase::Continue(std::function<void()> at) {
- continue_ = std::move(at);
-}
-
-void StoryProviderWatcherBase::Watch(
- fuchsia::modular::StoryProvider* const story_provider) {
- story_provider->Watch(binding_.NewBinding());
-}
-
-void StoryProviderWatcherBase::Reset() { binding_.Unbind(); }
-
-void StoryProviderWatcherBase::OnDelete(::std::string /*story_id*/) {}
-
-void StoryProviderWatcherBase::OnChange(
- fuchsia::modular::StoryInfo /*story_info*/,
- fuchsia::modular::StoryState /*story_state*/,
- fuchsia::modular::StoryVisibilityState /*story_visibility_state*/) {
- continue_();
-}
-
-} // namespace modular
diff --git a/lib/common/story_provider_watcher_base.h b/lib/common/story_provider_watcher_base.h
deleted file mode 100644
index e1edbbb..0000000
--- a/lib/common/story_provider_watcher_base.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_COMMON_STORY_PROVIDER_WATCHER_BASE_H_
-#define PERIDOT_LIB_COMMON_STORY_PROVIDER_WATCHER_BASE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-// A simple story provider watcher implementation that calls the Continue()
-// callback whenever OnChange() is received. This default implementation ignores
-// OnDelete(), but you can override this class to handle OnDelete().
-class StoryProviderWatcherBase : fuchsia::modular::StoryProviderWatcher {
- public:
- StoryProviderWatcherBase();
- ~StoryProviderWatcherBase() override;
-
- // Sets the callback that will be called whenever OnChange is received.
- // Derived classes can change this behavior by overriding OnChange() and
- // making the callback based on the desired criteria.
- void Continue(std::function<void()> at);
-
- // Registers itself a watcher on the given story provider. Only one story
- // provider can be watched at a time.
- void Watch(fuchsia::modular::StoryProvider* story_provider);
-
- // Deregisters itself from the watched story provider.
- void Reset();
-
- protected:
- std::function<void()> continue_;
-
- private:
- // |fuchsia::modular::StoryProviderWatcher|
- void OnDelete(::std::string story_id) override;
-
- // |fuchsia::modular::StoryProviderWatcher|
- void OnChange(
- fuchsia::modular::StoryInfo story_info,
- fuchsia::modular::StoryState story_state,
- fuchsia::modular::StoryVisibilityState story_visibility_state) override;
-
- fidl::Binding<fuchsia::modular::StoryProviderWatcher> binding_;
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryProviderWatcherBase);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_COMMON_STORY_PROVIDER_WATCHER_BASE_H_
diff --git a/lib/common/teardown.h b/lib/common/teardown.h
deleted file mode 100644
index 8d0b93d..0000000
--- a/lib/common/teardown.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_COMMON_TEARDOWN_H_
-#define PERIDOT_LIB_COMMON_TEARDOWN_H_
-
-#include <lib/zx/time.h>
-
-namespace modular {
-
-// Standard timeout for dispatcher teardown.
-constexpr auto kBasicTimeout = zx::sec(1);
-
-// Timeouts for teardown of composite objects need to be larger than the basic
-// timeout, because they run through the teardown of their parts, at least
-// partially sequentially.
-//
-// TODO(mesch): Obviously, this should adjust, be negotiated, or be set
-// automatically as needed rather than hardcoded.
-
-// fuchsia::modular::Agent + overhead.
-constexpr auto kAgentRunnerTimeout = kBasicTimeout * 2;
-
-// Stories + overhead.
-constexpr auto kStoryProviderTimeout = kBasicTimeout * 2;
-
-// Multiple parts as described.
-constexpr auto kSessionmgrTimeout =
- kBasicTimeout * 3 + kAgentRunnerTimeout + kStoryProviderTimeout;
-
-constexpr auto kUserProviderTimeout = kBasicTimeout + kSessionmgrTimeout;
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_COMMON_TEARDOWN_H_
diff --git a/lib/common/xdr.cc b/lib/common/xdr.cc
deleted file mode 100644
index 99f5dfc..0000000
--- a/lib/common/xdr.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/common/xdr.h"
-
-#include <fuchsia/modular/auth/cpp/fidl.h>
-
-namespace modular {
-
-void XdrAccount_v1(XdrContext* const xdr,
- fuchsia::modular::auth::Account* const data) {
- xdr->Field("id", &data->id);
- xdr->Field("identity_provider", &data->identity_provider);
- xdr->Field("display_name", &data->display_name);
- xdr->Field("profile_url", &data->url);
- xdr->Field("image_url", &data->image_url);
-}
-
-void XdrAccount_v2(XdrContext* const xdr,
- fuchsia::modular::auth::Account* const data) {
- if (!xdr->Version(2)) {
- return;
- }
- xdr->Field("id", &data->id);
- xdr->Field("identity_provider", &data->identity_provider);
- xdr->Field("display_name", &data->display_name);
- xdr->Field("profile_url", &data->url);
- xdr->Field("image_url", &data->image_url);
-}
-
-extern const XdrFilterType<fuchsia::modular::auth::Account> XdrAccount[] = {
- XdrAccount_v2,
- XdrAccount_v1,
- nullptr,
-};
-
-} // namespace modular
diff --git a/lib/common/xdr.h b/lib/common/xdr.h
deleted file mode 100644
index 51792a1..0000000
--- a/lib/common/xdr.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_COMMON_XDR_H_
-#define PERIDOT_LIB_COMMON_XDR_H_
-
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace fuchsia {
-namespace modular {
-namespace auth {
-class Account;
-} // namespace auth
-} // namespace modular
-} // namespace fuchsia
-
-namespace modular {
-
-extern const XdrFilterType<fuchsia::modular::auth::Account> XdrAccount[];
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_COMMON_XDR_H_
diff --git a/lib/convert/BUILD.gn b/lib/convert/BUILD.gn
deleted file mode 100644
index 734c647..0000000
--- a/lib/convert/BUILD.gn
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/flatbuffers/flatbuffer.gni")
-
-visibility = [
- "//peridot/bin/*",
- "//peridot/lib/*",
-]
-
-source_set("convert") {
- sources = [
- "convert.cc",
- "convert.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//third_party/flatbuffers",
- "//third_party/leveldb",
- "//third_party/rapidjson",
- "//zircon/public/lib/zx",
- ]
-}
-
-flatbuffer("byte_storage_test") {
- testonly = true
-
- sources = [
- "bytes_test.fbs",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "collection_view_unittest.cc",
- "convert_unittest.cc",
- ]
-
- deps = [
- ":byte_storage_test",
- ":convert",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/convert/bytes_test.fbs b/lib/convert/bytes_test.fbs
deleted file mode 100644
index 96085e9..0000000
--- a/lib/convert/bytes_test.fbs
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-namespace convert;
-
-table BytesTest {
- bytes: [ubyte];
-}
-
-root_type BytesTest;
diff --git a/lib/convert/collection_view.h b/lib/convert/collection_view.h
deleted file mode 100644
index b7a2616..0000000
--- a/lib/convert/collection_view.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_CONVERT_COLLECTION_VIEW_H_
-#define PERIDOT_LIB_CONVERT_COLLECTION_VIEW_H_
-
-#include <algorithm>
-#include <iterator>
-
-#include <lib/fxl/logging.h>
-
-namespace convert {
-
-// View over the given collection. Doesn't take ownership of the collection that
-// must outlives this class.
-//
-// Single-argument constructor is marked as NOLINT to suppress
-// `google-explicit-constructor` clang-tidy warning - in this case the implicit
-// conversion is intended.
-template <typename T>
-class CollectionView {
- public:
- using iterator = typename T::iterator;
- using const_iterator = typename T::const_iterator;
-
- CollectionView(T& collection) // NOLINT
- : collection_(collection),
- begin_(std::begin(collection)),
- end_(std::end(collection)) {}
- CollectionView(T& collection, iterator begin, iterator end)
- : collection_(collection),
- begin_(std::move(begin)),
- end_(std::move(end)) {}
- CollectionView(const CollectionView& collection) = default;
- CollectionView& operator=(const CollectionView& collection) = default;
-
- const_iterator begin() const { return begin_; }
- const_iterator end() const { return end_; }
- iterator begin() { return begin_; }
- iterator end() { return end_; }
-
- // Returns a view over this view with the first element removed.
- CollectionView Tail() const {
- if (begin_ == end_) {
- return CollectionView<T>(collection_, end_, end_);
- }
- return CollectionView(collection_, std::next(begin_), end_);
- }
-
- // Returns a sub view of this view.
- CollectionView SubCollection(size_t begin, size_t length) const {
- if (begin >= size()) {
- return CollectionView<T>(collection_, end_, end_);
- }
- auto begin_it = std::next(begin_, begin);
- size_t final_length =
- std::min(length, static_cast<size_t>(std::distance(begin_it, end_)));
- return CollectionView(collection_, begin_it,
- std::next(begin_it, final_length));
- }
-
- const auto& operator[](size_t pos) const {
- FXL_DCHECK(pos < size());
- return *std::next(begin_, pos);
- }
-
- auto& operator[](size_t pos) {
- FXL_DCHECK(pos < static_cast<size_t>(std::distance(begin_, end_)));
- return *std::next(begin_, pos);
- }
-
- bool empty() const { return begin_ == end_; }
-
- size_t size() const { return std::distance(begin_, end_); }
-
- private:
- T& collection_;
- iterator begin_;
- iterator end_;
-};
-
-} // namespace convert
-
-#endif // PERIDOT_LIB_CONVERT_COLLECTION_VIEW_H_
diff --git a/lib/convert/collection_view_unittest.cc b/lib/convert/collection_view_unittest.cc
deleted file mode 100644
index 9b7cd31..0000000
--- a/lib/convert/collection_view_unittest.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/convert/collection_view.h"
-
-#include <iterator>
-#include <set>
-#include <unordered_set>
-#include <vector>
-
-#include "gtest/gtest.h"
-
-// Add helper to print our types.
-namespace testing {
-namespace internal {
-template <>
-std::string GetTypeName<std::vector<uint32_t>>() {
- return "std::vector<uint32_t>";
-}
-template <>
-std::string GetTypeName<std::unordered_set<uint32_t>>() {
- return "std::unordered_set<uint32_t>";
-}
-template <>
-std::string GetTypeName<std::set<uint32_t>>() {
- return "std::set<uint32_t>";
-}
-} // namespace internal
-} // namespace testing
-
-namespace convert {
-namespace {
-
-template <typename T>
-::testing::AssertionResult Equals(const T& collection, size_t begin,
- size_t length, CollectionView<T> view) {
- auto it1 = std::next(collection.begin(), begin);
- auto it2 = view.begin();
- for (size_t i = 0; i < length; ++i) {
- if (it1 == collection.end()) {
- return ::testing::AssertionFailure() << "collection is not large enough.";
- }
- if (it2 == view.end()) {
- return ::testing::AssertionFailure() << "view is not large enough.";
- }
- }
- if (*it1 != *it2) {
- return ::testing::AssertionFailure() << "view is incorrect.";
- }
- return ::testing::AssertionSuccess();
-}
-
-template <typename T>
-using CollectionViewTest = ::testing::Test;
-
-using CollectionTypes =
- ::testing::Types<std::vector<uint32_t>, std::unordered_set<uint32_t>,
- std::set<uint32_t>>;
-
-TYPED_TEST_CASE(CollectionViewTest, CollectionTypes);
-
-TYPED_TEST(CollectionViewTest, Views) {
- TypeParam values = {0, 1, 2, 3, 4, 5};
- CollectionView<TypeParam> view = values;
-
- EXPECT_TRUE(Equals(values, 0, values.size(), view));
- EXPECT_TRUE(Equals(values, 1, values.size(), view.Tail()));
- EXPECT_TRUE(Equals(values, 1, values.size() - 2,
- view.SubCollection(1, values.size() - 2)));
- EXPECT_EQ(*std::next(values.begin()), view.Tail()[0]);
-}
-
-} // namespace
-} // namespace convert
diff --git a/lib/convert/convert.cc b/lib/convert/convert.cc
deleted file mode 100644
index 9d97a49..0000000
--- a/lib/convert/convert.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/convert/convert.h"
-
-#include <string.h>
-
-#include <leveldb/slice.h>
-
-namespace convert {
-
-namespace {
-const char kHexDigits[] = "0123456789ABCDEF";
-}
-
-std::vector<uint8_t> ExtendedStringView::ToArray() {
- std::vector<uint8_t> result(size());
- memcpy(result.data(), data(), size());
- return result;
-}
-
-flatbuffers::Offset<flatbuffers::Vector<uint8_t>>
-ExtendedStringView::ToFlatBufferVector(
- flatbuffers::FlatBufferBuilder* builder) {
- return builder->CreateVector(reinterpret_cast<const unsigned char*>(data()),
- size());
-}
-
-std::string ExtendedStringView::ToHex() {
- std::string result;
- result.reserve(size() * 2);
- for (unsigned char c : *this) {
- result.push_back(kHexDigits[c >> 4]);
- result.push_back(kHexDigits[c & 0xf]);
- }
- return result;
-}
-
-std::vector<uint8_t> ToArray(ExtendedStringView value) {
- return value.ToArray();
-}
-
-std::string ToString(ExtendedStringView value) { return value.ToString(); }
-
-flatbuffers::Offset<flatbuffers::Vector<uint8_t>> ToFlatBufferVector(
- flatbuffers::FlatBufferBuilder* builder, ExtendedStringView value) {
- return value.ToFlatBufferVector(builder);
-}
-
-std::string ToHex(ExtendedStringView value) { return value.ToHex(); }
-
-} // namespace convert
diff --git a/lib/convert/convert.h b/lib/convert/convert.h
deleted file mode 100644
index 946528d..0000000
--- a/lib/convert/convert.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_CONVERT_CONVERT_H_
-#define PERIDOT_LIB_CONVERT_CONVERT_H_
-
-#include <string>
-
-#include <flatbuffers/flatbuffers.h>
-#include <leveldb/db.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/vector.h>
-#include <lib/fxl/strings/string_view.h>
-#include <rapidjson/document.h>
-
-namespace convert {
-
-// Provides conversions between fidl::VectorPtr, leveldb::Slice and std::string
-// representations of a data object.
-//
-// This class doesn't take ownership of the data used to construct it. The data
-// must outlive it. It is used to allow transparent handling of FIDL arrays,
-// leveldb slices and strings.
-//
-// Single-argument constructors and conversion operators are marked as NOLINT to
-// suppress `google-explicit-constructor` clang-tidy warning - in this case the
-// implicit conversion is intended.
-class ExtendedStringView : public fxl::StringView {
- public:
- ExtendedStringView(const std::vector<uint8_t>& array) // NOLINT
- : fxl::StringView(reinterpret_cast<const char*>(array.data()),
- array.size()) {}
- ExtendedStringView(const fidl::VectorPtr<uint8_t>& array) // NOLINT
- : fxl::StringView(reinterpret_cast<const char*>(array->data()),
- array->size()) {}
- template <size_t N>
- constexpr ExtendedStringView(const fidl::Array<uint8_t, N>& array) // NOLINT
- : fxl::StringView(reinterpret_cast<const char*>(array.data()), N) {}
- ExtendedStringView(const leveldb::Slice& slice) // NOLINT
- : fxl::StringView(slice.data(), slice.size()) {}
- ExtendedStringView(const std::string& string) // NOLINT
- : fxl::StringView(string) {}
- constexpr ExtendedStringView(fxl::StringView string_view) // NOLINT
- : fxl::StringView(string_view) {}
- ExtendedStringView(const rapidjson::Value& value) // NOLINT
- : fxl::StringView(value.GetString(), value.GetStringLength()) {
- FXL_DCHECK(value.IsString());
- }
- template <size_t N>
- constexpr ExtendedStringView(const char (&str)[N]) // NOLINT
- : fxl::StringView(str) {}
- ExtendedStringView( // NOLINT
- const flatbuffers::Vector<uint8_t>* byte_storage)
- : fxl::StringView(reinterpret_cast<const char*>(byte_storage->data()),
- byte_storage->size()) {}
- ExtendedStringView( // NOLINT
- const flatbuffers::FlatBufferBuilder& buffer_builder)
- : fxl::StringView(
- reinterpret_cast<char*>(buffer_builder.GetBufferPointer()),
- buffer_builder.GetSize()) {}
-
- operator leveldb::Slice() const { // NOLINT
- return leveldb::Slice(data(), size());
- }
-
- std::vector<uint8_t> ToArray();
-
- flatbuffers::Offset<flatbuffers::Vector<uint8_t>> ToFlatBufferVector(
- flatbuffers::FlatBufferBuilder* builder);
-
- std::string ToHex();
-};
-
-// Returns the ExtendedStringView representation of the given value.
-inline ExtendedStringView ToStringView(ExtendedStringView value) {
- return value;
-}
-
-// Returns the representation of the given value in LevelDB.
-inline leveldb::Slice ToSlice(ExtendedStringView value) { return value; }
-
-// Returns the std::vector representation of the given value.
-std::vector<uint8_t> ToArray(ExtendedStringView value);
-
-// Returns the fidl::Array representation of the given value.
-template <size_t N>
-void ToArray(ExtendedStringView value, fidl::Array<uint8_t, N>* out) {
- ZX_ASSERT(value.size() == N);
- memcpy(out->mutable_data(), value.data(), N);
-}
-
-// Returns the std::string representation of the given value.
-std::string ToString(ExtendedStringView value);
-
-// Returns the hexadecimal representation of the given value.
-std::string ToHex(ExtendedStringView value);
-
-// Store the given value as a FlatBufferVector in the given builder.
-flatbuffers::Offset<flatbuffers::Vector<uint8_t>> ToFlatBufferVector(
- flatbuffers::FlatBufferBuilder* builder, ExtendedStringView value);
-
-// Comparator that allows heterogeneous lookup by StringView and
-// std::string in a container with the key type of std::string.
-struct StringViewComparator {
- using is_transparent = std::true_type;
- bool operator()(const std::string& lhs, const std::string& rhs) const {
- return lhs < rhs;
- }
- bool operator()(ExtendedStringView lhs, const std::string& rhs) const {
- return lhs < fxl::StringView(rhs);
- }
- bool operator()(const std::string& lhs, ExtendedStringView rhs) const {
- return fxl::StringView(lhs) < rhs;
- }
-};
-
-} // namespace convert
-
-#endif // PERIDOT_LIB_CONVERT_CONVERT_H_
diff --git a/lib/convert/convert_unittest.cc b/lib/convert/convert_unittest.cc
deleted file mode 100644
index d0e8fa0..0000000
--- a/lib/convert/convert_unittest.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/convert/convert.h"
-
-#include "gtest/gtest.h"
-#include "peridot/lib/convert/bytes_test_generated.h"
-
-namespace convert {
-namespace {
-
-std::vector<uint8_t> CreateArray(const char* data, size_t size) {
- std::vector<uint8_t> result;
- for (size_t i = 0; i < size; ++i) {
- result.push_back(data[i]);
- }
- return result;
-}
-
-TEST(Convert, ToSlice) {
- std::string str = "Hello";
- leveldb::Slice slice = ToSlice(str);
- EXPECT_EQ(str, std::string(slice.data(), slice.size()));
-
- std::vector<uint8_t> array = CreateArray(str.data(), str.size());
- slice = ToSlice(str);
- EXPECT_EQ(str, std::string(slice.data(), slice.size()));
-}
-
-TEST(Convert, ToArray) {
- std::string str = "Hello";
- std::vector<uint8_t> array = ToArray(str);
- EXPECT_EQ(str,
- std::string(reinterpret_cast<char*>(array.data()), array.size()));
-
- leveldb::Slice slice(str.data(), str.size());
- array = ToArray(slice);
- EXPECT_EQ(str,
- std::string(reinterpret_cast<char*>(array.data()), array.size()));
-}
-
-TEST(Convert, ToString) {
- std::string str = "Hello";
- leveldb::Slice slice(str.data(), str.size());
- std::string result = ToString(slice);
- EXPECT_EQ(str, result);
-
- std::vector<uint8_t> array = ToArray(str);
- result = ToString(array);
- EXPECT_EQ(str, result);
-}
-
-TEST(Convert, ToStringView) {
- std::string str = "Hello";
- leveldb::Slice slice(str.data(), str.size());
- ExtendedStringView result = slice;
- EXPECT_EQ(str, result.ToString());
-
- std::vector<uint8_t> array = ToArray(str);
- result = array;
- EXPECT_EQ(str, result.ToString());
-}
-
-TEST(Convert, ToFlatBufferVector) {
- flatbuffers::FlatBufferBuilder builder;
-
- std::string str = "Hello";
- ExtendedStringView str_view = str;
-
- auto bytes = str_view.ToFlatBufferVector(&builder);
- builder.Finish(CreateBytesTest(builder, bytes));
-
- ExtendedStringView result =
- GetBytesTest(builder.GetCurrentBufferPointer())->bytes();
- EXPECT_EQ(str, result);
-}
-
-TEST(Convert, ImplicitConversion) {
- std::string str = "Hello";
- ExtendedStringView esv(str);
-
- leveldb::Slice slice = esv;
- EXPECT_EQ(str, ToString(slice));
-
- // Suppress check warning that |string_view| is never modified so we could use
- // |esv| instead.
- fxl::StringView string_view = esv; // NOLINT
- EXPECT_EQ(str, ToString(string_view));
-}
-
-TEST(Convert, FromFlatBufferBuilder) {
- flatbuffers::FlatBufferBuilder builder;
- auto bytes = convert::ToFlatBufferVector(&builder, "test");
- builder.Finish(CreateBytesTest(builder, bytes));
-
- ExtendedStringView result(builder);
- std::string buffer_bytes(reinterpret_cast<char*>(builder.GetBufferPointer()),
- builder.GetSize());
-
- EXPECT_EQ(buffer_bytes, result);
-}
-
-} // namespace
-} // namespace convert
diff --git a/lib/device_info/BUILD.gn b/lib/device_info/BUILD.gn
deleted file mode 100644
index 6c54e2b..0000000
--- a/lib/device_info/BUILD.gn
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("device_info") {
- sources = [
- "device_info.cc",
- "device_info.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/lib/util:filesystem",
- ]
-}
-
-source_set("device_profile") {
- sources = [
- "device_profile.cc",
- "device_profile.h",
- ]
-
- public_deps = [
- ":device_info",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/lib/rapidjson",
- ]
-}
diff --git a/lib/device_info/device_info.cc b/lib/device_info/device_info.cc
deleted file mode 100644
index ab44e30..0000000
--- a/lib/device_info/device_info.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/device_info/device_info.h"
-
-#include <limits.h>
-#include <unistd.h>
-
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/random/uuid.h>
-#include <lib/fxl/strings/string_printf.h>
-#include <lib/fxl/strings/trim.h>
-
-#include "peridot/lib/util/filesystem.h"
-
-namespace modular {
-
-constexpr char kDeviceInfoDirectory[] = "/data/device";
-constexpr char kDeviceIDFile[] = "/data/device/%s.syncid";
-constexpr char kDeviceNameFile[] = "/data/device/%s.devicename";
-constexpr char kSyncDeviceProfile[] = "/data/device/profile_config.json";
-
-std::string LoadDeviceProfile() {
- std::string device_profile;
-
- if (!files::IsDirectory(kDeviceInfoDirectory)) {
- files::CreateDirectory(kDeviceInfoDirectory);
- }
-
- if (!files::ReadFileToString(kSyncDeviceProfile, &device_profile)) {
- device_profile = "{}";
- }
-
- return device_profile;
-}
-
-// TODO(security): this is a temporary implementation. audit the revocability
-// of this ID for syncing.
-std::string LoadDeviceID(const std::string& user) {
- std::string device_id;
-
- if (!files::IsDirectory(kDeviceInfoDirectory)) {
- files::CreateDirectory(kDeviceInfoDirectory);
- }
-
- std::string path = fxl::StringPrintf(kDeviceIDFile, user.c_str());
-
- if (!files::ReadFileToString(path, &device_id)) {
- // no existing device id. generate a UUID and store it to disk
- device_id = fxl::GenerateUUID();
- bool success = files::WriteFile(path, device_id.data(), device_id.length());
- FXL_DCHECK(success);
- }
-
- FXL_LOG(INFO) << "device_info: syncing device id for user: " << user
- << " set to: " << device_id;
-
- return device_id;
-}
-
-// TODO(zbowling): implement WriteDeviceName
-std::string LoadDeviceName(const std::string& user) {
- std::string device_name;
-
- if (!files::IsDirectory(kDeviceInfoDirectory)) {
- files::CreateDirectory(kDeviceInfoDirectory);
- }
-
- std::string path = fxl::StringPrintf(kDeviceNameFile, user.c_str());
-
- if (files::ReadFileToString(path, &device_name)) {
- // Remove whitespace because vim and echo like adding a newline.
- constexpr char ws[] = " \t\n\r";
- device_name = fxl::TrimString(device_name, ws).ToString();
- }
-
- if (device_name.empty()) {
- // gethostname() will return "fuchsia" if the network stack hasn't started.
- // Generally by this point we should have used OAuth to auth. This code is
- // designed to allow a friendly device name, or a fallback to the result
- // of gethostname() if the user didn't change it. The friendly name is
- // defined by users, so there appears to be no requirement for uniqueness.
- char host_name_buffer[HOST_NAME_MAX + 1];
- // Defense in depth.
- host_name_buffer[HOST_NAME_MAX] = '\0';
- int result = gethostname(host_name_buffer, sizeof(host_name_buffer));
-
- if (result < 0) {
- FXL_LOG(ERROR) << "unable to get hostname. errno " << errno;
- device_name = "fuchsia";
- } else {
- device_name = host_name_buffer;
- }
-
- // Saving this value causes any changes in the return value of gethostname()
- // to be ignored, but the cached copy helps with the aforementioned problem
- // that the network stack may not have started.
- // TODO(jimbe) Don't write the result of gethostname() to this file once
- // NET-79 is fixed. (Maybe write an empty file so users can find it.)
- bool success =
- files::WriteFile(path, device_name.data(), device_name.length());
- FXL_DCHECK(success);
- }
-
- return device_name;
-}
-
-} // namespace modular
diff --git a/lib/device_info/device_info.h b/lib/device_info/device_info.h
deleted file mode 100644
index fde3c7a..0000000
--- a/lib/device_info/device_info.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_DEVICE_INFO_DEVICE_INFO_H_
-#define PERIDOT_LIB_DEVICE_INFO_DEVICE_INFO_H_
-
-#include <string>
-
-namespace modular {
-
-// Reads the contents of /data/device/profile_config.json and returns the
-// result. If the file cannot be read, returns empty JSON-encoded object, "{}".
-std::string LoadDeviceProfile();
-
-// Reads a device id, scoped to |user|, for this device. Generates and persists
-// one on the first call of LoadDeviceID() on this device for this |user|.
-//
-// Thread-hostile.
-std::string LoadDeviceID(const std::string& user);
-
-// A wrapper around gethostname() which a) translates an error into the string
-// "fuchsia" and b) caches the output to a file scoped by |user| for future
-// calls.
-//
-// Thread-hostile.
-std::string LoadDeviceName(const std::string& user);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_DEVICE_INFO_DEVICE_INFO_H_
diff --git a/lib/device_info/device_profile.cc b/lib/device_info/device_profile.cc
deleted file mode 100644
index 27b14e0..0000000
--- a/lib/device_info/device_profile.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/device_info/device_profile.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-
-namespace modular {
-
-// TODO(zbowling): this is a hack. we need to later decide how we want to
-// identfiy a devices intent. For now just a flag to say the intends to act
-// "like" a remote display server
-constexpr char kPresentationServer[] = "remote_presentor";
-
-DeviceProfile::DeviceProfile() {}
-
-bool DeviceProfile::Parse(const std::string& jsonProfile) {
- fuchsia::modular::JsonDoc document;
- document.Parse(jsonProfile);
- if (!document.IsObject()) {
- return false;
- }
-
- if (document.HasMember(kPresentationServer) &&
- document[kPresentationServer].IsBool()) {
- presentation_server = document[kPresentationServer].GetBool();
- }
-
- return true;
-}
-
-bool DeviceProfile::ParseDefaultProfile() { return Parse(LoadDeviceProfile()); }
-
-} // namespace modular
diff --git a/lib/device_info/device_profile.h b/lib/device_info/device_profile.h
deleted file mode 100644
index d998465..0000000
--- a/lib/device_info/device_profile.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_DEVICE_INFO_DEVICE_PROFILE_H_
-#define PERIDOT_LIB_DEVICE_INFO_DEVICE_PROFILE_H_
-
-#include <string>
-
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/device_info/device_info.h"
-
-namespace modular {
-
-// Parses a device's profile JSON. Can be used to parse the current device or a
-// remote device's profile from the device map.
-class DeviceProfile {
- DeviceProfile();
- ~DeviceProfile() = delete;
-
- bool Parse(const std::string& jsonProfile);
- bool ParseDefaultProfile();
-
- // if this device is intended to be a remote presentation device.
- // HACK(zbowling): TBD: We need a better way deciding a device's idioms.
- bool presentation_server{false};
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DeviceProfile);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_DEVICE_INFO_DEVICE_PROFILE_H_
diff --git a/lib/entity/BUILD.gn b/lib/entity/BUILD.gn
deleted file mode 100644
index ffbe105..0000000
--- a/lib/entity/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("entity_watcher") {
- sources = [
- "entity_watcher_impl.cc",
- "entity_watcher_impl.h",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
diff --git a/lib/entity/entity_watcher_impl.cc b/lib/entity/entity_watcher_impl.cc
deleted file mode 100644
index 6f64c5a..0000000
--- a/lib/entity/entity_watcher_impl.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/entity/entity_watcher_impl.h"
-
-namespace modular {
-
-EntityWatcherImpl::EntityWatcherImpl() : binding_(this) {}
-
-EntityWatcherImpl::EntityWatcherImpl(
- fit::function<void(std::unique_ptr<fuchsia::mem::Buffer> value)> callback)
- : callback_(std::move(callback)), binding_(this) {}
-
-void EntityWatcherImpl::SetOnUpdated(
- fit::function<void(std::unique_ptr<fuchsia::mem::Buffer> value)> callback) {
- callback_ = std::move(callback);
-}
-
-void EntityWatcherImpl::Connect(
- fidl::InterfaceRequest<fuchsia::modular::EntityWatcher> request) {
- binding_.Bind(std::move(request));
-}
-
-void EntityWatcherImpl::OnUpdated(std::unique_ptr<fuchsia::mem::Buffer> value) {
- if (callback_) {
- callback_(std::move(value));
- }
-}
-
-} // namespace modular
diff --git a/lib/entity/entity_watcher_impl.h b/lib/entity/entity_watcher_impl.h
deleted file mode 100644
index 79e62e2..0000000
--- a/lib/entity/entity_watcher_impl.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_ENTITY_ENTITY_WATCHER_IMPL_H_
-#define PERIDOT_LIB_ENTITY_ENTITY_WATCHER_IMPL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-
-#include <memory>
-
-namespace modular {
-
-// An EntityWatcher implementation which calls a callback when the entity data
-// is updated.
-class EntityWatcherImpl : public fuchsia::modular::EntityWatcher {
- public:
- EntityWatcherImpl();
- EntityWatcherImpl(
- fit::function<void(std::unique_ptr<fuchsia::mem::Buffer> value)>
- callback);
-
- // Sets the callback which will be called with the updated entity value.
- void SetOnUpdated(
- fit::function<void(std::unique_ptr<fuchsia::mem::Buffer> value)>
- callback);
-
- // Binds |request| to this EntityWatcher implementation.
- void Connect(fidl::InterfaceRequest<fuchsia::modular::EntityWatcher> request);
-
- private:
- // |EntityWatcher|
- void OnUpdated(std::unique_ptr<fuchsia::mem::Buffer> value);
-
- // The callback which is called when the entity data update is observed.
- fit::function<void(std::unique_ptr<fuchsia::mem::Buffer> value)> callback_;
-
- // The binding which is used by |Connect()| to bind incoming EntityWatcher
- // requests.
- fidl::Binding<fuchsia::modular::EntityWatcher> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(EntityWatcherImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_ENTITY_ENTITY_WATCHER_IMPL_H_
diff --git a/lib/environment_host/BUILD.gn b/lib/environment_host/BUILD.gn
deleted file mode 100644
index 89c8548..0000000
--- a/lib/environment_host/BUILD.gn
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("environment_host") {
- sources = [
- "maxwell_service_provider_bridge.cc",
- "maxwell_service_provider_bridge.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/svc/cpp",
- ]
-}
diff --git a/lib/environment_host/maxwell_service_provider_bridge.cc b/lib/environment_host/maxwell_service_provider_bridge.cc
deleted file mode 100644
index 88df821..0000000
--- a/lib/environment_host/maxwell_service_provider_bridge.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/environment_host/maxwell_service_provider_bridge.h"
-
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/connect.h>
-
-namespace maxwell {
-namespace {
-
-// TODO(abarth): Get this constant from a generated header once netstack uses
-// FIDL.
-constexpr char kNetstack[] = "net.Netstack";
-
-} // namespace
-
-MaxwellServiceProviderBridge::MaxwellServiceProviderBridge(
- fuchsia::sys::Environment* parent_env)
- : vfs_(async_get_default_dispatcher()),
- services_dir_(fbl::AdoptRef(new fs::PseudoDir)) {
- AddService<fuchsia::sys::Loader>(
- [parent_env](fidl::InterfaceRequest<fuchsia::sys::Loader> request) {
- fuchsia::sys::ServiceProviderPtr services;
- parent_env->GetServices(services.NewRequest());
- component::ConnectToService(services.get(), std::move(request));
- });
- AddServiceWithName(
- kNetstack,
- fbl::AdoptRef(new fs::Service([parent_env](zx::channel request) {
- fuchsia::sys::ServiceProviderPtr services;
- parent_env->GetServices(services.NewRequest());
- services->ConnectToService(kNetstack, std::move(request));
- return ZX_OK;
- })));
-}
-
-void MaxwellServiceProviderBridge::AddServiceWithName(
- const char* name, fbl::RefPtr<fs::Service> service) {
- service_names_.push_back(name);
- services_dir_->AddEntry(name, service);
-}
-
-zx::channel MaxwellServiceProviderBridge::OpenAsDirectory() {
- zx::channel h1, h2;
- if (zx::channel::create(0, &h1, &h2) != ZX_OK)
- return zx::channel();
- if (vfs_.ServeDirectory(services_dir_, std::move(h1)) != ZX_OK)
- return zx::channel();
- return h2;
-}
-
-} // namespace maxwell
diff --git a/lib/environment_host/maxwell_service_provider_bridge.h b/lib/environment_host/maxwell_service_provider_bridge.h
deleted file mode 100644
index 6b095a9..0000000
--- a/lib/environment_host/maxwell_service_provider_bridge.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_ENVIRONMENT_HOST_MAXWELL_SERVICE_PROVIDER_BRIDGE_H_
-#define PERIDOT_LIB_ENVIRONMENT_HOST_MAXWELL_SERVICE_PROVIDER_BRIDGE_H_
-
-#include <fbl/ref_ptr.h>
-#include <fs/pseudo-dir.h>
-#include <fs/service.h>
-#include <fs/synchronous-vfs.h>
-#include <fuchsia/sys/cpp/fidl.h>
-
-namespace maxwell {
-
-// Environment surfacing only explicitly given environment services.
-class MaxwellServiceProviderBridge {
- public:
- MaxwellServiceProviderBridge(fuchsia::sys::Environment* parent_env);
-
- zx::channel OpenAsDirectory();
- const std::vector<std::string>& service_names() {
- return service_names_;
- }
-
- template <typename Interface>
- void AddService(fidl::InterfaceRequestHandler<Interface> handler) {
- auto service = fbl::AdoptRef(new fs::Service(
- [this, handler = std::move(handler)](zx::channel channel) {
- handler(fidl::InterfaceRequest<Interface>(std::move(channel)));
- return ZX_OK;
- }));
- AddServiceWithName(Interface::Name_, service);
- }
-
- void AddServiceWithName(const char* name, fbl::RefPtr<fs::Service> svc);
-
- private:
- fs::SynchronousVfs vfs_;
- fbl::RefPtr<fs::PseudoDir> services_dir_;
- std::vector<std::string> service_names_;
-};
-
-} // namespace maxwell
-
-#endif // PERIDOT_LIB_ENVIRONMENT_HOST_MAXWELL_SERVICE_PROVIDER_BRIDGE_H_
diff --git a/lib/fidl/BUILD.gn b/lib/fidl/BUILD.gn
deleted file mode 100644
index cbf3a3a..0000000
--- a/lib/fidl/BUILD.gn
+++ /dev/null
@@ -1,191 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-source_set("app_client") {
- sources = [
- "app_client.cc",
- "app_client.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/svc/cpp",
- "//peridot/lib/common:async_holder",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("array_to_string") {
- sources = [
- "array_to_string.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- ]
-}
-
-source_set("json_xdr") {
- sources = [
- "json_xdr.cc",
- "json_xdr.h",
- ]
-
- # MUST be public so clients pick up the defines from
- # //third_party/rapidjson:rapidjson_config
- public_deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/rapidjson",
- "//third_party/rapidjson",
- ]
-}
-
-source_set("proxy") {
- sources = [
- "proxy.cc",
- "proxy.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("clone") {
- sources = [
- "clone.h",
- ]
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("environment") {
- sources = [
- "environment.cc",
- "environment.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("single_service_app") {
- sources = [
- "single_service_app.h",
- ]
-
- public_deps = [
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/fidl/fuchsia.ui.app",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/fidl/fuchsia.ui.viewsv1token",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- "//zircon/public/lib/zx",
- ]
-}
-
-source_set("view_host") {
- sources = [
- "view_host.cc",
- "view_host.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/ui/base_view/cpp",
- "//zircon/public/lib/zx",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.ui.app",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/fidl/fuchsia.ui.viewsv1token",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- ]
-}
-
-fidl("app_client_unittest_fidl") {
- testonly = true
- cpp_legacy_callbacks = true
-
- name = "test.peridot.lib.fidl.appclient"
-
- sources = [
- "app_client_unittest.fidl",
- ]
-}
-
-group("unittests") {
- testonly = true
-
- deps = [
- ":app_client_unittest",
- ":json_xdr_unittest",
- ]
-}
-
-source_set("app_client_unittest") {
- testonly = true
-
- sources = [
- "app_client_unittest.cc",
- ]
-
- deps = [
- ":app_client",
- ":app_client_unittest_fidl",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/component/cpp/testing:fake_launcher",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest",
- ]
-}
-
-fidl("json_xdr_unittest_fidl") {
- testonly = true
- cpp_legacy_callbacks = true
-
- name = "test.peridot.lib.fidl.jsonxdr"
-
- sources = [
- "json_xdr_unittest.fidl",
- ]
-}
-
-source_set("json_xdr_unittest") {
- testonly = true
-
- sources = [
- "json_xdr_unittest.cc",
- ]
-
- deps = [
- ":json_xdr",
- ":json_xdr_unittest_fidl",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/fidl/README.md b/lib/fidl/README.md
deleted file mode 100644
index c0126dd..0000000
--- a/lib/fidl/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory contains files that make it (slightly) easier to use fidl in the
-modular code base.
diff --git a/lib/fidl/app_client.cc b/lib/fidl/app_client.cc
deleted file mode 100644
index bd0c122..0000000
--- a/lib/fidl/app_client.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/fidl/app_client.h"
-
-#include <fcntl.h>
-
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/fdio/limits.h>
-#include <lib/fdio/util.h>
-#include <lib/fsl/io/fd.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <zircon/processargs.h>
-
-namespace modular {
-AppClientBase::AppClientBase(fuchsia::sys::Launcher* const launcher,
- fuchsia::modular::AppConfig config,
- std::string data_origin,
- fuchsia::sys::ServiceListPtr additional_services)
- : AsyncHolderBase(config.url) {
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.directory_request = services_.NewRequest();
- launch_info.url = config.url;
- std::vector<std::string> args;
- for (const auto& arg : *config.args) {
- launch_info.arguments.push_back(arg);
- }
-
- if (!data_origin.empty()) {
- if (!files::CreateDirectory(data_origin)) {
- FXL_LOG(ERROR) << "Unable to create directory at " << data_origin;
- return;
- }
- launch_info.flat_namespace = fuchsia::sys::FlatNamespace::New();
- launch_info.flat_namespace->paths.push_back("/data");
-
- fxl::UniqueFD dir(open(data_origin.c_str(), O_DIRECTORY | O_RDONLY));
- if (!dir.is_valid()) {
- FXL_LOG(ERROR) << "Unable to open directory at " << data_origin
- << ". errno: " << errno;
- return;
- }
-
- launch_info.flat_namespace->directories.push_back(
- fsl::CloneChannelFromFileDescriptor(dir.get()));
- if (!launch_info.flat_namespace->directories.at(0)) {
- FXL_LOG(ERROR) << "Unable create a handle from " << data_origin;
- return;
- }
- }
-
- if (additional_services) {
- launch_info.additional_services = std::move(additional_services);
- }
- launcher->CreateComponent(std::move(launch_info), app_.NewRequest());
-}
-
-AppClientBase::~AppClientBase() = default;
-
-void AppClientBase::ImplTeardown(std::function<void()> done) {
- ServiceTerminate(std::move(done));
-}
-
-void AppClientBase::ImplReset() {
- app_.Unbind();
- ServiceUnbind();
-}
-
-void AppClientBase::SetAppErrorHandler(
- const std::function<void()>& error_handler) {
- app_.set_error_handler(
- [error_handler](zx_status_t status) { error_handler(); });
-}
-
-void AppClientBase::ServiceTerminate(const std::function<void()>& /* done */) {}
-
-void AppClientBase::ServiceUnbind() {}
-
-template <>
-void AppClient<fuchsia::modular::Lifecycle>::ServiceTerminate(
- const std::function<void()>& done) {
- SetAppErrorHandler(done);
- if (primary_service())
- primary_service()->Terminate();
-}
-
-} // namespace modular
diff --git a/lib/fidl/app_client.h b/lib/fidl/app_client.h
deleted file mode 100644
index 1e10e77..0000000
--- a/lib/fidl/app_client.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIDL_APP_CLIENT_H_
-#define PERIDOT_LIB_FIDL_APP_CLIENT_H_
-
-#include <memory>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/time/time_delta.h>
-#include <lib/svc/cpp/services.h>
-
-#include "peridot/lib/common/async_holder.h"
-
-namespace modular {
-
-// A class that holds a connection to a single service instance in an
-// application instance. The service instance supports life cycle with a
-// Terminate() method. When calling Terminate(), the service is supposed to
-// close its connection, and when that happens, we can kill the application, or
-// it's gone already anyway. If the service connection doesn't close after a
-// timeout, we close it and kill the application anyway.
-//
-// When starting an application instance, the directory pointed to by
-// |data_origin| will be mapped into /data for the newly started application.
-// If left empty, it'll be mapped to the root /data.
-//
-// |additional_services| will allow us to add custom services to an applications
-// namespace.
-//
-// AppClientBase are the non-template parts factored out so they don't need to
-// be inline. It can be used on its own too.
-class AppClientBase : public AsyncHolderBase {
- public:
- AppClientBase(fuchsia::sys::Launcher* launcher,
- fuchsia::modular::AppConfig config,
- std::string data_origin = "",
- fuchsia::sys::ServiceListPtr additional_services = nullptr);
- ~AppClientBase() override;
-
- // Gives access to the services of the started application. Services
- // obtained from it are not involved in life cycle management provided by
- // AppClient, however. This is used for example to obtain the ViewProvider.
- component::Services& services() { return services_; }
-
- // Registers a handler to receive a notification when this application
- // connection encounters an error. This typically happens when this
- // application stops or crashes. |error_handler| will be deregistered when
- // attempting graceful termination via |AsyncHolderBase::Teardown()|.
- void SetAppErrorHandler(const std::function<void()>& error_handler);
-
- private:
- // The termination sequence as prescribed by AsyncHolderBase.
- void ImplTeardown(std::function<void()> done) override;
- void ImplReset() override;
-
- // Service specific parts of the termination sequence.
- virtual void ServiceTerminate(const std::function<void()>& done);
- virtual void ServiceUnbind();
-
- fuchsia::sys::ComponentControllerPtr app_;
- component::Services services_;
- FXL_DISALLOW_COPY_AND_ASSIGN(AppClientBase);
-};
-
-// A generic client that does the standard termination sequence. For a service
-// with another termination sequence, another implementation could be created.
-template <class Service>
-class AppClient : public AppClientBase {
- public:
- AppClient(fuchsia::sys::Launcher* const launcher,
- fuchsia::modular::AppConfig config, std::string data_origin = "",
- fuchsia::sys::ServiceListPtr additional_services = nullptr)
- : AppClientBase(launcher, std::move(config), std::move(data_origin),
- std::move(additional_services)) {
- services().ConnectToService(service_.NewRequest());
- }
-
- ~AppClient() override = default;
-
- fidl::InterfacePtr<Service>& primary_service() { return service_; }
-
- private:
- void ServiceTerminate(const std::function<void()>& done) override {
- // The service is expected to acknowledge the Terminate() request by
- // closing its connection within the timeout set in Teardown().
- service_.set_error_handler([done](zx_status_t status) { done(); });
- service_->Terminate();
- }
-
- void ServiceUnbind() override { service_.Unbind(); }
-
- fidl::InterfacePtr<Service> service_;
- FXL_DISALLOW_COPY_AND_ASSIGN(AppClient);
-};
-
-template <>
-void AppClient<fuchsia::modular::Lifecycle>::ServiceTerminate(
- const std::function<void()>& done);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_FIDL_APP_CLIENT_H_
diff --git a/lib/fidl/app_client_unittest.cc b/lib/fidl/app_client_unittest.cc
deleted file mode 100644
index b79ef95..0000000
--- a/lib/fidl/app_client_unittest.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/fidl/app_client.h"
-
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/component/cpp/testing/fake_launcher.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include <test/peridot/lib/fidl/appclient/cpp/fidl.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace testing {
-namespace {
-
-using ::component::testing::FakeLauncher;
-using ::test::peridot::lib::fidl::appclient::TerminateService;
-
-constexpr char kServiceName[] = "service1";
-constexpr char kTestUrl[] = "some/test/url";
-
-fuchsia::modular::AppConfig GetTestAppConfig() {
- fuchsia::modular::AppConfig app_config;
- app_config.url = kTestUrl;
- return app_config;
-}
-
-class TestComponentController : fuchsia::sys::ComponentController {
- public:
- TestComponentController() : binding_(this) {}
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> request) {
- binding_.Bind(std::move(request));
- binding_.set_error_handler([this](zx_status_t status) { Kill(); });
- }
-
- bool killed() { return killed_; }
-
- private:
- void Kill() override { killed_ = true; }
-
- void Detach() override {}
-
- fidl::Binding<fuchsia::sys::ComponentController> binding_;
-
- bool killed_{};
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestComponentController);
-};
-
-class AppClientTest : public gtest::TestLoopFixture {};
-
-TEST_F(AppClientTest, BaseRun_Success) {
- bool callback_called = false;
- FakeLauncher launcher;
- launcher.RegisterComponent(
- kTestUrl,
- [&callback_called](
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- EXPECT_EQ(kTestUrl, launch_info.url);
- callback_called = true;
- });
- AppClientBase app_client_base(&launcher, GetTestAppConfig());
-
- EXPECT_TRUE(callback_called);
-}
-
-TEST_F(AppClientTest, BaseTerminate_Success) {
- FakeLauncher launcher;
- TestComponentController controller;
- bool callback_called = false;
- launcher.RegisterComponent(
- kTestUrl,
- [&callback_called, &controller](
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- EXPECT_EQ(kTestUrl, launch_info.url);
- callback_called = true;
- controller.Connect(std::move(ctrl));
- });
-
- AppClientBase app_client_base(&launcher, GetTestAppConfig());
-
- bool app_terminated_callback_called = false;
- app_client_base.Teardown(zx::duration(), [&app_terminated_callback_called] {
- app_terminated_callback_called = true;
- });
-
- EXPECT_TRUE(callback_called);
- RunLoopUntilIdle();
- EXPECT_TRUE(app_terminated_callback_called);
- EXPECT_TRUE(controller.killed());
-}
-
-TEST_F(AppClientTest, Run_Success) {
- bool callback_called = false;
- FakeLauncher launcher;
- launcher.RegisterComponent(
- kTestUrl,
- [&callback_called](
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- EXPECT_EQ(kTestUrl, launch_info.url);
- callback_called = true;
- });
-
- AppClient<TerminateService> app_client(&launcher, GetTestAppConfig());
-
- EXPECT_TRUE(callback_called);
-}
-
-TEST_F(AppClientTest, RunWithParams_Success) {
- fuchsia::sys::ServiceListPtr additional_services =
- fuchsia::sys::ServiceList::New();
- additional_services->names.push_back(kServiceName);
- // We just need |provider_request| to stay around till the end of this test.
- auto provider_request = additional_services->provider.NewRequest();
-
- bool callback_called = false;
- FakeLauncher launcher;
- launcher.RegisterComponent(
- kTestUrl,
- [&callback_called](
- fuchsia::sys::LaunchInfo launch_info,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
- EXPECT_EQ(kTestUrl, launch_info.url);
- auto additional_services = std::move(launch_info.additional_services);
- EXPECT_EQ(kServiceName, additional_services->names.at(0));
- callback_called = true;
- });
-
- AppClient<TerminateService> app_client(&launcher, GetTestAppConfig(), "",
- std::move(additional_services));
-
- EXPECT_TRUE(callback_called);
-}
-
-} // namespace
-} // namespace testing
-} // namespace modular
diff --git a/lib/fidl/app_client_unittest.fidl b/lib/fidl/app_client_unittest.fidl
deleted file mode 100644
index 6cf7849..0000000
--- a/lib/fidl/app_client_unittest.fidl
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Interface(s) used by AppClient's unittest.
-
-library test.peridot.lib.fidl.appclient;
-
-[Discoverable]
-interface TerminateService {
- 1: Terminate();
-};
diff --git a/lib/fidl/array_to_string.h b/lib/fidl/array_to_string.h
deleted file mode 100644
index d87d094..0000000
--- a/lib/fidl/array_to_string.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIDL_ARRAY_TO_STRING_H_
-#define PERIDOT_LIB_FIDL_ARRAY_TO_STRING_H_
-
-#include <string>
-#include <vector>
-
-#include <lib/fidl/cpp/string.h>
-#include <lib/fidl/cpp/vector.h>
-
-namespace modular {
-
-inline std::string to_string(const fidl::Array<uint8_t, 16>& data) {
- return std::string(reinterpret_cast<const char*>(data.data()), data.count());
-}
-
-inline std::string to_string(const fidl::VectorPtr<uint8_t>& data) {
- return std::string(reinterpret_cast<const char*>(data->data()), data->size());
-}
-
-inline std::string to_string(const std::vector<uint8_t>& data) {
- return std::string(reinterpret_cast<const char*>(data.data()), data.size());
-}
-
-inline std::string to_hex_string(const uint8_t* data, size_t size) {
- constexpr char kHexadecimalCharacters[] = "0123456789abcdef";
- std::string ret;
- ret.reserve(size * 2);
- for (size_t i = 0; i < size; i++) {
- unsigned char c = data[i];
- ret.push_back(kHexadecimalCharacters[c >> 4]);
- ret.push_back(kHexadecimalCharacters[c & 0xf]);
- }
- return ret;
-}
-
-template <size_t N>
-inline std::string to_hex_string(const fidl::Array<uint8_t, N>& data) {
- return to_hex_string(data.data(), N);
-}
-
-template <size_t N>
-inline std::string to_hex_string(const std::array<uint8_t, N>& data) {
- return to_hex_string(data.data(), N);
-}
-
-inline std::string to_hex_string(const fidl::VectorPtr<uint8_t>& data) {
- return to_hex_string(data->data(), data->size());
-}
-
-inline std::string to_hex_string(const std::vector<uint8_t>& data) {
- return to_hex_string(data.data(), data.size());
-}
-
-// If possible use convert::ToArray instead.
-inline fidl::VectorPtr<uint8_t> to_array(const std::string& val) {
- fidl::VectorPtr<uint8_t> ret = fidl::VectorPtr<uint8_t>::New(0);
- for (char c : val) {
- ret.push_back(c);
- }
- return ret;
-}
-
-inline fidl::VectorPtr<fidl::StringPtr> to_array(
- const std::vector<std::string>& val) {
- fidl::VectorPtr<fidl::StringPtr> ret =
- fidl::VectorPtr<fidl::StringPtr>::New(0);
- for (const std::string& s : val) {
- ret.push_back(s);
- }
- return ret;
-}
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_FIDL_ARRAY_TO_STRING_H_
diff --git a/lib/fidl/clone.h b/lib/fidl/clone.h
deleted file mode 100644
index 6836d9f..0000000
--- a/lib/fidl/clone.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIDL_CLONE_H_
-#define PERIDOT_LIB_FIDL_CLONE_H_
-
-#include <memory>
-
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fidl/cpp/vector.h>
-
-namespace modular {
-
-template <typename T>
-T CloneStruct(const T& value) {
- T new_value;
- value.Clone(&new_value);
- return new_value;
-}
-
-template <typename T>
-std::unique_ptr<T> CloneOptional(const T& value) {
- T new_value;
- value.Clone(&new_value);
- return fidl::MakeOptional<T>(std::move(new_value));
-}
-
-template <typename T>
-std::unique_ptr<T> CloneOptional(const std::unique_ptr<T>& value_ptr) {
- if (value_ptr) {
- T new_value;
- value_ptr->Clone(&new_value);
- return fidl::MakeOptional<T>(std::move(new_value));
- }
- return nullptr;
-}
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_FIDL_CLONE_H_
diff --git a/lib/fidl/environment.cc b/lib/fidl/environment.cc
deleted file mode 100644
index ac97109..0000000
--- a/lib/fidl/environment.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/fidl/environment.h"
-
-#include <lib/async/default.h>
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-Environment::Environment(const fuchsia::sys::EnvironmentPtr& parent_env,
- const std::string& label,
- const std::vector<std::string>& service_names,
- bool kill_on_oom)
- : vfs_(async_get_default_dispatcher()) {
- InitEnvironment(parent_env, label, service_names, kill_on_oom);
-}
-
-Environment::Environment(const Environment* const parent_scope,
- const std::string& label,
- const std::vector<std::string>& service_names,
- bool kill_on_oom)
- : vfs_(async_get_default_dispatcher()) {
- FXL_DCHECK(parent_scope != nullptr);
- InitEnvironment(parent_scope->environment(), label, service_names,
- kill_on_oom);
-}
-
-fuchsia::sys::Launcher* Environment::GetLauncher() {
- if (!env_launcher_) {
- env_->GetLauncher(env_launcher_.NewRequest());
- }
- return env_launcher_.get();
-}
-
-zx::channel Environment::OpenAsDirectory() {
- zx::channel h1, h2;
- if (zx::channel::create(0, &h1, &h2) != ZX_OK)
- return zx::channel();
- if (vfs_.ServeDirectory(services_dir_, std::move(h1)) != ZX_OK)
- return zx::channel();
- return h2;
-}
-
-void Environment::InitEnvironment(
- const fuchsia::sys::EnvironmentPtr& parent_env, const std::string& label,
- const std::vector<std::string>& service_names, bool kill_on_oom) {
- services_dir_ = fbl::AdoptRef(new fs::PseudoDir);
- fuchsia::sys::ServiceListPtr service_list(new fuchsia::sys::ServiceList);
- for (const auto& name : service_names) {
- service_list->names.push_back(name);
- }
- service_list->host_directory = OpenAsDirectory();
- parent_env->CreateNestedEnvironment(
- env_.NewRequest(), env_controller_.NewRequest(), label,
- std::move(service_list),
- {.inherit_parent_services = true, .kill_on_oom = kill_on_oom});
-}
-
-} // namespace modular
diff --git a/lib/fidl/environment.h b/lib/fidl/environment.h
deleted file mode 100644
index 570abd6..0000000
--- a/lib/fidl/environment.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIDL_ENVIRONMENT_H_
-#define PERIDOT_LIB_FIDL_ENVIRONMENT_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <fbl/ref_ptr.h>
-#include <fs/pseudo-dir.h>
-#include <fs/service.h>
-#include <fs/synchronous-vfs.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fit/function.h>
-
-namespace modular {
-
-// Provides fate separation of sets of applications run by one application. The
-// environment services are delegated to the parent environment.
-class Environment {
- public:
- Environment(const fuchsia::sys::EnvironmentPtr& parent_env,
- const std::string& label,
- const std::vector<std::string>& service_names, bool kill_on_oom);
-
- Environment(const Environment* parent_scope, const std::string& label,
- const std::vector<std::string>& service_names, bool kill_on_oom);
-
- template <typename Interface>
- void AddService(fidl::InterfaceRequestHandler<Interface> handler,
- const std::string& service_name = Interface::Name_) {
- auto service = fbl::AdoptRef(new fs::Service(
- [this, handler = std::move(handler)](zx::channel channel) {
- handler(fidl::InterfaceRequest<Interface>(std::move(channel)));
- return ZX_OK;
- }));
- services_dir_->AddEntry(service_name, service);
- }
-
- fuchsia::sys::Launcher* GetLauncher();
-
- const fuchsia::sys::EnvironmentPtr& environment() const { return env_; }
-
- private:
- zx::channel OpenAsDirectory();
-
- void InitEnvironment(const fuchsia::sys::EnvironmentPtr& parent_env,
- const std::string& label,
- const std::vector<std::string>& service_names,
- bool kill_on_oom);
-
- fuchsia::sys::EnvironmentPtr env_;
- fuchsia::sys::LauncherPtr env_launcher_;
- fuchsia::sys::EnvironmentControllerPtr env_controller_;
- fs::SynchronousVfs vfs_;
- fbl::RefPtr<fs::PseudoDir> services_dir_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_FIDL_ENVIRONMENT_H_
diff --git a/lib/fidl/json_xdr.cc b/lib/fidl/json_xdr.cc
deleted file mode 100644
index e9b72b6..0000000
--- a/lib/fidl/json_xdr.cc
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/fidl/json_xdr.h"
-
-#include <string>
-
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-
-namespace modular {
-
-namespace {
-const char* JsonTypeName(const rapidjson::Type type) {
- switch (type) {
- case rapidjson::kNullType:
- return "null";
- case rapidjson::kFalseType:
- return "false";
- case rapidjson::kTrueType:
- return "true";
- case rapidjson::kObjectType:
- return "object";
- case rapidjson::kArrayType:
- return "array";
- case rapidjson::kStringType:
- return "string";
- case rapidjson::kNumberType:
- return "number";
- };
-}
-} // namespace
-
-// HACK(mesch): We should not need this, get rid of it.
-thread_local JsonValue XdrContext::null_ = JsonValue();
-
-XdrContext::XdrContext(const XdrOp op, JsonDoc* const doc,
- std::string* const error)
- : parent_(nullptr),
- name_(nullptr),
- error_(error),
- op_(op),
- doc_(doc),
- value_(doc) {
- FXL_DCHECK(doc_ != nullptr);
- FXL_DCHECK(error_ != nullptr);
-}
-
-XdrContext::XdrContext(XdrContext* const parent, const char* const name,
- const XdrOp op, JsonDoc* const doc,
- JsonValue* const value)
- : parent_(parent),
- name_(name),
- error_(nullptr),
- op_(op),
- doc_(doc),
- value_(value) {
- FXL_DCHECK(parent_ != nullptr);
- FXL_DCHECK(doc_ != nullptr);
- FXL_DCHECK(value_ != nullptr);
-}
-
-XdrContext::~XdrContext() = default;
-
-bool XdrContext::Version(uint32_t version) {
- constexpr char kVersion[] = "@version";
- switch (op_) {
- case XdrOp::TO_JSON:
- Field(kVersion).Value(&version);
- return true;
-
- case XdrOp::FROM_JSON: {
- if (!value_->IsObject()) {
- AddError("Version(): must be on an Object.");
- return false;
- }
- auto i = value_->FindMember(kVersion);
- if (i == value_->MemberEnd()) {
- AddError("Version(): No @version present.");
- return false;
- }
- uint32_t actual_version{};
- Field(kVersion).Value(&actual_version);
- if (actual_version != version) {
- AddError("Version(): Found version " + std::to_string(actual_version) +
- " but expected version " + std::to_string(version));
- return false;
- }
- return true;
- }
- }
-}
-
-void XdrContext::Value(unsigned char* const data) {
- switch (op_) {
- case XdrOp::TO_JSON:
- value_->Set(static_cast<int>(*data), allocator());
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->Is<int>()) {
- AddError("Value() of unsigned char: int expected");
- return;
- }
- *data = static_cast<unsigned char>(value_->Get<int>());
- }
-}
-
-void XdrContext::Value(int8_t* const data) {
- switch (op_) {
- case XdrOp::TO_JSON:
- value_->Set(static_cast<int>(*data), allocator());
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->Is<int>()) {
- AddError("Value() of int8: int expected");
- return;
- }
- *data = static_cast<int8_t>(value_->Get<int>());
- }
-}
-
-void XdrContext::Value(unsigned short* const data) {
- switch (op_) {
- case XdrOp::TO_JSON:
- value_->Set(static_cast<int>(*data), allocator());
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->Is<int>()) {
- AddError("Value() of unsigned short: int expected");
- return;
- }
- *data = static_cast<unsigned short>(value_->Get<int>());
- }
-}
-
-void XdrContext::Value(short* const data) {
- switch (op_) {
- case XdrOp::TO_JSON:
- value_->Set(static_cast<int>(*data), allocator());
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->Is<int>()) {
- AddError("Value() of short: int expected");
- return;
- }
- *data = static_cast<short>(value_->Get<int>());
- }
-}
-
-void XdrContext::Value(fidl::StringPtr* const data) {
- switch (op_) {
- case XdrOp::TO_JSON:
- if (data->is_null()) {
- value_->SetNull();
- } else {
- value_->SetString(data->get(), allocator());
- }
- break;
-
- case XdrOp::FROM_JSON:
- if (value_->IsNull()) {
- data->reset();
- } else if (value_->IsString()) {
- *data = value_->GetString();
- } else {
- AddError("Value() of fidl::StringPtr: string expected");
- }
- break;
- }
-}
-
-void XdrContext::Value(std::string* const data) {
- switch (op_) {
- case XdrOp::TO_JSON:
- value_->SetString(*data, allocator());
- break;
-
- case XdrOp::FROM_JSON:
- if (value_->IsString()) {
- *data = value_->GetString();
- } else {
- AddError("Value() of std::string: string expected");
- }
- break;
- }
-}
-
-XdrContext XdrContext::Field(const char field[]) {
- switch (op_) {
- case XdrOp::TO_JSON:
- if (!value_->IsObject()) {
- value_->SetObject();
- }
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->IsObject()) {
- AddError("Object expected for field " + std::string(field));
- return {this, field, op_, doc_, &null_};
- }
- }
-
- auto i = value_->FindMember(field);
- if (i != value_->MemberEnd()) {
- return {this, field, op_, doc_, &i->value};
- }
-
- switch (op_) {
- case XdrOp::TO_JSON: {
- JsonValue name{field, allocator()};
- value_->AddMember(name, JsonValue(), allocator());
- auto i = value_->FindMember(field);
- FXL_DCHECK(i != value_->MemberEnd());
- return {this, field, op_, doc_, &i->value};
- }
-
- case XdrOp::FROM_JSON:
- return {this, field, op_, doc_, &null_};
- }
-}
-
-XdrContext XdrContext::Element(const size_t i) {
- switch (op_) {
- case XdrOp::TO_JSON:
- if (!value_->IsArray()) {
- value_->SetArray();
- }
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->IsArray()) {
- AddError("Array expected for element " + std::to_string(i));
- return {this, nullptr, op_, doc_, &null_};
- }
- }
-
- if (i < value_->Size()) {
- return {this, nullptr, op_, doc_, &value_->operator[](i)};
- }
-
- switch (op_) {
- case XdrOp::TO_JSON:
- while (i >= value_->Size()) {
- value_->PushBack(JsonValue(), allocator());
- }
- return {this, nullptr, op_, doc_, &value_->operator[](i)};
-
- case XdrOp::FROM_JSON:
- return {this, nullptr, op_, doc_, &null_};
- }
-}
-
-void XdrContext::AddError(const std::string& message) {
- auto error = AddError();
- error->append(": " + message + "\n");
-}
-
-std::string* XdrContext::AddError() {
- std::string* const ret = parent_ ? parent_->AddError() : error_;
-
- if (parent_) {
- ret->append("/");
- }
-
- ret->append(JsonTypeName(value_->GetType()));
-
- if (name_) {
- ret->append(" ");
- ret->append(name_);
- }
-
- return ret;
-}
-
-std::string* XdrContext::GetError() {
- return parent_ ? parent_->GetError() : error_;
-}
-
-} // namespace modular
diff --git a/lib/fidl/json_xdr.h b/lib/fidl/json_xdr.h
deleted file mode 100644
index da4d727..0000000
--- a/lib/fidl/json_xdr.h
+++ /dev/null
@@ -1,695 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIDL_JSON_XDR_H_
-#define PERIDOT_LIB_FIDL_JSON_XDR_H_
-
-#include <map>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "rapidjson/document.h"
-
-namespace modular {
-
-// This file provides a tool to serialize arbitrary data structures
-// into JSON, and back. It specifically supports serialization of FIDL
-// data (structs, arrays, maps, and combinations thereof), but FIDL is
-// not a requirement. For example, support for STL containers in
-// addition to FIDL containers is easy to add once we need it.
-//
-// We use JSON as the serialization format to store structured values
-// (and at times also structured keys) in the ledger.
-//
-// The design is inspired by Sun RPC's XDR, specifically the definiton
-// of "filters". A filter function takes an operation and a data
-// pointer, and depending on the operation parameter either serializes
-// or deserializes the data. There is one such filter function for
-// every data type. A filter for a simple data type does different
-// things for serialization and deserialization, so having a single
-// one for both operations instead of two separate functions barely
-// reduces code size. However, the efficiency of this design shows in
-// composition: A filter for a struct can be written by simply calling
-// the filters for each field of the struct and passing the operation
-// parameter down. Thus, a filter function for a struct is half the
-// code size of a pair of serialization/deserialization functions.
-//
-// NOTES:
-//
-// XDR is not sync: Although the XDR operation can be applied to an
-// existing instance of the output end (an existing FIDL struct, or an
-// existing JSON AST), full synchronization of the data structure is
-// not guaranteed. All data that exist in the input are added to the
-// output, but not necessarily all data that don't exist in the input
-// are removed from the output. Also, if an error occurs, the output
-// is left in some intermediate state. The most suitable use for
-// updates as of now is to always create a fresh output instance, and
-// if the transciption succeeds, replace the previous instance by the
-// fresh instance.
-//
-// XDR is not about resolving conflicts: If an existing output
-// instance is updated using XDR, we might improve accuracy of
-// removing data that no longer exist, but it is out of the scope of
-// XDR (at least for now) to note that input data conflict with
-// existing output data, and resolving the conflict. Conflict
-// resolution between different versions of data is most likely
-// handled outside XDR.
-//
-// It may be that we will use XDR to support conflict resolution in a
-// data type agnostic way: Instead of defining a conflict resolution
-// between e.g. STL or FIDL data structures, we might instead define
-// XDR filters for them, translate all values to JSON, apply conflict
-// resolution to JSON, and translate the result back.
-//
-// SCHEMA VERSION BACK COMPATIBILITY:
-//
-// The schema of the persistent data is defined in terms of filter functions. In
-// order to support new versions of the code reading versions of the data
-// written by old versions of the code, filter functions are always defined by
-// the client at the top level entry points as lists, never as single functions.
-//
-// The lists contain the filter for the current version of the schema at the
-// top, and filters for reading previous versions into the current version of
-// the code below.
-//
-// Whenever the storage schema changes, a new version of the filter is created
-// and add it to the version list.
-//
-// If the memory schema changes, filters of all versions are adjusted as
-// necessary.
-//
-// Filters that don't change can be reused between versions. If a filter does
-// not change, but the ones that it uses do change, templates can be used to
-// save on code duplication.
-//
-// TODO(mesch): Right now there is no way to ensure that old versions of the
-// code will never read new versions of the data. Support for this is expected
-// from the Ledger, and partially from an upcoming API for explicit version
-// numbers.
-//
-// See comments on XdrFilterType, XdrRead(), and XdrWrite() for details.
-
-class XdrContext;
-
-// The two operations: reading from JSON or writing to JSON.
-enum class XdrOp {
- TO_JSON = 0,
- FROM_JSON = 1,
-};
-
-// Custom types are serialized by passing a function of this type to a method on
-// XdrContext. Note this is a pointer type that points to a const (an existing
-// function). So we will never use a reference or a const of it. However,
-// argument values of such will still be defined const.
-//
-// The top level entry functions used by clients never pass a single filter
-// function alone, but always a list of filters for different versions of the
-// data, such that the reading code can fall back to functions reading
-// previously written versions. Such lists can (and should) be defined
-// statically as constexpr:
-//
-// void XdrFoo_v1(XdrContext* const xdr, Foo* const data) { ... }
-// void XdrFoo_v2(XdrContext* const xdr, Foo* const data) { ... }
-//
-// constexpr XdrFilterType<Foo> XdrFoo[] = {
-// XdrFoo_v1,
-// XdrFoo_v2,
-// nullptr,
-// };
-//
-// Foo foo;
-// XdrRead(json, &foo, XdrFoo);
-//
-// XdrRead and XdrWrite are defined to take an XdrFilterList<> argument, which
-// that constexpr can be passed to. See Definition of XdrRead(), below.
-template <typename T>
-using XdrFilterType = void (*)(XdrContext*, T*);
-
-template <typename T>
-using XdrFilterList = void (*const*)(XdrContext*, T*);
-
-// A generic implementation of such a filter, which works for simple
-// types. (The implementation uses XdrContext, so it's below.)
-template <typename V>
-void XdrFilter(XdrContext* xdr, V* value);
-
-// XdrContext holds on to a JSON document as well as a specific
-// position inside the document on which its methods operate, as well
-// as the operation (writing to JSON, reading from JSON) that is
-// executed when methods are called.
-//
-// There are two kinds of methods: Value() and Field(). Value()
-// affects the current JSON value itself. Field() assumes the current
-// JSON value is an Object, accesses a property on it and affects the
-// value of the property.
-//
-// Clients usually call Value(); filters for custom types usually call
-// Field().
-class XdrContext {
- public:
- XdrContext(XdrOp op, JsonDoc* doc, std::string* error);
-
- ~XdrContext();
-
- // Returns the XdrOp that this XdrContext was created with.
- //
- // This is required by some XdrFilters that cannot use the same code to set or
- // get data from objects. However, in general, try to avoid special-casing
- // an XdrFilter to change behavior based on whether it's translating to or
- // from JSON.
- XdrOp op() const { return op_; }
-
- // Below are methods to handle values on properties of objects for
- // handling standalone values. These methods are called by filter
- // code during a serialization/deserialization operation.
-
- // The version of a struct. On Write, the version number is written and it
- // always returns true. On Read, raises an error and returns false if the
- // version number read doesn't match the version number passed in. Thus it
- // gives an explicit way to a filter function to force an error.
- //
- // The filter should also return early so as to not partially read data.
- //
- // This can be applied at any level, but only when it happens as the first
- // call in the top level filter will it fully prevent partial reads.
- //
- // How it should be used:
- //
- // void XdrFoo_v1(XdrContext* const xdr, Foo* const data) { ... }
- // void XdrFoo_v2(XdrContext* const xdr, Foo* const data) {
- // if (!xdr->Version(2)) {
- // return;
- // }
- // ...
- // }
- //
- // constexpr XdrFilterType<Foo> XdrFoo[] = {
- // XdrFoo_v2,
- // XdrFoo_v1,
- // nullptr,
- // };
- //
- // Foo foo;
- // XdrRead(json, &foo, XdrFoo);
- //
- // Notice that _v1 doesn't need to have a Version() call. This is usual when
- // the first use of the data predates the introduction of the Version()
- // mechanism.
- //
- // This method cannot be used (and returns false and logs an error) in a
- // context that is not Object.
- //
- // It writes the reserved field name "@version" to the current Object context.
- //
- // The value passed to the call inside the Xdr filter function should never be
- // defined as a constant outside of the filter function, because then it
- // becomes tempting to change it to a new version number without creating a
- // copy of the filter function for the previous version number.
- bool Version(uint32_t version);
-
- // A field of a struct. The value type V is assumed to be one of the
- // primitive JSON data types. If anything else is passed here and
- // not to the method below with a custom filter, the rapidjson code
- // will fail to compile.
- template <typename V>
- void Field(const char field[], V* const data) {
- Field(field).Value(data);
- }
-
- // If we supply a custom filter for the value of a field, the data
- // type of the field very often does not match directly the data
- // type for which we write a filter, therefore this template has two
- // type parameters. This happens in several situations:
- //
- // 1. Fields with fidl struct types. The field data type, which we pass the
- // data for, is a std::unique_ptr<X>, but the filter supplied is for X (and
- // thus takes X*).
- //
- // 2. Fields with fidl array types. The filter is for an element,
- // but the field is the array type.
- //
- // 3. Fields with STL container types. The filter is for an element,
- // but the field is the container type.
- //
- // We could handle this by specialization, it's much simpler to just cover all
- // possible combinations with a template of higher dimension, at the expense
- // of covering also a few impossible cases.
- template <typename D, typename V>
- void Field(const char field[], D* const data, XdrFilterType<V> const filter) {
- Field(field).Value(data, filter);
- }
-
- // Below are methods analog to those for values on properties of
- // objects for handling standalone values. These methods are called
- // by XdrContext client code such as XdrRead() and XdrWrite() to
- // start a serialization/deserialization operation.
-
- // A simple value is mapped to the corresponding JSON type (int,
- // float, bool) directly.
- template <typename V>
- typename std::enable_if<!std::is_enum<V>::value>::type Value(V* data) {
- switch (op_) {
- case XdrOp::TO_JSON:
- value_->Set(*data, allocator());
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->Is<V>()) {
- AddError("Unexpected type.");
- return;
- }
- *data = value_->Get<V>();
- }
- }
-
- // An enum is mapped to a JSON int.
- template <typename V>
- typename std::enable_if<std::is_enum<V>::value>::type Value(V* const data) {
- switch (op_) {
- case XdrOp::TO_JSON:
- value_->Set(static_cast<int>(*data), allocator());
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->Is<int>()) {
- AddError("Unexpected type.");
- return;
- }
- *data = static_cast<V>(value_->Get<int>());
- }
- }
-
- // Bytes and shorts, both signed and unsigned, are mapped to JSON int, since
- // they are not directly supported in the rapidjson API.
- void Value(unsigned char* data);
- void Value(int8_t* data);
- void Value(unsigned short* data);
- void Value(short* data);
-
- // A fidl String is mapped to either (i.e., the union type of) JSON
- // null or JSON string.
- void Value(fidl::StringPtr* data);
-
- // An STL string is mapped to a JSON string.
- void Value(std::string* data);
-
- // A value of a custom type is mapped using the custom filter. See
- // the corresponding Field() method for why there are two type
- // parameters here.
- template <typename D, typename V>
- void Value(D* data, XdrFilterType<V> filter) {
- filter(this, data);
- }
-
- // Operator & may be overloaded to return a type that acts like a pointer, but
- // isn't one, and therefore is not matched by the Value<D,V>(data, filter)
- // method above. In that case, we need to exercise the operator * of the
- // pointer type explicitly.
- //
- // This is needed for example for std::vector<bool>, where &at(i) is a bit
- // iterator, not a bool*.
- template <typename Ptr, typename V>
- void Value(Ptr data, XdrFilterType<V> filter) {
- switch (op_) {
- case XdrOp::TO_JSON: {
- V value = *data;
- filter(this, &value);
- break;
- }
-
- case XdrOp::FROM_JSON: {
- V value;
- filter(this, &value);
- *data = std::move(value);
- }
- }
- }
-
- template <typename S>
- void Value(std::unique_ptr<S>* data, XdrFilterType<S> filter) {
- switch (op_) {
- case XdrOp::TO_JSON:
- if (!data->get()) {
- value_->SetNull();
- } else {
- value_->SetObject();
- filter(this, data->get());
- }
- break;
-
- case XdrOp::FROM_JSON:
- if (value_->IsNull()) {
- data->reset();
- } else {
- if (!value_->IsObject()) {
- AddError("Object type expected.");
- return;
- }
-
- *data = std::make_unique<S>();
- filter(this, data->get());
- }
- }
- }
-
- // A fidl vector is mapped to JSON null and JSON Array with a custom
- // filter for the elements.
- template <typename D, typename V>
- void Value(fidl::VectorPtr<D>* const data, const XdrFilterType<V> filter) {
- switch (op_) {
- case XdrOp::TO_JSON:
- if (data->is_null()) {
- value_->SetNull();
-
- } else {
- value_->SetArray();
- value_->Reserve((*data)->size(), allocator());
-
- for (size_t i = 0; i < (*data)->size(); ++i) {
- Element(i).Value(&(*data)->at(i), filter);
- }
- }
- break;
-
- case XdrOp::FROM_JSON:
- if (value_->IsNull()) {
- data->reset();
-
- } else {
- if (!value_->IsArray()) {
- AddError("Array type expected.");
- return;
- }
-
- // The resize() call has two purposes:
- //
- // (1) Setting data to non-null, even if there are only zero
- // elements. This is essential, otherwise the FIDL output
- // is wrong (i.e., the FIDL output cannot be used in FIDL
- // method calls without crashing).
- //
- // (2) It saves on allocations for growing the underlying
- // vector one by one.
- data->resize(value_->Size());
-
- for (size_t i = 0; i < value_->Size(); ++i) {
- Element(i).Value(&(*data)->at(i), filter);
- }
- }
- }
- }
-
- // A fidl array with a simple element type can infer its element
- // value filter from the type parameters of the array.
- template <typename V>
- void Value(fidl::VectorPtr<V>* const data) {
- Value(data, XdrFilter<V>);
- }
-
- // A fidl array is mapped to JSON null and JSON Array with a custom
- // filter for the elements.
- template <typename D, size_t N, typename V>
- void Value(fidl::Array<D, N>* const data, const XdrFilterType<V> filter) {
- switch (op_) {
- case XdrOp::TO_JSON: {
- value_->SetArray();
- value_->Reserve(N, allocator());
-
- for (size_t i = 0; i < N; ++i) {
- Element(i).Value(&data->at(i), filter);
- }
- break;
- }
-
- case XdrOp::FROM_JSON: {
- if (!value_->IsArray()) {
- AddError("Array type expected.");
- return;
- }
-
- if (value_->Size() != N) {
- AddError(std::string("Array size unexpected: found ") +
- std::to_string(value_->Size()) + " expected " +
- std::to_string(N));
- return;
- }
-
- for (size_t i = 0; i < N; ++i) {
- Element(i).Value(&data->at(i), filter);
- }
- }
- }
- }
-
- // A fidl array with a simple element type can infer its element
- // value filter from the type parameters of the array.
- template <typename V, size_t N>
- void Value(fidl::Array<V, N>* const data) {
- Value(data, XdrFilter<V>);
- }
-
- // An STL vector is mapped to JSON Array with a custom filter for the
- // elements.
- template <typename D, typename V>
- void Value(std::vector<D>* const data, const XdrFilterType<V> filter) {
- switch (op_) {
- case XdrOp::TO_JSON:
- value_->SetArray();
- value_->Reserve(data->size(), allocator());
-
- for (size_t i = 0; i < data->size(); ++i) {
- Element(i).Value(&data->at(i), filter);
- }
- break;
-
- case XdrOp::FROM_JSON:
- if (!value_->IsArray()) {
- AddError("Array type expected.");
- return;
- }
-
- data->resize(value_->Size());
-
- for (size_t i = 0; i < value_->Size(); ++i) {
- Element(i).Value(&data->at(i), filter);
- }
- }
- }
-
- // An STL vector with a simple element type can infer its element value filter
- // from the type parameters of the array.
- template <typename V>
- void Value(std::vector<V>* const data) {
- Value(data, XdrFilter<V>);
- }
-
- // An STL map is mapped to an array of pairs of key and value, because maps
- // can have non-string keys. There are two filters, for the key type and the
- // value type.
- template <typename K, typename V>
- void Value(std::map<K, V>* const data, XdrFilterType<K> const key_filter,
- XdrFilterType<V> const value_filter) {
- switch (op_) {
- case XdrOp::TO_JSON: {
- value_->SetArray();
- value_->Reserve(data->size(), allocator());
-
- size_t index = 0;
- for (auto i = data->begin(); i != data->end(); ++i) {
- XdrContext&& element = Element(index++);
- element.value_->SetObject();
-
- K k{i->first};
- element.Field("@k").Value(&k, key_filter);
-
- V v{i->second};
- element.Field("@v").Value(&v, value_filter);
- }
- break;
- }
-
- case XdrOp::FROM_JSON: {
- if (!value_->IsArray()) {
- AddError("Array type expected.");
- return;
- }
-
- // Erase existing data in case there are some left.
- data->clear();
-
- size_t index = 0;
- for (auto i = value_->Begin(); i != value_->End(); ++i) {
- XdrContext&& element = Element(index++);
-
- K k;
- element.Field("@k").Value(&k, key_filter);
-
- V v;
- element.Field("@v").Value(&v, value_filter);
-
- data->emplace(std::move(k), std::move(v));
- }
- }
- }
- }
-
- // An STL map with only simple values can infer its key value filters from the
- // type parameters of the map.
- template <typename K, typename V>
- void Value(std::map<K, V>* const data) {
- Value(data, XdrFilter<K>, XdrFilter<V>);
- }
-
- private:
- XdrContext(XdrContext* parent, const char* name, XdrOp op, JsonDoc* doc,
- JsonValue* value);
- JsonDoc::AllocatorType& allocator() const { return doc_->GetAllocator(); }
- XdrContext Field(const char field[]);
- XdrContext Element(size_t i);
-
- // Error reporting: Recursively requests the error string from the
- // parent, and on the way back appends a description of the current
- // JSON context hierarchy.
- void AddError(const std::string& message);
- std::string* AddError();
-
- // Return the root error string so that IgnoreError() can manipulate it.
- std::string* GetError();
-
- // The root of the context tree (where parent_ == nullptr) keeps a
- // string to write errors to. In an error situation the chain of
- // parent contexts is traversed up in order to (1) access the error
- // string to write to, (2) record the current context hierarchy in
- // an error message. Each level in the context hierarchy is
- // described using the type of value_ and, if present, name_. name_
- // is the name of the field for contexts that are values of a field,
- // otherwise nullptr.
- XdrContext* const parent_;
- const char* const name_;
- std::string* const error_;
-
- // These three fields represent the context itself: The operation to
- // perform (read or write), the value it will be performed on, and
- // the document the value is part of, in order to access the
- // allocator.
- const XdrOp op_;
- JsonDoc* const doc_;
- JsonValue* const value_;
-
- // A JSON value to continue processing on when the expected one is
- // not found in the JSON AST, to avoid value_ becoming null. It
- // needs to be thread local because it is a global that's modified
- // potentially by every ongoing XDR invocation.
- static thread_local JsonValue null_;
-
- // All Xdr* functions take a XdrContext* and pass it on. We might
- // want to change this once we support asynchronous input/output
- // operations, for example directly to/from a Ledger page rather
- // than just the JSON DOM.
- FXL_DISALLOW_COPY_AND_ASSIGN(XdrContext);
-};
-
-// This filter function works for all types for which XdrContext has a Value()
-// method defined.
-template <typename V>
-void XdrFilter(XdrContext* const xdr, V* const value) {
- xdr->Value(value);
-}
-
-// Clients use the following functions as entry points.
-
-// A wrapper function to read data from a JSON document. This may fail if the
-// JSON document doesn't match the structure required by any of the filter
-// versions. In that case it logs an error and returns false. Clients are
-// expected to either crash or recover e.g. by ignoring the value.
-//
-// The items in the filter versions list are tried in turn until one succeeds.
-// The filter versions list must end with a nullptr entry to mark the end.
-template <typename D, typename V>
-bool XdrRead(JsonDoc* const doc, D* const data,
- XdrFilterList<V> filter_versions) {
- std::vector<std::string> errors;
- for (XdrFilterList<V> filter = filter_versions; *filter; ++filter) {
- std::string error;
- XdrContext xdr(XdrOp::FROM_JSON, doc, &error);
- xdr.Value(data, *filter);
-
- if (error.empty()) {
- return true;
- }
-
- FXL_LOG(INFO) << "Filter failed, trying previous version.";
- errors.emplace_back(std::move(error));
- }
-
- FXL_LOG(ERROR) << "XdrRead: No filter version succeeded"
- << " to extract data from JSON: "
- << JsonValueToPrettyString(*doc) << std::endl;
- for (const std::string& error : errors) {
- FXL_LOG(INFO) << "XdrRead error message: " << error;
- }
-
- return false;
-}
-
-// A wrapper function to read data from a JSON string. This may fail if the JSON
-// doesn't parse or doesn't match the structure required by the filter version
-// list. In that case it logs an error and returns false. Clients are expected
-// to either crash or recover e.g. by ignoring the value.
-template <typename D, typename V>
-bool XdrRead(const std::string& json, D* const data,
- XdrFilterList<V> filter_versions) {
- JsonDoc doc;
- doc.Parse(json);
- if (doc.HasParseError()) {
- FXL_LOG(ERROR) << "Unable to parse data as JSON: " << json;
- return false;
- }
-
- return XdrRead(&doc, data, filter_versions);
-}
-
-// A wrapper function to write data as JSON doc. This never fails. It always
-// only uses the first version of the filter. It takes a filter version list
-// anyway for symmetry with XdrRead(), so that the same filter version list
-// constant can be passed to both XdrRead and XdrWrite.
-template <typename D, typename V>
-void XdrWrite(JsonDoc* const doc, D* const data,
- XdrFilterList<V> filter_versions) {
- std::string error;
- XdrContext xdr(XdrOp::TO_JSON, doc, &error);
- xdr.Value(data, filter_versions[0]);
- FXL_DCHECK(error.empty())
- << "There are no errors possible in XdrOp::TO_JSON: " << std::endl
- << error << std::endl
- << JsonValueToPrettyString(*doc) << std::endl;
-}
-
-// A wrapper function to write data as JSON to a string. This never fails.
-template <typename D, typename V>
-void XdrWrite(std::string* const json, D* const data,
- XdrFilterList<V> filter_versions) {
- JsonDoc doc;
- XdrWrite(&doc, data, filter_versions);
- *json = JsonValueToString(doc);
-}
-
-// A wrapper function to return data as a JSON string. This never fails.
-template <typename D, typename V>
-std::string XdrWrite(D* const data, XdrFilterList<V> filter_versions) {
- std::string json;
- XdrWrite(&json, data, filter_versions);
- return json;
-}
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_FIDL_JSON_XDR_H_
diff --git a/lib/fidl/json_xdr_unittest.cc b/lib/fidl/json_xdr_unittest.cc
deleted file mode 100644
index 9576ddc..0000000
--- a/lib/fidl/json_xdr_unittest.cc
+++ /dev/null
@@ -1,867 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/fidl/json_xdr.h"
-
-#include <map>
-#include <vector>
-
-#include <test/peridot/lib/fidl/jsonxdr/cpp/fidl.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-namespace json_xdr_unittest = ::test::peridot::lib::fidl::jsonxdr;
-
-struct T {
- int i;
- std::string s;
- bool b;
-
- std::vector<int> vi;
- std::vector<std::string> vs;
- std::vector<bool> vb;
-
- std::map<int, int> mi;
- std::map<std::string, int> ms;
- std::map<bool, bool> mb;
-};
-
-void XdrT_v1(XdrContext* const xdr, T* const data) {
- xdr->Field("i", &data->i);
- xdr->Field("s", &data->s);
- xdr->Field("b", &data->b);
- xdr->Field("vi", &data->vi);
- xdr->Field("vs", &data->vs);
- xdr->Field("vb", &data->vb);
- xdr->Field("mi", &data->mi);
- xdr->Field("ms", &data->ms);
- xdr->Field("mb", &data->mb);
-}
-
-constexpr XdrFilterType<T> XdrT[] = {
- XdrT_v1,
- nullptr,
-};
-
-TEST(Xdr, Struct) {
- std::string json;
-
- T t0;
- t0.i = 1;
- t0.s = "2";
- t0.b = true;
- t0.vi.push_back(3);
- t0.vs.emplace_back("4");
- t0.vb.push_back(true);
- t0.mi[5] = 6;
- t0.ms["7"] = 8;
- t0.mb[true] = false;
- XdrWrite(&json, &t0, XdrT);
-
- T t1;
- EXPECT_TRUE(XdrRead(json, &t1, XdrT));
-
- EXPECT_EQ(t1.i, t0.i);
- EXPECT_EQ(t1.s, t0.s);
- EXPECT_EQ(t1.b, t0.b);
- EXPECT_EQ(t1.vi, t0.vi);
- EXPECT_EQ(t1.vs, t0.vs);
- EXPECT_EQ(t1.vb, t0.vb);
- EXPECT_EQ(t1.mi, t0.mi);
- EXPECT_EQ(t1.ms, t0.ms);
- EXPECT_EQ(t1.mb, t0.mb);
-}
-
-void XdrT_v2(XdrContext* const xdr, T* const data) {
- xdr->Field("i", &data->i);
- xdr->Field("s", &data->s);
- xdr->Field("b", &data->b);
- xdr->Field("vi", &data->vi);
- xdr->Field("vs_v2", &data->vs);
- xdr->Field("vb", &data->vb);
- xdr->Field("mi", &data->mi);
- xdr->Field("ms", &data->ms);
- xdr->Field("mb", &data->mb);
-}
-
-TEST(Xdr, StructVersions) {
- // Filter versioning with version lists: Write with an old version of the
- // filter, then attempt to read with a newer version only, which fails.
- // Attempt again with a filter verision list that has both the old and the new
- // version of filter, which succeeds.
-
- std::string json;
-
- T t0;
- t0.i = 1;
- t0.s = "2";
- t0.b = true;
- t0.vi.push_back(3);
- t0.vs.emplace_back("4");
- t0.vb.push_back(true);
- t0.mi[5] = 6;
- t0.ms["7"] = 8;
- t0.mb[true] = false;
- XdrWrite(&json, &t0, XdrT);
-
- T t1;
-
- constexpr XdrFilterType<T> filter_versions_v2_only[] = {
- XdrT_v2,
- nullptr,
- };
-
- EXPECT_FALSE(XdrRead(json, &t1, filter_versions_v2_only));
-
- constexpr XdrFilterType<T> filter_versions_all[] = {
- XdrT_v2,
- XdrT_v1,
- nullptr,
- };
-
- EXPECT_TRUE(XdrRead(json, &t1, filter_versions_all));
-}
-
-void XdrT_v3(XdrContext* const xdr, T* const data) {
- if (!xdr->Version(3)) {
- return;
- }
-
- xdr->Field("i", &data->i);
- xdr->Field("s", &data->s);
- xdr->Field("b", &data->b);
- xdr->Field("vi", &data->vi);
- xdr->Field("vs", &data->vs);
- xdr->Field("vb", &data->vb);
- xdr->Field("mi", &data->mi);
- xdr->Field("ms", &data->ms);
- xdr->Field("mb", &data->mb);
-}
-
-TEST(Xdr, StructVersionsExplicitFallback) {
- // Filter versioning with explicit version numbers: Write with an old version
- // of the filter without version number, then attempt to read with a filter
- // that expects a version number, which fails. Attempt again with a filter
- // version list that has both the old and the new version of filter, which
- // succeeds.
-
- std::string json;
-
- T t0;
- t0.i = 1;
- t0.s = "2";
- t0.b = true;
- t0.vi.push_back(3);
- t0.vs.emplace_back("4");
- t0.vb.push_back(true);
- t0.mi[5] = 6;
- t0.ms["7"] = 8;
- t0.mb[true] = false;
- XdrWrite(&json, &t0, XdrT);
-
- T t1;
-
- constexpr XdrFilterType<T> filter_versions_v3_only[] = {
- XdrT_v3,
- nullptr,
- };
-
- EXPECT_FALSE(XdrRead(json, &t1, filter_versions_v3_only));
-
- constexpr XdrFilterType<T> filter_versions_all[] = {
- XdrT_v3,
- XdrT_v1,
- nullptr,
- };
-
- EXPECT_TRUE(XdrRead(json, &t1, filter_versions_all));
-}
-
-void XdrT_v4(XdrContext* const xdr, T* const data) {
- if (!xdr->Version(4)) {
- return;
- }
-
- xdr->Field("i", &data->i);
- xdr->Field("s", &data->s);
- xdr->Field("b", &data->b);
- xdr->Field("vi", &data->vi);
- xdr->Field("vs", &data->vs);
- xdr->Field("vb", &data->vb);
- xdr->Field("mi", &data->mi);
- xdr->Field("ms", &data->ms);
- xdr->Field("mb", &data->mb);
-}
-
-TEST(Xdr, StructVersionsExplicit) {
- // Filter versioning with explicit version numbers: Write with a version of
- // the filter with a version number, then attempt to read it back with the
- // same filter, which succeeds. Attempt to read it with a newer version
- // filter, which fails.
-
- std::string json;
-
- constexpr XdrFilterType<T> filter_versions_v3_only[] = {
- XdrT_v3,
- nullptr,
- };
-
- T t0;
- t0.i = 1;
- t0.s = "2";
- t0.b = true;
- t0.vi.push_back(3);
- t0.vs.emplace_back("4");
- t0.vb.push_back(true);
- t0.mi[5] = 6;
- t0.ms["7"] = 8;
- t0.mb[true] = false;
- XdrWrite(&json, &t0, filter_versions_v3_only);
-
- T t1;
- EXPECT_TRUE(XdrRead(json, &t1, filter_versions_v3_only));
-
- constexpr XdrFilterType<T> filter_versions_v4_only[] = {
- XdrT_v4,
- nullptr,
- };
-
- T t2;
- EXPECT_FALSE(XdrRead(json, &t2, filter_versions_v4_only));
-
- constexpr XdrFilterType<T> filter_versions_all[] = {
- XdrT_v4, XdrT_v3, XdrT_v2, XdrT_v1, nullptr,
- };
-
- T t3;
- EXPECT_TRUE(XdrRead(json, &t3, filter_versions_all));
-}
-
-void XdrStruct(XdrContext* const xdr, json_xdr_unittest::Struct* const data) {
- xdr->Field("item", &data->item);
-}
-
-void XdrUnion(XdrContext* const xdr, json_xdr_unittest::Union* const data) {
- // NOTE(mesch): There is no direct support for FIDL unions in XdrContext,
- // mostly because we cannot point a union field in the same way s we can point
- // to a struct field.
- //
- // The below is the current best way we have figured out to XDR unions. A
- // lager and more realistic (and slightly different) real life example of
- // XDRing a FIDL union type is XdrNoun() in story_controller_impl.cc.
-
- static constexpr char kTag[] = "@tag";
- static constexpr char kValue[] = "@value";
- static constexpr char kString[] = "string";
- static constexpr char kInt32[] = "int32";
-
- switch (xdr->op()) {
- case XdrOp::FROM_JSON: {
- std::string tag;
- xdr->Field(kTag, &tag);
-
- if (tag == kString) {
- std::string value;
- xdr->Field(kValue, &value);
- data->set_string(std::move(value));
-
- } else if (tag == kInt32) {
- int32_t value;
- xdr->Field(kValue, &value);
- data->set_int32(std::move(value));
-
- } else {
- ASSERT_TRUE(false) << "XdrUnion FROM_JSON unknown tag: " << tag;
- }
- break;
- }
-
- case XdrOp::TO_JSON: {
- std::string tag;
-
- switch (data->Which()) {
- case json_xdr_unittest::Union::Tag::kString: {
- tag = kString;
- std::string value = data->string();
- xdr->Field(kValue, &value);
- break;
- }
- case json_xdr_unittest::Union::Tag::kInt32: {
- tag = kInt32;
- int32_t value = data->int32();
- xdr->Field(kValue, &value);
- break;
- }
- case json_xdr_unittest::Union::Tag::Invalid:
- ASSERT_TRUE(false) << "XdrUnion TO_JSON unknown tag: "
- << static_cast<int>(data->Which());
- break;
- }
-
- xdr->Field(kTag, &tag);
- break;
- }
- }
-}
-
-// Data can be any of RequiredData, RequiredRepeatedRequiredData,
-// OptionalRepeatedRequiredData.
-template <typename Data>
-void XdrRequiredData_v1(XdrContext* const xdr, Data* const data) {
- xdr->Field("string", &data->string);
- xdr->Field("bool", &data->bool_);
- xdr->Field("int8", &data->int8);
- xdr->Field("int16", &data->int16);
- xdr->Field("int32", &data->int32);
- xdr->Field("int64", &data->int64);
- xdr->Field("uint8", &data->uint8);
- xdr->Field("uint16", &data->uint16);
- xdr->Field("uint32", &data->uint32);
- xdr->Field("uint64", &data->uint64);
- xdr->Field("float32", &data->float32);
- xdr->Field("float64", &data->float64);
- xdr->Field("struct", &data->struct_, XdrStruct);
- xdr->Field("enum", &data->enum_);
- xdr->Field("union", &data->union_, XdrUnion);
-}
-
-// Data can be any of OptionalData, RequiredRepeatedOptionalData,
-// OptionalRepeatedOptionalData.
-template <typename Data>
-void XdrOptionalData_v1(XdrContext* const xdr, Data* const data) {
- xdr->Field("string", &data->string);
- xdr->Field("struct", &data->struct_, XdrStruct);
- xdr->Field("union", &data->union_, XdrUnion);
-}
-
-constexpr XdrFilterType<json_xdr_unittest::RequiredData> XdrRequiredData[] = {
- XdrRequiredData_v1<json_xdr_unittest::RequiredData>,
- nullptr,
-};
-
-TEST(Xdr, FidlRequired) {
- std::string json;
-
- json_xdr_unittest::RequiredData t0;
-
- t0.string = "1";
- t0.bool_ = true;
- t0.int8 = 2;
- t0.int16 = 3;
- t0.int32 = 4;
- t0.int64 = 5;
- t0.uint8 = 6;
- t0.uint16 = 7;
- t0.uint32 = 8;
- t0.uint64 = 9;
- t0.float32 = 10;
- t0.float64 = 11;
- t0.struct_.item = 12;
- t0.enum_ = json_xdr_unittest::Enum::ONE;
- t0.union_.set_int32(13);
-
- XdrWrite(&json, &t0, XdrRequiredData);
-
- json_xdr_unittest::RequiredData t1;
- EXPECT_TRUE(XdrRead(json, &t1, XdrRequiredData));
-
- EXPECT_EQ(t1, t0) << json;
-
- // Technically not needed because the equality should cover this, but makes it
- // more transparent what's going on.
- EXPECT_EQ("1", t1.string);
- EXPECT_TRUE(t1.bool_);
- EXPECT_EQ(2, t1.int8);
- EXPECT_EQ(3, t1.int16);
- EXPECT_EQ(4, t1.int32);
- EXPECT_EQ(5, t1.int64);
- EXPECT_EQ(6u, t1.uint8);
- EXPECT_EQ(7u, t1.uint16);
- EXPECT_EQ(8u, t1.uint32);
- EXPECT_EQ(9u, t1.uint64);
- EXPECT_EQ(10.0f, t1.float32);
- EXPECT_EQ(11.0, t1.float64);
- EXPECT_EQ(12, t1.struct_.item);
- EXPECT_EQ(json_xdr_unittest::Enum::ONE, t1.enum_);
- EXPECT_TRUE(t1.union_.is_int32());
- EXPECT_EQ(13, t1.union_.int32());
-}
-
-constexpr XdrFilterType<json_xdr_unittest::OptionalData> XdrOptionalData[] = {
- XdrOptionalData_v1<json_xdr_unittest::OptionalData>,
- nullptr,
-};
-
-TEST(Xdr, FidlOptional) {
- std::string json;
-
- json_xdr_unittest::OptionalData t0;
-
- t0.string = "1";
- t0.struct_ = json_xdr_unittest::Struct::New();
- t0.struct_->item = 12;
- t0.union_ = json_xdr_unittest::Union::New();
- t0.union_->set_int32(13);
-
- XdrWrite(&json, &t0, XdrOptionalData);
-
- json_xdr_unittest::OptionalData t1;
- EXPECT_TRUE(XdrRead(json, &t1, XdrOptionalData));
-
- EXPECT_EQ(t1, t0) << json;
-
- // See comment in FidlRequired.
- EXPECT_FALSE(t1.string.is_null());
- EXPECT_EQ("1", t1.string);
-
- EXPECT_FALSE(nullptr == t1.struct_);
- EXPECT_EQ(12, t1.struct_->item);
-
- EXPECT_FALSE(nullptr == t1.union_);
- EXPECT_TRUE(t1.union_->is_int32());
- EXPECT_EQ(13, t1.union_->int32());
-
- t1.string.reset();
- t1.struct_.reset();
- t1.union_.reset();
-
- XdrWrite(&json, &t1, XdrOptionalData);
-
- json_xdr_unittest::OptionalData t2;
- EXPECT_TRUE(XdrRead(json, &t2, XdrOptionalData));
-
- EXPECT_EQ(t2, t1) << json;
-
- // See comment in FidlRequired.
- EXPECT_TRUE(t2.string.is_null());
- EXPECT_TRUE(nullptr == t2.struct_);
- EXPECT_TRUE(nullptr == t2.union_);
-}
-
-constexpr XdrFilterType<json_xdr_unittest::RequiredRepeatedRequiredData>
- XdrRequiredRepeatedRequiredData[] = {
- XdrRequiredData_v1<json_xdr_unittest::RequiredRepeatedRequiredData>,
- nullptr,
-};
-
-TEST(Xdr, FidlRequiredRepeatedRequired) {
- std::string json;
-
- json_xdr_unittest::RequiredRepeatedRequiredData t0;
-
- t0.string.push_back("1");
- t0.bool_.push_back(true);
- t0.int8.push_back(2);
- t0.int16.push_back(3);
- t0.int32.push_back(4);
- t0.int64.push_back(5);
- t0.uint8.push_back(6);
- t0.uint16.push_back(7);
- t0.uint32.push_back(8);
- t0.uint64.push_back(9);
- t0.float32.push_back(10);
- t0.float64.push_back(11);
- t0.struct_.push_back({12});
- t0.enum_.push_back(json_xdr_unittest::Enum::ONE);
-
- json_xdr_unittest::Union u;
- u.set_int32(13);
- t0.union_.push_back(std::move(u));
-
- XdrWrite(&json, &t0, XdrRequiredRepeatedRequiredData);
-
- json_xdr_unittest::RequiredRepeatedRequiredData t1;
- EXPECT_TRUE(XdrRead(json, &t1, XdrRequiredRepeatedRequiredData));
-
- EXPECT_EQ(t1, t0) << json;
-
- EXPECT_EQ(1u, t1.string.size());
- EXPECT_EQ(1u, t1.bool_.size());
- EXPECT_EQ(1u, t1.int8.size());
- EXPECT_EQ(1u, t1.int16.size());
- EXPECT_EQ(1u, t1.int32.size());
- EXPECT_EQ(1u, t1.int64.size());
- EXPECT_EQ(1u, t1.uint8.size());
- EXPECT_EQ(1u, t1.uint16.size());
- EXPECT_EQ(1u, t1.uint32.size());
- EXPECT_EQ(1u, t1.uint64.size());
- EXPECT_EQ(1u, t1.float32.size());
- EXPECT_EQ(1u, t1.float64.size());
- EXPECT_EQ(1u, t1.struct_.size());
- EXPECT_EQ(1u, t1.enum_.size());
- EXPECT_EQ(1u, t1.union_.size());
-
- EXPECT_EQ("1", t1.string.at(0));
- EXPECT_TRUE(t1.bool_.at(0));
- EXPECT_EQ(2, t1.int8.at(0));
- EXPECT_EQ(3, t1.int16.at(0));
- EXPECT_EQ(4, t1.int32.at(0));
- EXPECT_EQ(5, t1.int64.at(0));
- EXPECT_EQ(6u, t1.uint8.at(0));
- EXPECT_EQ(7u, t1.uint16.at(0));
- EXPECT_EQ(8u, t1.uint32.at(0));
- EXPECT_EQ(9u, t1.uint64.at(0));
- EXPECT_EQ(10.0f, t1.float32.at(0));
- EXPECT_EQ(11.0, t1.float64.at(0));
- EXPECT_EQ(12, t1.struct_.at(0).item);
- EXPECT_EQ(json_xdr_unittest::Enum::ONE, t1.enum_.at(0));
- EXPECT_TRUE(t1.union_.at(0).is_int32());
- EXPECT_EQ(13, t1.union_.at(0).int32());
-}
-
-constexpr XdrFilterType<json_xdr_unittest::RequiredRepeatedOptionalData>
- XdrRequiredRepeatedOptionalData[] = {
- XdrOptionalData_v1<json_xdr_unittest::RequiredRepeatedOptionalData>,
- nullptr,
-};
-
-TEST(Xdr, FidlRequiredRepeatedOptional) {
- std::string json;
-
- json_xdr_unittest::RequiredRepeatedOptionalData t0;
- t0.string.push_back("1");
-
- json_xdr_unittest::StructPtr s = json_xdr_unittest::Struct::New();
- s->item = 12;
- t0.struct_.push_back(std::move(s));
-
- json_xdr_unittest::UnionPtr u = json_xdr_unittest::Union::New();
- u->set_int32(13);
- t0.union_.push_back(std::move(u));
-
- XdrWrite(&json, &t0, XdrRequiredRepeatedOptionalData);
-
- json_xdr_unittest::RequiredRepeatedOptionalData t1;
- EXPECT_TRUE(XdrRead(json, &t1, XdrRequiredRepeatedOptionalData));
-
- EXPECT_EQ(t1, t0) << json;
-
- // See comment in FidlRequired.
- EXPECT_EQ(1u, t1.string.size());
- EXPECT_EQ(1u, t1.struct_.size());
- EXPECT_EQ(1u, t1.union_.size());
-
- EXPECT_FALSE(t1.string.at(0).is_null());
- EXPECT_EQ("1", t1.string.at(0));
-
- EXPECT_FALSE(nullptr == t1.struct_.at(0));
- EXPECT_EQ(12, t1.struct_.at(0)->item);
-
- EXPECT_FALSE(nullptr == t1.union_.at(0));
- EXPECT_TRUE(t1.union_.at(0)->is_int32());
- EXPECT_EQ(13, t1.union_.at(0)->int32());
-
- t1.string.at(0).reset();
- t1.struct_.at(0).reset();
- t1.union_.at(0).reset();
-
- XdrWrite(&json, &t1, XdrRequiredRepeatedOptionalData);
-
- json_xdr_unittest::RequiredRepeatedOptionalData t2;
- EXPECT_TRUE(XdrRead(json, &t2, XdrRequiredRepeatedOptionalData));
-
- EXPECT_EQ(t2, t1) << json;
-
- // See comment in FidlRequired.
- EXPECT_EQ(1u, t2.string.size());
- EXPECT_EQ(1u, t2.struct_.size());
- EXPECT_EQ(1u, t2.union_.size());
-
- EXPECT_TRUE(t2.string.at(0).is_null());
- EXPECT_TRUE(nullptr == t2.struct_.at(0));
- EXPECT_TRUE(nullptr == t2.union_.at(0));
-}
-
-constexpr XdrFilterType<json_xdr_unittest::OptionalRepeatedRequiredData>
- XdrOptionalRepeatedRequiredData[] = {
- XdrRequiredData_v1<json_xdr_unittest::OptionalRepeatedRequiredData>,
- nullptr,
-};
-
-TEST(Xdr, FidlOptionalRepeatedRequired) {
- std::string json;
-
- json_xdr_unittest::OptionalRepeatedRequiredData t0;
-
- t0.string.push_back("1");
- t0.bool_.push_back(true);
- t0.int8.push_back(2);
- t0.int16.push_back(3);
- t0.int32.push_back(4);
- t0.int64.push_back(5);
- t0.uint8.push_back(6);
- t0.uint16.push_back(7);
- t0.uint32.push_back(8);
- t0.uint64.push_back(9);
- t0.float32.push_back(10);
- t0.float64.push_back(11);
- t0.struct_.push_back({12});
- t0.enum_.push_back(json_xdr_unittest::Enum::ONE);
- json_xdr_unittest::Union u;
- u.set_int32(13);
- t0.union_.push_back(std::move(u));
-
- XdrWrite(&json, &t0, XdrOptionalRepeatedRequiredData);
-
- json_xdr_unittest::OptionalRepeatedRequiredData t1;
- EXPECT_TRUE(XdrRead(json, &t1, XdrOptionalRepeatedRequiredData));
-
- EXPECT_EQ(t1, t0) << json;
-
- EXPECT_FALSE(t1.string.is_null());
- EXPECT_FALSE(t1.bool_.is_null());
- EXPECT_FALSE(t1.int8.is_null());
- EXPECT_FALSE(t1.int16.is_null());
- EXPECT_FALSE(t1.int32.is_null());
- EXPECT_FALSE(t1.int64.is_null());
- EXPECT_FALSE(t1.uint8.is_null());
- EXPECT_FALSE(t1.uint16.is_null());
- EXPECT_FALSE(t1.uint32.is_null());
- EXPECT_FALSE(t1.uint64.is_null());
- EXPECT_FALSE(t1.float32.is_null());
- EXPECT_FALSE(t1.float64.is_null());
- EXPECT_FALSE(t1.struct_.is_null());
- EXPECT_FALSE(t1.enum_.is_null());
- EXPECT_FALSE(t1.union_.is_null());
-
- EXPECT_EQ(1u, t1.string->size());
- EXPECT_EQ(1u, t1.bool_->size());
- EXPECT_EQ(1u, t1.int8->size());
- EXPECT_EQ(1u, t1.int16->size());
- EXPECT_EQ(1u, t1.int32->size());
- EXPECT_EQ(1u, t1.int64->size());
- EXPECT_EQ(1u, t1.uint8->size());
- EXPECT_EQ(1u, t1.uint16->size());
- EXPECT_EQ(1u, t1.uint32->size());
- EXPECT_EQ(1u, t1.uint64->size());
- EXPECT_EQ(1u, t1.float32->size());
- EXPECT_EQ(1u, t1.float64->size());
- EXPECT_EQ(1u, t1.struct_->size());
- EXPECT_EQ(1u, t1.enum_->size());
- EXPECT_EQ(1u, t1.union_->size());
-
- EXPECT_EQ("1", t1.string->at(0));
- EXPECT_TRUE(t1.bool_->at(0));
- EXPECT_EQ(2, t1.int8->at(0));
- EXPECT_EQ(3, t1.int16->at(0));
- EXPECT_EQ(4, t1.int32->at(0));
- EXPECT_EQ(5, t1.int64->at(0));
- EXPECT_EQ(6u, t1.uint8->at(0));
- EXPECT_EQ(7u, t1.uint16->at(0));
- EXPECT_EQ(8u, t1.uint32->at(0));
- EXPECT_EQ(9u, t1.uint64->at(0));
- EXPECT_EQ(10.0f, t1.float32->at(0));
- EXPECT_EQ(11.0, t1.float64->at(0));
- EXPECT_EQ(12, t1.struct_->at(0).item);
- EXPECT_EQ(json_xdr_unittest::Enum::ONE, t1.enum_->at(0));
- EXPECT_TRUE(t1.union_->at(0).is_int32());
- EXPECT_EQ(13, t1.union_->at(0).int32());
-
- t1.string.reset();
- t1.bool_.reset();
- t1.int8.reset();
- t1.int16.reset();
- t1.int32.reset();
- t1.int64.reset();
- t1.uint8.reset();
- t1.uint16.reset();
- t1.uint32.reset();
- t1.uint64.reset();
- t1.float32.reset();
- t1.float64.reset();
- t1.struct_.reset();
- t1.enum_.reset();
- t1.union_.reset();
-
- XdrWrite(&json, &t1, XdrOptionalRepeatedRequiredData);
-
- json_xdr_unittest::OptionalRepeatedRequiredData t2;
- EXPECT_TRUE(XdrRead(json, &t2, XdrOptionalRepeatedRequiredData));
-
- EXPECT_EQ(t2, t1) << json;
-
- EXPECT_TRUE(t2.string.is_null());
- EXPECT_TRUE(t2.bool_.is_null());
- EXPECT_TRUE(t2.int8.is_null());
- EXPECT_TRUE(t2.int16.is_null());
- EXPECT_TRUE(t2.int32.is_null());
- EXPECT_TRUE(t2.int64.is_null());
- EXPECT_TRUE(t2.uint8.is_null());
- EXPECT_TRUE(t2.uint16.is_null());
- EXPECT_TRUE(t2.uint32.is_null());
- EXPECT_TRUE(t2.uint64.is_null());
- EXPECT_TRUE(t2.float32.is_null());
- EXPECT_TRUE(t2.float64.is_null());
- EXPECT_TRUE(t2.struct_.is_null());
- EXPECT_TRUE(t2.enum_.is_null());
- EXPECT_TRUE(t2.union_.is_null());
-
- EXPECT_EQ(0u, t2.string->size());
- EXPECT_EQ(0u, t2.bool_->size());
- EXPECT_EQ(0u, t2.int8->size());
- EXPECT_EQ(0u, t2.int16->size());
- EXPECT_EQ(0u, t2.int32->size());
- EXPECT_EQ(0u, t2.int64->size());
- EXPECT_EQ(0u, t2.uint8->size());
- EXPECT_EQ(0u, t2.uint16->size());
- EXPECT_EQ(0u, t2.uint32->size());
- EXPECT_EQ(0u, t2.uint64->size());
- EXPECT_EQ(0u, t2.float32->size());
- EXPECT_EQ(0u, t2.float64->size());
- EXPECT_EQ(0u, t2.struct_->size());
- EXPECT_EQ(0u, t2.enum_->size());
- EXPECT_EQ(0u, t2.union_->size());
-}
-
-constexpr XdrFilterType<json_xdr_unittest::OptionalRepeatedOptionalData>
- XdrOptionalRepeatedOptionalData[] = {
- XdrOptionalData_v1<json_xdr_unittest::OptionalRepeatedOptionalData>,
- nullptr,
-};
-
-TEST(Xdr, FidlOptionalRepeatedOptional) {
- std::string json;
-
- json_xdr_unittest::OptionalRepeatedOptionalData t0;
- t0.string.push_back("1");
-
- json_xdr_unittest::StructPtr s = json_xdr_unittest::Struct::New();
- s->item = 12;
- t0.struct_.push_back(std::move(s));
-
- json_xdr_unittest::UnionPtr u = json_xdr_unittest::Union::New();
- u->set_int32(13);
- t0.union_.push_back(std::move(u));
-
- XdrWrite(&json, &t0, XdrOptionalRepeatedOptionalData);
-
- json_xdr_unittest::OptionalRepeatedOptionalData t1;
- EXPECT_TRUE(XdrRead(json, &t1, XdrOptionalRepeatedOptionalData));
-
- EXPECT_EQ(t1, t0) << json;
-
- // See comment in FidlRequired.
- EXPECT_FALSE(t1.string.is_null());
- EXPECT_FALSE(t1.struct_.is_null());
- EXPECT_FALSE(t1.union_.is_null());
-
- EXPECT_EQ(1u, t1.string->size());
- EXPECT_EQ(1u, t1.struct_->size());
- EXPECT_EQ(1u, t1.union_->size());
-
- EXPECT_FALSE(t1.string->at(0).is_null());
- EXPECT_EQ("1", t1.string->at(0));
-
- EXPECT_FALSE(nullptr == t1.struct_->at(0));
- EXPECT_EQ(12, t1.struct_->at(0)->item);
-
- EXPECT_FALSE(nullptr == t1.union_->at(0));
- EXPECT_TRUE(t1.union_->at(0)->is_int32());
- EXPECT_EQ(13, t1.union_->at(0)->int32());
-
- t1.string->at(0).reset();
- t1.struct_->at(0).reset();
- t1.union_->at(0).reset();
-
- XdrWrite(&json, &t1, XdrOptionalRepeatedOptionalData);
-
- json_xdr_unittest::OptionalRepeatedOptionalData t2;
- EXPECT_TRUE(XdrRead(json, &t2, XdrOptionalRepeatedOptionalData));
-
- EXPECT_EQ(t2, t1) << json;
-
- // See comment in FidlRequired.
- EXPECT_FALSE(t2.string.is_null());
- EXPECT_FALSE(t2.struct_.is_null());
- EXPECT_FALSE(t2.union_.is_null());
-
- EXPECT_EQ(1u, t2.string->size());
- EXPECT_EQ(1u, t2.struct_->size());
- EXPECT_EQ(1u, t2.union_->size());
-
- EXPECT_TRUE(t2.string->at(0).is_null());
- EXPECT_TRUE(nullptr == t2.struct_->at(0));
- EXPECT_TRUE(nullptr == t2.union_->at(0));
-
- t2.string.reset();
- t2.struct_.reset();
- t2.union_.reset();
-
- XdrWrite(&json, &t2, XdrOptionalRepeatedOptionalData);
-
- json_xdr_unittest::OptionalRepeatedOptionalData t3;
- EXPECT_TRUE(XdrRead(json, &t3, XdrOptionalRepeatedOptionalData));
-
- EXPECT_EQ(t3, t2) << json;
-
- // See comment in FidlRequired.
- EXPECT_TRUE(t3.string.is_null());
- EXPECT_TRUE(t3.struct_.is_null());
- EXPECT_TRUE(t3.union_.is_null());
-
- EXPECT_EQ(0u, t3.string->size());
- EXPECT_EQ(0u, t3.struct_->size());
- EXPECT_EQ(0u, t3.union_->size());
-}
-
-constexpr XdrFilterType<json_xdr_unittest::ArrayData> XdrArrayData[] = {
- XdrRequiredData_v1<json_xdr_unittest::ArrayData>,
- nullptr,
-};
-
-TEST(Xdr, FidlArray) {
- std::string json;
-
- json_xdr_unittest::ArrayData t0;
-
- for (size_t i=0; i<t0.string.size(); i++) {
- t0.string.at(i) = "1";
- t0.bool_.at(i) = true;
- t0.int8.at(i) = 2;
- t0.int16.at(i) = 3;
- t0.int32.at(i) = 4;
- t0.int64.at(i) = 5;
- t0.uint8.at(i) = 6;
- t0.uint16.at(i) = 7;
- t0.uint32.at(i) = 8;
- t0.uint64.at(i) = 9;
- t0.float32.at(i) = 10;
- t0.float64.at(i) = 11;
- t0.struct_.at(i).item = 12;
- t0.enum_.at(i) = json_xdr_unittest::Enum::ONE;
- t0.union_.at(i).set_int32(13);
- }
-
- XdrWrite(&json, &t0, XdrArrayData);
-
- json_xdr_unittest::ArrayData t1;
- EXPECT_TRUE(XdrRead(json, &t1, XdrArrayData));
-
- EXPECT_EQ(t1, t0) << json;
-
- // Technically not needed because the equality should cover this, but makes it
- // more transparent what's going on.
- EXPECT_EQ("1", t1.string.at(0));
- EXPECT_TRUE(t1.bool_.at(0));
- EXPECT_EQ(2, t1.int8.at(0));
- EXPECT_EQ(3, t1.int16.at(0));
- EXPECT_EQ(4, t1.int32.at(0));
- EXPECT_EQ(5, t1.int64.at(0));
- EXPECT_EQ(6u, t1.uint8.at(0));
- EXPECT_EQ(7u, t1.uint16.at(0));
- EXPECT_EQ(8u, t1.uint32.at(0));
- EXPECT_EQ(9u, t1.uint64.at(0));
- EXPECT_EQ(10.0f, t1.float32.at(0));
- EXPECT_EQ(11.0, t1.float64.at(0));
- EXPECT_EQ(12, t1.struct_.at(0).item);
- EXPECT_EQ(json_xdr_unittest::Enum::ONE, t1.enum_.at(0));
- EXPECT_TRUE(t1.union_.at(0).is_int32());
- EXPECT_EQ(13, t1.union_.at(0).int32());
-}
-
-} // namespace
-} // namespace modular
diff --git a/lib/fidl/json_xdr_unittest.fidl b/lib/fidl/json_xdr_unittest.fidl
deleted file mode 100644
index f9d639c..0000000
--- a/lib/fidl/json_xdr_unittest.fidl
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library test.peridot.lib.fidl.jsonxdr;
-
-struct RequiredData {
- string string;
- bool bool;
- int8 int8;
- int16 int16;
- int32 int32;
- int64 int64;
- uint8 uint8;
- uint16 uint16;
- uint32 uint32;
- uint64 uint64;
- float32 float32;
- float64 float64;
- Struct struct;
- Enum enum;
- Union union;
-};
-
-struct OptionalData {
- string? string;
- Struct? struct;
- Union? union;
-};
-
-struct RequiredRepeatedRequiredData {
- vector<string> string;
- vector<bool> bool;
- vector<int8> int8;
- vector<int16> int16;
- vector<int32> int32;
- vector<int64> int64;
- vector<uint8> uint8;
- vector<uint16> uint16;
- vector<uint32> uint32;
- vector<uint64> uint64;
- vector<float32> float32;
- vector<float64> float64;
- vector<Struct> struct;
- vector<Enum> enum;
- vector<Union> union;
-};
-
-struct RequiredRepeatedOptionalData {
- vector<string?> string;
- vector<Struct?> struct;
- vector<Union?> union;
-};
-
-// NOTE(mesch): According to jeffbrown, optional vector typed fields are going
-// away.
-
-struct OptionalRepeatedRequiredData {
- vector<string>? string;
- vector<bool>? bool;
- vector<int8>? int8;
- vector<int16>? int16;
- vector<int32>? int32;
- vector<int64>? int64;
- vector<uint8>? uint8;
- vector<uint16>? uint16;
- vector<uint32>? uint32;
- vector<uint64>? uint64;
- vector<float32>? float32;
- vector<float64>? float64;
- vector<Struct>? struct;
- vector<Enum>? enum;
- vector<Union>? union;
-};
-
-struct OptionalRepeatedOptionalData {
- vector<string?>? string;
- vector<Struct?>? struct;
- vector<Union?>? union;
-};
-
-struct ArrayData {
- array<string>:10 string;
- array<bool>:10 bool;
- array<int8>:10 int8;
- array<int16>:10 int16;
- array<int32>:10 int32;
- array<int64>:10 int64;
- array<uint8>:10 uint8;
- array<uint16>:10 uint16;
- array<uint32>:10 uint32;
- array<uint64>:10 uint64;
- array<float32>:10 float32;
- array<float64>:10 float64;
- array<Struct>:10 struct;
- array<Enum>:10 enum;
- array<Union>:10 union;
-};
-
-// The purpose of this struct is coverage for struct valued fields above. The
-// field exists only so we have something to be checked to be there. Other types
-// of fields of structs are covered above, not here.
-struct Struct {
- int32 item;
-};
-
-enum Enum {
- ZERO = 0;
- ONE = 1;
- TWO = 2;
-};
-
-// NOTE(mesch): Can't use struct, FIDL-130.
-union Union {
- int32 int32;
- string string;
-};
diff --git a/lib/fidl/proxy.cc b/lib/fidl/proxy.cc
deleted file mode 100644
index fa68acd..0000000
--- a/lib/fidl/proxy.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/fidl/proxy.h"
-
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-ProxySet::ProxySet() = default;
-
-ProxySet::~ProxySet() = default;
-
-void ProxySet::Drop(ProxyBase* const proxy) {
- auto i = std::remove_if(
- proxies_.begin(), proxies_.end(),
- [proxy](std::unique_ptr<ProxyBase>& p) { return proxy == p.get(); });
- FXL_DCHECK(i != proxies_.end());
- proxies_.erase(i, proxies_.end());
-}
-
-ProxyBase::ProxyBase(ProxySet* const set) : set_(set) {}
-
-ProxyBase::~ProxyBase() = default;
-
-void ProxyBase::Drop() { set_->Drop(this); }
-
-} // namespace modular
diff --git a/lib/fidl/proxy.h b/lib/fidl/proxy.h
deleted file mode 100644
index 47de223..0000000
--- a/lib/fidl/proxy.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIDL_PROXY_H_
-#define PERIDOT_LIB_FIDL_PROXY_H_
-
-#include <memory>
-#include <vector>
-
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-class ProxyBase;
-
-// A proxy allows to bind a fidl interface request to an existing fidl interface
-// ptr of the same interface type.
-//
-// Proxy instances are held in a proxy set, from which they are automatically
-// removed once one of their connection closes, which then also closes the other
-// connection.
-//
-// A proxy set can polymorphically hold proxies of various interface types.
-class ProxySet {
- public:
- ProxySet();
- ~ProxySet();
-
- template <typename I>
- void Connect(fidl::InterfacePtr<I> ptr, fidl::InterfaceRequest<I> request);
-
- private:
- friend class ProxyBase;
- void Drop(ProxyBase* proxy);
-
- std::vector<std::unique_ptr<ProxyBase>> proxies_;
- FXL_DISALLOW_COPY_AND_ASSIGN(ProxySet);
-};
-
-// Used internally by ProxySet, but needs to be here because it supports the
-// Proxy template class below.
-class ProxyBase {
- public:
- explicit ProxyBase(ProxySet* set);
- virtual ~ProxyBase();
-
- protected:
- void Drop();
-
- private:
- ProxySet* const set_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ProxyBase);
-};
-
-// Used internally by ProxySet, but needs to be here because it is a
-// template.
-template <typename I>
-class Proxy : public ProxyBase {
- public:
- Proxy(ProxySet* set, fidl::InterfacePtr<I> ptr,
- fidl::InterfaceRequest<I> request);
- ~Proxy() override;
-
- private:
- fidl::InterfacePtr<I> ptr_;
- fidl::Binding<I> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(Proxy);
-};
-
-template <typename I>
-void ProxySet::Connect(fidl::InterfacePtr<I> ptr,
- fidl::InterfaceRequest<I> request) {
- proxies_.emplace_back(new Proxy<I>(this, std::move(ptr), std::move(request)));
-}
-
-template <typename I>
-Proxy<I>::Proxy(ProxySet* const set, fidl::InterfacePtr<I> ptr,
- fidl::InterfaceRequest<I> request)
- : ProxyBase(set),
- ptr_(std::move(ptr)),
- binding_(ptr_.get(), std::move(request)) {
- ptr_.set_error_handler([this](zx_status_t status) { Drop(); });
- binding_.set_error_handler([this](zx_status_t status) { Drop(); });
-}
-
-template <typename I>
-Proxy<I>::~Proxy() = default;
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_FIDL_PROXY_H_
diff --git a/lib/fidl/single_service_app.h b/lib/fidl/single_service_app.h
deleted file mode 100644
index f28e778..0000000
--- a/lib/fidl/single_service_app.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIDL_SINGLE_SERVICE_APP_H_
-#define PERIDOT_LIB_FIDL_SINGLE_SERVICE_APP_H_
-
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/app/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <zx/eventpair.h>
-#include <memory>
-
-namespace modular {
-
-// Base class for a simple application which only provides the ViewProvider
-// service. It also implements a Terminate() method that makes it suitable to be
-// used as an Impl class of AppDriver.
-class ViewApp : private fuchsia::ui::app::ViewProvider,
- private fuchsia::ui::viewsv1::ViewProvider {
- public:
- ViewApp(component::StartupContext* const startup_context)
- : startup_context_(startup_context),
- old_view_provider_binding_(this),
- view_provider_binding_(this) {
- startup_context_->outgoing()
- .AddPublicService<fuchsia::ui::viewsv1::ViewProvider>(
- [this](fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- request) {
- FXL_DCHECK(!old_view_provider_binding_.is_bound());
- old_view_provider_binding_.Bind(std::move(request));
- });
-
- startup_context_->outgoing()
- .AddPublicService<fuchsia::ui::app::ViewProvider>(
- [this](fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>
- request) {
- FXL_DCHECK(!view_provider_binding_.is_bound());
- view_provider_binding_.Bind(std::move(request));
- });
- }
-
- ~ViewApp() override = default;
-
- virtual void Terminate(std::function<void()> done) { done(); }
-
- protected:
- component::StartupContext* startup_context() const {
- return startup_context_;
- }
-
- private:
- // |ViewProvider|
- void CreateView(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner_request,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services) final {
- // Forward into fuchsia.ui.app.ViewProvider by "casting" the ViewOwner
- // channel to an eventpair.
- CreateView(zx::eventpair(view_owner_request.TakeChannel().release()),
- std::move(services), nullptr);
- }
-
- // |ViewProvider| -- Derived classes should override this method.
- void CreateView(
- zx::eventpair /*view_token*/,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services,
- fidl::InterfaceHandle<
- fuchsia::sys::ServiceProvider> /*outgoing_services*/) override {}
-
- component::StartupContext* const startup_context_;
- fidl::Binding<fuchsia::ui::viewsv1::ViewProvider> old_view_provider_binding_;
- fidl::Binding<fuchsia::ui::app::ViewProvider> view_provider_binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ViewApp);
-};
-
-// Base class for a simple application which provides a single instance of a
-// single service and the ViewProvider service.
-template <class Service>
-class SingleServiceApp : public ViewApp, protected Service {
- public:
- SingleServiceApp(component::StartupContext* const start_context)
- : ViewApp(start_context), service_binding_(this) {
- // The 'template' is required here because AddPublicService is a dependent
- // template name.
- startup_context()->outgoing().template AddPublicService<Service>(
- [this](fidl::InterfaceRequest<Service> request) {
- FXL_DCHECK(!service_binding_.is_bound());
- service_binding_.Bind(std::move(request));
- });
- }
-
- ~SingleServiceApp() override = default;
-
- private:
- fidl::Binding<Service> service_binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SingleServiceApp);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_FIDL_SINGLE_SERVICE_APP_H_
diff --git a/lib/fidl/view_host.cc b/lib/fidl/view_host.cc
deleted file mode 100644
index 351ca08..0000000
--- a/lib/fidl/view_host.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/fidl/view_host.h"
-
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-struct ViewHost::ViewData {
- explicit ViewData(scenic::Session* session) : host_node(session) {}
-
- scenic::EntityNode host_node;
-};
-
-ViewHost::ViewHost(scenic::ViewContext view_context)
- : V1BaseView(std::move(view_context), "ViewHost"),
- container_node_(session()) {
- parent_node().AddChild(container_node_);
-}
-
-ViewHost::~ViewHost() = default;
-
-void ViewHost::ConnectView(zx::eventpair view_holder_token) {
- const uint32_t child_key = next_child_key_++;
-
- auto view_data = std::make_unique<ViewData>(session());
-
- zx::eventpair host_import_token;
- view_data->host_node.ExportAsRequest(&host_import_token);
- container_node_.AddChild(view_data->host_node);
- views_.emplace(child_key, std::move(view_data));
-
- GetViewContainer()->AddChild2(child_key, std::move(view_holder_token),
- std::move(host_import_token));
- UpdateScene();
-}
-
-void ViewHost::ConnectView(
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner> view_owner) {
- ConnectView(zx::eventpair(view_owner.TakeChannel().release()));
-}
-
-void ViewHost::OnPropertiesChanged(
- fuchsia::ui::viewsv1::ViewProperties /*old_properties*/) {
- UpdateScene();
-}
-
-void ViewHost::OnChildUnavailable(uint32_t child_key) {
- FXL_LOG(ERROR) << "View died unexpectedly: child_key=" << child_key;
-
- auto it = views_.find(child_key);
- FXL_DCHECK(it != views_.end());
-
- it->second->host_node.Detach();
- views_.erase(it);
-
- GetViewContainer()->RemoveChild2(child_key, zx::eventpair());
- UpdateScene();
-}
-
-void ViewHost::UpdateScene() {
- if (!properties().view_layout || views_.empty()) {
- return;
- }
-
- // Layout all children in a row.
- uint32_t index = 0;
- uint32_t space = logical_size().width;
- uint32_t base = space / views_.size();
- uint32_t excess = space % views_.size();
- uint32_t offset = 0;
- for (auto it = views_.begin(); it != views_.end(); ++it, ++index) {
- ViewData* view_data = it->second.get();
-
- // Distribute any excess width among the leading children.
- uint32_t extent = base;
- if (excess) {
- extent++;
- excess--;
- }
-
- fuchsia::math::RectF layout_bounds;
- layout_bounds.x = offset;
- layout_bounds.y = 0;
- layout_bounds.width = extent;
- layout_bounds.height = logical_size().height;
- offset += extent;
-
- auto view_properties = fuchsia::ui::viewsv1::ViewProperties::New();
- view_properties->view_layout = fuchsia::ui::viewsv1::ViewLayout::New();
- view_properties->view_layout->size = fuchsia::math::SizeF();
- view_properties->view_layout->size.width = layout_bounds.width;
- view_properties->view_layout->size.height = layout_bounds.height;
- view_properties->view_layout->inset = fuchsia::math::InsetF();
- GetViewContainer()->SetChildProperties(it->first,
- std::move(view_properties));
-
- view_data->host_node.SetTranslation(layout_bounds.x, layout_bounds.y, 0u);
- }
-
- InvalidateScene();
-}
-
-} // namespace modular
diff --git a/lib/fidl/view_host.h b/lib/fidl/view_host.h
deleted file mode 100644
index a4c0155..0000000
--- a/lib/fidl/view_host.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIDL_VIEW_HOST_H_
-#define PERIDOT_LIB_FIDL_VIEW_HOST_H_
-
-#include <map>
-#include <memory>
-
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/fxl/macros.h>
-#include <lib/ui/base_view/cpp/v1_base_view.h>
-#include <zx/eventpair.h>
-
-namespace modular {
-
-// A class that allows modules to display the UI of their child
-// modules, without displaying any UI on their own. Used for modules
-// that play the role of a view controller (aka quarterback, recipe).
-// It supports to embed views of *multiple* children, which are laid
-// out horizontally.
-class ViewHost : public scenic::V1BaseView {
- public:
- explicit ViewHost(scenic::ViewContext view_context);
- ~ViewHost() override;
-
- // Connects one more view. Calling this method multiple times adds
- // multiple views and lays them out horizontally next to each other.
- // This is experimental to establish data flow patterns in toy
- // applications and can be changed or extended as needed.
- void ConnectView(zx::eventpair view_holder_token);
- void ConnectView(
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner> view_owner);
-
- private:
- struct ViewData;
-
- // |scenic::V1BaseView|
- void OnPropertiesChanged(
- fuchsia::ui::viewsv1::ViewProperties old_properties) override;
- void OnChildUnavailable(uint32_t child_key) override;
-
- void UpdateScene();
-
- scenic::EntityNode container_node_;
-
- std::map<uint32_t, std::unique_ptr<ViewData>> views_;
- uint32_t next_child_key_{1u};
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ViewHost);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_FIDL_VIEW_HOST_H_
diff --git a/lib/firebase/BUILD.gn b/lib/firebase/BUILD.gn
deleted file mode 100644
index 38e3e72..0000000
--- a/lib/firebase/BUILD.gn
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- "//peridot/bin/*",
- "//peridot/lib/*",
-]
-
-source_set("firebase") {
- sources = [
- "encoding.cc",
- "encoding.h",
- "event_stream.cc",
- "event_stream.h",
- "firebase.h",
- "firebase_impl.cc",
- "firebase_impl.h",
- "status.cc",
- "status.h",
- "watch_client.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/network_wrapper",
- "//peridot/lib/convert",
- "//third_party/rapidjson",
- ]
-
- deps = [
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/base64url",
- "//peridot/lib/socket",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "encoding_unittest.cc",
- "event_stream_unittest.cc",
- "firebase_impl_unittest.cc",
- ]
-
- deps = [
- ":firebase",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//garnet/public/lib/network_wrapper:fake",
- "//peridot/lib/convert",
- "//peridot/lib/socket",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/firebase/README.md b/lib/firebase/README.md
deleted file mode 100644
index f9875df..0000000
--- a/lib/firebase/README.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# firebase
-
-Client library for the REST API of the Firebase Realtime Database.
-
-## curl
-
-In order to manually debug potential sync issues, we can use `curl` to interact
-with the database from the command line.
-
-Reading data:
-
-```sh
-curl <host>/<path>.json -X GET
-```
-
-Writing data:
-
-```sh
-curl <host>/<path>.json -X PUT -d <data>
-```
-
-Opening a notification stream:
-
-```sh
-curl -L <host>/<path>.json -X GET -H "Accept: text/event-stream"
-```
diff --git a/lib/firebase/encoding.cc b/lib/firebase/encoding.cc
deleted file mode 100644
index cc70a71..0000000
--- a/lib/firebase/encoding.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase/encoding.h"
-
-#include <lib/fxl/strings/utf_codecs.h>
-
-#include "peridot/lib/base64url/base64url.h"
-
-namespace firebase {
-
-namespace {
-
-// Returns true iff the given value can be put in Firebase without encoding.
-// Firebase requires the values to be valid UTF-8 JSON strings. JSON disallows
-// control characters in strings. We disallow backslash and double quote to
-// avoid reasoning about escaping. Note: this is a stop-gap solution, see
-// LE-118.
-bool CanValueBeVerbatim(fxl::StringView bytes) {
- // Once encryption is in place this won't be useful. Until then, storing valid
- // utf8 strings verbatim simplifies debugging.
- if (!fxl::IsStringUTF8(bytes)) {
- return false;
- }
-
- for (const char& byte : bytes) {
- if (static_cast<unsigned char>(byte) <= 31 || byte == 127 || byte == '\"' ||
- byte == '\\') {
- return false;
- }
- }
-
- return true;
-}
-
-// Characters that are not allowed to appear in a Firebase key (but may appear
-// in a value). See
-// https://firebase.google.com/docs/database/rest/structure-data.
-const char kIllegalKeyChars[] = ".$#[]/+";
-
-// Encodes the given bytes for storage in Firebase. We use the same encoding
-// function for both values and keys for simplicity, yielding values that can be
-// always safely used as either. Note: this is a stop-gap solution, see LE-118.
-std::string Encode(fxl::StringView s, bool verbatim) {
- if (verbatim) {
- return s.ToString() + "V";
- }
-
- std::string encoded;
- return base64url::Base64UrlEncode(s) + "B";
-}
-
-} // namespace
-
-// Returns true if the given value can be used as a Firebase key without
-// encoding.
-bool CanKeyBeVerbatim(fxl::StringView bytes) {
- if (!CanValueBeVerbatim(bytes)) {
- return false;
- }
-
- if (bytes.find_first_of(std::string(kIllegalKeyChars)) != std::string::npos) {
- return false;
- }
-
- return true;
-}
-
-std::string EncodeKey(convert::ExtendedStringView bytes) {
- return Encode(bytes, CanKeyBeVerbatim(bytes));
-}
-
-std::string EncodeValue(convert::ExtendedStringView bytes) {
- return Encode(bytes, CanValueBeVerbatim(bytes));
-}
-
-bool Decode(convert::ExtendedStringView input, std::string* output) {
- if (input.empty()) {
- return false;
- }
-
- fxl::StringView data = input.substr(0, input.size() - 1);
-
- if (input.back() == 'V') {
- *output = data.ToString();
- return true;
- }
-
- if (input.back() == 'B') {
- return base64url::Base64UrlDecode(data, output);
- }
-
- return false;
-}
-
-} // namespace firebase
diff --git a/lib/firebase/encoding.h b/lib/firebase/encoding.h
deleted file mode 100644
index b4640a3..0000000
--- a/lib/firebase/encoding.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_ENCODING_H_
-#define PERIDOT_LIB_FIREBASE_ENCODING_H_
-
-#include <string>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace firebase {
-
-// Returns true iff the given value can be put in Firebase as a key name without
-// encoding.
-bool CanKeyBeVerbatim(fxl::StringView bytes);
-
-// Warning: this is a naive solution which needs multiple passes and copies of
-// the data each time. To be optimized if we are going to use this in the target
-// implementation - see LE-118.
-
-// These methods encode the given bytes as a valid Firebase key / value.
-//
-// Strings that are already valid Firebase keys / values are encoded as:
-// "<original string>V" ("V" standing for "verbatim". This saves bytes (compared
-// to base64) and allows to make sense of the data upon manual inspection.
-//
-// Strings that are not valid Firebase keys / values are encoded as base64 with
-// slashes replaced with backslashes and "B" added at the end.
-std::string EncodeKey(convert::ExtendedStringView bytes);
-std::string EncodeValue(convert::ExtendedStringView bytes);
-
-// Returns true iff the key or value was correctly decoded and stored in |out|.
-// We don't need separate methods for keys and values, as the decoding algorithm
-// is identical.
-bool Decode(convert::ExtendedStringView input, std::string* output);
-
-} // namespace firebase
-
-#endif // PERIDOT_LIB_FIREBASE_ENCODING_H_
diff --git a/lib/firebase/encoding_unittest.cc b/lib/firebase/encoding_unittest.cc
deleted file mode 100644
index f8b397b..0000000
--- a/lib/firebase/encoding_unittest.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase/encoding.h"
-
-#include <string>
-
-#include <lib/fxl/random/rand.h>
-#include <lib/fxl/strings/utf_codecs.h>
-#include <zircon/syscalls.h>
-
-#include "gtest/gtest.h"
-
-namespace firebase {
-namespace {
-
-// Allows to create correct std::strings with \0 bytes inside from C-style
-// string constants.
-std::string operator"" _s(const char* str, size_t size) {
- return std::string(str, size);
-}
-
-// See
-// https://www.firebase.com/docs/rest/guide/understanding-data.html#section-limitations
-bool IsValidKey(const std::string& s) {
- if (!fxl::IsStringUTF8(s)) {
- return false;
- }
-
- for (const char& c : s) {
- if (static_cast<unsigned char>(c) <= 31) {
- return false;
- }
-
- if (c == 127) {
- return false;
- }
-
- if (c == '+' || c == '$' || c == '[' || c == ']' || c == '/' || c == '\"' ||
- c == '\\') {
- return false;
- }
- }
- return true;
-}
-
-bool IsValidValue(const std::string s) {
- if (!fxl::IsStringUTF8(s)) {
- return false;
- }
-
- for (const char& c : s) {
- if (static_cast<unsigned char>(c) <= 31) {
- return false;
- }
-
- if (c == 127) {
- return false;
- }
-
- if (c == '\"' || c == '\\') {
- return false;
- }
- }
- return true;
-}
-
-TEST(EncodingTest, BackAndForth) {
- std::string s;
- std::string ret_key;
- std::string ret_value;
-
- s = "";
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "abcdef";
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "leśna łączka";
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "\x02\x7F";
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "\xFF";
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "\x01";
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "abc\"def\"ghi'jkl'";
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "\0\0\0"_s;
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "bazinga\0\0\0"_s;
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- s = "alice\0bob"_s;
- EXPECT_TRUE(Decode(EncodeKey(s), &ret_key));
- EXPECT_EQ(s, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(s), &ret_value));
- EXPECT_EQ(s, ret_value);
-
- // Check random sequence of size less or equals 3.
- for (size_t i = 0; i < 10000; ++i) {
- size_t size = fxl::RandUint64() % 4;
- char buffer[size];
- fxl::StringView view(buffer, size);
- zx_cprng_draw(reinterpret_cast<unsigned char*>(buffer), size);
- EXPECT_TRUE(Decode(EncodeKey(view), &ret_key));
- EXPECT_EQ(view, ret_key);
- EXPECT_TRUE(Decode(EncodeValue(view), &ret_value));
- EXPECT_EQ(view, ret_value);
- }
-}
-
-TEST(EncodingTest, Keys) {
- EXPECT_EQ("V", EncodeKey(""));
- EXPECT_EQ("abcV", EncodeKey("abc"));
- EXPECT_EQ("qwerty123V", EncodeKey("qwerty123"));
- EXPECT_EQ("YWJjLw==B", EncodeKey("abc/"));
- EXPECT_EQ("I1tdIQ==B", EncodeKey("#[]!"));
- EXPECT_EQ("fw==B", EncodeKey("\x7F"));
- EXPECT_EQ("_w==B", EncodeKey("\xFF"));
- EXPECT_EQ("Ig==B", EncodeKey("\""));
- EXPECT_EQ("Kw==B", EncodeKey("+"));
-}
-
-TEST(EncodingTest, Values) {
- EXPECT_EQ("V", EncodeValue(""));
- EXPECT_EQ("abcV", EncodeValue("abc"));
- EXPECT_EQ("qwerty123V", EncodeValue("qwerty123"));
- EXPECT_EQ("abc/V", EncodeValue("abc/"));
- EXPECT_EQ("#[]!V", EncodeValue("#[]!"));
- EXPECT_EQ("fw==B", EncodeValue("\x7F"));
- EXPECT_EQ("_w==B", EncodeValue("\xFF"));
- EXPECT_EQ("Ig==B", EncodeValue("\""));
- EXPECT_EQ("Iy9cIT9bXQ==B", EncodeValue("#/\\!?[]"));
- EXPECT_EQ("+V", EncodeValue("+"));
-}
-
-TEST(EncodingTest, ValidKeys) {
- std::string original;
- std::string encoded;
- std::string decoded;
-
- original = "\x02, \x7F, \x18, \x1D are forbidden, [], $ and / too!";
- encoded = EncodeKey(original);
- EXPECT_TRUE(IsValidKey(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-
- original = "\xFF";
- encoded = EncodeKey(original);
- EXPECT_TRUE(IsValidKey(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-
- original = "\xFF\x7F\x05\x09\xFF\xFF\x0B";
- encoded = EncodeKey(original);
- EXPECT_TRUE(IsValidKey(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-
- original = "zażółć gęślÄ… jaźń\xFF\xFF";
- encoded = EncodeKey(original);
- EXPECT_TRUE(IsValidKey(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-}
-
-TEST(EncodingTest, ValidValues) {
- std::string original;
- std::string encoded;
- std::string decoded;
-
- original = "\x02, \x7F, \x18, \x1D are ok, [], $ and / too!";
- encoded = EncodeValue(original);
- EXPECT_TRUE(IsValidValue(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-
- original = "\x01\x00\x02"_s;
- encoded = EncodeValue(original);
- EXPECT_TRUE(IsValidValue(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-
- original = "\xFF";
- encoded = EncodeValue(original);
- EXPECT_TRUE(IsValidValue(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-
- original = "\xFF\x7F\x05\x09\xFF\xFF\x0B";
- encoded = EncodeValue(original);
- EXPECT_TRUE(IsValidValue(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-
- original = "zażółć gęślÄ… jaźń\xFF\xFF";
- encoded = EncodeValue(original);
- EXPECT_TRUE(IsValidValue(encoded));
- EXPECT_TRUE(Decode(encoded, &decoded));
- EXPECT_EQ(original, decoded);
-}
-
-} // namespace
-} // namespace firebase
diff --git a/lib/firebase/event_stream.cc b/lib/firebase/event_stream.cc
deleted file mode 100644
index 4d52958..0000000
--- a/lib/firebase/event_stream.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase/event_stream.h"
-
-#include <utility>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/trim.h>
-
-namespace firebase {
-
-EventStream::EventStream() {}
-
-EventStream::~EventStream() {}
-
-void EventStream::Start(zx::socket source,
- fit::function<EventCallback> event_callback,
- fit::function<CompletionCallback> completion_callback) {
- event_callback_ = std::move(event_callback);
- completion_callback_ = std::move(completion_callback);
- drainer_ = std::make_unique<fsl::SocketDrainer>(this);
- drainer_->Start(std::move(source));
-}
-
-void EventStream::OnDataAvailable(const void* data, size_t num_bytes) {
- const char* current = static_cast<const char*>(data);
- const char* const end = current + num_bytes;
- while (current < end) {
- const char* newline = std::find(current, end, '\n');
- pending_line_.append(current, newline - current);
- current = newline;
- if (newline != end) {
- if (!ProcessLine(pending_line_))
- return;
- pending_line_.clear();
- ++current;
- }
- }
-}
-
-void EventStream::OnDataComplete() { completion_callback_(); }
-
-// See https://www.w3.org/TR/eventsource/#event-stream-interpretation.
-bool EventStream::ProcessLine(fxl::StringView line) {
- // If the line is empty, dispatch the event.
- if (line.empty()) {
- // If data is empty, clear event type and abort.
- if (data_.empty()) {
- event_type_.clear();
- return true;
- }
-
- // Remove the trailing line break from data.
- if (*(data_.rbegin()) == '\n') {
- data_.resize(data_.size() - 1);
- }
-
- if (destruction_sentinel_.DestructedWhile(
- [this] { event_callback_(Status::OK, event_type_, data_); })) {
- return false;
- }
- event_type_.clear();
- data_.clear();
- return true;
- }
-
- // If the line starts with a colon, ignore the line.
- if (line[0] == ':') {
- return true;
- }
-
- // If the line contains a colon, process the field.
- size_t colon_pos = line.find(':');
- if (colon_pos != std::string::npos) {
- fxl::StringView field(line.substr(0, colon_pos));
- fxl::StringView value = line.substr(colon_pos + 1);
- ProcessField(field, fxl::TrimString(value, " "));
- return true;
- }
-
- // If the line does not contain a colon, process the field using the whole
- // line as the field name and empty string as field value.
- ProcessField(line, "");
- return true;
-}
-
-void EventStream::ProcessField(fxl::StringView field, fxl::StringView value) {
- if (field == "event") {
- event_type_ = value.ToString();
- } else if (field == "data") {
- data_.append(value.data(), value.size());
- data_.append("\n");
- } else if (field == "id" || field == "retry") {
- // Not implemented.
- FXL_LOG(WARNING) << "Event stream - field type not implemented: " << field;
- } else {
- // The spec says to ignore unknown field names.
- FXL_LOG(WARNING) << "Event stream - unknown field name: " << field;
- }
-}
-
-} // namespace firebase
diff --git a/lib/firebase/event_stream.h b/lib/firebase/event_stream.h
deleted file mode 100644
index 091d485..0000000
--- a/lib/firebase/event_stream.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_EVENT_STREAM_H_
-#define PERIDOT_LIB_FIREBASE_EVENT_STREAM_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-
-#include <lib/callback/destruction_sentinel.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/socket_drainer.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-#include "peridot/lib/firebase/status.h"
-
-namespace firebase {
-
-// TODO(ppi): Use a client interface instead.
-using EventCallback = void(Status status, const std::string& event,
- const std::string& data);
-using CompletionCallback = void();
-
-// Socket drainer that parses a stream of Server-Sent Events.
-// Data format of the stream is specified in http://www.w3.org/TR/eventsource/.
-class EventStream : public fsl::SocketDrainer::Client {
- public:
- EventStream();
- ~EventStream() override;
-
- void Start(zx::socket source, fit::function<EventCallback> event_callback,
- fit::function<CompletionCallback> completion_callback);
-
- private:
- friend class EventStreamTest;
-
- // fsl::SocketDrainer::Client:
- void OnDataAvailable(const void* data, size_t num_bytes) override;
- void OnDataComplete() override;
-
- // Returns false if the object has been destroyed within this method.
- bool ProcessLine(fxl::StringView line);
-
- void ProcessField(fxl::StringView field, fxl::StringView value);
-
- fit::function<EventCallback> event_callback_;
- fit::function<CompletionCallback> completion_callback_;
-
- // Unprocessed part of the current line.
- std::string pending_line_;
- std::string data_;
- std::string event_type_;
-
- std::unique_ptr<fsl::SocketDrainer> drainer_;
-
- callback::DestructionSentinel destruction_sentinel_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(EventStream);
-};
-
-} // namespace firebase
-
-#endif // PERIDOT_LIB_FIREBASE_EVENT_STREAM_H_
diff --git a/lib/firebase/event_stream_unittest.cc b/lib/firebase/event_stream_unittest.cc
deleted file mode 100644
index 8aa0723..0000000
--- a/lib/firebase/event_stream_unittest.cc
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase/event_stream.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <lib/async/cpp/task.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/lib/socket/socket_pair.h"
-
-namespace firebase {
-
-class EventStreamTest : public ::gtest::TestLoopFixture {
- public:
- EventStreamTest() {}
- ~EventStreamTest() override {}
-
- protected:
- // ApplicationTestBase:
- void SetUp() override {
- ::testing::Test::SetUp();
- socket::SocketPair socket;
- producer_socket_ = std::move(socket.socket1);
- event_stream_ = std::make_unique<EventStream>();
- event_stream_->Start(std::move(socket.socket2),
- [this](Status status, const std::string& event,
- const std::string& data) {
- status_.push_back(status);
- events_.push_back(event);
- data_.push_back(data);
- if (delete_on_event_) {
- event_stream_.reset();
- }
- },
- []() {});
- }
-
- void TearDown() override {
- producer_socket_.reset();
- ::testing::Test::TearDown();
- }
-
- void Feed(const std::string& data) {
- event_stream_->OnDataAvailable(data.data(), data.size());
- }
-
- void Done() { event_stream_->OnDataComplete(); }
-
- zx::socket producer_socket_;
- std::unique_ptr<EventStream> event_stream_;
- std::vector<Status> status_;
- std::vector<std::string> events_;
- std::vector<std::string> data_;
- bool delete_on_event_ = false;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(EventStreamTest);
-};
-
-namespace {
-
-TEST_F(EventStreamTest, OneEvent) {
- Feed("event: abc\ndata: bazinga\n\n");
- Done();
-
- EXPECT_EQ(1u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("bazinga", data_[0]);
-}
-
-TEST_F(EventStreamTest, CutAtLineBreaks) {
- Feed("event: abc\n");
- Feed("data: bazinga\n");
- Feed("\n");
- Done();
-
- EXPECT_EQ(1u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("bazinga", data_[0]);
-}
-
-TEST_F(EventStreamTest, CutInsideTag) {
- Feed("eve");
- Feed("nt: abc\n");
- Feed("da");
- Feed("ta: bazinga\n\n");
- Done();
-
- EXPECT_EQ(1u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("bazinga", data_[0]);
-}
-
-TEST_F(EventStreamTest, CutInsideData) {
- Feed("event: abc\n");
- Feed("data: baz");
- Feed("inga\n\n");
- Done();
-
- EXPECT_EQ(1u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("bazinga", data_[0]);
-}
-
-TEST_F(EventStreamTest, DataInMultipleLines) {
- Feed("event: abc\n");
- Feed("data: baz\n");
- Feed("data: in\ndata: ga\n");
- Feed("\n");
- Done();
-
- EXPECT_EQ(1u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("baz\nin\nga", data_[0]);
-}
-
-TEST_F(EventStreamTest, IgnoreUnknownFieldNames) {
- Feed("event: abc\n");
- Feed("data: baz\n");
- Feed("trololo: trololo\n"); // Unknown field name.
- Feed("data: in\ndata: ga\n");
- Feed("\n");
- Done();
-
- EXPECT_EQ(1u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("baz\nin\nga", data_[0]);
-}
-
-TEST_F(EventStreamTest, IgnoreLinesStartingWithColon) {
- Feed("event: abc\n");
- Feed(":ignore me, trololo\n");
- Feed("data: bazinga\n\n");
- Done();
-
- EXPECT_EQ(1u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("bazinga", data_[0]);
-}
-
-TEST_F(EventStreamTest, MultipleEvents) {
- Feed("event: abc\n");
- Feed("data: bazinga\n\n");
- Feed("event: cde\n");
- Feed("data: 42\n\n");
- Feed("event: fgh\n");
- Feed("data: 50\n\n");
- Done();
-
- EXPECT_EQ(3u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("bazinga", data_[0]);
-
- EXPECT_EQ(Status::OK, status_[1]);
- EXPECT_EQ("cde", events_[1]);
- EXPECT_EQ("42", data_[1]);
-
- EXPECT_EQ(Status::OK, status_[2]);
- EXPECT_EQ("fgh", events_[2]);
- EXPECT_EQ("50", data_[2]);
-}
-
-TEST_F(EventStreamTest, DeleteOnEvent) {
- delete_on_event_ = true;
- fsl::BlockingCopyFromString("event: abc\ndata: bazinga\n\n",
- producer_socket_);
-
- RunLoopUntilIdle();
-
- EXPECT_EQ(1u, status_.size());
- EXPECT_EQ(Status::OK, status_[0]);
- EXPECT_EQ("abc", events_[0]);
- EXPECT_EQ("bazinga", data_[0]);
-}
-
-} // namespace
-} // namespace firebase
diff --git a/lib/firebase/firebase.h b/lib/firebase/firebase.h
deleted file mode 100644
index abcce08..0000000
--- a/lib/firebase/firebase.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_FIREBASE_H_
-#define PERIDOT_LIB_FIREBASE_FIREBASE_H_
-
-#include <functional>
-#include <string>
-#include <vector>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <rapidjson/document.h>
-
-#include "peridot/lib/firebase/status.h"
-#include "peridot/lib/firebase/watch_client.h"
-
-namespace firebase {
-
-class Firebase {
- public:
- Firebase() {}
- virtual ~Firebase() {}
-
- // Common parameters:
- // |query_params| - array of params that are joined using the "&" separator
- // passed verbatim as the query parameter of the request. Can be empty.
-
- // Retrieves the JSON representation of the data under the given path. See
- // https://firebase.google.com/docs/database/rest/retrieve-data.
- //
- // TODO(ppi): support response Content-Length header, see LE-210.
- virtual void Get(const std::string& key,
- const std::vector<std::string>& query_params,
- fit::function<void(Status status,
- std::unique_ptr<rapidjson::Value> value)>
- callback) = 0;
-
- // Overwrites the data under the given path. Data needs to be a valid JSON
- // object or JSON primitive value.
- // https://firebase.google.com/docs/database/rest/save-data
- virtual void Put(const std::string& key,
- const std::vector<std::string>& query_params,
- const std::string& data,
- fit::function<void(Status status)> callback) = 0;
-
- // Adds or updates multiple keys under the given path. Data needs to be a
- // JSON dictionary.
- // https://firebase.google.com/docs/database/rest/save-data
- virtual void Patch(const std::string& key,
- const std::vector<std::string>& query_params,
- const std::string& data,
- fit::function<void(Status status)> callback) = 0;
-
- // Deletes the data under the given path.
- virtual void Delete(const std::string& key,
- const std::vector<std::string>& query_params,
- fit::function<void(Status status)> callback) = 0;
-
- // Registers the given |watch_client| to receive notifications about changes
- // under the given |key|. See
- // https://firebase.google.com/docs/database/rest/retrieve-data.
- virtual void Watch(const std::string& key,
- const std::vector<std::string>& query_params,
- WatchClient* watch_client) = 0;
-
- // Unregisters the given |watch_client|. No calls on the client will be made
- // after this method returns.
- virtual void UnWatch(WatchClient* watch_client) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(Firebase);
-};
-
-} // namespace firebase
-
-#endif // PERIDOT_LIB_FIREBASE_FIREBASE_H_
diff --git a/lib/firebase/firebase_impl.cc b/lib/firebase/firebase_impl.cc
deleted file mode 100644
index 862cbdd..0000000
--- a/lib/firebase/firebase_impl.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase/firebase_impl.h"
-
-#include <memory>
-#include <sstream>
-#include <utility>
-
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/ascii.h>
-#include <lib/fxl/strings/join_strings.h>
-
-#include "peridot/lib/socket/socket_drainer_client.h"
-
-namespace firebase {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-namespace {
-
-fit::function<http::URLRequest()> MakeRequest(const std::string& url,
- const std::string& method,
- const std::string& message,
- bool stream_request = false) {
- fsl::SizedVmo body;
- if (!message.empty()) {
- if (!fsl::VmoFromString(message, &body)) {
- FXL_LOG(ERROR) << "Unable to create VMO from string.";
- return nullptr;
- }
- }
-
- return fxl::MakeCopyable(
- [url, method, body = std::move(body), stream_request]() {
- http::URLRequest request;
- request.url = url;
- request.method = method;
- request.auto_follow_redirects = true;
- if (body) {
- fsl::SizedVmo duplicated_body;
- zx_status_t status =
- body.Duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_READ, &duplicated_body);
- if (status != ZX_OK) {
- FXL_LOG(WARNING) << "Unable to duplicate a vmo. Status: " << status;
- return http::URLRequest();
- }
- request.body = http::URLBody::New();
- request.body->set_buffer(std::move(duplicated_body).ToTransport());
- }
- if (stream_request) {
- http::HttpHeader accept_header;
- accept_header.name = "Accept";
- accept_header.value = "text/event-stream";
- request.headers.push_back(std::move(accept_header));
- }
- return request;
- });
-}
-
-} // namespace
-
-struct FirebaseImpl::WatchData {
- WatchData();
- ~WatchData();
-
- callback::AutoCancel request;
- std::unique_ptr<EventStream> event_stream;
- std::unique_ptr<socket::SocketDrainerClient> drainer;
-};
-
-FirebaseImpl::WatchData::WatchData() {}
-FirebaseImpl::WatchData::~WatchData() {}
-
-FirebaseImpl::FirebaseImpl(network_wrapper::NetworkWrapper* network_wrapper,
- const std::string& db_id, const std::string& prefix)
- : network_wrapper_(network_wrapper), api_url_(BuildApiUrl(db_id, prefix)) {
- FXL_DCHECK(network_wrapper_);
-}
-
-FirebaseImpl::~FirebaseImpl() {}
-
-void FirebaseImpl::Get(
- const std::string& key, const std::vector<std::string>& query_params,
- fit::function<void(Status status, std::unique_ptr<rapidjson::Value> value)>
- callback) {
- auto request_callback = [callback = std::move(callback)](
- Status status, const std::string& response) {
- if (status != Status::OK) {
- callback(status, std::make_unique<rapidjson::Value>());
- return;
- }
-
- auto document = std::make_unique<rapidjson::Document>();
- document->Parse(response.c_str(), response.size());
- if (document->HasParseError()) {
- callback(Status::PARSE_ERROR, std::make_unique<rapidjson::Value>());
- return;
- }
-
- callback(Status::OK, std::move(document));
- };
-
- Request(BuildRequestUrl(key, query_params), "GET", "",
- std::move(request_callback));
-}
-
-void FirebaseImpl::Put(const std::string& key,
- const std::vector<std::string>& query_params,
- const std::string& data,
- fit::function<void(Status status)> callback) {
- Request(BuildRequestUrl(key, query_params), "PUT", data,
- [callback = std::move(callback)](Status status,
- const std::string& response) {
- // Ignore the response body, which is the same data we sent to the
- // server.
- callback(status);
- });
-}
-
-void FirebaseImpl::Patch(const std::string& key,
- const std::vector<std::string>& query_params,
- const std::string& data,
- fit::function<void(Status status)> callback) {
- Request(BuildRequestUrl(key, query_params), "PATCH", data,
- [callback = std::move(callback)](Status status,
- const std::string& response) {
- // Ignore the response body, which is the same data we sent to the
- // server.
- callback(status);
- });
-}
-
-void FirebaseImpl::Delete(const std::string& key,
- const std::vector<std::string>& query_params,
- fit::function<void(Status status)> callback) {
- Request(
- BuildRequestUrl(key, query_params), "DELETE", "",
- [callback = std::move(callback)](
- Status status, const std::string& response) { callback(status); });
-}
-
-void FirebaseImpl::Watch(const std::string& key,
- const std::vector<std::string>& query_params,
- WatchClient* watch_client) {
- watch_data_[watch_client] = std::make_unique<WatchData>();
- watch_data_[watch_client]->request.Reset(network_wrapper_->Request(
- MakeRequest(BuildRequestUrl(key, query_params), "GET", "", true),
- [this, watch_client](http::URLResponse response) {
- OnStream(watch_client, std::move(response));
- }));
-}
-
-void FirebaseImpl::UnWatch(WatchClient* watch_client) {
- watch_data_.erase(watch_client);
-}
-
-std::string FirebaseImpl::BuildApiUrl(const std::string& db_id,
- const std::string& prefix) {
- std::string api_url = "https://" + db_id + ".firebaseio.com";
-
- if (!prefix.empty()) {
- FXL_DCHECK(prefix.front() != '/');
- FXL_DCHECK(prefix.back() != '/');
- api_url.append("/");
- api_url.append(prefix);
- }
-
- FXL_DCHECK(api_url.back() != '/');
- return api_url;
-}
-
-std::string FirebaseImpl::BuildRequestUrl(
- const std::string& key,
- const std::vector<std::string>& query_params) const {
- std::ostringstream result;
- result << api_url_;
- result << "/" << key << ".json";
- if (query_params.empty()) {
- return result.str();
- }
- result << "?" << fxl::JoinStrings(query_params, "&");
- return result.str();
-}
-
-void FirebaseImpl::Request(
- const std::string& url, const std::string& method,
- const std::string& message,
- fit::function<void(Status status, std::string response)> callback) {
- requests_.emplace(network_wrapper_->Request(
- MakeRequest(url, method, message),
- [this,
- callback = std::move(callback)](http::URLResponse response) mutable {
- OnResponse(std::move(callback), std::move(response));
- }));
-}
-
-void FirebaseImpl::OnResponse(
- fit::function<void(Status status, std::string response)> callback,
- http::URLResponse response) {
- if (response.error) {
- FXL_LOG(ERROR) << response.url << " error " << response.error->description;
- callback(Status::NETWORK_ERROR, "");
- return;
- }
-
- if (response.status_code != 200 && response.status_code != 204) {
- const std::string& url = response.url;
- const std::string& status_line = response.status_line;
- FXL_DCHECK(response.body->is_stream());
- auto& drainer = drainers_.emplace();
- drainer.Start(std::move(response.body->stream()),
- [callback = std::move(callback), url,
- status_line](const std::string& body) {
- FXL_LOG(ERROR)
- << url << " error " << status_line << ":" << std::endl
- << body;
- callback(Status::SERVER_ERROR, "");
- });
- return;
- }
-
- FXL_DCHECK(response.body->is_stream());
- auto& drainer = drainers_.emplace();
- drainer.Start(std::move(response.body->stream()),
- [callback = std::move(callback)](const std::string& body) {
- callback(Status::OK, body);
- });
-}
-
-void FirebaseImpl::OnStream(WatchClient* watch_client,
- http::URLResponse response) {
- if (response.error) {
- FXL_LOG(ERROR) << response.url << " error " << response.error->description;
- watch_client->OnConnectionError();
- watch_data_.erase(watch_client);
- return;
- }
-
- FXL_DCHECK(response.body->is_stream());
-
- if (response.status_code != 200 && response.status_code != 204) {
- const std::string& url = response.url;
- const std::string& status_line = response.status_line;
- watch_data_[watch_client]->drainer =
- std::make_unique<socket::SocketDrainerClient>();
- watch_data_[watch_client]->drainer->Start(
- std::move(response.body->stream()),
- [this, watch_client, url, status_line](const std::string& body) {
- FXL_LOG(ERROR) << url << " error " << status_line << ":" << std::endl
- << body;
- watch_client->OnConnectionError();
- watch_data_.erase(watch_client);
- });
- return;
- }
-
- watch_data_[watch_client]->event_stream = std::make_unique<EventStream>();
- watch_data_[watch_client]->event_stream->Start(
- std::move(response.body->stream()),
- [this, watch_client](Status status, const std::string& event,
- const std::string& data) {
- OnStreamEvent(watch_client, status, event, data);
- },
- [this, watch_client]() { OnStreamComplete(watch_client); });
-}
-
-void FirebaseImpl::OnStreamComplete(WatchClient* watch_client) {
- watch_data_[watch_client]->event_stream.reset();
- watch_client->OnConnectionError();
- watch_data_.erase(watch_client);
-}
-
-void FirebaseImpl::OnStreamEvent(WatchClient* watch_client, Status /*status*/,
- const std::string& event,
- const std::string& payload) {
- if (event == "put" || event == "patch") {
- rapidjson::Document parsed_payload;
- parsed_payload.Parse(payload.c_str(), payload.size());
- if (parsed_payload.HasParseError()) {
- HandleMalformedEvent(watch_client, event, payload,
- "failed to parse the event payload");
- return;
- }
-
- // Both 'put' and 'patch' events must carry a dictionary of "path" and
- // "data".
- if (!parsed_payload.IsObject()) {
- HandleMalformedEvent(watch_client, event, payload,
- "event payload doesn't appear to be an object");
- return;
- }
- if (!parsed_payload.HasMember("path") ||
- !parsed_payload["path"].IsString()) {
- HandleMalformedEvent(watch_client, event, payload,
- "event payload doesn't contain the `path` string");
- return;
- }
- if (!parsed_payload.HasMember("data")) {
- HandleMalformedEvent(watch_client, event, payload,
- "event payload doesn't contain the `data` member");
- return;
- }
-
- if (event == "put") {
- watch_client->OnPut(parsed_payload["path"].GetString(),
- parsed_payload["data"]);
- } else if (event == "patch") {
- // In case of patch, data must be a dictionary itself.
- if (!parsed_payload["data"].IsObject()) {
- HandleMalformedEvent(
- watch_client, event, payload,
- "event payload `data` member doesn't appear to be an object");
- return;
- }
-
- watch_client->OnPatch(parsed_payload["path"].GetString(),
- parsed_payload["data"]);
- } else {
- FXL_NOTREACHED();
- }
- } else if (event == "keep-alive") {
- // Do nothing.
- } else if (event == "cancel") {
- watch_client->OnCancel();
- } else if (event == "auth_revoked") {
- watch_client->OnAuthRevoked(payload);
- } else {
- HandleMalformedEvent(watch_client, event, payload,
- "unrecognized event type");
- }
-}
-
-void FirebaseImpl::HandleMalformedEvent(WatchClient* watch_client,
- const std::string& event,
- const std::string& payload,
- const char error_description[]) {
- FXL_LOG(ERROR) << "Error processing a Firebase event: " << error_description;
- FXL_LOG(ERROR) << "Event: " << event;
- FXL_LOG(ERROR) << "Data: " << payload;
- watch_client->OnMalformedEvent();
-}
-
-} // namespace firebase
diff --git a/lib/firebase/firebase_impl.h b/lib/firebase/firebase_impl.h
deleted file mode 100644
index d44612a..0000000
--- a/lib/firebase/firebase_impl.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_FIREBASE_IMPL_H_
-#define PERIDOT_LIB_FIREBASE_FIREBASE_IMPL_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <lib/callback/auto_cleanable.h>
-#include <lib/callback/cancellable.h>
-#include <lib/fit/function.h>
-#include <lib/network_wrapper/network_wrapper.h>
-#include <rapidjson/document.h>
-
-#include "peridot/lib/firebase/event_stream.h"
-#include "peridot/lib/firebase/firebase.h"
-#include "peridot/lib/firebase/status.h"
-#include "peridot/lib/firebase/watch_client.h"
-#include "peridot/lib/socket/socket_drainer_client.h"
-
-namespace firebase {
-
-class FirebaseImpl : public Firebase {
- public:
- // |db_id| is the identifier of the Firebase Realtime Database instance. E.g.,
- // if the database is hosted at https://example.firebaseio.com/, its
- // identifier is "example".
- //
- // |prefix| is a url prefix against which all requests will be made, without a
- // leading or trailing slash. (possible with slashes inside) If empty,
- // requests will be made against root of the database.
- FirebaseImpl(network_wrapper::NetworkWrapper* network_wrapper,
- const std::string& db_id, const std::string& prefix);
- ~FirebaseImpl() override;
-
- // Firebase:
- void Get(const std::string& key, const std::vector<std::string>& query_params,
- fit::function<void(Status status,
- std::unique_ptr<rapidjson::Value> value)>
- callback) override;
- void Put(const std::string& key, const std::vector<std::string>& query_params,
- const std::string& data,
- fit::function<void(Status status)> callback) override;
- void Patch(const std::string& key,
- const std::vector<std::string>& query_params,
- const std::string& data,
- fit::function<void(Status status)> callback) override;
- void Delete(const std::string& key,
- const std::vector<std::string>& query_params,
- fit::function<void(Status status)> callback) override;
- void Watch(const std::string& key,
- const std::vector<std::string>& query_params,
- WatchClient* watch_client) override;
- void UnWatch(WatchClient* watch_client) override;
-
- const std::string& api_url() { return api_url_; }
-
- private:
- std::string BuildApiUrl(const std::string& db_id, const std::string& prefix);
-
- std::string BuildRequestUrl(
- const std::string& key,
- const std::vector<std::string>& query_params) const;
-
- void Request(
- const std::string& url, const std::string& method,
- const std::string& message,
- fit::function<void(Status status, std::string response)> callback);
-
- void OnResponse(
- fit::function<void(Status status, std::string response)> callback,
- ::fuchsia::net::oldhttp::URLResponse response);
-
- void OnStream(WatchClient* watch_client,
- ::fuchsia::net::oldhttp::URLResponse response);
-
- void OnStreamComplete(WatchClient* watch_client);
-
- void OnStreamEvent(WatchClient* watch_client, Status status,
- const std::string& event, const std::string& payload);
-
- void HandleMalformedEvent(WatchClient* watch_client, const std::string& event,
- const std::string& payload,
- const char error_description[]);
-
- network_wrapper::NetworkWrapper* const network_wrapper_;
- // Api url against which requests are made, without a trailing slash.
- const std::string api_url_;
-
- callback::CancellableContainer requests_;
- callback::AutoCleanableSet<socket::SocketDrainerClient> drainers_;
-
- struct WatchData;
- std::map<WatchClient*, std::unique_ptr<WatchData>> watch_data_;
-};
-
-} // namespace firebase
-
-#endif // PERIDOT_LIB_FIREBASE_FIREBASE_IMPL_H_
diff --git a/lib/firebase/firebase_impl_unittest.cc b/lib/firebase/firebase_impl_unittest.cc
deleted file mode 100644
index 7811484..0000000
--- a/lib/firebase/firebase_impl_unittest.cc
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase/firebase_impl.h"
-
-#include <memory>
-#include <utility>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fsl/socket/strings.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include <lib/network_wrapper/fake_network_wrapper.h>
-#include <lib/network_wrapper/network_wrapper_impl.h>
-#include <rapidjson/document.h>
-
-#include "peridot/lib/socket/socket_pair.h"
-
-namespace firebase {
-namespace {
-
-class FirebaseImplTest : public gtest::TestLoopFixture, public WatchClient {
- public:
- FirebaseImplTest()
- : fake_network_wrapper_(dispatcher()),
- firebase_(&fake_network_wrapper_, "example", "pre/fix") {}
- ~FirebaseImplTest() override {}
-
- protected:
- // WatchClient:
- void OnPut(const std::string& path, const rapidjson::Value& value) override {
- put_count_++;
- put_paths_.push_back(path);
- put_data_.emplace_back(value, document_.GetAllocator());
- }
-
- void OnPatch(const std::string& path,
- const rapidjson::Value& value) override {
- patch_count_++;
- patch_paths_.push_back(path);
- patch_data_.emplace_back(value, document_.GetAllocator());
- }
-
- void OnCancel() override { cancel_count_++; }
-
- void OnAuthRevoked(const std::string& reason) override {
- auth_revoked_count_++;
- auth_revoked_reasons_.push_back(reason);
- }
-
- void OnMalformedEvent() override { malformed_event_count_++; }
-
- void OnConnectionError() override { connection_error_count_++; }
-
- std::vector<std::string> put_paths_;
- std::vector<rapidjson::Value> put_data_;
- unsigned int put_count_ = 0u;
-
- std::vector<std::string> patch_paths_;
- std::vector<rapidjson::Value> patch_data_;
- unsigned int patch_count_ = 0u;
-
- unsigned int cancel_count_ = 0u;
-
- std::vector<std::string> auth_revoked_reasons_;
- unsigned int auth_revoked_count_ = 0u;
-
- unsigned int malformed_event_count_ = 0u;
-
- unsigned int connection_error_count_ = 0u;
-
- network_wrapper::FakeNetworkWrapper fake_network_wrapper_;
- FirebaseImpl firebase_;
-
- private:
- // Used for its allocator which we use to make copies of rapidjson Values.
- rapidjson::Document document_;
- FXL_DISALLOW_COPY_AND_ASSIGN(FirebaseImplTest);
-};
-
-// Verifies that GET requests are handled correctly.
-TEST_F(FirebaseImplTest, Get) {
- fake_network_wrapper_.SetStringResponse("\"content\"", 200);
-
- bool called;
- Status status;
- std::unique_ptr<rapidjson::Value> value;
- firebase_.Get(
- "bazinga", {},
- callback::Capture(callback::SetWhenCalled(&called), &status, &value));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- ASSERT_TRUE(value);
- EXPECT_TRUE(value->IsString());
- EXPECT_EQ("content", *value);
- EXPECT_EQ("https://example.firebaseio.com/pre/fix/bazinga.json",
- fake_network_wrapper_.GetRequest()->url);
- EXPECT_EQ("GET", fake_network_wrapper_.GetRequest()->method);
-}
-
-TEST_F(FirebaseImplTest, GetError) {
- fake_network_wrapper_.SetStringResponse("\"content\"", 404);
- bool called;
- Status status;
- std::unique_ptr<rapidjson::Value> value;
- firebase_.Get(
- "bazinga", {},
- callback::Capture(callback::SetWhenCalled(&called), &status, &value));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_NE(Status::OK, status);
- ASSERT_TRUE(value);
- EXPECT_TRUE(value->IsNull());
-}
-
-TEST_F(FirebaseImplTest, GetWithSingleQueryParam) {
- fake_network_wrapper_.SetStringResponse("content", 200);
- bool called;
- Status status;
- firebase_.Get("bazinga", {"orderBy=\"timestamp\""},
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &std::ignore));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PARSE_ERROR, status);
- EXPECT_EQ(
- "https://example.firebaseio.com/pre/fix/"
- "bazinga.json?orderBy=\"timestamp\"",
- fake_network_wrapper_.GetRequest()->url);
- EXPECT_EQ("GET", fake_network_wrapper_.GetRequest()->method);
-}
-
-TEST_F(FirebaseImplTest, GetWithTwoQueryParams) {
- fake_network_wrapper_.SetStringResponse("content", 200);
- bool called;
- Status status;
- firebase_.Get("bazinga", {"one_param", "other_param=bla"},
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &std::ignore));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::PARSE_ERROR, status);
- EXPECT_EQ(
- "https://example.firebaseio.com/pre/fix/"
- "bazinga.json?one_param&other_param=bla",
- fake_network_wrapper_.GetRequest()->url);
- EXPECT_EQ("GET", fake_network_wrapper_.GetRequest()->method);
-}
-
-// Verifies that request urls for root of the db are correctly formed.
-TEST_F(FirebaseImplTest, Root) {
- fake_network_wrapper_.SetStringResponse("42", 200);
- bool called;
- Status status;
- firebase_.Get("", {},
- callback::Capture(callback::SetWhenCalled(&called), &status,
- &std::ignore));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ("https://example.firebaseio.com/pre/fix/.json",
- fake_network_wrapper_.GetRequest()->url);
-}
-
-// Verifies that PUT requests are handled correctly.
-TEST_F(FirebaseImplTest, Put) {
- // Firebase server seems to respond with the data we sent to it. This is not
- // useful for the client so our API doesn't expose it to the client.
- fake_network_wrapper_.SetStringResponse("\"Alice\"", 200);
- bool called;
- Status status;
- firebase_.Put("name", {}, "\"Alice\"",
- callback::Capture(callback::SetWhenCalled(&called), &status));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ("https://example.firebaseio.com/pre/fix/name.json",
- fake_network_wrapper_.GetRequest()->url);
- EXPECT_EQ("PUT", fake_network_wrapper_.GetRequest()->method);
-}
-
-// Verifies that PATCH requests are handled correctly.
-TEST_F(FirebaseImplTest, Patch) {
- fake_network_wrapper_.SetStringResponse("\"ok\"", 200);
- bool called;
- Status status;
- std::string data = R"({"name":"Alice"})";
- firebase_.Patch("person", {}, data,
- callback::Capture(callback::SetWhenCalled(&called), &status));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ("https://example.firebaseio.com/pre/fix/person.json",
- fake_network_wrapper_.GetRequest()->url);
- EXPECT_EQ("PATCH", fake_network_wrapper_.GetRequest()->method);
-}
-
-// Verifies that DELETE requests are made correctly.
-TEST_F(FirebaseImplTest, Delete) {
- fake_network_wrapper_.SetStringResponse("", 200);
- bool called;
- Status status;
- firebase_.Delete(
- "name", {}, callback::Capture(callback::SetWhenCalled(&called), &status));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(Status::OK, status);
- EXPECT_EQ("https://example.firebaseio.com/pre/fix/name.json",
- fake_network_wrapper_.GetRequest()->url);
- EXPECT_EQ("DELETE", fake_network_wrapper_.GetRequest()->method);
-}
-
-// Verifies that event-stream requests are correctly formed.
-TEST_F(FirebaseImplTest, WatchRequest) {
- fake_network_wrapper_.SetStringResponse("", 200);
-
- firebase_.Watch("some/path", {}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ("https://example.firebaseio.com/pre/fix/some/path.json",
- fake_network_wrapper_.GetRequest()->url);
- EXPECT_EQ("GET", fake_network_wrapper_.GetRequest()->method);
- EXPECT_EQ(1u, fake_network_wrapper_.GetRequest()->headers->size());
- EXPECT_EQ("Accept", fake_network_wrapper_.GetRequest()->headers->at(0).name);
- EXPECT_EQ("text/event-stream",
- fake_network_wrapper_.GetRequest()->headers->at(0).value);
-}
-
-TEST_F(FirebaseImplTest, WatchRequestWithQuery) {
- fake_network_wrapper_.SetStringResponse("", 200);
-
- firebase_.Watch("some/path", {"orderBy=\"timestamp\""}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ(
- "https://example.firebaseio.com/pre/fix/some/path.json"
- "?orderBy=\"timestamp\"",
- fake_network_wrapper_.GetRequest()->url);
- EXPECT_EQ("GET", fake_network_wrapper_.GetRequest()->method);
- EXPECT_EQ(1u, fake_network_wrapper_.GetRequest()->headers->size());
- EXPECT_EQ("Accept", fake_network_wrapper_.GetRequest()->headers->at(0).name);
- EXPECT_EQ("text/event-stream",
- fake_network_wrapper_.GetRequest()->headers->at(0).value);
-}
-
-TEST_F(FirebaseImplTest, WatchPut) {
- std::string stream_body = std::string(
- "event: put\n"
- "data: {\"path\":\"/\",\"data\":\"Alice\"}\n"
- "\n"
- "event: put\n"
- "data: {\"path\":\"/bla/\",\"data\":{\"name\":\"Bob\"}}\n"
- "\n"
- "event: put\n"
- "data: {\"path\":\"/\",\"data\":42.5}\n"
- "\n");
- fake_network_wrapper_.SetStringResponse(stream_body, 200);
-
- firebase_.Watch("/", {}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ(3u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
-
- EXPECT_EQ("/", put_paths_[0]);
- EXPECT_EQ("Alice", put_data_[0]);
-
- EXPECT_EQ("/bla/", put_paths_[1]);
- EXPECT_EQ("Bob", put_data_[1]["name"]);
-
- EXPECT_EQ("/", put_paths_[2]);
- EXPECT_EQ(42.5, put_data_[2]);
-}
-
-TEST_F(FirebaseImplTest, WatchPatch) {
- std::string stream_body = std::string(
- "event: patch\n"
- "data: "
- "{\"path\":\"/bla/\",\"data\":{\"name1\":\"Alice\",\"name2\":\"Bob\"}}\n"
- "\n");
- fake_network_wrapper_.SetStringResponse(stream_body, 200);
-
- firebase_.Watch("/", {}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ(0u, put_count_);
- EXPECT_EQ(1u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
-
- EXPECT_EQ("/bla/", patch_paths_[0]);
- EXPECT_EQ("Alice", patch_data_[0]["name1"]);
- EXPECT_EQ("Bob", patch_data_[0]["name2"]);
-}
-
-TEST_F(FirebaseImplTest, WatchKeepAlive) {
- std::string stream_body = std::string(
- "event: keep-alive\n"
- "data: null\n"
- "\n");
- fake_network_wrapper_.SetStringResponse(stream_body, 200);
-
- firebase_.Watch("name", {}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ(0u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
-}
-
-TEST_F(FirebaseImplTest, WatchCancel) {
- std::string stream_body = std::string(
- "event: cancel\n"
- "data: null\n"
- "\n");
- fake_network_wrapper_.SetStringResponse(stream_body, 200);
-
- firebase_.Watch("/", {}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ(0u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(1u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
-}
-
-TEST_F(FirebaseImplTest, WatchAuthRevoked) {
- std::string stream_body = std::string(
- "event: auth_revoked\n"
- "data: credential is no longer valid\n"
- "\n");
- fake_network_wrapper_.SetStringResponse(stream_body, 200);
-
- firebase_.Watch("/", {}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ(0u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(1u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
-
- EXPECT_EQ("credential is no longer valid", auth_revoked_reasons_[0]);
-}
-
-TEST_F(FirebaseImplTest, WatchErrorUnknownEvent) {
- std::string stream_body = std::string(
- "event: wild-animal-appears\n"
- "data: null\n"
- "\n");
- fake_network_wrapper_.SetStringResponse(stream_body, 200);
-
- firebase_.Watch("/", {}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ(0u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(1u, malformed_event_count_);
-}
-
-TEST_F(FirebaseImplTest, WatchHttpError) {
- fake_network_wrapper_.SetStringResponse("", 404);
-
- firebase_.Watch("/", {}, this);
- RunLoopUntilIdle();
-
- EXPECT_EQ(0u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
- EXPECT_EQ(1u, connection_error_count_);
-}
-
-TEST_F(FirebaseImplTest, UnWatch) {
- std::string event = std::string(
- "event: put\n"
- "data: {\"path\":\"/\",\"data\":\"Alice\"}\n"
- "\n");
- socket::SocketPair socket;
- fake_network_wrapper_.SetSocketResponse(std::move(socket.socket1), 200);
- firebase_.Watch("/", {}, this);
-
- EXPECT_TRUE(fsl::BlockingCopyFromString(event, socket.socket2));
- RunLoopUntilIdle();
-
- EXPECT_EQ(1u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
- EXPECT_EQ(0u, connection_error_count_);
-
- EXPECT_TRUE(fsl::BlockingCopyFromString(event, socket.socket2));
- RunLoopUntilIdle();
-
- EXPECT_EQ(2u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
- EXPECT_EQ(0u, connection_error_count_);
-
- // Unregister the watch client and make sure that we are *not* notified about
- // the next event.
- firebase_.UnWatch(this);
- EXPECT_TRUE(fsl::BlockingCopyFromString(event, socket.socket2));
- RunLoopUntilIdle();
-
- EXPECT_EQ(2u, put_count_);
- EXPECT_EQ(0u, patch_count_);
- EXPECT_EQ(0u, cancel_count_);
- EXPECT_EQ(0u, auth_revoked_count_);
- EXPECT_EQ(0u, malformed_event_count_);
- EXPECT_EQ(0u, connection_error_count_);
-}
-
-} // namespace
-} // namespace firebase
diff --git a/lib/firebase/status.cc b/lib/firebase/status.cc
deleted file mode 100644
index 09521f9..0000000
--- a/lib/firebase/status.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase/status.h"
-
-namespace firebase {
-
-fxl::StringView StatusToString(Status status) {
- switch (status) {
- case Status::OK:
- return "OK";
- case Status::NETWORK_ERROR:
- return "NETWORK_ERROR";
- case Status::PARSE_ERROR:
- return "PARSE_ERROR";
- case Status::SERVER_ERROR:
- return "SERVER_ERROR";
- }
-}
-
-std::ostream& operator<<(std::ostream& os, Status status) {
- return os << StatusToString(status);
-}
-
-} // namespace firebase
diff --git a/lib/firebase/status.h b/lib/firebase/status.h
deleted file mode 100644
index 7457290..0000000
--- a/lib/firebase/status.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_STATUS_H_
-#define PERIDOT_LIB_FIREBASE_STATUS_H_
-
-#include <iostream>
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace firebase {
-
-enum class Status { OK, NETWORK_ERROR, PARSE_ERROR, SERVER_ERROR };
-
-fxl::StringView StatusToString(Status status);
-
-std::ostream& operator<<(std::ostream& os, Status status);
-
-} // namespace firebase
-
-#endif // PERIDOT_LIB_FIREBASE_STATUS_H_
diff --git a/lib/firebase/watch_client.h b/lib/firebase/watch_client.h
deleted file mode 100644
index c15670a..0000000
--- a/lib/firebase/watch_client.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_WATCH_CLIENT_H_
-#define PERIDOT_LIB_FIREBASE_WATCH_CLIENT_H_
-
-#include <rapidjson/document.h>
-
-namespace firebase {
-
-class WatchClient {
- public:
- virtual ~WatchClient() {}
-
- // See
- // https://firebase.google.com/docs/database/rest/retrieve-data#section-rest-streaming
- virtual void OnPut(const std::string& path,
- const rapidjson::Value& value) = 0;
- virtual void OnPatch(const std::string& path,
- const rapidjson::Value& value) = 0;
- virtual void OnCancel() = 0;
- virtual void OnAuthRevoked(const std::string& reason) = 0;
-
- // Called when a Firebase event of incorrect format is received. Such
- // notification is ignored, further events continue to be processed after this
- // call (but clients might choose to close the stream themselves).
- virtual void OnMalformedEvent() = 0;
-
- // Called when the stream of events can't be established, or is interrupted,
- // or the server closes the connection. No further calls will be made on this
- // WatchClient.
- virtual void OnConnectionError() = 0;
-};
-
-} // namespace firebase
-
-#endif // PERIDOT_LIB_FIREBASE_WATCH_CLIENT_H_
diff --git a/lib/firebase_auth/BUILD.gn b/lib/firebase_auth/BUILD.gn
deleted file mode 100644
index 4e847f0..0000000
--- a/lib/firebase_auth/BUILD.gn
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- "//peridot/bin/*",
- "//peridot/lib/*",
-]
-
-# TODO(prathyushk): Refactor this once the GN feature discussed below
-# is available.
-# https://groups.google.com/a/chromium.org/d/msg/gn-dev/zoVnBgjLgnQ/9yzGr7r3BAAJ
-#
-# This source_set depends on including the generated ledger Cobalt
-# config as a resource. See peridot/bin/ledger/BUILD.gn for an example.
-source_set("firebase_auth") {
- sources = [
- "firebase_auth.h",
- "firebase_auth_impl.cc",
- "firebase_auth_impl.h",
- ]
-
- public_deps = [
- "//garnet/public/fidl/fuchsia.auth",
- "//garnet/public/lib/backoff",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/cobalt/cpp:cobalt_logger",
- "//garnet/public/lib/fxl",
- "//peridot/lib/rng",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//zircon/public/lib/fit",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "firebase_auth_impl_unittest.cc",
- ]
-
- deps = [
- ":firebase_auth",
- "//garnet/public/lib/backoff/testing",
- "//garnet/public/lib/gtest",
- "//peridot/lib/firebase_auth/testing",
- ]
-}
diff --git a/lib/firebase_auth/firebase_auth.h b/lib/firebase_auth/firebase_auth.h
deleted file mode 100644
index 2c87c86..0000000
--- a/lib/firebase_auth/firebase_auth.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_FIREBASE_AUTH_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_FIREBASE_AUTH_H_
-
-#include <functional>
-#include <string>
-
-#include <lib/callback/cancellable.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/functional/closure.h>
-#include <lib/fxl/macros.h>
-
-namespace firebase_auth {
-
-enum class AuthStatus {
- OK,
- // Failed to retrieve the auth token.
- ERROR
-};
-
-// Source of Firebase Auth tokens that can be used to authenticate with Firebase
-// services such as Firebase Real-Time Database, Firebase Storage or Firestore.
-//
-// Each instance of this class is tied to exactly one user.
-class FirebaseAuth {
- public:
- FirebaseAuth() {}
- virtual ~FirebaseAuth() {}
-
- virtual void set_error_handler(fit::closure /*on_error*/) {}
-
- // Retrieves the Firebase ID token suitable to use with Firebase Real-time
- // Database and Firebase Storage.
- virtual fxl::RefPtr<callback::Cancellable> GetFirebaseToken(
- fit::function<void(AuthStatus, std::string)> callback) = 0;
-
- // Retrieves the Firebase user ID of the user.
- virtual fxl::RefPtr<callback::Cancellable> GetFirebaseUserId(
- fit::function<void(AuthStatus, std::string)> callback) = 0;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(FirebaseAuth);
-};
-
-} // namespace firebase_auth
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_FIREBASE_AUTH_H_
diff --git a/lib/firebase_auth/firebase_auth_impl.cc b/lib/firebase_auth/firebase_auth_impl.cc
deleted file mode 100644
index f5de43b..0000000
--- a/lib/firebase_auth/firebase_auth_impl.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/firebase_auth_impl.h"
-
-#include <utility>
-
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/callback/cancellable_helper.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/vmo/file.h>
-#include <lib/fxl/functional/closure.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-namespace firebase_auth {
-namespace {
-
-constexpr char kConfigBinProtoPath[] =
- "/pkg/data/firebase_auth_cobalt_config.pb";
-constexpr int32_t kCobaltAuthFailureMetricId = 4;
-
-// Returns true if the authentication failure may be transient.
-bool IsRetriableError(fuchsia::auth::Status status) {
- switch (status) {
- case fuchsia::auth::Status::OK: // This should never happen.
- case fuchsia::auth::Status::AUTH_PROVIDER_SERVER_ERROR:
- case fuchsia::auth::Status::AUTH_PROVIDER_SERVICE_UNAVAILABLE:
- case fuchsia::auth::Status::INVALID_AUTH_CONTEXT:
- case fuchsia::auth::Status::INVALID_REQUEST:
- case fuchsia::auth::Status::USER_NOT_FOUND:
- case fuchsia::auth::Status::USER_CANCELLED:
- case fuchsia::auth::Status::REAUTH_REQUIRED:
- return false;
- case fuchsia::auth::Status::UNKNOWN_ERROR:
- case fuchsia::auth::Status::NETWORK_ERROR:
- case fuchsia::auth::Status::INTERNAL_ERROR:
- case fuchsia::auth::Status::IO_ERROR:
- return true;
- }
- // In case of unexpected status, retry just in case.
- return true;
-}
-} // namespace
-
-FirebaseAuthImpl::FirebaseAuthImpl(
- Config config, async_dispatcher_t* dispatcher, rng::Random* random,
- fuchsia::auth::TokenManagerPtr token_manager,
- component::StartupContext* startup_context)
- : config_(std::move(config)),
- token_manager_(std::move(token_manager)),
- backoff_(std::make_unique<backoff::ExponentialBackoff>(
- random->NewBitGenerator<uint64_t>())),
- max_retries_(config_.max_retries),
- cobalt_client_name_(config_.cobalt_client_name),
- task_runner_(dispatcher) {
- if (startup_context) {
- cobalt_logger_ = cobalt::NewCobaltLogger(dispatcher, startup_context,
- kConfigBinProtoPath);
- } else {
- cobalt_logger_ = nullptr;
- }
-}
-
-FirebaseAuthImpl::FirebaseAuthImpl(
- Config config, async_dispatcher_t* dispatcher,
- fuchsia::auth::TokenManagerPtr token_manager,
- std::unique_ptr<backoff::Backoff> backoff,
- std::unique_ptr<cobalt::CobaltLogger> cobalt_logger)
- : config_(std::move(config)),
- token_manager_(std::move(token_manager)),
- backoff_(std::move(backoff)),
- max_retries_(config_.max_retries),
- cobalt_client_name_(config_.cobalt_client_name),
- cobalt_logger_(std::move(cobalt_logger)),
- task_runner_(dispatcher) {}
-
-void FirebaseAuthImpl::set_error_handler(fit::closure on_error) {
- token_manager_.set_error_handler(
- [on_error = std::move(on_error)](zx_status_t status) { on_error(); });
-}
-
-fxl::RefPtr<callback::Cancellable> FirebaseAuthImpl::GetFirebaseToken(
- fit::function<void(AuthStatus, std::string)> callback) {
- if (config_.api_key.empty()) {
- FXL_LOG(WARNING) << "No Firebase API key provided. Connection to Firebase "
- "may be unauthenticated.";
- }
- auto cancellable = callback::CancellableImpl::Create([] {});
- GetToken(max_retries_, [callback = cancellable->WrapCallback(
- std::move(callback))](auto status, auto token) {
- callback(status, token ? token->id_token : "");
- });
- return cancellable;
-}
-
-fxl::RefPtr<callback::Cancellable> FirebaseAuthImpl::GetFirebaseUserId(
- fit::function<void(AuthStatus, std::string)> callback) {
- auto cancellable = callback::CancellableImpl::Create([] {});
- GetToken(max_retries_, [callback = cancellable->WrapCallback(
- std::move(callback))](auto status, auto token) {
- callback(status, token ? token->local_id : "");
- });
- return cancellable;
-}
-
-void FirebaseAuthImpl::GetToken(
- int max_retries,
- fit::function<void(AuthStatus, fuchsia::auth::FirebaseTokenPtr)> callback) {
- fuchsia::auth::AppConfig oauth_config;
- oauth_config.auth_provider_type = "google";
-
- token_manager_->GetFirebaseToken(
- std::move(oauth_config), "", /*user_profile_id*/
- "", /*audience*/
- config_.api_key,
- fxl::MakeCopyable([this, max_retries, callback = std::move(callback)](
- fuchsia::auth::Status status,
- fuchsia::auth::FirebaseTokenPtr token) mutable {
- if (!token || status != fuchsia::auth::Status::OK) {
- if (!token && status == fuchsia::auth::Status::OK) {
- FXL_LOG(ERROR)
- << "null Firebase token returned from token provider with no "
- << "error reported. This should never happen. Retrying.";
- status = fuchsia::auth::Status::UNKNOWN_ERROR;
- } else {
- FXL_LOG(ERROR)
- << "Error retrieving the Firebase token from token provider: "
- << fidl::ToUnderlying(status) << "', retrying.";
- }
-
- if (max_retries > 0 && IsRetriableError(status)) {
- task_runner_.PostDelayedTask(
- [this, max_retries, callback = std::move(callback)]() mutable {
- GetToken(max_retries - 1, std::move(callback));
- },
- backoff_->GetNext());
- return;
- }
- }
-
- backoff_->Reset();
- if (status == fuchsia::auth::Status::OK) {
- callback(AuthStatus::OK, std::move(token));
- } else {
- ReportError(kCobaltAuthFailureMetricId,
- static_cast<uint32_t>(status));
- callback(AuthStatus::ERROR, std::move(token));
- }
- }));
-}
-
-void FirebaseAuthImpl::ReportError(int32_t metric_id, uint32_t status) {
- if (cobalt_client_name_.empty() || cobalt_logger_ == nullptr) {
- return;
- }
-
- cobalt_logger_->LogEventCount(metric_id, status, cobalt_client_name_,
- zx::duration(0), 1);
-}
-} // namespace firebase_auth
diff --git a/lib/firebase_auth/firebase_auth_impl.h b/lib/firebase_auth/firebase_auth_impl.h
deleted file mode 100644
index 3e74c2d..0000000
--- a/lib/firebase_auth/firebase_auth_impl.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_FIREBASE_AUTH_IMPL_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_FIREBASE_AUTH_IMPL_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <lib/async/dispatcher.h>
-#include <lib/backoff/backoff.h>
-#include <lib/callback/cancellable.h>
-#include <lib/callback/scoped_task_runner.h>
-#include <lib/cobalt/cpp/cobalt_logger.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fit/function.h>
-
-#include "peridot/lib/firebase_auth/firebase_auth.h"
-#include "peridot/lib/rng/random.h"
-
-namespace firebase_auth {
-
-// Source of the auth information for cloud sync to use, implemented using the
-// system token provider.
-//
-// If configured with an empty |api_key|, doesn't attempt to use
-// |token_manager| and yields empty Firebase tokens and user ids. This allows
-// the code to work without auth against public instances (e.g. for running
-// benchmarks).
-//
-// If configured with an empty |cobalt_client_name| or null |startup_context|,
-// disables statistics collection about failures.
-//
-// *Warning*: if |token_manager| disconnects, all requests in progress are
-// dropped on the floor. TODO(ppi): keep track of pending requests and call the
-// callbacks with status TOKEN_MANAGER_DISCONNECTED when this happens.
-class FirebaseAuthImpl : public FirebaseAuth {
- public:
- struct Config {
- // Value of the Firebase api key.
- std::string api_key;
- // Name of the client to record during Cobalt error reporting.
- std::string cobalt_client_name;
- // Maximum number of retries on non-fatal errors.
- int max_retries = 5;
- };
-
- FirebaseAuthImpl(Config config, async_dispatcher_t* dispatcher,
- rng::Random* random,
- fuchsia::auth::TokenManagerPtr token_manager,
- component::StartupContext* startup_context);
- // For tests.
- FirebaseAuthImpl(Config config, async_dispatcher_t* dispatcher,
- fuchsia::auth::TokenManagerPtr token_manager,
- std::unique_ptr<backoff::Backoff> backoff,
- std::unique_ptr<cobalt::CobaltLogger> cobalt_logger);
-
- // FirebaseAuth:
- void set_error_handler(fit::closure on_error) override;
-
- fxl::RefPtr<callback::Cancellable> GetFirebaseToken(
- fit::function<void(firebase_auth::AuthStatus, std::string)> callback)
- override;
-
- fxl::RefPtr<callback::Cancellable> GetFirebaseUserId(
- fit::function<void(firebase_auth::AuthStatus, std::string)> callback)
- override;
-
- private:
- // Retrieves the Firebase token from the fuchsia::auth::TokenManager,
- // transparently retrying the request up to |max_retries| times in case of
- // non-fatal errors.
- void GetToken(int max_retries,
- fit::function<void(firebase_auth::AuthStatus,
- fuchsia::auth::FirebaseTokenPtr)>
- callback);
-
- // Sends a Cobalt event for metric |metric_id| counting the error code
- // |status|, unless |cobalt_client_name_| is empty.
- void ReportError(int32_t metric_id, uint32_t status);
-
- const Config config_;
- fuchsia::auth::TokenManagerPtr token_manager_;
- const std::unique_ptr<backoff::Backoff> backoff_;
- const int max_retries_;
-
- // Members for Cobalt reporting.
- const std::string cobalt_client_name_;
- std::unique_ptr<cobalt::CobaltLogger> cobalt_logger_;
-
- // Must be the last member field.
- callback::ScopedTaskRunner task_runner_;
-};
-
-} // namespace firebase_auth
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_FIREBASE_AUTH_IMPL_H_
diff --git a/lib/firebase_auth/firebase_auth_impl_unittest.cc b/lib/firebase_auth/firebase_auth_impl_unittest.cc
deleted file mode 100644
index 58df55c..0000000
--- a/lib/firebase_auth/firebase_auth_impl_unittest.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/firebase_auth_impl.h"
-
-#include <utility>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <lib/backoff/testing/test_backoff.h>
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/lib/firebase_auth/testing/test_token_manager.h"
-
-namespace firebase_auth {
-
-namespace {
-
-class MockCobaltLogger : public cobalt::CobaltLogger {
- public:
- ~MockCobaltLogger() override = default;
-
- MockCobaltLogger(int* called) : called_(called) {}
-
- void LogEvent(uint32_t metric_id, uint32_t event_code) override {}
- void LogEventCount(uint32_t metric_id, uint32_t event_code,
- const std::string& component, zx::duration period_duration,
- int64_t count) override {
- EXPECT_EQ(4u, metric_id);
- // The value should contain the client name.
- EXPECT_TRUE(component.find("firebase-test") != std::string::npos);
- *called_ += 1;
- }
- void LogElapsedTime(uint32_t metric_id, uint32_t event_code,
- const std::string& component,
- zx::duration elapsed_time) override {}
- void LogFrameRate(uint32_t metric_id, uint32_t event_code,
- const std::string& component, float fps) override {}
- void LogMemoryUsage(uint32_t metric_id, uint32_t event_code,
- const std::string& component, int64_t bytes) override {}
- void LogString(uint32_t metric_id, const std::string& s) override {}
- void StartTimer(uint32_t metric_id, uint32_t event_code,
- const std::string& component, const std::string& timer_id,
- zx::time timestamp, zx::duration timeout) override {}
- void EndTimer(const std::string& timer_id, zx::time timestamp,
- zx::duration timeout) override {}
- void LogIntHistogram(
- uint32_t metric_id, uint32_t event_code, const std::string& component,
- std::vector<fuchsia::cobalt::HistogramBucket> histogram) override {}
- void LogCustomEvent(
- uint32_t metric_id,
- std::vector<fuchsia::cobalt::CustomEventValue> event_values) override {}
-
- private:
- int* called_;
-};
-
-class FirebaseAuthImplTest : public gtest::TestLoopFixture {
- public:
- FirebaseAuthImplTest()
- : token_manager_(dispatcher()),
- token_manager_binding_(&token_manager_),
- firebase_auth_(
- {"api_key", "firebase-test", 1}, dispatcher(),
- token_manager_binding_.NewBinding().Bind(), InitBackoff(),
- std::make_unique<MockCobaltLogger>(&report_observation_count_)) {}
-
- ~FirebaseAuthImplTest() override {}
-
- protected:
- std::unique_ptr<backoff::Backoff> InitBackoff() {
- // TODO(LE-630): Don't use a backoff duration of 0.
- auto backoff = std::make_unique<backoff::TestBackoff>(zx::sec(0));
- backoff_ = backoff.get();
- return backoff;
- }
-
- TestTokenManager token_manager_;
- fidl::Binding<fuchsia::auth::TokenManager> token_manager_binding_;
- FirebaseAuthImpl firebase_auth_;
- int report_observation_count_ = 0;
- backoff::TestBackoff* backoff_;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(FirebaseAuthImplTest);
-};
-
-TEST_F(FirebaseAuthImplTest, GetFirebaseToken) {
- token_manager_.Set("this is a token", "some id", "me@example.com");
-
- bool called;
- AuthStatus auth_status;
- std::string firebase_token;
- firebase_auth_.GetFirebaseToken(callback::Capture(
- callback::SetWhenCalled(&called), &auth_status, &firebase_token));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(AuthStatus::OK, auth_status);
- EXPECT_EQ("this is a token", firebase_token);
- EXPECT_EQ(0, report_observation_count_);
-}
-
-TEST_F(FirebaseAuthImplTest, GetFirebaseTokenRetryOnError) {
- bool called;
- AuthStatus auth_status;
- std::string firebase_token;
- token_manager_.SetError(fuchsia::auth::Status::NETWORK_ERROR);
- backoff_->SetOnGetNext(QuitLoopClosure());
- firebase_auth_.GetFirebaseToken(callback::Capture(
- callback::SetWhenCalled(&called), &auth_status, &firebase_token));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- EXPECT_EQ(1, backoff_->get_next_count);
- EXPECT_EQ(0, backoff_->reset_count);
- EXPECT_EQ(0, report_observation_count_);
-
- token_manager_.Set("this is a token", "some id", "me@example.com");
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(AuthStatus::OK, auth_status);
- EXPECT_EQ("this is a token", firebase_token);
- EXPECT_EQ(1, backoff_->get_next_count);
- EXPECT_EQ(1, backoff_->reset_count);
- EXPECT_EQ(0, report_observation_count_);
-}
-
-TEST_F(FirebaseAuthImplTest, GetFirebaseUserId) {
- token_manager_.Set("this is a token", "some id", "me@example.com");
-
- bool called;
- AuthStatus auth_status;
- std::string firebase_user_id;
- firebase_auth_.GetFirebaseUserId(callback::Capture(
- callback::SetWhenCalled(&called), &auth_status, &firebase_user_id));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(AuthStatus::OK, auth_status);
- EXPECT_EQ("some id", firebase_user_id);
- EXPECT_EQ(0, report_observation_count_);
-}
-
-TEST_F(FirebaseAuthImplTest, GetFirebaseUserIdRetryOnError) {
- bool called;
- AuthStatus auth_status;
- std::string firebase_id;
- token_manager_.SetError(fuchsia::auth::Status::NETWORK_ERROR);
- backoff_->SetOnGetNext(QuitLoopClosure());
- firebase_auth_.GetFirebaseUserId(callback::Capture(
- callback::SetWhenCalled(&called), &auth_status, &firebase_id));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- EXPECT_EQ(1, backoff_->get_next_count);
- EXPECT_EQ(0, backoff_->reset_count);
- EXPECT_EQ(0, report_observation_count_);
-
- token_manager_.Set("this is a token", "some id", "me@example.com");
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(AuthStatus::OK, auth_status);
- EXPECT_EQ("some id", firebase_id);
- EXPECT_EQ(1, backoff_->get_next_count);
- EXPECT_EQ(1, backoff_->reset_count);
- EXPECT_EQ(0, report_observation_count_);
-}
-
-TEST_F(FirebaseAuthImplTest, GetFirebaseUserIdMaxRetry) {
- bool called;
- AuthStatus auth_status;
- token_manager_.SetError(fuchsia::auth::Status::NETWORK_ERROR);
- backoff_->SetOnGetNext(QuitLoopClosure());
- firebase_auth_.GetFirebaseUserId(callback::Capture(
- callback::SetWhenCalled(&called), &auth_status, &std::ignore));
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
- EXPECT_EQ(1, backoff_->get_next_count);
- EXPECT_EQ(0, backoff_->reset_count);
- EXPECT_EQ(0, report_observation_count_);
-
- // Exceeding the maximum number of retriable errors returns an error.
- token_manager_.SetError(fuchsia::auth::Status::INTERNAL_ERROR);
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(AuthStatus::ERROR, auth_status);
- EXPECT_EQ(1, backoff_->get_next_count);
- EXPECT_EQ(1, backoff_->reset_count);
- EXPECT_EQ(1, report_observation_count_);
-}
-
-TEST_F(FirebaseAuthImplTest, GetFirebaseUserIdNonRetriableError) {
- bool called;
- AuthStatus auth_status;
- token_manager_.SetError(fuchsia::auth::Status::INVALID_REQUEST);
- backoff_->SetOnGetNext(QuitLoopClosure());
- firebase_auth_.GetFirebaseUserId(callback::Capture(
- callback::SetWhenCalled(&called), &auth_status, &std::ignore));
- RunLoopUntilIdle();
- EXPECT_TRUE(called);
- EXPECT_EQ(AuthStatus::ERROR, auth_status);
- EXPECT_EQ(0, backoff_->get_next_count);
- EXPECT_EQ(1, backoff_->reset_count);
- EXPECT_EQ(1, report_observation_count_);
-}
-
-} // namespace
-
-} // namespace firebase_auth
diff --git a/lib/firebase_auth/testing/BUILD.gn b/lib/firebase_auth/testing/BUILD.gn
deleted file mode 100644
index b72396c..0000000
--- a/lib/firebase_auth/testing/BUILD.gn
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- "//peridot/bin/*",
- "//peridot/lib/*",
-]
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "fake_token_manager.cc",
- "fake_token_manager.h",
- "test_firebase_auth.cc",
- "test_firebase_auth.h",
- "test_token_manager.cc",
- "test_token_manager.h",
- ]
-
- public_deps = [
- "//garnet/public/fidl/fuchsia.auth",
- "//peridot/lib/firebase_auth",
- "//peridot/lib/rng",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/convert",
- ]
-
- configs += [ "//peridot/bin/ledger:ledger_config" ]
-}
-
-source_set("service_account_provider") {
- testonly = true
-
- sources = [
- "service_account_token_manager.cc",
- "service_account_token_manager.h",
- "service_account_token_minter.cc",
- "service_account_token_minter.h",
- ]
-
- public_deps = [
- ":service_account",
- "//garnet/public/fidl/fuchsia.auth",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/network_wrapper",
- ]
-
- deps = [
- ":json_schema",
- "//garnet/public/lib/fsl",
- "//peridot/lib/base64url",
- "//peridot/lib/convert",
- "//third_party/boringssl",
- "//third_party/rapidjson",
- ]
-}
-
-source_set("json_schema") {
- sources = [
- "json_schema.cc",
- "json_schema.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fsl",
- "//third_party/rapidjson",
- ]
-}
-
-source_set("service_account") {
- testonly = true
-
- sources = [
- "credentials.cc",
- "credentials.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//third_party/boringssl",
- "//third_party/rapidjson",
- ]
-
- deps = [
- ":json_schema",
- ]
-}
-
-source_set("service_account_test_constants") {
- testonly = true
-
- sources = [
- "service_account_test_constants.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "credentials_unittest.cc",
- "json_schema_unittest.cc",
- "service_account_test_util.cc",
- "service_account_test_util.h",
- "service_account_token_manager_unittest.cc",
- "service_account_token_minter_unittest.cc",
- ]
-
- deps = [
- ":json_schema",
- ":service_account",
- ":service_account_provider",
- ":service_account_test_constants",
- "//garnet/public/lib/gtest",
- "//garnet/public/lib/network_wrapper:fake",
- "//third_party/googletest:gtest",
- "//third_party/rapidjson",
- ]
-}
diff --git a/lib/firebase_auth/testing/credentials.cc b/lib/firebase_auth/testing/credentials.cc
deleted file mode 100644
index 0ebf1c1..0000000
--- a/lib/firebase_auth/testing/credentials.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/credentials.h"
-
-#include <rapidjson/document.h>
-#include <rapidjson/schema.h>
-
-#include "peridot/lib/firebase_auth/testing/json_schema.h"
-
-namespace service_account {
-
-namespace {
-constexpr fxl::StringView kServiceAccountConfigurationSchema = R"({
- "type": "object",
- "additionalProperties": true,
- "properties": {
- "project_id": {
- "type": "string"
- },
- "private_key": {
- "type": "string"
- },
- "client_email": {
- "type": "string"
- },
- "client_id": {
- "type": "string"
- }
- },
- "required": ["project_id", "private_key", "client_email", "client_id"]
-})";
-} // namespace
-
-Credentials::Credentials(std::string project_id, std::string client_email,
- std::string client_id,
- bssl::UniquePtr<EVP_PKEY> private_key)
- : project_id_(std::move(project_id)),
- client_email_(std::move(client_email)),
- client_id_(std::move(client_id)),
- private_key_(std::move(private_key)) {}
-
-std::unique_ptr<Credentials> Credentials::Parse(fxl::StringView json) {
- rapidjson::Document document;
- document.Parse(json.data(), json.size());
-
- if (document.HasParseError() || !document.IsObject()) {
- FXL_LOG(ERROR) << "Json file is incorrect: " << json;
- return nullptr;
- }
-
- return Parse(document);
-}
-
-std::unique_ptr<Credentials> Credentials::Parse(const rapidjson::Value& json) {
- static auto service_account_schema =
- json_schema::InitSchema(kServiceAccountConfigurationSchema);
-
- FXL_DCHECK(json.IsObject());
- if (!json_schema::ValidateSchema(json, *service_account_schema)) {
- return nullptr;
- }
-
- auto project_id = json["project_id"].GetString();
- auto client_email = json["client_email"].GetString();
- auto client_id = json["client_id"].GetString();
-
- bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(
- json["private_key"].GetString(), json["private_key"].GetStringLength()));
- bssl::UniquePtr<EVP_PKEY> private_key(
- PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
-
- if (EVP_PKEY_id(private_key.get()) != EVP_PKEY_RSA) {
- FXL_LOG(ERROR) << "Provided key is not a RSA key.";
- return nullptr;
- }
-
- return std::make_unique<Credentials>(
- std::move(project_id), std::move(client_email), std::move(client_id),
- std::move(private_key));
-}
-
-std::unique_ptr<Credentials> Credentials::Clone() {
- if (!EVP_PKEY_up_ref(private_key_.get())) {
- FXL_LOG(ERROR) << "Unable to increment the private key ref count.";
- return nullptr;
- }
- bssl::UniquePtr<EVP_PKEY> private_key(private_key_.get());
- return std::make_unique<Credentials>(project_id_, client_email_, client_id_,
- std::move(private_key));
-}
-
-} // namespace service_account
diff --git a/lib/firebase_auth/testing/credentials.h b/lib/firebase_auth/testing/credentials.h
deleted file mode 100644
index 9f5c5ec..0000000
--- a/lib/firebase_auth/testing/credentials.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_CREDENTIALS_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_CREDENTIALS_H_
-
-#include <string>
-
-#include <lib/fxl/strings/string_view.h>
-#include <openssl/pem.h>
-#include <rapidjson/document.h>
-
-namespace service_account {
-
-// Credentials to access a Google cloud service.
-//
-// A Firebase service account with admin access to the project is automatically
-// created for every Firebase project.
-//
-// In order to download the JSON credential file corresponding to this account,
-// visit `Settings > Service accounts > Firebase admin SDK` in the Firebase
-// Console and click on the 'Generate new private key' button. The content of
-// this JSON file must be pass to the |Parse| method of this class.
-class Credentials {
- public:
- Credentials(std::string project_id, std::string client_email,
- std::string client_id, bssl::UniquePtr<EVP_PKEY> private_key);
-
- const std::string& project_id() { return project_id_; }
- const std::string& client_email() { return client_email_; }
- const std::string& client_id() { return client_id_; }
- const bssl::UniquePtr<EVP_PKEY>& private_key() { return private_key_; }
-
- // Clone the current credentials.
- std::unique_ptr<Credentials> Clone();
-
- // Loads the service account credentials.
- //
- // This method must be called before this class is usable. |json| must be the
- // content of the service account configuration file that can be retrieved
- // from the firebase admin console (see the class-level comment).
- //
- // These methods will return an empty unique_ptr if the json content is
- // invalid.
- static std::unique_ptr<Credentials> Parse(fxl::StringView json);
- static std::unique_ptr<Credentials> Parse(const rapidjson::Value& json);
-
- private:
- std::string project_id_;
- std::string client_email_;
- std::string client_id_;
- bssl::UniquePtr<EVP_PKEY> private_key_;
-};
-
-} // namespace service_account
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_TESTING_CREDENTIALS_H_
diff --git a/lib/firebase_auth/testing/credentials_unittest.cc b/lib/firebase_auth/testing/credentials_unittest.cc
deleted file mode 100644
index c17a9f5..0000000
--- a/lib/firebase_auth/testing/credentials_unittest.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/credentials.h"
-
-#include "gtest/gtest.h"
-#include "peridot/lib/firebase_auth/testing/service_account_test_constants.h"
-
-namespace service_account {
-namespace {
-
-TEST(CredentialsTest, CorrectConfig) {
- auto config = Credentials::Parse(kTestServiceAccountConfig);
- EXPECT_TRUE(config);
-
- EXPECT_EQ(kTestServiceAccountProjectId, config->project_id());
- EXPECT_EQ(kTestServiceAccountClientEmail, config->client_email());
- EXPECT_EQ(kTestServiceAccountClientId, config->client_id());
-}
-
-TEST(CredentialsTest, IncorrectConfig) {
- EXPECT_FALSE(Credentials::Parse(""));
- EXPECT_FALSE(Credentials::Parse("{}"));
- EXPECT_FALSE(Credentials::Parse(kWrongKeyTestServiceAccountConfig));
-}
-
-TEST(CredentialsTest, Clone) {
- auto config = Credentials::Parse(kTestServiceAccountConfig);
- ASSERT_TRUE(config);
-
- auto cloned_config = config->Clone();
- EXPECT_EQ(config->project_id(), cloned_config->project_id());
- EXPECT_EQ(config->client_email(), cloned_config->client_email());
- EXPECT_EQ(config->client_id(), cloned_config->client_id());
-
- EXPECT_EQ(1, EVP_PKEY_cmp(config->private_key().get(),
- cloned_config->private_key().get()));
-}
-
-} // namespace
-} // namespace service_account
diff --git a/lib/firebase_auth/testing/fake_token_manager.cc b/lib/firebase_auth/testing/fake_token_manager.cc
deleted file mode 100644
index 19666b9..0000000
--- a/lib/firebase_auth/testing/fake_token_manager.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/fake_token_manager.h"
-
-#include <lib/fxl/logging.h>
-
-#include "peridot/lib/convert/convert.h"
-
-namespace firebase_auth {
-
-FakeTokenManager::FakeTokenManager(rng::Random* random)
- : firebase_id_token_(""),
- firebase_local_id_(convert::ToHex(random->RandomUniqueBytes())),
- email_("dummy@example.com") {}
-
-void FakeTokenManager::Authorize(
- AppConfig app_config,
- fidl::InterfaceHandle<AuthenticationUIContext> auth_ui_context,
- std::vector<std::string> /*app_scopes*/,
- fidl::StringPtr /*user_profile_id*/, fidl::StringPtr /*auth_code*/,
- AuthorizeCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED() << "FakeTokenManager::Authorize not implemented";
- callback(fuchsia::auth::Status::INTERNAL_ERROR, nullptr);
-}
-
-void FakeTokenManager::GetAccessToken(
- AppConfig app_config, std::string /*user_profile_id*/,
- std::vector<std::string> /*app_scopes*/,
- GetAccessTokenCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED() << "FakeTokenManager::GetAccessToken not implemented";
- callback(fuchsia::auth::Status::INTERNAL_ERROR, nullptr);
-}
-
-void FakeTokenManager::GetIdToken(AppConfig app_config,
- std::string /*user_profile_id*/,
- fidl::StringPtr /*audience*/,
- GetIdTokenCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED() << "FakeTokenManager::GetIdToken not implemented";
- callback(fuchsia::auth::Status::INTERNAL_ERROR, {});
-}
-
-void FakeTokenManager::GetFirebaseToken(AppConfig /*app_config*/,
- std::string /*user_profile_id*/,
- std::string /*audience*/,
- std::string /*firebase_api_key*/,
- GetFirebaseTokenCallback callback) {
- if (firebase_local_id_.empty()) {
- callback(fuchsia::auth::Status::OK, nullptr);
- return;
- }
- fuchsia::auth::FirebaseTokenPtr token = fuchsia::auth::FirebaseToken::New();
- token->id_token = firebase_id_token_;
- token->local_id = firebase_local_id_;
- token->email = email_;
- callback(fuchsia::auth::Status::OK, std::move(token));
-}
-
-void FakeTokenManager::DeleteAllTokens(AppConfig /*app_config*/,
- std::string /*user_profile_id*/,
- DeleteAllTokensCallback callback) {
- FXL_NOTIMPLEMENTED() << "FakeTokenManager::DeleteAllTokens not implemented";
- callback(fuchsia::auth::Status::INTERNAL_ERROR);
-}
-
-void FakeTokenManager::ListProfileIds(AppConfig app_config,
- ListProfileIdsCallback callback) {
- FXL_NOTIMPLEMENTED() << "FakeTokenManager::ListProifleIds not implemented";
- callback(fuchsia::auth::Status::INTERNAL_ERROR, {});
-}
-
-} // namespace firebase_auth
diff --git a/lib/firebase_auth/testing/fake_token_manager.h b/lib/firebase_auth/testing/fake_token_manager.h
deleted file mode 100644
index 01394a0..0000000
--- a/lib/firebase_auth/testing/fake_token_manager.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_FAKE_TOKEN_MANAGER_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_FAKE_TOKEN_MANAGER_H_
-
-#include <functional>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/rng/random.h"
-
-namespace firebase_auth {
-
-using fuchsia::auth::AppConfig;
-using fuchsia::auth::AuthenticationUIContext;
-
-// FakeTokenManager is a dummy implementation of a TokenManager intended to be
-// used to connect to unauthenticated firebase instances.
-//
-// The local ID Firebase token are set to a random UUID fixed at the
-// construction time.
-//
-// Other token values are set to dummy const values.
-class FakeTokenManager : public fuchsia::auth::TokenManager {
- public:
- FakeTokenManager(rng::Random* random);
- ~FakeTokenManager() override {}
-
- private:
- // fuchsia::auth::TokenManager:
- void Authorize(AppConfig app_config,
- fidl::InterfaceHandle<AuthenticationUIContext> auth_ui_context,
- std::vector<std::string> app_scopes,
- fidl::StringPtr user_profile_id, fidl::StringPtr auth_code,
- AuthorizeCallback callback) override;
-
- void GetAccessToken(AppConfig app_config, std::string user_profile_id,
- std::vector<std::string> app_scopes,
- GetAccessTokenCallback callback) override;
-
- void GetIdToken(AppConfig app_config, std::string user_profile_id,
- fidl::StringPtr audience,
- GetIdTokenCallback callback) override;
-
- void GetFirebaseToken(AppConfig app_config, std::string user_profile_id,
- std::string audience,
- std::string firebase_api_key,
- GetFirebaseTokenCallback callback) override;
-
- void DeleteAllTokens(AppConfig app_config, std::string user_profile_id,
- DeleteAllTokensCallback callback) override;
-
- void ListProfileIds(AppConfig app_config,
- ListProfileIdsCallback callback) override;
-
- // Sets the token to return to null, and status to |status|.
- std::string firebase_id_token_;
- std::string firebase_local_id_;
- std::string email_;
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeTokenManager);
-};
-
-} // namespace firebase_auth
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_TESTING_FAKE_TOKEN_MANAGER_H_
diff --git a/lib/firebase_auth/testing/json_schema.cc b/lib/firebase_auth/testing/json_schema.cc
deleted file mode 100644
index a2d387e..0000000
--- a/lib/firebase_auth/testing/json_schema.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/json_schema.h"
-
-#include <lib/fxl/logging.h>
-
-namespace json_schema {
-
-std::unique_ptr<rapidjson::SchemaDocument> InitSchema(fxl::StringView json) {
- rapidjson::Document schema_document;
- if (schema_document.Parse(json.data(), json.size()).HasParseError()) {
- FXL_LOG(ERROR) << "Schema validation spec itself is not valid JSON.";
- return nullptr;
- }
- auto schema = std::make_unique<rapidjson::SchemaDocument>(schema_document);
- rapidjson::SchemaValidator validator(*schema);
- if (!validator.IsValid()) {
- FXL_LOG(ERROR) << "Schema validation spec itself is not a valid schema.";
- return nullptr;
- }
- return schema;
-}
-
-bool ValidateSchema(const rapidjson::Value& value,
- const rapidjson::SchemaDocument& schema) {
- rapidjson::SchemaValidator validator(schema);
- if (!value.Accept(validator)) {
- rapidjson::StringBuffer uri_buffer;
- validator.GetInvalidSchemaPointer().StringifyUriFragment(uri_buffer);
- FXL_LOG(ERROR) << "Incorrect schema at " << uri_buffer.GetString()
- << " , schema violation: "
- << validator.GetInvalidSchemaKeyword();
- return false;
- }
- return true;
-}
-
-} // namespace json_schema
diff --git a/lib/firebase_auth/testing/json_schema.h b/lib/firebase_auth/testing/json_schema.h
deleted file mode 100644
index 1bdb1c3..0000000
--- a/lib/firebase_auth/testing/json_schema.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_JSON_SCHEMA_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_JSON_SCHEMA_H_
-
-#include <memory>
-
-#include <lib/fxl/strings/string_view.h>
-#include <rapidjson/document.h>
-#include <rapidjson/schema.h>
-
-namespace json_schema {
-
-// Build a SchemaDocument from a json encoded string.
-std::unique_ptr<rapidjson::SchemaDocument> InitSchema(fxl::StringView json);
-
-// Validate that the given json value match the given schema.
-bool ValidateSchema(const rapidjson::Value& value,
- const rapidjson::SchemaDocument& schema);
-
-}; // namespace json_schema
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_TESTING_JSON_SCHEMA_H_
diff --git a/lib/firebase_auth/testing/json_schema_unittest.cc b/lib/firebase_auth/testing/json_schema_unittest.cc
deleted file mode 100644
index 3b6d591..0000000
--- a/lib/firebase_auth/testing/json_schema_unittest.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/json_schema.h"
-
-#include "gtest/gtest.h"
-
-namespace json_schema {
-namespace {
-
-constexpr fxl::StringView kInvalidSchema = "Hello";
-
-constexpr fxl::StringView kValidSchema = R"({
- "type": "object",
- "additionalProperties": true,
- "properties": {
- "foo": {
- "type": "string"
- }
- },
- "required": ["foo"]
-})";
-
-constexpr fxl::StringView kInvalidJson = R"({
- "hello": "world"
-})";
-
-constexpr fxl::StringView kValidJson = R"({
- "foo": "bar",
- "hello": "world"
-})";
-
-bool ParseJson(fxl::StringView json, rapidjson::Document* document) {
- document->Parse(json.data(), json.size());
- return !document->HasParseError();
-}
-
-TEST(JsonSchemaTest, InvalidSchema) {
- EXPECT_FALSE(InitSchema(kInvalidSchema));
-}
-
-TEST(JsonSchemaTest, ValidSchema) { EXPECT_TRUE(InitSchema(kValidSchema)); }
-
-TEST(JsonSchemaTest, ValidJson) {
- auto schema = InitSchema(kValidSchema);
- ASSERT_TRUE(schema);
-
- rapidjson::Document document;
- ASSERT_TRUE(ParseJson(kValidJson, &document));
-
- EXPECT_TRUE(ValidateSchema(document, *schema));
-}
-
-TEST(JsonSchemaTest, InvalidJson) {
- auto schema = InitSchema(kValidSchema);
- ASSERT_TRUE(schema);
-
- rapidjson::Document document;
- ASSERT_TRUE(ParseJson(kInvalidJson, &document));
-
- EXPECT_FALSE(ValidateSchema(document, *schema));
-}
-
-} // namespace
-} // namespace json_schema
diff --git a/lib/firebase_auth/testing/service_account_test_constants.h b/lib/firebase_auth/testing/service_account_test_constants.h
deleted file mode 100644
index 1b57d68..0000000
--- a/lib/firebase_auth/testing/service_account_test_constants.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TEST_CONSTANTS_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TEST_CONSTANTS_H_
-
-#include <lib/fxl/strings/string_view.h>
-
-// This file contains constant strings used to test code that needs a
-// Credentials.
-namespace service_account {
-
-// Expected value for the Credentials members.
-constexpr fxl::StringView kTestServiceAccountProjectId = "fake_project_id";
-constexpr fxl::StringView kTestServiceAccountClientEmail =
- "fake_email@example.com";
-constexpr fxl::StringView kTestServiceAccountClientId = "fake_client_id";
-
-// Correct test json configuration file for Credentials.
-constexpr fxl::StringView kTestServiceAccountConfig =
- "{"
- "\"project_id\": \"fake_project_id\","
- "\"private_key\": \""
- "-----BEGIN RSA PRIVATE KEY-----\\n"
- "MIIBOQIBAAJBALTlyNACX5j/oFWdgy/KvAZL9qj+eNuhXGBSvQM9noaPKqVhOXFH\\n"
- "hycW+TBzlHzj4Ga5uGtVJNzZaxdpfbqxV1cCAwEAAQJAZDJShESMRuZwHHveSf51\\n"
- "Hte8i+ZHcv9xdzjc0Iq037pGGmHh/TiNNZPtqgVbxQuGGdGQqJ54DMpz3Ja2ck1V\\n"
- "wQIhAOMyXwq0Se8+hCXFFFIo6QSVpDn5ZnXTyz+GBdiwkVXZAiEAy9TIRCCUd9j+\\n"
- "cy77lTCx6k6Pw5lY1LM5jTUR7dAD6K8CIBie1snUK8bvYWauartUj5vdk4Rs0Huo\\n"
- "Tfg+T9fhmn5RAiB5nfEL7SCIzbksgqjroE1Xjx5qR5Hf/zvki/ixmz7p0wIgdxLS\\n"
- "T/hN67jcu9a+/2geGTnk1ku2nhVlxS7UPCTq0os=\\n"
- "-----END RSA PRIVATE KEY-----"
- "\","
- "\"client_email\": \"fake_email@example.com\","
- "\"client_id\": \"fake_client_id\""
- "}";
-
-// Incorrect test json configuration file.
-constexpr fxl::StringView kWrongKeyTestServiceAccountConfig =
- "{"
- "\"project_id\": \"fake_project_id\","
- "\"private_key\": \""
- "-----BEGIN DSA PRIVATE KEY-----\\n"
- "MIH4AgEAAkEAteW2IBzioOu0aNGrQFv5RZ6VxS8NAyuNwvOrmjq8pxJSzTyrwD52\\n"
- "9XJmNVVXv/UWKvyPtr0rzrsJVpSzCEwaewIVAJT9/8i3lQrQEeACuO9bwzaG28Lh\\n"
- "AkAnvmU9Ogz6eTof5V58Lv1f8uKF6ZujgVb+Wc1gudx8wKIexKUBhE7rsnJUfLYw\\n"
- "HMXC8xZ5XJTEYog2U0vLKke7AkEApEq8XBO8qwEzP3VicpC/Huxa/zNZ2lveNgWm\\n"
- "tr089fvp3PSf4DwKTOKGZyg9NYsOSCfaCSvkWMeFCW4Y7XTpTAIUV9YTY3SlInIv\\n"
- "Ho2twE3HuzNZpLQ=\\n"
- "-----END DSA PRIVATE KEY-----\\n"
- "\","
- "\"client_email\": \"fake_email@example.com\","
- "\"client_id\": \"fake_id\""
- "}";
-
-} // namespace service_account
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TEST_CONSTANTS_H_
diff --git a/lib/firebase_auth/testing/service_account_test_util.cc b/lib/firebase_auth/testing/service_account_test_util.cc
deleted file mode 100644
index 5ef89e9..0000000
--- a/lib/firebase_auth/testing/service_account_test_util.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include <lib/network_wrapper/fake_network_wrapper.h>
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
-
-namespace service_account {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-std::string GetSuccessResponseBodyForTest(std::string token,
- size_t expiration) {
- rapidjson::StringBuffer string_buffer;
- rapidjson::Writer<rapidjson::StringBuffer> writer(string_buffer);
-
- writer.StartObject();
-
- writer.Key("idToken");
- writer.String(token);
-
- writer.Key("expiresIn");
- writer.String(fxl::NumberToString(expiration));
-
- writer.EndObject();
-
- return std::string(string_buffer.GetString(), string_buffer.GetSize());
-}
-
-http::URLResponse GetResponseForTest(http::HttpErrorPtr error, uint32_t status,
- std::string body) {
- http::URLResponse response;
- response.error = std::move(error);
- response.status_code = status;
- fsl::SizedVmo buffer;
- if (!fsl::VmoFromString(body, &buffer)) {
- ADD_FAILURE() << "Unable to convert string to Vmo.";
- }
- response.body = http::URLBody::New();
- response.body->set_buffer(std::move(buffer).ToTransport());
- return response;
-}
-
-} // namespace service_account
diff --git a/lib/firebase_auth/testing/service_account_test_util.h b/lib/firebase_auth/testing/service_account_test_util.h
deleted file mode 100644
index a873cca..0000000
--- a/lib/firebase_auth/testing/service_account_test_util.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/network_wrapper/fake_network_wrapper.h>
-
-namespace service_account {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-std::string GetSuccessResponseBodyForTest(std::string token, size_t expiration);
-
-http::URLResponse GetResponseForTest(http::HttpErrorPtr error, uint32_t status,
- std::string body);
-
-} // namespace service_account
diff --git a/lib/firebase_auth/testing/service_account_token_manager.cc b/lib/firebase_auth/testing/service_account_token_manager.cc
deleted file mode 100644
index 425c6af..0000000
--- a/lib/firebase_auth/testing/service_account_token_manager.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/service_account_token_manager.h"
-
-#include <lib/fxl/logging.h>
-
-namespace service_account {
-namespace {
-
-fuchsia::auth::Status ConvertStatus(ServiceAccountTokenMinter::Status status) {
- switch (status) {
- case ServiceAccountTokenMinter::Status::OK:
- return fuchsia::auth::Status::OK;
- case ServiceAccountTokenMinter::Status::AUTH_SERVER_ERROR:
- return fuchsia::auth::Status::AUTH_PROVIDER_SERVER_ERROR;
- case ServiceAccountTokenMinter::Status::BAD_RESPONSE:
- return fuchsia::auth::Status::AUTH_PROVIDER_SERVER_ERROR;
- case ServiceAccountTokenMinter::Status::NETWORK_ERROR:
- return fuchsia::auth::Status::NETWORK_ERROR;
- case ServiceAccountTokenMinter::Status::INTERNAL_ERROR:
- default:
- return fuchsia::auth::Status::INTERNAL_ERROR;
- }
-}
-
-} // namespace
-
-ServiceAccountTokenManager::ServiceAccountTokenManager(
- network_wrapper::NetworkWrapper* network_wrapper,
- std::unique_ptr<Credentials> credentials, std::string user_id)
- : service_account_token_minter_(network_wrapper, std::move(credentials),
- std::move(user_id)) {}
-
-ServiceAccountTokenManager::~ServiceAccountTokenManager() {}
-
-void ServiceAccountTokenManager::Authorize(
- AppConfig app_config,
- fidl::InterfaceHandle<AuthenticationUIContext> auth_ui_context,
- std::vector<std::string> /*app_scopes*/,
- fidl::StringPtr /*user_profile_id*/, fidl::StringPtr /*auth_code*/,
- AuthorizeCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED();
- callback(fuchsia::auth::Status::INTERNAL_ERROR /*Not implemented*/, nullptr);
-}
-
-void ServiceAccountTokenManager::GetAccessToken(
- AppConfig app_config, std::string /*user_profile_id*/,
- std::vector<std::string> /*app_scopes*/,
- GetAccessTokenCallback callback) {
- FXL_NOTIMPLEMENTED();
- callback(fuchsia::auth::Status::INTERNAL_ERROR /*Not implemented*/, nullptr);
-}
-
-void ServiceAccountTokenManager::GetIdToken(
- AppConfig app_config, std::string /*user_profile_id*/,
- fidl::StringPtr /*audience*/, GetIdTokenCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED();
- callback(fuchsia::auth::Status::INTERNAL_ERROR /*Not implemented*/, nullptr);
-}
-
-void ServiceAccountTokenManager::GetFirebaseToken(
- AppConfig /*app_config*/, std::string /*user_profile_id*/,
- std::string /*audience*/, std::string firebase_api_key,
- GetFirebaseTokenCallback callback) {
- service_account_token_minter_.GetFirebaseToken(
- std::move(firebase_api_key),
- [this, callback = std::move(callback)](
- const ServiceAccountTokenMinter::GetTokenResponse& response) {
- auto status = ConvertStatus(response.status);
-
- if (response.status == ServiceAccountTokenMinter::Status::OK) {
- auto fb_token = fuchsia::auth::FirebaseToken::New();
- fb_token->id_token = response.id_token;
- fb_token->local_id = response.local_id;
- fb_token->email = response.email;
- callback(status, std::move(fb_token));
- } else {
- FXL_LOG(ERROR) << "Encountered error in GetToken(): "
- << response.error_msg;
- callback(status, nullptr);
- }
- });
-}
-
-void ServiceAccountTokenManager::DeleteAllTokens(
- AppConfig app_config, std::string /*user_profile_id*/,
- DeleteAllTokensCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED();
- callback(fuchsia::auth::Status::INTERNAL_ERROR /*Not implemented*/);
-}
-
-void ServiceAccountTokenManager::ListProfileIds(
- AppConfig app_config, ListProfileIdsCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED();
- callback(fuchsia::auth::Status::INTERNAL_ERROR /*Not implemented*/, {});
-}
-
-} // namespace service_account
diff --git a/lib/firebase_auth/testing/service_account_token_manager.h b/lib/firebase_auth/testing/service_account_token_manager.h
deleted file mode 100644
index 1d7fcfc..0000000
--- a/lib/firebase_auth/testing/service_account_token_manager.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TOKEN_MANAGER_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TOKEN_MANAGER_H_
-
-#include <map>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/firebase_auth/testing/service_account_token_minter.h"
-
-namespace service_account {
-
-using fuchsia::auth::AppConfig;
-using fuchsia::auth::AuthenticationUIContext;
-
-// An implementation of |TokenManager| that uses a Firebase service account to
-// register a new user of the given id and mint tokens for it.
-//
-// A Firebase service account with admin access to the project is automatically
-// created for every Firebase project.
-//
-// In order to download the JSON credential file corresponding to this account,
-// visit `Settings > Service accounts > Firebase admin SDK` in the Firebase
-// Console and click on the 'Generate new private key' button. This JSON file
-// must be available on the device, and its path must be passed to the
-// LoadCredentials() method to initialize this class.
-class ServiceAccountTokenManager : public fuchsia::auth::TokenManager {
- public:
- ServiceAccountTokenManager(network_wrapper::NetworkWrapper* network_wrapper,
- std::unique_ptr<Credentials> credentials,
- std::string user_id);
- ~ServiceAccountTokenManager() override;
-
- // fuchsia::auth::TokenManager:
- void Authorize(AppConfig app_config,
- fidl::InterfaceHandle<AuthenticationUIContext> auth_ui_context,
- std::vector<std::string> app_scopes,
- fidl::StringPtr user_profile_id, fidl::StringPtr auth_code,
- AuthorizeCallback callback) override;
-
- void GetAccessToken(AppConfig app_config, std::string user_profile_id,
- std::vector<std::string> app_scopes,
- GetAccessTokenCallback callback) override;
-
- void GetIdToken(AppConfig app_config, std::string user_profile_id,
- fidl::StringPtr audience,
- GetIdTokenCallback callback) override;
-
- void GetFirebaseToken(AppConfig app_config, std::string user_profile_id,
- std::string audience,
- std::string firebase_api_key,
- GetFirebaseTokenCallback callback) override;
-
- void DeleteAllTokens(AppConfig app_config, std::string user_profile_id,
- DeleteAllTokensCallback callback) override;
-
- void ListProfileIds(AppConfig app_config,
- ListProfileIdsCallback callback) override;
-
- private:
- ServiceAccountTokenMinter service_account_token_minter_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ServiceAccountTokenManager);
-};
-
-}; // namespace service_account
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TOKEN_MANAGER_H_
diff --git a/lib/firebase_auth/testing/service_account_token_manager_unittest.cc b/lib/firebase_auth/testing/service_account_token_manager_unittest.cc
deleted file mode 100644
index 0cd4037..0000000
--- a/lib/firebase_auth/testing/service_account_token_manager_unittest.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/service_account_token_manager.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include <lib/network_wrapper/fake_network_wrapper.h>
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
-
-#include "peridot/lib/firebase_auth/testing/service_account_test_constants.h"
-#include "peridot/lib/firebase_auth/testing/service_account_test_util.h"
-
-namespace service_account {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-namespace {
-
-class ServiceAccountTokenManagerTest : public gtest::TestLoopFixture {
- public:
- ServiceAccountTokenManagerTest()
- : network_wrapper_(dispatcher()),
- token_manager_(&network_wrapper_,
- Credentials::Parse(kTestServiceAccountConfig),
- "user_id") {}
-
- protected:
- bool GetToken(std::string api_key, fuchsia::auth::FirebaseTokenPtr* token,
- fuchsia::auth::Status* status) {
- bool called;
- token_manager_.GetFirebaseToken(
- {"google", "", ""}, /*app_config*/
- "", /*user_profile_id*/
- "", /*audience*/
- api_key,
- callback::Capture(callback::SetWhenCalled(&called), status, token));
- RunLoopUntilIdle();
- return called;
- }
-
- network_wrapper::FakeNetworkWrapper network_wrapper_;
- ServiceAccountTokenManager token_manager_;
-};
-
-TEST_F(ServiceAccountTokenManagerTest, GetToken) {
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token", 3600)));
-
- fuchsia::auth::FirebaseTokenPtr token;
- fuchsia::auth::Status status;
- ASSERT_TRUE(GetToken("api_key", &token, &status));
- ASSERT_EQ(fuchsia::auth::Status::OK, status);
- ASSERT_EQ("token", token->id_token);
-}
-
-TEST_F(ServiceAccountTokenManagerTest, GetTokenFromCache) {
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token", 3600)));
-
- fuchsia::auth::FirebaseTokenPtr token;
- fuchsia::auth::Status status;
-
- ASSERT_TRUE(GetToken("api_key", &token, &status));
- EXPECT_EQ(fuchsia::auth::Status::OK, status);
- EXPECT_EQ("token", token->id_token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-
- network_wrapper_.ResetRequest();
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token2", 3600)));
-
- ASSERT_TRUE(GetToken("api_key", &token, &status));
- EXPECT_EQ(fuchsia::auth::Status::OK, status);
- EXPECT_EQ("token", token->id_token);
- EXPECT_FALSE(network_wrapper_.GetRequest());
-}
-
-TEST_F(ServiceAccountTokenManagerTest, GetTokenNoCacheCache) {
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token", 0)));
-
- fuchsia::auth::FirebaseTokenPtr token;
- fuchsia::auth::Status status;
-
- ASSERT_TRUE(GetToken("api_key", &token, &status));
- EXPECT_EQ(fuchsia::auth::Status::OK, status);
- EXPECT_EQ("token", token->id_token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token2", 0)));
-
- ASSERT_TRUE(GetToken("api_key", &token, &status));
- EXPECT_EQ(fuchsia::auth::Status::OK, status);
- EXPECT_EQ("token2", token->id_token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-}
-
-TEST_F(ServiceAccountTokenManagerTest, NetworkError) {
- auto network_status = http::HttpError::New();
- network_status->description = "Error";
-
- network_wrapper_.SetResponse(
- GetResponseForTest(std::move(network_status), 0, ""));
-
- fuchsia::auth::FirebaseTokenPtr token;
- fuchsia::auth::Status status;
-
- ASSERT_TRUE(GetToken("api_key", &token, &status));
- EXPECT_EQ(fuchsia::auth::Status::NETWORK_ERROR, status);
- EXPECT_FALSE(token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-}
-
-TEST_F(ServiceAccountTokenManagerTest, AuthenticationError) {
- network_wrapper_.SetResponse(
- GetResponseForTest(nullptr, 401, "Unauthorized"));
-
- fuchsia::auth::FirebaseTokenPtr token;
- fuchsia::auth::Status status;
-
- ASSERT_TRUE(GetToken("api_key", &token, &status));
- EXPECT_EQ(fuchsia::auth::Status::AUTH_PROVIDER_SERVER_ERROR, status);
- EXPECT_FALSE(token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-}
-
-TEST_F(ServiceAccountTokenManagerTest, ResponseFormatError) {
- network_wrapper_.SetResponse(GetResponseForTest(nullptr, 200, ""));
-
- fuchsia::auth::FirebaseTokenPtr token;
- fuchsia::auth::Status status;
-
- ASSERT_TRUE(GetToken("api_key", &token, &status));
- EXPECT_EQ(fuchsia::auth::Status::AUTH_PROVIDER_SERVER_ERROR, status);
- EXPECT_FALSE(token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-}
-
-} // namespace
-} // namespace service_account
diff --git a/lib/firebase_auth/testing/service_account_token_minter.cc b/lib/firebase_auth/testing/service_account_token_minter.cc
deleted file mode 100644
index 6186693..0000000
--- a/lib/firebase_auth/testing/service_account_token_minter.cc
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/service_account_token_minter.h"
-
-#include <time.h>
-
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/arraysize.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/fxl/strings/string_view.h>
-#include <openssl/bio.h>
-#include <openssl/digest.h>
-#include <openssl/hmac.h>
-#include <openssl/pem.h>
-#include <rapidjson/document.h>
-#include <rapidjson/schema.h>
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
-
-#include "peridot/lib/base64url/base64url.h"
-#include "peridot/lib/convert/convert.h"
-#include "peridot/lib/firebase_auth/testing/json_schema.h"
-
-namespace service_account {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-namespace {
-constexpr fxl::StringView kIdentityResponseSchema = R"({
- "type": "object",
- "additionalProperties": true,
- "properties": {
- "idToken": {
- "type": "string"
- },
- "expiresIn": {
- "type": "string"
- }
- },
- "required": ["idToken", "expiresIn"]
-})";
-
-rapidjson::SchemaDocument& GetResponseSchema() {
- static auto schema = json_schema::InitSchema(kIdentityResponseSchema);
- FXL_DCHECK(schema);
- return *schema;
-}
-
-std::string GetHeader() {
- rapidjson::StringBuffer string_buffer;
- rapidjson::Writer<rapidjson::StringBuffer> writer(string_buffer);
-
- writer.StartObject();
-
- writer.Key("typ");
- writer.String("JWT");
-
- writer.Key("alg");
- writer.String("RS256");
-
- writer.EndObject();
-
- return base64url::Base64UrlEncode(
- fxl::StringView(string_buffer.GetString(), string_buffer.GetSize()));
-}
-
-} // namespace
-
-struct ServiceAccountTokenMinter::CachedToken {
- std::string id_token;
- // TODO: Use zx::time for expiration_time.
- time_t expiration_time;
-};
-
-ServiceAccountTokenMinter::GetTokenResponse
-ServiceAccountTokenMinter::GetErrorResponse(Status status,
- const std::string& error_msg) {
- GetTokenResponse response = {status, /* response status */
- "", /* id_token */
- "", /* local_id */
- "", /* email */
- error_msg /* detailed error msg */};
- return response;
-}
-
-ServiceAccountTokenMinter::GetTokenResponse
-ServiceAccountTokenMinter::GetSuccessResponse(const std::string& id_token) {
- GetTokenResponse response = {Status::OK, /* success status */
- id_token, /* token */
- user_id_, /* local_id */
- user_id_ + "@example.com", /* email */
- "OK" /* success msg */};
- return response;
-}
-
-ServiceAccountTokenMinter::ServiceAccountTokenMinter(
- network_wrapper::NetworkWrapper* network_wrapper,
- std::unique_ptr<Credentials> credentials, std::string user_id)
- : network_wrapper_(network_wrapper),
- credentials_(std::move(credentials)),
- user_id_(std::move(user_id)) {}
-
-ServiceAccountTokenMinter::~ServiceAccountTokenMinter() {
- for (const auto& pair : in_progress_callbacks_) {
- ResolveCallbacks(
- pair.first,
- GetErrorResponse(Status::INTERNAL_ERROR,
- "Account provider deleted with requests in flight."));
- }
-}
-
-void ServiceAccountTokenMinter::GetFirebaseToken(
- fidl::StringPtr firebase_api_key, GetFirebaseTokenCallback callback) {
- // A request is in progress to get a token. Registers the callback that will
- // be called when the request ends.
- if (!in_progress_callbacks_[firebase_api_key].empty()) {
- in_progress_callbacks_[firebase_api_key].push_back(std::move(callback));
- return;
- }
-
- // Check if a token is currently cached.
- if (cached_tokens_[firebase_api_key]) {
- auto& cached_token = cached_tokens_[firebase_api_key];
- if (time(nullptr) < cached_token->expiration_time) {
- callback(GetSuccessResponse(cached_token->id_token));
- return;
- }
-
- // The token expired. Falls back to fetch a new one.
- cached_tokens_.erase(firebase_api_key);
- }
-
- // Build the custom token to exchange for an id token.
- std::string custom_token;
- if (!GetCustomToken(&custom_token)) {
- callback(
- GetErrorResponse(Status::INTERNAL_ERROR,
- "Unable to compute custom authentication token."));
- return;
- }
-
- in_progress_callbacks_[firebase_api_key].push_back(std::move(callback));
-
- in_progress_requests_.emplace(network_wrapper_->Request(
- [this, firebase_api_key = firebase_api_key.get(),
- custom_token = std::move(custom_token)] {
- return GetIdentityRequest(firebase_api_key, custom_token);
- },
- [this,
- firebase_api_key = firebase_api_key.get()](http::URLResponse response) {
- HandleIdentityResponse(firebase_api_key, std::move(response));
- }));
-}
-
-std::string ServiceAccountTokenMinter::GetClientId() {
- return credentials_->client_id();
-}
-
-std::string ServiceAccountTokenMinter::GetClaims() {
- rapidjson::StringBuffer string_buffer;
- rapidjson::Writer<rapidjson::StringBuffer> writer(string_buffer);
-
- writer.StartObject();
-
- writer.Key("iss");
- writer.String(credentials_->client_email());
-
- writer.Key("sub");
- writer.String(credentials_->client_email());
-
- writer.Key("aud");
- writer.String(
- "https://identitytoolkit.googleapis.com/"
- "google.identity.identitytoolkit.v1.IdentityToolkit");
-
- time_t current_time = time(nullptr);
- writer.Key("iat");
- writer.Int(current_time);
-
- writer.Key("exp");
- writer.Int(current_time + 3600);
-
- writer.Key("uid");
- writer.String(user_id_);
-
- writer.EndObject();
-
- return base64url::Base64UrlEncode(
- fxl::StringView(string_buffer.GetString(), string_buffer.GetSize()));
-}
-
-bool ServiceAccountTokenMinter::GetCustomToken(std::string* custom_token) {
- std::string message = GetHeader() + "." + GetClaims();
-
- bssl::ScopedEVP_MD_CTX md_ctx;
- if (EVP_DigestSignInit(md_ctx.get(), nullptr, EVP_sha256(), nullptr,
- credentials_->private_key().get()) != 1) {
- FXL_LOG(ERROR) << ERR_reason_error_string(ERR_get_error());
- return false;
- }
-
- if (EVP_DigestSignUpdate(md_ctx.get(), message.c_str(), message.size()) !=
- 1) {
- FXL_LOG(ERROR) << ERR_reason_error_string(ERR_get_error());
- return false;
- }
-
- size_t result_length;
- if (EVP_DigestSignFinal(md_ctx.get(), nullptr, &result_length) != 1) {
- FXL_LOG(ERROR) << ERR_reason_error_string(ERR_get_error());
- return false;
- }
-
- char result[result_length];
- if (EVP_DigestSignFinal(md_ctx.get(), reinterpret_cast<uint8_t*>(result),
- &result_length) != 1) {
- FXL_LOG(ERROR) << ERR_reason_error_string(ERR_get_error());
- return false;
- }
-
- std::string signature =
- base64url::Base64UrlEncode(fxl::StringView(result, result_length));
-
- *custom_token = message + "." + signature;
- return true;
-}
-
-http::URLRequest ServiceAccountTokenMinter::GetIdentityRequest(
- const std::string& api_key, const std::string& custom_token) {
- http::URLRequest request;
- request.url =
- "https://www.googleapis.com/identitytoolkit/v3/relyingparty/"
- "verifyCustomToken?key=" +
- api_key;
- request.method = "POST";
- request.auto_follow_redirects = true;
- request.response_body_mode = http::ResponseBodyMode::BUFFER;
-
- // content-type header.
- http::HttpHeader content_type_header;
- content_type_header.name = "content-type";
- content_type_header.value = "application/json";
- request.headers.push_back(std::move(content_type_header));
-
- // set accept header
- http::HttpHeader accept_header;
- accept_header.name = "accept";
- accept_header.value = "application/json";
- request.headers.push_back(std::move(accept_header));
-
- fsl::SizedVmo data;
- bool result = fsl::VmoFromString(GetIdentityRequestBody(custom_token), &data);
- FXL_DCHECK(result);
-
- request.body = http::URLBody::New();
- request.body->set_buffer(std::move(data).ToTransport());
-
- return request;
-}
-
-std::string ServiceAccountTokenMinter::GetIdentityRequestBody(
- const std::string& custom_token) {
- rapidjson::StringBuffer string_buffer;
- rapidjson::Writer<rapidjson::StringBuffer> writer(string_buffer);
-
- writer.StartObject();
-
- writer.Key("token");
- writer.String(custom_token);
-
- writer.Key("returnSecureToken");
- writer.Bool(true);
-
- writer.EndObject();
-
- return std::string(string_buffer.GetString(), string_buffer.GetSize());
-}
-
-void ServiceAccountTokenMinter::HandleIdentityResponse(
- const std::string& api_key, http::URLResponse response) {
- if (response.error) {
- ResolveCallbacks(api_key, GetErrorResponse(Status::NETWORK_ERROR,
- response.error->description));
- return;
- }
-
- std::string response_body;
- if (response.body) {
- FXL_DCHECK(response.body->is_buffer());
- if (!fsl::StringFromVmo(response.body->buffer(), &response_body)) {
- ResolveCallbacks(api_key, GetErrorResponse(Status::INTERNAL_ERROR,
- "Unable to read from VMO."));
- return;
- }
- }
-
- if (response.status_code != 200) {
- ResolveCallbacks(
- api_key, GetErrorResponse(Status::AUTH_SERVER_ERROR, response_body));
- return;
- }
-
- rapidjson::Document document;
- document.Parse(response_body.c_str(), response_body.size());
- if (document.HasParseError() || !document.IsObject()) {
- ResolveCallbacks(api_key, GetErrorResponse(Status::BAD_RESPONSE,
- "Unable to parse response: " +
- response_body));
- return;
- }
-
- if (!json_schema::ValidateSchema(document, GetResponseSchema())) {
- ResolveCallbacks(api_key,
- GetErrorResponse(Status::BAD_RESPONSE,
- "Malformed response: " + response_body));
- return;
- }
-
- auto cached_token = std::make_unique<CachedToken>();
- cached_token->id_token = convert::ToString(document["idToken"]);
- cached_token->expiration_time =
- time(nullptr) + (9u *
- fxl::StringToNumber<time_t>(
- convert::ToStringView(document["expiresIn"])) /
- 10u);
- const auto& id_token = cached_token->id_token;
- cached_tokens_[api_key] = std::move(cached_token);
- ResolveCallbacks(api_key, GetSuccessResponse(id_token));
-}
-
-void ServiceAccountTokenMinter::ResolveCallbacks(const std::string& api_key,
- GetTokenResponse response) {
- auto callbacks = std::move(in_progress_callbacks_[api_key]);
- in_progress_callbacks_[api_key].clear();
- for (const auto& callback : callbacks) {
- callback(std::move(response));
- }
-}
-
-} // namespace service_account
diff --git a/lib/firebase_auth/testing/service_account_token_minter.h b/lib/firebase_auth/testing/service_account_token_minter.h
deleted file mode 100644
index 69fec31..0000000
--- a/lib/firebase_auth/testing/service_account_token_minter.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TOKEN_MINTER_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TOKEN_MINTER_H_
-
-#include <map>
-
-#include <lib/callback/cancellable.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/network_wrapper/network_wrapper.h>
-
-#include "peridot/lib/firebase_auth/testing/credentials.h"
-
-namespace service_account {
-
-// An implementation of |fuchsia::auth::TokenManager| that uses a Firebase
-// service account to register a new user of the given id and mint tokens for
-// it.
-class ServiceAccountTokenMinter {
- public:
- enum Status {
- OK,
- NETWORK_ERROR,
- BAD_RESPONSE,
- AUTH_SERVER_ERROR,
- INTERNAL_ERROR
- };
-
- struct GetTokenResponse {
- Status status;
- std::string id_token;
- std::string local_id;
- std::string email;
- std::string error_msg;
- };
- ServiceAccountTokenMinter(network_wrapper::NetworkWrapper* network_wrapper,
- std::unique_ptr<Credentials> credentials,
- std::string user_id);
-
- ~ServiceAccountTokenMinter();
-
- using GetFirebaseTokenCallback =
- fit::function<void(const GetTokenResponse& response)>;
-
- void GetFirebaseToken(fidl::StringPtr firebase_api_key,
- GetFirebaseTokenCallback callback);
-
- std::string GetClientId();
-
- private:
- struct CachedToken;
-
- std::string GetClaims();
- bool GetCustomToken(std::string* custom_token);
- GetTokenResponse GetCachedToken(fidl::StringPtr firebase_api_key);
- GetTokenResponse GetSuccessResponse(const std::string& id_token);
- GetTokenResponse GetErrorResponse(Status status,
- const std::string& error_msg);
- ::fuchsia::net::oldhttp::URLRequest GetIdentityRequest(
- const std::string& api_key, const std::string& custom_token);
- std::string GetIdentityRequestBody(const std::string& custom_token);
- void HandleIdentityResponse(const std::string& api_key,
- ::fuchsia::net::oldhttp::URLResponse response);
- void ResolveCallbacks(const std::string& api_key, GetTokenResponse response);
-
- network_wrapper::NetworkWrapper* network_wrapper_;
- std::unique_ptr<Credentials> credentials_;
- const std::string user_id_;
- std::map<std::string, std::unique_ptr<CachedToken>> cached_tokens_;
- std::map<std::string, std::vector<GetFirebaseTokenCallback>>
- in_progress_callbacks_;
- callback::CancellableContainer in_progress_requests_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ServiceAccountTokenMinter);
-};
-
-}; // namespace service_account
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_TESTING_SERVICE_ACCOUNT_TOKEN_MINTER_H_
diff --git a/lib/firebase_auth/testing/service_account_token_minter_unittest.cc b/lib/firebase_auth/testing/service_account_token_minter_unittest.cc
deleted file mode 100644
index 149c76e..0000000
--- a/lib/firebase_auth/testing/service_account_token_minter_unittest.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/service_account_token_minter.h"
-
-#include <lib/callback/capture.h>
-#include <lib/callback/set_when_called.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <lib/gtest/test_loop_fixture.h>
-#include <lib/network_wrapper/fake_network_wrapper.h>
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
-
-#include "peridot/lib/firebase_auth/testing/service_account_test_constants.h"
-#include "peridot/lib/firebase_auth/testing/service_account_test_util.h"
-
-namespace service_account {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-namespace {
-
-class ServiceAccountTokenMinterTest : public gtest::TestLoopFixture {
- public:
- ServiceAccountTokenMinterTest()
- : network_wrapper_(dispatcher()),
- token_minter_(&network_wrapper_,
- Credentials::Parse(kTestServiceAccountConfig),
- "user_id") {}
-
- protected:
- bool GetFirebaseToken(std::string api_key,
- ServiceAccountTokenMinter::GetTokenResponse* response) {
- bool called;
- token_minter_.GetFirebaseToken(
- "api_key",
- callback::Capture(callback::SetWhenCalled(&called), response));
- RunLoopUntilIdle();
- return called;
- }
-
- std::string GetClientId() { return token_minter_.GetClientId(); }
-
- network_wrapper::FakeNetworkWrapper network_wrapper_;
- ServiceAccountTokenMinter token_minter_;
-};
-
-TEST_F(ServiceAccountTokenMinterTest, GetClientId) {
- EXPECT_FALSE(GetClientId().empty());
-}
-
-TEST_F(ServiceAccountTokenMinterTest, GetFirebaseToken) {
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token", 3600)));
-
- ServiceAccountTokenMinter::GetTokenResponse resp;
- ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
- ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
- ASSERT_EQ("token", resp.id_token);
-}
-
-TEST_F(ServiceAccountTokenMinterTest, GetFirebaseTokenFromCache) {
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token", 3600)));
-
- ServiceAccountTokenMinter::GetTokenResponse resp;
-
- ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
- ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
- ASSERT_EQ("token", resp.id_token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-
- network_wrapper_.ResetRequest();
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token2", 3600)));
-
- ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
- ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
- ASSERT_EQ("token", resp.id_token);
- EXPECT_FALSE(network_wrapper_.GetRequest());
-}
-
-TEST_F(ServiceAccountTokenMinterTest, GetFirebaseTokenNoCacheCache) {
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token", 0)));
-
- ServiceAccountTokenMinter::GetTokenResponse resp;
-
- ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
- ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
- ASSERT_EQ("token", resp.id_token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-
- network_wrapper_.ResetRequest();
- network_wrapper_.SetResponse(GetResponseForTest(
- nullptr, 200, GetSuccessResponseBodyForTest("token2", 3600)));
-
- ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
- ASSERT_EQ(ServiceAccountTokenMinter::Status::OK, resp.status);
- ASSERT_EQ("token2", resp.id_token);
- EXPECT_TRUE(network_wrapper_.GetRequest());
-}
-
-TEST_F(ServiceAccountTokenMinterTest, NetworkError) {
- auto network_status = http::HttpError::New();
- network_status->description = "Error";
-
- network_wrapper_.SetResponse(
- GetResponseForTest(std::move(network_status), 0, ""));
-
- ServiceAccountTokenMinter::GetTokenResponse resp;
-
- ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
- ASSERT_EQ(ServiceAccountTokenMinter::Status::NETWORK_ERROR, resp.status);
- EXPECT_TRUE(resp.id_token.empty());
- EXPECT_TRUE(network_wrapper_.GetRequest());
-}
-
-TEST_F(ServiceAccountTokenMinterTest, AuthenticationError) {
- network_wrapper_.SetResponse(
- GetResponseForTest(nullptr, 401, "Unauthorized"));
-
- ServiceAccountTokenMinter::GetTokenResponse resp;
-
- ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
- ASSERT_EQ(ServiceAccountTokenMinter::Status::AUTH_SERVER_ERROR, resp.status);
- EXPECT_TRUE(resp.id_token.empty());
- EXPECT_TRUE(network_wrapper_.GetRequest());
-}
-
-TEST_F(ServiceAccountTokenMinterTest, ResponseFormatError) {
- network_wrapper_.SetResponse(GetResponseForTest(nullptr, 200, ""));
-
- ServiceAccountTokenMinter::GetTokenResponse resp;
-
- ASSERT_TRUE(GetFirebaseToken("api_key", &resp));
- ASSERT_EQ(ServiceAccountTokenMinter::Status::BAD_RESPONSE, resp.status);
- EXPECT_TRUE(resp.id_token.empty());
- EXPECT_TRUE(network_wrapper_.GetRequest());
-}
-
-} // namespace
-} // namespace service_account
diff --git a/lib/firebase_auth/testing/test_firebase_auth.cc b/lib/firebase_auth/testing/test_firebase_auth.cc
deleted file mode 100644
index 374ccc3..0000000
--- a/lib/firebase_auth/testing/test_firebase_auth.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/test_firebase_auth.h"
-
-#include <utility>
-
-#include <lib/async/cpp/task.h>
-#include <lib/callback/cancellable_helper.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/functional/closure.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-namespace firebase_auth {
-
-TestFirebaseAuth::TestFirebaseAuth(async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher) {}
-
-void TestFirebaseAuth::set_error_handler(fit::closure on_error) {
- error_handler_ = std::move(on_error);
-}
-
-fxl::RefPtr<callback::Cancellable> TestFirebaseAuth::GetFirebaseToken(
- fit::function<void(AuthStatus, std::string)> callback) {
- auto cancellable = callback::CancellableImpl::Create([] {});
-
- async::PostTask(dispatcher_, [this, callback = cancellable->WrapCallback(
- std::move(callback))]() mutable {
- callback(status_to_return, token_to_return);
- });
- return cancellable;
-}
-
-fxl::RefPtr<callback::Cancellable> TestFirebaseAuth::GetFirebaseUserId(
- fit::function<void(AuthStatus, std::string)> callback) {
- auto cancellable = callback::CancellableImpl::Create([] {});
-
- async::PostTask(dispatcher_, [this, callback = cancellable->WrapCallback(
- std::move(callback))]() mutable {
- callback(status_to_return, user_id_to_return);
- });
- return cancellable;
-}
-
-void TestFirebaseAuth::TriggerConnectionErrorHandler() { error_handler_(); }
-
-} // namespace firebase_auth
diff --git a/lib/firebase_auth/testing/test_firebase_auth.h b/lib/firebase_auth/testing/test_firebase_auth.h
deleted file mode 100644
index 2b5bbe2..0000000
--- a/lib/firebase_auth/testing/test_firebase_auth.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_TEST_FIREBASE_AUTH_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_TEST_FIREBASE_AUTH_H_
-
-#include <lib/async/dispatcher.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/functional/closure.h>
-
-#include "peridot/lib/firebase_auth/firebase_auth.h"
-
-namespace firebase_auth {
-
-class TestFirebaseAuth : public FirebaseAuth {
- public:
- explicit TestFirebaseAuth(async_dispatcher_t* dispatcher);
-
- // FirebaseAuth:
- void set_error_handler(fit::closure on_error) override;
-
- fxl::RefPtr<callback::Cancellable> GetFirebaseToken(
- fit::function<void(AuthStatus, std::string)> callback) override;
-
- fxl::RefPtr<callback::Cancellable> GetFirebaseUserId(
- fit::function<void(AuthStatus, std::string)> callback) override;
-
- void TriggerConnectionErrorHandler();
-
- std::string token_to_return;
-
- AuthStatus status_to_return = AuthStatus::OK;
-
- std::string user_id_to_return;
-
- private:
- async_dispatcher_t* const dispatcher_;
-
- fit::closure error_handler_;
-};
-
-} // namespace firebase_auth
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_TESTING_TEST_FIREBASE_AUTH_H_
diff --git a/lib/firebase_auth/testing/test_token_manager.cc b/lib/firebase_auth/testing/test_token_manager.cc
deleted file mode 100644
index dfbc4e4..0000000
--- a/lib/firebase_auth/testing/test_token_manager.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/firebase_auth/testing/test_token_manager.h"
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/logging.h>
-
-namespace firebase_auth {
-TestTokenManager::TestTokenManager(async_dispatcher_t* dispatcher)
- : dispatcher_(dispatcher) {
- status_to_return_ = fuchsia::auth::Status::OK;
-}
-
-TestTokenManager::~TestTokenManager() {}
-
-void TestTokenManager::Authorize(
- AppConfig app_config,
- fidl::InterfaceHandle<AuthenticationUIContext> auth_ui_context,
- std::vector<std::string> /*app_scopes*/,
- fidl::StringPtr /*user_profile_id*/, fidl::StringPtr /*auth_code*/,
- AuthorizeCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-void TestTokenManager::GetAccessToken(
- AppConfig app_config, std::string /*user_profile_id*/,
- std::vector<std::string> /*app_scopes*/,
- GetAccessTokenCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-void TestTokenManager::GetIdToken(AppConfig app_config,
- std::string /*user_profile_id*/,
- fidl::StringPtr /*audience*/,
- GetIdTokenCallback callback /*callback*/) {
- FXL_NOTIMPLEMENTED();
-}
-
-void TestTokenManager::GetFirebaseToken(AppConfig /*app_config*/,
- std::string /*user_profile_id*/,
- std::string /*audience*/,
- std::string /*firebase_api_key*/,
- GetFirebaseTokenCallback callback) {
- fuchsia::auth::FirebaseTokenPtr token_to_return_copy;
- fidl::Clone(token_to_return_, &token_to_return_copy);
- fuchsia::auth::Status status_to_return_copy;
- status_to_return_copy = status_to_return_;
- async::PostTask(dispatcher_,
- [status_to_return = status_to_return_copy,
- token_to_return = std::move(token_to_return_copy),
- callback = std::move(callback)]() mutable {
- callback(status_to_return, std::move(token_to_return));
- });
-}
-
-void TestTokenManager::DeleteAllTokens(AppConfig /*app_config*/,
- std::string /*user_profile_id*/,
- DeleteAllTokensCallback callback) {
- FXL_NOTIMPLEMENTED();
-}
-
-void TestTokenManager::ListProfileIds(AppConfig app_config,
- ListProfileIdsCallback callback) {
- FXL_NOTIMPLEMENTED();
-}
-
-void TestTokenManager::Set(std::string id_token, std::string local_id,
- std::string email) {
- token_to_return_ = fuchsia::auth::FirebaseToken::New();
- token_to_return_->id_token = id_token;
- token_to_return_->local_id = local_id;
- token_to_return_->email = email;
- status_to_return_ = fuchsia::auth::Status::OK;
-}
-
-void TestTokenManager::SetError(fuchsia::auth::Status status) {
- FXL_CHECK(status != fuchsia::auth::Status::OK);
- token_to_return_ = nullptr;
- status_to_return_ = status;
-}
-} // namespace firebase_auth
diff --git a/lib/firebase_auth/testing/test_token_manager.h b/lib/firebase_auth/testing/test_token_manager.h
deleted file mode 100644
index da9b975..0000000
--- a/lib/firebase_auth/testing/test_token_manager.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_FIREBASE_AUTH_TESTING_TEST_TOKEN_MANAGER_H_
-#define PERIDOT_LIB_FIREBASE_AUTH_TESTING_TEST_TOKEN_MANAGER_H_
-
-#include <string>
-
-#include <fuchsia/auth/cpp/fidl.h>
-#include <lib/async/dispatcher.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/memory/ref_ptr.h>
-
-using fuchsia::auth::AppConfig;
-using fuchsia::auth::AuthenticationUIContext;
-
-namespace firebase_auth {
-
-class TestTokenManager : public fuchsia::auth::TokenManager {
- public:
- explicit TestTokenManager(async_dispatcher_t* dispatcher);
-
- ~TestTokenManager() override;
-
- // fuchsia::auth::TokenManager:
- void Authorize(AppConfig app_config,
- fidl::InterfaceHandle<AuthenticationUIContext> auth_ui_context,
- std::vector<std::string> app_scopes,
- fidl::StringPtr user_profile_id, fidl::StringPtr auth_code,
- AuthorizeCallback callback) override;
-
- void GetAccessToken(AppConfig app_config, std::string user_profile_id,
- std::vector<std::string> app_scopes,
- GetAccessTokenCallback callback) override;
-
- void GetIdToken(AppConfig app_config, std::string user_profile_id,
- fidl::StringPtr audience,
- GetIdTokenCallback callback) override;
-
- void GetFirebaseToken(AppConfig app_config, std::string user_profile_id,
- std::string audience,
- std::string firebase_api_key,
- GetFirebaseTokenCallback callback) override;
-
- void DeleteAllTokens(AppConfig app_config, std::string user_profile_id,
- DeleteAllTokensCallback callback) override;
-
- void ListProfileIds(AppConfig app_config,
- ListProfileIdsCallback callback) override;
-
- // Sets the token to return with the provided parameters, and status to OK.
- void Set(std::string id_token, std::string local_id, std::string email);
-
- // Sets the token to return to null, and status to |status|.
- // |status| must not be OK.
- void SetError(fuchsia::auth::Status status);
-
- private:
- async_dispatcher_t* const dispatcher_;
- fuchsia::auth::FirebaseTokenPtr token_to_return_;
- fuchsia::auth::Status status_to_return_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestTokenManager);
-};
-
-} // namespace firebase_auth
-
-#endif // PERIDOT_LIB_FIREBASE_AUTH_TESTING_TEST_TOKEN_MANAGER_H_
diff --git a/lib/ledger_client/BUILD.gn b/lib/ledger_client/BUILD.gn
deleted file mode 100644
index b23fdd6..0000000
--- a/lib/ledger_client/BUILD.gn
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("ledger_client") {
- deps = [
- ":constants",
- ":operations",
- ":page_client",
- ":promise",
- ":types",
- ]
-}
-
-source_set("constants") {
- sources = [
- "constants.h",
- ]
-}
-
-source_set("operations") {
- sources = [
- "operations.h",
- ]
-
- public_deps = [
- ":page_client",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-source_set("page_client") {
- sources = [
- "ledger_client.cc",
- "ledger_client.h",
- "page_client.cc",
- "page_client.h",
- "page_id.cc",
- "page_id.h",
- ]
-
- deps = [
- ":status",
- ":types",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:clone",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/lib/async/cpp:operation",
- ]
-}
-
-source_set("promise") {
- sources = [
- "promise.h",
- ]
-
- public_deps = [
- "//peridot/lib/fidl:array_to_string",
- "//peridot/public/fidl/fuchsia.ledger",
- ]
-}
-
-source_set("status") {
- sources = [
- "status.cc",
- "status.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.ledger",
- ]
-}
-
-source_set("types") {
- sources = [
- "types.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- ]
-}
-
-group("unittests") {
- testonly = true
-
- deps = [
- ":page_client_unittest",
- ]
-}
-
-source_set("page_client_unittest") {
- testonly = true
-
- sources = [
- "page_client_unittest.cc",
- ]
-
- deps = [
- ":page_client",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/testing:test_with_ledger",
- "//peridot/public/lib/async/cpp:operation",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/ledger_client/MAINTAINERS b/lib/ledger_client/MAINTAINERS
deleted file mode 100644
index 5402e1d..0000000
--- a/lib/ledger_client/MAINTAINERS
+++ /dev/null
@@ -1 +0,0 @@
-qsr@google.com
diff --git a/lib/ledger_client/constants.h b/lib/ledger_client/constants.h
deleted file mode 100644
index 18b7f47..0000000
--- a/lib/ledger_client/constants.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_LEDGER_CLIENT_CONSTANTS_H_
-#define PERIDOT_LIB_LEDGER_CLIENT_CONSTANTS_H_
-
-namespace modular {
-
-inline constexpr char kCloudProviderFirestoreAppUrl[] =
- "fuchsia-pkg://fuchsia.com/cloud_provider_firestore#meta/cloud_provider_firestore.cmx";
-inline constexpr char kLedgerAppUrl[] =
- "fuchsia-pkg://fuchsia.com/ledger#meta/ledger.cmx";
-
-// Hard-coded communal Ledger instance.
-inline constexpr char kFirebaseProjectId[] = "fuchsia-ledger";
-inline constexpr char kFirebaseApiKey[] =
- "AIzaSyDzzuJILOn6riFPTXC36HlH6CEdliLapDA";
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_LEDGER_CLIENT_CONSTANTS_H_
diff --git a/lib/ledger_client/ledger_client.cc b/lib/ledger_client/ledger_client.cc
deleted file mode 100644
index 1e902d7..0000000
--- a/lib/ledger_client/ledger_client.cc
+++ /dev/null
@@ -1,418 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LtICENSE file.
-
-#include "peridot/lib/ledger_client/ledger_client.h"
-
-#include <algorithm>
-
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/ledger_client/page_client.h"
-#include "peridot/lib/ledger_client/status.h"
-#include "peridot/lib/ledger_client/types.h"
-
-namespace modular {
-
-struct LedgerClient::PageEntry {
- LedgerPageId page_id;
- fuchsia::ledger::PagePtr page;
- std::vector<PageClient*> clients;
-};
-
-namespace {
-
-PageClient::Conflict ToConflict(const fuchsia::ledger::DiffEntry* entry) {
- PageClient::Conflict conflict;
- conflict.key = entry->key;
- if (entry->left) {
- conflict.has_left = true;
- std::string value;
- if (!fsl::StringFromVmo(*entry->left->value, &value)) {
- FXL_LOG(ERROR) << "Unable to read vmo for left entry of "
- << to_hex_string(conflict.key) << ".";
- return conflict;
- }
- conflict.left = std::move(value);
- } else {
- conflict.left_is_deleted = true;
- }
- if (entry->right) {
- conflict.has_right = true;
- std::string value;
- if (!fsl::StringFromVmo(*entry->right->value, &value)) {
- FXL_LOG(ERROR) << "Unable to read vmo for right entry of "
- << to_hex_string(conflict.key) << ".";
- return conflict;
- }
- conflict.right = std::move(value);
- } else {
- conflict.right_is_deleted = true;
- }
- return conflict;
-}
-
-void GetDiffRecursive(
- fuchsia::ledger::MergeResultProvider* const result_provider,
- std::map<std::string, PageClient::Conflict>* conflicts, LedgerToken token,
- fit::closure callback) {
- auto cont = [result_provider, conflicts, callback = std::move(callback)](
- fuchsia::ledger::IterationStatus status,
- std::vector<fuchsia::ledger::DiffEntry> change_delta,
- LedgerToken token) mutable {
- for (auto& diff_entry : change_delta) {
- (*conflicts)[to_string(diff_entry.key)] = ToConflict(&diff_entry);
- }
-
- if (status == fuchsia::ledger::IterationStatus::OK) {
- callback();
- return;
- }
-
- GetDiffRecursive(result_provider, conflicts, std::move(token),
- std::move(callback));
- };
-
- result_provider->GetConflictingDiffNew(std::move(token), std::move(cont));
-}
-
-void GetDiff(fuchsia::ledger::MergeResultProvider* const result_provider,
- std::map<std::string, PageClient::Conflict>* conflicts,
- fit::closure callback) {
- GetDiffRecursive(result_provider, conflicts, nullptr /* token */,
- std::move(callback));
-}
-
-bool HasPrefix(const std::string& value, const std::string& prefix) {
- if (value.size() < prefix.size()) {
- return false;
- }
-
- for (size_t i = 0; i < prefix.size(); ++i) {
- if (value[i] != prefix[i]) {
- return false;
- }
- }
-
- return true;
-}
-
-} // namespace
-
-class LedgerClient::ConflictResolverImpl::ResolveCall : public Operation<> {
- public:
- ResolveCall(ConflictResolverImpl* const impl,
- fuchsia::ledger::MergeResultProviderPtr result_provider,
- fuchsia::ledger::PageSnapshotPtr left_version,
- fuchsia::ledger::PageSnapshotPtr right_version,
- fuchsia::ledger::PageSnapshotPtr common_version)
- : Operation("LedgerClient::ResolveCall", [] {}),
- impl_(impl),
- result_provider_(std::move(result_provider)),
- left_version_(std::move(left_version)),
- right_version_(std::move(right_version)),
- common_version_(std::move(common_version)) {
- result_provider_.set_error_handler([](zx_status_t status) {
- if (status != ZX_OK && status != ZX_ERR_PEER_CLOSED) {
- FXL_LOG(ERROR) << "ResultProvider error: "
- << LedgerEpitaphToString(status);
- } else {
- FXL_LOG(INFO) << "ResultProvider disconnected: "
- << LedgerEpitaphToString(status);
- }
- });
- }
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- result_provider_->MergeNonConflictingEntriesNew();
-
- GetDiff(result_provider_.get(), &conflicts_,
- [this, flow] { WithDiff(flow); });
-
- GetEntries(left_version_.get(), &left_entries_,
- [this, flow](fuchsia::ledger::Status) {
- LogEntries("left", left_entries_);
- });
-
- GetEntries(right_version_.get(), &right_entries_,
- [this, flow](fuchsia::ledger::Status) {
- LogEntries("right", right_entries_);
- });
-
- GetEntries(common_version_.get(), &common_entries_,
- [this, flow](fuchsia::ledger::Status) {
- LogEntries("common", common_entries_);
- });
- }
-
- void WithDiff(FlowToken flow) {
- std::vector<PageClient*> page_clients;
- impl_->GetPageClients(&page_clients);
-
- for (auto& pair : conflicts_) {
- const PageClient::Conflict& conflict = pair.second;
- std::vector<fuchsia::ledger::MergedValue> merge_changes;
-
- if (conflict.has_left && conflict.has_right) {
- for (PageClient* const page_client : page_clients) {
- if (HasPrefix(pair.first, page_client->prefix())) {
- page_client->OnPageConflict(&pair.second);
-
- if (pair.second.resolution != PageClient::LEFT) {
- fuchsia::ledger::MergedValue merged_value;
- merged_value.key = conflict.key;
- if (pair.second.resolution == PageClient::RIGHT) {
- merged_value.source = fuchsia::ledger::ValueSource::RIGHT;
- } else {
- if (pair.second.merged_is_deleted) {
- merged_value.source = fuchsia::ledger::ValueSource::DELETE;
- } else {
- merged_value.source = fuchsia::ledger::ValueSource::NEW;
- merged_value.new_value =
- fuchsia::ledger::BytesOrReference::New();
- merged_value.new_value->set_bytes(
- to_array(pair.second.merged));
- }
- }
- merge_changes.push_back(std::move(merged_value));
- }
-
- // First client handles the conflict.
- //
- // TODO(mesch): We should order clients reverse-lexicographically by
- // prefix, so that longer prefixes are checked first.
- //
- // TODO(mesch): Default resolution could then be PASS, which would
- // pass to the next matching client. Too easy to abuse though.
- //
- // TODO(mesch): Best would be if overlapping prefixes are
- // prohibited.
- break;
- }
- }
- }
-
- if (!merge_changes.empty()) {
- result_provider_->MergeNew(std::move(merge_changes));
- }
- }
-
- result_provider_->DoneNew();
- result_provider_->Sync([this, flow] { impl_->NotifyWatchers(); });
- }
-
- void LogEntries(const std::string& headline,
- const std::vector<fuchsia::ledger::Entry>& entries) {
- FXL_VLOG(4) << "Entries " << headline;
- for (const fuchsia::ledger::Entry& entry : entries) {
- FXL_VLOG(4) << " - " << to_string(entry.key);
- }
- }
-
- ConflictResolverImpl* const impl_;
- fuchsia::ledger::MergeResultProviderPtr result_provider_;
-
- fuchsia::ledger::PageSnapshotPtr left_version_;
- fuchsia::ledger::PageSnapshotPtr right_version_;
- fuchsia::ledger::PageSnapshotPtr common_version_;
-
- std::vector<fuchsia::ledger::Entry> left_entries_;
- std::vector<fuchsia::ledger::Entry> right_entries_;
- std::vector<fuchsia::ledger::Entry> common_entries_;
-
- std::map<std::string, PageClient::Conflict> conflicts_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ResolveCall);
-};
-
-LedgerClient::LedgerClient(fuchsia::ledger::LedgerPtr ledger)
- : ledger_(std::move(ledger)) {
- ledger_->SetConflictResolverFactory(
- bindings_.AddBinding(this), [](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "Ledger.SetConflictResolverFactory() failed: "
- << LedgerStatusToString(status);
- }
- });
-}
-
-LedgerClient::LedgerClient(
- fuchsia::ledger::internal::LedgerRepository* const ledger_repository,
- const std::string& name, std::function<void()> error) {
- ledger_.set_error_handler([](zx_status_t status) {
- if (status != ZX_OK && status != ZX_ERR_PEER_CLOSED) {
- FXL_LOG(ERROR) << "Ledger error: " << LedgerEpitaphToString(status);
- } else {
- FXL_LOG(INFO) << "Ledger disconnected: "
- << LedgerEpitaphToString(status);
- }
- });
- // Open Ledger.
- ledger_repository->GetLedger(to_array(name), ledger_.NewRequest());
-
- // This must be the first call after GetLedger, otherwise the Ledger
- // starts with one reconciliation strategy, then switches to another.
- ledger_->SetConflictResolverFactory(
- bindings_.AddBinding(this), [error](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "Ledger.SetConflictResolverFactory() failed: "
- << LedgerStatusToString(status);
- error();
- }
- });
-}
-
-LedgerClient::~LedgerClient() = default;
-
-fuchsia::ledger::Page* LedgerClient::GetPage(
- PageClient* const page_client, const std::string& context,
- const fuchsia::ledger::PageId& page_id) {
- auto i = std::find_if(pages_.begin(), pages_.end(), [&page_id](auto& entry) {
- return PageIdsEqual(entry->page_id, page_id);
- });
-
- if (i != pages_.end()) {
- (*i)->clients.push_back(page_client);
- return (*i)->page.get();
- }
-
- fuchsia::ledger::PagePtr page;
- fuchsia::ledger::PageIdPtr page_id_copy = fuchsia::ledger::PageId::New();
-
- page_id_copy->id = page_id.id;
- ledger_->GetPage(std::move(page_id_copy), page.NewRequest(),
- [context](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << "Ledger.GetPage() " << context << " "
- << fidl::ToUnderlying(status);
- }
- });
-
- auto entry = std::make_unique<PageEntry>();
- entry->page_id = CloneStruct(page_id);
- entry->clients.push_back(page_client);
-
- entry->page = std::move(page);
- entry->page.set_error_handler([context](zx_status_t status) {
- // TODO(mesch): If this happens, larger things are wrong. This should
- // probably be signalled up, or at least must be signalled to the page
- // client.
- FXL_LOG(ERROR) << context << ": "
- << "Page connection unexpectedly closed.";
- });
-
- pages_.emplace_back(std::move(entry));
- return pages_.back()->page.get();
-}
-
-void LedgerClient::DropPageClient(PageClient* const page_client) {
- for (auto i = pages_.begin(); i < pages_.end(); ++i) {
- std::vector<PageClient*>* const page_clients = &(*i)->clients;
-
- auto ii = std::remove_if(
- page_clients->begin(), page_clients->end(),
- [page_client](PageClient* item) { return item == page_client; });
-
- if (ii != page_clients->end()) {
- page_clients->erase(ii, page_clients->end());
-
- if (page_clients->empty()) {
- ClearConflictResolver((*i)->page_id);
- pages_.erase(i);
- break; // Loop variable now invalid; must not continue loop.
- }
- }
- }
-}
-
-void LedgerClient::GetPolicy(LedgerPageId page_id, GetPolicyCallback callback) {
- auto i = std::find_if(pages_.begin(), pages_.end(), [&page_id](auto& entry) {
- return PageIdsEqual(entry->page_id, page_id);
- });
-
- // This is wrong if GetPolicy() is called for a page before its page client
- // has registered. Therefore, if an app keeps multiple connections to a page,
- // the ones kept by page clients must be created first.
- //
- // TODO(mesch): Maybe AUTOMATIC_WITH_FALLBACK should always be used anyway,
- // and the resolver should deal with conflicts on pages that don't have a page
- // client.
- if (i != pages_.end()) {
- callback(fuchsia::ledger::MergePolicy::AUTOMATIC_WITH_FALLBACK);
- return;
- }
-
- callback(fuchsia::ledger::MergePolicy::LAST_ONE_WINS);
-}
-
-void LedgerClient::NewConflictResolver(
- LedgerPageId page_id,
- fidl::InterfaceRequest<fuchsia::ledger::ConflictResolver> request) {
- for (auto& i : resolvers_) {
- if (PageIdsEqual(i->page_id(), page_id)) {
- i->Connect(std::move(request));
- return;
- }
- }
-
- resolvers_.emplace_back(
- std::make_unique<ConflictResolverImpl>(this, std::move(page_id)));
- resolvers_.back()->Connect(std::move(request));
-}
-
-void LedgerClient::ClearConflictResolver(const LedgerPageId& page_id) {
- auto i = std::remove_if(resolvers_.begin(), resolvers_.end(),
- [&page_id](auto& item) {
- return PageIdsEqual(item->page_id(), page_id);
- });
-
- if (i != resolvers_.end()) {
- resolvers_.erase(i, resolvers_.end());
- }
-}
-
-LedgerClient::ConflictResolverImpl::ConflictResolverImpl(
- LedgerClient* const ledger_client, const LedgerPageId& page_id)
- : ledger_client_(ledger_client), page_id_(CloneStruct(page_id)) {}
-
-LedgerClient::ConflictResolverImpl::~ConflictResolverImpl() = default;
-
-void LedgerClient::ConflictResolverImpl::Connect(
- fidl::InterfaceRequest<fuchsia::ledger::ConflictResolver> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void LedgerClient::ConflictResolverImpl::Resolve(
- fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> left_version,
- fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> right_version,
- fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> common_version,
- fidl::InterfaceHandle<fuchsia::ledger::MergeResultProvider>
- result_provider) {
- operation_queue_.Add(
- new ResolveCall(this, result_provider.Bind(), left_version.Bind(),
- right_version.Bind(), common_version.Bind()));
-}
-
-void LedgerClient::ConflictResolverImpl::GetPageClients(
- std::vector<PageClient*>* page_clients) {
- auto i = std::find_if(
- ledger_client_->pages_.begin(), ledger_client_->pages_.end(),
- [this](auto& item) { return PageIdsEqual(item->page_id, page_id_); });
-
- FXL_CHECK(i != ledger_client_->pages_.end());
- *page_clients = (*i)->clients;
-}
-
-void LedgerClient::ConflictResolverImpl::NotifyWatchers() const {
- for (auto& watcher : ledger_client_->watchers_) {
- watcher();
- }
-}
-
-} // namespace modular
diff --git a/lib/ledger_client/ledger_client.h b/lib/ledger_client/ledger_client.h
deleted file mode 100644
index b6ed4c8..0000000
--- a/lib/ledger_client/ledger_client.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_LEDGER_CLIENT_LEDGER_CLIENT_H_
-#define PERIDOT_LIB_LEDGER_CLIENT_LEDGER_CLIENT_H_
-
-#include <functional>
-#include <memory>
-#include <vector>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/ledger_client/types.h"
-
-namespace modular {
-
-class PageClient;
-
-// The primary purpose of the ledger client is to act as conflict resolver
-// factory which is able to dispatch conflicts to the page clients based on
-// their page and key prefix.
-class LedgerClient : fuchsia::ledger::ConflictResolverFactory {
- public:
- LedgerClient(fuchsia::ledger::internal::LedgerRepository* ledger_repository,
- const std::string& name, std::function<void()> error);
- LedgerClient(fuchsia::ledger::LedgerPtr ledger);
- ~LedgerClient() override;
-
- fuchsia::ledger::Ledger* ledger() const { return ledger_.get(); }
-
- // A callback that is invoked every time one conflict resolution completes.
- // Used only for testing so far.
- void add_watcher(std::function<void()> watcher) {
- watchers_.emplace_back(std::move(watcher));
- }
-
- private:
- friend class PageClient;
- class ConflictResolverImpl;
- struct PageEntry;
-
- // Used by PageClient to access a new page on creation. Two page clients of
- // the same page share the same ledger::Page connection.
- fuchsia::ledger::Page* GetPage(PageClient* page_client,
- const std::string& context,
- const fuchsia::ledger::PageId& page_id);
-
- // PageClient deregisters itself on destrution.
- void DropPageClient(PageClient* page_client);
-
- // |ConflictResolverFactory|
- void GetPolicy(LedgerPageId page_id, GetPolicyCallback callback) override;
-
- // |ConflictResolverFactory|
- void NewConflictResolver(
- LedgerPageId page_id,
- fidl::InterfaceRequest<fuchsia::ledger::ConflictResolver> request)
- override;
-
- void ClearConflictResolver(const LedgerPageId& page_id);
-
- // The ledger this is a client of.
- fuchsia::ledger::LedgerPtr ledger_;
-
- fidl::BindingSet<fuchsia::ledger::ConflictResolverFactory> bindings_;
- std::vector<std::unique_ptr<ConflictResolverImpl>> resolvers_;
-
- // ledger::Page connections are owned by LedgerClient, and only handed to
- // PageClient as naked pointers. This allows multiple clients of the same page
- // to share a page connection.
- std::vector<std::unique_ptr<PageEntry>> pages_;
-
- // Notified whenever a conflict resolution cycle finishes.
- std::vector<std::function<void()>> watchers_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerClient);
-};
-
-// A conflict resolver for one page that delegates the diff for a key to the
-// appropriate page client that handles that key.
-class LedgerClient::ConflictResolverImpl : fuchsia::ledger::ConflictResolver {
- public:
- ConflictResolverImpl(LedgerClient* ledger_client,
- const LedgerPageId& page_id);
- ~ConflictResolverImpl() override;
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::ledger::ConflictResolver> request);
-
- const LedgerPageId& page_id() const { return page_id_; }
-
- private:
- // |ConflictResolver|
- void Resolve(
- fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> left_version,
- fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> right_version,
- fidl::InterfaceHandle<fuchsia::ledger::PageSnapshot> common_version,
- fidl::InterfaceHandle<fuchsia::ledger::MergeResultProvider>
- result_provider) override;
-
- void GetPageClients(std::vector<PageClient*>* page_clients);
-
- void NotifyWatchers() const;
-
- LedgerClient* const ledger_client_;
- LedgerPageId page_id_;
-
- fidl::BindingSet<fuchsia::ledger::ConflictResolver> bindings_;
-
- OperationQueue operation_queue_;
- class ResolveCall;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ConflictResolverImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_LEDGER_CLIENT_LEDGER_CLIENT_H_
diff --git a/lib/ledger_client/operations.h b/lib/ledger_client/operations.h
deleted file mode 100644
index 2af0227..0000000
--- a/lib/ledger_client/operations.h
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The file defines Operations commonly executed on Ledger pages.
-
-#ifndef PERIDOT_LIB_LEDGER_CLIENT_OPERATIONS_H_
-#define PERIDOT_LIB_LEDGER_CLIENT_OPERATIONS_H_
-
-#include <string>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <lib/async/cpp/operation.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/ledger_client/page_client.h"
-
-namespace modular {
-
-// Common base class for all Operation classes that operate on a ledger Page.
-//
-// The ledger page is always passed as a naked pointer fuchsia::ledger::Page*
-// rather than as a FIDL pointer fuchsia::ledger::PagePtr to the Operation
-// instance, because the connection to the page is shared between different
-// Operation instances executed by different actors in the framework. The
-// PagePtr is held by LedgerClient and handed out as Page* to PageClient, which
-// passes it on to the respective Operations.
-//
-// As a result, callbacks for methods invoked on the Page* are not cancelled
-// when the Operation instance is deleted, as they would be if the FIDL pointer
-// were owned by the Operation instance. Therefore, such callbacks must be
-// explicitly guarded using a weak pointer to the Operation instance against
-// execution after their Operation instance was destroyed.
-//
-// This base class provides the method Protect() for the purpose.
-//
-// In derived class that are themselves template classes, the method must be
-// invoked by explicit qualification with this-> (or alternatively with the base
-// class name), because of template name lookup rules.
-//
-// Also, it is not possible to pass a PageSnapshotPtr to the Operation instead,
-// because the snapshot must be taken at the time the Operation is executed, not
-// at the time the Operation is enqueued, because it must reflect the effect of
-// the execution of preceding operations.
-template <typename... Args>
-class PageOperation : public Operation<Args...> {
- public:
- using ResultCall = std::function<void(Args...)>;
-
- PageOperation(const char* const trace_name, fuchsia::ledger::Page* const page,
- ResultCall result_call, const std::string& trace_info = "")
- : Operation<Args...>(trace_name, std::move(result_call), trace_info),
- page_(page) {}
-
- protected:
- fuchsia::ledger::Page* page() const { return page_; }
-
- using PageCallback = std::function<void(fuchsia::ledger::Status)>;
-
- PageCallback Protect(PageCallback callback) {
- return [weak_this = this->GetWeakPtr(),
- callback = std::move(callback)](fuchsia::ledger::Status status) {
- if (weak_this) {
- callback(status);
- }
- };
- }
-
- private:
- fuchsia::ledger::Page* const page_;
-};
-
-// Like PageOperation, but also takes a naked Ledger pointer, which has the same
-// problems.
-//
-// This could be unified more with PageOperation, but only worthwhile once there
-// are more situations to support. For now, it's very nice to label Operation
-// classes explicitly with their base classes.
-template <typename... Args>
-class LedgerOperation : public Operation<Args...> {
- public:
- using ResultCall = std::function<void(Args...)>;
-
- LedgerOperation(const char* const trace_name, fuchsia::ledger::Ledger* ledger,
- fuchsia::ledger::Page* const page, ResultCall result_call,
- const std::string& trace_info = "")
- : Operation<Args...>(trace_name, std::move(result_call), trace_info),
- ledger_(ledger),
- page_(page) {}
-
- protected:
- fuchsia::ledger::Ledger* ledger() const { return ledger_; }
- fuchsia::ledger::Page* page() const { return page_; }
-
- using LedgerCallback = std::function<void(fuchsia::ledger::Status)>;
-
- LedgerCallback Protect(LedgerCallback callback) {
- return [weak_this = this->GetWeakPtr(),
- callback = std::move(callback)](fuchsia::ledger::Status status) {
- if (weak_this) {
- callback(status);
- }
- };
- }
-
- private:
- fuchsia::ledger::Ledger* const ledger_;
- fuchsia::ledger::Page* const page_;
-};
-
-template <typename Data, typename DataPtr = std::unique_ptr<Data>,
- typename DataFilter = XdrFilterList<Data>>
-class ReadDataCall : public PageOperation<DataPtr> {
- public:
- using ResultCall = std::function<void(DataPtr)>;
- using FlowToken = typename Operation<DataPtr>::FlowToken;
-
- ReadDataCall(fuchsia::ledger::Page* const page, const std::string& key,
- const bool not_found_is_ok, DataFilter filter,
- ResultCall result_call)
- : PageOperation<DataPtr>("ReadDataCall", page, std::move(result_call),
- key),
- key_(key),
- not_found_is_ok_(not_found_is_ok),
- filter_(filter) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &result_};
-
- this->page()->GetSnapshot(
- page_snapshot_.NewRequest(), fidl::VectorPtr<uint8_t>::New(0), nullptr,
- this->Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << this->trace_name() << " " << key_ << " "
- << "Page.GetSnapshot() "
- << fidl::ToUnderlying(status);
- return;
- }
-
- Cont(flow);
- }));
- }
-
- void Cont(FlowToken flow) {
- page_snapshot_->Get(to_array(key_), [this, flow](
- fuchsia::ledger::Status status,
- fuchsia::mem::BufferPtr value) {
- if (status != fuchsia::ledger::Status::OK) {
- if (status != fuchsia::ledger::Status::KEY_NOT_FOUND ||
- !not_found_is_ok_) {
- FXL_LOG(ERROR) << this->trace_name() << " " << key_ << " "
- << "PageSnapshot.Get() " << fidl::ToUnderlying(status);
- }
- return;
- }
-
- if (!value) {
- FXL_LOG(ERROR) << this->trace_name() << " " << key_ << " "
- << "PageSnapshot.Get() null vmo";
- }
-
- std::string value_as_string;
- if (!fsl::StringFromVmo(*value, &value_as_string)) {
- FXL_LOG(ERROR) << this->trace_name() << " " << key_
- << " Unable to extract data.";
- return;
- }
-
- if (!XdrRead(value_as_string, &result_, filter_)) {
- result_.reset();
- return;
- }
-
- FXL_DCHECK(result_);
- });
- }
-
- const std::string key_;
- const bool not_found_is_ok_;
- DataFilter const filter_;
- fuchsia::ledger::PageSnapshotPtr page_snapshot_;
- DataPtr result_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ReadDataCall);
-};
-
-template <typename Data, typename DataArray = std::vector<Data>,
- typename DataFilter = XdrFilterList<Data>>
-class ReadAllDataCall : public PageOperation<DataArray> {
- public:
- using ResultCall = std::function<void(DataArray)>;
- using FlowToken = typename Operation<DataArray>::FlowToken;
-
- ReadAllDataCall(fuchsia::ledger::Page* const page, std::string prefix,
- DataFilter const filter, ResultCall result_call)
- : PageOperation<DataArray>("ReadAllDataCall", page,
- std::move(result_call), prefix),
- prefix_(std::move(prefix)),
- filter_(filter) {
- data_.resize(0);
- }
-
- private:
- void Run() override {
- FlowToken flow{this, &data_};
-
- this->page()->GetSnapshot(
- page_snapshot_.NewRequest(), to_array(prefix_), nullptr,
- this->Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << this->trace_name() << " "
- << "Page.GetSnapshot() "
- << fidl::ToUnderlying(status);
- return;
- }
-
- Cont1(flow);
- }));
- }
-
- void Cont1(FlowToken flow) {
- GetEntries(page_snapshot_.get(), &entries_,
- [this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR)
- << this->trace_name() << " "
- << "GetEntries() " << fidl::ToUnderlying(status);
- return;
- }
-
- Cont2(flow);
- });
- }
-
- void Cont2(FlowToken /*flow*/) {
- for (auto& entry : entries_) {
- std::string value_as_string;
- if (!fsl::StringFromVmo(*entry.value, &value_as_string)) {
- FXL_LOG(ERROR) << this->trace_name() << " "
- << "Unable to extract data.";
- continue;
- }
-
- Data data;
- if (!XdrRead(value_as_string, &data, filter_)) {
- continue;
- }
-
- data_.push_back(std::move(data));
- }
- }
-
- fuchsia::ledger::PageSnapshotPtr page_snapshot_;
- const std::string prefix_;
- DataFilter const filter_;
- std::vector<fuchsia::ledger::Entry> entries_;
- DataArray data_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ReadAllDataCall);
-};
-
-template <typename Data, typename DataPtr = std::unique_ptr<Data>,
- typename DataFilter = XdrFilterList<Data>>
-class WriteDataCall : public PageOperation<> {
- public:
- WriteDataCall(fuchsia::ledger::Page* const page, const std::string& key,
- DataFilter filter, DataPtr data, ResultCall result_call)
- : PageOperation("WriteDataCall", page, std::move(result_call), key),
- key_(key),
- filter_(filter),
- data_(std::move(data)) {}
-
- private:
- void Run() override {
- FlowToken flow{this};
-
- std::string json;
- XdrWrite(&json, &data_, filter_);
-
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(json, &vmo));
- page()->CreateReferenceFromBuffer(
- std::move(vmo).ToTransport(),
- [this, weak_ptr = GetWeakPtr(), flow](
- fuchsia::ledger::Status status,
- std::unique_ptr<fuchsia::ledger::Reference> reference) {
- if (!weak_ptr) {
- return;
- }
- PutReference(std::move(reference), flow);
- });
- }
-
- void PutReference(std::unique_ptr<fuchsia::ledger::Reference> reference,
- FlowToken flow) {
- if (!reference) {
- FXL_LOG(ERROR) << trace_name() << " " << key_ << " "
- << "Page.Put() could not construct reference.";
- return;
- }
-
- page()->PutReference(
- to_array(key_), std::move(*reference), fuchsia::ledger::Priority::EAGER,
- Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << trace_name() << " " << key_ << " "
- << "Page.Put() " << fidl::ToUnderlying(status);
- }
- }));
- }
-
- const std::string key_;
- DataFilter const filter_;
- DataPtr data_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(WriteDataCall);
-};
-
-class DumpPageSnapshotCall : public PageOperation<std::string> {
- public:
- DumpPageSnapshotCall(fuchsia::ledger::Page* const page,
- ResultCall result_call)
- : PageOperation("DumpPageSnapshotCall", page, std::move(result_call)) {}
-
- private:
- void Run() override {
- FlowToken flow{this, &dump_};
-
- page()->GetSnapshot(page_snapshot_.NewRequest(),
- fidl::VectorPtr<uint8_t>::New(0), nullptr,
- Protect([this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << this->trace_name() << " "
- << "Page.GetSnapshot() "
- << fidl::ToUnderlying(status);
- return;
- }
-
- Cont1(flow);
- }));
- }
-
- void Cont1(FlowToken flow) {
- GetEntries(page_snapshot_.get(), &entries_,
- [this, flow](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR)
- << this->trace_name() << " "
- << "GetEntries() " << fidl::ToUnderlying(status);
- return;
- }
-
- Cont2(flow);
- });
- }
-
- void Cont2(FlowToken /*flow*/) {
- std::ostringstream stream;
- for (auto& entry : entries_) {
- stream << "key: " << to_hex_string(entry.key) << std::endl;
-
- std::string value_as_string;
- if (!fsl::StringFromVmo(*entry.value, &value_as_string)) {
- FXL_LOG(ERROR) << this->trace_name() << " "
- << "Unable to extract data.";
- continue;
- }
- stream << "value: " << value_as_string << std::endl;
- }
- dump_ = stream.str();
- }
-
- fuchsia::ledger::PageSnapshotPtr page_snapshot_;
- std::vector<fuchsia::ledger::Entry> entries_;
- std::string dump_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DumpPageSnapshotCall);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_LEDGER_CLIENT_OPERATIONS_H_
diff --git a/lib/ledger_client/page_client.cc b/lib/ledger_client/page_client.cc
deleted file mode 100644
index e75ae85..0000000
--- a/lib/ledger_client/page_client.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/ledger_client/page_client.h"
-
-#include <memory>
-#include <utility>
-
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-
-namespace modular {
-
-PageClient::PageClient(std::string context, LedgerClient* ledger_client,
- LedgerPageId page_id, std::string prefix)
- : binding_(this),
- context_(std::move(context)),
- ledger_client_(ledger_client),
- page_id_(std::move(page_id)),
- page_(ledger_client_->GetPage(this, context_, page_id_)),
- prefix_(std::move(prefix)) {
- fuchsia::ledger::PageSnapshotPtr snapshot;
- page_->GetSnapshot(snapshot.NewRequest(), to_array(prefix_),
- binding_.NewBinding(),
- [this](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << context_ << " Page.GetSnapshot() "
- << fidl::ToUnderlying(status);
- }
- });
-}
-
-PageClient::~PageClient() {
- // We assume ledger client always outlives page client.
- ledger_client_->DropPageClient(this);
-}
-
-fuchsia::ledger::PageSnapshotPtr PageClient::NewSnapshot(
- std::function<void()> on_error) {
- fuchsia::ledger::PageSnapshotPtr ptr;
- page_->GetSnapshot(
- ptr.NewRequest(), to_array(prefix_), nullptr /* page_watcher */,
- [this, on_error = std::move(on_error)](fuchsia::ledger::Status status) {
- if (status != fuchsia::ledger::Status::OK) {
- FXL_LOG(ERROR) << context_ << " Page.GetSnapshot() "
- << fidl::ToUnderlying(status);
- on_error();
- }
- });
- return ptr;
-}
-
-// |PageWatcher|
-void PageClient::OnChange(fuchsia::ledger::PageChange page,
- fuchsia::ledger::ResultState result_state,
- OnChangeCallback callback) {
- for (auto& entry : page.changed_entries) {
- // Remove key prefix maybe?
- OnPageChange(to_string(entry.key), std::move(entry.value));
- }
-
- for (auto& key : page.deleted_keys) {
- OnPageDelete(to_string(key));
- }
-
- callback(nullptr);
-}
-
-void PageClient::OnPageChange(const std::string& key,
- fuchsia::mem::BufferPtr value) {
- std::string value_string;
- if (fsl::StringFromVmo(*value, &value_string)) {
- OnPageChange(key, value_string);
- } else {
- FXL_LOG(ERROR) << "PageClient::OnChange() " << context_ << ": "
- << "Unable to read/copy data.";
- }
-}
-
-void PageClient::OnPageChange(const std::string& /*key*/,
- const std::string& /*value*/) {}
-
-void PageClient::OnPageDelete(const std::string& /*key*/) {}
-
-void PageClient::OnPageConflict(Conflict* const conflict) {
- FXL_LOG(INFO) << "PageClient::OnPageConflict() " << context_ << " "
- << to_hex_string(conflict->key) << " " << conflict->left << " "
- << conflict->right;
-};
-
-namespace {
-
-void GetEntriesRecursive(fuchsia::ledger::PageSnapshot* const snapshot,
- std::vector<fuchsia::ledger::Entry>* const entries,
- std::unique_ptr<fuchsia::ledger::Token> next_token,
- std::function<void(fuchsia::ledger::Status)> done) {
- snapshot->GetEntries(
- std::vector<uint8_t>{} /* key_start */, std::move(next_token),
- fxl::MakeCopyable([snapshot, entries, done = std::move(done)](
- fuchsia::ledger::Status status, auto new_entries,
- auto next_token) mutable {
- if (status != fuchsia::ledger::Status::OK &&
- status != fuchsia::ledger::Status::PARTIAL_RESULT) {
- done(status);
- return;
- }
-
- for (size_t i = 0; i < new_entries.size(); ++i) {
- entries->push_back(std::move(new_entries.at(i)));
- }
-
- if (status == fuchsia::ledger::Status::OK) {
- done(fuchsia::ledger::Status::OK);
- return;
- }
-
- GetEntriesRecursive(snapshot, entries, std::move(next_token),
- std::move(done));
- }));
-}
-
-} // namespace
-
-void GetEntries(fuchsia::ledger::PageSnapshot* const snapshot,
- std::vector<fuchsia::ledger::Entry>* const entries,
- std::function<void(fuchsia::ledger::Status)> done) {
- GetEntriesRecursive(snapshot, entries, nullptr /* next_token */,
- std::move(done));
-}
-
-} // namespace modular
diff --git a/lib/ledger_client/page_client.h b/lib/ledger_client/page_client.h
deleted file mode 100644
index 33cd36b..0000000
--- a/lib/ledger_client/page_client.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_LEDGER_CLIENT_PAGE_CLIENT_H_
-#define PERIDOT_LIB_LEDGER_CLIENT_PAGE_CLIENT_H_
-
-#include <array>
-#include <string>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/ledger_client/types.h"
-
-namespace modular {
-
-class LedgerClient;
-
-// A helper class that aids in interfacing with a fuchsia.ledger.Page by:
-//
-// 1) Forwarding requests for conflict resolution from the
-// fuchsia.ledger.Ledger connection to a PageClient's OnPageConflict() which is
-// constructed with an associated key prefix of the Page.
-// 2) Providing a convenient method to acquire a PageSnapshot from the Page.
-// 3) Providing an optional and convenient per-key
-// fuchsia.ledger.PageWatcher.OnChange() implementation that calls into
-// OnPageChange(). Clients that care about the notification semantics of >1 key
-// at a time may wish to implement OnChange() directly.
-//
-// NOTE: The conflict resolution API is currently implemented on a per-key
-// basis. Conflict resolution may be difficult for some clients to implement
-// if a multiple-key update has semantic meaning. MF-157
-class PageClient : fuchsia::ledger::PageWatcher {
- public:
- // |context| is used as a string prefix on log messages. |ledger_client| is
- // used to retrieve a handle to the page specified in |page_id|, and to
- // listen for conflicts from the ledger. If |prefix| is provided, the
- // resulting page snapshot and change notifications are limited to only keys
- // with that prefix. However, OnPageChange()'s |key| will include the full
- // key, including the prefix.
- //
- // |ledger_client| must outlive *this.
- PageClient(std::string context, LedgerClient* ledger_client,
- LedgerPageId page_id, std::string prefix = "");
- ~PageClient() override;
-
- // Returns a snapshot of the Ledger page under |prefix| at the most recent
- // timepoint.
- //
- // If |on_error| is provided, it will be called if there was a Ledger error
- // trying to get the snapshot.
- //
- // NOTE: There is no guaranteed timing for writes made to the returned
- // PageSnapshot and notifications of changes through OnPageChange(). The
- // ordering is guaranteed to be the same, ignoring changes to the writes
- // caused by conflict resolution which can cause some writes to disappear.
- fuchsia::ledger::PageSnapshotPtr NewSnapshot(
- std::function<void()> on_error = nullptr);
-
- const fuchsia::ledger::PageId& page_id() const { return page_id_; }
- const std::string& prefix() const { return prefix_; }
- fuchsia::ledger::Page* page() { return page_; }
-
- // Computed by implementations of OnPageConflict() in derived classes.
- enum ConflictResolution { LEFT, RIGHT, MERGE };
-
- // The argument to OnPageConflict(). It's mutated in place so it's easier to
- // extend without having to alter clients.
- struct Conflict {
- std::vector<uint8_t> key;
-
- bool has_left{};
- std::string left;
- bool left_is_deleted{};
-
- bool has_right{};
- std::string right;
- bool right_is_deleted{};
-
- ConflictResolution resolution{LEFT};
- std::string merged;
- bool merged_is_deleted{};
- };
-
- protected:
- // Derived classes may implement this method as needed. The default
- // implementation copies the VMO to a string and forwards to
- // |OnPageChange(const std::string&, const std::string&)|.
- virtual void OnPageChange(const std::string& key,
- fuchsia::mem::BufferPtr value);
-
- using PageWatcher::OnChangeCallback;
- // |PageWatcher|
- //
- // Derived classes may implement this method as needed. The default
- // implementation forwards individual changed keys to OnPageChange() and
- // OnPageDelete().
- void OnChange(fuchsia::ledger::PageChange page,
- fuchsia::ledger::ResultState result_state,
- OnChangeCallback callback) override;
-
- private:
- // Derived classes implement this method as needed. The default implementation
- // does nothing. This method is only called if forwarded from
- // |OnPageChange(const std::string&, fuchsia::mem::BufferPtr)|.
- virtual void OnPageChange(const std::string& key, const std::string& value);
- // Derived classes implement this method as needed. The default implementation
- // does nothing.
- virtual void OnPageDelete(const std::string& key);
-
- // Derived classes implement this method as needed. The default implementation
- // selects left and logs an INFO about the unresolved conflict.
- //
- // For now, only per-key conflict resolution is supported by page client. If
- // we need more coherency for conflict resolution, this can be changed.
- //
- // For now, conflict resolution is synchronous. Can be changed too, for
- // example to go on an OperationQueue to wait for ongoing changes to reconcile
- // with.
- //
- // If ConflictResolution is MERGE, the result is returned in merged*. It is
- // possible that the merge of two undeleted values is to the delete the key.
- //
- // This is invoked from the conflict resolver in LedgerClient.
- friend class LedgerClient;
- virtual void OnPageConflict(Conflict* conflict);
-
-
- fidl::Binding<fuchsia::ledger::PageWatcher> binding_;
- const std::string context_;
-
- LedgerClient* const ledger_client_;
- const fuchsia::ledger::PageId page_id_;
- fuchsia::ledger::Page* const page_;
- const std::string prefix_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageClient);
-};
-
-// Retrieves all entries from the given snapshot and calls the given callback
-// with the final status.
-//
-// The FIDL pointer backing |snapshot| must have the same life time as
-// |entries|, so that callbacks are cancelled when |entries| are deleted before
-// |callback| is invoked.
-void GetEntries(fuchsia::ledger::PageSnapshot* snapshot,
- std::vector<fuchsia::ledger::Entry>* entries,
- std::function<void(fuchsia::ledger::Status)> done);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_LEDGER_CLIENT_PAGE_CLIENT_H_
diff --git a/lib/ledger_client/page_client_unittest.cc b/lib/ledger_client/page_client_unittest.cc
deleted file mode 100644
index 43ac830..0000000
--- a/lib/ledger_client/page_client_unittest.cc
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/ledger_client/page_client.h"
-
-#include <memory>
-
-#include <lib/fxl/macros.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/testing/test_with_ledger.h"
-
-namespace modular {
-namespace testing {
-namespace {
-
-// NOTE(mesch): Test cases here take about 300ms when running in CI.
-// Occasionally they take much longer, presumably because of load on
-// shared machines. With the default timeout, we see flakiness. Cf.
-// FW-287.
-constexpr zx::duration kTimeout = zx::sec(10);
-
-class PageClientImpl : public PageClient {
- public:
- PageClientImpl(LedgerClient* ledger_client, LedgerPageId page_id,
- std::string prefix = "")
- : PageClient("PageClientImpl", ledger_client, std::move(page_id),
- std::move(prefix)) {}
-
- ~PageClientImpl() override = default;
-
- void OnPageChange(const std::string& key, const std::string& value) override {
- ++change_count_;
-
- values_[key] = value;
-
- FXL_LOG(INFO) << "OnPageChange \"" << prefix() << "\""
- << " " << change_count_ << " " << key << " " << value;
- }
-
- void SetConflictResolver(std::function<void(Conflict*)> conflict_resolver) {
- conflict_resolver_ = std::move(conflict_resolver);
- }
-
- void OnPageConflict(Conflict* const conflict) override {
- ++conflict_count_;
-
- FXL_LOG(INFO) << "OnPageConflict " << prefix() << " " << conflict_count_
- << " " << to_string(conflict->key) << " " << conflict->left
- << " " << conflict->right;
-
- conflict_resolver_(conflict);
- }
-
- int change_count() const { return change_count_; }
- int conflict_count() const { return conflict_count_; }
-
- bool has_value(const std::string& key) { return values_.count(key) > 0; }
- const std::string& value(const std::string& key) { return values_[key]; }
-
- private:
- std::map<std::string, std::string> values_;
- int change_count_{};
- int conflict_count_{};
-
- std::function<void(Conflict*)> conflict_resolver_;
-};
-
-class PageClientTest : public TestWithLedger {
- protected:
- PageClientTest() {}
-
- ~PageClientTest() = default;
-
- void SetUp() override {
- TestWithLedger::SetUp();
- // We only handle one conflict resolution per test case for now.
- ledger_client()->add_watcher([this] { resolved_ = true; });
- }
-
- void TearDown() override {
- page_clients_.clear();
- TestWithLedger::TearDown();
- }
-
- PageClientImpl* CreatePageClient(const std::string& page_id,
- const std::string& prefix = "") {
- auto page_client = std::make_unique<PageClientImpl>(
- ledger_client(), MakePageId(page_id), prefix);
- auto* ptr = page_client.get();
- page_clients_.emplace_back(std::move(page_client));
- return ptr;
- }
-
- fuchsia::ledger::PagePtr CreatePagePtr(const std::string& page_id) {
- fuchsia::ledger::PagePtr page;
- ledger_client()->ledger()->GetPage(
- std::make_unique<fuchsia::ledger::PageId>(MakePageId(page_id)),
- page.NewRequest(), [](fuchsia::ledger::Status status) {
- ASSERT_EQ(fuchsia::ledger::Status::OK, status);
- });
- return page;
- }
-
- // Factory for a ledger callback function that just logs errors.
- std::function<void(fuchsia::ledger::Status)> log(std::string context) {
- return [context](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status) << context;
- };
- }
-
- bool resolved() const { return resolved_; }
-
- private:
- // Storage for page clients created with CreatePageClient(). All will use the
- // same page connection since they are created with the same LedgerClient.
- std::vector<std::unique_ptr<PageClientImpl>> page_clients_;
-
- // Set to true when LedgerClient sees a change. This happens to co-occur with
- // when conflict resolution is done.
- bool resolved_{};
-
- FXL_DISALLOW_COPY_AND_ASSIGN(PageClientTest);
-};
-
-// This test is flaky. https://fuchsia.atlassian.net/browse/MI4-797
-TEST_F(PageClientTest, DISABLED_SimpleWriteObserve) {
- // Create a PageClient for a page, and write directly to it. We expect to see
- // the resulting change in the PageClient.
- auto client = CreatePageClient("page");
-
- client->page()->Put(to_array("key"), to_array("value"), log("Put"));
-
- RunLoopWithTimeoutOrUntil([&] { return client->value("key") == "value"; },
- kTimeout);
-
- EXPECT_EQ(0, client->conflict_count());
- EXPECT_EQ("value", client->value("key"));
-}
-
-TEST_F(PageClientTest, PrefixWriteObserve) {
- // Put two values, one for each of two prefixes. The two PageClients, being
- // configured to only look for each of those two prefixes, respectively,
- // should only be notified of the relevant keys when the values change.
- auto client_a = CreatePageClient("page", "a/");
- auto client_b = CreatePageClient("page", "b/");
-
- auto page = CreatePagePtr("page");
- page->Put(to_array("a/key"), to_array("value"), log("Put"));
- page->Put(to_array("b/key"), to_array("value"), log("Put"));
-
- RunLoopWithTimeoutOrUntil(
- [&] {
- return client_a->value("a/key") == "value" &&
- client_b->value("b/key") == "value";
- },
- kTimeout);
-
- EXPECT_EQ(0, client_a->conflict_count());
- EXPECT_EQ(0, client_b->conflict_count());
- EXPECT_EQ("value", client_a->value("a/key"));
- EXPECT_FALSE(client_a->has_value("b/key"));
- EXPECT_EQ("value", client_b->value("b/key"));
- EXPECT_FALSE(client_b->has_value("a/key"));
-}
-
-TEST_F(PageClientTest, ConcurrentWrite) {
- // Put two different values using two different PagePtr connections. We
- // should still see both of them in a PageClient looking at the same page.
- auto client = CreatePageClient("page");
-
- auto page1 = CreatePagePtr("page");
- auto page2 = CreatePagePtr("page");
- page1->Put(to_array("key1"), to_array("value1"), log("Put key1"));
- page2->Put(to_array("key2"), to_array("value2"), log("Put key2"));
-
- RunLoopWithTimeoutOrUntil(
- [&] {
- return client->value("key1") == "value1" &&
- client->value("key2") == "value2";
- },
- kTimeout);
-
- EXPECT_EQ(0, client->conflict_count());
- EXPECT_EQ("value1", client->value("key1"));
- EXPECT_EQ("value2", client->value("key2"));
-}
-
-TEST_F(PageClientTest, ConflictWrite) {
- // Write to the same key on two different PagePtrs, and set our PageClient to
- // resolve conflict by setting yet a third value.
- auto client = CreatePageClient("page");
- client->SetConflictResolver([](PageClient::Conflict* const conflict) {
- conflict->resolution = PageClient::MERGE;
- conflict->merged = "value3";
- });
-
- auto page1 = client->page();
- auto page2 = CreatePagePtr("page");
-
- bool finished{};
-
- page2->StartTransaction([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page2->Put(to_array("key"), to_array("value2"),
- [&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->StartTransaction([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->Put(
- to_array("key"), to_array("value1"),
- [&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page2->Commit([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->Commit([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- finished = true;
- });
- });
- });
- });
- });
- });
-
- RunLoopWithTimeoutOrUntil(
- [&] {
- return finished && resolved() && client->value("key") == "value3";
- },
- kTimeout);
-
- EXPECT_EQ(1, client->conflict_count());
- EXPECT_EQ("value3", client->value("key"));
-}
-
-TEST_F(PageClientTest, ConflictPrefixWrite) {
- // Same as above, but this time have two PageClients, each configured for a
- // different key prefix. Show that the correct one is used for conflict
- // resolution, and the other is not consulted at all.
- auto client_a = CreatePageClient("page", "a/");
- auto client_b = CreatePageClient("page", "b/");
- client_a->SetConflictResolver([](PageClient::Conflict* const conflict) {
- conflict->resolution = PageClient::MERGE;
- conflict->merged = "value3";
- });
-
- auto page1 = client_a->page();
- auto page2 = CreatePagePtr("page");
-
- bool finished{};
- page2->StartTransaction([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page2->Put(to_array("a/key"), to_array("value2"),
- [&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->StartTransaction([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->Put(
- to_array("a/key"), to_array("value1"),
- [&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page2->Commit([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->Commit([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- finished = true;
- });
- });
- });
- });
- });
- });
-
- RunLoopWithTimeoutOrUntil(
- [&] {
- return finished && resolved() && client_a->value("a/key") == "value3";
- },
- kTimeout);
-
- EXPECT_EQ(1, client_a->conflict_count());
- EXPECT_EQ(0, client_b->conflict_count());
- EXPECT_EQ("value3", client_a->value("a/key"));
- EXPECT_FALSE(client_b->has_value("a/key"));
-}
-
-TEST_F(PageClientTest, ConcurrentConflictWrite) {
- // Explicitly cause a conflict on one key, but not on other keys. We should
- // see the conflict resolve, but it should not affect the other keys at all.
- auto client = CreatePageClient("page");
- client->SetConflictResolver([](PageClient::Conflict* const conflict) {
- conflict->resolution = PageClient::MERGE;
- conflict->merged = "value3";
- });
-
- auto page1 = client->page();
- auto page2 = CreatePagePtr("page");
-
- bool finished{};
- page2->StartTransaction([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page2->Put(to_array("key2"), to_array("value2"), log("Put 2 key2"));
- page2->Put(
- to_array("key"), to_array("value2"),
- [&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->StartTransaction([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->Put(to_array("key1"), to_array("value1"), log("Put 1 key1"));
- page1->Put(to_array("key"), to_array("value1"),
- [&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page2->Commit([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- page1->Commit([&](fuchsia::ledger::Status status) {
- EXPECT_EQ(fuchsia::ledger::Status::OK, status);
- finished = true;
- });
- });
- });
- });
- });
- });
-
- RunLoopWithTimeoutOrUntil(
- [&] {
- return finished && resolved() && client->value("key") == "value3" &&
- client->value("key1") == "value1" &&
- client->value("key2") == "value2";
- },
- kTimeout);
-
- EXPECT_EQ(1, client->conflict_count());
- EXPECT_EQ("value1", client->value("key1"));
- EXPECT_EQ("value2", client->value("key2"));
- EXPECT_EQ("value3", client->value("key"));
-}
-
-} // namespace
-} // namespace testing
-} // namespace modular
diff --git a/lib/ledger_client/page_id.cc b/lib/ledger_client/page_id.cc
deleted file mode 100644
index c103263..0000000
--- a/lib/ledger_client/page_id.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/ledger_client/page_id.h"
-
-namespace modular {
-
-fuchsia::ledger::PageId MakePageId(const std::string& value) {
- fuchsia::ledger::PageId page_id;
- memset(page_id.id.mutable_data(), 0, page_id.id.count());
- size_t size = std::min(value.length(), page_id.id.count());
- memcpy(page_id.id.mutable_data(), value.data(), size);
- return page_id;
-}
-
-} // namespace modular
diff --git a/lib/ledger_client/page_id.h b/lib/ledger_client/page_id.h
deleted file mode 100644
index 43cd5ea..0000000
--- a/lib/ledger_client/page_id.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_LEDGER_CLIENT_PAGE_ID_H_
-#define PERIDOT_LIB_LEDGER_CLIENT_PAGE_ID_H_
-
-#include <string>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-
-namespace modular {
-
-// Creates a page ID from an equivalent |std::string|.
-//
-// Caveat: This along with |fuchsia::modular::to_string| should not be used for
-// JSON serialization of arbitrary page IDs as JSON string encoding involves a
-// potentially non-invertible UTF-8 encoding. Instead, use |PageIdFromBase64|
-// and |PageIdToBase64|.
-fuchsia::ledger::PageId MakePageId(const std::string& value);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_LEDGER_CLIENT_PAGE_ID_H_
diff --git a/lib/ledger_client/promise.h b/lib/ledger_client/promise.h
deleted file mode 100644
index 6cf14d6..0000000
--- a/lib/ledger_client/promise.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <lib/fit/bridge.h>
-#include <lib/fit/promise.h>
-
-#include "peridot/lib/fidl/array_to_string.h" // for to_string(), to_array()
-
-namespace modular {
-
-// These wrapper functions wrap fuchsia.ledger APIs such that they return
-// a fit::promise<> representing the result of the call. They are useful to
-// incorporate into tasks themselves expressed as fit::promises.
-//
-// The wrapper classes act as namespaces for static methods. For a given api
-// (such as fuchsia.ledger.Page), the wrapper class is called PagePromise, and
-// each method has the same signature as that in fuchsia::ledger::Page, with the
-// addition that the first parameter is always a fuchsia::ledger::Page* and the
-// last parameter (the result callback) is omitted.
-//
-// Note that these wrapper methods IMMEDIATELY call the underlying FIDL
-// function (meaning that a message is dispatched immediately on the underlying
-// channel). The returned promise will block until a response message is
-// received.
-//
-// EXAMPLE
-//
-// auto p = fit::make_promise([snapshot = page_snapshot_ptr.get()] () {
-// return PageSnapshotPromise::GetInline(snapshot, key);
-// }).and_then([] (const std::vector<uint8_t> bytes) {
-// // Decode and use |bytes|.
-// });
-
-// fit::promise wrapper functions for fuchsia.ledger.Page.
-class PagePromise {
- public:
- static fit::promise<> StartTransaction(fuchsia::ledger::Page* page) {
- fit::bridge<> bridge;
- page->StartTransaction([completer = std::move(bridge.completer)](
- fuchsia::ledger::Status status) mutable {
- if (status == fuchsia::ledger::Status::OK) {
- completer.complete_ok();
- } else {
- completer.complete_error();
- }
- });
- return bridge.consumer.promise();
- }
-
- static fit::promise<> Commit(fuchsia::ledger::Page* page) {
- fit::bridge<> bridge;
- page->Commit([completer = std::move(bridge.completer)](
- fuchsia::ledger::Status status) mutable {
- if (status == fuchsia::ledger::Status::OK) {
- completer.complete_ok();
- } else {
- completer.complete_error();
- }
- });
- return bridge.consumer.promise();
- }
-
- static fit::promise<> Rollback(fuchsia::ledger::Page* page) {
- fit::bridge<> bridge;
- page->Commit([completer = std::move(bridge.completer)](
- fuchsia::ledger::Status status) mutable {
- if (status == fuchsia::ledger::Status::OK) {
- completer.complete_ok();
- } else {
- completer.complete_error();
- }
- });
- return bridge.consumer.promise();
- }
-
- static fit::promise<> GetSnapshot(
- fuchsia::ledger::Page* page,
- fidl::InterfaceRequest<fuchsia::ledger::PageSnapshot> request) {
- fit::bridge<> bridge;
- page->GetSnapshot(std::move(request),
- fidl::VectorPtr<uint8_t>::New(0) /* key_prefix */,
- nullptr /* watcher */,
- [completer = std::move(bridge.completer)](
- fuchsia::ledger::Status status) mutable {
- if (status == fuchsia::ledger::Status::OK) {
- completer.complete_ok();
- } else {
- completer.complete_error();
- }
- });
- return bridge.consumer.promise();
- }
-
- static fit::promise<> Put(fuchsia::ledger::Page* page, std::string key,
- std::vector<uint8_t> value) {
- fit::bridge<> bridge;
- page->Put(to_array(key), fidl::VectorPtr<uint8_t>(std::move(value)),
- [completer = std::move(bridge.completer)](
- fuchsia::ledger::Status status) mutable {
- if (status == fuchsia::ledger::Status::OK) {
- completer.complete_ok();
- } else {
- completer.complete_error();
- }
- });
- return bridge.consumer.promise();
- }
-};
-
-// fit::promise wrapper functions for fuchsia.ledger.Page.
-//
-// These methods match the signatures in fuchsia.ledger.Page with the exception
-// that the first parameter is always a fuchsia::ledger::Page*.
-class PageSnapshotPromise {
- public:
- // fit::promise wrapper function for PageSnapshot.GetInline().
- //
- // Falls back to PageSnapshot::Get() if the value is too large.
- // TODO(thatguy): Implement the fallback.
- static fit::promise<std::unique_ptr<std::vector<uint8_t>>> GetInline(
- fuchsia::ledger::PageSnapshot* snapshot, std::string key) {
- fit::bridge<std::unique_ptr<std::vector<uint8_t>>> bridge;
- snapshot->GetInline(
- to_array(key), [completer = std::move(bridge.completer)](
- fuchsia::ledger::Status status,
- fuchsia::ledger::InlinedValuePtr value) mutable {
- switch (status) {
- case fuchsia::ledger::Status::OK:
- case fuchsia::ledger::Status::KEY_NOT_FOUND:
- if (value) {
- // Convert the result to a unique_ptr instead of a VectorPtr.
- auto ret =
- std::make_unique<std::vector<uint8_t>>(value->value);
- completer.complete_ok(std::move(ret));
- } else {
- completer.complete_ok(nullptr);
- }
- break;
- case fuchsia::ledger::Status::VALUE_TOO_LARGE:
- // TODO(thatguy): Handle a too-large value.
- FXL_LOG(FATAL) << "TODO: fallback to PageSnapshot_Get().";
- default:
- FXL_LOG(ERROR) << "PageSnapshotPromise::GetInline() failed with "
- << fidl::ToUnderlying(status);
- completer.complete_error();
- }
- });
- return bridge.consumer.promise();
- }
-};
-
-} // namespace modular
diff --git a/lib/ledger_client/status.cc b/lib/ledger_client/status.cc
deleted file mode 100644
index b79f223..0000000
--- a/lib/ledger_client/status.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/ledger_client/status.h"
-
-#include <string>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <lib/fxl/logging.h>
-#include <zircon/status.h>
-
-namespace modular {
-
-std::string LedgerStatusToString(fuchsia::ledger::Status status) {
- switch (status) {
- case fuchsia::ledger::Status::OK:
- return "OK";
- case fuchsia::ledger::Status::PARTIAL_RESULT:
- return "PARTIAL_RESULT";
- case fuchsia::ledger::Status::INVALID_TOKEN:
- return "INVALID_TOKEN";
- case fuchsia::ledger::Status::INVALID_ARGUMENT:
- return "INVALID_ARGUMENT";
- case fuchsia::ledger::Status::PAGE_NOT_FOUND:
- return "PAGE_NOT_FOUND";
- case fuchsia::ledger::Status::KEY_NOT_FOUND:
- return "KEY_NOT_FOUND";
- case fuchsia::ledger::Status::REFERENCE_NOT_FOUND:
- return "REFERENCE_NOT_FOUND";
- case fuchsia::ledger::Status::NEEDS_FETCH:
- return "NEEDS_FETCH";
- case fuchsia::ledger::Status::IO_ERROR:
- return "IO_ERROR";
- case fuchsia::ledger::Status::NETWORK_ERROR:
- return "NETWORK_ERROR";
- case fuchsia::ledger::Status::TRANSACTION_ALREADY_IN_PROGRESS:
- return "TRANSACTION_ALREADY_IN_PROGRESS";
- case fuchsia::ledger::Status::NO_TRANSACTION_IN_PROGRESS:
- return "NO_TRANSACTION_IN_PROGRESS";
- case fuchsia::ledger::Status::INTERNAL_ERROR:
- return "INTERNAL_ERROR";
- case fuchsia::ledger::Status::VALUE_TOO_LARGE:
- return "VALUE_TOO_LARGE";
- case fuchsia::ledger::Status::ILLEGAL_STATE:
- return "ILLEGAL_STATE";
- case fuchsia::ledger::Status::UNKNOWN_ERROR:
- return "UNKNOWN_ERROR";
- }
-};
-
-std::string LedgerEpitaphToString(zx_status_t status) {
- if (status > 0) {
- return LedgerStatusToString(static_cast<fuchsia::ledger::Status>(status));
- }
- return zx_status_get_string(status);
-}
-
-} // namespace modular
diff --git a/lib/ledger_client/status.h b/lib/ledger_client/status.h
deleted file mode 100644
index 8b4dbe1..0000000
--- a/lib/ledger_client/status.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_LEDGER_CLIENT_STATUS_H_
-#define PERIDOT_LIB_LEDGER_CLIENT_STATUS_H_
-
-#include <string>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-
-namespace modular {
-
-std::string LedgerStatusToString(fuchsia::ledger::Status status);
-std::string LedgerEpitaphToString(zx_status_t status);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_LEDGER_CLIENT_STATUS_H_
diff --git a/lib/ledger_client/types.h b/lib/ledger_client/types.h
deleted file mode 100644
index e5919df..0000000
--- a/lib/ledger_client/types.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_LEDGER_CLIENT_TYPES_H_
-#define PERIDOT_LIB_LEDGER_CLIENT_TYPES_H_
-
-#include <algorithm>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <lib/fidl/cpp/array.h>
-#include <lib/fidl/cpp/vector.h>
-
-namespace modular {
-
-using LedgerPageId = fuchsia::ledger::PageId;
-using LedgerPageKey = fidl::VectorPtr<uint8_t>;
-using LedgerToken = std::unique_ptr<fuchsia::ledger::Token>;
-
-inline bool PageIdsEqual(const LedgerPageId& a, const LedgerPageId& b) {
- return a.id == b.id;
-}
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_LEDGER_CLIENT_TYPES_H_
diff --git a/lib/module_manifest/BUILD.gn b/lib/module_manifest/BUILD.gn
deleted file mode 100644
index 8f6f701..0000000
--- a/lib/module_manifest/BUILD.gn
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("module_manifest") {
- public_deps = [
- ":json_xdr",
- ]
-}
-
-group("unittests") {
- testonly = true
-
- deps = [
- ":module_facet_reader_impl_unittest",
- ":module_manifest_xdr_unittest",
- ]
-}
-
-source_set("module_facet_reader") {
- sources = [
- "module_facet_reader.h",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("module_facet_reader_impl") {
- sources = [
- "module_facet_reader_impl.cc",
- "module_facet_reader_impl.h",
- ]
-
- deps = [
- ":json_xdr",
- ":module_facet_reader",
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/lib/cmx_facet_parser",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/json",
- "//garnet/public/lib/pkg_url",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("module_facet_reader_impl_unittest") {
- testonly = true
-
- sources = [
- "module_facet_reader_impl_unittest.cc",
- ]
-
- deps = [
- ":module_facet_reader_impl",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//peridot/lib/scoped_tmpfs",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/googletest:gtest",
- ]
-}
-
-source_set("json_xdr") {
- sources = [
- "module_manifest_xdr.cc",
- "module_manifest_xdr.h",
- ]
-
- deps = [
- "//peridot/lib/fidl:json_xdr",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("module_manifest_xdr_unittest") {
- testonly = true
-
- sources = [
- "module_manifest_xdr_unittest.cc",
- ]
-
- deps = [
- ":json_xdr",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/module_manifest/module_facet_reader.h b/lib/module_manifest/module_facet_reader.h
deleted file mode 100644
index 0e99672..0000000
--- a/lib/module_manifest/module_facet_reader.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_MODULE_MANIFEST_MODULE_FACET_READER_H_
-#define PERIDOT_LIB_MODULE_MANIFEST_MODULE_FACET_READER_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace modular {
-
-// |ModuleFacetReader| provides a way to read the the module facet declared in
-// a module's component manifest.
-class ModuleFacetReader {
- public:
- // Given a module URL, returns the |fuchsia.modular.ModuleManifestPtr|
- // declared in the module's component manifest. A null |manifest| is returned
- // if the module does not have a module facet declared.
- using GetModuleManifestCallback =
- std::function<void(fuchsia::modular::ModuleManifestPtr manifest)>;
- virtual void GetModuleManifest(const std::string& module_url,
- GetModuleManifestCallback callback) = 0;
-
- virtual ~ModuleFacetReader() = default;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_MODULE_MANIFEST_MODULE_FACET_READER_H_
diff --git a/lib/module_manifest/module_facet_reader_impl.cc b/lib/module_manifest/module_facet_reader_impl.cc
deleted file mode 100644
index 8732c03..0000000
--- a/lib/module_manifest/module_facet_reader_impl.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest/module_facet_reader_impl.h"
-
-#include "lib/cmx_facet_parser/cmx_facet_parser.h"
-#include "lib/component/cpp/startup_context.h"
-#include "lib/fsl/io/fd.h"
-#include "lib/json/json_parser.h"
-#include "lib/pkg_url/fuchsia_pkg_url.h"
-#include "lib/pkg_url/url_resolver.h"
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/module_manifest/module_manifest_xdr.h"
-
-namespace modular {
-namespace {
-
-constexpr char kModuleFacetName[] = "fuchsia.module";
-
-} // namespace
-
-ModuleFacetReaderImpl::ModuleFacetReaderImpl(fuchsia::sys::LoaderPtr loader)
- : loader_(std::move(loader)) {}
-
-ModuleFacetReaderImpl::~ModuleFacetReaderImpl() {}
-
-void ModuleFacetReaderImpl::GetModuleManifest(
- const std::string& module_url, GetModuleManifestCallback callback) {
- auto canonical_url = component::CanonicalizeURL(module_url);
- loader_->LoadUrl(canonical_url, [canonical_url,
- callback](fuchsia::sys::PackagePtr package) {
- if (!package) {
- FXL_LOG(ERROR) << "Could not resolve URL: " << canonical_url;
- callback({});
- return;
- }
- fxl::UniqueFD fd =
- fsl::OpenChannelAsFileDescriptor(std::move(package->directory));
-
- component::FuchsiaPkgUrl pkg_url;
- std::string cmx_path;
- if (pkg_url.Parse(package->resolved_url)) {
- if (!pkg_url.resource_path().empty()) {
- // If the url has a resource, assume that's the cmx.
- cmx_path = pkg_url.resource_path();
- } else {
- // It's possible the url does not have a resource, in which case either
- // the cmx exists at meta/<package_name.cmx> or it does not exist.
- cmx_path = pkg_url.GetDefaultComponentCmxPath();
- }
- } else {
- FXL_LOG(ERROR) << "Could not parse package URL: "
- << package->resolved_url;
- callback({});
- }
-
- component::CmxFacetParser facet_parser;
- json::JSONParser json_parser;
- if (!facet_parser.ParseFromFileAt(fd.get(), cmx_path, &json_parser)) {
- FXL_LOG(ERROR) << "Could not parse CMX manifest " << cmx_path << ": "
- << json_parser.error_str();
- callback({});
- return;
- }
-
- const auto& mod_facet = facet_parser.GetSection(kModuleFacetName);
- if (mod_facet.IsNull()) {
- FXL_LOG(INFO) << "No module facet declared for module="
- << package->resolved_url;
- callback({});
- return;
- }
-
- fuchsia::modular::ModuleManifestPtr module_manifest;
- auto mod_facet_str = JsonValueToString(mod_facet);
- if (!XdrRead(mod_facet_str, &module_manifest, XdrModuleManifest)) {
- FXL_LOG(WARNING) << "Unable to parse manifest module facet for "
- << package->resolved_url << ": " << mod_facet_str;
- callback({});
- return;
- }
- // TODO(MF-94): Deprecate ModuleManfiest.binary in favour of getting it from
- // the cmx manifest.
- module_manifest->binary = canonical_url;
- callback(std::move(module_manifest));
- });
-}
-
-} // namespace modular
diff --git a/lib/module_manifest/module_facet_reader_impl.h b/lib/module_manifest/module_facet_reader_impl.h
deleted file mode 100644
index 23d8faa..0000000
--- a/lib/module_manifest/module_facet_reader_impl.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_MODULE_MANIFEST_MODULE_FACET_READER_IMPL_H_
-#define PERIDOT_LIB_MODULE_MANIFEST_MODULE_FACET_READER_IMPL_H_
-
-#include <fuchsia/sys/cpp/fidl.h>
-
-#include "lib/fxl/macros.h"
-#include "peridot/lib/module_manifest/module_facet_reader.h"
-
-namespace modular {
-
-class ModuleFacetReaderImpl : public ModuleFacetReader {
- public:
- // This ModuleFacetReader implementation uses the fuchsia.sys.Loader interface
- // to retreive information for where the module facet is located.
- explicit ModuleFacetReaderImpl(fuchsia::sys::LoaderPtr loader);
- ~ModuleFacetReaderImpl() override;
-
- private:
- void GetModuleManifest(const std::string& module_url,
- GetModuleManifestCallback callback) override;
-
- fuchsia::sys::LoaderPtr loader_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ModuleFacetReaderImpl);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_MODULE_MANIFEST_MODULE_FACET_READER_IMPL_H_
diff --git a/lib/module_manifest/module_facet_reader_impl_unittest.cc b/lib/module_manifest/module_facet_reader_impl_unittest.cc
deleted file mode 100644
index 840bcd5..0000000
--- a/lib/module_manifest/module_facet_reader_impl_unittest.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest/module_facet_reader_impl.h"
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <map>
-#include <string>
-
-#include "gtest/gtest.h"
-#include "lib/fidl/cpp/binding.h"
-#include "lib/fsl/io/fd.h"
-#include "lib/fxl/files/directory.h"
-#include "lib/fxl/files/file.h"
-#include "lib/fxl/files/path.h"
-#include "lib/fxl/files/unique_fd.h"
-#include "lib/fxl/strings/substitute.h"
-#include "lib/gtest/real_loop_fixture.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace {
-
-// A utility class for making a static filesystem. Use |AddFile| to populate the
-// file system with (file path, file content)s.
-class FilesystemForTest {
- public:
- // Returns an opened file descriptor for |dir|. |dir| must be an absolute
- // path.
- zx::channel GetChannelForDir(fxl::StringView dir) {
- std::string dir_str = ToRelativePath(dir);
- FXL_CHECK(files::IsDirectoryAt(tmpfs_.root_fd(), dir_str));
-
- int fd = openat(tmpfs_.root_fd(), dir_str.data(), O_DIRECTORY);
- FXL_CHECK(fd != -1);
-
- auto ch = fsl::CloneChannelFromFileDescriptor(fd);
- close(fd);
- return ch;
- }
-
- // Adds a file to the filesystem. |path| must be an absolute path representing
- // a file. |data| contains the file contents. Intermediate directories
- // required for |path| exist are created as needed.
- void AddFile(fxl::StringView path, const std::string& data) {
- std::string path_str = ToRelativePath(path);
- FXL_CHECK(files::CreateDirectoryAt(tmpfs_.root_fd(),
- files::GetDirectoryName(path_str)));
- FXL_CHECK(files::WriteFileAt(tmpfs_.root_fd(), path_str, data.data(),
- data.size()));
- }
-
- private:
- std::string ToRelativePath(fxl::StringView path) {
- if (path[0] == '/') {
- return path.substr(1).ToString();
- }
- return path.ToString();
- }
-
- // In-memory file system.
- scoped_tmpfs::ScopedTmpFS tmpfs_;
-};
-
-// A Loader used for testing. Use |AddLoadInfo()| to pre-populate answers to
-// |fuchsia.sys.Loader.LoadUrl()| requests. Because directories are not
-// trivially clonable, |AddLoadInfo(url,..)| is only able to serve one
-// |fuchsia.sys.Loader.LoadUrl(url)|.
-class SysLoaderForTest : fuchsia::sys::Loader {
- public:
- SysLoaderForTest() : binding_(this) {}
-
- // Returns a fuchsia::sys::LoaderPtr that returns one-shot answers that were
- // added from |AddLoadInfo|.
- fuchsia::sys::LoaderPtr NewEndpoint() {
- fuchsia::sys::LoaderPtr loader;
- binding_.Bind(loader.NewRequest());
- return loader;
- }
-
- // Populate a one-shot answer to |fuchsia.sys.Loader.LoadUrl|; that is,
- // LoadUrl() will not be able to answer for |url| a second time unless
- // |AddLoadInfo| is called again.
- void AddLoadInfo(fidl::StringPtr url, fuchsia::sys::PackagePtr pkg) {
- if (url->find("//") == std::string::npos) {
- url = fxl::Substitute("file://$0", url.get());
- }
- load_info_[url.get()] = std::move(pkg);
- }
-
- private:
- // |fuchsia::sys::Loader|
- void LoadUrl(std::string url, LoadUrlCallback cb) {
- if (load_info_.find(url) != load_info_.end()) {
- auto retval = std::move(load_info_[url]);
- load_info_.erase(url);
-
- cb(std::move(retval));
- } else {
- cb({});
- }
- }
-
- std::map<std::string, fuchsia::sys::PackagePtr> load_info_;
- fidl::Binding<fuchsia::sys::Loader> binding_;
-};
-
-} // namespace
-
-class ModuleFacetReaderImplTest : public gtest::RealLoopFixture {
- protected:
- ModuleFacetReaderImplTest()
- : module_facet_reader_impl_(sys_loader_.NewEndpoint()) {}
-
- static constexpr char kNoFacet[] = R"({})";
- static constexpr char kBasicFacet[] = R"(
- {
- "facets": {
- "fuchsia.module":{
- "@version":2,
- "binary":"binary",
- "suggestion_headline":"suggestion_headline",
- "intent_filters":[
- {
- "action":"action",
- "parameters":[
- {
- "name":"name",
- "type":"type"
- }
- ]
- }
- ]
- }
- }
- }
- )";
-
- modular::ModuleFacetReader* module_facet_reader() {
- return &module_facet_reader_impl_;
- }
-
- // Populates a one-shot answer for fuchsia::sys::Loader used by
- // ModuleFacetReaderImpl::GetModuleFacet()
- void PopulateModFacetFromPkgUrl(fxl::StringView mod_pkg_name,
- fxl::StringView mod_cmx_data) {
- fs_.AddFile(fxl::Substitute("/$0/meta/$0.cmx", mod_pkg_name),
- mod_cmx_data.data());
- auto pkg = fuchsia::sys::Package::New();
- pkg->resolved_url = fxl::Substitute(
- "fuchsia-pkg://fuchsia.com/$0#meta/$0.cmx", mod_pkg_name);
- pkg->directory = fs_.GetChannelForDir(mod_pkg_name);
- sys_loader_.AddLoadInfo(mod_pkg_name.ToString(), std::move(pkg));
- }
-
- // Populates a one-shot answer for fuchsia::sys::Loader used by
- // ModuleFacetReaderImpl::GetModuleFacet()
- void PopulateModFacetFromComponentUrl(fxl::StringView mod_pkg_name,
- fxl::StringView mod_component_name,
- fxl::StringView mod_cmx_data) {
- fs_.AddFile(
- fxl::Substitute("/$0/meta/$1.cmx", mod_pkg_name, mod_component_name),
- mod_cmx_data.data());
- auto pkg = fuchsia::sys::Package::New();
- pkg->resolved_url =
- fxl::Substitute("fuchsia-pkg://fuchsia.com/$0#meta/$1.cmx",
- mod_pkg_name, mod_component_name);
- pkg->directory = fs_.GetChannelForDir(mod_pkg_name);
- sys_loader_.AddLoadInfo(
- fxl::Substitute("fuchsia-pkg://fuchsia.com/$0#meta/$1.cmx",
- mod_pkg_name, mod_component_name),
- std::move(pkg));
- }
-
- private:
- FilesystemForTest fs_;
- SysLoaderForTest sys_loader_;
- modular::ModuleFacetReaderImpl module_facet_reader_impl_;
-};
-
-TEST_F(ModuleFacetReaderImplTest, ModFacetFoundFromPkgUrl) {
- constexpr char kModName[] = "my_mod_url";
- PopulateModFacetFromPkgUrl(kModName, kBasicFacet);
-
- bool done = false;
- module_facet_reader()->GetModuleManifest(
- kModName, [&done](fuchsia::modular::ModuleManifestPtr manifest) {
- EXPECT_TRUE(manifest);
- EXPECT_EQ("file://my_mod_url", manifest->binary);
- EXPECT_EQ("suggestion_headline", manifest->suggestion_headline);
- EXPECT_EQ(1u, manifest->intent_filters->size());
- done = true;
- });
- RunLoopUntil([&done] { return done; });
- EXPECT_TRUE(done);
-}
-
-TEST_F(ModuleFacetReaderImplTest, ModFacetFoundFromComponentUrl) {
- constexpr char kPkgName[] = "my_pkg_name";
- constexpr char kModName[] = "my_mod_name";
- PopulateModFacetFromComponentUrl(kPkgName, kModName, kBasicFacet);
-
- bool done = false;
- module_facet_reader()->GetModuleManifest(
- fxl::Substitute("fuchsia-pkg://fuchsia.com/$0#meta/$1.cmx", kPkgName,
- kModName),
- [&done](fuchsia::modular::ModuleManifestPtr manifest) {
- EXPECT_TRUE(manifest);
- EXPECT_EQ("fuchsia-pkg://fuchsia.com/my_pkg_name#meta/my_mod_name.cmx",
- manifest->binary);
- EXPECT_EQ("suggestion_headline", manifest->suggestion_headline);
- EXPECT_EQ(1u, manifest->intent_filters->size());
- done = true;
- });
- RunLoopUntil([&done] { return done; });
- EXPECT_TRUE(done);
-}
-
-TEST_F(ModuleFacetReaderImplTest, ModHasNoFacet) {
- constexpr char kModName[] = "my_mod_url";
- PopulateModFacetFromPkgUrl(kModName, kNoFacet);
- bool done = false;
- module_facet_reader()->GetModuleManifest(
- kModName, [&done](fuchsia::modular::ModuleManifestPtr manifest) {
- EXPECT_FALSE(manifest);
- done = true;
- });
- RunLoopUntil([&done] { return done; });
- EXPECT_TRUE(done);
-}
-
-TEST_F(ModuleFacetReaderImplTest, ModDoesntExist) {
- bool done = false;
- module_facet_reader()->GetModuleManifest(
- "kajsdhf", [&done](fuchsia::modular::ModuleManifestPtr manifest) {
- EXPECT_FALSE(manifest);
- done = true;
- });
- RunLoopUntil([&done] { return done; });
- EXPECT_TRUE(done);
-}
diff --git a/lib/module_manifest/module_manifest_xdr.cc b/lib/module_manifest/module_manifest_xdr.cc
deleted file mode 100644
index ad67166..0000000
--- a/lib/module_manifest/module_manifest_xdr.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest/module_manifest_xdr.h"
-
-namespace modular {
-namespace {
-
-void XdrParameterConstraint(XdrContext* const xdr,
- fuchsia::modular::ParameterConstraint* const data) {
- xdr->Field("name", &data->name);
- xdr->Field("type", &data->type);
-}
-
-void XdrModuleManifestIntentFilters(
- XdrContext* const xdr, fuchsia::modular::IntentFilter* const data) {
- xdr->Field("action", &data->action);
- xdr->Field("parameters", &data->parameter_constraints,
- XdrParameterConstraint);
-}
-
-} // namespace
-
-void XdrModuleManifest_v1(XdrContext* const xdr,
- fuchsia::modular::ModuleManifest* const data) {
- xdr->Field("binary", &data->binary);
- xdr->Field("suggestion_headline", &data->suggestion_headline);
- xdr->Field("composition_pattern", &data->composition_pattern);
-
- // Version 2 supports multiple actions using the "intent_filters" field. This
- // version supports just one with "action" and "parameters" fields, so we
- // put those in "IntentFilter[0]".
- data->intent_filters->resize(1);
- xdr->Field("action", &data->intent_filters->at(0).action);
- xdr->Field("parameters", &data->intent_filters->at(0).parameter_constraints,
- XdrParameterConstraint);
-}
-
-void XdrModuleManifest_v2(XdrContext* const xdr,
- fuchsia::modular::ModuleManifest* const data) {
- if (!xdr->Version(2)) {
- return;
- }
- xdr->Field("binary", &data->binary);
- xdr->Field("suggestion_headline", &data->suggestion_headline);
- xdr->Field("composition_pattern", &data->composition_pattern);
- xdr->Field("intent_filters", &data->intent_filters,
- XdrModuleManifestIntentFilters);
- xdr->Field("placeholder_color", &data->placeholder_color);
-}
-
-// New nullable fields may be added to latest version (i.e., no need to do a
-// version bump). Removing old fields needs a new version, in which case all xdr
-// filter for previous versions should be updated to provide a polyfill.
-extern const XdrFilterType<fuchsia::modular::ModuleManifest>
- XdrModuleManifest[] = {
- XdrModuleManifest_v2,
- XdrModuleManifest_v1,
- nullptr,
-};
-
-} // namespace modular
diff --git a/lib/module_manifest/module_manifest_xdr.h b/lib/module_manifest/module_manifest_xdr.h
deleted file mode 100644
index 019e1a7..0000000
--- a/lib/module_manifest/module_manifest_xdr.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_MODULE_MANIFEST_MODULE_MANIFEST_XDR_H_
-#define PERIDOT_LIB_MODULE_MANIFEST_MODULE_MANIFEST_XDR_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/lib/fidl/json_xdr.h"
-
-namespace modular {
-
-extern const XdrFilterType<fuchsia::modular::ModuleManifest>
- XdrModuleManifest[];
-
-void XdrModuleManifest_v1(XdrContext* const xdr,
- fuchsia::modular::ModuleManifest* const data);
-
-void XdrModuleManifest_v2(XdrContext* const xdr,
- fuchsia::modular::ModuleManifest* const data);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_MODULE_MANIFEST_MODULE_MANIFEST_XDR_H_
diff --git a/lib/module_manifest/module_manifest_xdr_unittest.cc b/lib/module_manifest/module_manifest_xdr_unittest.cc
deleted file mode 100644
index 3566c76..0000000
--- a/lib/module_manifest/module_manifest_xdr_unittest.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest/module_manifest_xdr.h"
-
-#include "gtest/gtest.h"
-#include "peridot/lib/fidl/json_xdr.h"
-
-void ExpectBasicManifest(const char manifest_str[]) {
- fuchsia::modular::ModuleManifest m;
- EXPECT_TRUE(XdrRead(manifest_str, &m, modular::XdrModuleManifest));
- EXPECT_EQ("binary", m.binary);
- EXPECT_EQ("suggestion_headline", m.suggestion_headline);
-
- EXPECT_EQ(1u, m.intent_filters->size());
- EXPECT_EQ(1u, m.intent_filters->at(0).parameter_constraints.size());
- EXPECT_EQ("name", m.intent_filters->at(0).parameter_constraints.at(0).name);
- EXPECT_EQ("type", m.intent_filters->at(0).parameter_constraints.at(0).type);
-}
-
-// Tests version 4 of the manifest
-TEST(XdrModuleManifestTest, BasicVersion2) {
- ExpectBasicManifest(R"(
- {
- "@version": 2,
- "binary": "binary",
- "suggestion_headline": "suggestion_headline",
- "intent_filters": [
- {
- "action": "action",
- "parameters": [{
- "name": "name",
- "type": "type"
- }]
- }
- ]
- }
- )");
-}
-
-TEST(XdrModuleManifestTest, BasicVersion1) {
- ExpectBasicManifest(R"(
- {
- "binary": "binary",
- "suggestion_headline": "suggestion_headline",
- "action": "action",
- "parameters": [{
- "name": "name",
- "type": "type"
- }]
- }
- )");
-}
diff --git a/lib/module_manifest_source/BUILD.gn b/lib/module_manifest_source/BUILD.gn
deleted file mode 100644
index d055c93..0000000
--- a/lib/module_manifest_source/BUILD.gn
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("module_manifest_source") {
- sources = [
- "module_manifest_source.cc",
- "module_manifest_source.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("json") {
- sources = [
- "json.cc",
- "json.h",
- ]
-
- deps = [
- ":module_manifest_source",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/module_manifest:json_xdr",
- "//peridot/lib/rapidjson",
- "//third_party/rapidjson",
- ]
-}
-
-source_set("firebase_source") {
- sources = [
- "firebase_source.cc",
- "firebase_source.h",
- ]
-
- public_deps = [
- ":module_manifest_source",
- "//garnet/public/fidl/fuchsia.net.oldhttp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:json_xdr",
- "//peridot/lib/firebase",
- "//peridot/lib/module_manifest:json_xdr",
- "//third_party/rapidjson",
- ]
-}
-
-source_set("package_util") {
- sources = [
- "package_util.cc",
- "package_util.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("module_package_source") {
- sources = [
- "module_package_source.cc",
- "module_package_source.h",
- ]
-
- public_deps = [
- ":json",
- ":module_manifest_source",
- ":package_util",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib:maxwell_internal",
- ]
-}
diff --git a/lib/module_manifest_source/fidl/module_package_indexer.fidl b/lib/module_manifest_source/fidl/module_package_indexer.fidl
deleted file mode 100644
index 0c8bad6..0000000
--- a/lib/module_manifest_source/fidl/module_package_indexer.fidl
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.maxwell.internal;
-
-[Discoverable]
-interface ModulePackageIndexer {
- 1: IndexManifest(string package_name, string module_manifest_path);
-};
diff --git a/lib/module_manifest_source/firebase_source.cc b/lib/module_manifest_source/firebase_source.cc
deleted file mode 100644
index fe8510c..0000000
--- a/lib/module_manifest_source/firebase_source.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest_source/firebase_source.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <thread>
-
-#include <lib/async/cpp/task.h>
-#include <lib/backoff/exponential_backoff.h>
-#include <lib/fdio/watcher.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/network_wrapper/network_wrapper_impl.h>
-
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/firebase/firebase_impl.h"
-#include "peridot/lib/module_manifest/module_manifest_xdr.h"
-#include "rapidjson/document.h"
-
-namespace modular {
-
-namespace http = ::fuchsia::net::oldhttp;
-
-class FirebaseModuleManifestSource::Watcher : public firebase::WatchClient {
- public:
- Watcher(async_dispatcher_t* dispatcher, ModuleManifestSource::IdleFn idle_fn,
- ModuleManifestSource::NewEntryFn new_fn,
- ModuleManifestSource::RemovedEntryFn removed_fn,
- fxl::WeakPtr<FirebaseModuleManifestSource> owner)
- : dispatcher_(dispatcher),
- idle_fn_(idle_fn),
- new_fn_(new_fn),
- removed_fn_(removed_fn),
- reconnect_wait_seconds_(0),
- owner_(owner) {}
- ~Watcher() override = default;
-
- private:
- void OnPut(const std::string& path, const rapidjson::Value& value) override {
- // Successful connection established. Reset our reconnect counter.
- reconnect_wait_seconds_ = 0;
-
- // The first time we're called, we get a dump of all existing values as a
- // JSON object at path "/".
- //
- // From then on, we get notifications of individual values changing with
- // paths like "/module-id".
- if (path == "/") {
- if (value.IsNull()) {
- idle_fn_();
- return;
- }
-
- if (!value.IsObject()) {
- FXL_LOG(ERROR) << "Got update at /, but it's not a JSON object??";
- idle_fn_();
- return;
- }
-
- for (rapidjson::Value::ConstMemberIterator it = value.MemberBegin();
- it != value.MemberEnd(); ++it) {
- // When we get updates, the path is "/<module id>", so we add "/" here
- // to the member name.
- ProcessEntry(path + it->name.GetString(), it->value);
- }
-
- // We've read all existing entries.
- idle_fn_();
- } else {
- if (value.IsNull()) {
- removed_fn_(path);
- } else {
- ProcessEntry(path, value);
- }
- }
- }
- void OnPatch(const std::string& path,
- const rapidjson::Value& value) override {}
- void OnCancel() override {}
- void OnAuthRevoked(const std::string& reason) override {}
-
- void OnMalformedEvent() override {}
-
- void OnConnectionError() override {
- idle_fn_();
-
- // Simple exponential backoff counter.
- if (reconnect_wait_seconds_ == 0) {
- reconnect_wait_seconds_ = 1;
- } else {
- reconnect_wait_seconds_ *= 2;
- if (reconnect_wait_seconds_ > 60)
- reconnect_wait_seconds_ = 60;
- }
-
- // Try to reconnect.
- FXL_LOG(INFO) << "Reconnecting to Firebase in " << reconnect_wait_seconds_
- << " seconds.";
- async::PostDelayedTask(dispatcher_,
- [owner = owner_, this]() {
- if (!owner)
- return;
- owner->StartWatching(this);
- },
- zx::sec(reconnect_wait_seconds_));
- }
-
- void ProcessEntry(const std::string& name, const rapidjson::Value& value) {
- // We have to deep-copy |it->value| because XdrRead() must have a
- // rapidjson::Document.
- rapidjson::Document doc;
- doc.CopyFrom(value, doc.GetAllocator());
-
- // Handle bad manifests, including older files expressed as an array.
- // Any mismatch causes XdrRead to DCHECK.
- if (!doc.IsObject()) {
- FXL_LOG(WARNING) << "Ignored invalid manifest: " << name;
- return;
- }
-
- fuchsia::modular::ModuleManifest entry;
- if (!XdrRead(&doc, &entry, XdrModuleManifest)) {
- FXL_LOG(WARNING) << "Could not parse Module manifest from: " << name;
- return;
- }
-
- new_fn_(name, std::move(entry));
- }
-
- async_dispatcher_t* const dispatcher_;
-
- ModuleManifestSource::IdleFn idle_fn_;
- ModuleManifestSource::NewEntryFn new_fn_;
- ModuleManifestSource::RemovedEntryFn removed_fn_;
-
- int reconnect_wait_seconds_;
-
- fxl::WeakPtr<FirebaseModuleManifestSource> owner_;
-};
-
-FirebaseModuleManifestSource::FirebaseModuleManifestSource(
- async_dispatcher_t* dispatcher,
- std::function<http::HttpServicePtr()> network_service_factory,
- std::string db_id, std::string prefix)
- : db_id_(db_id),
- prefix_(prefix),
- network_wrapper_(new network_wrapper::NetworkWrapperImpl(
- dispatcher, std::make_unique<backoff::ExponentialBackoff>(),
- std::move(network_service_factory))),
- client_(
- new firebase::FirebaseImpl(network_wrapper_.get(), db_id, prefix)),
- weak_factory_(this) {}
-
-FirebaseModuleManifestSource::~FirebaseModuleManifestSource() {
- for (auto& watcher : watchers_) {
- client_->UnWatch(watcher.get());
- }
-}
-
-void FirebaseModuleManifestSource::Watch(async_dispatcher_t* dispatcher,
- IdleFn idle_fn, NewEntryFn new_fn,
- RemovedEntryFn removed_fn) {
- auto watcher = std::make_unique<Watcher>(
- dispatcher, std::move(idle_fn), std::move(new_fn), std::move(removed_fn),
- weak_factory_.GetWeakPtr());
-
- StartWatching(watcher.get());
- watchers_.push_back(std::move(watcher));
-}
-
-void FirebaseModuleManifestSource::StartWatching(Watcher* watcher) {
- client_->Watch("/manifests", {}, watcher);
-}
-
-} // namespace modular
diff --git a/lib/module_manifest_source/firebase_source.h b/lib/module_manifest_source/firebase_source.h
deleted file mode 100644
index a5d9b88..0000000
--- a/lib/module_manifest_source/firebase_source.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_MODULE_MANIFEST_SOURCE_FIREBASE_SOURCE_H_
-#define PERIDOT_LIB_MODULE_MANIFEST_SOURCE_FIREBASE_SOURCE_H_
-
-#include <functional>
-#include <map>
-#include <string>
-#include <vector>
-
-#include <fuchsia/net/oldhttp/cpp/fidl.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/lib/module_manifest_source/module_manifest_source.h"
-
-namespace firebase {
-class Firebase;
-}
-
-namespace network_wrapper {
-class NetworkWrapper;
-}
-
-namespace modular {
-
-// Watches a Manifest repository stored in Firebase.
-// Expects the database to be constructed like so:
-// {
-// "manifests": {
-// "module id 1": [ manifest entry, manifest entry, ... ],
-// "module id 2": ...
-// }
-// }
-class FirebaseModuleManifestSource : public ModuleManifestSource {
- public:
- FirebaseModuleManifestSource(
- async_dispatcher_t* dispatcher,
- std::function<::fuchsia::net::oldhttp::HttpServicePtr()>
- network_service_factory,
- std::string db_id, std::string prefix);
- ~FirebaseModuleManifestSource() override;
-
- void Watch(async_dispatcher_t* dispatcher, IdleFn idle_fn, NewEntryFn new_fn,
- RemovedEntryFn removed_fn) override;
-
- private:
- class Watcher;
-
- void StartWatching(Watcher* watcher);
-
- // Only used for logging.
- const std::string db_id_;
- const std::string prefix_;
-
- std::unique_ptr<network_wrapper::NetworkWrapper> network_wrapper_;
- std::unique_ptr<firebase::Firebase> client_;
-
- std::vector<std::unique_ptr<Watcher>> watchers_;
-
- fxl::WeakPtrFactory<FirebaseModuleManifestSource> weak_factory_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_MODULE_MANIFEST_SOURCE_FIREBASE_SOURCE_H_
diff --git a/lib/module_manifest_source/json.cc b/lib/module_manifest_source/json.cc
deleted file mode 100644
index b70d049..0000000
--- a/lib/module_manifest_source/json.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest_source/json.h"
-
-#include "peridot/lib/fidl/json_xdr.h"
-#include "peridot/lib/module_manifest/module_manifest_xdr.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "rapidjson/document.h"
-
-namespace modular {
-
-bool ModuleManifestEntryFromJson(const std::string& json,
- fuchsia::modular::ModuleManifest* entry) {
- rapidjson::Document doc;
- // Schema validation of the JSON is happening at publish time. By the time we
- // get here, we assume it's valid manifest JSON.
- doc.Parse(json.c_str());
-
- // Handle bad manifests, including older files expressed as an array.
- // Any mismatch causes XdrRead to DCHECK.
- if (!doc.IsObject()) {
- return false;
- }
-
- // Our tooling validates |doc|'s JSON schema so that we don't have to here.
- // It may be good to do this, though.
- // TODO(thatguy): Do this if it becomes a problem.
- if (!XdrRead(&doc, entry, XdrModuleManifest)) {
- return false;
- }
- return true;
-}
-
-void ModuleManifestEntryToJson(const fuchsia::modular::ModuleManifest& entry,
- std::string* json) {
- rapidjson::Document doc;
- fuchsia::modular::ModuleManifest local_entry;
- fidl::Clone(entry, &local_entry);
- XdrWrite(&doc, &local_entry, XdrModuleManifest);
-
- *json = JsonValueToPrettyString(doc);
-}
-
-} // namespace modular
diff --git a/lib/module_manifest_source/json.h b/lib/module_manifest_source/json.h
deleted file mode 100644
index 82adfd7..0000000
--- a/lib/module_manifest_source/json.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_MODULE_MANIFEST_SOURCE_JSON_H_
-#define PERIDOT_LIB_MODULE_MANIFEST_SOURCE_JSON_H_
-
-#include "peridot/lib/module_manifest_source/module_manifest_source.h"
-
-namespace modular {
-
-bool ModuleManifestEntryFromJson(const std::string& json,
- fuchsia::modular::ModuleManifest* entry);
-void ModuleManifestEntryToJson(const fuchsia::modular::ModuleManifest& entry,
- std::string* json);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_MODULE_MANIFEST_SOURCE_JSON_H_
diff --git a/lib/module_manifest_source/module_manifest_source.cc b/lib/module_manifest_source/module_manifest_source.cc
deleted file mode 100644
index b65ec68..0000000
--- a/lib/module_manifest_source/module_manifest_source.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest_source/module_manifest_source.h"
-
-namespace modular {
-
-ModuleManifestSource::~ModuleManifestSource() = default;
-
-} // namespace modular
diff --git a/lib/module_manifest_source/module_manifest_source.h b/lib/module_manifest_source/module_manifest_source.h
deleted file mode 100644
index 9730305..0000000
--- a/lib/module_manifest_source/module_manifest_source.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_MODULE_MANIFEST_SOURCE_MODULE_MANIFEST_SOURCE_H_
-#define PERIDOT_LIB_MODULE_MANIFEST_SOURCE_MODULE_MANIFEST_SOURCE_H_
-
-#include <functional>
-#include <string>
-#include <vector>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/dispatcher.h>
-
-namespace modular {
-
-// Abstract base class for all Module Manifest Source implementations.
-class ModuleManifestSource {
- public:
- using NewEntryFn = std::function<void(std::string /* source name*/,
- fuchsia::modular::ModuleManifest)>;
- using RemovedEntryFn = std::function<void(std::string /* module uri */)>;
- using IdleFn = std::function<void()>;
-
- virtual ~ModuleManifestSource() = 0;
-
- // Watches the source for new or removed Module manifest entries. Posts
- // tasks to |dispatcher| calling |new_fn| for each entry in new files and
- // |removed_fn| for entries that have been removed. Calls |idle_fn| once all
- // existing entries at the time of calling Watch() have been read and sent to
- // |new_fn|.
- //
- // Destroying |this| stops watching and guarantees neither |new_fn| or
- // |removed_fn| will be called. Caller is responsible for ensuring
- // |dispatcher| remains alive as long as |this| is alive.
- //
- // |new_fn| takes a string Entry id and the Entry itself.
- //
- // |removed_fn| takes only the string Entry id.
- virtual void Watch(async_dispatcher_t* dispatcher, IdleFn idle_fn,
- NewEntryFn new_fn, RemovedEntryFn removed_fn) = 0;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_MODULE_MANIFEST_SOURCE_MODULE_MANIFEST_SOURCE_H_
diff --git a/lib/module_manifest_source/module_package_source.cc b/lib/module_manifest_source/module_package_source.cc
deleted file mode 100644
index d848c64..0000000
--- a/lib/module_manifest_source/module_package_source.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest_source/module_package_source.h"
-
-#include <dirent.h>
-#include <sys/types.h>
-
-#include <fs/service.h>
-#include <lib/async/cpp/task.h>
-#include <lib/fxl/files/directory.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/fxl/strings/split_string.h>
-#include <lib/fxl/strings/string_printf.h>
-
-#include "peridot/lib/module_manifest_source/json.h"
-#include "peridot/lib/module_manifest_source/package_util.h"
-
-namespace modular {
-namespace {
-// NOTE: This must match the path specified in
-// //peridot/build/module_manifest.gni
-constexpr char kInitialModulePackagesIndexDir[] =
- "/system/data/initial_module_packages";
-} // namespace
-
-using ::fuchsia::maxwell::internal::ModulePackageIndexer;
-
-ModulePackageSource::ModulePackageSource(
- component::StartupContext* const context)
- : weak_factory_(this) {
- context->outgoing().debug_dir()->AddEntry(
- ModulePackageIndexer::Name_,
- fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
- indexer_bindings_.AddBinding(
- this,
- fidl::InterfaceRequest<ModulePackageIndexer>(std::move(channel)));
- return ZX_OK;
- })));
-}
-
-ModulePackageSource::~ModulePackageSource() {}
-
-void ModulePackageSource::IndexManifest(std::string package_name,
- std::string module_manifest_path) {
- FXL_DCHECK(dispatcher_);
- FXL_DCHECK(new_entry_fn_);
-
- std::string data;
- if (!files::ReadFileToString(module_manifest_path, &data)) {
- FXL_LOG(ERROR) << "Couldn't read module manifest from: "
- << module_manifest_path;
- return;
- }
-
- fuchsia::modular::ModuleManifest entry;
- if (!ModuleManifestEntryFromJson(data, &entry)) {
- FXL_LOG(WARNING) << "Couldn't parse module manifest from: "
- << module_manifest_path;
- return;
- }
-
- async::PostTask(
- dispatcher_,
- fxl::MakeCopyable([weak_this = weak_factory_.GetWeakPtr(), package_name,
- entry = std::move(entry)]() mutable {
- if (!weak_this) {
- return;
- }
-
- weak_this->new_entry_fn_(entry.binary, std::move(entry));
- }));
-}
-
-// TODO(vardhan): Move this into garnet's fxl.
-void IterateDirectory(fxl::StringView dirname,
- std::function<void(fxl::StringView)> callback) {
- DIR* fd = opendir(dirname.data());
- if (fd == nullptr) {
- perror("Could not open module package index directory: ");
- return;
- }
- struct dirent* dp = nullptr;
- while ((dp = readdir(fd)) != nullptr) {
- if (dp->d_name[0] != '.') {
- callback(dp->d_name);
- }
- }
- closedir(fd);
-}
-
-void ModulePackageSource::Watch(async_dispatcher_t* dispatcher, IdleFn idle_fn,
- NewEntryFn new_fn, RemovedEntryFn removed_fn) {
- dispatcher_ = dispatcher;
- new_entry_fn_ = new_fn;
-
- IterateDirectory(
- kInitialModulePackagesIndexDir, [this](fxl::StringView filename) {
- std::string contents;
- if (!files::ReadFileToString(
- fxl::StringPrintf("%s/%s", kInitialModulePackagesIndexDir,
- filename.data()),
- &contents)) {
- FXL_LOG(ERROR) << "Could not read module package index: "
- << filename.data();
- }
- auto module_pkgs = fxl::SplitString(
- contents, "\n", fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
- for (auto module_pkg_view : module_pkgs) {
- auto module_pkg = module_pkg_view.ToString();
- // TODO(vardhan): We only index module package with version=0. Do
- // better.
- IndexManifest(module_pkg,
- GetModuleManifestPathFromPackage(module_pkg, "0"));
- }
- });
-
- idle_fn();
-}
-
-} // namespace modular
diff --git a/lib/module_manifest_source/module_package_source.h b/lib/module_manifest_source/module_package_source.h
deleted file mode 100644
index 5e1f6a5..0000000
--- a/lib/module_manifest_source/module_package_source.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_MODULE_MANIFEST_SOURCE_MODULE_PACKAGE_SOURCE_H_
-#define PERIDOT_LIB_MODULE_MANIFEST_SOURCE_MODULE_PACKAGE_SOURCE_H_
-
-#include <functional>
-#include <map>
-#include <string>
-#include <vector>
-
-#include <fuchsia/maxwell/internal/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/lib/module_manifest_source/module_manifest_source.h"
-
-namespace modular {
-
-// This source exposes a |ModuleManifestIndexer| service to this application's
-// debug service. New manifests are published using that interfaces. When this
-// source starts up, it gets its initial set of module packages to index by
-// reading the module package index directory located under /system/data/.
-class ModulePackageSource : public ModuleManifestSource,
- ::fuchsia::maxwell::internal::ModulePackageIndexer {
- public:
- ModulePackageSource(component::StartupContext* context);
- ~ModulePackageSource() override;
-
- // |ModuleManifestSource|
- void Watch(async_dispatcher_t* dispatcher, IdleFn idle_fn, NewEntryFn new_fn,
- RemovedEntryFn removed_fn) override;
-
- private:
- // |ModulePackageIndexer|
- void IndexManifest(std::string package_name,
- std::string module_manifest_path) override;
-
- const std::string dir_;
- NewEntryFn new_entry_fn_;
- fidl::BindingSet<::fuchsia::maxwell::internal::ModulePackageIndexer>
- indexer_bindings_;
- async_dispatcher_t* dispatcher_;
-
- fxl::WeakPtrFactory<ModulePackageSource> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ModulePackageSource);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_MODULE_MANIFEST_SOURCE_MODULE_PACKAGE_SOURCE_H_
diff --git a/lib/module_manifest_source/package_util.cc b/lib/module_manifest_source/package_util.cc
deleted file mode 100644
index 59cbc0a..0000000
--- a/lib/module_manifest_source/package_util.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/module_manifest_source/package_util.h"
-
-#include <lib/fxl/strings/string_printf.h>
-
-namespace modular {
-
-std::string GetModuleManifestPathFromPackage(fxl::StringView package_name,
- fxl::StringView package_version) {
- return fxl::StringPrintf("/pkgfs/packages/%s/%s/meta/module.json",
- package_name.data(), package_version.data());
-}
-
-} // namespace modular
diff --git a/lib/module_manifest_source/package_util.h b/lib/module_manifest_source/package_util.h
deleted file mode 100644
index 2829f71..0000000
--- a/lib/module_manifest_source/package_util.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_MODULE_MANIFEST_SOURCE_PACKAGE_UTIL_H_
-#define PERIDOT_LIB_MODULE_MANIFEST_SOURCE_PACKAGE_UTIL_H_
-
-#include <string>
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace modular {
-
-std::string GetModuleManifestPathFromPackage(fxl::StringView package_name,
- fxl::StringView package_version);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_MODULE_MANIFEST_SOURCE_PACKAGE_UTIL_H_
diff --git a/lib/rapidjson/BUILD.gn b/lib/rapidjson/BUILD.gn
deleted file mode 100644
index c13aebb..0000000
--- a/lib/rapidjson/BUILD.gn
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("rapidjson") {
- sources = [
- "rapidjson.h",
- ]
-
- public_deps = [
- "//third_party/rapidjson",
- ]
-}
diff --git a/lib/rapidjson/rapidjson.h b/lib/rapidjson/rapidjson.h
deleted file mode 100644
index dd4e9e6..0000000
--- a/lib/rapidjson/rapidjson.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_RAPIDJSON_RAPIDJSON_H_
-#define PERIDOT_LIB_RAPIDJSON_RAPIDJSON_H_
-
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "rapidjson/document.h"
-#include "rapidjson/pointer.h"
-#include "rapidjson/prettywriter.h"
-#include "rapidjson/stringbuffer.h"
-#include "rapidjson/writer.h"
-
-namespace modular {
-
-using JsonDoc = ::rapidjson::Document;
-using JsonValue = JsonDoc::ValueType;
-using JsonPointer = ::rapidjson::GenericPointer<JsonValue>;
-
-// Helper function to convert the given JsonValue to a string. Note that a
-// JsonDoc is also a JsonValue.
-template <typename T>
-inline std::string JsonValueToString(const T& v) {
- rapidjson::StringBuffer buffer;
- rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
- v.Accept(writer);
- return buffer.GetString();
-}
-
-// Like above, but pretty prints the string.
-template <typename T>
-inline std::string JsonValueToPrettyString(const T& v) {
- rapidjson::StringBuffer buffer;
- rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
- v.Accept(writer);
- return buffer.GetString();
-}
-
-// Take a vector of std::string and convert it to "/a/b/c" form for display.
-// For debugging/logging purposes only
-inline std::string PrettyPrintPath(const std::vector<std::string>& path) {
- std::string result;
- for (const auto& str : path) {
- result += '/' + str;
- }
- return result;
-}
-
-// Take an array of strings representing the segments in a JSON Path
-// and construct a rapidjson::GenericPointer() object.
-template <typename Doc>
-inline rapidjson::GenericPointer<typename Doc::ValueType> CreatePointer(
- const Doc& /*doc*/, std::vector<std::string>::iterator begin,
- std::vector<std::string>::iterator end) {
- rapidjson::GenericPointer<typename Doc::ValueType> pointer;
- for (auto it = begin; it != end; ++it) {
- pointer = pointer.Append(*it, nullptr);
- }
- return pointer;
-}
-
-template <typename Doc, typename Collection>
-inline rapidjson::GenericPointer<typename Doc::ValueType> CreatePointer(
- const Doc& doc, const Collection& path) {
- rapidjson::GenericPointer<typename Doc::ValueType> pointer;
- for (const auto& it : path) {
- pointer = pointer.Append(it, nullptr);
- }
- return pointer;
-}
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_RAPIDJSON_RAPIDJSON_H_
diff --git a/lib/rng/BUILD.gn b/lib/rng/BUILD.gn
deleted file mode 100644
index 4b6f2f9..0000000
--- a/lib/rng/BUILD.gn
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("rng") {
- sources = [
- "random.h",
- ]
-}
-
-source_set("system") {
- sources = [
- "system_random.h",
- ]
-
- public_deps = [
- ":rng",
- "//zircon/public/lib/zx",
- ]
-}
-
-source_set("testing") {
- testonly = true
-
- sources = [
- "test_random.cc",
- "test_random.h",
- ]
-
- public_deps = [
- ":rng",
- ]
-}
-
-source_set("unittests") {
- testonly = true
- sources = [
- "system_random_unittest.cc",
- "test_random_unittest.cc",
- ]
-
- deps = [
- ":system",
- ":testing",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gmock",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/rng/random.h b/lib/rng/random.h
deleted file mode 100644
index cfbc853..0000000
--- a/lib/rng/random.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_RNG_RANDOM_H_
-#define PERIDOT_LIB_RNG_RANDOM_H_
-
-#include <limits>
-#include <string>
-#include <type_traits>
-
-namespace rng {
-
-// Abstraction over the random number generator.
-//
-// This class allows to get random values. It can generate random bytes on a
-// given buffer, fill a mutable string-like object, or return a POD like
-// object.
-//
-// Using this class allows to control the randomness when running tests by
-// injecting a seedable PRNG and reseeding it with the same value to re-run the
-// same test.
-class Random {
- public:
- // An object satifying the |UniformRandomBitGenerator| requirements. See:
- // https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator
- template <typename I>
- class BitGenerator {
- public:
- static_assert(std::is_unsigned<I>::value,
- "RandomBitGenerator only valid for unsigned integers");
- using result_type = I;
-
- BitGenerator(Random* random) : random_(random) {}
- ~BitGenerator() = default;
- BitGenerator(const BitGenerator&) = default;
- BitGenerator& operator=(const BitGenerator&) = default;
-
- static constexpr result_type min() {
- return std::numeric_limits<result_type>::min();
- }
- static constexpr result_type max() {
- return std::numeric_limits<result_type>::max();
- }
- constexpr double entropy() const noexcept {
- return std::numeric_limits<result_type>::digits;
- };
- result_type operator()() { return random_->Draw<I>(); }
-
- private:
- Random* const random_;
- };
-
- Random() = default;
- Random(const Random&) = delete;
- Random& operator=(const Random&) = delete;
- virtual ~Random() = default;
-
- // Fill |buffer| with |buffer_size| random bytes.
- void Draw(void* buffer, size_t buffer_size) {
- InternalDraw(buffer, buffer_size);
- }
-
- // Fills |*string_like| with random bytes. |string_like| must have a random
- // access operator returning a non-const reference. |string_like must have a
- // |size| method. &(*string_like)[0] must be the start of writable memory
- // range of at least |string_like->size()| bytes. Usual datatype that support
- // this schema are std::string and std::vector<uint8_t>.
- template <typename S>
- S& Draw(S* string_like) {
- Draw(&(*string_like)[0], string_like->size());
- return *string_like;
- }
-
- // Returns an instance of |I| where the content has been filled with randomly
- // generated bytes. |I| must be trivially copyable.
- template <typename I>
- I Draw() {
- static_assert(std::is_trivially_copyable<I>::value,
- "The return type must be trivially copyable.");
- I result;
- Draw(&result, sizeof(I));
- return result;
- }
-
- // Returns a random string that is statistically certain to be unique.
- std::string RandomUniqueBytes() {
- constexpr size_t kBitsCountForUnicity = 128;
- char bytes[kBitsCountForUnicity / 8];
- Draw(bytes, sizeof(bytes));
- return std::string(bytes, sizeof(bytes));
- }
-
- // Returns an object satifying the |UniformRandomBitGenerator| requirements.
- // See: https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator
- template <typename I>
- BitGenerator<I> NewBitGenerator() {
- return BitGenerator<I>(this);
- }
-
- protected:
- // Fills |buffer| with |buffer_size| random bytes.
- virtual void InternalDraw(void* buffer, size_t buffer_size) = 0;
-};
-
-}; // namespace rng
-
-#endif // PERIDOT_LIB_RNG_RANDOM_H_
diff --git a/lib/rng/system_random.h b/lib/rng/system_random.h
deleted file mode 100644
index 311f45f..0000000
--- a/lib/rng/system_random.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_RNG_SYSTEM_RANDOM_H_
-#define PERIDOT_LIB_RNG_SYSTEM_RANDOM_H_
-
-#include "peridot/lib/rng/random.h"
-
-#include <zircon/syscalls.h>
-
-namespace rng {
-
-// Implementation of |Random| that uses the system RNG.
-class SystemRandom final : public Random {
- private:
- void InternalDraw(void* buffer, size_t buffer_size) override {
- zx_cprng_draw(buffer, buffer_size);
- }
-};
-
-} // namespace rng
-
-#endif // PERIDOT_LIB_RNG_SYSTEM_RANDOM_H_
diff --git a/lib/rng/system_random_unittest.cc b/lib/rng/system_random_unittest.cc
deleted file mode 100644
index 9a33610..0000000
--- a/lib/rng/system_random_unittest.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/rng/system_random.h"
-
-#include <algorithm>
-#include <random>
-#include <vector>
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace rng {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::Ge;
-using ::testing::Le;
-using ::testing::SizeIs;
-
-TEST(TestRandomTest, InUniquePtr) {
- auto test_random = std::make_unique<SystemRandom>();
- std::unique_ptr<Random> random = std::move(test_random);
- EXPECT_TRUE(random);
-}
-
-TEST(SystemRandomTest, MiscRandomTest) {
- constexpr size_t kNbElement = 20;
-
- SystemRandom random;
-
- std::vector<uint32_t> v1;
- for (size_t i = 0; i < kNbElement; ++i) {
- v1.push_back(random.Draw<uint32_t>());
- }
- EXPECT_TRUE(std::any_of(v1.begin(), v1.end(),
- [](const uint8_t& v) { return v != 0; }));
-
- std::vector<uint8_t> v2(kNbElement, 0);
- random.Draw(&v2);
- EXPECT_TRUE(std::any_of(v2.begin(), v2.end(),
- [](const uint8_t& v) { return v != 0; }));
-
- uint8_t bytes[kNbElement];
- random.Draw(bytes, kNbElement);
- EXPECT_TRUE(std::any_of(bytes, bytes + kNbElement,
- [](const uint8_t& v) { return v != 0; }));
-}
-
-TEST(SystemRandomTest, BitGeneratorTest) {
- constexpr size_t kNbElement = 100;
- SystemRandom random;
-
- auto engine = random.NewBitGenerator<uint32_t>();
- std::discrete_distribution<> d({1, 1, 1, 1});
- std::set<uint32_t> s;
- for (size_t i = 0; i < kNbElement; ++i) {
- s.insert(d(engine));
- }
- EXPECT_THAT(s, ElementsAre(0, 1, 2, 3));
-}
-
-TEST(SystemRandomTest, RandomStructTest) {
- constexpr size_t kNbElement = 64;
- struct S {
- uint64_t array[kNbElement];
- };
- SystemRandom random;
-
- auto s1 = random.Draw<S>();
- std::set<uint64_t> v1(s1.array, s1.array + kNbElement);
-
- EXPECT_THAT(v1, SizeIs(Ge(kNbElement - 2)));
-
- auto s2 = random.Draw<S>();
- std::set<uint64_t> v2(s2.array, s2.array + kNbElement);
-
- std::vector<uint64_t> common_data;
- set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
- std::back_inserter(common_data));
- EXPECT_THAT(common_data, SizeIs(Le(2u)));
-}
-
-TEST(SystemRandomTest, IndependantDraws) {
- constexpr size_t kNbElement = 20;
-
- SystemRandom random1;
- SystemRandom random2;
-
- std::vector<uint8_t> v1(kNbElement, 0);
- std::vector<uint8_t> v2(kNbElement, 0);
-
- random1.Draw(&v1);
- random2.Draw(&v2);
-
- EXPECT_NE(v1, v2);
-}
-
-} // namespace
-} // namespace rng
diff --git a/lib/rng/test_random.cc b/lib/rng/test_random.cc
deleted file mode 100644
index 23f9288..0000000
--- a/lib/rng/test_random.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/rng/test_random.h"
-
-#include <algorithm>
-
-namespace rng {
-
-TestRandom::TestRandom(std::uint_fast64_t seed) : char_engine_(seed) {}
-
-void TestRandom::InternalDraw(void* buffer, size_t buffer_size) {
- uint8_t* char_buffer = static_cast<uint8_t*>(buffer);
- std::generate(char_buffer, char_buffer + buffer_size, std::ref(char_engine_));
-}
-
-} // namespace rng
diff --git a/lib/rng/test_random.h b/lib/rng/test_random.h
deleted file mode 100644
index a28e59d..0000000
--- a/lib/rng/test_random.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_RNG_TEST_RANDOM_H_
-#define PERIDOT_LIB_RNG_TEST_RANDOM_H_
-
-#include <random>
-
-#include "peridot/lib/rng/random.h"
-
-namespace rng {
-
-// Implementation of |Random| that uses a PRNG.
-class TestRandom final : public Random {
- public:
- TestRandom(std::uint_fast64_t seed);
-
- private:
- void InternalDraw(void* buffer, size_t buffer_size) override;
-
- std::independent_bits_engine<std::mt19937_64, 8, uint8_t> char_engine_;
-};
-
-} // namespace rng
-
-#endif // PERIDOT_LIB_RNG_TEST_RANDOM_H_
diff --git a/lib/rng/test_random_unittest.cc b/lib/rng/test_random_unittest.cc
deleted file mode 100644
index 91e7411..0000000
--- a/lib/rng/test_random_unittest.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/rng/test_random.h"
-
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace rng {
-namespace {
-
-using ::testing::ElementsAreArray;
-using ::testing::Not;
-
-TEST(TestRandomTest, InUniquePtr) {
- auto test_random = std::make_unique<TestRandom>(0);
- std::unique_ptr<Random> random = std::move(test_random);
- EXPECT_TRUE(random);
-}
-
-TEST(TestRandomTest, DependantDraws) {
- constexpr size_t kNbElement = 20;
-
- TestRandom random1(0);
- TestRandom random2(0);
-
- std::vector<uint8_t> v1(kNbElement, 0);
- std::vector<uint8_t> v2(kNbElement, 0);
-
- random1.Draw(&v1);
- random2.Draw(&v2);
-
- EXPECT_THAT(v1, ElementsAreArray(v2));
-}
-
-TEST(TestRandomTest, ConsequentDraws) {
- constexpr size_t kNbElement = 20;
-
- TestRandom random1(0);
-
- std::vector<uint8_t> v1(kNbElement, 0);
- std::vector<uint8_t> v2(kNbElement, 0);
-
- random1.Draw(&v1);
- random1.Draw(&v2);
-
- EXPECT_THAT(v1, Not(ElementsAreArray(v2)));
-}
-
-TEST(TestRandomTest, IndependantDraws) {
- constexpr size_t kNbElement = 20;
-
- TestRandom random1(0);
- TestRandom random2(1);
-
- std::vector<uint8_t> v1(kNbElement, 0);
- std::vector<uint8_t> v2(kNbElement, 0);
-
- random1.Draw(&v1);
- random2.Draw(&v2);
-
- EXPECT_THAT(v1, Not(ElementsAreArray(v2)));
-}
-
-} // namespace
-} // namespace rng
diff --git a/lib/scoped_tmpfs/BUILD.gn b/lib/scoped_tmpfs/BUILD.gn
deleted file mode 100644
index eaa14f2..0000000
--- a/lib/scoped_tmpfs/BUILD.gn
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- "//peridot/bin/*",
- "//peridot/lib/*",
-]
-
-source_set("scoped_tmpfs") {
- sources = [
- "scoped_tmpfs.cc",
- "scoped_tmpfs.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//zircon/public/lib/async-loop-cpp",
- "//zircon/public/lib/memfs",
- "//zircon/public/lib/sync",
- ]
-
- deps = [
- "//zircon/public/lib/fdio",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "scoped_tmpfs_unittest.cc",
- ]
-
- deps = [
- ":scoped_tmpfs",
- "//garnet/public/lib/fxl",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/scoped_tmpfs/scoped_tmpfs.cc b/lib/scoped_tmpfs/scoped_tmpfs.cc
deleted file mode 100644
index 33a5f0f..0000000
--- a/lib/scoped_tmpfs/scoped_tmpfs.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-#include <lib/fdio/util.h>
-#include <lib/fsl/io/fd.h>
-#include <lib/fxl/logging.h>
-#include <lib/sync/completion.h>
-#include <zircon/processargs.h>
-
-namespace scoped_tmpfs {
-
-namespace {
-async_loop_config_t MakeConfig() {
- async_loop_config_t result = kAsyncLoopConfigAttachToThread;
- result.make_default_for_current_thread = false;
- return result;
-}
-} // namespace
-
-ScopedTmpFS::ScopedTmpFS() : config_(MakeConfig()), loop_(&config_) {
- zx_status_t status = loop_.StartThread("tmpfs_thread");
- FXL_CHECK(status == ZX_OK);
- zx_handle_t root_handle;
- status = memfs_create_filesystem(loop_.dispatcher(), &memfs_, &root_handle);
- FXL_CHECK(status == ZX_OK);
- root_fd_ = fsl::OpenChannelAsFileDescriptor(zx::channel(root_handle));
- FXL_CHECK(root_fd_.is_valid());
-}
-
-ScopedTmpFS::~ScopedTmpFS() {
- root_fd_.reset();
- sync_completion_t unmounted;
- memfs_free_filesystem(memfs_, &unmounted);
- zx_status_t status = sync_completion_wait(&unmounted, ZX_SEC(3));
- FXL_DCHECK(status == ZX_OK);
-}
-
-} // namespace scoped_tmpfs
diff --git a/lib/scoped_tmpfs/scoped_tmpfs.h b/lib/scoped_tmpfs/scoped_tmpfs.h
deleted file mode 100644
index eb8fee1..0000000
--- a/lib/scoped_tmpfs/scoped_tmpfs.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_SCOPED_TMPFS_SCOPED_TMPFS_H_
-#define PERIDOT_LIB_SCOPED_TMPFS_SCOPED_TMPFS_H_
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fxl/files/unique_fd.h>
-#include <lib/memfs/memfs.h>
-
-namespace scoped_tmpfs {
-
-// Scoped temporary filesystem that will be destroyed when this class is
-// deleted. The filesystem is not mounted on the process namespace and should be
-// accessed via the root file descriptor.
-class ScopedTmpFS {
- public:
- ScopedTmpFS();
- ScopedTmpFS(const ScopedTmpFS&) = delete;
- ScopedTmpFS& operator=(const ScopedTmpFS&) = delete;
- ~ScopedTmpFS();
-
- int root_fd() { return root_fd_.get(); }
-
- private:
- async_loop_config_t config_;
- async::Loop loop_;
- memfs_filesystem_t* memfs_;
- fxl::UniqueFD root_fd_;
-};
-
-} // namespace scoped_tmpfs
-
-#endif // PERIDOT_LIB_SCOPED_TMPFS_SCOPED_TMPFS_H_
diff --git a/lib/scoped_tmpfs/scoped_tmpfs_unittest.cc b/lib/scoped_tmpfs/scoped_tmpfs_unittest.cc
deleted file mode 100644
index b6816c0..0000000
--- a/lib/scoped_tmpfs/scoped_tmpfs_unittest.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <lib/fxl/files/unique_fd.h>
-
-#include "gtest/gtest.h"
-
-namespace scoped_tmpfs {
-namespace {
-
-TEST(ScopedTmpFsTest, ScopedTmpFs) {
- ScopedTmpFS scoped_tmpfs;
-
- EXPECT_GE(scoped_tmpfs.root_fd(), 0);
-
- fxl::UniqueFD fd(
- openat(scoped_tmpfs.root_fd(), "foo", O_WRONLY | O_CREAT | O_EXCL));
- ASSERT_TRUE(fd.is_valid());
- EXPECT_GT(write(fd.get(), "Hello", 6), 0);
- fd.reset(openat(scoped_tmpfs.root_fd(), "foo", O_RDONLY));
- ASSERT_TRUE(fd.is_valid());
- char b;
- EXPECT_EQ(1, read(fd.get(), &b, 1));
- EXPECT_EQ('H', b);
-}
-
-} // namespace
-} // namespace scoped_tmpfs
diff --git a/lib/session_shell_settings/BUILD.gn b/lib/session_shell_settings/BUILD.gn
deleted file mode 100644
index 4607a53..0000000
--- a/lib/session_shell_settings/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("unittests") {
- testonly = true
-
- deps = [
- ":session_shell_settings_unittest",
- ]
-}
-
-source_set("session_shell_settings") {
- sources = [
- "session_shell_settings.cc",
- "session_shell_settings.h",
- ]
-
- public_deps = [
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//peridot/lib/rapidjson:rapidjson",
- ]
-}
-
-source_set("session_shell_settings_unittest") {
- testonly = true
-
- sources = [
- "session_shell_settings_test.cc",
- ]
-
- deps = [
- ":session_shell_settings",
- "//garnet/public/lib/fxl",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/lib/session_shell_settings/session_shell_settings.cc b/lib/session_shell_settings/session_shell_settings.cc
deleted file mode 100644
index 4118697..0000000
--- a/lib/session_shell_settings/session_shell_settings.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/session_shell_settings/session_shell_settings.h"
-
-#include <cmath>
-
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-
-#include "rapidjson/document.h"
-
-namespace modular {
-
-namespace {
-
-constexpr char kBaseShellConfigJsonPath[] =
- "/system/data/sysui/base_shell_config.json";
-std::vector<SessionShellSettings>* g_system_settings;
-
-} // namespace
-
-namespace internal {
-
-// Given a rapidjson::Value that is an object (i.e. a key-value map), look up
-// |key| in the object and return the value associated with it.
-template <typename T>
-T GetObjectValue(const rapidjson::Value& object, const std::string& key);
-
-// Specializes |GetObjectValue|, expecting the type of object[key] to be an JSON
-// string. Returns "" if the key doesn't exist or isn't a JSON string.
-template <>
-std::string GetObjectValue(const rapidjson::Value& object,
- const std::string& key) {
- if (!object.IsObject())
- return "";
-
- if (!object.HasMember(key))
- return "";
-
- const auto& field = object[key];
-
- if (!field.IsString())
- return "";
-
- return field.GetString();
-}
-
-// Specializes |GetObjectValue|, expecting the type of object[key] to be a _JSON
-// string that represents a float_. (Note that the type is not expected to be a
-// raw JSON number!). Returns std::numeric_limits<float>::signaling_NaN() if
-// the float couldn't be parsed from the string.
-template <>
-float GetObjectValue(const rapidjson::Value& object, const std::string& key) {
- auto str = GetObjectValue<std::string>(object, key);
-
- if (str.empty())
- return std::numeric_limits<float>::signaling_NaN();
-
- const char* const c_str = str.c_str();
- char* c_str_end;
-
- const float f = std::strtof(c_str, &c_str_end);
- if (f == HUGE_VAL || (f == 0.0f && c_str_end == c_str))
- return std::numeric_limits<float>::signaling_NaN();
-
- return f;
-}
-
-// Specializes |GetObjectValue|, expecting the type of object[key] to be a JSON
-// string that represents a fuchsia::ui::policy::DisplayUsage. Returns kUnknown
-// if the string couldn't be parsed.
-template <>
-fuchsia::ui::policy::DisplayUsage GetObjectValue(const rapidjson::Value& object,
- const std::string& key) {
- auto str = GetObjectValue<std::string>(object, key);
- if (str.empty()) {
- return fuchsia::ui::policy::DisplayUsage::kUnknown;
- }
-
- // Keep in sync with
- // <https://fuchsia.googlesource.com/topaz/+/master/lib/base_shell/lib/session_shell_chooser.dart#64>.
- if (str == "handheld") {
- return fuchsia::ui::policy::DisplayUsage::kHandheld;
- } else if (str == "close") {
- return fuchsia::ui::policy::DisplayUsage::kClose;
- } else if (str == "near") {
- return fuchsia::ui::policy::DisplayUsage::kNear;
- } else if (str == "midrange") {
- return fuchsia::ui::policy::DisplayUsage::kMidrange;
- } else if (str == "far") {
- return fuchsia::ui::policy::DisplayUsage::kFar;
- } else {
- FXL_LOG(WARNING) << "unknown display usage string: " << str;
- return fuchsia::ui::policy::DisplayUsage::kUnknown;
- }
-};
-
-// Given a |json| string, parses it into list of session shell settings.
-std::vector<SessionShellSettings> ParseSessionShellSettings(
- const std::string& json) {
- std::vector<SessionShellSettings> settings;
-
- rapidjson::Document document;
- document.Parse(json.c_str());
- if (document.HasParseError()) {
- FXL_LOG(ERROR) << "ParseSessionShellSettings(): parse error "
- << document.GetParseError();
- return settings;
- }
-
- if (!document.IsArray()) {
- FXL_LOG(ERROR) << "ParseSessionShellSettings(): root item isn't an array";
- return settings;
- }
-
- if (document.Empty()) {
- FXL_LOG(ERROR) << "ParseSessionShellSettings(): root array is empty";
- return settings;
- }
-
- settings.reserve(document.Size());
-
- for (rapidjson::SizeType i = 0; i < document.Size(); i++) {
- using modular::internal::GetObjectValue;
-
- const auto& session_shell = document[i];
-
- const auto& name = GetObjectValue<std::string>(session_shell, "name");
- if (name.empty())
- continue;
-
- settings.push_back({
- .name = GetObjectValue<std::string>(session_shell, "name"),
- .screen_width = GetObjectValue<float>(session_shell, "screen_width"),
- .screen_height = GetObjectValue<float>(session_shell, "screen_height"),
- .display_usage = GetObjectValue<fuchsia::ui::policy::DisplayUsage>(
- session_shell, "display_usage"),
- });
- }
-
- return settings;
-}
-
-} // namespace internal
-
-const std::vector<SessionShellSettings>&
-SessionShellSettings::GetSystemSettings() {
- // This method is intentionally thread-hostile to keep things simple, and
- // needs modification to be thread-safe or thread-compatible.
-
- if (g_system_settings) {
- return *g_system_settings;
- }
-
- g_system_settings = new std::vector<SessionShellSettings>;
-
- std::string json;
- if (!files::ReadFileToString(kBaseShellConfigJsonPath, &json)) {
- FXL_LOG(ERROR) << kBaseShellConfigJsonPath << ": read failed";
-
- return *g_system_settings;
- }
-
- *g_system_settings = internal::ParseSessionShellSettings(json);
- return *g_system_settings;
-}
-
-bool operator==(const SessionShellSettings& lhs,
- const SessionShellSettings& rhs) {
- auto float_eq = [](float f, float g) {
- // OK to do direct float comparison here, since we want bitwise value
- // equality.
- if (f == g)
- return true;
-
- if (std::isnan(f) && std::isnan(g))
- return true;
-
- return false;
- };
-
- return lhs.name == rhs.name && float_eq(lhs.screen_width, rhs.screen_width) &&
- float_eq(lhs.screen_height, rhs.screen_height) &&
- lhs.display_usage == rhs.display_usage;
-}
-
-} // namespace modular
diff --git a/lib/session_shell_settings/session_shell_settings.h b/lib/session_shell_settings/session_shell_settings.h
deleted file mode 100644
index 2b7fce4..0000000
--- a/lib/session_shell_settings/session_shell_settings.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_SESSION_SHELL_SETTINGS_SESSION_SHELL_SETTINGS_H_
-#define PERIDOT_LIB_SESSION_SHELL_SETTINGS_SESSION_SHELL_SETTINGS_H_
-
-#include <vector>
-
-#include <fuchsia/ui/policy/cpp/fidl.h>
-
-namespace modular {
-
-// A data structure representing Session Shell Settings. See
-// |kBaseShellConfigJsonPath| in session_shell_settings.cc for the path name and
-// JSON that this is intended to represent.
-struct SessionShellSettings {
- // Returns the session shell settings for the system. This is guaranteed to be
- // O(1). This is thread-unsafe; callers can safely call this method if callers
- // synchronize access.
- static const std::vector<SessionShellSettings>& GetSystemSettings();
-
- // The name of the session shell, e.g. "ermine".
- const std::string name;
-
- // The screen width & height in millimeters for the session shell's display.
- // Defaults to a signaling NaN so that any attempts to use it without checking
- // for NaN will trap.
- const float screen_width = std::numeric_limits<float>::signaling_NaN();
- const float screen_height = std::numeric_limits<float>::signaling_NaN();
-
- // The display usage policy for this session shell.
- const fuchsia::ui::policy::DisplayUsage display_usage =
- fuchsia::ui::policy::DisplayUsage::kUnknown;
-};
-
-bool operator==(const SessionShellSettings& lhs,
- const SessionShellSettings& rhs);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_SESSION_SHELL_SETTINGS_SESSION_SHELL_SETTINGS_H_
diff --git a/lib/session_shell_settings/session_shell_settings_test.cc b/lib/session_shell_settings/session_shell_settings_test.cc
deleted file mode 100644
index 3c5923f..0000000
--- a/lib/session_shell_settings/session_shell_settings_test.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/session_shell_settings/session_shell_settings.h"
-
-#include <cmath>
-
-#include "gtest/gtest.h"
-#include "rapidjson/document.h"
-
-namespace modular {
-
-namespace internal {
-
-// Expose some functions in modular::internal for testing.
-
-template <typename T>
-T GetObjectValue(const rapidjson::Value& object, const std::string& field_name);
-
-extern template std::string GetObjectValue<std::string>(
- const rapidjson::Value& object, const std::string& field_name);
-
-extern template float GetObjectValue<float>(const rapidjson::Value& object,
- const std::string& field_name);
-
-extern template fuchsia::ui::policy::DisplayUsage
-GetObjectValue<fuchsia::ui::policy::DisplayUsage>(
- const rapidjson::Value& object, const std::string& field_name);
-
-std::vector<SessionShellSettings> ParseSessionShellSettings(const std::string& json);
-
-} // namespace internal
-
-namespace {
-
-using modular::internal::GetObjectValue;
-
-TEST(SessionShellSettingsTest,
- GetObjectValue_String_ReturnsEmptyStringOnNonStringType) {
- rapidjson::Document doc;
- std::string s;
-
- doc.Parse("5");
- s = GetObjectValue<std::string>(doc, "foo");
- EXPECT_EQ(s, "");
-
- doc.Parse("[]");
- s = GetObjectValue<std::string>(doc, "foo");
- EXPECT_EQ(s, "");
-
- doc.Parse("\"hi\"");
- s = GetObjectValue<std::string>(doc, "foo");
- EXPECT_EQ(s, "");
-}
-
-TEST(SessionShellSettingsTest, GetObjectValue_String) {
- rapidjson::Document doc;
- doc.Parse("{ \"foo\": \"bar\" }");
-
- const std::string& s = GetObjectValue<std::string>(doc, "foo");
- EXPECT_EQ(s, "bar");
-}
-
-TEST(SessionShellSettingsTest, GetObjectValue_Float_FailedParse) {
- rapidjson::Document doc;
- doc.Parse("{ \"foo\": \"bar\" }");
-
- const float f = GetObjectValue<float>(doc, "foo");
- EXPECT_TRUE(std::isnan(f));
-}
-
-TEST(SessionShellSettingsTest, GetObjectValue_Float_SuccessfulParse) {
- rapidjson::Document doc;
- doc.Parse("{ \"foo\": \"3.141\" }");
-
- const float f = GetObjectValue<float>(doc, "foo");
- EXPECT_FLOAT_EQ(f, 3.141f);
-}
-
-TEST(SessionShellSettingsTest, GetObjectValue_DisplayUsage_FailedParse) {
- using DisplayUsage = fuchsia::ui::policy::DisplayUsage;
-
- rapidjson::Document doc;
- doc.Parse("{ \"foo\": \"bar\" }");
-
- const DisplayUsage e = GetObjectValue<DisplayUsage>(doc, "foo");
- EXPECT_EQ(e, DisplayUsage::kUnknown);
-}
-
-TEST(SessionShellSettingsTest, GetObjectValue_DisplayUsage_SuccessfulParse) {
- using DisplayUsage = fuchsia::ui::policy::DisplayUsage;
-
- rapidjson::Document doc;
- doc.Parse("{ \"foo\": \"midrange\" }");
-
- const DisplayUsage e = GetObjectValue<DisplayUsage>(doc, "foo");
- EXPECT_EQ(e, DisplayUsage::kMidrange);
-}
-
-TEST(SessionShellSettingsTest, ParseSessionShellSettings_ParseError) {
- EXPECT_EQ(internal::ParseSessionShellSettings("a"),
- std::vector<SessionShellSettings>());
- EXPECT_EQ(internal::ParseSessionShellSettings("{}"),
- std::vector<SessionShellSettings>());
-}
-
-TEST(SessionShellSettingsTest, ParseSessionShellSettings_ParseEmptyList) {
- EXPECT_EQ(internal::ParseSessionShellSettings("[]"),
- std::vector<SessionShellSettings>());
-}
-
-TEST(SessionShellSettingsTest, ParseSessionShellSettings_ParseNameOnly) {
- using DisplayUsage = fuchsia::ui::policy::DisplayUsage;
-
- const auto& settings =
- internal::ParseSessionShellSettings(R"( [{ "name": "example_name" }] )")
- .at(0);
-
- EXPECT_EQ(settings.name, "example_name");
- EXPECT_TRUE(std::isnan(settings.screen_width));
- EXPECT_TRUE(std::isnan(settings.screen_height));
- EXPECT_EQ(settings.display_usage, DisplayUsage::kUnknown);
-}
-
-TEST(SessionShellSettingsTest, ParseSessionShellSettings_ParseCompleteEntry) {
- using DisplayUsage = fuchsia::ui::policy::DisplayUsage;
-
- const auto& settings = internal::ParseSessionShellSettings(
- R"( [{ "name": "example_name",
- "screen_width": "3.14",
- "screen_height": "2.718",
- "display_usage": "close" }] )")
- .at(0);
-
- EXPECT_EQ(settings.name, "example_name");
- EXPECT_FLOAT_EQ(settings.screen_width, 3.14f);
- EXPECT_FLOAT_EQ(settings.screen_height, 2.718f);
- EXPECT_EQ(settings.display_usage, DisplayUsage::kClose);
-}
-
-TEST(SessionShellSettingsTest, ParseSessionShellSettings_ParseThreeEntries) {
- const auto& vector = internal::ParseSessionShellSettings(
- R"( [{ "name": "example_name1" },
- { "name": "example_name2" },
- { "name": "example_name3" }] )");
-
- EXPECT_EQ(vector.size(), 3u);
-}
-
-} // namespace
-
-} // namespace modular
diff --git a/lib/socket/BUILD.gn b/lib/socket/BUILD.gn
deleted file mode 100644
index 92ac9c8..0000000
--- a/lib/socket/BUILD.gn
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [
- "//peridot/bin/*",
- "//peridot/lib/*",
-]
-
-source_set("socket") {
- sources = [
- "socket_drainer_client.cc",
- "socket_drainer_client.h",
- "socket_pair.h",
- "socket_writer.cc",
- "socket_writer.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/callback",
- "//zircon/public/lib/zx",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "socket_drainer_client_unittest.cc",
- "socket_writer_unittest.cc",
- ]
-
- deps = [
- ":socket",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/lib/socket/socket_drainer_client.cc b/lib/socket/socket_drainer_client.cc
deleted file mode 100644
index 619e820..0000000
--- a/lib/socket/socket_drainer_client.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/socket/socket_drainer_client.h"
-
-#include <utility>
-
-#include <lib/fit/function.h>
-
-namespace socket {
-
-SocketDrainerClient::SocketDrainerClient() : drainer_(this) {}
-
-SocketDrainerClient::~SocketDrainerClient() {}
-
-void SocketDrainerClient::Start(zx::socket source,
- fit::function<void(std::string)> callback) {
- callback_ = std::move(callback);
- drainer_.Start(std::move(source));
-}
-
-void SocketDrainerClient::OnDataAvailable(const void* data, size_t num_bytes) {
- data_.append(static_cast<const char*>(data), num_bytes);
-}
-
-void SocketDrainerClient::OnDataComplete() {
- if (destruction_sentinel_.DestructedWhile([this] { callback_(data_); })) {
- return;
- }
- if (on_empty_callback_) {
- on_empty_callback_();
- }
-}
-
-} // namespace socket
diff --git a/lib/socket/socket_drainer_client.h b/lib/socket/socket_drainer_client.h
deleted file mode 100644
index 6153779..0000000
--- a/lib/socket/socket_drainer_client.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_SOCKET_SOCKET_DRAINER_CLIENT_H_
-#define PERIDOT_LIB_SOCKET_SOCKET_DRAINER_CLIENT_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-
-#include <lib/callback/destruction_sentinel.h>
-#include <lib/fit/function.h>
-#include <lib/fsl/socket/socket_drainer.h>
-#include <lib/fxl/macros.h>
-
-namespace socket {
-
-class SocketDrainerClient : public fsl::SocketDrainer::Client {
- public:
- SocketDrainerClient();
-
- ~SocketDrainerClient() override;
-
- void Start(zx::socket source, fit::function<void(std::string)> callback);
-
- void set_on_empty(fit::closure on_empty_callback) {
- on_empty_callback_ = std::move(on_empty_callback);
- }
-
- private:
- void OnDataAvailable(const void* data, size_t num_bytes) override;
-
- void OnDataComplete() override;
-
- fit::function<void(std::string)> callback_;
- std::string data_;
- fsl::SocketDrainer drainer_;
- fit::closure on_empty_callback_;
- callback::DestructionSentinel destruction_sentinel_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SocketDrainerClient);
-};
-
-} // namespace socket
-
-#endif // PERIDOT_LIB_SOCKET_SOCKET_DRAINER_CLIENT_H_
diff --git a/lib/socket/socket_drainer_client_unittest.cc b/lib/socket/socket_drainer_client_unittest.cc
deleted file mode 100644
index cbd1c08..0000000
--- a/lib/socket/socket_drainer_client_unittest.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/socket/socket_drainer_client.h"
-
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/lib/socket/socket_pair.h"
-
-namespace socket {
-namespace {
-
-using SocketDrainerClientTest = gtest::TestLoopFixture;
-
-// Regression test for LE-229.
-TEST_F(SocketDrainerClientTest, DoNotCallOnDelete) {
- socket::SocketPair socket;
- socket.socket1.reset();
-
- auto drainer = std::make_unique<SocketDrainerClient>();
- bool called = false;
- drainer->set_on_empty([&called] { called = true; });
- drainer->Start(std::move(socket.socket2),
- [&drainer](const std::string& v) { drainer.reset(); });
- RunLoopUntilIdle();
- EXPECT_FALSE(called);
-}
-
-} // namespace
-} // namespace socket
diff --git a/lib/socket/socket_pair.h b/lib/socket/socket_pair.h
deleted file mode 100644
index bddf2ca..0000000
--- a/lib/socket/socket_pair.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_SOCKET_SOCKET_PAIR_H_
-#define PERIDOT_LIB_SOCKET_SOCKET_PAIR_H_
-
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/zx/socket.h>
-
-namespace socket {
-
-// SocketPair produces a pair of connected sockets.
-class SocketPair {
- public:
- SocketPair();
- ~SocketPair();
-
- zx::socket socket1;
- zx::socket socket2;
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(SocketPair);
-};
-
-inline SocketPair::SocketPair() {
- FXL_CHECK(zx::socket::create(0u, &socket1, &socket2) == ZX_OK);
-}
-
-inline SocketPair::~SocketPair() {}
-
-} // namespace socket
-
-#endif // PERIDOT_LIB_SOCKET_SOCKET_PAIR_H_
diff --git a/lib/socket/socket_writer.cc b/lib/socket/socket_writer.cc
deleted file mode 100644
index 10f5991..0000000
--- a/lib/socket/socket_writer.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/socket/socket_writer.h"
-
-#include <string.h>
-#include <algorithm>
-#include <utility>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/logging.h>
-
-namespace socket {
-
-// TODO(qsr): Remove this, and retrieve the buffer size from the socket when
-// available.
-constexpr size_t kDefaultSocketBufferSize = 256 * 1024u;
-
-SocketWriter::SocketWriter(Client* client, async_dispatcher_t* dispatcher)
- : client_(client), dispatcher_(dispatcher) {
- wait_.set_trigger(ZX_SOCKET_WRITABLE | ZX_SOCKET_PEER_CLOSED);
- wait_.set_handler(
- [this](async_dispatcher_t* dispatcher, async::Wait* wait,
- zx_status_t status,
- const zx_packet_signal_t* signal) { WriteData(data_view_); });
-}
-
-SocketWriter::~SocketWriter() = default;
-
-void SocketWriter::Start(zx::socket destination) {
- destination_ = std::move(destination);
- wait_.Cancel();
- wait_.set_object(destination_.get());
- GetData();
-}
-
-void SocketWriter::GetData() {
- FXL_DCHECK(data_.empty());
- wait_.Cancel();
- client_->GetNext(offset_, kDefaultSocketBufferSize,
- [this](fxl::StringView data) {
- if (data.empty()) {
- Done();
- return;
- }
- offset_ += data.size();
- WriteData(data);
- });
-}
-
-void SocketWriter::WriteData(fxl::StringView data) {
- zx_status_t status = ZX_OK;
- while (status == ZX_OK && !data.empty()) {
- size_t written;
- status = destination_.write(0u, data.data(), data.size(), &written);
- if (status == ZX_OK) {
- data = data.substr(written);
- }
- }
-
- if (status == ZX_OK) {
- FXL_DCHECK(data.empty());
- data_.clear();
- data_view_ = "";
- GetData();
- return;
- }
-
- FXL_DCHECK(!data.empty());
-
- if (status == ZX_ERR_PEER_CLOSED) {
- Done();
- return;
- }
-
- if (status == ZX_ERR_SHOULD_WAIT) {
- if (data_.empty()) {
- data_ = data.ToString();
- data_view_ = data_;
- } else {
- data_view_ = data;
- }
- if (!wait_.is_pending())
- wait_.Begin(dispatcher_);
- return;
- }
- FXL_DCHECK(false) << "Unhandled zx_status_t: " << status;
-}
-
-void SocketWriter::Done() {
- wait_.Cancel();
- destination_.reset();
- client_->OnDataComplete();
-}
-
-StringSocketWriter::StringSocketWriter(async_dispatcher_t* dispatcher)
- : socket_writer_(this, dispatcher) {}
-
-void StringSocketWriter::Start(std::string data, zx::socket destination) {
- data_ = std::move(data);
- socket_writer_.Start(std::move(destination));
-}
-
-void StringSocketWriter::GetNext(
- size_t offset, size_t max_size,
- fit::function<void(fxl::StringView)> callback) {
- fxl::StringView data = data_;
- callback(data.substr(offset, max_size));
-}
-
-void StringSocketWriter::OnDataComplete() { delete this; }
-
-} // namespace socket
diff --git a/lib/socket/socket_writer.h b/lib/socket/socket_writer.h
deleted file mode 100644
index 411c836..0000000
--- a/lib/socket/socket_writer.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_SOCKET_SOCKET_WRITER_H_
-#define PERIDOT_LIB_SOCKET_SOCKET_WRITER_H_
-
-#include <functional>
-#include <memory>
-#include <string>
-
-#include <lib/async/cpp/wait.h>
-#include <lib/async/default.h>
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/zx/socket.h>
-
-namespace socket {
-
-// Requests data to write from its client. Interrupts itself and closes the
-// socket when deleted.
-class SocketWriter {
- public:
- class Client {
- public:
- virtual void GetNext(size_t offset, size_t max_size,
- fit::function<void(fxl::StringView)> callback) = 0;
- virtual void OnDataComplete() = 0;
-
- protected:
- virtual ~Client() {}
- };
-
- explicit SocketWriter(Client* client, async_dispatcher_t* dispatcher =
- async_get_default_dispatcher());
- ~SocketWriter();
-
- void Start(zx::socket destination);
-
- private:
- void GetData();
- void WriteData(fxl::StringView data);
- void Done();
-
- Client* const client_;
- async_dispatcher_t* const dispatcher_;
- // Position of the next byte to request.
- size_t offset_ = 0u;
- // Data left to send from last call to |GetNext|.
- std::string data_;
- // Data left to send.
- fxl::StringView data_view_;
- zx::socket destination_;
- async::Wait wait_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SocketWriter);
-};
-
-// Writes the content of a string to a socket. Deletes itself when done.
-class StringSocketWriter : public SocketWriter::Client {
- public:
- explicit StringSocketWriter(
- async_dispatcher_t* dispatcher = async_get_default_dispatcher());
-
- void Start(std::string data, zx::socket destination);
-
- private:
- void GetNext(size_t offset, size_t max_size,
- fit::function<void(fxl::StringView)> callback) override;
- void OnDataComplete() override;
-
- SocketWriter socket_writer_;
- std::string data_;
-};
-
-} // namespace socket
-
-#endif // PERIDOT_LIB_SOCKET_SOCKET_WRITER_H_
diff --git a/lib/socket/socket_writer_unittest.cc b/lib/socket/socket_writer_unittest.cc
deleted file mode 100644
index 1f8acdd..0000000
--- a/lib/socket/socket_writer_unittest.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/socket/socket_writer.h"
-
-#include <utility>
-
-#include <lib/fit/function.h>
-#include <lib/fxl/macros.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "peridot/lib/socket/socket_drainer_client.h"
-#include "peridot/lib/socket/socket_pair.h"
-
-namespace socket {
-namespace {
-
-using SocketWriterTest = gtest::TestLoopFixture;
-
-class StringClient : public SocketWriter::Client {
- public:
- explicit StringClient(std::string value) : value_(std::move(value)) {}
-
- void GetNext(size_t offset, size_t max_size,
- fit::function<void(fxl::StringView)> callback) override {
- fxl::StringView data = value_;
- callback(data.substr(offset, max_size));
- }
-
- void OnDataComplete() override { completed_ = true; }
-
- bool completed() { return completed_; }
-
- private:
- std::string value_;
- bool completed_ = false;
-};
-
-TEST_F(SocketWriterTest, WriteAndRead) {
- SocketPair socket;
- StringClient client("bazinga\n");
- SocketWriter writer(&client);
- writer.Start(std::move(socket.socket1));
-
- std::string value;
- auto drainer = std::make_unique<SocketDrainerClient>();
- drainer->Start(std::move(socket.socket2),
- [&value](const std::string& v) { value = v; });
- RunLoopUntilIdle();
-
- EXPECT_EQ("bazinga\n", value);
- EXPECT_TRUE(client.completed());
-}
-
-TEST_F(SocketWriterTest, ClientClosedTheirEnd) {
- SocketPair socket;
- StringClient client("bazinga\n");
- SocketWriter writer(&client);
- socket.socket2.reset();
- writer.Start(std::move(socket.socket1));
- EXPECT_TRUE(client.completed());
-}
-
-TEST_F(SocketWriterTest, StringSocketWriter) {
- SocketPair socket;
- StringSocketWriter* writer = new StringSocketWriter();
- writer->Start("bazinga\n", std::move(socket.socket1));
-
- std::string value;
- auto drainer = std::make_unique<SocketDrainerClient>();
- drainer->Start(std::move(socket.socket2),
- [&value](const std::string& v) { value = v; });
- RunLoopUntilIdle();
-
- EXPECT_EQ("bazinga\n", value);
-}
-
-} // namespace
-} // namespace socket
diff --git a/lib/testing/BUILD.gn b/lib/testing/BUILD.gn
deleted file mode 100644
index 0b9ddba..0000000
--- a/lib/testing/BUILD.gn
+++ /dev/null
@@ -1,286 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("component_base") {
- testonly = true
-
- sources = [
- "component_base.h",
- ]
-
- public_deps = [
- ":component_main",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:single_service_app",
- "//peridot/public/lib/integration_testing/cpp",
- ]
-}
-
-source_set("component_main") {
- testonly = true
-
- sources = [
- "component_main.h",
- ]
-
- public_deps = [
- "//peridot/public/lib/app_driver/cpp:app_driver",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-source_set("component_context_fake") {
- testonly = true
-
- sources = [
- "component_context_fake.cc",
- "component_context_fake.h",
- ]
-
- public_deps = [
- ":entity_resolver_fake",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("entity_resolver_fake") {
- testonly = true
-
- sources = [
- "entity_resolver_fake.cc",
- "entity_resolver_fake.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("module_resolver_fake") {
- testonly = true
-
- sources = [
- "module_resolver_fake.cc",
- "module_resolver_fake.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fidl/cpp",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("module_facet_reader_fake") {
- testonly = true
-
- sources = [
- "module_facet_reader_fake.cc",
- "module_facet_reader_fake.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/lib/module_manifest:module_facet_reader",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("session_shell_base") {
- testonly = true
-
- sources = [
- "session_shell_base.h",
- ]
-
- public_deps = [
- ":component_base",
- ":session_shell_impl",
- ]
-}
-
-source_set("session_shell_impl") {
- testonly = true
-
- sources = [
- "session_shell_impl.cc",
- "session_shell_impl.h",
- ]
-
- public_deps = [
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-source_set("story_controller_mock") {
- testonly = true
-
- sources = [
- "story_controller_mock.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- ]
-}
-
-source_set("story_provider_mock") {
- testonly = true
-
- sources = [
- "story_provider_mock.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-
- deps = [
- ":story_controller_mock",
- "//garnet/public/lib/fidl/cpp",
- ]
-}
-
-source_set("test_story_command_executor") {
- testonly = true
-
- sources = [
- "test_story_command_executor.cc",
- "test_story_command_executor.h",
- ]
-
- deps = [
- "//peridot/bin/sessionmgr/puppet_master:story_command_executor",
- "//peridot/lib/fidl:clone",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("test_with_ledger") {
- testonly = true
-
- sources = [
- "test_with_ledger.cc",
- "test_with_ledger.h",
- ]
-
- public_deps = [
- ":ledger_repository_for_testing",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//peridot/lib/ledger_client:page_client",
- "//third_party/googletest:gtest",
- ]
-}
-
-source_set("test_with_session_storage") {
- testonly = true
-
- sources = [
- "test_with_session_storage.cc",
- "test_with_session_storage.h",
- ]
-
- public_deps = [
- ":test_with_ledger",
- "//peridot/bin/sessionmgr/storage",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("fake_agent_runner_storage") {
- testonly = true
-
- sources = [
- "fake_agent_runner_storage.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/sessionmgr/agent_runner:public",
- ]
-}
-
-source_set("ledger_repository_for_testing") {
- testonly = true
-
- sources = [
- "ledger_repository_for_testing.cc",
- "ledger_repository_for_testing.h",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/bin/ledger/fidl",
- "//peridot/lib/common:teardown",
- "//peridot/lib/fidl:app_client",
- "//peridot/lib/ledger_client:constants",
- "//peridot/lib/ledger_client:status",
- "//peridot/public/fidl/fuchsia.ledger",
- ]
-
- public_deps = [
- "//peridot/lib/scoped_tmpfs",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("mock_base") {
- testonly = true
-
- sources = [
- "mock_base.cc",
- "mock_base.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//third_party/googletest:gtest",
- ]
-}
-
-source_set("wait_until_idle") {
- testonly = true
-
- sources = [
- "wait_until_idle.h",
- ]
-
- public_deps = [
- "//zircon/public/lib/async-loop-cpp",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//third_party/googletest:gtest",
- ]
-}
-
-source_set("test_driver") {
- sources = [
- "test_driver.h",
- ]
-}
diff --git a/lib/testing/README.md b/lib/testing/README.md
deleted file mode 100644
index 0110c2f..0000000
--- a/lib/testing/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Here is code that helps clients of modular with testing.
-
-When linked against the `//peridot/lib/testing` library target, a test
-application can use the functions in `lib/testing/testing.h` to interact with
-the `TestRunner` service in its environment. This is the standard way to test
-multi-process modular applications; these functions allow a test to declare
-failure, and signal tear down of tests to the TestRunner service.
-
-See [//peridot/tests](/peridot/tests) for more details on running
-tests.
diff --git a/lib/testing/component_base.h b/lib/testing/component_base.h
deleted file mode 100644
index cec380d..0000000
--- a/lib/testing/component_base.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_COMPONENT_BASE_H_
-#define PERIDOT_LIB_TESTING_COMPONENT_BASE_H_
-
-#include <lib/component/cpp/connect.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/lib/fidl/single_service_app.h"
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-
-namespace modular {
-namespace testing {
-
-// A base class for components used in tests. It helps them to exit the
-// application at the end of the life cycle while properly posting test points
-// and calling TestRunner::Done().
-//
-// Component is fuchsia::modular::Module, fuchsia::modular::Agent,
-// fuchsia::modular::SessionShell, etc.
-template <typename Component>
-class ComponentBase : protected SingleServiceApp<Component> {
- public:
- void Terminate(std::function<void()> done) override {
- modular::testing::Done(done);
- }
-
- protected:
- // Invocations of methods of the base class must be unambiguously recognizable
- // by the compiler as method invocations at the point of template definition,
- // because the base class depends on the template parameter. This can be
- // accomplished either by class name prefix or by prepending this->. Without
- // either, the calls are assumed to be function calls that are unresolved (and
- // marked as error by the compiler) at template definition. Essentially, the
- // class name prefix turns the independent name into a dependent
- // name. Cf. http://en.cppreference.com/w/cpp/language/dependent_name.
- using Base = SingleServiceApp<Component>;
-
- ComponentBase(component::StartupContext* const startup_context)
- : Base(startup_context), weak_factory_(this) {}
-
- ~ComponentBase() override = default;
-
- // We must not call testing::Init() in the base class
- // constructor, because that's before the test points are initialized. It's
- // fine to call this from the derived class constructor.
- void TestInit(const char* const file) {
- testing::Init(Base::startup_context(), file);
- }
-
- // Wraps the callback function into a layer that protects executing the
- // callback in the argument against execution after this instance is deleted,
- // using the weak pointer factory.
- std::function<void()> Protect(std::function<void()> callback) {
- return [ptr = weak_factory_.GetWeakPtr(), callback = std::move(callback)] {
- if (ptr) {
- callback();
- }
- };
- }
-
- private:
- // This weak ptr factory is not the last member in the derived class, so it
- // cannot be used to protect code executed in member destructors against
- // accessing this. But it is enough to protect callbacks sent to the runloop
- // against execution after the instance is deleted.
- fxl::WeakPtrFactory<ComponentBase> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ComponentBase);
-};
-
-template <>
-class ComponentBase<void> : protected ViewApp {
- public:
- void Terminate(std::function<void()> done) override {
- modular::testing::Done(done);
- }
-
- protected:
- ComponentBase(component::StartupContext* const startup_context)
- : ViewApp(startup_context), weak_factory_(this) {}
-
- ~ComponentBase() override = default;
-
- // We must not call testing::Init() in the base class
- // constructor, because that's before the test points are initialized. It's
- // fine to call this from the derived class constructor.
- void TestInit(const char* const file) {
- testing::Init(ViewApp::startup_context(), file);
- }
-
- // Wraps the callback function into a layer that protects executing the
- // callback in the argument against execution after this instance is deleted,
- // using the weak pointer factory.
- std::function<void()> Protect(std::function<void()> callback) {
- return [ptr = weak_factory_.GetWeakPtr(), callback = std::move(callback)] {
- if (ptr) {
- callback();
- }
- };
- }
-
- private:
- // This weak ptr factory is not the last member in the derived class, so it
- // cannot be used to protect code executed in member destructors against
- // accessing this. But it is enough to protect callbacks sent to the runloop
- // against execution after the instance is deleted.
- fxl::WeakPtrFactory<ComponentBase> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ComponentBase);
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_COMPONENT_BASE_H_
diff --git a/lib/testing/component_context_fake.cc b/lib/testing/component_context_fake.cc
deleted file mode 100644
index ed15150..0000000
--- a/lib/testing/component_context_fake.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/component_context_fake.h"
-
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-ComponentContextFake::ComponentContextFake() {}
-
-ComponentContextFake::~ComponentContextFake() = default;
-
-void ComponentContextFake::Connect(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void ComponentContextFake::GetLedger(
- fidl::InterfaceRequest<fuchsia::ledger::Ledger> request) {
- FXL_NOTIMPLEMENTED();
-}
-
-void ComponentContextFake::ConnectToAgent(
- std::string url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) {
- FXL_NOTIMPLEMENTED();
-}
-
-void ComponentContextFake::ObtainMessageQueue(
- std::string name,
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request) {
- FXL_NOTIMPLEMENTED();
-}
-
-void ComponentContextFake::DeleteMessageQueue(std::string name) {
- FXL_NOTIMPLEMENTED();
-}
-
-void ComponentContextFake::GetMessageSender(
- std::string queue_token,
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request) {
- FXL_NOTIMPLEMENTED();
-}
-
-void ComponentContextFake::GetEntityResolver(
- fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request) {
- entity_resolver_.Connect(std::move(request));
-}
-
-void ComponentContextFake::CreateEntityWithData(
- std::vector<fuchsia::modular::TypeToDataEntry> type_to_data,
- CreateEntityWithDataCallback result) {
- FXL_NOTIMPLEMENTED();
-}
-
-void ComponentContextFake::GetPackageName(GetPackageNameCallback result) {
- FXL_NOTIMPLEMENTED();
-}
-
-} // namespace modular
diff --git a/lib/testing/component_context_fake.h b/lib/testing/component_context_fake.h
deleted file mode 100644
index 6cad271..0000000
--- a/lib/testing/component_context_fake.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_COMPONENT_CONTEXT_FAKE_H_
-#define PERIDOT_LIB_TESTING_COMPONENT_CONTEXT_FAKE_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/testing/entity_resolver_fake.h"
-
-namespace modular {
-
-// A fake implementation of fuchsia::modular::ComponentContext for tests.
-// fuchsia::modular::ComponentContext gives clients access to further services.
-// This implementation returns fake versions of the various services in
-// question.
-//
-// Implemented:
-//
-// * GetEntityResolver() -> returns a FakeEntityResolver (see
-// lib/entity/cpp/testing/fake_entity_resolver.h).
-// * CreateEntityWithData() -> returns a reference that the FakeEntityResolver
-// will resolve.
-class ComponentContextFake : public fuchsia::modular::ComponentContext {
- public:
- ComponentContextFake();
- ~ComponentContextFake() override;
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request);
-
- EntityResolverFake& entity_resolver_fake() { return entity_resolver_; }
-
- private:
- // |fuchsia::modular::ComponentContext|
- void GetLedger(
- fidl::InterfaceRequest<fuchsia::ledger::Ledger> request) override;
-
- // |fuchsia::modular::ComponentContext|
- void ConnectToAgent(std::string url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- incoming_services_request,
- fidl::InterfaceRequest<fuchsia::modular::AgentController>
- agent_controller_request) override;
-
- // |fuchsia::modular::ComponentContext|
- void ObtainMessageQueue(
- std::string name,
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request) override;
-
- // |fuchsia::modular::ComponentContext|
- void DeleteMessageQueue(std::string name) override;
-
- // |fuchsia::modular::ComponentContext|
- void GetMessageSender(
- std::string queue_token,
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> request) override;
-
- // |fuchsia::modular::ComponentContext|
- void GetEntityResolver(
- fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request)
- override;
-
- // |fuchsia::modular::ComponentContext|
- void CreateEntityWithData(
- std::vector<fuchsia::modular::TypeToDataEntry> type_to_data,
- CreateEntityWithDataCallback result) override;
-
- // |fuchsia::modular::ComponentContext|
- void GetPackageName(GetPackageNameCallback result) override;
-
- EntityResolverFake entity_resolver_;
-
- fidl::BindingSet<fuchsia::modular::ComponentContext> bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ComponentContextFake);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_COMPONENT_CONTEXT_FAKE_H_
diff --git a/lib/testing/component_main.h b/lib/testing/component_main.h
deleted file mode 100644
index 6f69368..0000000
--- a/lib/testing/component_main.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_COMPONENT_MAIN_H_
-#define PERIDOT_LIB_TESTING_COMPONENT_MAIN_H_
-
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-
-namespace modular {
-namespace testing {
-
-// A main function for an application that only runs the implementation of a
-// single component used for integration testing. The component implementation
-// Impl usually derives from ComponentBase.
-//
-// Args are meant to be either nothing or the instance of a Settings class
-// initialized from the command line arguments. They are just passed as
-// additional constructor arguments to Impl.
-//
-// Example use with settings (TestApp and Settings are locally defined classes):
-//
-// int main(int argc, const char** argv) {
-// auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
-// Settings settings(command_line);
-// modular::testing::ComponentMain<TestApp, Settings>(std::move(settings));
-// return 0;
-// }
-//
-// Example use without settings (TestApp is a locally defined class):
-//
-// int main(int, const char**) {
-// modular::testing::ComponentMain<TestApp>();
-// return 0;
-// }
-//
-// The classes ComponentBase and SessionShellBase defined in this directory are
-// meant to be used as base classes for Impl.
-template <typename Impl, typename... Args>
-void ComponentMain(Args... args) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
-
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AppDriver<Impl> driver(
- context->outgoing().deprecated_services(),
- std::make_unique<Impl>(context.get(), std::move(args)...),
- [&loop] { loop.Quit(); });
-
- loop.Run();
-}
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_COMPONENT_MAIN_H_
diff --git a/lib/testing/entity_resolver_fake.cc b/lib/testing/entity_resolver_fake.cc
deleted file mode 100644
index a8bc2af..0000000
--- a/lib/testing/entity_resolver_fake.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/entity_resolver_fake.h"
-
-#include <lib/fsl/vmo/strings.h>
-
-namespace modular {
-
-class EntityResolverFake::EntityImpl : fuchsia::modular::Entity {
- public:
- EntityImpl(std::map<std::string, std::string> types_and_data)
- : types_and_data_(types_and_data) {}
-
- void Connect(fidl::InterfaceRequest<fuchsia::modular::Entity> request) {
- bindings_.AddBinding(this, std::move(request));
- }
-
- private:
- // |fuchsia::modular::Entity|
- void GetTypes(GetTypesCallback callback) override {
- std::vector<std::string> types;
- for (const auto& entry : types_and_data_) {
- types.push_back(entry.first);
- }
- callback(std::move(types));
- }
-
- // |fuchsia::modular::Entity|
- void GetData(std::string type, GetDataCallback callback) override {
- auto it = types_and_data_.find(type);
- if (it == types_and_data_.end()) {
- callback(nullptr);
- return;
- }
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(it->second, &vmo));
- auto vmo_ptr =
- std::make_unique<fuchsia::mem::Buffer>(std::move(vmo).ToTransport());
-
- callback(std::move(vmo_ptr));
- }
-
- // |fuchsia::modular::Entity|
- void WriteData(std::string type, fuchsia::mem::Buffer data,
- WriteDataCallback callback) override {
- // TODO(rosswang)
- callback(fuchsia::modular::EntityWriteStatus::READ_ONLY);
- }
-
- // |fuchsia::modular::Entity|
- void GetReference(GetReferenceCallback callback) override {
- // TODO(rosswang)
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::Entity|
- void Watch(
- std::string type,
- fidl::InterfaceHandle<fuchsia::modular::EntityWatcher> watcher) override {
- // TODO(MI4-1301)
- FXL_NOTIMPLEMENTED();
- }
-
- std::map<std::string, std::string> types_and_data_;
-
- fidl::BindingSet<fuchsia::modular::Entity> bindings_;
-};
-
-EntityResolverFake::EntityResolverFake() = default;
-EntityResolverFake::~EntityResolverFake() = default;
-
-void EntityResolverFake::Connect(
- fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-// Returns an fuchsia::modular::Entity reference that will resolve to an
-// fuchsia::modular::Entity. |types_and_data| is a map of data type to data
-// bytes.
-fidl::StringPtr EntityResolverFake::AddEntity(
- std::map<std::string, std::string> types_and_data) {
- const std::string id = std::to_string(next_entity_id_++);
-
- auto entity = std::make_unique<EntityImpl>(std::move(types_and_data));
- entities_.emplace(id, std::move(entity));
- return id;
-}
-
-void EntityResolverFake::ResolveEntity(
- std::string entity_reference,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request) {
- auto it = entities_.find(entity_reference);
- if (it == entities_.end()) {
- return; // |entity_request| is reset here.
- }
-
- it->second->Connect(std::move(entity_request));
-}
-
-} // namespace modular
diff --git a/lib/testing/entity_resolver_fake.h b/lib/testing/entity_resolver_fake.h
deleted file mode 100644
index 82e353c..0000000
--- a/lib/testing/entity_resolver_fake.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_ENTITY_RESOLVER_FAKE_H_
-#define PERIDOT_LIB_TESTING_ENTITY_RESOLVER_FAKE_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fidl/cpp/string.h>
-#include <lib/fxl/macros.h>
-
-namespace modular {
-
-class EntityResolverFake : public fuchsia::modular::EntityResolver {
- public:
- EntityResolverFake();
- ~EntityResolverFake() override;
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request);
-
- // Returns an fuchsia::modular::Entity reference that will resolve to an
- // fuchsia::modular::Entity. |types_and_data| is a map of data type to data
- // bytes.
- fidl::StringPtr AddEntity(std::map<std::string, std::string> types_and_data);
-
- private:
- class EntityImpl;
-
- void ResolveEntity(
- std::string entity_reference,
- fidl::InterfaceRequest<fuchsia::modular::Entity> entity_request) override;
-
- int next_entity_id_{0};
- std::map<std::string, std::unique_ptr<EntityImpl>> entities_;
- fidl::BindingSet<fuchsia::modular::EntityResolver> bindings_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_ENTITY_RESOLVER_FAKE_H_
diff --git a/lib/testing/fake_agent_runner_storage.h b/lib/testing/fake_agent_runner_storage.h
deleted file mode 100644
index 224f110..0000000
--- a/lib/testing/fake_agent_runner_storage.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_FAKE_AGENT_RUNNER_STORAGE_H_
-#define PERIDOT_LIB_TESTING_FAKE_AGENT_RUNNER_STORAGE_H_
-
-#include <functional>
-#include <string>
-
-#include <lib/fxl/macros.h>
-
-#include "peridot/bin/sessionmgr/agent_runner/agent_runner_storage.h"
-
-namespace modular {
-namespace testing {
-
-class FakeAgentRunnerStorage : public AgentRunnerStorage {
- public:
- FakeAgentRunnerStorage() = default;
-
- // |AgentRunnerStorage|
- void Initialize(NotificationDelegate* /*delegate*/,
- const std::function<void()> done) override {
- done();
- }
-
- // |AgentRunnerStorage|
- void WriteTask(const std::string& /*agent_url*/, TriggerInfo /*info*/,
- const std::function<void(bool)> done) override {
- done(true);
- }
-
- // |AgentRunnerStorage|
- void DeleteTask(const std::string& /*agent_url*/,
- const std::string& /*task_id*/,
- const std::function<void(bool)> done) override {
- done(true);
- }
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FakeAgentRunnerStorage);
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_FAKE_AGENT_RUNNER_STORAGE_H_
diff --git a/lib/testing/ledger_repository_for_testing.cc b/lib/testing/ledger_repository_for_testing.cc
deleted file mode 100644
index 9fd148c..0000000
--- a/lib/testing/ledger_repository_for_testing.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/ledger_repository_for_testing.h"
-
-#include <utility>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fsl/io/fd.h>
-
-#include "peridot/lib/common/teardown.h"
-#include "peridot/lib/fidl/app_client.h"
-#include "peridot/lib/ledger_client/constants.h"
-#include "peridot/lib/ledger_client/status.h"
-
-namespace modular {
-
-namespace testing {
-
-LedgerRepositoryForTesting::LedgerRepositoryForTesting()
- : startup_context_(component::StartupContext::CreateFromStartupInfo()) {
- fuchsia::modular::AppConfig ledger_config;
- ledger_config.url = kLedgerAppUrl;
-
- auto& launcher = startup_context_->launcher();
- ledger_app_client_ =
- std::make_unique<AppClient<fuchsia::ledger::internal::LedgerController>>(
- launcher.get(), std::move(ledger_config));
-
- ledger_repo_factory_.set_error_handler([](zx_status_t status) {
- FXL_CHECK(false) << "LedgerRepositoryFactory returned an error. Status: "
- << LedgerEpitaphToString(status);
- });
- ledger_app_client_->services().ConnectToService(
- ledger_repo_factory_.NewRequest());
-}
-
-LedgerRepositoryForTesting::~LedgerRepositoryForTesting() = default;
-
-fuchsia::ledger::internal::LedgerRepository*
-LedgerRepositoryForTesting::ledger_repository() {
- if (!ledger_repo_) {
- ledger_repo_factory_->GetRepository(
- fsl::CloneChannelFromFileDescriptor(tmp_fs_.root_fd()), nullptr, "",
- ledger_repo_.NewRequest());
- }
-
- return ledger_repo_.get();
-}
-
-void LedgerRepositoryForTesting::Terminate(std::function<void()> done) {
- if (ledger_app_client_) {
- ledger_app_client_->Teardown(kBasicTimeout, [this, done] {
- ledger_repo_factory_.Unbind();
- ledger_app_client_.reset();
- done();
- });
-
- } else {
- done();
- }
-}
-
-} // namespace testing
-} // namespace modular
diff --git a/lib/testing/ledger_repository_for_testing.h b/lib/testing/ledger_repository_for_testing.h
deleted file mode 100644
index 5f1bfc9..0000000
--- a/lib/testing/ledger_repository_for_testing.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_LEDGER_REPOSITORY_FOR_TESTING_H_
-#define PERIDOT_LIB_TESTING_LEDGER_REPOSITORY_FOR_TESTING_H_
-
-#include <string>
-
-#include <fuchsia/ledger/cpp/fidl.h>
-#include <fuchsia/ledger/internal/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/fidl/app_client.h"
-#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
-
-namespace modular {
-namespace testing {
-
-// LedgerRepositoryForTesting spins up a ledger instance and acquires a ledger
-// repository meant to be used for testing, particularly in gtest unittests.
-class LedgerRepositoryForTesting {
- public:
- LedgerRepositoryForTesting();
- ~LedgerRepositoryForTesting();
-
- fuchsia::ledger::internal::LedgerRepository* ledger_repository();
-
- // Terminates the ledger repository app.
- void Terminate(std::function<void()> done);
-
- private:
- std::unique_ptr<component::StartupContext> startup_context_;
- scoped_tmpfs::ScopedTmpFS tmp_fs_;
- std::unique_ptr<AppClient<fuchsia::ledger::internal::LedgerController>>
- ledger_app_client_;
- fuchsia::ledger::internal::LedgerRepositoryFactoryPtr ledger_repo_factory_;
- fuchsia::ledger::internal::LedgerRepositoryPtr ledger_repo_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LedgerRepositoryForTesting);
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_LEDGER_REPOSITORY_FOR_TESTING_H_
diff --git a/lib/testing/mock_base.cc b/lib/testing/mock_base.cc
deleted file mode 100644
index c12cf90..0000000
--- a/lib/testing/mock_base.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/mock_base.h"
-
-#include <lib/fxl/logging.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace testing {
-
-MockBase::MockBase() = default;
-MockBase::~MockBase() = default;
-
-void MockBase::ExpectCalledOnce(const std::string& func) {
- EXPECT_EQ(1U, counts.count(func)) << "Expected 1 invocation of '" << func
- << "' but got " << counts.count(func);
- if (counts.count(func) > 0) {
- EXPECT_EQ(1U, counts[func]);
- counts.erase(func);
- }
-}
-
-void MockBase::ClearCalls() { counts.clear(); }
-
-void MockBase::ExpectNoOtherCalls() {
- EXPECT_TRUE(counts.empty());
- for (const auto& c : counts) {
- FXL_LOG(INFO) << " Unexpected call: " << c.first;
- }
-}
-
-} // namespace testing
-} // namespace modular
diff --git a/lib/testing/mock_base.h b/lib/testing/mock_base.h
deleted file mode 100644
index 7adb6fc..0000000
--- a/lib/testing/mock_base.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_MOCK_BASE_H_
-#define PERIDOT_LIB_TESTING_MOCK_BASE_H_
-
-#include <map>
-#include <string>
-
-namespace modular {
-namespace testing {
-
-// Helper class for unit testing that provides a collection to track the number
-// of times each function is called, then provides functions to validate those
-// calls.
-class MockBase {
- public:
- MockBase();
- virtual ~MockBase();
-
- // Validates that the given function was called once and removes that
- // information from the call history
- void ExpectCalledOnce(const std::string& func);
-
- // Removes the entire history of functions called
- void ClearCalls();
-
- // Validates that the call history is empty
- void ExpectNoOtherCalls();
-
- protected:
- std::map<std::string, unsigned int> counts;
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_MOCK_BASE_H_
diff --git a/lib/testing/module_facet_reader_fake.cc b/lib/testing/module_facet_reader_fake.cc
deleted file mode 100644
index 3174225..0000000
--- a/lib/testing/module_facet_reader_fake.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/module_facet_reader_fake.h"
-
-#include <lib/fxl/logging.h>
-
-namespace modular {
-
-void ModuleFacetReaderFake::SetGetModuleManifestSink(
- std::function<void(const std::string&, GetModuleManifestCallback)> sink) {
- sink_ = sink;
-}
-
-void ModuleFacetReaderFake::GetModuleManifest(
- const std::string& module_url, GetModuleManifestCallback callback) {
- if (sink_) {
- sink_(module_url, callback);
- } else {
- callback({});
- }
-}
-
-} // namespace modular
diff --git a/lib/testing/module_facet_reader_fake.h b/lib/testing/module_facet_reader_fake.h
deleted file mode 100644
index 7774b23..0000000
--- a/lib/testing/module_facet_reader_fake.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_MODULE_FACET_READER_FAKE_H_
-#define PERIDOT_LIB_TESTING_MODULE_FACET_READER_FAKE_H_
-
-#include "peridot/lib/module_manifest/module_facet_reader.h"
-
-#include <functional>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace modular {
-
-// A fake implementation of ModuleFacetReader used for testing. Use |set_sink()|
-// to capture GetModuleManifest calls.
-class ModuleFacetReaderFake : public ModuleFacetReader {
- public:
- // Call this method to supply a sink for
- // ModuleFacetReader.GetModuleManifest().
- void SetGetModuleManifestSink(
- std::function<void(const std::string&, GetModuleManifestCallback)> sink);
-
- private:
- // |modular::ModuleFacetReader|
- void GetModuleManifest(const std::string& module_url,
- GetModuleManifestCallback) override;
-
- std::function<void(const std::string&, GetModuleManifestCallback)> sink_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_MODULE_FACET_READER_FAKE_H_
diff --git a/lib/testing/module_resolver_fake.cc b/lib/testing/module_resolver_fake.cc
deleted file mode 100644
index 12125f4..0000000
--- a/lib/testing/module_resolver_fake.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/module_resolver_fake.h"
-
-namespace modular {
-
-ModuleResolverFake::ModuleResolverFake() {
- find_modules_response_.results.resize(0);
-}
-
-ModuleResolverFake::~ModuleResolverFake() = default;
-
-void ModuleResolverFake::SetStatus(fuchsia::modular::FindModulesStatus status) {
- find_modules_response_.status = status;
-}
-
-void ModuleResolverFake::FindModules(fuchsia::modular::FindModulesQuery query,
- FindModulesCallback callback) {
- if (find_modules_validate_fn_) {
- find_modules_validate_fn_(query);
- }
- callback(std::move(find_modules_response_));
-}
-
-void ModuleResolverFake::GetModuleManifest(std::string module_id,
- GetModuleManifestCallback callback) {
- if (get_module_manifest_validate_fn_) {
- get_module_manifest_validate_fn_(module_id);
- }
- callback(std::move(manifest_));
-}
-
-void ModuleResolverFake::FindModulesByTypes(
- fuchsia::modular::FindModulesByTypesQuery query,
- FindModulesByTypesCallback callback) {}
-
-void ModuleResolverFake::Connect(
- fidl::InterfaceRequest<fuchsia::modular::ModuleResolver> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
-void ModuleResolverFake::SetManifest(
- fuchsia::modular::ModuleManifestPtr manifest) {
- manifest_ = std::move(manifest);
-}
-
-void ModuleResolverFake::AddFindModulesResult(
- fuchsia::modular::FindModulesResult result) {
- find_modules_response_.results.push_back(std::move(result));
-}
-
-void ModuleResolverFake::SetFindModulesValidation(
- std::function<void(const fuchsia::modular::FindModulesQuery&)> fn) {
- find_modules_validate_fn_ = std::move(fn);
-}
-
-void ModuleResolverFake::SetGetModuleManifestValidation(
- std::function<void(const fidl::StringPtr&)> fn) {
- get_module_manifest_validate_fn_ = std::move(fn);
-}
-
-} // namespace modular
diff --git a/lib/testing/module_resolver_fake.h b/lib/testing/module_resolver_fake.h
deleted file mode 100644
index 73b967e..0000000
--- a/lib/testing/module_resolver_fake.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_MODULE_RESOLVER_FAKE_H_
-#define PERIDOT_LIB_TESTING_MODULE_RESOLVER_FAKE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-
-namespace modular {
-
-class ModuleResolverFake : fuchsia::modular::ModuleResolver {
- public:
- ModuleResolverFake();
- ~ModuleResolverFake() override;
-
- // |ModuleResolver|
- void FindModules(fuchsia::modular::FindModulesQuery query,
- FindModulesCallback callback) override;
-
- // |ModuleResolver|
- void GetModuleManifest(std::string module_id,
- GetModuleManifestCallback callback) override;
-
- // |ModuleResolver|
- void FindModulesByTypes(fuchsia::modular::FindModulesByTypesQuery query,
- FindModulesByTypesCallback callback) override;
-
- void Connect(
- fidl::InterfaceRequest<fuchsia::modular::ModuleResolver> request);
-
- // Sets the manifest for GetModuleManifest.
- void SetManifest(fuchsia::modular::ModuleManifestPtr manifest);
-
- // Sets the status for FindModules response.
- void SetStatus(fuchsia::modular::FindModulesStatus status);
-
- // Adds a result to the FindModules response.
- void AddFindModulesResult(fuchsia::modular::FindModulesResult result);
-
- // Sets a function for validation of the query when calling FindModules. This
- // is useful to intercept the query and ensure it was built as expected.
- void SetFindModulesValidation(
- std::function<void(const fuchsia::modular::FindModulesQuery&)> fn);
-
- // Sets a function for validation of the query when calling GetModuleManifest.
- // This is useful to intercept the query and ensure it was built as expected.
- void SetGetModuleManifestValidation(
- std::function<void(const fidl::StringPtr&)> fn);
-
- private:
- fidl::BindingSet<fuchsia::modular::ModuleResolver> bindings_;
- std::function<void(const fuchsia::modular::FindModulesQuery&)>
- find_modules_validate_fn_;
- std::function<void(const fidl::StringPtr&)> get_module_manifest_validate_fn_;
- fuchsia::modular::ModuleManifestPtr manifest_;
- fuchsia::modular::FindModulesResponse find_modules_response_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_MODULE_RESOLVER_FAKE_H_
diff --git a/lib/testing/session_shell_base.h b/lib/testing/session_shell_base.h
deleted file mode 100644
index f800523..0000000
--- a/lib/testing/session_shell_base.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_SESSION_SHELL_BASE_H_
-#define PERIDOT_LIB_TESTING_SESSION_SHELL_BASE_H_
-
-#include "peridot/lib/testing/component_base.h"
-#include "peridot/lib/testing/session_shell_impl.h"
-
-namespace modular {
-namespace testing {
-
-class SessionShellBase : public ComponentBase<void> {
- public:
- SessionShellBase(component::StartupContext* const startup_context) :
- ComponentBase(startup_context) {
- startup_context->ConnectToEnvironmentService(
- session_shell_context_.NewRequest());
-
- session_shell_context_->GetStoryProvider(
- story_provider_.NewRequest());
-
- startup_context->outgoing().AddPublicService(
- session_shell_impl_.GetHandler());
- }
-
- protected:
- modular::testing::SessionShellImpl* session_shell_impl() {
- return &session_shell_impl_;
- }
-
- fuchsia::modular::SessionShellContext* session_shell_context() {
- return session_shell_context_.get();
- }
-
- fuchsia::modular::StoryProvider* story_provider() {
- return story_provider_.get();
- }
-
- private:
- modular::testing::SessionShellImpl session_shell_impl_;
- fuchsia::modular::SessionShellContextPtr session_shell_context_;
- fuchsia::modular::StoryProviderPtr story_provider_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SessionShellBase);
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_SESSION_SHELL_BASE_H_
diff --git a/lib/testing/session_shell_impl.cc b/lib/testing/session_shell_impl.cc
deleted file mode 100644
index ac09240..0000000
--- a/lib/testing/session_shell_impl.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/session_shell_impl.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-
-namespace modular {
-namespace testing {
-
-SessionShellImpl::SessionShellImpl() = default;
-SessionShellImpl::~SessionShellImpl() = default;
-
-fidl::InterfaceRequestHandler<fuchsia::modular::SessionShell> SessionShellImpl::GetHandler() {
- return bindings_.GetHandler(this);
-}
-
-// |SessionShell|
-void SessionShellImpl::AttachView(fuchsia::modular::ViewIdentifier view_id,
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner) {
- on_attach_view_(std::move(view_id));
-}
-
-// |SessionShell|
-void SessionShellImpl::DetachView(fuchsia::modular::ViewIdentifier view_id,
- std::function<void()> done) {
- on_detach_view_(std::move(view_id));
-
- // Used to simulate a sluggish shell that hits the timeout.
- async::PostDelayedTask(async_get_default_dispatcher(),
- std::move(done), detach_delay_);
-}
-
-} // namespace testing
-} // namespace modular
diff --git a/lib/testing/session_shell_impl.h b/lib/testing/session_shell_impl.h
deleted file mode 100644
index 1a1a51f..0000000
--- a/lib/testing/session_shell_impl.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_SESSION_SHELL_IMPL_H_
-#define PERIDOT_LIB_TESTING_SESSION_SHELL_IMPL_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/time/time_delta.h>
-
-namespace modular {
-namespace testing {
-
-// An implementation of the fuchsia.modular.SessionShell FIDL service, to be
-// used in session shell components in integration tests. Usually used through
-// SessionShellBase.
-class SessionShellImpl : fuchsia::modular::SessionShell {
- public:
- SessionShellImpl();
- ~SessionShellImpl() override;
-
- using ViewId = fuchsia::modular::ViewIdentifier;
-
- // Produces a handler function that can be used in the outgoing service
- // provider.
- fidl::InterfaceRequestHandler<fuchsia::modular::SessionShell> GetHandler();
-
- // Whenever SessionShell.AttachView() is called, the supplied callback is
- // invoked with the view ID. The ViewOwner is dropped.
- void set_on_attach_view(std::function<void(ViewId view_id)> callback) {
- on_attach_view_ = std::move(callback);
- }
-
- // Whenever SessionShell.DetachView() is called, the supplied callback is
- // invoked with the view ID. The return callback of DetachView() is invoked
- // asynchronously after a delay that can be configured by the client with
- // set_detach_delay().
- void set_on_detach_view(std::function<void(ViewId view_id)> callback) {
- on_detach_view_ = std::move(callback);
- }
-
- // Configures the delay after which the return callback of DetachView() is
- // invoked. Used to test the timeout behavior of sessionmgr.
- void set_detach_delay(zx::duration detach_delay) {
- detach_delay_ = std::move(detach_delay);
- }
-
- private:
- // |SessionShell|
- void AttachView(fuchsia::modular::ViewIdentifier view_id,
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner>
- view_owner) override;
-
- // |SessionShell|
- void DetachView(fuchsia::modular::ViewIdentifier view_id,
- std::function<void()> done) override;
-
- fidl::BindingSet<fuchsia::modular::SessionShell> bindings_;
- std::function<void(ViewId view_id)> on_attach_view_{[](ViewId) {}};
- std::function<void(ViewId view_id)> on_detach_view_{[](ViewId) {}};
- zx::duration detach_delay_{};
-
- FXL_DISALLOW_COPY_AND_ASSIGN(SessionShellImpl);
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_SESSION_SHELL_IMPL_H_
diff --git a/lib/testing/story_controller_mock.h b/lib/testing/story_controller_mock.h
deleted file mode 100644
index 0230aa8..0000000
--- a/lib/testing/story_controller_mock.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_STORY_CONTROLLER_MOCK_H_
-#define PERIDOT_LIB_TESTING_STORY_CONTROLLER_MOCK_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-
-namespace modular {
-
-class StoryControllerMock : public fuchsia::modular::StoryController {
- public:
- StoryControllerMock() {}
-
- struct GetLinkCall {
- fuchsia::modular::LinkPath link_path;
- };
- std::vector<GetLinkCall> get_link_calls;
-
- private:
- // |fuchsia::modular::StoryController|
- void GetInfo(GetInfoCallback callback) override {
- fuchsia::modular::StoryInfo info;
- info.id = "wow";
- info.url = "wow";
- callback(std::move(info), fuchsia::modular::StoryState::STOPPED);
- }
-
- // |fuchsia::modular::StoryController|
- void RequestStart() override {
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::StoryController|
- void Stop(StopCallback done) override {
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::StoryController|
- void TakeAndLoadSnapshot(
- fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> request,
- TakeAndLoadSnapshotCallback done) override {
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::StoryController|
- void Watch(
- fidl::InterfaceHandle<fuchsia::modular::StoryWatcher> watcher) override {
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::StoryController|
- void GetActiveModules(GetActiveModulesCallback callback) override {
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::StoryController|
- void GetModules(GetModulesCallback callback) override {
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::StoryController|
- void GetModuleController(
- std::vector<std::string> module_path,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController> request)
- override {
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::StoryController|
- void GetActiveLinks(
- fidl::InterfaceHandle<fuchsia::modular::StoryLinksWatcher> watcher,
- GetActiveLinksCallback callback) override {
- FXL_NOTIMPLEMENTED();
- }
-
- // |fuchsia::modular::StoryController|
- void GetLink(
- fuchsia::modular::LinkPath link_path,
- fidl::InterfaceRequest<fuchsia::modular::Link> request) override {
- GetLinkCall call{std::move(link_path)};
- get_link_calls.push_back(std::move(call));
- }
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryControllerMock);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_STORY_CONTROLLER_MOCK_H_
diff --git a/lib/testing/story_provider_mock.h b/lib/testing/story_provider_mock.h
deleted file mode 100644
index b799712..0000000
--- a/lib/testing/story_provider_mock.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_STORY_PROVIDER_MOCK_H_
-#define PERIDOT_LIB_TESTING_STORY_PROVIDER_MOCK_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/interface_ptr_set.h>
-
-#include "peridot/lib/testing/story_controller_mock.h"
-
-namespace modular {
-
-class StoryProviderMock : public fuchsia::modular::StoryProvider {
- public:
- // Allows notification of watchers.
- void NotifyStoryChanged(
- fuchsia::modular::StoryInfo story_info,
- fuchsia::modular::StoryState story_state,
- fuchsia::modular::StoryVisibilityState story_visibility_state) {
- for (const auto& watcher : watchers_.ptrs()) {
- fuchsia::modular::StoryInfo story_info_clone;
- fidl::Clone(story_info, &story_info_clone);
- (*watcher)->OnChange(std::move(story_info_clone), story_state,
- story_visibility_state);
- }
- }
-
- const StoryControllerMock& story_controller() const {
- return controller_mock_;
- }
-
- const std::string& last_created_story() const { return last_created_story_; }
-
- const std::string& last_created_kind_of_story() const {
- return last_created_kind_of_proto_story_;
- }
-
- const std::string& deleted_story() const { return deleted_story_; }
-
- private:
- // |fuchsia::modular::StoryProvider|
- void GetStories(
- fidl::InterfaceHandle<fuchsia::modular::StoryProviderWatcher> watcher,
- GetStoriesCallback callback) override {
- std::vector<fuchsia::modular::StoryInfo> stories;
- callback(std::move(stories));
- }
-
- // |fuchsia::modular::StoryProvider|
- void Watch(fidl::InterfaceHandle<fuchsia::modular::StoryProviderWatcher>
- watcher) override {
- watchers_.AddInterfacePtr(watcher.Bind());
- }
-
- // |fuchsia::modular::StoryProvider|
- void WatchActivity(
- fidl::InterfaceHandle<fuchsia::modular::StoryActivityWatcher> watcher)
- override {
- activity_watchers_.AddInterfacePtr(watcher.Bind());
- }
-
- // |fuchsia::modular::StoryProvider|
- void GetStoryInfo(std::string story_id,
- GetStoryInfoCallback callback) override {
- callback(nullptr);
- }
-
- // |fuchsia::modular::StoryProvider|
- void GetController(std::string story_id,
- fidl::InterfaceRequest<fuchsia::modular::StoryController>
- story) override {
- binding_set_.AddBinding(&controller_mock_, std::move(story));
- }
-
- // |fuchsia::modular::StoryProvider|
- void PreviousStories(PreviousStoriesCallback callback) override {
- callback(std::vector<fuchsia::modular::StoryInfo>());
- }
-
- std::string last_created_story_;
- std::string last_created_kind_of_proto_story_;
- std::string deleted_story_;
- StoryControllerMock controller_mock_;
- fidl::BindingSet<fuchsia::modular::StoryController> binding_set_;
- fidl::InterfacePtrSet<fuchsia::modular::StoryProviderWatcher> watchers_;
- fidl::InterfacePtrSet<fuchsia::modular::StoryActivityWatcher>
- activity_watchers_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_STORY_PROVIDER_MOCK_H_
diff --git a/lib/testing/test_driver.h b/lib/testing/test_driver.h
deleted file mode 100644
index b805886..0000000
--- a/lib/testing/test_driver.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_TEST_DRIVER_H_
-#define PERIDOT_LIB_TESTING_TEST_DRIVER_H_
-
-// Header for definitions for Link communication with a test driver module.
-namespace modular {
-namespace testing {
-
-// This URL is used in a test driver module as the path in a link. Its value is
-// used to determine the URL for a sub-module to launch for integration testing.
-constexpr char kModuleUnderTestPath[] = "module_under_test";
-
-// This URL is used in a test driver module as the path in a link. Its value is
-// used to determine the URL for a test driver script that will be used for
-// integration testing against the mod run in |kModuleUnderTestPath|
-constexpr char kTestDriverPath[] = "test_driver_url";
-
-constexpr char kTestDriverLinkName[] = "test_driver_module";
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_TEST_DRIVER_H_
diff --git a/lib/testing/test_story_command_executor.cc b/lib/testing/test_story_command_executor.cc
deleted file mode 100644
index 68b5509..0000000
--- a/lib/testing/test_story_command_executor.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "peridot/lib/testing/test_story_command_executor.h"
-
-namespace modular {
-namespace testing {
-
-void TestStoryCommandExecutor::SetExecuteReturnResult(
- fuchsia::modular::ExecuteStatus status, fidl::StringPtr error_message) {
- result_.status = status;
- result_.error_message = error_message;
-}
-
-void TestStoryCommandExecutor::Reset() {
- last_story_id_.reset();
- last_commands_.clear();
- execute_count_ = 0;
-}
-
-void TestStoryCommandExecutor::ExecuteCommandsInternal(
- fidl::StringPtr story_id,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::function<void(fuchsia::modular::ExecuteResult)> done) {
- ++execute_count_;
- last_story_id_ = story_id;
- last_commands_ = std::move(commands);
- fuchsia::modular::ExecuteResult result;
- fidl::Clone(result_, &result);
- result.story_id = story_id;
- done(std::move(result));
-}
-
-} // namespace testing
-} // namespace modular
diff --git a/lib/testing/test_story_command_executor.h b/lib/testing/test_story_command_executor.h
deleted file mode 100644
index acf44e0..0000000
--- a/lib/testing/test_story_command_executor.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_TEST_STORY_COMMAND_EXECUTOR_H_
-#define PERIDOT_LIB_TESTING_TEST_STORY_COMMAND_EXECUTOR_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <vector>
-#include "peridot/bin/sessionmgr/puppet_master/story_command_executor.h"
-
-namespace modular {
-namespace testing {
-
-class TestStoryCommandExecutor : public StoryCommandExecutor {
- public:
- void SetExecuteReturnResult(fuchsia::modular::ExecuteStatus status,
- fidl::StringPtr error_message);
-
- void Reset();
-
- int execute_count() const { return execute_count_; }
- fidl::StringPtr last_story_id() const { return last_story_id_; }
- const std::vector<fuchsia::modular::StoryCommand>& last_commands() const {
- return last_commands_;
- }
-
- private:
- // |StoryCommandExecutor|
- void ExecuteCommandsInternal(
- fidl::StringPtr story_id,
- std::vector<fuchsia::modular::StoryCommand> commands,
- std::function<void(fuchsia::modular::ExecuteResult)> done) override;
-
- int execute_count_{0};
- fidl::StringPtr last_story_id_;
- std::vector<fuchsia::modular::StoryCommand> last_commands_;
- fuchsia::modular::ExecuteResult result_;
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_TEST_STORY_COMMAND_EXECUTOR_H_
diff --git a/lib/testing/test_with_ledger.cc b/lib/testing/test_with_ledger.cc
deleted file mode 100644
index ce56393..0000000
--- a/lib/testing/test_with_ledger.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/test_with_ledger.h"
-
-#include <lib/fit/function.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/ledger_client/ledger_client.h"
-
-namespace modular {
-namespace testing {
-
-TestWithLedger::TestWithLedger() = default;
-TestWithLedger::~TestWithLedger() = default;
-
-void TestWithLedger::SetUp() {
- RealLoopFixture::SetUp();
-
- ledger_app_ = std::make_unique<testing::LedgerRepositoryForTesting>();
-
- ledger_client_ = std::make_unique<LedgerClient>(
- ledger_app_->ledger_repository(), __FILE__, [] { ASSERT_TRUE(false); });
-}
-
-void TestWithLedger::TearDown() {
- ledger_client_.reset();
-
- bool terminated = false;
- ledger_app_->Terminate([&terminated] { terminated = true; });
- if (!terminated) {
- RunLoopWithTimeoutOrUntil([&terminated] { return terminated; });
- }
-
- ledger_app_.reset();
-
- RealLoopFixture::TearDown();
-}
-
-bool TestWithLedger::RunLoopWithTimeout(zx::duration timeout) {
- return RealLoopFixture::RunLoopWithTimeout(timeout);
-}
-
-bool TestWithLedger::RunLoopWithTimeoutOrUntil(fit::function<bool()> condition,
- zx::duration timeout) {
- return RealLoopFixture::RunLoopWithTimeoutOrUntil(std::move(condition),
- timeout);
-}
-
-} // namespace testing
-} // namespace modular
diff --git a/lib/testing/test_with_ledger.h b/lib/testing/test_with_ledger.h
deleted file mode 100644
index 0c91a48..0000000
--- a/lib/testing/test_with_ledger.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_TEST_WITH_LEDGER_H_
-#define PERIDOT_LIB_TESTING_TEST_WITH_LEDGER_H_
-
-#include <memory>
-
-#include <lib/fit/function.h>
-#include <lib/gtest/real_loop_fixture.h>
-
-#include "peridot/lib/testing/ledger_repository_for_testing.h"
-
-namespace modular {
-class LedgerClient;
-
-namespace testing {
-
-// A test fixture class for a test case that needs a ledger repository, ledger,
-// ledger client, or ledger page. This fixture sets up a ledger repository and a
-// ledger client in SetUp() and erases the repository and stops the ledger in
-// TearDown(). This also runs a message loop, which is required to interact with
-// the ledger through fidl calls.
-//
-// The ledger client is available to the test case and its fixture through the
-// ledger_client() getter, the ledger repository through ledger_repository().
-//
-// A fixture class that extends this fixture and has its own SetUp() and
-// TearDown() must call this fixture's SetUp() and TearDown().
-class TestWithLedger : public gtest::RealLoopFixture {
- public:
- TestWithLedger();
- ~TestWithLedger() override;
-
- void SetUp() override;
- void TearDown() override;
-
- protected:
- fuchsia::ledger::internal::LedgerRepository* ledger_repository() {
- return ledger_app_->ledger_repository();
- }
- LedgerClient* ledger_client() { return ledger_client_.get(); }
-
- // Increases default timeout over plain test with message loop, because
- // methods executing on the message loop are real fidl calls.
- //
- // Test cases involving ledger calls take about 300ms when running in CI.
- // Occasionally, however, they take much longer, presumably because of load on
- // shared machines. With the default timeout of RealLoopFixture of 1s, we
- // see flakiness. Cf. FW-287.
- bool RunLoopWithTimeout(zx::duration timeout = zx::sec(10));
- bool RunLoopWithTimeoutOrUntil(fit::function<bool()> condition,
- zx::duration timeout = zx::sec(10));
-
- private:
- std::unique_ptr<testing::LedgerRepositoryForTesting> ledger_app_;
- std::unique_ptr<LedgerClient> ledger_client_;
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_TEST_WITH_LEDGER_H_
diff --git a/lib/testing/test_with_session_storage.cc b/lib/testing/test_with_session_storage.cc
deleted file mode 100644
index 67a0d25..0000000
--- a/lib/testing/test_with_session_storage.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/testing/test_with_session_storage.h"
-
-namespace modular {
-namespace testing {
-
-TestWithSessionStorage::TestWithSessionStorage() = default;
-TestWithSessionStorage::~TestWithSessionStorage() = default;
-
-std::unique_ptr<SessionStorage> TestWithSessionStorage::MakeSessionStorage(
- std::string ledger_page) {
- auto page_id = MakePageId(ledger_page);
- return std::make_unique<SessionStorage>(ledger_client(), page_id);
-}
-
-std::unique_ptr<StoryStorage> TestWithSessionStorage::GetStoryStorage(
- SessionStorage* const storage, std::string story_id) {
- std::unique_ptr<StoryStorage> story_storage;
- bool done{};
- storage->GetStoryStorage(story_id)->Then(
- [&](std::unique_ptr<StoryStorage> result) {
- FXL_DCHECK(result);
- story_storage = std::move(result);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-
- return story_storage;
-}
-
-fidl::StringPtr TestWithSessionStorage::CreateStory(
- SessionStorage* const storage) {
- auto future_story =
- storage->CreateStory(nullptr /* extra */, {} /* story_options */);
- bool done{};
- fidl::StringPtr story_id;
- future_story->Then([&](fidl::StringPtr id, fuchsia::ledger::PageId) {
- done = true;
- story_id = std::move(id);
- });
- RunLoopUntil([&] { return done; });
-
- return story_id;
-}
-
-void TestWithSessionStorage::SetLinkValue(StoryStorage* const story_storage,
- const std::string& link_name,
- const std::string& link_value) {
- SetLinkValue(story_storage, MakeLinkPath(link_name), link_value);
-}
-
-void TestWithSessionStorage::SetLinkValue(
- StoryStorage* const story_storage,
- const fuchsia::modular::LinkPath& link_path,
- const std::string& link_value) {
- bool done{};
- int context;
- story_storage
- ->UpdateLinkValue(link_path,
- [&](fidl::StringPtr* value) { *value = link_value; },
- &context)
- ->Then([&](StoryStorage::Status status) {
- ASSERT_EQ(status, StoryStorage::Status::OK);
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-void TestWithSessionStorage::WriteModuleData(
- StoryStorage* const story_storage,
- fuchsia::modular::ModuleData module_data) {
- bool done{};
- story_storage->WriteModuleData(std::move(module_data))->Then([&] {
- done = true;
- });
- RunLoopUntil([&] { return done; });
-}
-
-std::string TestWithSessionStorage::GetLinkValue(
- StoryStorage* const story_storage, const std::string& link_name) {
- return GetLinkValue(story_storage, MakeLinkPath(link_name));
-}
-
-std::string TestWithSessionStorage::GetLinkValue(
- StoryStorage* const story_storage, const fuchsia::modular::LinkPath& path) {
- bool done{};
- std::string value;
- story_storage->GetLinkValue(path)->Then(
- [&](StoryStorage::Status status, fidl::StringPtr v) {
- value = *v;
- done = true;
- });
- RunLoopUntil([&] { return done; });
- return value;
-}
-
-fuchsia::modular::LinkPath TestWithSessionStorage::MakeLinkPath(
- const std::string& name) {
- fuchsia::modular::LinkPath path;
- path.link_name = name;
- return path;
-}
-
-} // namespace testing
-} // namespace modular
diff --git a/lib/testing/test_with_session_storage.h b/lib/testing/test_with_session_storage.h
deleted file mode 100644
index 53f20fa..0000000
--- a/lib/testing/test_with_session_storage.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_TEST_WITH_SESSION_STORAGE_H_
-#define PERIDOT_LIB_TESTING_TEST_WITH_SESSION_STORAGE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/bin/sessionmgr/storage/session_storage.h"
-#include "peridot/bin/sessionmgr/storage/story_storage.h"
-#include "peridot/lib/ledger_client/page_id.h"
-#include "peridot/lib/testing/test_with_ledger.h"
-
-namespace modular {
-namespace testing {
-
-class TestWithSessionStorage : public testing::TestWithLedger {
- public:
- TestWithSessionStorage();
- ~TestWithSessionStorage() override;
-
- protected:
- std::unique_ptr<SessionStorage> MakeSessionStorage(std::string ledger_page);
-
- std::unique_ptr<StoryStorage> GetStoryStorage(SessionStorage* const storage,
- std::string story_id);
-
- fidl::StringPtr CreateStory(SessionStorage* const storage);
-
- void SetLinkValue(StoryStorage* const story_storage,
- const std::string& link_name,
- const std::string& link_value);
-
- void SetLinkValue(StoryStorage* const story_storage,
- const fuchsia::modular::LinkPath& link_path,
- const std::string& link_value);
-
- void WriteModuleData(StoryStorage* const story_storage,
- fuchsia::modular::ModuleData module_data);
-
- std::string GetLinkValue(StoryStorage* const story_storage,
- const fuchsia::modular::LinkPath& path);
-
- std::string GetLinkValue(StoryStorage* const story_storage,
- const std::string& link_name);
-
- fuchsia::modular::LinkPath MakeLinkPath(const std::string& name);
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // PERIDOT_LIB_TESTING_TEST_WITH_SESSION_STORAGE_H_
diff --git a/lib/testing/wait_until_idle.h b/lib/testing/wait_until_idle.h
deleted file mode 100644
index 6c0c770..0000000
--- a/lib/testing/wait_until_idle.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_TESTING_WAIT_UNTIL_IDLE_H_
-#define PERIDOT_LIB_TESTING_WAIT_UNTIL_IDLE_H_
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/fidl/cpp/interface_ptr.h>
-
-#include "gtest/gtest.h"
-
-namespace util {
-
-// Convenience invocation of a debug FIDL interface's |WaitUntilIdle() => ()|
-// function. This wrapper includes the necessary logic to run the message loop
-// while waiting and drain any coincident messages afterwards. It also adds an
-// error handler on the debug interface pointer provided, and clears it
-// afterwards.
-template <class Interface>
-void WaitUntilIdle(fidl::InterfacePtr<Interface>* debug_interface_ptr,
- async::Loop* loop) {
- debug_interface_ptr->set_error_handler([loop](zx_status_t status) {
- loop->Quit();
- ADD_FAILURE() << Interface::Name_
- << " disconnected (check app logs for crash)";
- });
-
- // We can't just use a synchronous ptr or
- // |fidl::InterfacePtr::WaitForResponse| because those don't run the message
- // loop while they wait.
- (*debug_interface_ptr)->WaitUntilIdle([loop] { loop->Quit(); });
- loop->Run();
- loop->ResetQuit();
- // Finish processing any remaining messages.
- loop->RunUntilIdle();
- loop->ResetQuit();
-
- debug_interface_ptr->set_error_handler(nullptr);
-}
-
-} // namespace util
-
-#endif // PERIDOT_LIB_TESTING_WAIT_UNTIL_IDLE_H_
diff --git a/lib/util/BUILD.gn b/lib/util/BUILD.gn
deleted file mode 100644
index 23748fe..0000000
--- a/lib/util/BUILD.gn
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("debug") {
- sources = [
- "debug.h",
- ]
-}
-
-source_set("filesystem") {
- sources = [
- "filesystem.cc",
- "filesystem.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("rate_limited_retry") {
- sources = [
- "rate_limited_retry.cc",
- "rate_limited_retry.h",
- ]
-
- public_deps = [
- "//zircon/public/lib/zx",
- ]
-}
-
-source_set("util") {
- sources = [
- "string_escape.cc",
- "string_escape.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- ]
-}
-
-source_set("ptr") {
- sources = [
- "ptr.h",
- ]
-}
-
-source_set("unittests") {
- testonly = true
-
- sources = [
- "string_escape_unittest.cc",
- ]
-
- public_deps = [
- ":util",
- "//garnet/public/lib/fxl",
- "//third_party/googletest:gtest",
- ]
-}
-
-source_set("idle_waiter") {
- sources = [
- "idle_waiter.cc",
- "idle_waiter.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//zircon/public/lib/async-cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
diff --git a/lib/util/debug.h b/lib/util/debug.h
deleted file mode 100644
index 866b524..0000000
--- a/lib/util/debug.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_UTIL_DEBUG_H_
-#define PERIDOT_LIB_UTIL_DEBUG_H_
-
-#include <ostream>
-#include <string>
-
-namespace modular {
-
-// When debugging multiple copies of an object (such as Links), this creates a
-// printable id to disambiguate them
-inline std::string GetDebugId(void* p) {
- std::ostringstream stream;
- stream << std::hex << ((uint64_t)p & 0x0fff) << " ";
- return stream.str();
-}
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_UTIL_DEBUG_H_
diff --git a/lib/util/filesystem.cc b/lib/util/filesystem.cc
deleted file mode 100644
index 295df85..0000000
--- a/lib/util/filesystem.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/util/filesystem.h"
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <memory>
-#include <utility>
-
-#include <fbl/unique_fd.h>
-#include <fuchsia/io/c/fidl.h>
-#include <lib/fxl/files/file.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_printf.h>
-#include <lib/fxl/strings/string_view.h>
-#include <lib/fzl/fdio.h>
-#include <lib/zx/time.h>
-#include <zircon/device/vfs.h>
-#include <zircon/syscalls.h>
-
-namespace modular {
-
-// For polling minfs.
-constexpr fxl::StringView kPersistentFileSystem = "/data";
-constexpr fxl::StringView kMinFsName = "minfs";
-constexpr zx::duration kMaxPollingDelay = zx::sec(10);
-
-void WaitForMinfs() {
- auto delay = zx::msec(10);
- zx::time now = zx::clock::get_monotonic();
- while (zx::clock::get_monotonic() - now < kMaxPollingDelay) {
- fbl::unique_fd fd(open(kPersistentFileSystem.data(), O_RDONLY));
- if (fd.is_valid()) {
- fuchsia_io_FilesystemInfo info;
- zx_status_t status, io_status;
- fzl::FdioCaller caller{std::move(fd)};
- io_status = fuchsia_io_DirectoryAdminQueryFilesystem(
- caller.borrow_channel(), &status, &info);
- if (io_status == ZX_OK && status == ZX_OK) {
- const char* name = reinterpret_cast<const char*>(info.name);
- fxl::StringView fs_name(name,
- strnlen(name, fuchsia_io_MAX_FS_NAME_BUFFER));
- if (fs_name == kMinFsName) {
- return;
- }
- }
- }
-
- usleep(delay.to_usecs());
- delay = delay * 2;
- }
-
- FXL_LOG(WARNING) << kPersistentFileSystem
- << " is not persistent. Did you forget to configure it?";
-}
-
-} // namespace modular
diff --git a/lib/util/filesystem.h b/lib/util/filesystem.h
deleted file mode 100644
index 1e0407e..0000000
--- a/lib/util/filesystem.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_UTIL_FILESYSTEM_H_
-#define PERIDOT_LIB_UTIL_FILESYSTEM_H_
-
-namespace modular {
-
-// Sleep until Minfs is mounted.
-void WaitForMinfs();
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_UTIL_FILESYSTEM_H_
diff --git a/lib/util/idle_waiter.cc b/lib/util/idle_waiter.cc
deleted file mode 100644
index e77f5c5..0000000
--- a/lib/util/idle_waiter.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/util/idle_waiter.h"
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fxl/functional/closure.h>
-
-namespace util {
-
-IdleWaiter::Activity::Activity(fxl::WeakPtr<IdleWaiter> tracker)
- : tracker_(tracker) {
- tracker_->activity_ = this;
-}
-
-IdleWaiter::Activity::~Activity() {
- if (tracker_) {
- tracker_->activity_ = nullptr;
- if (tracker_->loop_) {
- tracker_->PostIdleCheck();
- }
- }
-}
-
-IdleWaiter::IdleWaiter() : weak_ptr_factory_(this) {}
-
-IdleWaiter::~IdleWaiter() = default;
-
-void IdleWaiter::SetLoop(async::Loop* loop) {
- FXL_DCHECK(!loop_);
- loop_ = loop;
-}
-
-IdleWaiter::ActivityToken IdleWaiter::RegisterOngoingActivity() {
- // !loop_ for unit tests
- FXL_DCHECK(!loop_ || loop_->dispatcher() == async_get_default_dispatcher());
-
- if (activity_) {
- return ActivityToken(activity_);
- } else {
- // |activity_| is set in the |Activity| constructor and cleared in
- // the destructor
- return fxl::MakeRefCounted<Activity>(weak_ptr_factory_.GetWeakPtr());
- }
-}
-
-void IdleWaiter::WaitUntilIdle(fxl::Closure callback) {
- callbacks_.push_back(std::move(callback));
- PostIdleCheck();
-}
-
-void IdleWaiter::PostIdleCheck() {
- FXL_DCHECK(loop_) << "No message loop set for debug features. If this is a "
- "unit test rather than an integration test, consider "
- "using //garnet/public/lib/gtest gtest::TestLoopFixture "
- "features instead.";
-
- if (!(callbacks_.empty() || activity_ || idle_check_pending_)) {
- FXL_DCHECK(loop_->dispatcher() == async_get_default_dispatcher());
- loop_->Quit();
- idle_check_pending_ = true;
- }
-}
-
-bool IdleWaiter::FinishIdleCheck() {
- if (idle_check_pending_) {
- FXL_DCHECK(loop_ && loop_->dispatcher() == async_get_default_dispatcher());
- loop_->RunUntilIdle();
- loop_->ResetQuit();
- if (!activity_) {
- for (const auto& callback : callbacks_) {
- callback();
- }
- callbacks_.clear();
- }
- // Otherwise, |PostIdleCheck| will be invoked again when |activity_| is
- // released.
-
- idle_check_pending_ = false;
- return true;
- } else {
- return false;
- }
-}
-
-} // namespace util
diff --git a/lib/util/idle_waiter.h b/lib/util/idle_waiter.h
deleted file mode 100644
index 025bb88..0000000
--- a/lib/util/idle_waiter.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_UTIL_IDLE_WAITER_H_
-#define PERIDOT_LIB_UTIL_IDLE_WAITER_H_
-
-#include <vector>
-
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fxl/functional/closure.h>
-#include <lib/fxl/memory/ref_ptr.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-namespace util {
-
-// A utility class that exposes the |WaitUntilIdle| function, which invokes a
-// callback after all outstanding tasks (not including delayed tasks) have been
-// processed on a task queue and all user-instrumented asynchronous activities
-// have completed. This function is typically exposed on a service's debug FIDL
-// interface and used for test synchronization.
-//
-// This class is bound to a message loop using SetLoop(). Unbound
-// instances of this class may exist in unit tests.
-class IdleWaiter final {
- public:
- class Activity : public fxl::RefCountedThreadSafe<Activity> {
- public:
- Activity(fxl::WeakPtr<IdleWaiter> tracker);
- ~Activity();
-
- private:
- fxl::WeakPtr<IdleWaiter> tracker_;
- };
-
- using ActivityToken = fxl::RefPtr<Activity>;
-
- IdleWaiter();
- ~IdleWaiter();
-
- void SetLoop(async::Loop* loop);
- async::Loop* loop() const { return loop_; }
-
- // Registers an ongoing activity which prevents this app from being
- // considered idle. When the last copy of |ActivityToken| is destroyed, the
- // activity is considered complete.
- //
- // |ActivityToken| should typically be captured in any lambda triggered while
- // handling a call. It is not necessary to register an activity that completes
- // synchronously.
- //
- // This method must be invoked on the thread that constructed |IdleWaiter|,
- // and |ActivityToken| must be released on the same thread.
- ActivityToken RegisterOngoingActivity();
-
- // Checking for inactivity involves draining the message loop of ready tasks.
- // Doing so must happen outside of the main message loop, so when the time
- // comes for an idle check, this class escapes the main message loop with a
- // quit task. When this happens, app main should call |FinishIdleCheck| and
- // then resume the main message loop if it returns |true|.
- //
- // TODO(rosswang): Remove this requirement if |RunUntilIdle| is ever supported
- // from within an outer message loop.
- bool FinishIdleCheck();
-
- // Waits until the app has reached a steady state such that no further
- // activity will occur unless acted upon from the outside:
- // * when there are no ready tasks in the message loop; delayed tasks are not
- // included
- // * when no outstanding copies of |ActivityToken|s created by
- // |RegisterOngoingActivity| are held by the instrumented app
- void WaitUntilIdle(fxl::Closure callback);
-
- private:
- // Idle checks must be performed outside of the main message loop, so
- // |PostIdleCheck| escapes the main message loop with a quit task. See
- // |FinishIdleCheck| for more information.
- void PostIdleCheck();
-
- async::Loop* loop_{};
- std::vector<fxl::Closure> callbacks_;
-
- Activity* activity_ = nullptr;
- bool idle_check_pending_ = false;
-
- fxl::WeakPtrFactory<IdleWaiter> weak_ptr_factory_;
-};
-
-} // namespace util
-
-#endif // PERIDOT_LIB_UTIL_IDLE_WAITER_H_
diff --git a/lib/util/ptr.h b/lib/util/ptr.h
deleted file mode 100644
index 6657314..0000000
--- a/lib/util/ptr.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_UTIL_PTR_H_
-#define PERIDOT_LIB_UTIL_PTR_H_
-
-#include <memory>
-
-namespace util {
-
-// Returns true if the provided std::unique_ptrs are both empty, or point to
-// equal objects. Returns false otherwise.
-template <typename T>
-bool EqualPtr(const std::unique_ptr<T>& lhs, const std::unique_ptr<T>& rhs) {
- if (bool(lhs) != bool(rhs)) {
- return false;
- }
- if (!lhs && !rhs) {
- return true;
- }
- return *lhs == *rhs;
-}
-
-} // namespace util
-
-#endif // PERIDOT_LIB_UTIL_PTR_H_
diff --git a/lib/util/rate_limited_retry.cc b/lib/util/rate_limited_retry.cc
deleted file mode 100644
index 6866b5b..0000000
--- a/lib/util/rate_limited_retry.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/util/rate_limited_retry.h"
-
-namespace modular {
-
-RateLimitedRetry::RateLimitedRetry(const Threshold& threshold)
- : threshold_(threshold), failure_series_count_(0) {}
-
-bool RateLimitedRetry::ShouldRetry() {
- zx::time now = zx::clock::get_monotonic();
- if (failure_series_count_ == 0 ||
- now - failure_series_start_ >= threshold_.period) {
- failure_series_start_ = now;
- failure_series_count_ = 0;
- }
-
- if (failure_series_count_ >= threshold_.count) {
- return false;
- } else {
- ++failure_series_count_;
- return true;
- }
-}
-
-} // namespace modular
diff --git a/lib/util/rate_limited_retry.h b/lib/util/rate_limited_retry.h
deleted file mode 100644
index 0a44014..0000000
--- a/lib/util/rate_limited_retry.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_UTIL_RATE_LIMITED_RETRY_H_
-#define PERIDOT_LIB_UTIL_RATE_LIMITED_RETRY_H_
-
-#include <lib/zx/time.h>
-
-namespace modular {
-
-// Keeps track of a retry scheme where infinite retries are allowed unless an
-// operation fails many times in a short interval. This can be used to enable a
-// decent user experience in the face of a flaky dependency without undue churn
-// or log spamming if an unrecoverable failure has occurred.
-class RateLimitedRetry {
- public:
- struct Threshold {
- unsigned int count;
- zx::duration period;
- };
-
- // Constructs a retry tracker where retry should occur as long as no more than
- // |count| failures have occurred within a |period|.
- //
- // As an example, an allowance of 1 failure per second will allow retries if
- // failures occur no more frequently than exactly once every second.
- RateLimitedRetry(const Threshold& threshold);
-
- // Call |ShouldRetry()| when the operation you are tracking fails, to
- // determine whether a retry should be attempted. Returns |false| if
- // |ShouldRetry()| has been called more than |count| times within a |period|.
- bool ShouldRetry();
-
- private:
- const Threshold threshold_;
-
- unsigned int failure_series_count_;
- zx::time failure_series_start_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_UTIL_RATE_LIMITED_RETRY_H_
diff --git a/lib/util/string_escape.cc b/lib/util/string_escape.cc
deleted file mode 100644
index 3c6f85b..0000000
--- a/lib/util/string_escape.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/util/string_escape.h"
-
-using fxl::StringView;
-
-namespace modular {
-
-std::string StringEscape(StringView input, StringView chars_to_escape,
- char escape_char) {
- std::string output;
- output.reserve(input.size());
-
- for (const auto& c : input) {
- if (chars_to_escape.find(c) != StringView::npos || c == escape_char) {
- output.push_back(escape_char);
- }
- output.push_back(c);
- }
-
- return output;
-}
-
-std::string StringUnescape(StringView input, char escape_char) {
- std::string output;
-
- for (size_t i = 0; i < input.size(); i++) {
- if (input[i] == escape_char) {
- FXL_DCHECK(i != input.size() - 1)
- << "StringUnescape: unescapable string: " << input;
- if (i != input.size() - 1) {
- i++;
- }
- }
- output.push_back(input[i]);
- }
-
- return output;
-}
-
-std::vector<StringView> SplitEscapedString(StringView input, char split_char,
- char escape_char) {
- std::vector<StringView> output;
- size_t last_pos = 0;
- for (size_t i = 0; i < input.size(); i++) {
- if (input[i] == escape_char) {
- i++;
- // skips a 2nd time:
- continue;
- }
-
- if (input[i] == split_char) {
- output.push_back(input.substr(last_pos, i - last_pos));
- last_pos = i + 1;
- continue;
- }
- }
-
- if (last_pos < input.size()) {
- output.push_back(input.substr(last_pos, input.size() - last_pos));
- }
-
- return output;
-}
-
-} // namespace modular
diff --git a/lib/util/string_escape.h b/lib/util/string_escape.h
deleted file mode 100644
index 5c77058..0000000
--- a/lib/util/string_escape.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_LIB_UTIL_STRING_ESCAPE_H_
-#define PERIDOT_LIB_UTIL_STRING_ESCAPE_H_
-
-#include <vector>
-
-#include <lib/fxl/strings/string_view.h>
-
-namespace modular {
-
-constexpr char kDefaultEscapeChar = '\\';
-
-// Escape the set of chars in |chars_to_escape| in |input||. Use |escape_char|
-// to escape. All params are expected to be in ASCII.
-std::string StringEscape(fxl::StringView input, fxl::StringView chars_to_escape,
- char escape_char = kDefaultEscapeChar);
-
-// Unescape all escape sequences in |input|, where the escape sequence begins
-// with |escape_char|. All input params are expected to be in ASCII. In debug
-// mode, crashes if |input| cannot be unescaped.
-std::string StringUnescape(fxl::StringView input,
- char escape_char = kDefaultEscapeChar);
-
-// Splits an escaped string |input| by |split_char|; this splitter skips over
-// any characters escaped using |escape_char|s. All params are expected to be in
-// ASCII.
-//
-// Example:
-// SplitEscapedString("a_b\\_c_d", '_', '\\')
-// => std::vector<StringView>{"a", "b\\_c", "d"}
-std::vector<fxl::StringView> SplitEscapedString(
- fxl::StringView input, char split_char,
- char escape_char = kDefaultEscapeChar);
-
-} // namespace modular
-
-#endif // PERIDOT_LIB_UTIL_STRING_ESCAPE_H_
diff --git a/lib/util/string_escape_unittest.cc b/lib/util/string_escape_unittest.cc
deleted file mode 100644
index b4fe266..0000000
--- a/lib/util/string_escape_unittest.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/lib/util/string_escape.h"
-
-#include "gtest/gtest.h"
-
-using fxl::StringView;
-
-namespace modular {
-namespace {
-
-TEST(EscapeStringTest, EscapeUnescape) {
- StringView original = "ABCDEFGHIJKLMNOPQRST";
- std::string expected = "ABCD|EFGHI|JKLMNOPQRST";
-
- EXPECT_EQ(expected, StringEscape(original, "EJ", '|'));
- EXPECT_EQ(original, StringUnescape(expected, '|'));
-
- EXPECT_EQ("a", StringUnescape("|a", '|'));
-}
-
-TEST(EscapeStringTest, SplitSimple) {
- auto result = SplitEscapedString("a_b|_c_d", '_', '|');
- EXPECT_EQ(3u, result.size());
- EXPECT_EQ("a", result[0]);
- EXPECT_EQ("b|_c", result[1]);
- EXPECT_EQ("d", result[2]);
-}
-
-TEST(EscapeStringTest, SplitEdge) {
- auto result = SplitEscapedString("a_", '_', '|');
- EXPECT_EQ(1u, result.size());
- EXPECT_EQ("a", result[0]);
-}
-
-TEST(EscapeStringTest, SplitWithEmpties) {
- auto result = SplitEscapedString("a___b", '_', '|');
- EXPECT_EQ(4u, result.size());
- EXPECT_EQ("a", result[0]);
- EXPECT_EQ("", result[1]);
- EXPECT_EQ("", result[2]);
- EXPECT_EQ("b", result[3]);
-}
-
-} // namespace
-} // namespace modular
diff --git a/navbar.md b/navbar.md
deleted file mode 100644
index d8b034b..0000000
--- a/navbar.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Peridot
-
-* [Home][home]
-* [Modular](/docs/modular/getting_started.md)
-* [Ledger](/docs/ledger/README.md)
-* [fuchsia::modular::Intent](/docs/modular/intent.md)
-* [fuchsia::modular::Entity](/docs/modular/entity.md)
-* [Examples](/examples)
-* [Tests](/tests)
-
-[home]: /README.md
-[logo]: /docs/images/fuchsia-logo-32x32.png
diff --git a/packages/README.md b/packages/README.md
deleted file mode 100644
index a5050b3..0000000
--- a/packages/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Build packages
-
-This directory contains build packages used to customize the content of a build.
-Its structure follows [a strict format][package-layout], enforced by continuous
-builds.
-
-[package-layout]: https://fuchsia.googlesource.com/docs/+/master/development/build/package_layout.md
diff --git a/packages/all b/packages/all
deleted file mode 100644
index 65ec31c..0000000
--- a/packages/all
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "imports": [
- "peridot/packages/benchmarks/all",
- "peridot/packages/examples/all",
- "peridot/packages/prod/all",
- "peridot/packages/tests/all"
- ]
-}
diff --git a/packages/benchmarks/all b/packages/benchmarks/all
deleted file mode 100644
index ddca20b5..0000000
--- a/packages/benchmarks/all
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "imports": [
- "peridot/packages/benchmarks/ledger",
- "peridot/packages/benchmarks/modular",
- "peridot/packages/benchmarks/peridot"
- ]
-}
diff --git a/packages/benchmarks/ledger b/packages/benchmarks/ledger
deleted file mode 100644
index 299f1b7..0000000
--- a/packages/benchmarks/ledger
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "imports": [
- "peridot/packages/prod/ledger"
- ],
- "packages": [
- "//peridot/bin/ledger/tests/benchmark:ledger_benchmarks"
- ]
-}
diff --git a/packages/benchmarks/modular b/packages/benchmarks/modular
deleted file mode 100644
index fd6830b..0000000
--- a/packages/benchmarks/modular
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "imports": [
- "garnet/packages/benchmarks/buildbot",
- "peridot/packages/prod/modular"
- ],
- "packages": [
- "//peridot/tests/benchmarks:modular_benchmarks",
- "//peridot/tests/benchmarks/story:modular_benchmark_story_module",
- "//peridot/tests/benchmarks/story:modular_benchmark_story_session_shell"
- ]
-}
diff --git a/packages/benchmarks/peridot b/packages/benchmarks/peridot
deleted file mode 100644
index c47981a..0000000
--- a/packages/benchmarks/peridot
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "imports": [
- "garnet/packages/benchmarks/buildbot",
- "peridot/packages/benchmarks/ledger"
- ],
- "packages": [
- "//peridot/tests/benchmarks:peridot_benchmarks"
- ]
-}
diff --git a/packages/buildbot b/packages/buildbot
deleted file mode 100644
index 044c8ca..0000000
--- a/packages/buildbot
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "imports": [
- "garnet/packages/garnet",
- "peridot/packages/all"
- ]
-}
diff --git a/packages/default b/packages/default
deleted file mode 100644
index 9fec4ea..0000000
--- a/packages/default
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "imports": [
- "garnet/packages/garnet",
- "garnet/packages/tools/all",
- "peridot/packages/all"
- ]
-}
diff --git a/packages/examples/all b/packages/examples/all
deleted file mode 100644
index 1ca35d6..0000000
--- a/packages/examples/all
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "imports": [
- "peridot/packages/examples/modular"
- ]
-}
diff --git a/packages/examples/modular b/packages/examples/modular
deleted file mode 100644
index bbc8dcf..0000000
--- a/packages/examples/modular
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "packages": [
- "//peridot/examples/simple:simple_agent",
- "//peridot/examples/simple:simple_module",
- "//peridot/examples/swap_cpp:swap_module1",
- "//peridot/examples/swap_cpp:swap_module2",
- "//peridot/examples/swap_cpp:swap_recipe",
- "//peridot/examples/todo_cpp:todo_cpp"
- ]
-}
diff --git a/packages/kitchen_sink b/packages/kitchen_sink
deleted file mode 100644
index 54a70ff..0000000
--- a/packages/kitchen_sink
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "imports": [
- "garnet/packages/kitchen_sink",
- "peridot/packages/all"
- ]
-}
diff --git a/packages/peridot b/packages/peridot
deleted file mode 100644
index a2c0ddf..0000000
--- a/packages/peridot
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "imports": [
- "garnet/packages/garnet",
- "peridot/packages/prod/all"
- ]
-}
diff --git a/packages/prod/all b/packages/prod/all
deleted file mode 100644
index 3aab919..0000000
--- a/packages/prod/all
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "imports": [
- "peridot/packages/prod/clipboard_agent",
- "peridot/packages/prod/cloud_provider_firestore",
- "peridot/packages/prod/integration_testing",
- "peridot/packages/prod/ledger",
- "peridot/packages/prod/maxwell",
- "peridot/packages/prod/modular",
- "peridot/packages/prod/module_resolver",
- "peridot/packages/prod/sessionctl",
- "peridot/packages/prod/story_info"
- ]
-}
diff --git a/packages/prod/clipboard_agent b/packages/prod/clipboard_agent
deleted file mode 100644
index cd95768..0000000
--- a/packages/prod/clipboard_agent
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//peridot/bin/agents/clipboard:clipboard_agent"
- ]
-}
diff --git a/packages/prod/cloud_provider_firestore b/packages/prod/cloud_provider_firestore
deleted file mode 100644
index 942ebde..0000000
--- a/packages/prod/cloud_provider_firestore
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//peridot/bin/cloud_provider_firestore"
- ]
-}
diff --git a/packages/prod/integration_testing b/packages/prod/integration_testing
deleted file mode 100644
index 1ca2a33..0000000
--- a/packages/prod/integration_testing
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "imports": [
- "garnet/packages/prod/test_runner",
- "peridot/packages/prod/modular"
- ],
- "packages": [
- "//peridot/bin/basemgr:dev_base_shell",
- "//peridot/bin/sessionmgr/story_runner:dev_story_shell",
- "//peridot/bin/test_driver:test_driver_module",
- "//peridot/bin/token_manager:dev_token_manager",
- "//peridot/bin/sessionmgr:dev_session_shell"
- ]
-}
diff --git a/packages/prod/ledger b/packages/prod/ledger
deleted file mode 100644
index 3567043..0000000
--- a/packages/prod/ledger
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//peridot/bin/ledger"
- ]
-}
diff --git a/packages/prod/maxwell b/packages/prod/maxwell
deleted file mode 100644
index a931631..0000000
--- a/packages/prod/maxwell
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "packages": [
- "//peridot/bin/context_engine",
- "//peridot/bin/suggestion_engine"
- ]
-}
diff --git a/packages/prod/modular b/packages/prod/modular
deleted file mode 100644
index c45c455..0000000
--- a/packages/prod/modular
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "packages": [
- "//peridot/bin/basemgr",
- "//peridot/bin/sessionmgr"
- ],
- "labels": [
- "//peridot/cloud/go/src/remote_module_resolver:host"
- ]
-}
diff --git a/packages/prod/module_resolver b/packages/prod/module_resolver
deleted file mode 100644
index 0098af6..0000000
--- a/packages/prod/module_resolver
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "packages": [
- "//peridot/bin/module_resolver",
- "//peridot/bin/module_resolver/module_package_indexer"
- ]
-}
diff --git a/packages/prod/sessionctl b/packages/prod/sessionctl
deleted file mode 100644
index 72ca949..0000000
--- a/packages/prod/sessionctl
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//peridot/bin/sessionctl"
- ]
-}
diff --git a/packages/prod/story_info b/packages/prod/story_info
deleted file mode 100644
index fbee17b..0000000
--- a/packages/prod/story_info
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//peridot/bin/acquirers/story_info"
- ]
-}
diff --git a/packages/products/framework b/packages/products/framework
deleted file mode 100644
index 75f37d6..0000000
--- a/packages/products/framework
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "imports": [
- "garnet/packages/config/mdns",
- "garnet/packages/config/netconnector",
- "garnet/packages/prod/cobalt_client",
- "garnet/packages/prod/mdns",
- "garnet/packages/prod/mdns-util",
- "garnet/packages/prod/netconnector",
- "peridot/packages/prod/clipboard_agent",
- "peridot/packages/prod/cloud_provider_firestore",
- "peridot/packages/prod/ledger",
- "peridot/packages/prod/maxwell",
- "peridot/packages/prod/modular",
- "peridot/packages/prod/module_resolver",
- "peridot/packages/prod/sessionctl",
- "peridot/packages/prod/story_info"
- ]
-}
diff --git a/packages/products/framework_minimal b/packages/products/framework_minimal
deleted file mode 100644
index c44cd3f..0000000
--- a/packages/products/framework_minimal
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "imports": [
- "peridot/packages/prod/ledger",
- "peridot/packages/prod/maxwell",
- "peridot/packages/prod/modular",
- "peridot/packages/prod/module_resolver",
- "peridot/packages/prod/story_info"
- ]
-}
diff --git a/packages/products/test_modular b/packages/products/test_modular
deleted file mode 100644
index 044c8ca..0000000
--- a/packages/products/test_modular
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "imports": [
- "garnet/packages/garnet",
- "peridot/packages/all"
- ]
-}
diff --git a/packages/tests/all b/packages/tests/all
deleted file mode 100644
index bcb8834..0000000
--- a/packages/tests/all
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "imports": [
- "garnet/packages/testing/run_test_component",
- "peridot/packages/tests/bup",
- "peridot/packages/tests/ledger",
- "peridot/packages/tests/leveldb",
- "peridot/packages/tests/maxwell_integration_tests",
- "peridot/packages/tests/maxwell_unittests",
- "peridot/packages/tests/modular_integration_tests",
- "peridot/packages/tests/modular_unittests",
- "peridot/packages/tests/peridot_tests",
- "peridot/packages/tests/re2"
- ]
-}
diff --git a/packages/tests/bup b/packages/tests/bup
deleted file mode 100644
index 8c0133f..0000000
--- a/packages/tests/bup
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//peridot/third_party/bup:bup_tests"
- ]
-}
diff --git a/packages/tests/ledger b/packages/tests/ledger
deleted file mode 100644
index dbf807b..0000000
--- a/packages/tests/ledger
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "imports": [
- "peridot/packages/prod/cloud_provider_firestore",
- "peridot/packages/prod/ledger"
- ],
- "packages": [
- "//peridot/bin/ledger:ledger_tests",
- "//peridot/bin/ledger:ledger_fuzzers",
- "//peridot/bin/ledger/testing/ledger_test_instance_provider:ledger_test_instance_provider"
- ]
-}
diff --git a/packages/tests/leveldb b/packages/tests/leveldb
deleted file mode 100644
index db6195f..0000000
--- a/packages/tests/leveldb
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "packages": [
- "//third_party/leveldb:leveldb_tests",
- "//third_party/leveldb:leveldb_benchmarks"
- ]
-}
diff --git a/packages/tests/maxwell_integration_tests b/packages/tests/maxwell_integration_tests
deleted file mode 100644
index eca1213..0000000
--- a/packages/tests/maxwell_integration_tests
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//peridot/tests/maxwell_integration:maxwell_integration_tests"
- ]
-}
diff --git a/packages/tests/maxwell_unittests b/packages/tests/maxwell_unittests
deleted file mode 100644
index a72fdbc..0000000
--- a/packages/tests/maxwell_unittests
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "packages": [
- "//peridot/bin/context_engine:context_engine_unittests",
- "//peridot/bin/module_resolver:module_resolver_unittests",
- "//peridot/bin/suggestion_engine:suggestion_engine_unittests"
- ]
-}
diff --git a/packages/tests/modular_integration_tests b/packages/tests/modular_integration_tests
deleted file mode 100644
index a18cf17..0000000
--- a/packages/tests/modular_integration_tests
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "imports": [
- "garnet/packages/prod/test_runner",
- "peridot/packages/prod/integration_testing"
- ],
- "packages": [
- "//peridot/tests/clipboard:clipboard_test_module",
- "//peridot/tests/common:common_active_module",
- "//peridot/tests/common:common_module_index",
- "//peridot/tests/common:common_null_module",
- "//peridot/tests/component_context:component_context_test_module",
- "//peridot/tests/component_context:component_context_test_one_agent",
- "//peridot/tests/component_context:component_context_test_two_agent",
- "//peridot/tests/component_context:component_context_test_unstoppable_agent",
- "//peridot/tests/embed_shell:embed_shell_test_child_module",
- "//peridot/tests/embed_shell:embed_shell_test_parent_module",
- "//peridot/tests/embed_shell:embed_shell_test_session_shell",
- "//peridot/tests/embed_shell:embed_shell_test_story_shell",
- "//peridot/tests/intents:intent_test_parent_module",
- "//peridot/tests/intents:intent_test_child_module",
- "//peridot/tests/last_focus_time:last_focus_time_test_session_shell",
- "//peridot/tests/link_context_entities:link_context_entities_test_module",
- "//peridot/tests/link_context_entities:link_context_entities_test_session_shell",
- "//peridot/tests:modular_tests",
- "//peridot/tests/module_context:module_context_test_session_shell",
- "//peridot/tests/module_context:module_context_test_module",
- "//peridot/tests/module_context:module_context_test_entity_module",
- "//peridot/tests/parent_child:parent_child_test_child_module1",
- "//peridot/tests/parent_child:parent_child_test_child_module2",
- "//peridot/tests/parent_child:parent_child_test_parent_module",
- "//peridot/tests/queue_persistence:queue_persistence_test_agent",
- "//peridot/tests/queue_persistence:queue_persistence_test_module",
- "//peridot/tests/story_shell:story_shell_test_story_shell",
- "//peridot/tests/story_shell:story_shell_test_session_shell",
- "//peridot/tests/suggestion:suggestion_test_module",
- "//peridot/tests/suggestion:suggestion_test_session_shell",
- "//peridot/tests/trigger:trigger_test_agent",
- "//peridot/tests/trigger:trigger_test_module",
- "//peridot/tests/trigger:trigger_test_session_shell",
- "//peridot/tests/session_shell:session_shell_test_session_shell",
- "//peridot/tests/sessionctl:sessionctl_integration_tests"
- ]
-}
diff --git a/packages/tests/modular_unittests b/packages/tests/modular_unittests
deleted file mode 100644
index 2b18fdb..0000000
--- a/packages/tests/modular_unittests
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "packages": [
- "//peridot/bin/agents/clipboard:clipboard_unittests",
- "//peridot/bin/basemgr:basemgr_unittests",
- "//peridot/bin/sessionctl:sessionctl_unittests",
- "//peridot/bin/sessionmgr/agent_runner:agent_runner_unittests",
- "//peridot/bin/sessionmgr/entity_provider_runner:entity_provider_runner_unittests",
- "//peridot/bin/sessionmgr/story/model:story_model_unittests",
- "//peridot/bin/sessionmgr/story/systems:story_systems_unittests",
- "//peridot/bin/sessionmgr/puppet_master:puppet_master_unittests",
- "//peridot/bin/sessionmgr/storage:storage_unittests",
- "//peridot/bin/sessionmgr/story_runner:story_runner_unittests"
- ]
-}
diff --git a/packages/tests/peridot_tests b/packages/tests/peridot_tests
deleted file mode 100644
index 676573d..0000000
--- a/packages/tests/peridot_tests
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//peridot:peridot_tests"
- ]
-}
diff --git a/packages/tests/re2 b/packages/tests/re2
deleted file mode 100644
index 301cc1e..0000000
--- a/packages/tests/re2
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "packages": [
- "//third_party/re2:re2_tests"
- ]
-}
diff --git a/products/default.gni b/products/default.gni
deleted file mode 100644
index ade663d..0000000
--- a/products/default.gni
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-monolith = [ "peridot/packages/default" ]
-
-preinstall = []
-
-available = [ "peridot/packages/all" ]
diff --git a/products/framework.gni b/products/framework.gni
deleted file mode 100644
index 47dde09..0000000
--- a/products/framework.gni
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-monolith = [ "peridot/packages/products/framework" ]
-
-preinstall = []
-
-available = []
diff --git a/products/kitchen_sink.gni b/products/kitchen_sink.gni
deleted file mode 100644
index 142ff00..0000000
--- a/products/kitchen_sink.gni
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-monolith = [ "peridot/packages/kitchen_sink" ]
-
-preinstall = []
-
-available = []
diff --git a/products/test_modular.gni b/products/test_modular.gni
deleted file mode 100644
index f37efcc..0000000
--- a/products/test_modular.gni
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-monolith = [ "peridot/packages/products/test_modular" ]
-
-preinstall = []
-
-available = []
diff --git a/public/BUILD.gn b/public/BUILD.gn
deleted file mode 100644
index 8d80dff..0000000
--- a/public/BUILD.gn
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-config("config") {
- include_dirs = [
- ".",
- "$root_gen_dir/peridot/public",
- ]
-}
diff --git a/public/fidl/fuchsia.ledger.cloud/BUILD.gn b/public/fidl/fuchsia.ledger.cloud/BUILD.gn
deleted file mode 100644
index be62ab0..0000000
--- a/public/fidl/fuchsia.ledger.cloud/BUILD.gn
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-fidl("fuchsia.ledger.cloud") {
- sources = [
- "cloud_provider.fidl",
- ]
-
- public_deps = [
- "//zircon/public/fidl/fuchsia-mem",
- ]
-}
diff --git a/public/fidl/fuchsia.ledger.cloud/cloud_provider.fidl b/public/fidl/fuchsia.ledger.cloud/cloud_provider.fidl
deleted file mode 100644
index 15483db..0000000
--- a/public/fidl/fuchsia.ledger.cloud/cloud_provider.fidl
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.ledger.cloud;
-
-using fuchsia.mem;
-
-// This file defines a cloud service that can be used by Ledger to power cloud
-// sync.
-
-/// Response status for cloud provider operations.
-enum Status : int32 {
- OK = 0;
- AUTH_ERROR = 1;
- ARGUMENT_ERROR = 2;
- INTERNAL_ERROR = 3;
- NETWORK_ERROR = 4;
- NOT_FOUND = 5;
- PARSE_ERROR = 6;
- SERVER_ERROR = 7;
- UNKNOWN_ERROR = -1;
-};
-
-/// Cloud service that powers cloud sync for a single user. Top-level interface
-/// of this file.
-///
-/// Closing the client connection to CloudProvider shuts down all controllers
-/// (DeviceSets, PageClouds) that were produced by it.
-[Discoverable]
-interface CloudProvider {
- /// Retrieves the controller for the user device set.
- 1: GetDeviceSet(request<DeviceSet> device_set) -> (Status status);
-
- /// Retrieves the controller for cloud sync of a particular page.
- 2: GetPageCloud(vector<uint8> app_id, vector<uint8> page_id, request<PageCloud> page_cloud)
- -> (Status status);
-};
-
-/// Cloud registry of devices participating in cloud sync.
-///
-/// Closing the client connection to DeviceSet disconnects all watchers set on
-/// it.
-interface DeviceSet {
- /// Verifies that the device fingerprint in the cloud is still in the list of
- /// devices, ensuring that the cloud was not erased since the last sync.
- 1: CheckFingerprint(vector<uint8> fingerprint) -> (Status status);
-
- /// Adds the device fingerprint to the list of devices in the cloud.
- 2: SetFingerprint(vector<uint8> fingerprint) -> (Status status);
-
- /// Watches the given |fingerprint| in the cloud so that |watcher| is notified
- /// when the fingerprint is erased.
- ///
- /// At most one watcher can be set at any given time. If more than one watcher
- /// is set, only the one set most recently receives notifications.
- ///
- /// The returned status is:
- ///
- /// - OK, if setting the watcher succeeded,
- /// - NOT_FOUND, if the fingerprint was not found in the cloud
- /// - NETWORK_ERROR, if the watcher couldn't be set due to a network error
- ///
- /// If the returned status is not OK, the corresponding error call is also made
- /// on the watcher.
- 3: SetWatcher(vector<uint8> fingerprint, DeviceSetWatcher watcher)
- -> (Status status);
-
- /// Erases the entire registry of devices. This makes all devices detect that
- /// cloud has been erased.
- 4: Erase() -> (Status status);
-};
-
-/// Watcher for push notifications from the cloud registry of devices
-/// participating in cloud sync.
-interface DeviceSetWatcher {
- /// Called when cloud provider detects that the cloud storage was erased. No
- /// further calls are made on the watcher after this is called.
- 1: OnCloudErased();
-
- /// Called when the network connection is lost. No further calls are made on
- /// the watcher after this is called.
- 2: OnNetworkError();
-};
-
-// TODO(ppi): switch to a format defined in a FIDL table, so that the protocol
-// is fully described by the FIDL file.
-/// Contains an ordered list of commits serialized using the SerializedCommits
-/// schema defined in serialized_commits.fbs.
-struct CommitPack {
- fuchsia.mem.Buffer buffer;
-};
-
-/// A continuation token for paginated requests.
-struct Token {
- vector<uint8> opaque_id;
-};
-
-/// Handler for cloud sync of a single page.
-///
-/// Implementation of this class manages a *commit log*, which is an append-only
-/// list of commits produced by all devices that participate in syncing this
-/// page. Position of commits within the log are references using position
-/// tokens, allowing the caller to retrieve the commits added to the cloud since
-/// the previous read. (plus possibly more - see comments for GetCommits() and
-/// SetWatcher().)
-///
-/// Closing the client connection to PageCloud disconnects all watchers set on
-/// it.
-interface PageCloud {
- /// Adds the given commits to the commit log in the cloud.
- ///
- /// The commits are added in one batch, on the receiving side they are
- /// delivered in the same order in a single OnNewCommits() call.
- 1: AddCommits(CommitPack commits) -> (Status status);
-
- /// Retrieves commits from the cloud.
- ///
- /// All commits newer than |min_position_token| are guaranteed to be returned.
- /// In addition to that, the response may include additional commits older
- /// than or at |min_position_token|. Passing null |min_position_token|
- /// retrieves all commits.
- ///
- /// If the resulting |status| is |OK|, |commits| contains all matching commits
- /// (might be empty) and |position_token| contains the position token of the
- /// most recent of the |commits| (equivalent to |min_position_token| if
- /// |commits| is empty).
- 2: GetCommits(Token? min_position_token)
- -> (Status status, CommitPack? commits, Token? position_token);
-
- /// Uploads the given object to the cloud under the given id.
- ///
- /// If the object already exists in the cloud this method returns OK.
- 3: AddObject(vector<uint8> id, fuchsia.mem.Buffer buffer) -> (Status status);
-
- /// Retrieves the object of the given id from the cloud.
- ///
- /// If the resulting |status| is |OK|, |buffer| will contain the object
- /// content. If the resulting |status| is not |OK|, |buffer| will be null.
- 4: GetObject(vector<uint8> id)
- -> (Status status, fuchsia.mem.Buffer? buffer);
-
- /// Watches the cloud for push notifications.
- ///
- /// At most one watcher can be set at any given time. If more than one watcher
- /// is set, only the one set most recently receives notifications.
- ///
- /// All commits newer than |min_position_token| added to the cloud before or
- /// after making this call are guaranteed to be delivered to |watcher|. In
- /// addition to that, additional commits older than or at |min_position_token|
- /// may be delivered to. If |min_position_token| is null, notifications for
- /// all commits are delivered.
- 5: SetWatcher(Token? min_position_token, PageCloudWatcher watcher)
- -> (Status status);
-};
-
-/// Watcher for push notifications from cloud sync of a single page.
-interface PageCloudWatcher {
- /// Called when new commits are added to the commit log in the cloud.
- ///
- /// The method takes the list of new |commits| along with the |position_token|
- /// of the most recent of them.
- ///
- /// No subsequent calls are made until the client calls the callback of the
- /// previous one.
- 1: OnNewCommits(CommitPack commits, Token position_token) -> ();
-
- /// Called when a new object is added to the cloud.
- ///
- /// The method takes the |id| and the content of the new object.
- ///
- /// No subsequent calls are made until the client calls the callback of the
- /// previous one.
- 2: OnNewObject(vector<uint8> id, fuchsia.mem.Buffer buffer) -> ();
-
- /// Called when an error occurs.
- ///
- /// No further calls are made on the watcher after this is called. The client
- /// can then re-establish the watcher by calling SetWatcher() again.
- ///
- /// The status is one of:
- ///
- /// - AUTH_ERROR, if the auth token needs a refresh
- /// - NETWORK_ERROR, if the connection was dropped
- /// - PARSE_ERROR, if an invalid server notification was received
- 3: OnError(Status status);
-};
diff --git a/public/fidl/fuchsia.ledger.cloud/serialized_commits.fbs b/public/fidl/fuchsia.ledger.cloud/serialized_commits.fbs
deleted file mode 100644
index f38ba5b..0000000
--- a/public/fidl/fuchsia.ledger.cloud/serialized_commits.fbs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-namespace cloud_provider;
-
-table SerializedCommit {
- id: [ubyte];
- data: [ubyte];
-}
-
-table SerializedCommits {
- commits: [SerializedCommit];
-}
-
-root_type SerializedCommits;
diff --git a/public/fidl/fuchsia.ledger/BUILD.gn b/public/fidl/fuchsia.ledger/BUILD.gn
deleted file mode 100644
index 74c8b12..0000000
--- a/public/fidl/fuchsia.ledger/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-fidl("fuchsia.ledger") {
- sdk_category = "partner"
-
- sources = [
- "ledger.fidl",
- ]
-
- public_deps = [
- "//zircon/public/fidl/fuchsia-mem",
- ]
-}
diff --git a/public/fidl/fuchsia.ledger/MAINTAINERS b/public/fidl/fuchsia.ledger/MAINTAINERS
deleted file mode 100644
index d0e7ba7..0000000
--- a/public/fidl/fuchsia.ledger/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-etiennej@google.com
-qsr@google.com
diff --git a/public/fidl/fuchsia.ledger/ledger.fidl b/public/fidl/fuchsia.ledger/ledger.fidl
deleted file mode 100644
index e393885..0000000
--- a/public/fidl/fuchsia.ledger/ledger.fidl
+++ /dev/null
@@ -1,570 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.ledger;
-
-using fuchsia.mem;
-using zx;
-
-// This file contains definitions of interfaces and data structures to access
-// the Fuchsia Ledger.
-
-/// Response code for ledger operations.
-enum Status : int32 {
- OK = 0;
- PARTIAL_RESULT = 1;
- INVALID_TOKEN = 2;
- INVALID_ARGUMENT = 3;
- PAGE_NOT_FOUND = 4;
- KEY_NOT_FOUND = 5;
- REFERENCE_NOT_FOUND = 6;
- NEEDS_FETCH = 7;
- IO_ERROR = 8;
- NETWORK_ERROR = 9;
- TRANSACTION_ALREADY_IN_PROGRESS = 10;
- NO_TRANSACTION_IN_PROGRESS = 11;
- INTERNAL_ERROR = 12;
- VALUE_TOO_LARGE = 13;
- ILLEGAL_STATE = 14;
- UNKNOWN_ERROR = -1;
-};
-
-/// Size in bytes of Page IDs.
-const uint32 kPageIdSize = 16;
-
-struct PageId {
- array<uint8>:kPageIdSize id;
-};
-
-/// Base interface for all services offered by the Ledger.
-//
-/// In case of an unexpected error on one of the service offered by the Ledger,
-/// the service will close the connected channel, sending a |ledger.Status| as an epitaph.
-///
-/// If a client needs to ensure a sequence of operation has been processed by
-/// the service, it can issue a |Sync| command. The response will be send once
-/// all request started before the |Sync| request has been processed by the
-/// service.
-[FragileBase]
-interface ErrorNotifier {
- 1000: Sync() -> ();
-};
-
-[Discoverable]
-interface Ledger {
- /// Retrieves the page with the given identifier, creating it if needed. A
- /// |null| identifier can be passed to create a new page with a random unique
- /// identifier. It is allowed to connect to the same page concurrently
- /// multiple times.
-
- /// Parameters:
- /// |id| the identifier of the page, or |null| to create a new page with a random identifier.
- ///
- /// Returns OK and binds |page_request| to the page on success.
- 1: GetPage(PageId? id, request<Page> page_request) -> (Status status);
-
- /// Gets the page with identifier
- /// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].
- /// This is a convenience method equivalent to:
- /// GetPage([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], page_request).
- 2: GetRootPage(request<Page> page_request) -> (Status status);
-
- /// Sets the |ConflictResolverFactory| to use for resolving conflicts on pages.
- /// If this method has never been called, a last-one-wins policy will be used
- /// for every page. If this method is called multiple times, the factories are
- /// kept and conflict resolver requests are sent to one of the connected
- /// factories. If all factories are later disconnected, pages that already have
- /// a conflict resolution strategy (because they were opened before the factory
- /// disconnected) will continue using their current strategy. The pages for
- /// which no conflict resolution is set up will not get their conflicts
- /// resolved until this method is called again.
- 3: SetConflictResolverFactory(ConflictResolverFactory factory)
- -> (Status status);
-};
-
-/// A reference to a value.
-struct Reference {
- vector<uint8> opaque_id;
-};
-
-/// A continuation token for paginated requests.
-struct Token {
- vector<uint8> opaque_id;
-};
-
-/// The result of a wait for conflict resolution. See
-/// |Page.WaitForConflictResolution| for details.
-enum ConflictResolutionWaitStatus {
- /// No conflict was observed when the callback was registered.
- NO_CONFLICTS = 0;
- /// Some conflicts were observed when the callback was registered, and all
- /// have been resolved.
- CONFLICTS_RESOLVED = 1;
-};
-
-/// A page is the smallest unit of syncable data.
-interface Page {
- /// Returns the identifier for the page.
- 1: GetId() -> (PageId id);
-
- /// Creates a snapshot of the page, allowing the client app to read a
- /// consistent view of the content of the page. If |key_prefix| is provided,
- /// the resulting snapshot includes only the entries with matching keys.
- ///
- /// If |watcher| is provided, it will receive notifications for changes of the
- /// page state on this page connection newer than the resulting snapshot.
- /// Change notifications will only contain the entries matching |key_prefix|.
- /// To receive all changes, use an empty |key_prefix|.
- 2: GetSnapshot(request<PageSnapshot> snapshot_request,
- vector<uint8>:256 key_prefix, PageWatcher? watcher) -> (Status status);
-
- // Mutation operations.
-
- // Key level operations.
- /// Mutations are bundled together into atomic commits. If a transaction is in
- /// progress, the list of mutations bundled together is tied to the current
- /// transaction. If no transaction is in progress, mutations will be bundled
- /// with the following rules:
- /// - A call to either |GetSnapshot()| or |StartTransaction()| will
- /// commit any pending mutations.
- /// - All pending mutations will regularly be bundled together and committed.
- /// They are guaranteed to be persisted as soon as the client receives a
- /// successful status.
- /// |Put()| and |PutWithPriority()| can be used for small values that
- /// fit inside a FIDL message. If the value is bigger, a reference must be
- /// first created using |CreateReferenceFromSocket()| or
- /// |CreateReferenceFromBuffer()| and then |PutReference()| can be used.
- /// |PutWithPriority()| and |PutReference()| have an additional |priority|
- /// parameter managing the synchronization policy for this value. |Put()| uses
- /// a default priority of |Priority.EAGER|. For the list of available
- /// priorities and their definition, see |Priority|.
- 3: Put(vector<uint8>:256 key, vector<uint8> value) -> (Status status);
- 4: PutWithPriority(vector<uint8>:256 key, vector<uint8> value,
- Priority priority) -> (Status status);
- 5: PutReference(vector<uint8>:256 key, Reference reference, Priority priority)
- -> (Status status);
- 6: Delete(vector<uint8>:256 key) -> (Status status);
-
- // Page level operations.
-
- /// Deletes all entries in the page.
- /// Outside of a transaction, this operation is equivalent to deleting every
- /// key currently present on the page in a single transaction.
- /// In a transaction, this operation is equivalent to deleting every key
- /// present in the page before the transaction, as well as any new key added
- /// since the transaction started.
- 7: Clear() -> (Status status);
-
- // References.
- /// Creates a new reference. The object is not part of any commit. It must be
- /// associated with a key using |PutReference()|. The content of the reference
- /// will be the content of the socket. The content size must be equal to
- /// |size|, otherwise the call will fail.
- 8: CreateReferenceFromSocket(uint64 size, handle<socket> data)
- -> (Status status, Reference? reference);
- /// Creates a new reference. The object is not part of any commit. It must be
- /// associated with a key using |PutReference()|. The content of the reference
- /// will be the content of the buffer.
- 9: CreateReferenceFromBuffer(fuchsia.mem.Buffer buffer)
- -> (Status status, Reference? reference);
-
- // Transactions.
-
- /// Transactions allow the client to ensures changes are seen atomically by
- /// observers of this page. Once a transaction is started with
- /// |StartTransaction()|, every call to |Put(...)| and |Delete(...)| will not
- /// be visible until either |Commit()| is called, and all changes are applied
- /// in a single commit, or |Rollback()| is called and all changes are
- /// discarded.
- ///
- /// Parallel transactions on the same *page connection* are not allowed, and
- /// calling |StartTransaction()| when a transaction is already in progress
- /// returns an error. However, a client is free to connect to the same page
- /// multiple times, and run parallel transactions on the same page using
- /// separate connections. In this case, commiting each transaction creates
- /// divergent commits, which are later subject to conflict resolution.
- ///
- /// When a transaction is in progress, the page content visible *on this page
- /// connection* is pinned to the state from when |StartTransaction()| was
- /// called. In particular, no watch notifications are delivered, and the
- /// conflict resolution is not invoked while the transaction is in progress. If
- /// conflicting changes are made or synced while the transaction is in
- /// progress, conflict resolution is invoked after the transaction is
- /// committed.
- ///
- /// Starting a transaction will block until all watchers registered on this
- /// page connection have received the current page state, ie. the one that
- /// will be used as the base of the transaction. Put (with all its variants)
- /// and Delete calls may be pipelined while StartTransaction() is pending and
- /// will be taken into account in the transaction while it is pending.
- 10: StartTransaction() -> (Status status);
- 11: Commit() -> (Status status);
- 12: Rollback() -> (Status status);
-
- /// Sets a watcher to track the synchronisation state of this page. The
- /// current state is immediately sent to the watcher when this method is
- /// called.
- 13: SetSyncStateWatcher(SyncWatcher watcher) -> (Status status);
-
- // Conflict resolution.
-
- /// Waits until all conflicts are resolved before calling the callback.
- /// The client can call this method multiple times, even before the previous
- /// calls are completed. Callbacks will be executed in the order they were
- /// added and indicate whether a merge happened between the callback
- /// registration and its execution.
- /// If there are no pending conflicts at the time this is called, the callback
- /// gets executed right away.
- 14: WaitForConflictResolution() -> (ConflictResolutionWaitStatus wait_status);
-};
-
-/// The synchronization priority of a reference.
-enum Priority {
- /// EAGER values will be downloaded with the commit and have the same
- /// availability.
- EAGER = 0;
- /// LAZY values will not be downloaded with their commit, but only on demand.
- /// A LAZY value thus may not be available when requested, for example if the
- /// device has no internet connection at request time.
- LAZY = 1;
-};
-
-/// A pair of key and value.
-struct Entry {
- vector<uint8>:256 key;
- /// |value| is null and |size| is 0 if the value requested has the LAZY
- /// priority and is not present on the device. Clients must use a Fetch call
- /// to retrieve the contents.
- fuchsia.mem.Buffer? value;
- Priority priority;
-};
-
-/// A value inlined in a message.
-struct InlinedValue {
- vector<uint8> value;
-};
-
-/// A pair of key and an inlined value.
-struct InlinedEntry {
- vector<uint8>:256 key;
- /// |value| is null if the value requested has the LAZY priority and is not
- /// present on the device. Clients must use a Fetch call to retrieve the
- /// contents.
- InlinedValue? inlined_value;
- Priority priority;
-};
-
-/// The content of a page at a given time. Closing the connection to a |Page|
-/// interface closes all |PageSnapshot| interfaces it created. The contents
-/// provided by this interface are limited to the prefix provided to the
-/// Page.GetSnapshot() call.
-interface PageSnapshot {
- /// Returns the entries in the page with keys greater or equal to |key_start|
- /// using the lexicographic order. If |key_start| is empty, all entries are
- /// returned. If the result fits in a single fidl message, |status| will be
- /// |OK| and |next_token| equal to NULL. Otherwise, |status| will be
- /// |PARTIAL_RESULT| and |next_token| will have a non-NULL value. To retrieve
- /// the remaining results, another call to |GetEntries| should be made,
- /// initializing the optional |token| argument with the value of |next_token|
- /// returned in the previous call. |status| will be |PARTIAL_RESULT| as long
- /// as there are more results and |OK| once finished.
- /// Only |EAGER| values are guaranteed to be returned inside |entries|.
- /// Missing |LAZY| values can be retrieved over the network using Fetch().
- /// The returned |entries| are sorted by |key|.
- 1: GetEntries(vector<uint8>:256 key_start, Token? token)
- -> (Status status, vector<Entry> entries, Token? next_token);
-
- /// Same as |GetEntries()|. |VALUE_TOO_LARGE| is returned if a value does not
- /// fit in a FIDL message.
- 2: GetEntriesInline(vector<uint8>:256 key_start, Token? token)
- -> (Status status, vector<InlinedEntry> entries,
- Token? next_token);
-
- /// Returns the keys of all entries in the page which are greater or equal to
- /// |key_start| using the lexicographic order. If |key_start| is empty, all
- /// keys are returned. If the result fits in a single FIDL message, |status|
- /// will be |OK| and |next_token| equal to NULL. Otherwise, |status| will be
- /// |PARTIAL_RESULT| and |next_token| will have a non-NULL value. To retrieve
- /// the remaining results, another call to |GetKeys| should be made,
- /// initializing the optional |token| argument with the value of |next_token|
- /// returned in the previous call.
- /// The returned |keys| are sorted. |status| will be |PARTIAL_RESULT| as long
- /// as there are more results and |OK| once finished.
- 3: GetKeys(vector<uint8>:256 key_start, Token? token)
- -> (Status status, vector<vector<uint8>:256> keys,
- Token? next_token);
-
- /// Returns the value of a given key.
- /// Only |EAGER| values are guaranteed to be returned. Calls when the value is
- /// |LAZY| and not available will return a |NEEDS_FETCH| status. The value can
- /// be retrieved over the network using a Fetch() call.
- 4: Get(vector<uint8>:256 key) -> (Status status, fuchsia.mem.Buffer? buffer);
-
- /// Returns the value of a given key if it fits in a FIDL message.
- /// |VALUE_TOO_LARGE| is returned if the value does not fit in a FIDL message.
- /// See |Get()| for additional information.
- 5: GetInline(vector<uint8>:256 key) -> (Status status, InlinedValue? value);
-
- /// Fetches the value of a given key, over the network if not already present
- /// locally. |NETWORK_ERROR| is returned if the download fails (e.g.: network
- /// is not available).
- 6: Fetch(vector<uint8>:256 key) -> (Status status, fuchsia.mem.Buffer? buffer);
-
- /// Fetches the value of a given key, over the network if not already present
- /// locally, and returns a shared handle of a part of the value of a given
- /// key, starting at the position that is specified by |offset|. If |offset|
- /// is less than 0, starts at |-offset| from the end of the value.
- /// Returns at most |max_size| bytes. If |max_size| is less than 0, returns
- /// everything.
- 7: FetchPartial(vector<uint8>:256 key, int64 offset, int64 max_size)
- -> (Status status, fuchsia.mem.Buffer? buffer);
-};
-
-enum ResultState {
- COMPLETED = 0;
- PARTIAL_STARTED = 1;
- PARTIAL_CONTINUED = 2;
- PARTIAL_COMPLETED = 3;
-};
-
-struct PageChange {
- /// The timestamp of this change. This represents the number of nanoseconds
- /// since Unix epoch (i.e., since "1970-01-01 00:00 UTC", ignoring leap
- /// seconds). This value is set by the device that created the change and is
- /// not synchronized across devices. In particular, there is no guarantee that
- /// the |timestamp| of a follow up change is greater than this one's.
- zx.time timestamp;
- /// List of new and modified entries. |changed_entries| are sorted by |key|.
- vector<Entry> changed_entries;
- /// List of deleted keys, in sorted order.
- vector<vector<uint8>:256> deleted_keys;
-};
-
-/// Interface to watch changes to a page. The client will receive changes made by
-/// itself, as well as other clients or synced from other devices. The contents
-/// of a transaction will never be split across multiple OnChange() calls, but
-/// the contents of multiple transactions may be merged into one OnChange() call.
-interface PageWatcher {
- /// Called for changes made on the page. If the result fits in a single fidl
- /// message, |result_state| will be |COMPLETED|. Otherwise, OnChange will be
- /// called multiple times and |result_state| will be |PARTIAL_STARTED| the
- /// first time, |PARTIAL_CONTINUED| the following ones and finally
- /// |PARTIAL_COMPLETED| on the last call. No new OnChange() call will be made
- /// while the previous one is still active. If clients are interested in the
- /// full content of the page at the time of the change, they can request a
- /// PageSnapshot in the callback. This request is optional and can be requested
- /// in any partial (started, continued or completed) and/or COMPLETED OnChange
- /// call. In any case, all requests made on a sequence of OnChange calls for
- /// the same page change, will always return the same snapshot: the one
- /// including all changes.
- ///
- /// Note that calls to Page.StartTransaction() on the page connection on which
- /// the watcher was registered will block until all OnChange() calls have
- /// finished.
- 1: OnChange(PageChange page_change, ResultState result_state)
- -> (request<PageSnapshot>? snapshot);
-};
-
-/// This interface lets clients control the conflict resolution policy of the
-/// ledger. It allows them to either use pre-defined policies, or provide their
-/// own implementation. This can be decided on a page-by-page basis.
-interface ConflictResolverFactory {
- /// Returns the conflict resolution policy for the given page.
- 1: GetPolicy(PageId page_id) -> (MergePolicy policy);
- /// Returns a |ConflictResolver| to use for the given page. This will only be
- /// called if |GetPolicy| for the same page returned |AUTOMATIC_WITH_FALLBACK|
- /// or |CUSTOM|.
- 2: NewConflictResolver(PageId page_id, request<ConflictResolver> resolver);
-};
-
-/// Strategy to be used when resolving conflicts.
-enum MergePolicy {
- /// Last one wins. When 2 commits are merged, the resulting commit contains:
- /// - all keys/values that do not conflict
- /// - all keys/values of the commit with the biggest timestamp (or biggest
- /// id, if the timestamps are the same)
- LAST_ONE_WINS = 0;
- /// Commits are automatically merged when no key has been modified on both
- /// sides. When a key has been modified by both commits, conflict resolution is
- /// delegated to a user-provided |ConflictResolver| that is created by calling
- /// |ConflictResolverFactory.NewConflictResolver|. A single |ConflictResolver|
- /// is created for each page. When the |ConflictResolver| is disconnected, a
- /// new one is requested.
- AUTOMATIC_WITH_FALLBACK = 1;
- /// All merges are resolved by a user-provided |ConflictResolver| as described
- /// above, even when commits to be merged change a disjoined set of keys.
- CUSTOM = 2;
-};
-
-/// A value that is either small enough to be directly embedded in |bytes| or
-/// that is referenced by |reference|.
-union BytesOrReference {
- vector<uint8> bytes;
- Reference reference;
-};
-
-/// Source of the value used to resolve a conflict.
-///
-/// |DELETE| deletes the key; |NEW| creates a new value; |RIGHT|
-/// selects the value from the right branch. If no value is sent, the left
-/// branch is selected.
-/// Used by |MergedValue|.
-enum ValueSource {
- RIGHT = 0;
- NEW = 1;
- DELETE = 2;
-};
-
-/// A change in the page. If |source| is set to |NEW|, |new_value| must be set
-/// to the new value. If |source| is not |NEW|, |new_value| and |priority| are
-/// ignored.
-struct MergedValue {
- vector<uint8>:256 key;
- ValueSource source;
- BytesOrReference? new_value;
- Priority priority;
-};
-
-/// An entry in a diff, as returned by |MergeResultProvider|.
-///
-/// If |base|, |left| or |right| are NULL, this means that the corresponding key
-/// was not present in the base, left or right (respectively) branch of the
-/// page.
-struct DiffEntry {
- vector<uint8>:256 key;
-
- Value? base;
- Value? left;
- Value? right;
-};
-
-/// A value in a DiffEntry.
-///
-/// If the value is LAZY and is not present locally, |value| will be NULL. The
-/// value can be retrieved using a |Fetch()| call on a corresponding snapshot.
-struct Value {
- fuchsia.mem.Buffer? value;
- Priority priority;
-};
-
-/// Status for methods that return a sequence of values.
-enum IterationStatus : int8 {
- /// The iteration has finished.
- OK = 0;
- /// The iteration has not finished. The method must be called again to
- /// retrieve the next batch of responses.
- PARTIAL_RESULT = 1;
-};
-
-/// A merge result provider, obtained from |ConflictResolver.Resolve()|. Can be
-/// used to retrieve data about the conflict, and provide the merge result. When
-/// all changes have been sent, |Done()| should be called to mark the end of
-/// incoming merge changes.
-interface MergeResultProvider : ErrorNotifier {
- /// |GetFullDiff| returns the set of all key/value pairs (entries) that
- /// have been modified between the common ancestor (see
- /// |ConflictResolver.Resolve()|) and the left and right branches.
- ///
- /// Values of |LAZY| keys may not be present on the device. In that case, the
- /// corresponding Value objects within DiffEntry will have a NULL |value|
- /// field. If needed, |left| and |right|, provided by the
- /// |ConflictResolver.Resolve()| method can be used by clients to Fetch these
- /// values. If a key is not present at all in one of the branches, its
- /// corresponding Value object will be NULL.
- ///
- /// The first call to get the |DiffEntry|s should be done using a NULL
- /// token. If the result does not fit in a single fidl message, |status| will
- /// be |PARTIAL_RESULT| and |next_token| will have a non-NULL value, which can
- /// be used to retrieve the rest of the results by calling |GetFullDiff()|
- /// with that token.
- 1: GetFullDiff(Token? token)
- -> (Status status, vector<DiffEntry> changes, Token? next_token);
- 1001: GetFullDiffNew(Token? token)
- -> (IterationStatus status, vector<DiffEntry> changes, Token? next_token);
-
- /// |GetConflictingDiff| returns the set of all key/value pairs that were
- /// modified on both sides to different values, or deleted on one side and
- /// modified on the other.
- ///
- /// It behaves like |GetFullDiff| otherwise.
- 2: GetConflictingDiff(Token? token)
- -> (Status status, vector<DiffEntry> changes, Token? next_token);
- 1002: GetConflictingDiffNew(Token? token)
- -> (IterationStatus status, vector<DiffEntry> changes, Token? next_token);
-
- /// Once the result of the merge has been computed |Merge()| can be called with
- /// all changes that resolve this conflict. If the result does not fit in a
- /// single fidl message, |Merge()| can be called multiple times. If any of the
- /// |Merge()| calls fails, i.e. |status| is not |OK|, all following calls will
- /// fail with the same error.
- ///
- /// If a key/value pair is sent multiple times in one or several |Merge()|
- /// call, only the last pair is taken into account.
- ///
- /// For all keys for which no merged value has been set (either here or
- /// through |MergeNonConflictingEntries()| below), the left value will be
- /// used. It is thus not necessary to send a MergedValue with a |LEFT| value
- /// source, unless to overwrite a previous MergedValue.
- 3: Merge(vector<MergedValue> merge_changes) -> (Status status);
- 1003: MergeNew(vector<MergedValue> merge_changes);
-
- /// Automatically merges all non conflicting entries (entries that are
- /// modified on one side only or identical on both sides). This is equivalent
- /// to sending, through |Merge()|, a MergedValue with a |RIGHT| ValueSource
- /// for all non-conflicting keys modified on the right side. Conflicting
- /// entries can still be merged using the |Merge()| method.
- 4: MergeNonConflictingEntries() -> (Status status);
- 1004: MergeNonConflictingEntriesNew();
-
- /// Marks the end of merge changes to resolve this conflict. After |Done()| is
- /// called |MergeResultProvider| interface cannot be used any more.
- 5: Done() -> (Status status);
- 1005: DoneNew();
-};
-
-/// Custom conflict resolver. If a |ConflictResolverFactory| is registered, and
-/// |ConflictResolverFactory.GetPolicy()| returns |AUTOMATIC_WITH_FALLBACK| or
-/// |CUSTOM| when called for a given page, the |NewConflictResolver| method will
-/// be called and will provide a |ConflictResolver|. Each time a custom conflict
-/// resolution is needed according to the chosen policy, the method
-/// |ConflictResolver.Resolve()| will be called, and the client will resolve the
-/// conflict by returning the final value for all conflicting keys as well as
-/// values for any other key that the client wants to change.
-interface ConflictResolver {
- /// Method called when a conflict needs to be resolved. |left| and |right|
- /// contain the snapshots of the two branches and |common_version| that of the
- /// lowest common ancestor. |common_version| can be NULL if this version is no
- /// longer available. The result of the merge can be given through the
- /// |result_provider|, using the left branch as the base of the merge commit,
- /// i.e. only key/value pairs that are different from the left version of the
- /// page should be sent. |result_provider| can also be used to retrieve the set
- /// of differences, i.e. conflicting keys, between the two versions.
- 1: Resolve(PageSnapshot left, PageSnapshot right, PageSnapshot? common_version,
- MergeResultProvider new_result_provider);
-};
-
-/// Synchronization state.
-enum SyncState {
- /// There are no pending operations.
- IDLE = 0;
- /// There are pending operations, but there is no syncing in progress. This
- /// could be because of (possibly a combination of):
- /// - waiting for better connectivity
- /// - waiting due to internal policies (e.g. batching network requests,
- /// waiting for a merge to happen before uploading)
- /// - waiting to determine if synchronization is needed (e.g. during initial
- /// setup)
- PENDING = 1;
- /// Synchronization is in progress.
- IN_PROGRESS = 2;
- /// An internal error occurred while trying to sync.
- ERROR = 3;
-};
-
-/// Watcher interface to be implemented by clients who wish to follow the
-/// synchronization status of their ledger. SyncStateChanged callback must be
-/// called for new state change calls to be sent.
-interface SyncWatcher {
- 1: SyncStateChanged(SyncState download_status, SyncState upload_status) -> ();
-};
diff --git a/public/fidl/fuchsia.modular.auth/BUILD.gn b/public/fidl/fuchsia.modular.auth/BUILD.gn
deleted file mode 100644
index f5bbc15..0000000
--- a/public/fidl/fuchsia.modular.auth/BUILD.gn
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-# TODO(alhaad/ukode): Also move these services to a separate repository.
-fidl("fuchsia.modular.auth") {
- sdk_category = "partner"
-
- sources = [
- "account/account.fidl",
- "account_provider.fidl",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.ui.viewsv1token",
- ]
-}
diff --git a/public/fidl/fuchsia.modular.auth/account/account.fidl b/public/fidl/fuchsia.modular.auth/account/account.fidl
deleted file mode 100644
index de52e9d..0000000
--- a/public/fidl/fuchsia.modular.auth/account/account.fidl
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.auth;
-
-// Stores attributes related to an account that is exposed to base shell.
-// A list of existing account(s) can be obtained via
-// UserProvider.PreviousUsers() and a new account can be added via
-// UserProvider.AddAccount().
-struct Account {
- // A randomly generated identifier that is used to identify this
- // account on this device. This is meant to be used by base shell when it
- // wants to login as a user who has previously logged in.
- string id;
-
- // The identity provider that was used to authenticate the user on this
- // device.
- IdentityProvider identity_provider;
-
- // Unique identifier configured for the given user at the Identity provider.
- // Profile id is fetched from user profile attributes as configured by the
- // user at the given identity provider.
- string profile_id;
-
- // The name that is displayed on the base shell while logging in. Display
- // name is fetched from user profile attributes as configured by the user at
- // the given identity provider.
- string display_name;
-
- // User's profile url that is used by the base shell while logging in.
- // Profile url is fetched from user profile attributes as configured by the
- // user at the given identity provider.
- string url;
-
- // User's profile image url that is used by the base shell while logging in.
- // Profile image url is fetched from user profile attributes as configured by
- // the user at the given identity provider.
- string image_url;
-};
-
-// The currently supported identity providers. An identity provider provides
-// identifiers for users to interact with the system and may provide information
-// about the user that is known to the provider.
-enum IdentityProvider {
- // An identity provider that's used for development and testing. If this
- // identity provider is chosen, the Framework will continue as if it has
- // identified the user. Note that the users that use this id provider would
- // not get cloud ledger access (unless done via a side channel).
- DEV = 0;
-
- // Uses Google as the identity provider. Doing this requires a working network
- // connection and a web view.
- GOOGLE = 1;
-};
diff --git a/public/fidl/fuchsia.modular.auth/account_provider.fidl b/public/fidl/fuchsia.modular.auth/account_provider.fidl
deleted file mode 100644
index e32a85c..0000000
--- a/public/fidl/fuchsia.modular.auth/account_provider.fidl
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.auth;
-
-using fuchsia.ui.viewsv1token;
-
-// Authentication errors returned by AccountProvider. It contains error status
-// code along with a detailed error message.
-struct AuthErr {
- Status status;
- string message;
-};
-
-// Specifies the success/failure status.
-enum Status {
- // Success
- OK = 0;
- // A problem with client configuration such as invalid_client, missing params
- // etc. This should happen only in development not at run-time, unless
- // user/developer changes any of this config. No retry is required.
- BAD_REQUEST = 1;
- // Unable to parse the server side response. Retry is optional, this error
- // should be extremely rare.
- BAD_RESPONSE = 2;
- // Server is reachable and propagated an error returned by OAuth Server
- // backends. That kind of error cannot be fixed on retries, and has some
- // root cause that needs to be addressed either in the client's configuration
- // or because the user explicitly revoked access to the client app. For
- // instance: invalid_token, expired_token, invalid_client_id, invalid_user,
- // invalid_args, etc.
- OAUTH_SERVER_ERROR = 3;
- // User cancelled the flow, no need to retry.
- USER_CANCELLED = 4;
- // Network error, eg. unreachable. This may be temporary, a retry is
- // recommended.
- NETWORK_ERROR = 5;
- // Internal error. Retry is optional, this error should be rare.
- INTERNAL_ERROR = 6;
-};
-
-// An interface that allows the Framework to talk to the token manager service
-// to add new accounts and be able to mint the corresponding |TokenManager|
-// specialized instances for thid party agents and first party ledger client.
-//
-// This is only meant to be used by the Framework and will be replaced with
-// |AccountManager| in the near future.
-[Discoverable]
-interface AccountProvider {
- // Adds a new user account. This involves talking to the identity provider and
- // fetching profile attributes.
- 2: AddAccount(IdentityProvider identity_provider)
- -> (Account? account, string? error_code);
-
- // Removes an existing user account. This involves talking to account's
- // identity provider and revoking user credentials both locally and remotely.
- // This operation also deletes cached tokens for the given account.
- //
- // TODO(ukode): Modify this api to take account_id and IDP as input once the
- // Account struct is cleaned up.
- //
- // If |revoke_all| is set to true, then all device credentials are revoked
- // both locally and remotely on the backend server and user is logged out from
- // all devices. If |revoke_all| is set to false, then credentials stored
- // locally are wiped. This includes cached tokens such as access/id and
- // firebase tokens and the locally persisted refresh token. By default,
- // |revoke_all| is set to false and deletes account only from that given
- // device.
- 3: RemoveAccount(Account account, bool revoke_all) -> (AuthErr status);
-
- // This signals |AccountProvider| to teardown itself. After the
- // AccountProvider responds by closing its handle, the caller may terminate
- // the |AccountProvider| application if it hasn't already exited.
- 5: Terminate();
-};
diff --git a/public/fidl/fuchsia.modular.internal/BUILD.gn b/public/fidl/fuchsia.modular.internal/BUILD.gn
deleted file mode 100644
index 2a0645f..0000000
--- a/public/fidl/fuchsia.modular.internal/BUILD.gn
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-fidl("fuchsia.modular.internal") {
- cpp_legacy_callbacks = true
-
- sources = [
- "basemgr_debug.fidl",
- "sessionmgr.fidl",
- "story_data.fidl",
- ]
- deps = [
- "//garnet/public/fidl/fuchsia.auth",
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/fidl/fuchsia.ui.viewsv1token",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.auth",
- ]
-}
diff --git a/public/fidl/fuchsia.modular.internal/basemgr_debug.fidl b/public/fidl/fuchsia.modular.internal/basemgr_debug.fidl
deleted file mode 100644
index 44e6527..0000000
--- a/public/fidl/fuchsia.modular.internal/basemgr_debug.fidl
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.internal;
-
-// A debug interface exposed by `basemgr` to allow developer tools to control
-// state within the `basemgr` process.
-[Discoverable]
-interface BasemgrDebug {
- // Restarts the current session.
- RestartSession();
-
- // Logs in as a guest user.
- LoginAsGuest();
-};
diff --git a/public/fidl/fuchsia.modular.internal/sessionmgr.fidl b/public/fidl/fuchsia.modular.internal/sessionmgr.fidl
deleted file mode 100644
index 5a9f440..0000000
--- a/public/fidl/fuchsia.modular.internal/sessionmgr.fidl
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.internal;
-
-using fuchsia.auth;
-using fuchsia.modular;
-using fuchsia.modular.auth;
-using fuchsia.ui.policy;
-using fuchsia.ui.viewsv1token;
-
-// The basemgr application (there is no |Basemgr| service) requests
-// an instance of this service in order to launch and display a |Sessionmgr| per
-// user.
-// TODO(alexmin): Re-word this bit once the Sessionmgr implementation is landed.
-[Discoverable] // Created by sessionmgr application.
-interface Sessionmgr {
- // Launches a sessionmgr instance for a user identified by |user_id| and
- // specific TokenManager handles for ledger and agent_runner.
- // TODO(alhaad): Fold paramters into |UserContext|.
- 1: Initialize(fuchsia.modular.auth.Account? account,
- fuchsia.modular.AppConfig session_shell,
- fuchsia.modular.AppConfig story_shell,
- fuchsia.auth.TokenManager? ledger_token_manager,
- fuchsia.auth.TokenManager? agent_token_manager,
- UserContext user_context,
- request<fuchsia.ui.viewsv1token.ViewOwner>? view_owner);
-
- 2: SwapSessionShell(fuchsia.modular.AppConfig session_shell) -> ();
-};
-
-// This interface is provided by basemgr to |Sessionmgr|.
-interface UserContext {
- // See detailed comments in SessionShellContext.Logout().
- 1: Logout();
-
- 2: GetPresentation(request<fuchsia.ui.policy.Presentation> presentation);
-};
diff --git a/public/fidl/fuchsia.modular.internal/story_data.fidl b/public/fidl/fuchsia.modular.internal/story_data.fidl
deleted file mode 100644
index ed1f50f..0000000
--- a/public/fidl/fuchsia.modular.internal/story_data.fidl
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.internal;
-
-using fuchsia.ledger;
-using fuchsia.modular;
-
-// Metadata and summary information about a single story. Does not contain the
-// data necessary to run a story: see story_model.fidl for that.
-struct StoryData {
- // Metadata available to the SessionShell.
- fuchsia.modular.StoryInfo story_info;
-
- // An optional client-supplied name for this story.
- string? story_name;
-
- // Story metadata and configuration.
- fuchsia.modular.StoryOptions story_options;
-
- // Page id on the user's ledger which stores story information. It
- // might be NULL until the story is being started.
- fuchsia.ledger.PageId? story_page_id;
-};
diff --git a/public/fidl/fuchsia.modular.storymodel/BUILD.gn b/public/fidl/fuchsia.modular.storymodel/BUILD.gn
deleted file mode 100644
index 0cbb358..0000000
--- a/public/fidl/fuchsia.modular.storymodel/BUILD.gn
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-fidl("fuchsia.modular.storymodel") {
- sources = [
- "constants.fidl",
- "story_model.fidl",
- "story_model_mutation.fidl",
- ]
- deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
diff --git a/public/fidl/fuchsia.modular.storymodel/constants.fidl b/public/fidl/fuchsia.modular.storymodel/constants.fidl
deleted file mode 100644
index 5630ec1..0000000
--- a/public/fidl/fuchsia.modular.storymodel/constants.fidl
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.storymodel;
-
-const uint32 MAX_STORY_NAME_LENGTH = 1024;
-
-const uint32 MAX_MODULES_PER_STORY = 128;
-const uint32 MAX_MODULE_NAME_LENGTH = 1024;
diff --git a/public/fidl/fuchsia.modular.storymodel/story_model.fidl b/public/fidl/fuchsia.modular.storymodel/story_model.fidl
deleted file mode 100644
index a496a22..0000000
--- a/public/fidl/fuchsia.modular.storymodel/story_model.fidl
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.storymodel;
-
-using fuchsia.modular;
-
-// IMPORTANT: StoryModel must only contain field types that are cloneable.
-//
-// The `StoryModel` FIDL table is used to represent the state of a story.
-// `sessionmgr` keeps a separate `StoryModel` in memory for each running story,
-// and also persists changes to it onto storage.
-table StoryModel {
- // The name of the story, set at story create time.
- //
- // Always set. Immutable.
- 1: string:MAX_STORY_NAME_LENGTH name;
-
- // An enum describing if the story is RUNNING, STOPPING, STOPPED.
- //
- // Always set. Defaults to StoryState::STOPPED.
- 2: fuchsia.modular.StoryState runtime_state;
-
- // An enum describing how the story should be displayed, when focused,
- // in the StoryShell.
- //
- // Always set. Defaults to StoryVisibilityState::DEFAULT.
- 3: fuchsia.modular.StoryVisibilityState visibility_state;
-
- // A list of modules present in the story.
- //
- // Always set. Defaults to an empty list.
- 4: vector<ModuleModel>:MAX_MODULES_PER_STORY modules;
-};
-
-table ModuleModel {
- // The name of the module, set by the client that requested creation
- // of the module. The name uniquely identifies this module within
- // the story.
- //
- // Always set. Immutable.
- 1: string:MAX_MODULE_NAME_LENGTH name;
-};
\ No newline at end of file
diff --git a/public/fidl/fuchsia.modular.storymodel/story_model_mutation.fidl b/public/fidl/fuchsia.modular.storymodel/story_model_mutation.fidl
deleted file mode 100644
index 9d096e6..0000000
--- a/public/fidl/fuchsia.modular.storymodel/story_model_mutation.fidl
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular.storymodel;
-
-using fuchsia.modular;
-
-// The `StoryModelMutation` union represents the set of all possible low-level mutations to data
-// for a single story. A vector of mutations represent mutations that are to be applied to the
-// model in a single transaction.
-//
-// This structured is used internally in `sessionmgr` and is not exposed to any clients outside
-// that process. Clients will typically construct these indirectly using convenience methods on the
-// `StoryMutator` class.
-union StoryModelMutation {
- // Sets the value of |StoryModel.visibility_state|.
- fuchsia.modular.StoryVisibilityState set_visibility_state;
-
- // Sets the value of |StoryModel.runtime_state|.
- fuchsia.modular.StoryState set_runtime_state;
-};
diff --git a/public/fidl/fuchsia.modular/BUILD.gn b/public/fidl/fuchsia.modular/BUILD.gn
deleted file mode 100644
index e2f1cb8..0000000
--- a/public/fidl/fuchsia.modular/BUILD.gn
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-fidl("fuchsia.modular") {
- cpp_legacy_callbacks = true
-
- sdk_category = "partner"
-
- sources = [
- "agent/agent.fidl",
- "agent/agent_context.fidl",
- "agent/agent_controller/agent_controller.fidl",
- "agent/agent_provider.fidl",
- "basemgr/base_shell.fidl",
- "basemgr/user_provider.fidl",
- "clipboard/clipboard.fidl",
- "component/component_context.fidl",
- "component/message_queue.fidl",
- "config/config.fidl",
- "context/context_engine.fidl",
- "context/context_reader.fidl",
- "context/context_writer.fidl",
- "context/debug.fidl",
- "context/metadata.fidl",
- "context/value.fidl",
- "context/value_type.fidl",
- "entity/entity.fidl",
- "entity/entity_provider.fidl",
- "entity/entity_reference_factory.fidl",
- "entity/entity_resolver.fidl",
- "intent/intent.fidl",
- "intent/intent_handler.fidl",
- "lifecycle/lifecycle.fidl",
- "module/link_path.fidl",
- "module/module_context.fidl",
- "module/module_controller.fidl",
- "module/module_data.fidl",
- "module/module_manifest.fidl",
- "module/module_state.fidl",
- "module_resolver/module_resolver.fidl",
- "session/device_map.fidl",
- "session/focus.fidl",
- "session/session_shell.fidl",
- "story/create_link.fidl",
- "story/create_module_parameter_map.fidl",
- "story/link.fidl",
- "story/puppet_master.fidl",
- "story/story_command.fidl",
- "story/story_controller.fidl",
- "story/story_info.fidl",
- "story/story_options.fidl",
- "story/story_provider.fidl",
- "story/story_shell.fidl",
- "story/story_state.fidl",
- "story/story_visibility_state.fidl",
- "suggestion/debug.fidl",
- "suggestion/proposal.fidl",
- "suggestion/proposal_publisher.fidl",
- "suggestion/query_handler.fidl",
- "suggestion/suggestion_display.fidl",
- "suggestion/suggestion_engine.fidl",
- "suggestion/suggestion_provider.fidl",
- "suggestion/user_input.fidl",
- "surface/container.fidl",
- "surface/surface.fidl",
- "user_intelligence/intelligence_services.fidl",
- "user_intelligence/scope.fidl",
- "user_intelligence/user_intelligence_provider.fidl",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.auth",
- "//garnet/public/fidl/fuchsia.images",
- "//garnet/public/fidl/fuchsia.media",
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/fidl/fuchsia.ui.viewsv1token",
- "//peridot/public/fidl/fuchsia.ledger",
- "//peridot/public/fidl/fuchsia.modular.auth",
- "//peridot/public/fidl/fuchsia.speech",
- "//zircon/public/fidl/fuchsia-mem",
- ]
-}
diff --git a/public/fidl/fuchsia.modular/README.md b/public/fidl/fuchsia.modular/README.md
deleted file mode 100644
index b91e29d..0000000
--- a/public/fidl/fuchsia.modular/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Modular FIDL API
-
-## Public SDK Approved APIs
-
-Modular has a large surface area which is undergoing significant change.
-For this reason, not all FIDL services are approved for external use.
-Here are the currently approved APIs:
-
-* fuchsia.modular.Agent
-* fuchsia.modular.PuppetMaster (with the exception of method `PuppetMaster.WatchSession()`).
-* fuchsia.modular.StoryPuppetMaster
-
-> NOTE: All `struct`s and `table`s assocated with the services above are
-> implicitly included.
\ No newline at end of file
diff --git a/public/fidl/fuchsia.modular/agent/agent.fidl b/public/fidl/fuchsia.modular/agent/agent.fidl
deleted file mode 100644
index 8e05225..0000000
--- a/public/fidl/fuchsia.modular/agent/agent.fidl
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.sys;
-
-/// An agent is a component whose lifecycle is not tied to any Story.
-///
-/// - An agent is a singleton instance.
-/// - Components can connect to an Agent using the
-/// fuchsia.modular.ComponentContext capability.
-/// - An agent vends services to components that connect to it over a
-/// ServiceProvider.
-/// - An agent is started when someone wants to connect to it, or when a task it
-/// has scheduled has triggered.
-///
-/// This FIDL interface should be implemented by a component that is meant to be
-/// run as an Agent.
-///
-/// When an agent application implements the |Lifecycle| interface, it can
-/// receive a signal for when it should stop. An agent may be stopped for the
-/// following reasons:
-///
-/// (1) All |AgentController| connections associated with this agent are closed.
-///
-/// (2) The system wants to optimize for resources.
-///
-/// Once the framework delivers a |Lifecycle.Terminate()|, the agent application
-/// may exit itself, or is killed by framework after a timeout.
-///
-/// For more info see:
-/// - fuchsia.modular.AgentContext and fuchsia.modular.ComponentContext for
-/// capabilities an agent has.
-/// - fuchsia.modular.Lifecycle for how Components get lifecycle events.
-[Discoverable] // Created by each agent.
-interface Agent {
- /// Called when some component tries to connect to this agent. |requestor_url|
- /// is the identifier for the component which called
- /// |ComponentContext.ConnectToAgent()|. The |services| are provided to that
- /// component.
- 1: Connect(string requestor_url, request<fuchsia.sys.ServiceProvider> services);
-
- /// Called when some task identified by |task_id| is scheduled to run. The task
- /// was first posted by this Agent using |AgentContext.ScheduleTask()|. The
- /// return callback is called by this Agent when all work related to this task
- /// is completed. Note that the framework may call |Lifecycle.Terminate()|
- /// before RunTask returns.
- ///
- /// TODO(alhaad): The current implementation allows the Agent to run a task
- /// until its callback returns. If the task takes a long time to finish, the
- /// framework has no way to signal a request for termination other than to shut
- /// down the entire Agent instance. Instead, we should cap task length with
- /// strategies like budgets. Also, the Task should likely have its own
- /// connection that allows for more signalling.
- 2: RunTask(string task_id) -> ();
-};
diff --git a/public/fidl/fuchsia.modular/agent/agent_context.fidl b/public/fidl/fuchsia.modular/agent/agent_context.fidl
deleted file mode 100644
index c0f0b6d..0000000
--- a/public/fidl/fuchsia.modular/agent/agent_context.fidl
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.auth;
-
-/// An instance of this service is exposed to agents in their namespace.
-/// |AgentContext| allows an agent to schedule tasks which run in response to
-/// triggers. Triggers are conditions such as a message arriving on a
-/// MessageQueue.
-[Discoverable]
-interface AgentContext {
- /// DEPRECATED: ComponentContext is now available in the
- /// namespace/environment for Modules.
- 1: GetComponentContext(request<ComponentContext> request);
-
- /// Connects to an EntityReferenceFactory for this Agent. Entity references
- /// obtained from this EntityReferenceFactory will be resolved back to this
- /// Agent.
- 4: GetEntityReferenceFactory(request<EntityReferenceFactory> request);
-
- /// Schedules a task described in |task_info|. When this task is scheduled to
- /// run, Agent.RunTask() is called.
- ///
- /// TODO(MI4-962): Add a callback to task scheduling.
- 5: ScheduleTask(TaskInfo task_info);
-
- /// No new runs of this task will be scheduled.
- 6: DeleteTask(string task_id);
-
- /// The auth token manager this Agent may use for accessing external services.
- 7: GetTokenManager(request<fuchsia.auth.TokenManager> request);
-};
-
-/// Used to describe a task to the framework.
-struct TaskInfo {
- /// An agent provided task id that can be used later to refer to this task.
- string task_id;
-
- /// The condition that would cause this task to get scheduled.
- TriggerCondition trigger_condition;
-
- /// If set to true, the trigger condition will be persisted on the user's
- /// ledger and will be available across reboots and devices.
- bool persistent;
-};
-
-/// Describes the condition that needs to be met for a task to become scheduled.
-/// This is not yet complete and will be extended or changed.
-union TriggerCondition {
- /// Triggers when there is a new message on a message queue.
- ///
- /// |message_on_queue| is the name of the message queue to be watched. This
- /// means that only the component that originally obtained the message queue
- /// will be able to observe new message events.
- string message_on_queue;
-
- /// Triggers when a message queue is deleted.
- ///
- /// |queue_deleted| is the token for the message queue that is to be watched.
- /// This allows both message queue readers and writers to watch for queue
- /// deletions.
- string queue_deleted;
-
- /// Fires an inexact repeating alarm every |alarm_in_seconds| seconds that'll
- /// satisfy this trigger condition. The first alarm fires in
- /// |alarm_in_seconds| seconds.
- uint32 alarm_in_seconds;
-};
diff --git a/public/fidl/fuchsia.modular/agent/agent_controller/agent_controller.fidl b/public/fidl/fuchsia.modular/agent/agent_controller/agent_controller.fidl
deleted file mode 100644
index 5f587a4..0000000
--- a/public/fidl/fuchsia.modular/agent/agent_controller/agent_controller.fidl
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// This interface is used by the caller of ComponentContext::ConnectToAgent() to
-// tell the framework that it is still interested in keeping this Agent running.
-//
-// The system counts AgentController connections and terminates this Agent if
-// the count goes to zero.
-interface AgentController {
-};
diff --git a/public/fidl/fuchsia.modular/agent/agent_provider.fidl b/public/fidl/fuchsia.modular/agent/agent_provider.fidl
deleted file mode 100644
index 03d17c3..0000000
--- a/public/fidl/fuchsia.modular/agent/agent_provider.fidl
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Sessionmgr creates an instance of this service and passes it to the
-// SessionShell so it can observe Agents for the user.
-//
-// TODO(alhaad): Add interfaces for modifying Agents for the user.
-interface AgentProvider {
- // Registers a listener for changes in the list of agents.
- 1: Watch(AgentProviderWatcher watcher);
-};
-
-// This interface is implemented by clients of AgentProvider and is updated
-// whenever there is a change to the list of users.
-interface AgentProviderWatcher {
- // Gives a full list of all agents that are running or scheduled to run.
- // TODO(alhaad): This currently only contains the URL of the agents. It should
- // contain more state information.
- 1: OnUpdate(vector<string> agent_urls);
-};
diff --git a/public/fidl/fuchsia.modular/basemgr/base_shell.fidl b/public/fidl/fuchsia.modular/basemgr/base_shell.fidl
deleted file mode 100644
index ff27c45..0000000
--- a/public/fidl/fuchsia.modular/basemgr/base_shell.fidl
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.auth;
-using fuchsia.ui.policy;
-
-// This interface is implemented by a base shell. Dependencies and parameters
-// are passed to it in Initialize() on startup. The base shell is also
-// expected to implement Lifecycle in order to receive a Terminate() call on
-// teardown.
-//
-// In one component instance there can only be one BaseShell service instance.
-// The ViewOwner request is sent to the separate ViewProvider service. This way,
-// the base shell may be implemented as a flutter component.
-//
-// Teardown may be initiated by the base shell calling
-// BaseShellContext.Shutdown(), or by the system shutting down.
-[Discoverable]
-interface BaseShell {
- 1: Initialize(BaseShellContext base_shell_context,
- BaseShellParams base_shell_params);
-
- // This method may be invoked by the basemgr to request an
- // AuthenticationUIContext. |request| will then be used to request the base
- // shell to show login screen during a UserProvider.AddUser() or if a token
- // needs to be refreshed.
- 3: GetAuthenticationUIContext(request<fuchsia.auth.AuthenticationUIContext> request);
-};
-
-// This interface allows the |BaseShell| to request capabilities from the
-// |Basemgr| in a way that is more explicit about the services that are
-// offered than a generic |ServiceProvider|.
-interface BaseShellContext {
- 1: GetUserProvider(request<UserProvider> request);
-
- // This requests the shutdown of the basemgr.
- 2: Shutdown();
-};
-
-// These params are passed to |BaseShell.Initialize|.
-struct BaseShellParams {
- // TODO(jjosh): make this non-optional, if feasible.
- fuchsia.ui.policy.Presentation? presentation;
-};
diff --git a/public/fidl/fuchsia.modular/basemgr/user_provider.fidl b/public/fidl/fuchsia.modular/basemgr/user_provider.fidl
deleted file mode 100644
index 45aeca7..0000000
--- a/public/fidl/fuchsia.modular/basemgr/user_provider.fidl
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.modular.auth;
-using fuchsia.ui.viewsv1token;
-using fuchsia.sys;
-
-// Given by the |Basemgr| to the |BaseShell| at Initialize() so the
-// |BaseShell| can get information about the users of this device from the
-// |Basemgr|, and act on the provided information (including extending the
-// user database).
-interface UserProvider {
- // Adds information of a user that can be used to authenticate her/him to this
- // device. Once successfully added, the user can login to the same device via
- // Login().
- //
- // |identity_provider| is the identity provider to use for identification.
- //
- // |device_name| is what the user wants to name the device. If null or empty
- // the device's current hostname will be used.
- //
- // |account| is NULL if there was an error during identification and
- // |error_code| is set.
- 1: AddUser(fuchsia.modular.auth.IdentityProvider identity_provider)
- -> (fuchsia.modular.auth.Account? account, string? error_code);
-
- // Removes information of a user from the local user database.
- //
- // |account_id| is received from either AddUser() or PreviousUsers().
- 2: RemoveUser(string account_id) -> (string? error_code);
-
- // Uses the credentials provided in AddUser() to start a user session. This
- // would mean syncing with the user's ledger instance and displaying a user
- // shell with all of the user's stories.
- // TODO(alhaad): In the future, we want to protect Login() with a password,
- // Android lock pattern, etc.
- 3: Login(UserLoginParams user_login_params);
-
- // List of all users who have authenticated to this device in the past.
- 4: PreviousUsers() -> (vector<fuchsia.modular.auth.Account> accounts);
-};
-
-// Used to specify arguments to log into a user session.
-struct UserLoginParams {
- // |account_id| is received from either AddUser() or PreviousUsers(). It
- // can be NULL which means logging-in in an incognito mode.
- string? account_id;
-
- // |view_owner| is the view given to the |SessionShell| started for the newly
- // logged-in user.
- request<fuchsia.ui.viewsv1token.ViewOwner> view_owner;
-
- // Services provided by the |BaseShell| that can be offered to the
- // |SessionShell| that is being logged into.
- fuchsia.sys.ServiceProvider? services;
-
- // If login fails, |user_controller| is closed.
- request<UserController> user_controller;
-};
-
-// Provided by the |Basemgr| to the |BaseShell| when it authenticates a
-// new user. This interface provides control to a logged-in user's life cycle,
-// and the life of this interface is bound to a user being logged in.
-//
-// An interface similar to this one, |UserContext|, is provided to the user
-// shell. It also contains a method to request logout. The difference is of
-// level of ownership and control:
-//
-// - A controller interface to one component instance is given to a component
-// instance which has control over the life cycle of the first component
-// instance. As such, the controller interface can be used by the controlling
-// component to change the life cycle of the controlled component.
-//
-// - A context interface to one component instance is given to a component
-// instance whose life cycle is controlled by the first component instance. As
-// such, the context interface can be used by the controlled component to
-// request a change to its life cycle (among other functions).
-//
-// In general, the separation of a service |Foo| implemented by a component, and
-// the service |FooController| given to the client of that component (rather
-// than |Foo| directly) is a hallmark of inversion of control that pervades the
-// design of our services.
-interface UserController {
- // Logs out a user by tearing down its sessionmgr. Returns once the
- // Sessionmgr has been torn down. This also triggers OnLogout() for
- // |UserWatcher|s.
- 1: Logout() -> ();
-
- // Registers a watcher for the user's life cycle events.
- 2: Watch(UserWatcher watcher);
-
- // Stops the currently running session shell and starts the one specified by
- // |session_shell_config|. This operation stops all stories before starting
- // the new shell.
- 3: SwapSessionShell(AppConfig session_shell_config) -> ();
-};
-
-// Implemented by a |BaseShell| implementation in order to receive
-// notification about life cycle changes of a logged in user.
-interface UserWatcher {
- // Called when a user has logged out, either by UserController.Logout() or by
- // UserContext.Logout(). By the time this event is processed by a watcher, the
- // Sessionmgr may already be torn down.
- //
- // TODO(vardhan): Make a guarantee that once OnLogout() is invoked, it is
- // possible to UserProvider.Login() the same user.
- 1: OnLogout();
-};
diff --git a/public/fidl/fuchsia.modular/clipboard/clipboard.fidl b/public/fidl/fuchsia.modular/clipboard/clipboard.fidl
deleted file mode 100644
index 903b57d..0000000
--- a/public/fidl/fuchsia.modular/clipboard/clipboard.fidl
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// An interface that provides clients with the ability to store and
-// retrieve text.
-[Discoverable]
-interface Clipboard {
- // Pushes |text| onto the clipboard.
- 1: Push(string text);
-
- // Peeks at the current topmost item on the clipboard and returns
- // it, or null if no such item exists.
- 2: Peek() -> (string? text);
-};
diff --git a/public/fidl/fuchsia.modular/component/component_context.fidl b/public/fidl/fuchsia.modular/component/component_context.fidl
deleted file mode 100644
index 853b120..0000000
--- a/public/fidl/fuchsia.modular/component/component_context.fidl
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.ledger;
-using fuchsia.sys;
-
-// Provided to all component instances in their respective initialization
-// information by the framework. For example, a Module gets it from its
-// ModuleContext and an Agent gets it from its AgentContext.
-[Discoverable]
-interface ComponentContext {
- // Gets the Ledger associated with this component. This ledger instance is
- // unique to this component (nb. not the component instance) under this user.
- 1: GetLedger(request<fuchsia.ledger.Ledger> request);
-
- // Used to start an agent in the user scope if it isn't already running, and
- // connect to it.
- 2: ConnectToAgent(string url,
- request<fuchsia.sys.ServiceProvider> incoming_services,
- request<AgentController> controller);
-
- // Used to create or delete a message queue or retrieve an existing queue
- // identified by |name|. |name| is local to the calling component instance.
- 3: ObtainMessageQueue(string name, request<MessageQueue> queue);
- 4: DeleteMessageQueue(string name);
-
- // Gets a MessageSender service that can be used to send a message to a queue
- // identified by |queue_token|. Token for a MessageQueue is obtained from its
- // GetToken() method. The token is unique within the scope of the user, i.e.
- // it can be used by other component instances than the one that created the
- // message queue.
- 5: GetMessageSender(string queue_token, request<MessageSender> sender);
-
- // Gets the EntityResolver service, which can be used to resolve an entity
- // reference to an Entity interface.
- 6: GetEntityResolver(request<EntityResolver> request);
-
- // Creates a new entity from |type_to_data| such that duplicate types are
- // overriden by subsequent entries.
- //
- // This is a useful way to represent small immutable entities without having
- // to provide the entity using an Agent. The types and data together must be
- // within 16KB in size.
- 7: CreateEntityWithData(vector<TypeToDataEntry> type_to_data)
- -> (string? entity_reference);
-
- // Gets the package name of this component.
- //
- // TODO(vardhan): MI4-939. This information should likely be exposed by a
- // lower level (component-level, or application level). This information is
- // most meant for a component to identify itself automatically when publishing
- // metrics.
- 8: GetPackageName() -> (string package_name);
-};
-
-// Used by ComponentContext.CreateEntityWithData().
-struct TypeToDataEntry {
- string type;
- string data;
-};
diff --git a/public/fidl/fuchsia.modular/component/message_queue.fidl b/public/fidl/fuchsia.modular/component/message_queue.fidl
deleted file mode 100644
index 27c2af0..0000000
--- a/public/fidl/fuchsia.modular/component/message_queue.fidl
+++ /dev/null
@@ -1,64 +0,0 @@
-// Use of this source code is governed by a BSD-style license that can be
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.mem;
-
-// A message queue is a named, locally persistent FIFO data structure. Message
-// queues are created, read from, and deleted by component instances through
-// their ComponentContext service.
-//
-// A message queue is created by a component instance from its component context
-// in order to receive messages in it.
-//
-// A sender token that identifies the queue can be obtained from the message
-// queue connection and passed to other components. This enables the other
-// component to send messages to the queue. A sender token does not allow a
-// component to read messages from a queue.
-//
-// The name of a queue is local to the component instance, i.e. it can only be
-// used by the component instance that created the queue to access it. The name
-// can specifically be used to obtain a MessageReader connection for the message
-// queue.
-//
-// The existence of message queues and their tokens is synchronized across
-// devices, allowing components with instances on multiple devices to route
-// messages within each device. For example, modules can use sender tokens on
-// different devices and see those messages delivered to the agent instance on
-// the same device. However, individual messages are local to a device.
-interface MessageQueue {
- // Gets a sender token associated with this queue. It can be used by other
- // components to send messages to this queue.
- 1: GetToken() -> (string queue_token);
-
- // Registers a receiver for this MessageQueue. MessageReader.OnReceive() is
- // called when there is an unread message. There can be at most one receiver
- // registered for a message queue at any time. Registering a new receiver
- // replaces the previous one.
- 2: RegisterReceiver(MessageReader receiver);
-};
-
-// Used to send a message to a message queue. The MessageSender connection is
-// obtained from ComponentContext.GetMessageSender() using a queue token of the
-// MessageQueue. The queue token is obtained by the component that created the
-// message queue and is then passed to the other component through services
-// specific to either component.
-interface MessageSender {
- 1: Send(fuchsia.mem.Buffer message);
-};
-
-// A component instance may implement and register a MessageReader interface
-// using MessageQueue.RegisterReceiver(). When there are new unread messages,
-// they are sent to MessageReader.OnReceive(). TODO(vardhan): There is a
-// conflict with C++ fidl bindings for 'MessageReceiver'. After that is fixed,
-// rename this interface to MessageReceiver.
-interface MessageReader {
- // Called when there is a new message to be received. Once an OnReceive()
- // responds back, the message is acknowledged as having been received and the
- // next one is sent when available. If a client's OnReceive() does not respond
- // before the MessageReader interface is closed, then a future MessageReader
- // for this message queue will receive the unacknowledged message again.
- 1: OnReceive(fuchsia.mem.Buffer message) -> ();
-};
diff --git a/public/fidl/fuchsia.modular/config/config.fidl b/public/fidl/fuchsia.modular/config/config.fidl
deleted file mode 100644
index f3f29fd..0000000
--- a/public/fidl/fuchsia.modular/config/config.fidl
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Used to pass around configuration references to apps such as user
-// shell, base shell, story shell.
-struct AppConfig {
- string url;
- vector<string>? args;
-};
diff --git a/public/fidl/fuchsia.modular/context/README.md b/public/fidl/fuchsia.modular/context/README.md
deleted file mode 100644
index a56f72b..0000000
--- a/public/fidl/fuchsia.modular/context/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-The files in this directory are undergoing a refactoring. Please reference MW-52
-for progress and more information.
\ No newline at end of file
diff --git a/public/fidl/fuchsia.modular/context/context_engine.fidl b/public/fidl/fuchsia.modular/context/context_engine.fidl
deleted file mode 100644
index 4839c2d..0000000
--- a/public/fidl/fuchsia.modular/context/context_engine.fidl
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Top-level service provider interface that vends services to read and write
-// context data.
-[Discoverable]
-interface ContextEngine {
- 1: GetReader(ComponentScope client_info, request<ContextReader> request);
-
- 2: GetWriter(ComponentScope client_info, request<ContextWriter> request);
-
- 3: GetContextDebug(request<ContextDebug> request);
-};
diff --git a/public/fidl/fuchsia.modular/context/context_reader.fidl b/public/fidl/fuchsia.modular/context/context_reader.fidl
deleted file mode 100644
index 8f4d48b..0000000
--- a/public/fidl/fuchsia.modular/context/context_reader.fidl
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Exposes access to Context values, each of which are explicitly named by a
-// 'topic'. Each topic has a known/pre-defined value representation.
-//
-// This interface is meant to be used in the scope of a single Fuchsia
-// component.
-[Discoverable]
-interface ContextReader {
- // When any conditions that would cause the resulting set of context values
- // selected by |query| to change, a ContextUpdate is sent to |listener|.
- //
- // The current state of values selected by |query| are sent to |listener|
- // immediately.
- //
- // The subscription will continue to stay active as long as the |listener|
- // handle is not closed.
- 1: Subscribe(ContextQuery query, ContextListener listener);
-
- // Returns the current context state matching |query|.
- 2: Get(ContextQuery query) -> (ContextUpdate update);
-};
-
-struct ContextQuery {
- // A map of ContextSelector structs. The keys are specified by the client.
- // Each key gets a corresponding entry in |ContextUpdate.values| when it is
- // generated in response to this query.
- vector<ContextQueryEntry> selector;
-};
-
-struct ContextQueryEntry {
- string key;
- ContextSelector value;
-};
-
-struct ContextSelector {
- // A partial metadata struct. Any metadata value given in |meta| restricts
- // the set of values in the eventual ContextUpdate to include only those
- // whose metadata match values given.
- //
- // A null |meta| will match any value of the given |type|. Use this sparingly
- // as a full update could become quite large.
- // TODO(thatguy): Find users of this and eliminate them if it becomes a
- // scaling problem.
- //
- // For example, to select all context values in a given story, one would
- // specify:
- // meta.value["story"]["id"] = "..."
- ContextMetadata? meta;
-
- // A string specifying the type of context object to return.
- ContextValueType type;
-};
-
-interface ContextListener {
- // Receives a full snapshot of context state every time context is updated
- // in such a way that results in a changed set of values for the ContextQuery
- // used in the subscription for this listener.
- //
- // TODO(thatguy): A broad ContextQuery will result in a large
- // |ContextUpdate|, which may exceed the FIDL max message size. In this case
- // updates would not be propagated. If this becomes an issue, allowing
- // clients to opt for delta-updates instead of state snapshots would suffice,
- // albeit also add some complexity to client implementations.
- 1: OnContextUpdate(ContextUpdate update);
-};
-
-struct ContextUpdate {
- // A list of ContextValue for each key in |ContextQuery.selector|. An empty
- // list means no values matched the given ContextSelector.
- vector<ContextUpdateEntry> values;
-};
-
-struct ContextUpdateEntry {
- string key;
- vector<ContextValue> value;
-};
diff --git a/public/fidl/fuchsia.modular/context/context_writer.fidl b/public/fidl/fuchsia.modular/context/context_writer.fidl
deleted file mode 100644
index 48406a5..0000000
--- a/public/fidl/fuchsia.modular/context/context_writer.fidl
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-[Discoverable]
-interface ContextWriter {
- // Creates and returns a ContextValueWriter for a future value of |type|,
- // allowing the client to set and update the contents at a later time. The
- // value is removed from the Context service when |value_writer| is closed or
- // a connection error occurs.
- 1: CreateValue(request<ContextValueWriter> value_writer, ContextValueType type);
-
- // This method is here to make transitioning from topic-based context
- // publishing to CreateValue() easier and will be removed eventually.
- // Internally, calls CreateValue() with type = ContextValueType.ENTITY,
- // and sets metadata.entity.topic = topic, unless WriteEntityTopic() was
- // called already on this instance with the same |topic| value. In that case,
- // performs an upate instead of adding a new value.
- //
- // Leaving |value| null removes the topic value from the Context service.
- //
- // TODO(thatguy): Remove this method and replace its behavior with
- // client-side library methods.
- 2: WriteEntityTopic(string topic, string? value);
-};
-
-interface ContextValueWriter {
- // Like ContextWriter.CreateValue(), but creates the new value as a child to
- // this value.
- //
- // TODO(thatguy): What is the lifetime relationship between these two values?
- // Ie, does removing the parent remove all its children?
- 1: CreateChildValue(request<ContextValueWriter> value_writer, ContextValueType type);
-
- // Updates the content and/or metadata of this value. If either |content| or
- // |metadata| are left null, the existing values will remain.
- 2: Set(string? content, ContextMetadata? metadata);
-};
diff --git a/public/fidl/fuchsia.modular/context/debug.fidl b/public/fidl/fuchsia.modular/context/debug.fidl
deleted file mode 100644
index c1bb3d0..0000000
--- a/public/fidl/fuchsia.modular/context/debug.fidl
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-[Discoverable]
-interface ContextDebug {
- // The watch will stay active until the |listener| handle is closed.
- 1: Watch(ContextDebugListener listener);
-
- // Waits until Context Engine has reached a steady state such that no further
- // activity will occur unless acted upon from the outside.
- 2: WaitUntilIdle() -> ();
-};
-
-interface ContextDebugListener {
- // Called any time a value is added, updated or removed. Each element in
- // |values| represents a single add, update or remove operation. Values are
- // guaranteed to appear before their children in the case that a parent and
- // its child are included in the same update.
- 1: OnValuesChanged(vector<ContextDebugValue> values);
-
- 2: OnSubscriptionsChanged(vector<ContextDebugSubscription> subscription);
-};
-
-// Represents a single update to a value. If |value| is omitted, the value with
-// |id| was deleted.
-struct ContextDebugValue {
- vector<string> parent_ids;
- string id;
- ContextValue? value;
-};
-
-struct ContextDebugSubscription {
- string id;
-
- // These are null when describing a subscription that was removed, although
- // it's safe to condition only on |query|.
- SubscriptionDebugInfo? debug_info;
- ContextQuery? query;
-};
-
-struct SubscriptionDebugInfo {
- ComponentScope client_info;
-};
diff --git a/public/fidl/fuchsia.modular/context/metadata.fidl b/public/fidl/fuchsia.modular/context/metadata.fidl
deleted file mode 100644
index 1f160b6..0000000
--- a/public/fidl/fuchsia.modular/context/metadata.fidl
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// This struct serves two purposes. It is:
-//
-// 1) Used to expose metadata along with each context node when interfacing
-// with clients either publishing, or retieving, context values.
-//
-// 2) Used while getting or querying for context values from a ContextReader to
-// restrict the set of values returned by partially specifying a
-// ContextMetadata struct.
-//
-// TODO(thatguy): Consider splitting these two purposes into their own structs
-// if the dual-responsibility becomes difficult to manage.
-struct ContextMetadata {
- StoryMetadata? story;
- ModuleMetadata? mod; // Annoyingly, "module" is a reserved word in FIDL.
- EntityMetadata? entity;
- LinkMetadata? link;
-
- // TODO(thatguy): Add Agent metadata.
-};
-
-struct StoryMetadata {
- string? id;
- FocusedState? focused;
- // TODO(thatguy): Add modular.StoryState
- // TODO(thatguy): Add visible state.
-};
-
-struct ModuleMetadata {
- string? url;
- vector<string>? path;
- FocusedState? focused;
-};
-
-struct EntityMetadata {
- string? topic;
- vector<string>? type;
-};
-
-struct LinkMetadata {
- // These fields are identical to those in modular.LinkPath. Can't use
- // modular.LinkPath directly because depending on lib/modular/fidl:link_path
- // causes issues with Dart bindings (they try to import the file from the
- // wrong package name), and depending on lib/modular/fidl causes a dependency
- // cycle (lib/context -> lib/module -> lib/user_intelligence -> lib/context).
- //
- // TODO(thatguy): Once we have FIDL2 (which will apparently fix the Dart
- // bindings problem), use LinkPath.
- vector<string>? module_path;
- string? name;
-};
-
-// bool type cannot be made optional (in StoryMetadata above), so we cannot
-// differentiate between an unspecified value and false. So we have to create a
-// struct with an enum in it to represent the boolean states, so that we can
-// allow it to be null.
-struct FocusedState {
- FocusedStateState state;
-};
-
-enum FocusedStateState {
- FOCUSED = 1;
- NOT_FOCUSED = 2;
-};
diff --git a/public/fidl/fuchsia.modular/context/value.fidl b/public/fidl/fuchsia.modular/context/value.fidl
deleted file mode 100644
index 5aa206e..0000000
--- a/public/fidl/fuchsia.modular/context/value.fidl
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-struct ContextValue {
- // The type of value this describes.
- ContextValueType type;
-
- // If |type| == ContextType.ENTITY, contains the JSON encoded representation
- // of the Entity's content.
- // TODO(thatguy): When Entities are handles we can pass around, make this
- // a FIDL handle to the entity.
- string? content;
-
- // All metadata for the node. When this ContextValue is included in a
- // ContextUpdate, |meta| will contain a merged view of metadata that is
- // inclusive of all of this value node's ancestors.
- ContextMetadata meta;
-};
diff --git a/public/fidl/fuchsia.modular/context/value_type.fidl b/public/fidl/fuchsia.modular/context/value_type.fidl
deleted file mode 100644
index c8463c7..0000000
--- a/public/fidl/fuchsia.modular/context/value_type.fidl
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-enum ContextValueType {
- STORY = 1;
- MODULE = 2;
- AGENT = 3;
- ENTITY = 4;
- LINK = 5;
-};
diff --git a/public/fidl/fuchsia.modular/entity/entity.fidl b/public/fidl/fuchsia.modular/entity/entity.fidl
deleted file mode 100644
index fdf1abf..0000000
--- a/public/fidl/fuchsia.modular/entity/entity.fidl
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.mem;
-
-/// A multi-typed data entity.
-interface Entity {
- /// Returns the types associated with this entity. Each entry in |types|
- /// references a well-known content type.
- 1: GetTypes() -> (vector<string> types);
-
- /// Given one of the types returned from |GetTypes()| above, returns
- /// associated short-form data, or null if the type is absent from
- /// |GetTypes()|.
- 2: GetData(string type) -> (fuchsia.mem.Buffer? data);
-
- /// Sets the data for a particular type. This will precipitate an |OnUpdated|
- /// event with the associated type.
- 3: WriteData(string type, fuchsia.mem.Buffer data)
- -> (EntityWriteStatus status);
-
- /// Gets the entity reference for this entity, which can be persisted and
- /// then later used to locate this entity. These references are weak
- /// references and are not sufficient to keep the entity alive.
- 4: GetReference() -> (string entity_reference);
-
- /// Begins watching for data changes on a particular type. The watcher
- /// immediately fires |OnUpdated| with the current value for the requested
- /// type (or null if the type is not present). Closing the |Entity| interface
- /// does not close the watcher.
- 5: Watch(string type, EntityWatcher watcher);
-};
-
-interface EntityWatcher {
- /// Fires on data updates for a particular type. If the type is initially not
- /// present, a null |data| pointer is produced. The type may only transition
- /// from absent to present at most once, as there is no deletion.
- ///
- /// No deduplication is performed.
- 1: OnUpdated(fuchsia.mem.Buffer? data);
-};
-
-enum EntityWriteStatus {
- OK = 0;
- /// Indicates a failure of the entity provider to write the update.
- ERROR = 1;
- /// Entity providers are not necessarily required to support entity mutation.
- READ_ONLY = 2;
-};
diff --git a/public/fidl/fuchsia.modular/entity/entity_provider.fidl b/public/fidl/fuchsia.modular/entity/entity_provider.fidl
deleted file mode 100644
index 28ac9c1..0000000
--- a/public/fidl/fuchsia.modular/entity/entity_provider.fidl
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.mem;
-
-/// EntityProviders (agents) must implement and provide the |EntityProvider|
-/// service if they create entity references (using |EntityReferenceFactory|).
-/// This service is used by the framework to provide data for an |Entity|
-/// interface for an entity. This interface is requested by the framework in
-/// the agent's *application* outgoing services, and is closed by the framework
-/// when there are no more |Entity|s that need to be provided.
-///
-/// In the below methods, |cookie| will have been previously passed to
-/// |EntityReferenceFactory.CreateReference()|, though this may have been in an
-/// earlier or remote app instance. Entity providers should attempt to resolve
-/// unfamiliar cookies or else treat the entities as empty and read-only.
-[Discoverable]
-interface EntityProvider {
- /// Returns the types associated with the requested entity. Each entry in
- /// |type| references a well-known content type.
- ///
- /// If the cookie cannot be resolved, the provider should produce an empty
- /// vector.
- 1: GetTypes(string cookie) -> (vector<string> types);
-
- /// Given one of the types returned from |GetTypes()| above, returns
- /// associated short-form data, or null if the type is absent from
- /// |GetTypes()|.
- ///
- /// If the cookie cannot be resolved, the provider should return null.
- 2: GetData(string cookie, string type) -> (fuchsia.mem.Buffer? data);
-
- /// Sets the data for a particular type. This must precipitate an |OnUpdate|
- /// event with the associated type.
- ///
- /// If the cookie cannot be resolved, the provider should no-op with
- /// |EntityWriteStatus::READ_ONLY|.
- 3: WriteData(string cookie, string type, fuchsia.mem.Buffer data)
- -> (EntityWriteStatus status);
-
- /// Begins watching for data changes on a particular type. The watcher must
- /// immediately fire |OnUpdated| with the current value for the requested
- /// type (or null if the type is not present).
- ///
- /// No deduplication of events should be performed.
- ///
- /// At most one update may be in-flight at a time on a particular watcher;
- /// once a client is ready for another update, it will call the callback. At
- /// most one update should be queued for dispatch for a particular watcher;
- /// older updates should be dropped.
- ///
- /// If the cookie cannot be resolved, the provider should emit a single event
- /// with null data.
- 5: Watch(string cookie, string type, EntityWatcher watcher);
-};
diff --git a/public/fidl/fuchsia.modular/entity/entity_reference_factory.fidl b/public/fidl/fuchsia.modular/entity/entity_reference_factory.fidl
deleted file mode 100644
index 2396eae..0000000
--- a/public/fidl/fuchsia.modular/entity/entity_reference_factory.fidl
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Agents use this interface to create Entity references that can subsequently
-// be dereferenced into an |Entity| interface using |EntityResolver|.
-// Agents that create entity references must also expose an |EntityProvider|
-// service in their application's outgoing services, so that agents can provide
-// data for |Entity|s that they create. This interface is available through an
-// agent's |AgentContext|.
-interface EntityReferenceFactory {
- // Agents call this to manufacture a reference for an Entity they will
- // provide. Returns an opaque, persistable |entity_reference| that components
- // can resolve into an |Entity| interface using |EntityResolver|. When data is
- // requested from an |Entity| interface resolved from this |entity_reference|,
- // the |cookie| associated with this |entity_reference| will be passed back to
- // the |EntityProvider| of the Agent that originally created this reference.
- //
- // |cookie| should uniquely identify the |Entity| within the scope of the
- // calling entity provider. For example, it may be used as the primary key
- // value for a database.
- 1: CreateReference(string cookie) -> (string entity_reference);
-};
diff --git a/public/fidl/fuchsia.modular/entity/entity_resolver.fidl b/public/fidl/fuchsia.modular/entity/entity_resolver.fidl
deleted file mode 100644
index 50614cb..0000000
--- a/public/fidl/fuchsia.modular/entity/entity_resolver.fidl
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// This interface is given to all components in their |ComponentContext|. Any
-// component can resolve an entity reference into an |Entity|.
-interface EntityResolver {
- // Finds and binds |entity_request| to an Entity handle for the Entity
- // referenced by |entity_reference|. If an error occurs, |entity_request|
- // will be closed.
- //
- // This method is called by any component who wants to use an Entity using an
- // entity reference. A component has to get an entity reference (directly or
- // indirectly) from an agent, for example through some fidl interface. The
- // agent will create an entity reference using EntityReferenceFactory. During
- // entity resolution, that agent then provides data for the Entity
- // through an EntityProvider service it exposes. Thus, any Agent that wishes
- // to use EntityReferenceFactory to dispense entity references through its
- // agent services MUST also implement the EntityProvider service.
- 1: ResolveEntity(string entity_reference, request<Entity> entity_request);
-};
diff --git a/public/fidl/fuchsia.modular/intent/intent.fidl b/public/fidl/fuchsia.modular/intent/intent.fidl
deleted file mode 100644
index 09fb8ef..0000000
--- a/public/fidl/fuchsia.modular/intent/intent.fidl
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.mem;
-
-// The Intent struct is a runtime descriptor for an abstract action to be initiated
-// in Fuchsia. For details please see docs/intent.md.
-struct Intent {
- // The name of the action represented by this Intent.
- //
- // This is nullable for backwards compatibility.
- // TODO(MI4-1100): Make action non-nullable.
- string? action;
-
- // An explicit handler for the Intent. Specified as the component URL of the
- // module.
- string? handler;
-
- // The parameters that will be passed to the handler of |action|.
- vector<IntentParameter>? parameters;
-};
-
-// A struct representing a parameter that is passed to the handler of an Intent's
-// Action.
-struct IntentParameter {
- // The name of the parameter. The handler (i.e. selected mod) will be provided
- // with the data for this parameter under a link called |name|.
- string? name;
-
- // The data that will be passed to the intent handler.
- IntentParameterData data;
-};
-
-union IntentParameterData {
- // Set this if you already have an Entity reference at runtime.
- // Entity.getTypes() will be used to set the constraints for this noun during
- // resolution.
- string entity_reference;
-
- // Set this if you have structured JSON data. Values typically are a JSON
- // object with a "@type" attribute and other associated data. TODO(thatguy):
- // We need to decide if we want to keep this in place, or deprecate this
- // eventually and move entirely to using Entity references.
- //
- // DEPRECATED: Use |entity_reference|.
- fuchsia.mem.Buffer json;
-
- // Set this if you want to explicitly define this noun's allowed types. This
- // is also useful in the cases where the noun has a 'direction' of type
- // 'output', and you wish to set the allowable output types from the Module
- // (see docs/modular/manifests/action_template.md for a definition of
- // 'direction').
- //
- // Only one entry in |entity_type| must match the constraint specified by
- // the Module for the constraint to be considered satisfied.
- vector<string> entity_type;
-};
diff --git a/public/fidl/fuchsia.modular/intent/intent_handler.fidl b/public/fidl/fuchsia.modular/intent/intent_handler.fidl
deleted file mode 100644
index ee8c8a6..0000000
--- a/public/fidl/fuchsia.modular/intent/intent_handler.fidl
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// The IntentHandler interface is exposed by modules which wish to handle
-// intents on the behalf of other modules or agents.
-//
-// The modular framework expects any module which declares support for intent
-// handling in its module manifest to expose IntentHandler in its outgoing
-// services.
-//
-// Any time the framework receives an intent which is to be handled by a specific
-// module its |IntentHandler| will be called with the intent it is meant to handle.
-[Discoverable]
-interface IntentHandler {
- // Handles the provided intent. Any links referenced in the intent parameters
- // will be in the namespace of the handling component, and can be retrieved via
- // |ModuleContext.GetLink|.
- 1: HandleIntent(Intent intent);
-};
diff --git a/public/fidl/fuchsia.modular/lifecycle/lifecycle.fidl b/public/fidl/fuchsia.modular/lifecycle/lifecycle.fidl
deleted file mode 100644
index 483420a..0000000
--- a/public/fidl/fuchsia.modular/lifecycle/lifecycle.fidl
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// An interface implemented by applications that wish to terminate gracefully.
-[Discoverable]
-interface Lifecycle {
- // The client of this application has requested that this application
- // terminate gracefully.
- //
- // If the application does not terminate itself in a timely manner, the client
- // may forcibly terminate the application.
- 1: Terminate();
-};
diff --git a/public/fidl/fuchsia.modular/module/link_path.fidl b/public/fidl/fuchsia.modular/module/link_path.fidl
deleted file mode 100644
index e5c575c..0000000
--- a/public/fidl/fuchsia.modular/module/link_path.fidl
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-/// Addresses a Link within a story. A LinkPath struct should be treated as an
-/// opaque unique identifier of a link instance. The |module_path| and
-/// |link_name| components are leftovers from legacy code and have no external
-/// meaning.
-/// TODO(thatguy,lindkvist): Replace this structure with a vector<>. MI4-1021
-struct LinkPath {
- vector<string> module_path;
- string? link_name;
-};
diff --git a/public/fidl/fuchsia.modular/module/module_context.fidl b/public/fidl/fuchsia.modular/module/module_context.fidl
deleted file mode 100644
index 286f3c9..0000000
--- a/public/fidl/fuchsia.modular/module/module_context.fidl
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.ui.viewsv1token;
-using fuchsia.mem;
-
-/// This interface is exposed to all Module instances in a story. It allows to
-/// create Link instances and run more Module instances.
-[Discoverable]
-interface ModuleContext {
- /// Gets a Link instance with the given name.
- ///
- /// The Link instance has a name so that it can be recognized when the story
- /// is resumed. The name is unique in the scope of the Module instance. If
- /// the method is called again with the same argument by the same Module
- /// instance, a new connection to the same Link instance is obtained. It's
- /// up to the Module instance to ensure the name is unique within the scope
- /// of itself.
- ///
- /// TODO(thatguy): When no modules use null link names any more, make name
- /// required.
- 1: GetLink(string? name, request<Link> link);
-
- /// Starts a new Module instance and adds it to the story. The Module to
- /// execute is identified by the contents of [intent] and the Module instance
- /// is given a [name] in the scope of the starting Module instance. The view
- /// for the Module is given to the story shell for display.
- ///
- /// Providing a [surface_relation] advises the StoryShell how to layout
- /// surfaces that the new module creates. If [surface_relation] is null then
- /// a default relation is used.
- ///
- /// If the method is called again with the same [name] by the same Module
- /// instance, but with different arguments, the existing Module instance is
- /// restarted with the changed arguments. If the other arguments don't
- /// change, just an additional ModuleController connection is made.
- 15: AddModuleToStory(string name, Intent intent,
- request<ModuleController> module_controller,
- SurfaceRelation? surface_relation)
- -> (StartModuleStatus status);
-
- /// Like AddModuleToStory(), but requests a [view_owner] explicitly to embed
- /// the view of the requested Module instance in the view of the requesting
- /// Module instance, instead of relying on the story shell for display. If a
- /// Module instance with the same [name] and [intent] is already running,
- /// [view_owner] is closed.
- 3: EmbedModule(string name, Intent intent,
- request<ModuleController> module_controller,
- request<fuchsia.ui.viewsv1token.ViewOwner> view_owner)
- -> (StartModuleStatus status);
-
- /// DEPRECATED: no longer implemented.
- 6: StartContainerInShell(string container_name,
- SurfaceRelation parent_relation,
- vector<ContainerLayout> layout,
- vector<ContainerRelationEntry> relationships,
- vector<ContainerNode> nodes);
-
- /// DEPRECATED: ComponentContext is now available in the
- /// namespace/environment for Modules.
- 7: GetComponentContext(request<ComponentContext> request);
-
- /// Gets the id for this story which may be used to create a suggestion
- /// proposal to resume this story, especially by agents.
- 9: GetStoryId() -> (string story_id);
-
- /// Requests that the current story and module gain focus. It's up to the story
- /// shell and session shell to honor that request.
- 10: RequestFocus();
-
- /// DEPRECATED in favor of using StartOngoingActivity().
- 11: Active();
-
- /// When a module calls [RemoveSelfFromStory()] the framework will stop the
- /// module and remove it from the story. If there are no more running modules
- /// in the story the story will be deleted.
- 16: RemoveSelfFromStory();
-
- /// Requests to update the visibility state of the current story within the
- /// session shell. The framework will decide whether to honor this request, then
- /// forward it to the session shell.
- ///
- /// Modules should not have any knowledge of the story's visibility state, nor
- /// should it ever operate with any assumption of the visibility state.
- ///
- /// Note that the framework keeps this state only in memory, which means that
- /// across reboots, the story visibility state will revert back to DEFAULT.
- /// This makes it unsafe for any component outside the framework to make
- /// assumptions about the story visibility state. Also, this differs from other
- /// UI states such as focus state, which is persisted across reboots.
- 13: RequestStoryVisibilityState(StoryVisibilityState visibility_state);
-
- /// Declares that activity of the given [type] is ongoing in this module.
- /// This information is forwarded to the session shell
- /// (cf. StoryProvider.WatchActivity() and StoryActivityWatcher).
- ///
- /// Modules should close [request] when the ongoing activity has stopped, and
- /// this will also signal to the session shell that the ongoing activity has
- /// stopped. For now, pausing media should count as a stopped ongoing activity,
- /// and when it is resumed it should be started as a new ongoing activity.
- /// Conversely, media playing in a continuous playlist (i.e playing the next
- /// video or song) should be treated as the same ongoing activity.
- /// Modules must request a connection per ongoing activity; a single connection
- /// may not be re-used for multiple ongoing activities.
- 14: StartOngoingActivity(OngoingActivityType type,
- request<OngoingActivity> request);
-
- /// Creates a [fuchsia.modular.Entity] with the given [type] and [data]. The
- /// lifetime of the created entity is tied to the lifetime of the current story,
- /// but can be dereferenced by modules and agents outside the scope of the story.
- ///
- /// [entity_request] will be connected to the created entity, or closed if the
- /// creation fails.
- ///
- /// The returned [reference] is the entity reference for the created entity, or
- /// null if the entity creation failed.
- 17: CreateEntity(string type, fuchsia.mem.Buffer data, request<Entity> entity_request)
- -> (string? entity_reference);
-};
-
-/// Communicates the status of an Intent to a Module.
-enum StartModuleStatus {
- SUCCESS = 0;
- NO_MODULES_FOUND = 1;
-};
-
-/// This interface defines the protocol over which a Module can communicate about
-/// an ongoing activity to the framework. It is provided to Modules via
-/// ModuleContext.StartOngoingActivity().
-interface OngoingActivity {
-};
-
-enum OngoingActivityType {
- UNSPECIFIED = 0;
- VIDEO = 1;
- AUDIO = 2;
-};
diff --git a/public/fidl/fuchsia.modular/module/module_controller.fidl b/public/fidl/fuchsia.modular/module/module_controller.fidl
deleted file mode 100644
index ade34ec..0000000
--- a/public/fidl/fuchsia.modular/module/module_controller.fidl
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-/// This interface is used by the caller of ModuleContext.StartModule() to
-/// control the started Module instance.
-///
-/// Closing this connection doesn't affect its Module instance; it just
-/// relinquishes the ability of the caller to control the Module instance.
-interface ModuleController {
- /// Requests that this module become the focused module in the story.
- 2: Focus();
-
- /// Requests that this module be hidden in the story.
- 3: Defocus();
-
- /// Requests the Module instance to stop. The running Module component's
- /// Lifecycle::Terminate() method is called, the instance is shut down and
- /// state within the framework is cleaned up.
-
- /// The result callback is called once the Module's runtime has been torn down.
- 4: Stop() -> ();
-
- /// Called with the current state when it changes.
- /// DEPRECATED: Do not use this. ModuleState is a framework-internal concept
- /// and should not be exposed outside.
- 5: -> OnStateChange(ModuleState new_state);
-};
diff --git a/public/fidl/fuchsia.modular/module/module_data.fidl b/public/fidl/fuchsia.modular/module/module_data.fidl
deleted file mode 100644
index b55eafe..0000000
--- a/public/fidl/fuchsia.modular/module/module_data.fidl
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-/// Information about a Module instance in a story.
-struct ModuleData {
- /// The URL of the Module binary.
- string module_url;
-
- /// The named path leading up to this Module instance. The last name in this
- /// array is the name by which the Module was started by the parent Module
- /// instance calling StartModule().
- vector<string> module_path;
-
- /// Contains the mapping of Mod parameter name to Link instances for this mod.
- ModuleParameterMap parameter_map;
-
- /// The way in which this Module instance was first started in the story,
- /// either by request from another Module instance (INTERNAL) or by request
- /// from outside the story (i.e. by suggestion from an agent - EXTERNAL).
- ModuleSource module_source;
-
- /// The |surface_relation| that was used to start this Module instance with.
- /// The same is used when re-inflating the Module instance when the story is
- /// resumed. A SurfaceRelation value of null represents an embedded Module
- /// instance (started by EmbedModule()) that is not managed by the story shell.
- SurfaceRelation? surface_relation;
-
- /// True if this module was removed from its story either through
- /// ModuleController.Stop() or ModuleContext.RemoveSelfFromStory().
- bool module_deleted;
-
- /// The intent that was issued to start add this Module instance to the story.
- /// Some Module instances may have been added not by an Intent, for example as
- /// the initial module of a story. For those the field may be null.
- ///
- /// TODO(thatguy,mesch): This field should now always be set, so make it
- /// required once the framework is cleaned up enough to guarantee this
- /// statement.
- Intent? intent;
-
- /// If true, this module was started by a parent module using
- /// ModuleContext.EmbedModule(), and its view is not managed by the
- /// StoryShell.
- bool is_embedded = false;
-};
-
-enum ModuleSource {
- /// Module that was added to the story from within the story by another
- /// module using ModuleContext.AddModuleToStory() or
- /// ModuleContext.EmbedModule().
- INTERNAL = 0;
-
- /// Module that was added to the story from outside the story using
- /// PuppetMaster.
- EXTERNAL = 1;
-};
-
-struct ModuleParameterMap {
- vector<ModuleParameterMapEntry> entries;
-};
-
-struct ModuleParameterMapEntry {
- /// A null [name] is allowed for backwards compatibility with default links.
- /// TODO(thatguy); When no modules use null link names any more, make this
- /// required.
- string? name;
- LinkPath link_path;
-};
diff --git a/public/fidl/fuchsia.modular/module/module_manifest.fidl b/public/fidl/fuchsia.modular/module/module_manifest.fidl
deleted file mode 100644
index c74f241..0000000
--- a/public/fidl/fuchsia.modular/module/module_manifest.fidl
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-/// Metadata that define the runtime properties of a Module.
-struct ModuleManifest {
- /// The relative path from the root of the package where the Module executable
- /// file can be found.
- /// TODO(MF-94): Extract a module's URL from its cmx manifest instead of
- /// here.
- string binary;
-
- /// A human-readable string that can be used when suggesting this Module.
- string? suggestion_headline;
-
- /// A list of intents that this module is able to handle.
- vector<IntentFilter>? intent_filters;
-
- /// Identifies the pattern with which to compose this module with others.
- string? composition_pattern;
-
- /// Defines the color of the placeholder widget used while the module loads.
- string? placeholder_color;
-};
-
-/// This struct is used to describe an intent that a module is able to handle.
-struct IntentFilter {
- /// The action this module is able to handle.
- string action;
-
- /// Includes the name and types of entities for the parameters required to
- /// execute specified [action].
- vector<ParameterConstraint> parameter_constraints;
-};
-
-struct ParameterConstraint {
- string name;
- /// The entity type that is valid for this parameter.
- string type;
-};
diff --git a/public/fidl/fuchsia.modular/module/module_state.fidl b/public/fidl/fuchsia.modular/module/module_state.fidl
deleted file mode 100644
index f2934c9..0000000
--- a/public/fidl/fuchsia.modular/module/module_state.fidl
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-/// State used to notify about state transitions of a Module
-/// instance. This is very similar to the StoryState, however it's not entirely
-/// the same and hence a separate type. A module cannot have an INITIAL state,
-/// because it's started as soon as it is created, and it gets deleted as soon as
-/// it reaches the STOPPED state, whileas a story can be restarted.
-///
-/// Currently possible state transitions (and the events that cause
-/// them) are:
-///
-/// -> RUNNING ModuleContext.AddModuleToStory() or
-/// ModuleContext.EmbedModule() or
-/// StoryController.AddModule()
-/// RUNNING -> STOPPED ModuleController.Stop() or StoryController.Stop()
-/// RUNNING -> ERROR application exits
-enum ModuleState {
- /// Module instance was created.
- RUNNING = 2;
- /// Module instance is stopped after Module.Stop(). No further transitions are
- /// to be expected.
- STOPPED = 4;
- /// Connection to the Module instance was closed without Stop() request. No
- /// further transitions are to be expected.
- ERROR = 5;
-};
diff --git a/public/fidl/fuchsia.modular/module_resolver/module_resolver.fidl b/public/fidl/fuchsia.modular/module_resolver/module_resolver.fidl
deleted file mode 100644
index dfe056b..0000000
--- a/public/fidl/fuchsia.modular/module_resolver/module_resolver.fidl
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-[Discoverable]
-interface ModuleResolver {
- // Finds Modules (contained in Fuchsia packages) that satisfy the constraints
- // specified in |query|. Module resolution is done by matching the requested
- // |query.action| and |query.parameter_constraints| (with both names and
- // types) against actions and constraints specified in module manifests.
- //
- // If no results could be found, |response.results| will be empty.
- //
- // For detailed information on the resolution process, see
- // docs/modular/module_resolution.md.
- //
- // TODO(thatguy): Offer some kind of fallback instruction/option to clients
- // in the case of no results.
- 1: FindModules(FindModulesQuery query) -> (FindModulesResponse response);
-
- // Find modules that satisfy the constraints specified in |query|. Module
- // resolution for this method is done by matching only the requested types
- // specified in |query.parameter_constriants|. This type of query is useful
- // for finding possible actions that satisfy a set of parameter types.
- //
- // Each module result in the response will provide a mapping from the
- // constraint names in |query| to the parameter names of a module result. If
- // no results could be found, |response.results| will be empty.
- 2: FindModulesByTypes(FindModulesByTypesQuery query)
- -> (FindModulesByTypesResponse response);
-
- // If |module_id| could not be found or does not have a manifest, returns a
- // null |contents|.
- 3: GetModuleManifest(string module_id) -> (ModuleManifest? contents);
-};
-
-// Mirrors the information present in a Intent. Where a Intent is meant to
-// interface between Modules and the Framework, this structure is specific to
-// the interface between the Framework and the ModuleResolver.
-//
-// In that role, it has references to structures and concepts that are only
-// visible within the abstraction layer of the Framework.
-// TODO(thatguy): Add scoring info here.
-struct FindModulesQuery {
- // The handler is a module URL; if the handler is specified, the search for
- // (action, parameter_constraints) is scoped within the specified handler.
- string? handler;
- string action;
- vector<FindModulesParameterConstraint> parameter_constraints;
-};
-
-struct FindModulesParameterConstraint {
- string param_name;
- vector<string> param_types;
-};
-
-enum FindModulesStatus {
- // A search was successfully conducted.
- SUCCESS = 0;
- // |FindModulesQuery.handler| was specified but the resolver doesn't know
- // about it.
- UNKNOWN_HANDLER = 1;
-};
-
-struct FindModulesResponse {
- FindModulesStatus status;
- vector<FindModulesResult> results;
-};
-
-struct FindModulesResult {
- // The ID of the Module. For now, this is the URL of the Module binary.
- string module_id;
-
- // The Module's manifest file (see docs/manifests/module.md).
- ModuleManifest? manifest;
- // TODO(thatguy): Add debug info.
-};
-
-struct FindModulesByTypesQuery {
- // Even though only |param_types| are used to search for possible modules,
- // each module result comes with a mapping from constraint_name =>
- // param_name.
- vector<FindModulesByTypesParameterConstraint> parameter_constraints;
-};
-
-struct FindModulesByTypesParameterConstraint {
- // This |constraint_name| is associated with a module result's |param_name|;
- string constraint_name;
- vector<string> param_types;
-};
-
-struct FindModulesByTypesResponse {
- // One result per (module_id, action, param mapping) tuple.
- // TODO(vardhan): For efficiency, consider grouping the results differently so
- // there aren't repeated transmissions of a manifest.
- vector<FindModulesByTypesResult> results;
-};
-
-struct FindModulesByTypesResult {
- float64 score;
-
- // The ID of the Module. For now, this is the URL of the Module package.
- string module_id;
- string action;
-
- // The Module's manifest file (see docs/manifests/module.md)
- ModuleManifest? manifest;
-
- // A list of mappings from query_constraint_name => result_param_name
- vector<FindModulesByTypesParameterMapping> parameter_mappings;
-};
-
-// Defines a single mapping entry from a specified constraint name to a module
-// result's parameter name.
-struct FindModulesByTypesParameterMapping {
- // This is the constraint name as specified in
- // |FindModulesByTypesParameterConstraint.constraint_name|.
- string query_constraint_name;
- // This is the associated parameter name from a module result.
- string result_param_name;
-};
diff --git a/public/fidl/fuchsia.modular/session/device_map.fidl b/public/fidl/fuchsia.modular/session/device_map.fidl
deleted file mode 100644
index a324d15..0000000
--- a/public/fidl/fuchsia.modular/session/device_map.fidl
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Gives access to the device map of the logged in user.
-[Discoverable] // Exposed in user environment.
-interface DeviceMap {
- // HACK(mesch): Just exposes all Device/* entries in the ledger.
- // We'll need something better, possibly with access policy.
- 1: Query() -> (vector<DeviceMapEntry> devices);
-
- // Returns the current device from the device map.
- 2: GetCurrentDevice() -> (DeviceMapEntry device);
-
- // Sets the profile string for the current device.
- // HACK(jimbe) This is a quick-and-dirty solution for FW-316. It needs to be
- // completely redesigned once the Framework has a concept of profile (such
- // as landscape/portrait.)
- 3: SetCurrentDeviceProfile(string profile);
-
- // Requests a notification for each change to the DeviceMap. The given
- // watcher will receive an initial notification for each existing device.
- 4: WatchDeviceMap(DeviceMapWatcher watcher);
-};
-
-struct DeviceMapEntry {
- // The device's name. This name is user editable and may be the same between
- // any of the user's devices.
- string name;
-
- // Semi-sticky device ID usable for syncing. Guarantees a unique device id
- // that no another hardware will be using while this device is syncing.
- // WARNING: This ID is persisted for an arbitrary amount of time and MAY be
- // revoked or changed between launches of this service on this hardware.
- string? device_id;
-
- // The device's intended usage profile (stored as JSON)
- string? profile;
-
- // The last known hostname of this device.
- // HACK(zbowling): this is temporary to assist with matching devices in
- // netconnector RPC discovery.
- string hostname;
-
- // The time that this DeviceMapEntry was last changed. Will never be zero.
- // Measured in Unix time, seconds since the epoch. This is not a heartbeat.
- // Intended to allow detection of stale device entries.
- uint64 last_change_timestamp;
-};
-
-// Implemented by the client calling DeviceMap.Watch().
-interface DeviceMapWatcher {
- // Called with the current state right after registration, and subsequently
- // when the state changes.
- 1: OnDeviceMapChange(DeviceMapEntry entry);
-};
diff --git a/public/fidl/fuchsia.modular/session/focus.fidl b/public/fidl/fuchsia.modular/session/focus.fidl
deleted file mode 100644
index 5edd1b9..0000000
--- a/public/fidl/fuchsia.modular/session/focus.fidl
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// This file has interfaces for 2 pieces of information: (1) The story
-// that is currently in focus and (2) stories that are visible to the
-// user. Names of interfaces follow the usual patterns:
-//
-// {Focus,VisibleStories}Controller is used by session shell to update
-// information whenever changes take place.
-//
-// {Focus,VisibleStories}Provider is used by maxwell and session shell to
-// query and get updates on which story is in focus on which device
-// and visible stories on this device.
-//
-// NOTE(alhaad): The information about visible stories can be used by
-// sessionmgr to stop / pause stories that are not visible to the
-// user.
-
-// Implemented by sessionmgr. Given to session shell through its namespace.
-interface FocusController {
- // Sets the focus on this device.
- 1: Set(string? focused_story_id);
- 2: WatchRequest(FocusRequestWatcher watcher);
-};
-
-// Implemented by session shell. OnFocusRequest() gets called whenever there
-// is a new request to change focus on this device. Requests can be
-// made via FocusProvider.Request().
-interface FocusRequestWatcher {
- 1: OnFocusRequest(string story_id);
-};
-
-// Implemented by sessionmgr. Given to session shell and session agents through
-// their namespace. Focus is persisted on the ledger.
-[Discoverable]
-interface FocusProvider {
- // Returns the stories that are focused across all devices.
- 1: Query() -> (vector<FocusInfo> focused_stories);
-
- // Watches for change in focus on any of the user's devices.
- 2: Watch(FocusWatcher watcher);
-
- // Requests session shell to change focus on this device. If session shell
- // responds to this request, focus shall be taken away from
- // previously focused story and an update will be sent on
- // FocusWatcher.OnFocusChange(). If |story_id| is NULL, the timeline
- // is brought back into focus.
- //
- // TODO(alhaad): Consider making this available for remote devices as
- // well.
- 3: Request(string? story_id);
-};
-
-// Implemented by anyone who is interested in getting updates when focus
-// changes.
-interface FocusWatcher {
- 1: OnFocusChange(FocusInfo? focus_info);
-};
-
-// Specifies the focused story of a device.
-struct FocusInfo {
- // The id of the device.
- string device_id;
-
- // The id of the focused story. If null, no stories are focused.
- string? focused_story_id;
-
- // The time the focused story on the device |device_id| was last
- // changed. 0 if no focus has ever been set for device |device_id|.
- uint64 last_focus_change_timestamp;
-};
-
-// Implemented by sessionmgr. Given to session shell through its namespace.
-interface VisibleStoriesController {
- 1: Set(vector<string>? visible_story_ids);
-};
-
-// Implemented by sessionmgr. Given to story info through its namespace.
-// Visible stories are NOT stored on the ledger.
-[Discoverable] // Maxwell apps request this from environment.
-interface VisibleStoriesProvider {
- // Returns the |story_ids| that are currently visible.
- 1: Query() -> (vector<string> story_id);
-
- // Watches for change in visible stories on this device.
- 2: Watch(VisibleStoriesWatcher watcher);
-};
-
-// Implemented by anyone (maxwell) who is interested in getting updates when
-// stories that are currently visible change.
-interface VisibleStoriesWatcher {
- 1: OnVisibleStoriesChange(vector<string>? visible_story_ids);
-};
diff --git a/public/fidl/fuchsia.modular/session/session_shell.fidl b/public/fidl/fuchsia.modular/session/session_shell.fidl
deleted file mode 100644
index b1a421e..0000000
--- a/public/fidl/fuchsia.modular/session/session_shell.fidl
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.modular.auth;
-using fuchsia.speech;
-using fuchsia.ui.policy;
-using fuchsia.ui.viewsv1token;
-
-
-// This interface is implemented by a session shell and is used by the
-// sessionmgr to hand to the session shell views of stories, or to notify that
-// the view of a story is about to be closed.
-[Discoverable]
-interface SessionShell {
- // Displays the given story view. The story this view belongs to is
- // identified by |view_id.story_id|.
- AttachView(ViewIdentifier view_id, fuchsia.ui.viewsv1token.ViewOwner view_owner);
-
- // Instructs the session shell to detach the view identified by |view_id|
- // that was previously provided by AttachView() from the UI of the session
- // shell. The view will be closed soon after DetachView() returns, or when a
- // timeout is reached.
- //
- // It is customary for the session shell to display a placeholder before a
- // view is attached for a given view identifier, or after it was detached.
- //
- // If the story identified by |view_id.story_id| is about to be deleted, the
- // Shell will observe a call to StoryProviderWatcher.OnDelete() sometime
- // after DetachView() returns.
- //
- // If the session for which this session shell is responsible for is being
- // terminated, or the session shell is stopped because it's replaced by
- // another session shell, DetachView() will *not* be called at all, and the
- // shell will rather observe a call to Lifecycle.Terminate().
- DetachView(ViewIdentifier view_id) -> ();
-};
-
-// Identifies a view provided to a session shell. The values of the |story_id|
-// field match those used in the |StoryProvider| interface, allowing
-// identification of the same story across interfaces.
-//
-// This is a struct rather than a naked string to allow for future evolution of
-// the identifier without changing the |SessionShell| API itself.
-struct ViewIdentifier {
- string story_id;
-};
-
-// This interface allows a |SessionShell| to request capabilities from its
-// creator in a way that is more explicit about the services that are
-// offered than a generic |ServiceProvider|.
-[Discoverable]
-interface SessionShellContext {
- // The account associated with the currently logged-in user. It's NULL if
- // logged into GUEST mode.
- 1: GetAccount() -> (fuchsia.modular.auth.Account? account);
- 2: GetAgentProvider(request<AgentProvider> request);
- 3: GetComponentContext(request<ComponentContext> request);
- 4: GetDeviceName() -> (string device_name);
- 5: GetFocusController(request<FocusController> request);
- 6: GetFocusProvider(request<FocusProvider> request);
- 8: GetLink(request<Link> request);
- 9: GetPresentation(request<fuchsia.ui.policy.Presentation> request);
- 10: GetSpeechToText(request<fuchsia.speech.SpeechToText> request);
- 11: GetStoryProvider(request<StoryProvider> request);
- 12: GetSuggestionProvider(request<SuggestionProvider> request);
- 13: GetVisibleStoriesController(request<VisibleStoriesController> request);
-
- // Requests logout of the user. This causes the basemgr to tear down the
- // |Sessionmgr| instance of the user.
- 16: Logout();
-};
-
-// Session shell provides this service to the framework which may plumb it to
-// different subscribers, such as story shell and intelligence provider.
-//
-// EXPERIMENTAL Service that allows consumers of a given story to get a
-// connection to a Presentation, and visual state services provided by the user
-// shell. This allows story shell implementations to coordinate event and focus
-// handling. An analog mechanism exists between BaseShell and SessionShell.
-[Discoverable] // Created by session shell components.
-interface SessionShellPresentationProvider {
- // When a StoryShell calls StoryShellContext.GetPresentation(), this request
- // arrives here.
- 1: GetPresentation(string story_id, request<fuchsia.ui.policy.Presentation> request);
-
- // When a StoryShell calls StoryShellContext.WatchVisualState(), this request
- // arrives here.
- 2: WatchVisualState(string story_id, StoryVisualStateWatcher watcher);
-};
diff --git a/public/fidl/fuchsia.modular/story/create_link.fidl b/public/fidl/fuchsia.modular/story/create_link.fidl
deleted file mode 100644
index eec40ae..0000000
--- a/public/fidl/fuchsia.modular/story/create_link.fidl
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.mem;
-
-// Defines the attributes for a Link when the Link is created.
-struct CreateLinkInfo {
- // Passed as root_json argument to StoryProvider.CreateStoryWithInfo()
- // Link.Set() to set the value in the root link of the new Story's primary
- // module.
- fuchsia.mem.Buffer initial_data;
-
- // If |allowed_types| is null, the Link contains JSON. No schema validation
- // is performed.
- LinkAllowedTypes? allowed_types;
-};
-
-struct LinkAllowedTypes {
- // The Link must contain an Entity (see Link.SetEntity()) that has at least
- // one of |allowed_entity_types| in its |Entity.GetTypes()| return value.
- //
- // If empty, allows any Entity type.
- vector<string> allowed_entity_types;
-};
diff --git a/public/fidl/fuchsia.modular/story/create_module_parameter_map.fidl b/public/fidl/fuchsia.modular/story/create_module_parameter_map.fidl
deleted file mode 100644
index 0023acc..0000000
--- a/public/fidl/fuchsia.modular/story/create_module_parameter_map.fidl
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Module parameters are named pointers to link instances.
-struct CreateModuleParameterMapInfo {
- // Contains instructions to create each name in the parameter map.
- vector<CreateModuleParameterMapEntry>? property_info;
-};
-
-struct CreateModuleParameterMapEntry {
- string? key;
- CreateModuleParameterInfo value;
-};
-
-union CreateModuleParameterInfo {
- // Instructs parameter map initialization to either use an existing Link
- // (|link_path| is set) or create a new Link (|create_link| is set).
- LinkPath link_path;
- CreateLinkInfo create_link;
-};
diff --git a/public/fidl/fuchsia.modular/story/link.fidl b/public/fidl/fuchsia.modular/story/link.fidl
deleted file mode 100644
index eee4a63..0000000
--- a/public/fidl/fuchsia.modular/story/link.fidl
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains the definition of Link as well as the structure
-// of the data it holds.
-
-library fuchsia.modular;
-
-using fuchsia.mem;
-
-// This interface is implemented by the story runner. The ModuleContext service
-// acts as a factory for it.
-//
-// An instance of Link holds one of two types of values:
-//
-// (1) A JSON string that can be modified incrementally or completely
-// overwritten, depending on the use of Set() and Update(). The JSON string
-// is set to "null" when the Link is created.
-//
-// (2) An entity reference that can be set or retrieved with SetEntity() and
-// GetEntity().
-//
-// Each Module instance receives one Link instance for each parameter of its
-// action template in its ModuleContext. It receives its ModuleContext in
-// Module.Initialize() or in its service namespace. The Module can access its
-// Links by calling ModuleContext.GetLink() with the intent parameter name as
-// the link name. These instances are shared with the parent Module if there is
-// any, or with the StoryController client if the Module is a top level Module
-// of a Story. A Module can create additional Link instances by calling
-// ModuleContext.GetLink() with any other link name. Why would it do that? To
-// share the new Link instance with Modules it requests to start in turn, or to
-// record its own state in the story record, so that it is transferred to other
-// devices that run the same story, or to persist it for later resumption of the
-// story.
-//
-// A client may obtain another handle to the same Link instance by calling
-// GetLink() with the same name again.
-//
-// A client of Link can set the JSON string stored in the instance and register
-// a handler (an implementation of the LinkWatcher interface) to be notified of
-// changes to the JSON string in the Link. A client may or may not be notified
-// of changes it itself makes to the Link value, depending on whether it
-// registers with WatchAll() or Watch(), respectively. If the client registers
-// with Watch(), then it will not be notified of changes made through the same
-// Link connection.
-//
-// No service name: returned from ModuleContext.GetLink().
-interface Link {
- // Gets the value at the given |path|, which is represented using the JSON
- // Pointer specification (https://tools.ietf.org/html/rfc6901).
- //
- // |json_data| is a UTF8 encoded string representing valid JSON.
- //
- // Returns null if |path| does not exist. Returns the entire JSON object
- // if |path| is either null or an empty array. Returns the string "null" if
- // the link is empty.
- 2: Get(vector<string>? path) -> (fuchsia.mem.Buffer? json_data);
-
- // Set() overwrites the value/object/array at the given |path|. Set also
- // overwrites any values or arrays as necessary to ensure that |path| exists.
- // The |json_data| parameter must be a UTF8 encoded JSON string.
- // Either pass "null" to set the value to null, or use Erase to
- // completely remove a member of an object. To replace the root, pass null for
- // |path|.
- //
- // This call notifies Watchers, although this may be skipped if nothing
- // changed.
- 3: Set(vector<string>? path, fuchsia.mem.Buffer json_data);
-
- // Erases the object member at the given |path|. If the path is not found or
- // does not match the current structure of the JSON, the path will not be
- // created and the call is ignored. The |path| parameter cannot be null or
- // zero length because the root is a value, not a key. This call notifies
- // Watchers, although this may be skipped if nothing changed.
- 5: Erase(vector<string> path);
-
- // Returns the entity reference in this link. If no entity reference is
- // present, returns a null fidl string.
- 9: GetEntity() -> (string? entity_reference);
-
- // Sets this to be an Entity Link with the given |entity_reference|. The
- // existing value of the link is overwritten. If |entity_reference| is null,
- // then any existing value in the link is overwritten with the JSON string
- // "null".
- 10: SetEntity(string? entity_reference);
-
- // Registers a watcher, which is notified whenever the document changes. This
- // watcher will not be invoked for changes caused by calls made on this
- // handle. The Notify() callback method will be immediately invoked with the
- // value in the Link, even if it's empty.
- //
- // The LinkWatcher connection will be closed if the owning Link handle closed.
-
- // All connections to a Link and LinkWatcher are closed once the story the
- // link belongs to is stopped.
- 6: Watch(LinkWatcher watcher);
-
- // Like Watch(), but the watcher is notified also of changes made through the
- // same handle as the watcher is registered on.
- 7: WatchAll(LinkWatcher watcher);
-
- // Waits for the completion of methods previously invoked on the same
- // connection. Allows to create sequentiality across service instances without
- // giving every method an empty return value. Nb. this makes no guarantees
- // about sequentiality with methods invoked on different connections, even to
- // the same Link instance.
- 8: Sync() -> ();
-};
-
-// This interface is implemented by a client of Link.
-//
-// The Notify() method is invoked whenever the Link changes. The entire JSON
-// string in the Link will be sent. In other words, this isn't an incremental
-// notification. |json| cannot be null because an empty Link is the valid JSON
-// document "null".
-//
-// No service name: created by Module.
-interface LinkWatcher {
- 1: Notify(fuchsia.mem.Buffer json);
-};
diff --git a/public/fidl/fuchsia.modular/story/puppet_master.fidl b/public/fidl/fuchsia.modular/story/puppet_master.fidl
deleted file mode 100644
index 23587b9..0000000
--- a/public/fidl/fuchsia.modular/story/puppet_master.fidl
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-enum ExecuteStatus {
- OK = 0;
-
- // Encountered an invalid command.
- INVALID_COMMAND = 1;
-
- // The |story_id| provided does not exist or is not visible
- // to this client.
- INVALID_STORY_ID = 2;
-
- // A story must contain at least one mod, and the commands given
- // either don't add one, or remove the last one.
- STORY_MUST_HAVE_MODS = 3;
-
- // The mod name specified in AddMod, RemoveMod or SendModCommand
- // was not found, or is invalid.
- INVALID_MOD = 4;
-
- // Resolution of the intent provided in AddMod returned zero results.
- NO_MODULES_FOUND = 5;
-
- // Some error happened while executing the command.
- INTERNAL_ERROR = 6;
-};
-
-struct ExecuteResult {
- ExecuteStatus status;
- string? story_id;
- string? error_message;
-};
-
-// Enables control of a session. A session, conceptually, is a single
-// full-screen experience of a Fuchsia device. A device can run multiple
-// sessions (ie, when one device powers multiple kiosks); that said, sessions
-// are siloed from each other.
-//
-// A session, concretely, is a collection of stories, their state, the modules
-// within them, any agents that run to support the mods and the various UI
-// shells (session and story shells).
-[Discoverable]
-interface PuppetMaster {
- // Requests a capability to control a story by name. The name acts as the
- // story's unique ID. Calling ControlStory() for the same story name will
- // control the same story.
- //
- // The story name, as well as modification to the story, are durable and
- // persist across device reboots. This allows the client to assign its own
- // identifiers to stories. Clients wishing to guarantee a new story is
- // created should generate a UUIDv4 or similar.
- //
- // |request| is closed if control cannot be granted.
- //
- // TODO(thatguy): We want story names to be scoped to the client's namespace.
- ControlStory(string story_name, request<StoryPuppetMaster> request);
-
- // Deletes a story associated to |story_name|.
- DeleteStory(string story_name) -> ();
-
- // Returns a list of all the names of stories in the session.
- GetStories() -> (vector<string> story_names);
-};
-
-struct WatchSessionOptions {
- // FIDL doens't allow empty structs. We want this struct to exist in the API
- // for future session watching options.
- int32 placeholder;
-};
-
-interface StoryPuppetMaster {
- // Enqueues the given |commands| in the order they are given.
- // Can be called as many times as necessary to specify the full
- // set of changes to the story.
- //
- // To execute all enqueued commands, call Execute().
- Enqueue(vector<StoryCommand> commands);
-
- // Executes the commands enqueued so far by Enqueue() in order and as
- // a batch: no other commands from other clients will be interleaved.
- //
- // If an error occurs, execution is stopped and an error code
- // and message are returned in |result|.
- Execute() -> (ExecuteResult result);
-
- // If this story is new, sets the options for its creation. Must be called
- // before the first call to Execute(). Any subsequent calls (either on the
- // same channel or on a new StoryPuppetMaster for an existing story) are
- // ignored. Some StoryOptions can be changed through specific story commands.
- // See story_command.fidl for details.
- SetCreateOptions(StoryOptions story_options);
-};
diff --git a/public/fidl/fuchsia.modular/story/story_command.fidl b/public/fidl/fuchsia.modular/story/story_command.fidl
deleted file mode 100644
index c0ca8fb..0000000
--- a/public/fidl/fuchsia.modular/story/story_command.fidl
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.mem;
-
-// StoryCommands are POD structures that describe the set of operations that
-// can be performed on a story by components outside the modular framework. All commands are:
-//
-// (1) Scoped to a single story
-// (2) Idempotent: issuing the same command twice yields the same result
-// (3) Symmetrical with observation: the same structures are used to describe
-// operations to watchers of a story (through SessionWatcher) as are used
-// to control a story.
-union StoryCommand {
- // Sets the focus state of the story to |set_focus_state.focused|.
- SetFocusState set_focus_state;
-
- // Adds a Mod.
- AddMod add_mod;
-
- // Removes an existing Mod.
- RemoveMod remove_mod;
-
- // Sets the value of a Link.
- SetLinkValue set_link_value;
-
- // Brings focus to a mod.
- FocusMod focus_mod;
-
- // Updates the kind_of_proto_story option in a story.
- SetKindOfProtoStoryOption set_kind_of_proto_story_option;
-};
-
-struct SetFocusState {
- bool focused;
-};
-
-// Adds a mod described by |intent| to the story with name |mod_name|. If
-// |mod_name| already exists in the story, the mod is updated.
-struct AddMod {
- // The name of the mod within the story. The mod's name acts as the unique
- // ID of the mod, scoped to the story in which it is contained. Since
- // AddMod is reused for observation and mod names are vector<string>
- // inside the framework, they are vector<string> here as well.
- //
- // Clients should treat the full vector as a single opaque value.
- vector<string> mod_name;
- Intent intent;
-
- // |surface_relation| defines the visual relationship between this mod and the
- // mod at |surface_parent_mod_name|.
- SurfaceRelation surface_relation;
- vector<string>? surface_parent_mod_name;
-};
-
-// Removes the mod under |mod_name| from the story.
-struct RemoveMod {
- vector<string> mod_name;
-};
-
-// Sets the value of link at |path| to |value|.
-struct SetLinkValue {
- LinkPath path;
- fuchsia.mem.Buffer? value;
-};
-
-// Instructs the session shell to focus the mod under |mod_name|.
-struct FocusMod {
- vector<string> mod_name;
-};
-
-// Updates the kind_of_proto_story option in a story.
-struct SetKindOfProtoStoryOption {
- bool value;
-};
diff --git a/public/fidl/fuchsia.modular/story/story_controller.fidl b/public/fidl/fuchsia.modular/story/story_controller.fidl
deleted file mode 100644
index 15648e2..0000000
--- a/public/fidl/fuchsia.modular/story/story_controller.fidl
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.ui.viewsv1token;
-
-// Used by the clients of StoryProvider (SessionShell) to interact with a single
-// story. Created by StoryProvider.
-//
-// If |StoryController| is closed, the |StoryState| associated with this story
-// does not change.
-interface StoryController {
- // Gets information associated with the story.
- 1: GetInfo() -> (StoryInfo info, StoryState state);
-
- // Requests to run the story controlled by this |StoryController| instance.
- // When the story starts, if not yet running, the view of the newly started
- // story shell will be passed in a call to SessionShell.AttachView().
- 14: RequestStart();
-
- // Requests to stop the story controlled by this |StoryController|. If Start()
- // requests are pending when this request is issued, the request is queued
- // until the Start() requests complete. Before stopping the story, a snapshot
- // of the story will be taken and saved. Returns when the story is stopped.
- 4: Stop() -> ();
-
- // Creates a new view with the given |view_owner| request to display
- // snapshots. Takes a snapshot for the story controlled by this
- // |StoryController| and then loads the snapshot to the created view such that
- // it is rendered. The callback will be invoked once the view has been created
- // and the snapshot has been loaded.
- 13: TakeAndLoadSnapshot(request<fuchsia.ui.viewsv1token.ViewOwner> view_owner) -> ();
-
- // Registers a watcher for changes of the story state.
- //
- // Note that stories can stop themselves at any time and it is advisable
- // for the holder of a StoryController to provide a watcher.
- 5: Watch(StoryWatcher watcher);
-
- // DEPRECATED
- 7: GetActiveModules() -> (vector<ModuleData> module_data);
-
- // DEPRECATED
- 8: GetModules() -> (vector<ModuleData> module_data);
-
- // DEPRECATED
- // (metadata about, and requesting changes to runtime state).
- 9: GetModuleController(vector<string> module_path, request<ModuleController> request);
-
- // DEPRECATED: MI4-1084
- 10: GetActiveLinks(StoryLinksWatcher? watcher) -> (vector<LinkPath> link_data);
-
- // DEPRECATED
- 11: GetLink(LinkPath link_path, request<Link> link);
-};
-
-// Implemented by the client calling StoryController.Watch().
-interface StoryWatcher {
- // Called with the current state right after registration, and subsequently
- // when the state changes.
- 1: OnStateChange(StoryState new_state);
-
- // DEPRECATED
- 2: OnModuleAdded(ModuleData module_data);
-
- // DEPRECATED
- 3: OnModuleFocused(vector<string> module_path);
-};
-
-// Implemented by the client calling StoryController.GetActiveLinks().
-//
-// DEPRECATED: StoryController is only to be used for Story concepts
-// (metadata about, and requesting changes to runtime state).
-interface StoryLinksWatcher {
- // Called when a link becomes active in the story, i.e. when it is loaded into
- // memory and connected with modules and watchers. After this notification,
- // the Link can be obtained with GetLink() and further notifications can be
- // obtained from watchers on the Link and connection error handlers on the
- // LinkWatcher.
- //
- // Note that the Link remains active until there are no connections to it
- // left. Hence in order to obtain a notification when the Link becomes
- // inactive, a client must give up the Link connection after registering a
- // LinkWatcher, and listen for the LinkWatcher connection to go down.
- //
- // This is EXPERIMENTAL. We certainly can make this simpler once we know it is
- // what we need.
- 1: OnNewLink(LinkPath link_path);
-};
diff --git a/public/fidl/fuchsia.modular/story/story_info.fidl b/public/fidl/fuchsia.modular/story/story_info.fidl
deleted file mode 100644
index 519a589..0000000
--- a/public/fidl/fuchsia.modular/story/story_info.fidl
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Information about a story as provided to the SessionShell.
-struct StoryInfo {
- // URL of the first module run in this story. This module is free to
- // run more modules in the story. Used for display purposes only.
- // TODO(thatguy): Remove this. It is not being set any more.
- string? url;
-
- // The ID of the Story, used to reference it in method arguments.
- string id;
-
- // Wallclock time when the story was last focused. From
- // zx_clock_get(ZX_CLOCK_UTC), thus nanoseconds since UNIX epoch (1970-01-01
- // 00:00 UTC).
- //
- // A value of zero means the story has never been focused.
- int64 last_focus_time;
-
- // Data the SessionShell wants to keep associated with this Story, like
- // title, a color, or a display rank.
- vector<StoryInfoExtraEntry>? extra;
-};
-
-struct StoryInfoExtraEntry {
- string key;
- string value;
-};
diff --git a/public/fidl/fuchsia.modular/story/story_options.fidl b/public/fidl/fuchsia.modular/story/story_options.fidl
deleted file mode 100644
index 045b646..0000000
--- a/public/fidl/fuchsia.modular/story/story_options.fidl
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-struct StoryOptions {
- // Whether or not the story will be hidden on a call to
- // StoryProvider#GetStories.
- bool kind_of_proto_story;
-};
diff --git a/public/fidl/fuchsia.modular/story/story_provider.fidl b/public/fidl/fuchsia.modular/story/story_provider.fidl
deleted file mode 100644
index eeecfa1..0000000
--- a/public/fidl/fuchsia.modular/story/story_provider.fidl
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Sessionmgr passes a connection to this service to the SessionShell so it can
-// operate on stories for the user. It is also passed to other services that
-// monitor or manipulate stories, specifically the maxwell services.
-//
-// Closing a |StoryProvider| connection has no effect on the state of the
-// framework.
-[Discoverable]
-interface StoryProvider {
- // Returns a list of existing stories. If |watcher| is provided, the client will
- // be notified of story changes (new stories, deleted stories, runtime
- // state changes).
- 4: GetStories(StoryProviderWatcher? watcher) -> (vector<StoryInfo> story_infos);
-
- // Requests detailed information about the given story. If the story doesn't
- // exist, returns null.
- 5: GetStoryInfo(string story_id) -> (StoryInfo? story_info);
-
- // Obtains a controller for a previously created story identified by its story
- // ID. Obtaining the controller doesn't run it yet. If the story doesn't
- // exist, the interface request is closed.
- 6: GetController(string story_id, request<StoryController> request);
-
- // Returns info of known stories.
- // DEPRECATED: In favor of GetStories().
- 7: PreviousStories() -> (vector<StoryInfo> story_infos);
-
- // Registers a watcher for changes in the story collection.
- // DEPRECATED: In favor of GetStories().
- 9: Watch(StoryProviderWatcher watcher);
-
- // Registers a watcher for ongoing story activity. Upon registration,
- // StoryActivityWatcher.OnStoryActivity() will be called to update clients
- // with the initial data. See StoryActivityWatcher for motivations.
- 10: WatchActivity(StoryActivityWatcher watcher);
-};
-
-// Implemented by clients of StoryProvider.
-interface StoryProviderWatcher {
- // Called in three different situations:
- //
- // * Immediately when a new watcher is registered with one OnChange()
- // invocation with the current infor and state of each story known on the
- // current device.
- //
- // * Every time a change to StoryInfo is applied to the record of the story
- // kept on the current device, including a new story created on another
- // device becoming known on this device for the first time.
- //
- // * Every time the StoryState of the story changes on this device. The
- // StoryState on another device of a story known on this device is not made
- // known on this device.
- //
- // * Every time the StoryVisibilityState of the story changes on this device.
- // The StoryVisibilityState on another device of a story known on this
- // device is not made known on this device.
- //
- // I.e. if the story is started or stopped on *another* device, it does
- // *not* cause an OnChange() call on *this* device. Cf. OnDelete() below.
- //
- // The ID of the story the notifications are about are part of StoryInfo.
- //
- // |story_state| is STOPPED if the story was just created or just became known
- // on this device and was not yet started on the current device. It's RUNNING
- // when the story is started on the current device.
- //
- // |story_visibility_state| is DEFAULT until a mod on the current device
- // requests for the visibility state to be changed.
- 1: OnChange(StoryInfo story_info, StoryState story_state,
- StoryVisibilityState story_visibility_state);
-
- // Called when a story record is permanently deleted. The deletion could
- // have originated on this or on another device.
- //
- // If the story is running on this device at the time it is deleted,
- // OnChange() will not be called first.
- 2: OnDelete(string story_id);
-};
-
-// Implemented by clients of StoryProvider in order to inform them about ongoing
-// activities in stories. |activities| is the entire list of ongoing activities
-// (represented by its type) within the story by the given |story_id|. If
-// |activities| is empty, it means that there is no ongoing activity within the
-// story.
-//
-// Clients can expect this event whenever there is a newly started/stopped
-// ongoing activity, as well as when the client first registers for updates
-// via StoryProvider.WatchActivity(). |activities| can contain duplicate
-// OngoingActivityType's, ex. if a story is playing 2 videos at once.
-interface StoryActivityWatcher {
- 1: OnStoryActivityChange(string story_id,
- vector<OngoingActivityType> activities);
-};
diff --git a/public/fidl/fuchsia.modular/story/story_shell.fidl b/public/fidl/fuchsia.modular/story/story_shell.fidl
deleted file mode 100644
index 966465d..0000000
--- a/public/fidl/fuchsia.modular/story/story_shell.fidl
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.ui.policy;
-using fuchsia.ui.viewsv1token;
-
-// This interface is implemented by a story shell. Dependencies are passed to it
-// in Initialize() on startup. The story shell is also expected to implement
-// Lifecycle in order to receive a Terminate() call on teardown.
-//
-// In one component instance there can only be one StoryShell service instance.
-// The ViewOwner request is sent to the separate ViewProvider service. This way,
-// the story shell may be implemented as a flutter component.
-//
-// Teardown may be initiated by the session shell calling StoryController.Stop(),
-// by the sessionmgr being terminated, or by the system shutting down.
-[Discoverable] // Created by story shell applications.
-interface StoryShell {
- 1: Initialize(StoryShellContext story_shell_context);
-
- // Adds a new Surface and its corresponding view to be displayed by the
- // StoryShell. More context that allows the story shell to decide how
- // to layout will be added later. Also, interface to influence life cycle and
- // focus is obviously missing.
- // |view_connection| the new view and the associated Surface ID.
- // |surface_info| metadata relating to the Surface.
- 2: AddSurface(ViewConnection view_connection, SurfaceInfo surface_info);
-
- // Focuses the surface with surface_id, bringing it to the foreground.
- 3: FocusSurface(string surface_id);
-
- // Defocuses the surface with surface_id, dismissing it to the background.
- 4: DefocusSurface(string surface_id) -> ();
-
- // Adds a container, with corresponding container layouts to the story.
- // Optionally provide a parent_id to connect to, if omitted adds the
- // Container node as the root of a new tree in the Story
- // DEPRECATED
- 5: AddContainer(string containerName, string? parentId,
- SurfaceRelation relation, // relation of container to parent
- vector<ContainerLayout> layout,
- vector<ContainerRelationEntry> relationships,
- vector<ContainerView> views);
-
- // Notify when a Surface is focused in the story. The focus could be from
- // a user interaction or requested by the framework through
- // StoryController#FocusModule.
- // EXPERIMENTAL
- 6: -> OnSurfaceFocused(string surface_id);
-
- // Remove the Surface with surface_id from the StoryShell entirely. This is
- // final. The Surface is removed from the graph. If necessary, the
- // associated Surface is defocused. There is no expectation that
- // DefocusSurface is called before this.
- 7: RemoveSurface(string surface_id);
-
- // Reconnect the view in viewConnection.
- //
- // Called to reconnect views that have previously been added
- // to the StoryShell via addSurface, and then disconnected. a ViewOwner
- // connects to a child view and is notified if the view is available. If
- // it becomes unavailable it's disconnected. If a surface with a
- // disconnected view is to be shown again, ReconnectView is called.
- //
- // E.g. called in response to StoryShell calling RequestView().
- 8: ReconnectView(ViewConnection view_connection);
-
- // Update the surface
- // This is called when the intent is to update the surface metadata in the
- // story graph in place. Any fields, except for the surface_id can be
- // updated. If no value or null is passed for a field it remains unchanged.
- // This includes the ViewOwner inside the connection.
- //
- // E.g called when an intent resolves to a module that is known by the
- // caller to already be running, to update associated metadata.
- 9: UpdateSurface(ViewConnection view_connection, SurfaceInfo surface_info);
-};
-
-// A pair mapping the view owner to surface ID
-struct ViewConnection {
- // The new view corresponding to the surface.
- fuchsia.ui.viewsv1token.ViewOwner owner;
-
- // The ID for the surface
- string surface_id;
-};
-
-// Contain metadata for a Surface
-struct SurfaceInfo {
- // ID of the view that is parent of this Surface.
- string parent_id;
-
- // The relationship between the parent Surface and this new Surface. Used
- // for layout optimization
- SurfaceRelation? surface_relation;
-
- // Information about the module populates the view.
- ModuleManifest? module_manifest;
-
- // How the Surface was generated. By an action internal to the story or by
- // an external action.
- ModuleSource module_source;
-};
-
-// Maps the node_name to the specific mozart view resulting from resolving and
-// launching the intent specified in a Container node
-struct ContainerView {
- // Name by which this container node is referenced in container layout and
- // surface relationship specifications (cf. container.fidl)
- string node_name;
-
- // The new view resolved from the intent corresponding to node_name
- fuchsia.ui.viewsv1token.ViewOwner owner;
-};
-
-// This interface provides the StoryShell instance with everything it needs to
-// know or be able to do about the Story. Not much right now, but we expect this
-// to increase.
-interface StoryShellContext {
- // Requests a Presentation connection from the SessionShell. See
- // SessionShellPresenationProvider in session_shell.fidl.
- 1: GetPresentation(request<fuchsia.ui.policy.Presentation> request);
-
- // Starts watching Story shell's visual state.
- 2: WatchVisualState(StoryVisualStateWatcher watcher);
-
- // Gets a Link instance that the story shell can use for persisting metadata.
- 3: GetLink(request<Link> request);
-
- // Requests a view for a Surface.
- // Requests that a view for |surface_id| is provided through
- // StoryShell.ReconnectView().
- 4: RequestView(string surface_id);
-
- // Notification that the Surface is no longer on screen.
- 5: OnSurfaceOffScreen(string surface_id);
-};
-
-// Implemented by StoryShell to get notified about visual state changes.
-interface StoryVisualStateWatcher {
- 1: OnVisualStateChange(StoryVisualState visual_state);
-};
-
-// Defines the visual state of the Story shell.
-enum StoryVisualState {
- MINIMIZED = 0;
- MAXIMIZED = 1;
- MAXIMIZED_OVERLAYED = 2;
-};
diff --git a/public/fidl/fuchsia.modular/story/story_state.fidl b/public/fidl/fuchsia.modular/story/story_state.fidl
deleted file mode 100644
index 797435a..0000000
--- a/public/fidl/fuchsia.modular/story/story_state.fidl
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// State of a Story. A story is either running, stopping, or stopped, separately
-// on every device of the user. If it's running, it can also be focused, but
-// that's tracked in a separate service, cf. FocusProvider in focus.fidl.
-//
-// Possible state transitions are:
-//
-// STOPPED -> RUNNING
-// RUNNING -> STOPPING
-// STOPPING -> STOPPED
-enum StoryState {
- // Story was started using StoryController.Start().
- RUNNING = 1;
- // Story is in the middle of stopping after StoryController.Stop() was
- // called.
- STOPPING = 2;
- // Story was not yet run, or Story was stopped after StoryController.Stop()
- // was called.
- STOPPED = 3;
-};
diff --git a/public/fidl/fuchsia.modular/story/story_visibility_state.fidl b/public/fidl/fuchsia.modular/story/story_visibility_state.fidl
deleted file mode 100644
index 1afbef1..0000000
--- a/public/fidl/fuchsia.modular/story/story_visibility_state.fidl
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Visibility state of a Story within the session shell.
-// This state describes how a story should be displayed within the session shell,
-// regardless of whether the story is in focus or not. Focus state and
-// visibility state are orthogonal concepts.
-// E.g A story can be out-of-focus and be in IMMERSIVE state at the same time
-// if a user was playing a video, exits, then re-enters the story. The
-// expectation in this scenario is that the story is in IMMERSIVE state upon
-// re-enter.
-//
-// All state transitions are possible.
-enum StoryVisibilityState {
- // Default state for a story.
- DEFAULT = 1;
- // Full-screen user experience, e.g. playing a video.
- IMMERSIVE = 2;
-};
diff --git a/public/fidl/fuchsia.modular/suggestion/debug.fidl b/public/fidl/fuchsia.modular/suggestion/debug.fidl
deleted file mode 100644
index 8b04dab..0000000
--- a/public/fidl/fuchsia.modular/suggestion/debug.fidl
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Debug service provider interface that provides the ability to listen to
-// the internal state of the suggestion service.
-[Discoverable]
-interface SuggestionDebug {
- 1: WatchAskProposals(AskProposalListener listener);
- 2: WatchInterruptionProposals(InterruptionProposalListener listener);
- 3: WatchNextProposals(NextProposalListener listener);
-
- // Waits until Suggestion Engine has reached a steady state such that no
- // further activity will occur unless acted upon from the outside.
- 4: WaitUntilIdle() -> ();
- // Calls |async::Loop::RunUntilIdle()|, which processes all immediately
- // available messages. Unlike |WaitUntilIdle|, this does not wait for
- // long-running delayed tasks.
- 5: RunUntilIdle() -> ();
-};
-
-interface AskProposalListener {
- // Receives the current ask query and ranked proposals
- 1: OnAskStart(string query, vector<ProposalSummary> proposals);
- // Receives notification of query completion or dismissal.
- // |selected_proposal| is null if query was dismissed
- 2: OnProposalSelected(ProposalSummary? selected_proposal);
-};
-
-interface InterruptionProposalListener {
- // Receives updates to the current proposal list and rankings
- 1: OnInterrupt(ProposalSummary interruption_proposal);
-};
-
-interface NextProposalListener {
- // Receives updates to the current proposal list and rankings
- 1: OnNextUpdate(vector<ProposalSummary> proposals);
-};
-
-// This is necessary because a Proposal is not Clone-able, as CustomAction
-// can contain an InterfaceHandle.
-struct ProposalSummary {
- string id;
- string publisher_url;
- SuggestionDisplay display;
-};
diff --git a/public/fidl/fuchsia.modular/suggestion/proposal.fidl b/public/fidl/fuchsia.modular/suggestion/proposal.fidl
deleted file mode 100644
index c7c811a..0000000
--- a/public/fidl/fuchsia.modular/suggestion/proposal.fidl
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.mem;
-
-struct Proposal {
- // Identifies a proposal, namespaced internally to the proposing component and
- // proposal channel (Query or Next/Interruption).
- string id;
-
- // A client-assigned name for the story to which the actions in |on_selected|
- // apply. If a story with the given name already exists (ie, because a past
- // Proposal with the same |story_name| was executed), the actions in
- // |on_selected| will apply to the existing story. Otherwise, a new story is
- // created.
- // If |story_name| is null, a new story is always created.
- // This name is namespaced to the agent that submitted the proposal.
- string? story_name;
-
- // Used to restrict the proposal potential appearance as a suggestion only
- // when certain story or mod is focused.
- vector<ProposalAffinity> affinity;
-
- // The list of actions to take when the user selects the associated
- // Suggestion.
- vector<StoryCommand> on_selected;
-
- // An optional hint about the probability that this proposal would be chosen
- // if it were the only proposal presented to the user. A confidence of 0.0
- // indicates no hint. The confidence assigned by the system may be subject to
- // other considerations such as performance metrics.
- float32 confidence = 0.0;
-
- // True iff the proposal would like to make use of a rich suggestion. Only
- // certain components are allowed to use rich suggestions.
- bool wants_rich_suggestion = false;
-
- SuggestionDisplay display;
-
- // A listener interface that is notified when the proposal is accepted by
- // the system.
- //
- // The listener is currently notified once when a proposal is accepted. Thus
- // the |story_id| provided will be of the first create story action in
- // |on_selected|, and subsequent create story actions will not notify the
- // listener.
- ProposalListener? listener;
-};
-
-// Restricts the proposal potential apparance as a suggestion only when
-// a story or a mod within a story are focused.
-union ProposalAffinity {
- StoryAffinity story_affinity;
- ModuleAffinity module_affinity;
-};
-
-// Restricts the proposal to appear only when the story identified by
-// |story_name| is focused.
-// The name is namespace to the agent that submitted the proposal.
-struct StoryAffinity {
- string story_name;
-};
-
-// Restricts the proposal to appear only when the module identified by
-// |module_name| within the story identified by |story_name| is focused.
-// The name is namespace to the agent that submitted the proposal.
-struct ModuleAffinity {
- string story_name;
- vector<string> module_name;
-};
-
-// An interface that allows Proposal creators to be notified when a proposal
-// is accepted by the system.
-interface ProposalListener {
- // Indicates that a proposal was accepted by the system.
- //
- // |proposal_id| The identifier of the accepted proposal.
- // |story_id| The identifier of the created story, if a story was created.
- 1: OnProposalAccepted(string proposal_id, string? story_id);
-};
diff --git a/public/fidl/fuchsia.modular/suggestion/proposal_publisher.fidl b/public/fidl/fuchsia.modular/suggestion/proposal_publisher.fidl
deleted file mode 100644
index b7afa0a..0000000
--- a/public/fidl/fuchsia.modular/suggestion/proposal_publisher.fidl
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// A service enabling Agents and Modules to contribute Proposals proactively to
-// the Suggestion engine.
-[Discoverable]
-interface ProposalPublisher {
- // Includes the given |proposal| in the Next/Interruption channel from this
- // publisher. Proposals are identified by |proposal.id|, and are namespaced by
- // the component's ID and proposal channel (Query vs. Next/Interruption).
- //
- // If a Next/Interruption Proposal with the same id is already present, it is
- // overwritten.
- 1: Propose(Proposal proposal);
-
- // Removes the Proposal with the given ID from the Next/Interruption channel
- // produced by this component.
- 2: Remove(string proposal_id);
-
- // Includes the navigation request in the Navigation channel from this
- // publisher. Navigation events are immediate and not tracked by any id.
- // TODO(ejia): Replace with puppetmaster.
- // EXPERIMENTAL
- 3: ProposeNavigation(NavigationAction navigation);
-};
diff --git a/public/fidl/fuchsia.modular/suggestion/query_handler.fidl b/public/fidl/fuchsia.modular/suggestion/query_handler.fidl
deleted file mode 100644
index 84e6457..0000000
--- a/public/fidl/fuchsia.modular/suggestion/query_handler.fidl
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.media;
-
-struct QueryResponse {
- vector<Proposal> proposals;
-};
-
-// An interface enabling Agents and Modules to contribute Proposals reactively
-// to the Suggestion engine based on a user query.
-interface QueryHandler {
- // Produces a list of Proposals in response to a query. The query may be empty
- // in the case of an initial ask, and this method is called every time the
- // query changes.
- //
- // Proposals given in the callback have their lifecycle tied to this query.
- // After the query has completed, the proposals are dismissed. When the query
- // changes, any proposals missing from the subsequent callback are likewise
- // dismissed. These Proposals are distinct from Next/Interruption proposals,
- // even if they may share IDs.
- //
- // Alternately, the client is free to call Propose on its
- // ProposalPublisher to make persistent Proposals. However, these
- // proposals may be subject to more stringent filtering by the Suggestion
- // Engine. TODO(rosswang): spec/revisit.
- 1: OnQuery(UserInput query) -> (QueryResponse response);
-};
diff --git a/public/fidl/fuchsia.modular/suggestion/suggestion_display.fidl b/public/fidl/fuchsia.modular/suggestion/suggestion_display.fidl
deleted file mode 100644
index 601a554..0000000
--- a/public/fidl/fuchsia.modular/suggestion/suggestion_display.fidl
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.images;
-
-enum SuggestionImageType {
- PERSON = 0;
- OTHER = 1;
-};
-
-enum AnnoyanceType {
- NONE = 0;
-
- // Tiny interruptions meant to be displayed and hidden quickly without user
- // interaction. Analogous to toasts. They won't reach the next space when
- // ignored or missed.
- PEEK = 1;
-
- // Interruptions meant to be displayed to the user. The user could accept or
- // dismiss them. They are placed in the Next space when ignored or missed.
- // Analogous to notifications.
- INTERRUPT = 2;
-
- // Meant to show system errors or other extremely urgent alerts. It would
- // block the rest of the interface and force the user to interact with it.
- BLOCKING = 3;
-};
-
-// Information for the main image of the Suggestion.
-struct SuggestionDisplayImage {
- // The image as a vmo.
- fuchsia.images.EncodedImage image;
-
- // Information about the content contained in the image
- SuggestionImageType image_type;
-};
-
-// TODO(thatguy): This will likely be a union eventually, with different
-// display descriptions for different kinds of Suggestions.
-struct SuggestionDisplay {
- // Title text for this Suggestion
- string headline;
-
- // Sub-headline text to be optionally displayed with this Suggestion
- string? subheadline;
-
- // A longer details string to be optionally displayed with this Suggestion
- string? details;
-
- // Color in which the Suggestion should be displayed
- // Format is 0xaarrggbb
- uint32 color;
-
- // Optional list of icons that can be displayed with the Suggestion
- vector<SuggestionDisplayImage>? icons;
-
- // Optional image to display as part of the Suggestion
- SuggestionDisplayImage? image;
-
- // How annoying should this suggestion be?
- AnnoyanceType annoyance;
-};
diff --git a/public/fidl/fuchsia.modular/suggestion/suggestion_engine.fidl b/public/fidl/fuchsia.modular/suggestion/suggestion_engine.fidl
deleted file mode 100644
index 0b568ac..0000000
--- a/public/fidl/fuchsia.modular/suggestion/suggestion_engine.fidl
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Administrative interface for Suggestion Engine.
-[Discoverable]
-interface SuggestionEngine {
- // Registers a component that produces suggestions.
- 1: RegisterProposalPublisher(string url, request<ProposalPublisher> publisher);
-
- // Registers a component that produces suggestions based on a query.
- 2: RegisterQueryHandler(string url, QueryHandler query_handler);
-};
diff --git a/public/fidl/fuchsia.modular/suggestion/suggestion_provider.fidl b/public/fidl/fuchsia.modular/suggestion/suggestion_provider.fidl
deleted file mode 100644
index 19ccfa5..0000000
--- a/public/fidl/fuchsia.modular/suggestion/suggestion_provider.fidl
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Allows clients to subscribe to different Suggestion "channels" and iterate
-// through the results. Supports both passive consumption of Suggestions based
-// on contextual changes, as well as Suggestions derived from user-driven
-// "Asks".
-[Discoverable]
-interface SuggestionProvider {
- // Creates a subscription to the "interruptions" category of Suggestions.
- // Interruptions are delivered immediately once they become available, and are
- // potentially unlimited in number.
- //
- // Closing the |listener| pipe terminates the subscription.
- //
- // Any user interactions received by the client should be forwarded to the
- // SuggestionService by calling NotifyInteraction().
- 1: SubscribeToInterruptions(InterruptionListener listener);
-
- // Creates a subscription to "Next" Suggestions, with changes sent to
- // |listener|. A maximum of |count| suggestions will be returned. To
- // change the count, call this method again with a new count.
- //
- // Closing the the |listener| pipe terminates the subscription.
- 2: SubscribeToNext(NextListener listener, int32 count);
-
- // Must be called when the user initiates a query for suggestions, perhaps
- // as an “Ask” or a scoped suggestion. Results are sent to |listener|. Changes
- // to the query should be communicated by closing the previous |listener| and
- // calling the method again with the new query.
- //
- // Closing the |listener| pipe signals to the SuggestionService that the query
- // has been completed or canceled.
- 3: Query(QueryListener listener, UserInput query, int32 count);
-
- // Notifies the suggestion engine that the user has interacted with the given
- // Suggestion in the manner described in |interaction|.
- 4: NotifyInteraction(string suggestion_uuid, Interaction interaction);
-
- // Creates a subscription to a "navigation" suggestion.
- // Like an interruption, the navigation based suggestion will be provided as
- // soon as it's available.
- 6: SubscribeToNavigation(NavigationListener listener);
-};
-
-// The navigation action requested to be performed
-enum NavigationAction {
- UNKNOWN = 0;
-
- // Navigate to the overview or home screen
- HOME = 1;
-
- // Navigate to the cover story
- SCREENSAVER = 2;
-
- // Launch the full settings
- SETTINGS = 3;
-};
-
-interface NavigationListener {
- // Notifies the user interface to perform the navigation requested
- 1: OnNavigation(NavigationAction action);
-};
-
-interface InterruptionListener {
- // Notifies the user interface to interrupt the user
- 1: OnInterrupt(Suggestion suggestion);
-};
-
-interface NextListener {
- // Notifies the user interface that the passive suggestion results have been
- // updated. This is called every time the suggestion results change.
- 1: OnNextResults(vector<Suggestion> suggestions);
-
- // Notifies the user interface when processing is occurring on the passive
- // suggestions, which may result in additions or re-ranking. The UI may
- // wish to show a spinner during this time.
- 2: OnProcessingChange(bool processing);
-};
-
-interface QueryListener {
- // Notifies the user interface that new suggestion results are available.
- // This may be called multiple times if the suggestion results are updated.
- 1: OnQueryResults(vector<Suggestion> suggestions);
-
- // Notifies the user interface that query processing is completed.
- 2: OnQueryComplete();
-};
-
-enum InteractionType {
- // Set when a suggestion was accepted by the user. In the case of an
- // interruption, it won't be placed in the next suggestions.
- SELECTED = 0;
-
- // Set when a suggestion was removed by the user. In the case of an
- // interruption, it won't be placed in the next suggestions and in the case of
- // a non-interruptive suggestion it will be removed from it.
- DISMISSED = 1;
-
- // Set when a suggestion was hidden by the user. An interruption that is
- // snoozed will be placed in next.
- // Note: as of 08/03/2018 this interaction is only defined for interruptions.
- // TODO(miguelfrde): define for regular suggestions.
- SNOOZED = 2;
-
- // Set when a suggestion is hidden by the session shell with no user interaction.
- // An interruption that is expired is placed in the next space.
- // This has no effect on regular suggestions, only on interruptions.
- EXPIRED = 3;
-};
-
-struct Interaction {
- InteractionType type;
-
- // TODO(thatguy): Include parameters for each type of interaction where
- // applicable. Consider making this a union in lieu of the struct/enum combo.
-};
-
-struct Suggestion {
- // Uniquely and globally identifies this Suggestion.
- string uuid;
-
- // The probability that a given suggestion would be selected if it were the
- // only suggestion shown to the user.
- float32 confidence;
-
- // Story id for a rich suggestion. Session shell may opt to start and compose the
- // story's UI as the suggestion display, instead of making use of the properties
- // in |display|.
- string? preloaded_story_id;
-
- // Display properties of the Suggestion
- SuggestionDisplay display;
-};
-
-// *** Speech Section ***
-// TODO(jwnichols): Move these into a separate speech service. It is
-// convenient to have them here now, but this is not a good long term
-// solution.
-
-// Encodes the valid states of an Ask, including spoken phases. States include
-// those used for interpreting speech to text as well as for when the system is
-// querying handlers or generating audio output.
-//
-// All state transitions are valid.
-//
-// TODO(rosswang): These states might be pertinent to non-speech flows as well.
-// TODO(rosswang): |IDLE| vs. |PROCESSING| is going to become the
-// |OnProcessingChanged| state event on |SuggestionHandler| soon.
-enum SpeechStatus {
- // Exchange complete or not started
- IDLE = 0;
- // Query sent, awaiting results
- PROCESSING = 1;
- // System speaking
- RESPONDING = 2;
-};
-
-// TODO(rosswang): This is very temporary. Probably next week, OnStatusChanged
-// will be split between the |TranscriptionListener| lifecycle and
-// |SuggestionListener|'s |onProcessingChanged|. |OnTextResponse will probably
-// be part of the callback on |Query|.
-interface FeedbackListener {
- // Called every time the internal |SpeechStatus| changes.
- 1: OnStatusChanged(SpeechStatus status);
-
- // TODO(rosswang): OnAudioResponse method (or fold it into OnTextResponse),
- // once it becomes trivial for SysUI to implement it. This would allow SysUI
- // to make a determination as to whether playback is warranted. For now, let
- // Suggestion Engine handle the playback. A possible next step could be to add
- // OnAudioResponse with a method to start playback.
-
- // Receives a text representation of the spoken response. This method is
- // called at the beginning of the |RESPONDING| phase.
- 2: OnTextResponse(string response_text);
-};
diff --git a/public/fidl/fuchsia.modular/suggestion/user_input.fidl b/public/fidl/fuchsia.modular/suggestion/user_input.fidl
deleted file mode 100644
index 233cc84..0000000
--- a/public/fidl/fuchsia.modular/suggestion/user_input.fidl
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-enum InputType {
- TEXT = 0;
- SPEECH = 1;
-};
-
-struct UserInput {
- InputType type = TEXT;
- string text;
- // Future evolutions of this struct may include alternate data formats, at
- // which point I'd like to rename text to string_value and make it optional.
-};
diff --git a/public/fidl/fuchsia.modular/surface/container.fidl b/public/fidl/fuchsia.modular/surface/container.fidl
deleted file mode 100644
index 3d8b420..0000000
--- a/public/fidl/fuchsia.modular/surface/container.fidl
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains the definition of module container layouts.
-
-library fuchsia.modular;
-
-// Specification of the layout of multiple surfaces in a module container. The
-// surfaces are referenced by name in ContainerRelationEntry.
-struct ContainerLayout {
- vector<LayoutEntry> surfaces;
-};
-
-// Specification of the postion of one surface within a container layout,
-// specified by a rectangle.
-struct LayoutEntry {
- // Surface name, referenced by container relation entry.
- string node_name;
-
- // Layout, as rectangle in Dart conventions(left, top, width, height), as a
- // proportion of the size of the container
- array<float32>:4 rectangle;
-};
-
-// Specifies the surface relationship between modules started together in module
-// container.
-//
-// TODO(djmurphy): this allows arbitrary graphs including cyclical ones, which
-// makes no sense. We could consider a nested data structure that makes cycles
-// impossible to specify.
-struct ContainerRelationEntry {
- // Surface name, referenced by layout.
- string node_name;
-
- // Surface name of the layout parent. This could be the container itself,
- // rather than a module in it.
- string parent_node_name;
-
- // This surface relation between the surface identified by node_name and by
- // parent_node_name.
- //
- // It is possible to specify a surface relationship of a module in a container
- // to the container itself, as opposed to another module in the container.
- // This expresses for example that a module can be dismissed individually, as
- // opposed to dismissing the module dismisses the container as a whole.
- //
- // TODO(djmurphy,mesch): The case above is not really a surface relationship,
- // because the container is not a surface as such. We could adjust the name
- // accordingly, or use a different type here. Depends on whether all surface
- // relationship types make sense between a module and its container or not,
- // etc.
- SurfaceRelation relationship;
-};
-
-// Specifies one module to start inside a container. The module is specified by
-// a intent as usual. The node_name of the surface is referenced by container
-// layout and by container relation entry.
-struct ContainerNode {
- // Name by which this module is references in layout and surface relationship
- // specifications (cf. above).
- string node_name;
-
- // The intent to resolve to a module.
- Intent intent;
-};
diff --git a/public/fidl/fuchsia.modular/surface/surface.fidl b/public/fidl/fuchsia.modular/surface/surface.fidl
deleted file mode 100644
index 3d10413..0000000
--- a/public/fidl/fuchsia.modular/surface/surface.fidl
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains the definition of SurfaceRelation and its properties.
-
-library fuchsia.modular;
-
-// Describes the relationship between two Surfaces.
-// Provides information to the StoryShell for layout optimization.
-struct SurfaceRelation {
- // Advice on arranging these surfaces on the screen together.
- SurfaceArrangement arrangement = NONE;
-
- // Advice for dismissal of surfaces to be linked.
- SurfaceDependency dependency = NONE;
-
- // Relative emphasis of the child surface, relative to the parent.
- // Influences relative areas of surfaces on screen.
- float32 emphasis = 1.0;
-};
-
-// Expresses arrangement type.
-enum SurfaceArrangement {
- // No arrangement specified.
- NONE = 0;
-
- // Desire to present simultaneously.
- COPRESENT = 1;
-
- // The parent prefers to not be presented simultaneously with its child.
- // (The child may still become part of a simultaneous presentation depending
- // on the relationships between it and subsequently added surfaces).
- SEQUENTIAL = 2;
-
- // Place this surface on top of and obscuring the parent surface. This is a
- // complete replacement, not a modal or inset presentation.
- ONTOP = 3;
-};
-
-// Links surface dismissal.
-enum SurfaceDependency {
- // No dependency specified.
- NONE = 0;
-
- // Child is dependent on parent.
- // If parent is dismissed, child is dismissed as well.
- DEPENDENT = 1;
-};
diff --git a/public/fidl/fuchsia.modular/user_intelligence/intelligence_services.fidl b/public/fidl/fuchsia.modular/user_intelligence/intelligence_services.fidl
deleted file mode 100644
index 4f21fe6..0000000
--- a/public/fidl/fuchsia.modular/user_intelligence/intelligence_services.fidl
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// A container for component-scoped services. This contains any and all
-// services needed by any sort of Module/Agent.
-[Discoverable]
-interface IntelligenceServices {
- // These are just here for illustrative purposes, and are not a complete
- // list.
- 1: GetContextReader(request<ContextReader> context_reader);
- 2: GetContextWriter(request<ContextWriter> context_writer);
-
- 3: GetProposalPublisher(request<ProposalPublisher> proposal_publisher);
-
- 4: RegisterQueryHandler(QueryHandler query_handler);
-};
diff --git a/public/fidl/fuchsia.modular/user_intelligence/scope.fidl b/public/fidl/fuchsia.modular/user_intelligence/scope.fidl
deleted file mode 100644
index 0e4e5b2..0000000
--- a/public/fidl/fuchsia.modular/user_intelligence/scope.fidl
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-// Specifies the access scope a given component has to services within Maxwell.
-//
-// TODO(thatguy): Eventually, replace this with a Fuchsia-level access scope.
-union ComponentScope {
- // Reserved for system-level services.
- GlobalScope global_scope;
- // Scope for a specific Module instance within a specific Story.
- ModuleScope module_scope; // Annoying: can't use "module" (it's reserved)
- // Scope for a specific Agent. Agents are not tied to a specific story.
- AgentScope agent_scope;
- // Scope for a specific Story, potentially containing several Module instances.
- StoryScope story_scope;
-};
-
-struct GlobalScope {
- uint32 dummy; // FIDL does not allow empty structs
-};
-
-struct ModuleScope {
- string url;
- string story_id;
- vector<string> module_path;
-};
-
-struct AgentScope {
- string url;
-};
-
-struct StoryScope {
- string story_id;
-};
diff --git a/public/fidl/fuchsia.modular/user_intelligence/user_intelligence_provider.fidl b/public/fidl/fuchsia.modular/user_intelligence/user_intelligence_provider.fidl
deleted file mode 100644
index 42742f5..0000000
--- a/public/fidl/fuchsia.modular/user_intelligence/user_intelligence_provider.fidl
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.modular;
-
-using fuchsia.speech;
-using fuchsia.sys;
-
-interface UserIntelligenceProvider {
- // Creates an |IntelligenceServices| scoped to a specific Component,
- // identified by |scope|.
- //
- // NOTE: Eventually |component_id| will become more complex, specifying
- // information needed to evaluate access-control policies for downstream
- // services.
- //
- // ANOTHER NOTE: |IntelligenceServices| is a short-term "big bucket" in which
- // to put any and all services that are to be exposed to Agents and Modules.
- // Once our understanding of the needs of Agents/Modules is clearer, we
- // should break the bucket apart.
- 1: GetComponentIntelligenceServices(ComponentScope scope,
- request<IntelligenceServices> services);
-
- 2: GetSuggestionProvider(request<SuggestionProvider> suggestion_provider);
-
- 3: GetSpeechToText(request<fuchsia.speech.SpeechToText> speech_to_text);
-
- // The |ComponentContext| is used to create agents and use message queues.
- 5: StartAgents(ComponentContext user_intelligence_context,
- vector<string> session_agents,
- vector<string> startup_agents);
-
- // A standard set of services provided to all agents at startup,
- // along with services particuarly for this agent.
- 6: GetServicesForAgent(string agent_url)
- -> (fuchsia.sys.ServiceList service_list);
-};
diff --git a/public/fidl/fuchsia.speech/BUILD.gn b/public/fidl/fuchsia.speech/BUILD.gn
deleted file mode 100644
index 93ba134..0000000
--- a/public/fidl/fuchsia.speech/BUILD.gn
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-fidl("fuchsia.speech") {
- cpp_legacy_callbacks = true
-
- sdk_category = "partner"
-
- sources = [
- "speech_to_text.fidl",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.media",
- ]
-}
diff --git a/public/fidl/fuchsia.speech/speech_to_text.fidl b/public/fidl/fuchsia.speech/speech_to_text.fidl
deleted file mode 100644
index 1509261..0000000
--- a/public/fidl/fuchsia.speech/speech_to_text.fidl
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library fuchsia.speech;
-
-[Discoverable]
-interface SpeechToText {
- // Starts capturing speech from the microphone.
- 1: BeginCapture(TranscriptionListener transcription_listener);
-
- // Begins hotword detection. Detected hotword utterances are reported on the
- // given listener.
- 2: ListenForHotword(HotwordListener hotword_listener);
-};
-
-// Represents an active transcription session. Either side may close this
-// interface to indicate that transcription should stop. If the transcription is
-// unexpectedly closed before |OnReady| is called, the implementer should treat
-// it as an error (in such cases, |OnError| is called).
-interface TranscriptionListener {
- // Indicates that capture has begun. Prior to this, parts of the system may
- // not have been initialized and audio may have been dropped. No calls to
- // |OnTranscriptUpdate| will occur before |OnReady| is called.
- 1: OnReady();
-
- // Receives updated transcripts. Each call receives the most likely
- // transcription of the entire utterance at that time. Previously transcribed
- // text may mutate in response to later input.
- 2: OnTranscriptUpdate(string spoken_text);
-
- // Provides periodic updates on the user's speech signal power, when the
- // microphone is open and streaming to the backend.
- // |speech_level| is instantaneous speech power, in decibels (negative).
- 4: OnSpeechLevelUpdate(float32 speech_level);
-
- // An error occurred before or during transcription. Depending on the nature
- // of the error, this may occur before |OnReady| is called, and |OnReady| may
- // never be called. This binding will be closed immediately after sending this
- // message.
- 3: OnError();
-};
-
-// Listens for hotwords. Each detected hotword utterance triggers |OnHotword|.
-// Closure of this handle by the speech service indicates an error.
-interface HotwordListener {
- // Indicates that capture has begun. Prior to this, parts of the system may
- // not have been initialized and audio may have been dropped. No calls to
- // |OnHotword| will occur before |OnReady| is called.
- 1: OnReady();
-
- // Called for each detected hotword utterance.
- 2: OnHotword();
-};
diff --git a/public/lib/BUILD.gn b/public/lib/BUILD.gn
deleted file mode 100644
index 5359c80..0000000
--- a/public/lib/BUILD.gn
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/toolchain.gni")
-
-group("services") {
- deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-group("just_fidl") {
- deps = [
- "//peridot/public/fidl/fuchsia.modular($fidl_toolchain)",
- ]
-}
-
-executable("peridot_public_lib_unittests") {
- testonly = true
-
- deps = [
- "async/cpp:unittests",
- "entity/cpp:unittests",
- "//third_party/googletest:gtest_main",
- ]
-}
diff --git a/public/lib/MAINTAINERS b/public/lib/MAINTAINERS
deleted file mode 100644
index e68679b..0000000
--- a/public/lib/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-mesch@google.com
-thatguy@google.com
diff --git a/public/lib/agent/cpp/BUILD.gn b/public/lib/agent/cpp/BUILD.gn
deleted file mode 100644
index 17a555b..0000000
--- a/public/lib/agent/cpp/BUILD.gn
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-group("cpp") {
- public_deps = [
- ":agent_impl",
- ]
-}
-
-source_set("agent_impl") {
- sources = [
- "agent_impl.cc",
- "agent_impl.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/svc/cpp",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
diff --git a/public/lib/agent/cpp/agent_impl.cc b/public/lib/agent/cpp/agent_impl.cc
deleted file mode 100644
index 5fbd0e1..0000000
--- a/public/lib/agent/cpp/agent_impl.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/agent/cpp/agent_impl.h>
-
-#include <fs/service.h>
-
-namespace modular {
-
-AgentImpl::AgentImpl(component::ServiceNamespace* const service_namespace,
- Delegate* const delegate)
- : delegate_(delegate), binding_(this) {
- service_namespace->AddService<fuchsia::modular::Agent>(
- [this](fidl::InterfaceRequest<fuchsia::modular::Agent> request) {
- binding_.Bind(std::move(request));
- });
-}
-
-AgentImpl::AgentImpl(fbl::RefPtr<fs::PseudoDir> directory,
- Delegate* const delegate)
- : delegate_(delegate), binding_(this) {
- directory->AddEntry(
- fuchsia::modular::Agent::Name_,
- fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
- binding_.Bind(std::move(channel));
- return ZX_OK;
- })));
-}
-
-// |fuchsia::modular::Agent|
-void AgentImpl::Connect(
- std::string requestor_url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services_request) {
- delegate_->Connect(std::move(services_request));
-}
-
-// |fuchsia::modular::Agent|
-void AgentImpl::RunTask(std::string task_id, RunTaskCallback callback) {
- delegate_->RunTask(task_id, callback);
-}
-
-} // namespace modular
diff --git a/public/lib/agent/cpp/agent_impl.h b/public/lib/agent/cpp/agent_impl.h
deleted file mode 100644
index 93bc403..0000000
--- a/public/lib/agent/cpp/agent_impl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_AGENT_CPP_AGENT_IMPL_H_
-#define LIB_AGENT_CPP_AGENT_IMPL_H_
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/macros.h>
-#include <lib/svc/cpp/service_namespace.h>
-
-namespace modular {
-
-// Use this class to talk to the modular framework as an
-// fuchsia::modular::Agent.
-class AgentImpl : public fuchsia::modular::Agent {
- public:
- // Users of AgentImpl register a delegate to receive messages from the
- // framework.
- class Delegate {
- public:
- virtual void Connect(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- outgoing_services) = 0;
- virtual void RunTask(const fidl::StringPtr& task_id,
- const std::function<void()>& done) = 0;
- };
-
- AgentImpl(component::ServiceNamespace* service_namespace, Delegate* delegate);
-
- AgentImpl(fbl::RefPtr<fs::PseudoDir> directory, Delegate* delegate);
-
- private:
- // |fuchsia::modular::Agent|
- void Connect(std::string requestor_url,
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- services_request) override;
- // |fuchsia::modular::Agent|
- void RunTask(std::string task_id, RunTaskCallback callback) override;
-
- Delegate* const delegate_;
- fidl::Binding<fuchsia::modular::Agent> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AgentImpl);
-};
-
-} // namespace modular
-
-#endif // LIB_AGENT_CPP_AGENT_IMPL_H_
diff --git a/public/lib/app_driver/cpp/BUILD.gn b/public/lib/app_driver/cpp/BUILD.gn
deleted file mode 100644
index f52561e..0000000
--- a/public/lib/app_driver/cpp/BUILD.gn
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-group("cpp") {
- public_deps = [
- ":agent_driver",
- ":app_driver",
- ":module_driver",
- ]
-}
-
-source_set("agent_driver") {
- sources = [
- "agent_driver.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/agent/cpp",
- "//peridot/public/lib/lifecycle/cpp",
- ]
-}
-
-source_set("app_driver") {
- sources = [
- "app_driver.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/public/lib/lifecycle/cpp",
- ]
-}
-
-source_set("module_driver") {
- sources = [
- "module_driver.h",
- ]
-
- public_deps = [
- "//garnet/public/fidl/fuchsia.ui.app",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/lifecycle/cpp",
- ]
-}
diff --git a/public/lib/app_driver/cpp/README.md b/public/lib/app_driver/cpp/README.md
deleted file mode 100644
index 74a53cd..0000000
--- a/public/lib/app_driver/cpp/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# AppDriver
-
-App driver is a small framework that supports life cycle management of fidl
-components by implementing the fuchsia::modular::Lifecycle FIDL service.
-
-There are three flavors of app driver: for generic components (AppDriver), for
-components that are run as Modules (ModuleDriver), and for components that are
-run as Agents (AgentDriver). Agents and Modules have additional facets at
-initialization in addition to the asynchronous teardown sequence that fuchsia::modular::Lifecycle
-imposes. See the .h files for details.
-
-
-
diff --git a/public/lib/app_driver/cpp/agent_driver.h b/public/lib/app_driver/cpp/agent_driver.h
deleted file mode 100644
index 884e23e..0000000
--- a/public/lib/app_driver/cpp/agent_driver.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_APP_DRIVER_CPP_AGENT_DRIVER_H_
-#define LIB_APP_DRIVER_CPP_AGENT_DRIVER_H_
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/agent/cpp/agent_impl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/logging.h>
-#include <lib/lifecycle/cpp/lifecycle_impl.h>
-
-namespace modular {
-
-// This interface is passed to the Impl object that AgentDriver initializes.
-class AgentHost {
- public:
- virtual component::StartupContext* startup_context() = 0;
- virtual fuchsia::modular::AgentContext* agent_context() = 0;
-};
-
-// AgentDriver provides a way to write agents and participate in application
-// lifecycle.
-//
-// class HelloAgent {
-// public:
-// HelloAgent(AgentHost* host) {}
-//
-// // Called by AgentDriver.
-// void Connect(fidl::InterfaceRequest<ServiceProvider> outgoing_services) {}
-//
-// // Called by AgentDriver.
-// void RunTask(const fidl::StringPtr& task_id,
-// const std::function<void()>& done) { done(); }
-//
-// // Called by AgentDriver.
-// void Terminate(const std::function<void()>& done) { done(); }
-// };
-//
-// int main(int argc, const char** argv) {
-// async::Loop loop(&kAsyncLoopConfigAttachToThread);
-// auto context = component::StartupContext::CreateFromStartupInfo();
-// modular::AgentDriver<HelloAgent> driver(context.get(),
-// [&loop] { loop.Quit(); });
-// loop.Run();
-// return 0;
-// }
-template <typename Impl>
-class AgentDriver : LifecycleImpl::Delegate, AgentImpl::Delegate, AgentHost {
- public:
- AgentDriver(component::StartupContext* const context,
- std::function<void()> on_terminated)
- : context_(context),
- lifecycle_impl_(context->outgoing().deprecated_services(), this),
- agent_impl_(std::make_unique<AgentImpl>(
- context->outgoing().deprecated_services(),
- static_cast<AgentImpl::Delegate*>(this))),
- on_terminated_(std::move(on_terminated)),
- agent_context_(context_->ConnectToEnvironmentService<
- fuchsia::modular::AgentContext>()),
- impl_(std::make_unique<Impl>(static_cast<AgentHost*>(this))) {}
-
- private:
- // |AgentHost|
- component::StartupContext* startup_context() override { return context_; }
-
- // |AgentHost|
- fuchsia::modular::AgentContext* agent_context() override {
- FXL_DCHECK(agent_context_);
- return agent_context_.get();
- }
-
- // |AgentImpl::Delegate|
- void Connect(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
- outgoing_services_request) override {
- impl_->Connect(std::move(outgoing_services_request));
- };
- // |AgentImpl::Delegate|
- void RunTask(const fidl::StringPtr& task_id,
- const std::function<void()>& done) override {
- impl_->RunTask(task_id, done);
- };
-
- // |LifecycleImpl::Delegate|
- void Terminate() override {
- agent_impl_.reset();
- if (impl_) {
- impl_->Terminate([this] {
- // Cf. AppDriver::Terminate().
- async::PostTask(async_get_default_dispatcher(), [this] {
- impl_.reset();
- on_terminated_();
- });
- });
- } else {
- on_terminated_();
- }
- }
-
- component::StartupContext* const context_;
- LifecycleImpl lifecycle_impl_;
- std::unique_ptr<AgentImpl> agent_impl_;
- std::function<void()> on_terminated_;
- fuchsia::modular::AgentContextPtr agent_context_;
- std::unique_ptr<Impl> impl_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AgentDriver);
-};
-
-} // namespace modular
-
-#endif // LIB_APP_DRIVER_CPP_AGENT_DRIVER_H_
diff --git a/public/lib/app_driver/cpp/app_driver.h b/public/lib/app_driver/cpp/app_driver.h
deleted file mode 100644
index 32b6927..0000000
--- a/public/lib/app_driver/cpp/app_driver.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_APP_DRIVER_CPP_APP_DRIVER_H_
-#define LIB_APP_DRIVER_CPP_APP_DRIVER_H_
-
-#include <functional>
-#include <memory>
-#include <utility>
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/lifecycle/cpp/lifecycle_impl.h>
-
-namespace modular {
-
-// AppDriver is a wrapper that simplifies participating in lifecycle management
-// by the application's parent. It does this by exposing the
-// fuchsia::modular::Lifecycle service in
-// component::StartupContext::outgoing().deprecated_services() and proxies
-// the Terminate() call of fuchsia::modular::Lifecycle to the Terminate() method
-// on your application's class instance.
-//
-// Usage:
-//
-// NOTE: Your application's class must implement:
-//
-// // Called by AppDriver. Call |done| once shutdown sequence is complete
-// // and |this| will be scheduled for deletion on the current MessageLoop.
-// void Terminate(const std::function<void()>& done);
-//
-// Example:
-//
-// class HelloWorldApp {
-// public:
-// HelloWorldApp(component::StartupContext* context) {
-// context->outgoing().AddPublicService<..>(...);
-// }
-//
-// void Terminate(const std::function<void()>& done) {
-// done();
-// }
-// };
-//
-// int main(int argc, const char** argv) {
-// async::Loop loop(&kAsyncLoopConfigAttachToThread);
-// auto context = component::StartupContext::CreateFromStartupInfo();
-// modular::AppDriver<HelloWorldApp> driver(
-// context->outgoing().deprecated_services(),
-// std::make_unique<HelloWorldApp>(context.get()),
-// [&loop] { loop.Quit(); });
-// loop.Run();
-// return 0;
-// }
-template <typename Impl>
-class AppDriver : LifecycleImpl::Delegate {
- public:
- AppDriver(component::ServiceNamespace* const outgoing_services,
- std::unique_ptr<Impl> impl, std::function<void()> on_terminated)
- : lifecycle_impl_(outgoing_services, this),
- impl_(std::move(impl)),
- on_terminated_(std::move(on_terminated)) {}
-
- private:
- // |LifecycleImpl::Delegate|
- void Terminate() override {
- impl_->Terminate([this] {
- // Since this callback is called by |impl_|, we delay destroying it
- // until the current stack rolls back up to the MessageLoop which
- // guarantees impl_::Terminate() and anything that asynchronously
- // invokes this callback are done running.
- async::PostTask(async_get_default_dispatcher(), [this] {
- impl_.reset();
- on_terminated_();
- });
- });
- }
-
- LifecycleImpl lifecycle_impl_;
- std::unique_ptr<Impl> impl_;
- std::function<void()> on_terminated_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(AppDriver);
-};
-
-} // namespace modular
-
-#endif // LIB_APP_DRIVER_CPP_APP_DRIVER_H_
diff --git a/public/lib/app_driver/cpp/module_driver.h b/public/lib/app_driver/cpp/module_driver.h
deleted file mode 100644
index 6431f48..0000000
--- a/public/lib/app_driver/cpp/module_driver.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_APP_DRIVER_CPP_MODULE_DRIVER_H_
-#define LIB_APP_DRIVER_CPP_MODULE_DRIVER_H_
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/app/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/interface_request.h>
-#include <lib/fxl/logging.h>
-#include <lib/lifecycle/cpp/lifecycle_impl.h>
-
-namespace modular {
-
-// This interface is passed to the |Impl| object that ModuleDriver initializes.
-class ModuleHost {
- public:
- virtual component::StartupContext* startup_context() = 0;
- virtual fuchsia::modular::ModuleContext* module_context() = 0;
-};
-
-// ModuleDriver provides a way to write modules and participate in application
-// lifecycle. The |Impl| class supplied to ModuleDriver is instantiated when the
-// Module and ViewProvider services have both been requested by the framework.
-//
-// Usage:
-// The |Impl| class must implement:
-//
-// // A constructor with the following signature:
-// Constructor(
-// modular::ModuleHost* module_host,
-// fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
-// view_provider_request);
-//
-// // Called by ModuleDriver. Call |done| once shutdown sequence is
-// // complete, at which point |this| will be deleted.
-// void Terminate(const std::function<void()>& done);
-//
-// Example:
-//
-// class HelloWorldModule {
-// public:
-// HelloWorldModule(
-// modular::ModuleHost* module_host,
-// fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
-// view_provider_request) {}
-//
-// // Called by ModuleDriver.
-// void Terminate(const std::function<void()>& done) { done(); }
-// };
-//
-// int main(int argc, const char** argv) {
-// async::Loop loop(&kAsyncLoopConfigAttachToThread);
-// auto context = component::StartupContext::CreateFromStartupInfo();
-// modular::ModuleDriver<HelloWorldApp> driver(context.get(),
-// [&loop] { loop.Quit(); });
-// loop.Run();
-// return 0;
-// }
-template <typename Impl>
-class ModuleDriver : LifecycleImpl::Delegate, ModuleHost {
- public:
- ModuleDriver(component::StartupContext* const context,
- std::function<void()> on_terminated)
- : context_(context),
- lifecycle_impl_(context->outgoing().deprecated_services(), this),
- on_terminated_(std::move(on_terminated)) {
- context_->ConnectToEnvironmentService(module_context_.NewRequest());
-
- context_->outgoing().AddPublicService<fuchsia::ui::app::ViewProvider>(
- [this](fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> request) {
- impl_ = std::make_unique<Impl>(static_cast<ModuleHost*>(this),
- std::move(request));
- });
-
- context_->outgoing().AddPublicService<fuchsia::ui::viewsv1::ViewProvider>(
- [this](fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- request) {
- impl_ = std::make_unique<Impl>(static_cast<ModuleHost*>(this),
- std::move(request));
- });
- }
-
- private:
- // |ModuleHost|
- component::StartupContext* startup_context() override { return context_; }
-
- // |ModuleHost|
- fuchsia::modular::ModuleContext* module_context() override {
- FXL_DCHECK(module_context_);
- return module_context_.get();
- }
-
- // |LifecycleImpl::Delegate|
- void Terminate() override {
- // It's possible that we process the |fuchsia::modular::Lifecycle.Terminate|
- // message before the |Module.Initialize| message, even when both messages
- // are ready to be processed at the same time. In this case, because |impl_|
- // hasn't been instantiated yet, we cannot delegate the
- // |fuchsia::modular::Lifecycle.Terminate| message.
- if (impl_) {
- impl_->Terminate([this] {
- // Cf. AppDriver::Terminate().
- async::PostTask(async_get_default_dispatcher(), [this] {
- impl_.reset();
- on_terminated_();
- });
- });
- } else {
- on_terminated_();
- }
- }
-
- component::StartupContext* const context_;
- LifecycleImpl lifecycle_impl_;
- std::function<void()> on_terminated_;
- fuchsia::modular::ModuleContextPtr module_context_;
-
- std::unique_ptr<Impl> impl_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ModuleDriver);
-};
-
-} // namespace modular
-
-#endif // LIB_APP_DRIVER_CPP_MODULE_DRIVER_H_
diff --git a/public/lib/async/cpp/BUILD.gn b/public/lib/async/cpp/BUILD.gn
deleted file mode 100644
index c579ff5..0000000
--- a/public/lib/async/cpp/BUILD.gn
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("future") {
- sources = [
- "future.cc",
- "future.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//zircon/public/lib/async-cpp",
- "//zircon/public/lib/async-default",
- ]
-}
-
-source_set("operation") {
- sources = [
- "operation.cc",
- "operation.h",
- ]
-
- public_deps = [
- ":future",
- "//garnet/public/lib/async_promise",
- "//garnet/public/lib/fxl",
- ]
-
- deps = [
- "//zircon/public/lib/trace",
- ]
-}
-
-group("unittests") {
- testonly = true
-
- deps = [
- ":future_unittest",
- ":operation_unittest",
- ]
-}
-
-source_set("future_unittest") {
- testonly = true
-
- sources = [
- "future_unittest.cc",
- ]
-
- deps = [
- ":future",
- "//third_party/googletest:gtest",
- "//zircon/public/lib/async-testutils",
- ]
-}
-
-source_set("operation_unittest") {
- testonly = true
-
- sources = [
- "operation_unittest.cc",
- ]
-
- deps = [
- ":operation",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/gtest",
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/public/lib/async/cpp/future.cc b/public/lib/async/cpp/future.cc
deleted file mode 100644
index 385b047..0000000
--- a/public/lib/async/cpp/future.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/async/cpp/future.h>
-
-namespace modular {
-
-namespace internal {
-
-ResultCollector<Future<>>::ResultCollector(size_t reserved_count)
- : reserved_count_(reserved_count) {}
-
-bool ResultCollector<Future<>>::IsComplete() const {
- return finished_count_ == reserved_count_;
-}
-
-void ResultCollector<Future<>>::Complete(Future<>* future) const {
- future->Complete();
-}
-
-} // namespace internal
-
-} // namespace modular
\ No newline at end of file
diff --git a/public/lib/async/cpp/future.h b/public/lib/async/cpp/future.h
deleted file mode 100644
index 449751f..0000000
--- a/public/lib/async/cpp/future.h
+++ /dev/null
@@ -1,1053 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_ASYNC_CPP_FUTURE_H_
-#define LIB_ASYNC_CPP_FUTURE_H_
-
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-
-#include "garnet/public/lib/fxl/functional/apply.h"
-#include "garnet/public/lib/fxl/macros.h"
-#include "garnet/public/lib/fxl/memory/ref_counted.h"
-#include "garnet/public/lib/fxl/memory/ref_ptr.h"
-#include "garnet/public/lib/fxl/memory/weak_ptr.h"
-
-namespace modular {
-
-// # Futures
-//
-// A *future* is an object representing the eventual value of an asynchronous
-// operation. They are a useful complement to callback functions or lambdas
-// because they are _composable_: asynchronous operations can be sequentially
-// executed, and an async operation's result can be passed to another async
-// operation, like a Unix pipeline.
-//
-// To use a future:
-//
-// 1. A *producer*, typically an async operation, creates a Future with
-// Future<ResultType>::Create().
-// 2. The producer starts its async operation (e.g. a network request or disk
-// read).
-// 3. The producer synchronously returns the Future to a *consumer*.
-// 4. A consumer attaches a *callback* lambda to the Future using Then(). (The
-// callback can be attached to the future any time after the future is
-// created, before or after the async operation is finished.)
-// 5. Some time later, when the producer's async operation is finished, the
-// producer *completes* the future with a *result* using Complete(result).
-// |result| is 0 to N movable or copyable values, e.g. Complete(),
-// Complete(value), Complete(value1, value2, ...).
-// 6. The consumer's callback is invoked after the future is completed, with the
-// completed result passed as zero or more parameters to the callback.
-//
-// The following example shows a simple use case:
-//
-// Producer:
-//
-// FuturePtr<Bytes> MakeNetworkRequest(NetworkRequest& request) {
-// auto f = Future<Bytes>::Create("NetworkRequest"); // a "trace_name" that's
-// // logged when things go
-// // wrong
-// auto network_request_callback = [f] (Bytes bytes) {
-// f->Complete(bytes);
-// };
-// PerformAsyncNetworkRequest(request, network_request_callback);
-// return f;
-// }
-//
-// Client:
-//
-// FuturePtr<Bytes> f = MakeNetworkRequest();
-// f->Then([] (Bytes bytes) {
-// ProcessBytes(bytes);
-// });
-//
-// ## Chaining and sequencing futures
-//
-// Futures can be composed; this is commonly called "chaining". Methods that
-// attach callbacks, such as Then(), will return another Future: the returned
-// Future is completed once the previous callback has finished executing. For
-// example:
-//
-// Client:
-//
-// ShowProgressSpinner(true);
-// FuturePtr<Bytes> f = MakeNetworkRequest(request);
-// f->AsyncMap([] (Bytes zipped_bytes) {
-// // Use AsyncMap() if your callback wants to return another Future.
-// FuturePtr<Bytes> f = UnzipInBackground(zipped_bytes);
-// return f;
-// })->Map([] (Bytes unzipped_bytes) {
-// // Use Map() if your callback returns a non-future: the callback's return
-// // value will be wrapped up into the returned Future.
-// JPEGImage image = DecodeImageSynchronously(unzipped_bytes);
-// return image;
-// })->AsyncMap([] (JPEGImage image) {
-// FuturePtr<> f = UpdateUIAsynchronously(image);
-// return f;
-// })->Then([] {
-// // Use Then() if your callback returns void. Note that Then() still returns
-// // a Future<>, which will be completed only when your callback finishes
-// // executing.
-// ShowProgressSpinner(false);
-// });
-//
-// ## Memory Management & Ownership
-//
-// FuturePtr is a fxl::RefPtr, which is a smart pointer similar to
-// std::shared_ptr that holds a reference count (refcount). When you call
-// Future::Create(), you are expected to maintain a reference to it. When the
-// Future is deleted, its result and callbacks are also deleted.
-//
-// Each method documents how it affects the future's refcount. To summarize:
-//
-// * Calling Then() on a future does not affect its refcount. This applies to
-// all methods that returns a chained future, such as AsyncMap() and Map().
-// * However, calling Then() on a future will cause that future to maintain a
-// reference to the returned chained future. So, you do not need to maintain a
-// reference to the returned future.
-// * Calling Complete() does not affect the future's refcount.
-// * Unlike Complete(), the closure returned by Completer() _does own_ the
-// future, so you do not need to maintain a reference to the future after
-// calling Completer(). (You do need to maintain a reference to the closure,
-// however.)
-// * Wait(futures) returns a future that every future in |futures| owns, so you
-// do not need to maintain a reference to the returned future. The callback
-// attached to each future in |futures| will also keep a reference to
-// themselves, so that if a future that is Wait()ed on otherwise goes out of
-// scope, the future itself is kept alive.
-//
-// See each method's documentation for more details on memory management.
-//
-// ## Use Weak*() variants to cancel callback chains
-//
-// "Weak" variants exist for all chain/sequence methods (WeakThen(),
-// WeakConstThen(), WeakMap() and WeakAsyncMap()). These are almost identical
-// to their non-weak counterparts but take an fxl::WeakPtr<T> as a first
-// argument. If, at callback invocation time, the WeakPtr is invalid, execution
-// will halt and no future further down the chain will be executed.
-//
-// Example:
-//
-// FuturePtr<> f = MakeFuture();
-// f->WeakThen(weak_ptr_factory.GetWeakPtr(), [] {
-// FXL_LOG(INFO) << "This won't execute";
-// })->Then([] {
-// FXL_LOG(INFO) << "Neither will this";
-// });
-// weak_ptr_factory.InvalidateWeakPtrs();
-// f->Complete();
-//
-// ## Use Wait() to synchronize on multiple futures
-//
-// If multiple futures are running, use the Wait() function to create a
-// Future that completes when all the futures passed to it are completed:
-//
-// FuturePtr<Bytes> f1 = MakeNetworkRequest(request1);
-// FuturePtr<Bytes> f2 = MakeNetworkRequest(request2);
-// FuturePtr<Bytes> f3 = MakeNetworkRequest(request3);
-// Wait<Future<>>("Network requests", {f1, f2, f3})->Then([] {
-// AllNetworkRequestsAreComplete();
-// });
-//
-// See the Wait() function documentation for more details.
-//
-// ## Use Completer() to integrate with functions requiring callbacks
-//
-// Use the Completer() method to integrate with existing code that uses callback
-// functions. Completer() returns an std::function<void(Result)> that, when
-// called, calls Complete() on the future. Re-visiting the first example:
-//
-// Without Completer():
-//
-// FuturePtr<Bytes> MakeNetworkRequest(NetworkRequest& request) {
-// auto f = Future<Bytes>::Create("NetworkRequest");
-// auto network_request_callback = [f] (Bytes bytes) {
-// f->Complete(bytes);
-// };
-// PerformAsyncNetworkRequest(request, network_request_callback);
-// return f;
-// }
-//
-// With Completer():
-//
-// FuturePtr<Bytes> MakeNetworkRequest(NetworkRequest& request) {
-// auto f = Future<Bytes>::Create("NetworkRequest");
-// PerformAsyncNetworkRequest(request, f->Completer());
-// return f;
-// }
-//
-// ## Use error values to propagate errors back to consumers
-//
-// If the future can fail, use a value (or multiple values) that's capable of
-// storing both the error and a successful result to propagate the return value
-// back to the consumer. For example:
-//
-// FuturePtr<std::error_code, Bytes> f = MakeNetworkRequest();
-// f->Then([] (std::error_code error, Bytes bytes) {
-// if (error) {
-// // handle error
-// } else {
-// // network request was successful
-// ProcessBytes(bytes);
-// }
-// });
-//
-// ## fuchsia::modular::Future vs other Futures/Promises
-//
-// If you are familiar with Futures & Promises in other languages, this Future
-// class is intentionally different from others, to better integrate with
-// Fuchsia coding patterns:
-//
-// * NOT THREADSAFE. This will change in the future when thread safety is
-// required, but there are no use cases yet. (YAGNI!)
-// * Support for multiple result values via variadic template parameters. This
-// is required for smooth integration with the fuchsia::modular::Operation
-// class.
-// * Only a single callback can be set via Then(), since move semantics are used
-// so heavily in Fuchsia code. (If multiple callbacks were supported and the
-// result is moved, how does one move the result from one callback to
-// another?)
-// * Multiple callbacks can be set if the callback lambda takes the result via
-// const&. In this case, use ConstThen() to attach each callback, rather
-// than Then(). ConstThen() calls can also be chained, like Then().
-// * There are no success/error callbacks and control flows: all callbacks are
-// "success callbacks".
-// * The traditional reason for error callbacks is to convert exceptions into
-// error values, but Google C++ style doesn't use exceptions, so error
-// callbacks aren't needed.
-// * There's some argument that using separate success/error control flow
-// paths is beneficial. However, in practice, a lot of client code using
-// this pattern don't attach error callbacks, only success callbacks, so
-// errors often go unchecked.
-// * If error values need to be propagated back to the client, use a dedicated
-// error type. (Note that many built-in types may have values that can be
-// interpreted as errors, e.g. nullptr, or 0 or -1.) This also forces a
-// consumer to inspect the type and check for errors.
-// * No cancellation/progress support. Adding cancellation/progress:
-// * adds more complexity to the futures implementation,
-// * can be implemented on top of a core futures implementation for the few
-// cases where they're required, and
-// * typically requires extra cancel/progress callbacks, which adds more
-// control flow paths.
-// * see fxl::CancelableCallback if you need cancellation.
-// * No execution contexts (yet).
-// * There needs to be a comprehensive story about runloops etc first.
-
-template <typename... Result>
-class Future;
-
-template <typename... Result>
-using FuturePtr = fxl::RefPtr<Future<Result...>>;
-
-namespace internal {
-
-enum class FutureStatus {
- kAwaiting, // not completed
- kCompleted, // value available, not yet moved into callback
- kConsumed // value moved into callback
-};
-
-// type_traits functions, ported from C++17.
-template <typename From, typename To>
-constexpr bool is_convertible_v = std::is_convertible<From, To>::value;
-
-template <class T>
-constexpr bool is_void_v = std::is_void<T>::value;
-
-template <typename... Result>
-class DefaultResultsFuture {
- public:
- using type = Future<std::vector<std::tuple<Result...>>>;
-};
-
-template <typename Result>
-class DefaultResultsFuture<Result> {
- public:
- using type = Future<std::vector<Result>>;
-};
-
-template <>
-class DefaultResultsFuture<> {
- public:
- using type = Future<>;
-};
-
-template <typename... Result>
-using DefaultResultsFuture_t = typename DefaultResultsFuture<Result...>::type;
-
-template <typename ResultsFuture>
-class ResultCollector {
- public:
- // ResultsFuture = Future<std::vector<ElementType>>
- using ElementType = typename std::tuple_element_t<
- 0, typename ResultsFuture::result_tuple_type>::value_type;
-
- ResultCollector(size_t reserved_count) : results_(reserved_count) {}
-
- bool IsComplete() const { return finished_count_ == results_.size(); }
-
- template <typename... Result>
- void AssignResult(size_t result_index, Result&&... result) {
- results_[result_index] =
- std::make_unique<ElementType>(std::forward<Result>(result)...);
- finished_count_++;
- }
-
- void Complete(ResultsFuture* future) {
- std::vector<ElementType> final_results;
- final_results.reserve(results_.size());
- for (auto& result : results_) {
- final_results.push_back(std::move(*result));
- }
- future->Complete(std::move(final_results));
- }
-
- private:
- size_t finished_count_ = 0;
- // Use unique ptrs initially so that we can reserve even if |ElementType| is
- // not default-constructible.
- //
- // TODO(rosswang): Consider adding a specialization for default-constructible
- // types.
- std::vector<std::unique_ptr<ElementType>> results_;
-};
-
-template <>
-class ResultCollector<Future<>> {
- public:
- ResultCollector(size_t reserved_count);
- bool IsComplete() const;
-
- // The template on this allows us to use Future<> collectors to swallow
- // unneeded results of futures we're waiting on.
- template <typename... Result>
- void AssignResult(size_t, Result... result) {
- finished_count_++;
- }
-
- void Complete(Future<>* future) const;
-
- private:
- size_t finished_count_ = 0;
- size_t reserved_count_;
-};
-
-} // namespace internal
-
-template <typename... Result>
-class Future : public fxl::RefCountedThreadSafe<Future<Result...>> {
- public:
- using result_tuple_type = std::tuple<Result...>;
-
- // Creates a FuturePtr<Result...>. |trace_name| is used solely for debugging
- // purposes, and is logged when something goes wrong (e.g. Complete() is
- // called twice.)
- static FuturePtr<Result...> Create(const std::string& trace_name) {
- auto f = fxl::AdoptRef(new Future<Result...>);
- f->trace_name_ = std::move(trace_name);
- return f;
- }
-
- // Creates a FuturePtr<Result...> that's already completed. For example:
- //
- // FuturePtr<int> f = Future<int>::CreateCompleted("MyFuture", 5);
- // f->Then([] (int i) {
- // // this lambda executes immediately
- // assert(i == 5);
- // });
- static FuturePtr<Result...> CreateCompleted(const std::string& trace_name,
- Result&&... result) {
- auto f = Create(std::move(trace_name));
- f->Complete(std::forward<Result>(result)...);
- return f;
- }
-
- // Completes a future with |result|. This causes any callbacks registered
- // with Then(), ConstThen(), etc to be invoked with |result| passed to them
- // as a parameter.
- //
- // Calling Complete() does not affect this future's refcount. This is because:
- //
- // 1. Any callbacks that are registered are called immediately and
- // synchronously, so the future's lifetime does not need to be extended
- // before callbacks are invoked.
- // 2. Then() correctly handles cases where the future may be deleted by their
- // callbacks.
- // 3. There is no danger of the future being deleted before Complete() is
- // called, because if Complete() is called, the code that calls Complete()
- // must have a reference to the future.
- void Complete(Result&&... result) {
- CompleteWithTuple(std::forward_as_tuple(std::forward<Result>(result)...));
- }
-
- // Returns a std::function<void(Result)> that, when called, calls Complete()
- // on this future. For example:
- //
- // FuturePtr<Bytes> MakeNetworkRequest(NetworkRequest& request) {
- // auto f = Future<Bytes>::Create();
- // PerformAsyncNetworkRequest(request, f->Completer());
- // return f;
- // }
- //
- // The returned closure will maintain a reference to the future, so that the
- // closure can call Complete() on it correctly later. In other words, calling
- // Completer() will increase this future's refcount, and you do not need to
- // maintain a reference to it. After the closure is called, the future's
- // refcount will drop by 1. This enables you to write code like
- //
- // {
- // auto f = Future<>::Create();
- // CallAsyncMethod(f->Completer());
- // // f will now go out of scope, but f->Completer() owns it, so it's
- // // still kept alive.
- // }
- std::function<void(Result...)> Completer() {
- return [shared_this = FuturePtr<Result...>(this)](Result&&... result) {
- shared_this->Complete(std::forward<Result>(result)...);
- };
- }
-
- // Attaches a |callback| that is invoked when the future is completed with
- // Complete(), and returns a Future that is complete once |callback| has
- // finished executing.
- //
- // * The callback is invoked immediately (synchronously); it is not scheduled
- // on the event loop.
- // * The callback is invoked on the same thread as the code that calls
- // Complete().
- // * Only one callback can be attached: any callback that was previously
- // attached with Then() is discarded.
- // * |callback| is called after callbacks attached with ConstThen().
- // * It is safe for |callback| to delete the future that Then() is invoked on.
- // If this occurs, any chained futures returned by Then(), Map() etc will be
- // de-referenced by this future and not be completed, even if a reference to
- // the chained future is maintained elsewhere.
- // * It is also safe for |callback| to delete the chained future that Then()
- // returns.
- // * The future returned by Then() will be owned by this future, so you do not
- // need to maintain a reference to it.
- //
- // The type of this function looks complex, but is basically:
- //
- // FuturePtr<> Then(std::function<void(Result...)> callback);
- template <typename Callback,
- typename = typename std::enable_if_t<
- internal::is_void_v<std::result_of_t<Callback(Result...)>>>>
- FuturePtr<> Then(Callback callback) {
- return SubfutureCreate(
- Future<>::Create(trace_name_ + "(Then)"),
- SubfutureVoidCallback<Result...>(std::move(callback)),
- SubfutureCompleter<>(), [] { return true; });
- }
-
- // Equivalent to Then(), but guards execution of |callback| with a WeakPtr.
- // If, at the time |callback| is to be executed, |weak_ptr| has been
- // invalidated, |callback| is not run, nor is the next Future in the chain
- // completed.
- template <typename Callback, typename T,
- typename = typename std::enable_if_t<
- internal::is_void_v<std::result_of_t<Callback(Result...)>>>>
- FuturePtr<> WeakThen(fxl::WeakPtr<T> weak_ptr, Callback callback) {
- return SubfutureCreate(
- Future<>::Create(trace_name_ + "(WeakThen)"),
- SubfutureVoidCallback<Result...>(std::move(callback)),
- SubfutureCompleter<>(), [weak_ptr] { return !!weak_ptr; });
- }
-
- // Similar to Then(), except that:
- //
- // * |const_callback| must take in the completed result via a const&,
- // * multiple callbacks can be attached,
- // * |const_callback| is called _before_ the Then() callback.
- FuturePtr<> ConstThen(std::function<void(const Result&...)> const_callback) {
- FuturePtr<> subfuture = Future<>::Create(trace_name_ + "(ConstThen)");
- AddConstCallback(SubfutureCallback<const Result&...>(
- subfuture,
- SubfutureVoidCallback<const Result&...>(std::move(const_callback)),
- SubfutureCompleter<>(), [] { return true; }));
- return subfuture;
- }
-
- // See WeakThen().
- template <typename T>
- FuturePtr<> WeakConstThen(
- fxl::WeakPtr<T> weak_ptr,
- std::function<void(const Result&...)> const_callback) {
- FuturePtr<> subfuture = Future<>::Create(trace_name_ + "(WeakConstThen)");
- AddConstCallback(SubfutureCallback<const Result&...>(
- subfuture,
- SubfutureVoidCallback<const Result&...>(std::move(const_callback)),
- SubfutureCompleter<>(), [weak_ptr] { return !!weak_ptr; }));
- return subfuture;
- }
-
- // Attaches a |callback| that is invoked when this future is completed with
- // Complete(). |callback| must return another future: when the returned future
- // completes, the future returned by AsyncMap() will complete. For example:
- //
- // ShowProgressSpinner(true);
- // FuturePtr<Bytes> f = MakeNetworkRequest(request);
- // f->AsyncMap([] (Bytes zipped_bytes) {
- // FuturePtr<Bytes> f = UnzipInBackground(zipped_bytes);
- // return f;
- // })->AsyncMap([] (Bytes unzipped_bytes) {
- // FuturePtr<JPEGImage> f = DecodeImageInBackground(unzipped_bytes);
- // return f;
- // })->AsyncMap([] (JPEGImage image) {
- // FuturePtr<> f = UpdateUIAsynchronously(image);
- // return f;
- // })->Then([] {
- // ShowProgressSpinner(false);
- // });
- //
- // The type of this method looks terrifying, but is basically:
- //
- // FuturePtr<CallbackResult>
- // AsyncMap(std::function<FuturePtr<CallbackResult>(Result...)> callback);
- template <typename Callback,
- typename AsyncMapResult = std::result_of_t<Callback(Result...)>,
- typename MapResult =
- typename AsyncMapResult::element_type::result_tuple_type,
- typename = typename std::enable_if_t<internal::is_convertible_v<
- FuturePtr<MapResult>, AsyncMapResult>>>
- AsyncMapResult AsyncMap(Callback callback) {
- return SubfutureCreate(
- AsyncMapResult::element_type::Create(trace_name_ + "(AsyncMap)"),
- std::move(callback), SubfutureAsyncMapCompleter<AsyncMapResult>(),
- [] { return true; });
- }
-
- template <typename Callback, typename T,
- typename AsyncMapResult = std::result_of_t<Callback(Result...)>,
- typename MapResult =
- typename AsyncMapResult::element_type::result_tuple_type,
- typename = typename std::enable_if_t<internal::is_convertible_v<
- FuturePtr<MapResult>, AsyncMapResult>>>
- AsyncMapResult WeakAsyncMap(fxl::WeakPtr<T> weak_ptr, Callback callback) {
- return SubfutureCreate(
- AsyncMapResult::element_type::Create(trace_name_ + "(WeakAsyncMap)"),
- std::move(callback), SubfutureAsyncMapCompleter<AsyncMapResult>(),
- [weak_ptr] { return !!weak_ptr; });
- }
-
- // Attaches a |callback| that is invoked when this future is completed with
- // Complete(). The returned future is completed with |callback|'s return
- // value, when |callback| finishes executing. Returned tuples are flattened
- // into variadic futures.
- //
- // To return a future that produces a tuple (uncommon), wrap the map result
- // in another tuple (or use |AsyncMap|).
- //
- // That is:
- // Callback return type | Returned future
- // ----------------------------------+----------------
- // T | FuturePtr<T>
- // std::tuple<T, U, ...> | FuturePtr<T, U, ...>
- // std::tuple<std::tuple<T, U, ...>> | FuturePtr<std::tuple<T, U, ...>>
- template <typename Callback,
- typename MapResult = std::result_of_t<Callback(Result...)>>
- auto Map(Callback callback) {
- return Map(std::move(callback), Tag<MapResult>{});
- }
-
- template <typename Callback, typename T,
- typename MapResult = std::result_of_t<Callback(Result...)>>
- FuturePtr<MapResult> WeakMap(fxl::WeakPtr<T> weak_ptr, Callback callback) {
- return SubfutureCreate(Future<MapResult>::Create(trace_name_ + "(WeakMap)"),
- std::move(callback), SubfutureCompleter<MapResult>(),
- [weak_ptr] { return !!weak_ptr; });
- }
-
- const std::string& trace_name() const { return trace_name_; }
-
- private:
- template <typename... Args>
- friend class Future;
-
- // This is a utility class used as a template parameter to determine function
- // overloading; see
- // <https://www.boost.org/community/generic_programming.html#tag_dispatching>
- // for more info.
- //
- // It is used in the |Map| overloads to "specialize" for |std::tuple| and
- // capture its parameter pack.
- template <typename T>
- class Tag {};
-
- template <typename ResultsFuture, typename... Args>
- friend fxl::RefPtr<ResultsFuture> Wait(
- const std::string& trace_name,
- const std::vector<FuturePtr<Args...>>& futures);
-
- template <typename ResultsFuture, typename TimeoutCallback, typename... Args>
- friend fxl::RefPtr<ResultsFuture> WaitWithTimeout(
- const std::string& trace_name, async_dispatcher_t* dispatcher,
- zx::duration timeout, TimeoutCallback on_timeout,
- const std::vector<FuturePtr<Args...>>& futures);
-
- FRIEND_REF_COUNTED_THREAD_SAFE(Future);
-
- Future() : result_{}, weak_factory_(this) {}
-
- void SetCallback(std::function<void(Result...)>&& callback) {
- callback_ = callback;
-
- MaybeInvokeCallbacks();
- }
-
- void SetCallbackWithTuple(
- std::function<void(std::tuple<Result...>)>&& callback) {
- SetCallback([callback](Result&&... result) {
- callback(std::forward_as_tuple(std::forward<Result>(result)...));
- });
- }
-
- void AddConstCallback(std::function<void(const Result&...)>&& callback) {
- if (!callback) {
- return;
- }
-
- // It's impossible to add a const callback after a future is completed
- // *and* it has a callback: the completed value will be moved into the
- // callback and won't be available for a ConstThen().
- if (status_ == internal::FutureStatus::kConsumed) {
- FXL_LOG(FATAL)
- << "Future@" << static_cast<void*>(this)
- << (trace_name_.length() ? "(" + trace_name_ + ")" : "")
- << ": Cannot add a const callback after completed result is "
- "already moved into Then() callback.";
- }
-
- const_callbacks_.emplace_back(callback);
-
- MaybeInvokeCallbacks();
- }
-
- void CompleteWithTuple(std::tuple<Result...>&& result) {
- FXL_DCHECK(status_ == internal::FutureStatus::kAwaiting)
- << "Future@" << static_cast<void*>(this)
- << (trace_name_.length() ? "(" + trace_name_ + ")" : "")
- << ": Complete() called twice.";
-
- result_ = std::forward<std::tuple<Result...>>(result);
- status_ = internal::FutureStatus::kCompleted;
-
- MaybeInvokeCallbacks();
- }
-
- void MaybeInvokeCallbacks() {
- if (status_ == internal::FutureStatus::kAwaiting) {
- return;
- }
-
- if (const_callbacks_.size()) {
- // Move |const_callbacks_| to a local variable. MaybeInvokeCallbacks()
- // can be called multiple times if the client only uses ConstThen() or
- // WeakConstThen() to fetch the completed values. This prevents calling
- // these callbacks multiple times by moving them out of the members
- // scope.
- auto local_const_callbacks = std::move(const_callbacks_);
- for (auto& const_callback : local_const_callbacks) {
- fxl::Apply(const_callback, result_);
- }
- }
-
- if (callback_) {
- auto callback = std::move(callback_);
- status_ = internal::FutureStatus::kConsumed;
- fxl::Apply(callback, std::move(result_));
- }
- }
-
- // The "subfuture" methods below are private helper functions designed to be
- // used with the futures that are returned by the public API (Then(), Map(),
- // etc); those returned futures are named "subfutures" in the code, which is
- // why the methods are named likewise.
-
- // A convenience method to call this->SetCallback() with the lambda returned
- // by SubfutureCallback().
- template <typename Subfuture, typename SubfutureCompleter, typename Callback,
- typename Guard>
- Subfuture SubfutureCreate(Subfuture subfuture, Callback&& callback,
- SubfutureCompleter&& subfuture_completer,
- Guard&& guard) {
- SetCallback(SubfutureCallback<Result...>(subfuture, callback,
- subfuture_completer, guard));
- return subfuture;
- }
-
- // Returns a lambda that:
- //
- // 1. calls |guard| before calling |callback|, and only calls |callback| if
- // |guard| returns true;
- // 2. will not call |subfuture_completer| if either |this| or |subfuture| are
- // destroyed by |callback|.
- template <typename... CoercedResult, typename Subfuture,
- typename SubfutureCompleter, typename Callback, typename Guard>
- auto SubfutureCallback(Subfuture subfuture, Callback&& callback,
- SubfutureCompleter&& subfuture_completer,
- Guard&& guard) {
- return [this, subfuture, callback, subfuture_completer,
- guard](CoercedResult&&... result) {
- if (!guard())
- return;
-
- auto weak_future = weak_factory_.GetWeakPtr();
- auto weak_subfuture = subfuture->weak_factory_.GetWeakPtr();
- auto subfuture_result = callback(std::forward<CoercedResult>(result)...);
-
- // |callback| above may delete this future or the returned subfuture when
- // it finishes executing, so check if |weak_future| and |weak_subfuture|
- // are still valid before attempting to complete the subfuture.
- if (weak_future && weak_subfuture)
- subfuture_completer(subfuture, std::move(subfuture_result));
- };
- }
-
- // Returns a lambda that calls |callback|, and returns an empty tuple. The
- // consistent return type enables generic programming techniques to be
- // applied to |callback| since the return type is consistent (it's always a
- // |std::tuple<T...>|).
- template <typename... CoercedResult, typename Callback>
- auto SubfutureVoidCallback(Callback&& callback) {
- return [callback](CoercedResult&&... result) {
- callback(std::forward<CoercedResult>(result)...);
- return std::make_tuple();
- };
- }
-
- // Returns a lambda that, when called with a subfuture and a std::tuple, will
- // complete the subfuture with the values from the tuple elements. This method
- // is designed to be used with SubfutureAsyncMapCompleter(), which will do
- // the same thing but can be passed Futures for the std::tuple values.
- // Together, this enables generic programming techniques to be applied to the
- // returned lambda, since the lambda presents a consistent API for callers.
- template <typename... SubfutureResult>
- auto SubfutureCompleter() {
- return [](FuturePtr<SubfutureResult...> subfuture,
- std::tuple<SubfutureResult...> subfuture_result) {
- subfuture->CompleteWithTuple(std::move(subfuture_result));
- };
- }
-
- // See the documentation for SubfutureCompleter() above.
- template <typename AsyncMapResult>
- auto SubfutureAsyncMapCompleter() {
- return [](AsyncMapResult subfuture,
- std::tuple<AsyncMapResult> subfuture_result) {
- std::get<0>(subfuture_result)
- ->SetCallbackWithTuple(
- [subfuture](
- std::tuple<
- typename AsyncMapResult::element_type::result_tuple_type>
- transformed_result) {
- subfuture->CompleteWithTuple(
- std::move(std::get<0>(transformed_result)));
- });
- };
- }
-
- // The following overloads enable |Map| to flatten out functions that map to
- // |std::tuple|.
-
- template <typename Callback, typename MapResult>
- FuturePtr<MapResult> Map(Callback callback, Tag<MapResult>) {
- // Directly passing |callback| like this ends up relying on an implicit
- // |std::tuple| memberwise constructor, which should be fine. It will
- // convert from |MapResult| to |std::tuple<MapResult>| implicitly.
- return Map(std::move(callback), Tag<std::tuple<MapResult>>{});
- }
-
- template <typename Callback, typename... MapResult>
- FuturePtr<MapResult...> Map(Callback callback,
- Tag<std::tuple<MapResult...>>) {
- return SubfutureCreate(Future<MapResult...>::Create(trace_name_ + "(Map)"),
- std::move(callback),
- SubfutureCompleter<MapResult...>(),
- [] { return true; });
- }
-
- std::string trace_name_;
-
- internal::FutureStatus status_ = internal::FutureStatus::kAwaiting;
- std::tuple<Result...> result_;
-
- // TODO(MI4-1102): Convert std::function to fit::function here & everywhere.
-
- // The callback attached to this future.
- std::function<void(Result...)> callback_;
-
- // Callbacks that have attached with the Const*() methods, such as
- // ConstThen().
- std::vector<std::function<void(const Result&...)>> const_callbacks_;
-
- // Keep this last in the list of members. (See WeakPtrFactory documentation
- // for more info.)
- fxl::WeakPtrFactory<Future<Result...>> weak_factory_;
-
- FXL_DISALLOW_COPY_ASSIGN_AND_MOVE(Future);
-
- // For unit tests only.
- friend class FutureTest;
-
- // For unit tests only.
- const std::tuple<Result...>& get() const {
- FXL_DCHECK(status_ != internal::FutureStatus::kAwaiting)
- << trace_name_ << ": get() called on unset future";
-
- return result_;
- }
-};
-
-// Returns a Future that completes when every future in |futures| is complete.
-// The future returned by Wait() will be kept alive until every future in
-// |futures| either completes or is destroyed. If any future in |futures| is
-// destroyed prior to completing, the returned future will never complete. The
-// order of the results corresponds to the order of the given futures,
-// regardless of their completion order.
-//
-// The default type of the resulting future depends on the types of the
-// component futures. Void futures produce a void future. Monadic futures
-// produce a future of a flat vector. Polyadic futures produce a future of a
-// vector of tuples. That is:
-//
-// Components | Result
-// -------------------+--------------------------------------------
-// FuturePtr<> | FuturePtr<>
-// FuturePtr<T> | FuturePtr<std::vector<T>>
-// FuturePtr<T, U...> | FuturePtr<std::vector<std::tuple<T, U...>>>
-//
-// These defaults may be overridden by specifying the template argument for
-// Wait as the type of future desired. All cases may produce a Future<> or a
-// Future<std::vector<std::tuple<...>>>.
-//
-// Example usage:
-//
-// FuturePtr<Bytes> f1 = MakeNetworkRequest(request1);
-// FuturePtr<Bytes> f2 = MakeNetworkRequest(request2);
-// FuturePtr<Bytes> f3 = MakeNetworkRequest(request3);
-// std::vector<FuturePtr<Bytes>> requests{f1, f2, f3};
-// Wait("NetworkRequests", requests)->Then([](
-// std::vector<Bytes> bytes_vector) {
-// Bytes f1_bytes = bytes_vector[0];
-// Bytes f2_bytes = bytes_vector[1];
-// Bytes f3_bytes = bytes_vector[2];
-// });
-//
-// This is similar to Promise.All() in JavaScript, or Join() in Rust.
-template <typename ResultsFuture, typename... Result>
-fxl::RefPtr<ResultsFuture> Wait(
- const std::string& trace_name,
- const std::vector<FuturePtr<Result...>>& futures) {
- if (futures.empty()) {
- auto immediate = ResultsFuture::Create(trace_name + "(Completed)");
- immediate->CompleteWithTuple({});
- return immediate;
- }
-
- auto results = std::make_shared<internal::ResultCollector<ResultsFuture>>(
- futures.size());
-
- fxl::RefPtr<ResultsFuture> all_futures_completed =
- ResultsFuture::Create(trace_name + "(WillWait)");
-
- for (size_t i = 0; i < futures.size(); i++) {
- const auto& future = futures[i];
- future->SetCallback(
- [i, all_futures_completed, results](Result&&... result) {
- results->AssignResult(i, std::forward<Result>(result)...);
-
- if (results->IsComplete()) {
- results->Complete(all_futures_completed.get());
- }
- });
- }
-
- return all_futures_completed;
-}
-
-// Like |Wait|, but gives up after a timeout. After the timeout, |on_timeout| is
-// invoked with a diagnostic error string containing the trace names of the
-// futures that have not completed.
-//
-// This maintains a reference to the returned |Future| until all component
-// futures have been completed or destroyed, or until the timeout has elapsed,
-// whichever happens first. However, |on_timeout| will be invoked on timeout if
-// any future has not completed even if any or all futures have been destroyed.
-template <typename ResultsFuture, typename TimeoutCallback, typename... Result>
-fxl::RefPtr<ResultsFuture> WaitWithTimeout(
- const std::string& trace_name, async_dispatcher_t* dispatcher,
- zx::duration timeout,
- TimeoutCallback on_timeout /* void (const std::string&) */,
- const std::vector<FuturePtr<Result...>>& futures) {
- auto all_futures_completed = Wait<ResultsFuture>(trace_name, futures);
-
- if (all_futures_completed->status_ != internal::FutureStatus::kAwaiting) {
- return all_futures_completed;
- }
-
- auto all_trace_names =
- std::make_shared<std::vector<std::unique_ptr<std::string>>>();
- all_trace_names->reserve(futures.size());
-
- for (const auto& future : futures) {
- // There's no point in waiting on completed futures. Furthermore if we tried
- // that we'd have to put this before |Wait| since |Wait| consumes the
- // results, but then if all futures are already completed this is all just
- // wasted effort.
- if (future->status_ == internal::FutureStatus::kAwaiting) {
- size_t i = all_trace_names->size();
- all_trace_names->push_back(
- std::make_unique<std::string>(future->trace_name_));
- future->AddConstCallback([i, all_trace_names](const Result&...) {
- if (!all_trace_names->empty()) {
- (*all_trace_names)[i] = nullptr;
- }
- });
- }
- }
-
- // Return a proxy so that we can cancel result forwarding in the case of a
- // timeout. This could with more difficulty be done within |Wait|, but this
- // way allows us to reuse the logic more easily.
- fxl::RefPtr<ResultsFuture> all_proxy =
- ResultsFuture::Create(trace_name + "(WillWaitWithTimeout)");
- all_futures_completed->SetCallback(all_proxy->Completer());
-
- // TODO(rosswang): Factor this into dump and cancel functions that can be
- // called at other times.
- async::PostDelayedTask(
- dispatcher,
- [all_trace_names = std::move(all_trace_names),
- on_timeout = std::move(on_timeout),
- all_futures_completed =
- all_futures_completed->weak_factory_.GetWeakPtr()] {
- std::ostringstream msg;
- for (const auto& trace_name : *all_trace_names) {
- if (trace_name) {
- msg << "\n\t" << *trace_name;
- }
- }
- if (!msg.str().empty()) {
- on_timeout("Wait timed out. Still waiting for futures:" + msg.str());
- if (all_futures_completed) {
- // cancel results forwarding (possibly releasing all_proxy)
- all_futures_completed->SetCallback(nullptr);
- }
- // Possibly release the component futures. Once this task completes
- // and goes out of scope, the last reference to the Wait future (also
- // holding onto the component futures) should be released as well.
- all_trace_names->clear();
- }
- },
- timeout);
-
- return all_proxy;
-}
-
-// |WaitWithTimeout| on the thread defaut dispatcher.
-template <typename ResultsFuture, typename TimeoutCallback, typename... Result>
-fxl::RefPtr<ResultsFuture> WaitWithTimeout(
- const std::string& trace_name, zx::duration timeout,
- TimeoutCallback on_timeout /* void (const std::string&) */,
- const std::vector<FuturePtr<Result...>>& futures) {
- return WaitWithTimeout<ResultsFuture>(trace_name,
- async_get_default_dispatcher(), timeout,
- std::move(on_timeout), futures);
-}
-
-// These overloads allow us to effectively default the first template parameter,
-// |ResultsFuture| (since the others are intended to be inferred).
-// TODO(rosswang): If the overload combinatoric explosion gets too heavy, we can
-// use a dummy struct parameter instead to encapsulate that template parameter.
-
-template <typename... Result>
-auto Wait(const std::string& trace_name,
- const std::vector<FuturePtr<Result...>>& futures) {
- return Wait<internal::DefaultResultsFuture_t<Result...>>(trace_name, futures);
-}
-
-template <typename TimeoutCallback, typename... Result>
-auto WaitWithTimeout(const std::string& trace_name,
- async_dispatcher_t* dispatcher, zx::duration timeout,
- TimeoutCallback on_timeout,
- const std::vector<FuturePtr<Result...>>& futures) {
- return WaitWithTimeout<internal::DefaultResultsFuture_t<Result...>>(
- trace_name, dispatcher, timeout, std::move(on_timeout), futures);
-}
-
-template <typename TimeoutCallback, typename... Result>
-auto WaitWithTimeout(const std::string& trace_name, zx::duration timeout,
- TimeoutCallback on_timeout /* void (const std::string&) */,
- const std::vector<FuturePtr<Result...>>& futures) {
- return WaitWithTimeout<internal::DefaultResultsFuture_t<Result...>>(
- trace_name, async_get_default_dispatcher(), timeout,
- std::move(on_timeout), futures);
-}
-
-// We need to provide the initializer list overloads or template deduction fails
-// for the above overloads if given an initializer list.
-// TODO(rosswang): Add a potentially heterogeneous variadic template instead,
-// and prefer it over initializer lists outside of tests.
-template <typename ResultsFuture, typename... Result>
-auto Wait(const std::string& trace_name,
- std::initializer_list<FuturePtr<Result...>> futures) {
- return Wait<ResultsFuture>(trace_name,
- std::vector<FuturePtr<Result...>>(futures));
-}
-
-template <typename ResultsFuture, typename TimeoutCallback, typename... Result>
-fxl::RefPtr<ResultsFuture> WaitWithTimeout(
- const std::string& trace_name, async_dispatcher_t* dispatcher,
- zx::duration timeout, TimeoutCallback on_timeout,
- std::initializer_list<FuturePtr<Result...>> futures) {
- return WaitWithTimeout<ResultsFuture>(
- trace_name, dispatcher, timeout, std::move(on_timeout),
- std::vector<FuturePtr<Result...>>(futures));
-}
-
-template <typename ResultsFuture, typename TimeoutCallback, typename... Result>
-fxl::RefPtr<ResultsFuture> WaitWithTimeout(
- const std::string& trace_name, zx::duration timeout,
- TimeoutCallback on_timeout /* void (const std::string&) */,
- std::initializer_list<FuturePtr<Result...>> futures) {
- return WaitWithTimeout<ResultsFuture>(
- trace_name, async_get_default_dispatcher(), timeout,
- std::move(on_timeout), std::vector<FuturePtr<Result...>>(futures));
-}
-
-template <typename... Result>
-auto Wait(const std::string& trace_name,
- std::initializer_list<FuturePtr<Result...>> futures) {
- return Wait(trace_name, std::vector<FuturePtr<Result...>>(futures));
-}
-
-template <typename TimeoutCallback, typename... Result>
-auto WaitWithTimeout(const std::string& trace_name,
- async_dispatcher_t* dispatcher, zx::duration timeout,
- TimeoutCallback on_timeout,
- std::initializer_list<FuturePtr<Result...>> futures) {
- return WaitWithTimeout(trace_name, dispatcher, timeout, std::move(on_timeout),
- std::vector<FuturePtr<Result...>>(futures));
-}
-
-template <typename TimeoutCallback, typename... Result>
-auto WaitWithTimeout(const std::string& trace_name, zx::duration timeout,
- TimeoutCallback on_timeout /* void (const std::string&) */,
- std::initializer_list<FuturePtr<Result...>> futures) {
- return WaitWithTimeout(trace_name, async_get_default_dispatcher(), timeout,
- std::move(on_timeout),
- std::vector<FuturePtr<Result...>>(futures));
-}
-
-} // namespace modular
-
-#endif // LIB_ASYNC_CPP_FUTURE_H_
diff --git a/public/lib/async/cpp/future_unittest.cc b/public/lib/async/cpp/future_unittest.cc
deleted file mode 100644
index 9bc2c05..0000000
--- a/public/lib/async/cpp/future_unittest.cc
+++ /dev/null
@@ -1,910 +0,0 @@
-#include <lib/async/cpp/future.h>
-
-#include <string>
-
-#include <lib/async-testutils/test_loop.h>
-#include <lib/fxl/logging.h>
-
-#include "gtest/gtest-spi.h"
-#include "gtest/gtest.h"
-
-#include <memory>
-#include <string>
-
-namespace modular {
-
-namespace {
-
-// https://www.reddit.com/r/Stargate/comments/114165/stargate_sg_1_episode_200_what_is_your_favorite/c6j8ryy
-// https://en.wikiquote.org/wiki/Stargate_SG-1/Season_10#200_[10.6]
-// (The actual duration is immaterial because we control time in unit tests.)
-constexpr zx::duration kPause = zx::min(38);
-
-// This is a simple class to enable asynchronous callbacks to be tested. In each
-// test:
-//
-// 1. Instantiate an AsyncExceptions object,
-// 2. Call Signal() in each async callback to indicate that an async callback
-// was successfully called. Note that doesn't mean that the callback itself
-// was passed the correct parameters or was successful: to ensure that, your
-// callback should call still EXPECT_* for its expected results.
-// 3. Call Verify(n) at the end of your test method to ensure that the number of
-// expected async callbacks is correct. |n| should be the number of Signal()
-// calls that were expected. Verify() will fail if Signal() hasn't been
-// called exactly |n| times.
-//
-// Note that AsyncExpectations does _not_ integrate with the message loop, since
-// its one use case has no need to do that.
-//
-// THIS CLASS IS NOT THREAD-SAFE.
-//
-// Example:
-//
-// TEST(FooTest, FooTestCase) {
-// AsyncExpectations async_expectations;
-// async_function_1([&] {
-// async_expectations.Signal();
-// });
-// async_function_2([&] {
-// async_expectations.Signal();
-// });
-// async_expectations.Verify(2);
-// }
-class AsyncExpectations {
- public:
- void Signal() { ++count_; }
- void Reset() { count_ = 0; }
-
- int count() const { return count_; }
-
- private:
- int count_ = 0;
-};
-
-TEST(AsyncExpectationTest, TestLessThanExpectedCountFails) {
- AsyncExpectations async_expectations;
-
- async_expectations.Signal();
- EXPECT_NONFATAL_FAILURE({ EXPECT_EQ(2, async_expectations.count()); },
- "Expected equality");
-}
-
-TEST(AsyncExpectationTest, TestExpectedCountSucceeds) {
- AsyncExpectations async_expectations;
-
- async_expectations.Signal();
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST(AsyncExpectationTest, TestMoreThanExpectedCountFails) {
- AsyncExpectations async_expectations;
-
- async_expectations.Signal();
- async_expectations.Signal();
- EXPECT_NONFATAL_FAILURE({ EXPECT_EQ(1, async_expectations.count()); },
- "Expected equality");
-}
-
-} // namespace
-
-// FutureTest must be in the ::modular namespace (not in an anonymous namespace)
-// so that the "friend class FutureTest;" declaration in the Future class can
-// properly befriend this test.
-class FutureTest : public ::testing::Test {
- protected:
- template <typename... Result>
- const std::tuple<Result...>& get(const FuturePtr<Result...>& future) const {
- return future->get();
- }
-
- template <typename... Result>
- fxl::WeakPtrFactory<Future<Result...>>& weak_factory(
- const FuturePtr<Result...>& future) const {
- return future->weak_factory_;
- }
-};
-
-namespace {
-
-TEST_F(FutureTest, Create) {
- auto f = Future<>::Create(__PRETTY_FUNCTION__);
-
- EXPECT_NE(f.get(), nullptr);
-}
-
-TEST_F(FutureTest, CompleteAndGet) {
- auto f = Future<int>::Create(__PRETTY_FUNCTION__);
-
- f->Complete(10);
- ASSERT_EQ(get(f), std::tuple<int>(10));
-}
-
-TEST_F(FutureTest, ThenWith0Argument) {
- auto f = Future<>::Create(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- f->Then([&]() { async_expectations.Signal(); });
-
- f->Complete();
- ASSERT_EQ(get(f), std::tuple<>());
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, ThenWith1Argument) {
- auto f = Future<int>::Create(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- f->Then([&](const int& value) {
- EXPECT_EQ(value, 10);
- async_expectations.Signal();
- });
-
- f->Complete(10);
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, ThenWith2Argument) {
- auto f = Future<int, float>::Create(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- f->Then([&](const int& i, const float& f) {
- EXPECT_EQ(i, 10);
- EXPECT_FLOAT_EQ(f, 3.14f);
- async_expectations.Signal();
- });
-
- f->Complete(10, 3.14f);
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, CompleteBeforeThen) {
- auto f = Future<int>::Create(__PRETTY_FUNCTION__);
-
- f->Complete(10);
-
- AsyncExpectations async_expectations;
-
- f->Then([&](const int& value) {
- EXPECT_EQ(value, 10);
- async_expectations.Signal();
- });
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, ThenCorrectlyMoves) {
- std::shared_ptr<int> p(new int(10));
- auto f = Future<std::shared_ptr<int>>::Create(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- f->Then([&](std::shared_ptr<int> p2) {
- EXPECT_EQ(p.get(), nullptr);
- EXPECT_NE(p2.get(), nullptr);
-
- EXPECT_EQ(*p2, 10);
- async_expectations.Signal();
- });
-
- f->Complete(std::move(p));
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, ConstThen) {
- std::shared_ptr<int> p(new int(10));
- auto f = Future<std::shared_ptr<int>>::Create(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- f->ConstThen([&](const std::shared_ptr<int>& p2) {
- EXPECT_NE(p2.get(), nullptr);
- EXPECT_EQ(p.get(), nullptr);
-
- EXPECT_EQ(*p2, 10);
- async_expectations.Signal();
- });
-
- f->ConstThen([&](const std::shared_ptr<int>& p3) {
- EXPECT_NE(p3.get(), nullptr);
- EXPECT_EQ(p.get(), nullptr);
-
- EXPECT_EQ(*p3, 10);
- async_expectations.Signal();
- });
-
- f->Complete(std::move(p));
-
- EXPECT_EQ(2, async_expectations.count());
-}
-
-TEST_F(FutureTest, ConstThenAfterComplete) {
- auto f = Future<int>::Create(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- bool first_const_then{};
- f->ConstThen([&](const int& i) {
- EXPECT_FALSE(first_const_then);
- first_const_then = true;
- async_expectations.Signal();
- });
-
- f->Complete(10);
-
- bool second_const_then{};
- f->ConstThen([&](const int& i) {
- EXPECT_FALSE(second_const_then);
- second_const_then = true;
- async_expectations.Signal();
- });
-
- EXPECT_EQ(2, async_expectations.count());
-}
-
-TEST_F(FutureTest, ConstThenAfterThen) {
- std::shared_ptr<int> p(new int(10));
- auto f = Future<std::shared_ptr<int>>::Create(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- f->ConstThen([&](const std::shared_ptr<int>& p2) {
- EXPECT_NE(p2.get(), nullptr);
- EXPECT_EQ(p.get(), nullptr);
-
- EXPECT_EQ(*p2, 10);
- async_expectations.Signal();
- });
-
- f->Then([&](std::shared_ptr<int> p4) {
- EXPECT_NE(p4.get(), nullptr);
- EXPECT_EQ(p.get(), nullptr);
-
- EXPECT_EQ(*p4, 10);
- async_expectations.Signal();
- });
-
- f->ConstThen([&](const std::shared_ptr<int>& p3) {
- EXPECT_NE(p3.get(), nullptr);
- EXPECT_EQ(p.get(), nullptr);
-
- EXPECT_EQ(*p3, 10);
- async_expectations.Signal();
- });
-
- f->Complete(std::move(p));
-
- EXPECT_EQ(3, async_expectations.count());
-}
-
-TEST_F(FutureTest, WeakThen) {
- // WeakThen() will break an execution chain if its weakptr is invalidated.
- int data = 0;
- fxl::WeakPtrFactory<int> factory(&data);
- AsyncExpectations async_expectations;
-
- // This time we expect all three to run because we haven't invalidated any
- // WeakPtrs.
- auto f =
- Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
- f->Then([&] { async_expectations.Signal(); })
- ->WeakThen(factory.GetWeakPtr(), [&] { async_expectations.Signal(); })
- ->Then([&] { async_expectations.Signal(); });
-
- f->Complete();
- EXPECT_EQ(3, async_expectations.count());
-
- // But this time we'll invalidate WeakPtrs in the first Then(). Only the first
- // Then() will run.
- async_expectations.Reset();
- f = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
- f->Then([&] {
- async_expectations.Signal();
- factory.InvalidateWeakPtrs();
- })
- ->WeakThen(factory.GetWeakPtr(), [&] { async_expectations.Signal(); })
- ->Then([&] { async_expectations.Signal(); });
-
- f->Complete();
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, WeakConstThen) {
- // WeakConstThen() will not run if its weakptr is invalidated.
- int data = 0;
- fxl::WeakPtrFactory<int> factory(&data);
- AsyncExpectations async_expectations;
-
- auto f =
- Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
- f->WeakConstThen(factory.GetWeakPtr(), [&] { async_expectations.Signal(); });
- f->Complete();
- EXPECT_EQ(1, async_expectations.count());
-
- async_expectations.Reset();
- f = Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
- f->WeakConstThen(factory.GetWeakPtr(), [&] { async_expectations.Signal(); });
- factory.InvalidateWeakPtrs();
- f->Complete();
- EXPECT_EQ(0, async_expectations.count());
-}
-
-TEST_F(FutureTest, WeakMap) {
- // Similar to WeakThen(), but using Map calls instead.
- int data = 0;
- fxl::WeakPtrFactory<int> factory(&data);
-
- auto f =
- Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
-
- // First let everything run.
- AsyncExpectations async_expectations;
- f->Map([&](int i) {
- async_expectations.Signal();
- return 42;
- })
- ->WeakMap(factory.GetWeakPtr(),
- [&](int i) {
- async_expectations.Signal();
- return 10;
- })
- ->Then([&](int i) { async_expectations.Signal(); });
-
- f->Complete(10);
- EXPECT_EQ(3, async_expectations.count());
-
- // Now invalidate it.
- f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("2"));
- async_expectations.Reset();
- f->Map([&](int i) {
- async_expectations.Signal();
- factory.InvalidateWeakPtrs();
- return 42;
- })
- ->WeakMap(factory.GetWeakPtr(),
- [&](int i) {
- async_expectations.Signal();
- return 10;
- })
- ->Then([&](int i) { async_expectations.Signal(); });
-
- f->Complete(10);
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, WeakAsyncMap) {
- // Similar to WeakThen(), but using Map calls instead.
- int data = 0;
- fxl::WeakPtrFactory<int> factory(&data);
-
- auto f =
- Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
-
- // First let everything run.
- AsyncExpectations async_expectations;
- f->Map([&](int i) {
- async_expectations.Signal();
- return 42;
- })
- ->WeakAsyncMap(factory.GetWeakPtr(),
- [&](int i) {
- async_expectations.Signal();
- return Future<int>::CreateCompleted(
- std::string(__PRETTY_FUNCTION__) + std::string("2"),
- 10);
- })
- ->Then([&](int i) { async_expectations.Signal(); });
-
- f->Complete(10);
- EXPECT_EQ(3, async_expectations.count());
-
- // Now invalidate it.
- f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("3"));
- async_expectations.Reset();
- f->Map([&](int i) {
- async_expectations.Signal();
- factory.InvalidateWeakPtrs();
- return 42;
- })
- ->WeakAsyncMap(factory.GetWeakPtr(),
- [&](int i) {
- async_expectations.Signal();
- return Future<int>::CreateCompleted(
- std::string(__PRETTY_FUNCTION__) + std::string("4"),
- 10);
- })
- ->Then([&](int i) { async_expectations.Signal(); });
-
- f->Complete(10);
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, CreateCompleted) {
- auto f = Future<>::CreateCompleted(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- f->Then([&]() { async_expectations.Signal(); });
-
- ASSERT_EQ(get(f), std::tuple<>());
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, Wait) {
- auto f1 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) +
- std::string("1"));
- auto f2 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) +
- std::string("2"));
- auto f3 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) +
- std::string("3"));
-
- AsyncExpectations async_expectations;
-
- auto f =
- Wait(std::string(__PRETTY_FUNCTION__) + std::string("4"), {f1, f2, f3});
- f->Then([&](std::vector<std::tuple<int, std::string>> v) {
- EXPECT_EQ(v.size(), 3ul);
-
- EXPECT_EQ(v[0], std::make_tuple(10, "10"));
- EXPECT_EQ(v[1], std::make_tuple(20, "20"));
- EXPECT_EQ(v[2], std::make_tuple(30, "30"));
-
- async_expectations.Signal();
- });
-
- // Go ahead and insert out of order to also ensure that Wait produces results
- // in insertion order rather than completion order.
- f2->Complete(20, "20");
- EXPECT_EQ(0, async_expectations.count());
- f1->Complete(10, "10");
- EXPECT_EQ(0, async_expectations.count());
- f3->Complete(30, "30");
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, WaitOnZeroFutures) {
- auto f = Wait(__PRETTY_FUNCTION__, std::vector<FuturePtr<int>>{});
-
- AsyncExpectations async_expectations;
-
- f->Then([&](std::vector<int> v) {
- EXPECT_EQ(v.size(), 0ul);
- async_expectations.Signal();
- });
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(
- FutureTest,
- WaitReleasesReturnedFutureIfAllComponentFuturesHaveBeenCompletedOrDestroyed) {
- fxl::WeakPtr<Future<std::vector<int>>> weak_f;
-
- auto f1 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("1"));
- {
- auto f2 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("2"));
- weak_f =
- weak_factory(Wait(__PRETTY_FUNCTION__ + std::string("Wait"), {f1, f2}))
- .GetWeakPtr();
- }
-
- ASSERT_TRUE(weak_f);
- weak_f->Then([&](std::vector<int>) { FAIL(); });
- f1->Complete(42);
- EXPECT_FALSE(weak_f);
-}
-
-// This test is the happy case, more or less identical to |Wait|.
-TEST_F(FutureTest, WaitWithTimeout) {
- auto f1 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) +
- std::string("1"));
- auto f2 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) +
- std::string("2"));
- auto f3 = Future<int, std::string>::Create(std::string(__PRETTY_FUNCTION__) +
- std::string("3"));
-
- AsyncExpectations async_expectations;
- async::TestLoop loop;
-
- auto f = WaitWithTimeout(
- std::string(__PRETTY_FUNCTION__) + std::string("4"), loop.dispatcher(),
- kPause, [](const std::string& msg) { FAIL() << msg; }, {f1, f2, f3});
-
- f->Then([&](std::vector<std::tuple<int, std::string>> v) {
- EXPECT_EQ(v.size(), 3ul);
-
- EXPECT_EQ(v[0], std::make_tuple(10, "10"));
- EXPECT_EQ(v[1], std::make_tuple(20, "20"));
- EXPECT_EQ(v[2], std::make_tuple(30, "30"));
-
- async_expectations.Signal();
- });
-
- loop.RunUntilIdle(); // ensure the timeout does not occur
-
- // Go ahead and insert out of order to also ensure that Wait produces results
- // in insertion order rather than completion order.
- f2->Complete(20, "20");
- EXPECT_EQ(0, async_expectations.count());
- f1->Complete(10, "10");
- EXPECT_EQ(0, async_expectations.count());
- f3->Complete(30, "30");
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-// Zero futures should instantly complete regardless of timeout.
-TEST_F(FutureTest, WaitWithTimeoutOnZeroFutures) {
- AsyncExpectations async_expectations;
- async::TestLoop loop;
-
- auto f = WaitWithTimeout(__PRETTY_FUNCTION__, loop.dispatcher(), {},
- [](const std::string& msg) { FAIL() << msg; },
- std::vector<FuturePtr<int>>{});
-
- loop.RunUntilIdle();
-
- f->Then([&](std::vector<int> v) {
- EXPECT_EQ(v.size(), 0ul);
- async_expectations.Signal();
- });
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, WaitWithTimeoutCallsCallbackOnTimeout) {
- AsyncExpectations async_expectations;
- async::TestLoop loop;
-
- auto f1 =
- Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
-
- auto f = WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("2"),
- loop.dispatcher(), {},
- [&](const std::string& msg) {
- EXPECT_EQ('1', msg[msg.size() - 1]);
- async_expectations.Signal();
- },
- {f1});
-
- loop.RunUntilIdle();
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, WaitWithTimeoutWithDefaultDispatcher) {
- AsyncExpectations async_expectations;
- async::TestLoop loop;
-
- async_set_default_dispatcher(loop.dispatcher());
-
- auto f1 =
- Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
-
- auto f =
- WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("2"), {},
- [&](const std::string& msg) {
- EXPECT_EQ('1', msg[msg.size() - 1]);
- async_expectations.Signal();
- },
- {f1});
-
- loop.RunUntilIdle();
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, WaitWithTimeoutDoesNotCompleteAfterTimeout) {
- async::TestLoop loop;
-
- auto f1 =
- Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
-
- auto f = WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("2"),
- loop.dispatcher(), {}, [](const auto&) {}, {f1});
-
- f->Then([] { FAIL(); });
-
- loop.RunUntilIdle();
- f1->Complete();
-}
-
-// The following several tests also test additional Wait functionality, since
-// WaitWithTimeout is implemented in terms of Wait.
-TEST_F(FutureTest, WaitWithTimeoutOnMoveOnlyType) {
- AsyncExpectations async_expectations;
- async::TestLoop loop;
-
- auto f1 = Future<std::unique_ptr<int>>::Create(
- std::string(__PRETTY_FUNCTION__) + std::string("1"));
-
- auto f = WaitWithTimeout(std::string(__PRETTY_FUNCTION__) + std::string("2"),
- loop.dispatcher(), kPause,
- [](const std::string& msg) { FAIL() << msg; }, {f1});
-
- f->Then([&](std::vector<std::unique_ptr<int>> v) {
- EXPECT_EQ(v.size(), 1u);
-
- EXPECT_EQ(*v[0], 42);
-
- async_expectations.Signal();
- });
-
- f1->Complete(std::make_unique<int>(42));
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, WaitWithTimeoutNoTypeStreamlining) {
- // This test contains no assertions as it is a compile-time test.
- async::TestLoop loop;
- auto f1 =
- Future<>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
-
- auto f = WaitWithTimeout<Future<std::vector<std::tuple<>>>>(
- std::string(__PRETTY_FUNCTION__) + std::string("2"), loop.dispatcher(),
- kPause, [](const auto&) {}, {f1});
- f->Then([](std::vector<std::tuple<>> v) {});
-}
-
-// This tests a specific bug case where some futures started completed and some
-// did not. In this bug, WaitWithTimeout added its notification const callbacks
-// after invoking Wait. The futures that were completed would invoke the
-// callback added by Wait immediately, making the const callbacks then added by
-// WaitWithTimeout illegal. This did not manifest when all futures started
-// completed due to an optimization in WaitWithTimeout that returns immediately
-// if the Wait future starts complete.
-TEST_F(FutureTest, WaitWithTimeoutOnPartiallyCompletedFutures) {
- AsyncExpectations async_expectations;
- async::TestLoop loop;
-
- auto f1 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("1"));
- auto f2 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("2"));
- f1->Complete(42);
- auto f =
- WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"),
- loop.dispatcher(), kPause, [](const auto&) {}, {f1, f2})
- ->Then([&](const std::vector<int>& results) {
- ASSERT_EQ(2u, results.size());
- EXPECT_EQ(42, results[0]);
- EXPECT_EQ(54, results[1]);
- async_expectations.Signal();
- });
- f2->Complete(54); // http://hitchhikers.wikia.com/wiki/42
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, WaitWithTimeoutReleasesFuturesOnCompletion) {
- async::TestLoop loop;
- fxl::WeakPtr<Future<>> weak_f1;
-
- {
- auto f1 = Future<>::Create(__PRETTY_FUNCTION__ + std::string("1"));
- weak_f1 = weak_factory(f1).GetWeakPtr();
-
- auto f =
- WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"),
- loop.dispatcher(), kPause, [](const auto&) {}, {f1});
- f1->Complete();
- }
-
- EXPECT_FALSE(weak_f1);
-}
-
-TEST_F(FutureTest, WaitWithTimeoutReleasesFuturesOnTimeout) {
- async::TestLoop loop;
- fxl::WeakPtr<Future<>> weak_f1;
-
- {
- auto f1 = Future<>::Create(__PRETTY_FUNCTION__ + std::string("1"));
- weak_f1 = weak_factory(f1).GetWeakPtr();
-
- WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"),
- loop.dispatcher(), {}, [](const auto&) {}, {f1});
- loop.RunUntilIdle();
- }
-
- EXPECT_FALSE(weak_f1);
-}
-
-TEST_F(FutureTest,
- WaitWithTimeoutCallsCallbackOnTimeoutEvenIfFuturesAreDestroyed) {
- AsyncExpectations async_expectations;
- async::TestLoop loop;
-
- {
- auto f1 = Future<>::Create(__PRETTY_FUNCTION__ + std::string("1"));
- WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"),
- loop.dispatcher(), {},
- [&](const auto&) { async_expectations.Signal(); }, {f1});
- }
-
- loop.RunUntilIdle();
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(
- FutureTest,
- WaitWithTimeoutReleasesReturnedFutureIfAllComponentFuturesHaveBeenCompletedOrDestroyed) {
- async::TestLoop loop;
- fxl::WeakPtr<Future<std::vector<int>>> weak_f;
-
- auto f1 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("1"));
- {
- auto f2 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("2"));
- weak_f =
- weak_factory(WaitWithTimeout(__PRETTY_FUNCTION__ + std::string("Wait"),
- loop.dispatcher(), kPause,
- [](const auto&) {}, {f1, f2}))
- .GetWeakPtr();
- }
-
- ASSERT_TRUE(weak_f);
- weak_f->Then([&](std::vector<int>) { FAIL(); });
- f1->Complete(42);
- EXPECT_FALSE(weak_f);
-}
-
-TEST_F(FutureTest, WaitWithTimeoutReleasesReturnedFutureOnTimeout) {
- async::TestLoop loop;
- fxl::WeakPtr<Future<std::vector<int>>> weak_f;
-
- {
- auto f1 = Future<int>::Create(__PRETTY_FUNCTION__ + std::string("1"));
- weak_f = weak_factory(WaitWithTimeout(
- __PRETTY_FUNCTION__ + std::string("Wait"),
- loop.dispatcher(), {}, [](const auto&) {}, {f1}))
- .GetWeakPtr();
- }
-
- loop.RunUntilIdle();
- EXPECT_FALSE(weak_f);
-}
-
-TEST_F(FutureTest, Completer) {
- auto f = Future<int>::Create(__PRETTY_FUNCTION__);
-
- auto completer = f->Completer();
- completer(5);
-
- AsyncExpectations async_expectations;
-
- f->Then([&](int i) {
- EXPECT_EQ(i, 5);
- async_expectations.Signal();
- });
-
- EXPECT_EQ(1, async_expectations.count());
-}
-
-TEST_F(FutureTest, AsyncMap) {
- auto future =
- Future<int>::Create(std::string(__PRETTY_FUNCTION__) + std::string("1"));
-
- AsyncExpectations async_expectations;
-
- future
- ->AsyncMap([&](int i) {
- EXPECT_EQ(i, 10);
- async_expectations.Signal();
-
- auto f = Future<std::string>::Create(std::string(__PRETTY_FUNCTION__) +
- std::string("2"));
- f->Complete(std::to_string(i * 2));
- return f;
- })
- ->AsyncMap([&](std::string s) {
- EXPECT_EQ(s, "20");
- async_expectations.Signal();
-
- auto f = Future<int>::Create(std::string(__PRETTY_FUNCTION__) +
- std::string("3"));
- f->Complete(std::stoi(s));
- return f;
- })
- ->Then([&](int i) {
- EXPECT_EQ(i, 20);
- async_expectations.Signal();
- });
-
- future->Complete(10);
-
- EXPECT_EQ(3, async_expectations.count());
-}
-
-TEST_F(FutureTest, Map) {
- auto f = Future<int>::Create(__PRETTY_FUNCTION__);
-
- AsyncExpectations async_expectations;
-
- f->Map([&](int i) {
- EXPECT_EQ(i, 10);
- async_expectations.Signal();
-
- return std::to_string(i * 2);
- })
- ->Map([&](std::string s) {
- EXPECT_EQ(s, "20");
- async_expectations.Signal();
-
- return std::stoi(s);
- })
- ->Then([&](int i) {
- EXPECT_EQ(i, 20);
- async_expectations.Signal();
- });
-
- f->Complete(10);
-
- EXPECT_EQ(3, async_expectations.count());
-}
-
-TEST_F(FutureTest, MapToTuple) {
- float fresult;
- std::string sresult;
-
- auto f1 = Future<int>::Create(__PRETTY_FUNCTION__);
- FuturePtr<float, std::string> f2 = f1->Map(
- [](int i) { return std::make_tuple(i / 2.f, std::to_string(i)); });
-
- f2->Then([&](float fvalue, const std::string& svalue) {
- fresult = fvalue;
- sresult = std::move(svalue);
- });
-
- f1->Complete(3);
-
- EXPECT_EQ(1.5f, fresult);
- EXPECT_EQ("3", sresult);
-}
-
-// compile-time test
-namespace MapToTupleTuple {
-FuturePtr<std::tuple<float, std::string>> f =
- Future<int>::Create("MapToTupleTuple")->Map([](int i) {
- return std::make_tuple(std::make_tuple(i / 2.f, std::to_string(i)));
- });
-}
-
-TEST_F(FutureTest, trace_name) {
- auto f = Future<>::Create("test");
- EXPECT_EQ(f->trace_name(), "test");
-}
-
-TEST_F(FutureTest, ThenCallbackDestroysFuture) {
- struct S {
- FuturePtr<> f;
- };
- S* s = new S;
-
- AsyncExpectations async_expectations;
-
- s->f = Future<>::Create(__PRETTY_FUNCTION__);
-
- // Explicitly retain the subfuture returned by Then() to keep it alive. This
- // tests whether the original future will still complete its subfuture if the
- // original future is destroyed, but the subfuture is still kept alive. (That
- // should not happen, as per documentation for Then().)
- auto subfuture = s->f->Then([&] {
- delete s;
- async_expectations.Signal();
- });
-
- subfuture->Then([&] {
- // This lambda shouldn't be executed because s--and therefore s->f--was
- // deleted in the Then() callback above.
- async_expectations.Signal();
- });
-
- s->f->Complete();
-
- EXPECT_EQ(1, async_expectations.count()); // not 2!
-}
-
-} // namespace
-} // namespace modular
diff --git a/public/lib/async/cpp/operation.cc b/public/lib/async/cpp/operation.cc
deleted file mode 100644
index 7d636bd..0000000
--- a/public/lib/async/cpp/operation.cc
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/async/cpp/operation.h>
-
-#include <utility>
-
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fit/bridge.h>
-#include <lib/fit/defer.h>
-#include <lib/fxl/logging.h>
-#include <trace/event.h>
-
-namespace modular {
-
-constexpr char kModularTraceCategory[] = "modular";
-constexpr char kTraceIdKey[] = "id";
-constexpr char kTraceInfoKey[] = "info";
-
-OperationContainer::OperationContainer() = default;
-
-OperationContainer::~OperationContainer() = default;
-
-void OperationContainer::Add(OperationBase* const o) {
- FXL_DCHECK(o != nullptr);
- o->SetOwner(this);
- Hold(o); // Takes ownership.
-}
-
-void OperationContainer::Schedule(OperationBase* const o) { o->Schedule(); }
-
-void OperationContainer::InvalidateWeakPtrs(OperationBase* const o) {
- o->InvalidateWeakPtrs();
-}
-
-OperationCollection::OperationCollection()
- : executor_(async_get_default_dispatcher()), weak_ptr_factory_(this) {}
-
-OperationCollection::~OperationCollection() {
- // We invalidate weakptrs to all Operation<>s first before destroying them, so
- // that an outstanding FlowToken<> that gets destroyed in the process doesn't
- // erroneously call Operation<>::Done.
- for (auto& operation : operations_) {
- FXL_DCHECK(operation.get() != nullptr);
- InvalidateWeakPtrs(operation.get());
- }
-}
-
-fxl::WeakPtr<OperationContainer> OperationCollection::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
-}
-
-void OperationCollection::Hold(OperationBase* const o) {
- operations_.emplace_back(o);
- Schedule(o);
-}
-
-void OperationCollection::Drop(OperationBase* const o) {
- auto it = std::find_if(
- operations_.begin(), operations_.end(),
- [o](const std::unique_ptr<OperationBase>& p) { return p.get() == o; });
- FXL_DCHECK(it != operations_.end());
-
- // Ensures we erase the operation off our container first.
- // By keeping a reference to the operation its destructor is only triggered
- // after the scope of this method. Otherwise, we would trigger the
- // operation's destructor first before we actually removed the operation from
- // the container. To prevent reentry in case, an operation might have a
- // member variable to someone who has the parent container containing our
- // operation.
- //
- // Example:
- // operations.erase(operation) calls operation's destructor ~KillModuleCall()
- // ~KillModuleCall() [has member variable FlowToken of OnModuleUpdatedCall]
- // ~OnModuleUpdatedCall() [holding container containing KillModuleCall]
- // ~OperationQueue() [triggered by ~OnModuleUpdatedCall()]
- // [ERROR KillModuleCall in operation_ is nullptr at this point]
- // operations_.erase() actually erases the operation from the container
- //
- // See operation_unittest.cc for testcase. TestCollectionNotNullPtr
- std::unique_ptr<OperationBase> operation = std::move(*it);
- FXL_DCHECK(it->get() == nullptr);
- FXL_DCHECK(operation.get() == o);
- InvalidateWeakPtrs(operation.get());
- operations_.erase(it);
-}
-
-void OperationCollection::Cont() {
- // no-op for operation collection.
-}
-
-void OperationCollection::ScheduleTask(fit::pending_task task) {
- executor_.schedule_task(std::move(task));
-}
-
-OperationQueue::OperationQueue()
- : executor_(async_get_default_dispatcher()), weak_ptr_factory_(this) {}
-
-OperationQueue::~OperationQueue() {
- // We invalidate weakptrs to all Operation<>s first before destroying them, so
- // that an outstanding FlowToken<> that gets destroyed in the process doesn't
- // erroneously call Operation<>::Done.
- while (!operations_.empty()) {
- FXL_DCHECK(operations_.front().get() != nullptr);
- InvalidateWeakPtrs(operations_.front().get());
- operations_.pop();
- }
-}
-
-fxl::WeakPtr<OperationContainer> OperationQueue::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
-}
-
-void OperationQueue::Hold(OperationBase* const o) {
- operations_.emplace(o);
- if (idle_) {
- FXL_DCHECK(operations_.size() == 1);
- idle_ = false;
- Schedule(o);
- }
-}
-
-void OperationQueue::Drop(OperationBase* const o) {
- FXL_DCHECK(!operations_.empty());
- FXL_DCHECK(operations_.front().get() == o);
-
- // See comment in OperationCollection::Drop() for why this move is important.
- std::unique_ptr<OperationBase> operation = std::move(operations_.front());
- FXL_DCHECK(operations_.front().get() == nullptr);
- FXL_DCHECK(operation.get() == o);
- InvalidateWeakPtrs(operation.get());
- operations_.pop();
-}
-
-void OperationQueue::Cont() {
- if (!operations_.empty()) {
- auto o = operations_.front().get();
- Schedule(o);
- } else {
- idle_ = true;
- }
-}
-
-namespace {
-class PromiseWrapperCall : public Operation<> {
- public:
- PromiseWrapperCall(fit::completer<> completer)
- : Operation("PromiseDoneCall", [] {}), completer_(std::move(completer)) {}
-
- void Run() {
- running_ = true;
- completer_.complete_ok();
- }
-
- void SayDone() {
- FXL_CHECK(running_);
- Done();
- }
-
- private:
- fit::completer<> completer_;
- bool running_{false};
-};
-} // namespace
-
-void OperationQueue::ScheduleTask(fit::pending_task task) {
- // We need to block the execution of this task on tasks in |operations_|, and
- // then also block further execution of |operations_| on this task finishing.
- // We do this by "wrapping" the promise in a PromiseWrapperCall.
- //
- // |start| will be completed when |wrapper->Run()| is called, and |wrapper|
- // will be finished as a result of the promise finishing: we call
- // |wrapper->SayDone()| when |task| is destroyed. It is destroyed when either
- // a) it is abandoned or b) it is completed successfully or with an error. In
- // either case we want to unblock the next operation in the queue.
- fit::bridge start;
- auto wrapper = new PromiseWrapperCall(std::move(start.completer));
- executor_.schedule_task(start.consumer.promise().then(
- [p = task.take_promise(), wrapper](fit::result<>&) mutable {
- // It is safe to call SayDone() on |wrapper| because we know that
- // |wrapper| will be alive so long as this promise is being executed.
- //
- // We use a fit::defer on the capture list of .then() so that if |p| is
- // abandoned, we still unblock the queue.
- return p.then([defer = fit::defer([wrapper] { wrapper->SayDone(); })](
- fit::result<>&) {});
- }));
-
- Add(wrapper);
-}
-
-OperationBase::OperationBase(const char* const trace_name,
- std::string trace_info)
- // While we transition all operations to be explicitly added to containers
- // with OperationContainer::Add(), some |c|'s are going to be null.
- : weak_ptr_factory_(this),
- trace_name_(trace_name),
- trace_id_(TRACE_NONCE()),
- trace_info_(std::move(trace_info)) {}
-
-OperationBase::~OperationBase() = default;
-
-fxl::WeakPtr<OperationBase> OperationBase::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
-}
-
-void OperationBase::SetOwner(OperationContainer* c) {
- FXL_DCHECK(!container_);
- container_ = c->GetWeakPtr();
-}
-
-void OperationBase::Schedule() {
- TraceAsyncBegin();
-
- async::PostTask(async_get_default_dispatcher(),
- [this, weak = weak_ptr_factory_.GetWeakPtr()] {
- if (weak) {
- Run();
- }
- });
-}
-
-void OperationBase::InvalidateWeakPtrs() {
- weak_ptr_factory_.InvalidateWeakPtrs();
-}
-
-void OperationBase::TraceAsyncBegin() {
- TRACE_ASYNC_BEGIN(kModularTraceCategory, trace_name_, trace_id_, kTraceIdKey,
- trace_id_, kTraceInfoKey, trace_info_);
-}
-
-void OperationBase::TraceAsyncEnd() {
- TRACE_ASYNC_END(kModularTraceCategory, trace_name_, trace_id_, kTraceIdKey,
- trace_id_, kTraceInfoKey, trace_info_);
-}
-
-OperationBase::FlowTokenBase::FlowTokenBase(OperationBase* const op)
- : refcount_(new int), weak_op_(op->weak_ptr_factory_.GetWeakPtr()) {
- *refcount_ = 1;
-}
-
-OperationBase::FlowTokenBase::FlowTokenBase(const FlowTokenBase& other)
- : refcount_(other.refcount_), weak_op_(other.weak_op_) {
- ++*refcount_;
-}
-
-OperationBase::FlowTokenBase::~FlowTokenBase() {
- --*refcount_;
- if (*refcount_ == 0) {
- delete refcount_;
- }
-}
-
-} // namespace modular
diff --git a/public/lib/async/cpp/operation.h b/public/lib/async/cpp/operation.h
deleted file mode 100644
index 0898e0d..0000000
--- a/public/lib/async/cpp/operation.h
+++ /dev/null
@@ -1,556 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_ASYNC_CPP_OPERATION_H_
-#define LIB_ASYNC_CPP_OPERATION_H_
-
-#include <functional>
-#include <memory>
-#include <queue>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include <lib/async/cpp/future.h>
-#include <lib/async_promise/executor.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/fit/promise.h>
-
-namespace modular {
-class OperationBase;
-
-// An abstract base class which provides methods to hold on to Operation
-// instances until they declare themselves to be Done(). Ownership of
-// the operations must be managed by implementations.
-class OperationContainer {
- public:
- OperationContainer();
- virtual ~OperationContainer();
-
- // Adds |o| to this container and takes ownership.
- virtual void Add(OperationBase* o) final;
-
- // Adds |task| to be scheduled on |this|. This mirrors
- // the interface in fit::executor, and is here only during
- // a transition from Operations to fit::promises.
- virtual void ScheduleTask(fit::pending_task task) = 0;
-
- protected:
- void Schedule(OperationBase* o);
- void InvalidateWeakPtrs(OperationBase* o);
-
- private:
- // OperationBase calls the methods below.
- friend class OperationBase;
-
- virtual fxl::WeakPtr<OperationContainer> GetWeakPtr() = 0;
- // Must take ownership of |o|.
- virtual void Hold(OperationBase* o) = 0;
- // Must clean up memory for |o|.
- virtual void Drop(OperationBase* o) = 0;
- virtual void Cont() = 0;
-};
-
-// An implementation of |OperationContainer| which runs every instance of
-// Operation as soon as it arrives.
-class OperationCollection : public OperationContainer {
- public:
- OperationCollection();
- ~OperationCollection() override;
-
- void ScheduleTask(fit::pending_task task) override;
-
- private:
- fxl::WeakPtr<OperationContainer> GetWeakPtr() override;
- void Hold(OperationBase* o) override;
- void Drop(OperationBase* o) override;
- void Cont() override;
-
- async::Executor executor_;
- std::vector<std::unique_ptr<OperationBase>> operations_;
-
- // It is essential that the weak_ptr_factory is defined after the operations_
- // container, so that it gets destroyed before operations_, and hence before
- // the Operation instances in it, so that the Done() call on their
- // OperationBase sees the container weak pointer to be null. That's also why
- // we need the virtual GetWeakPtr() in the base class, rather than to put the
- // weak ptr factory in the base class.
- fxl::WeakPtrFactory<OperationContainer> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(OperationCollection);
-};
-
-// An implementation of |OperationContainer| which runs incoming Operations
-// sequentially. This ensures that there are no partially complete operations
-// when a new operation starts.
-class OperationQueue : public OperationContainer {
- public:
- OperationQueue();
- ~OperationQueue() override;
-
- void ScheduleTask(fit::pending_task task) override;
-
- private:
- fxl::WeakPtr<OperationContainer> GetWeakPtr() override;
- void Hold(OperationBase* o) override;
- void Drop(OperationBase* o) override;
- void Cont() override;
-
- // Are there any operations running? An operation is considered running once
- // its |Run()| has been invoked, up until result callback has finished. Note
- // that an operation could be running while it is not present in
- // |operations_|: its result callback could be executing.
- bool idle_ = true;
-
- async::Executor executor_;
- std::queue<std::unique_ptr<OperationBase>> operations_;
-
- // It is essential that the weak_ptr_factory is defined after the operations_
- // container, so that it gets destroyed before operations_, and hence before
- // the Operation instances in it, so that the Done() call on their
- // OperationBase sees the container weak pointer to be null. That's also why
- // we need the virtual GetWeakPtr() in the base class, rather than to put the
- // weak ptr factory in the base class.
- fxl::WeakPtrFactory<OperationContainer> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(OperationQueue);
-};
-
-// Something that can be put in an OperationContainer until it calls Done() on
-// itself. Used to implement asynchronous operations that need to hold on to
-// handles until the operation asynchronously completes and returns a value.
-//
-// Held by a unique_ptr<> in the OperationContainer, so instances of derived
-// classes need to be created with new.
-//
-// Advantages of using an Operation instance to implement asynchronous fidl
-// method invocations:
-//
-// 1. To receive the return callback, the interface pointer on which the method
-// is invoked needs to be kept around. It's tricky to place a move-only
-// interface pointer on the capture list of a lambda passed as argument to
-// its own method. An instance is much simpler.
-//
-// 2. The capture list of the callbacks only holds this, everything else that
-// needs to be passed on is in the instance.
-//
-// 3. Completion callbacks don't need to be made copyable and don't need to be
-// mutable, because no move only pointer is pulled from their capture list.
-//
-// 4. Conversion of Handle to Ptr can be done by Bind() because the Ptr is
-// already there.
-//
-// Use of Operation instances must adhere to invariants:
-//
-// * Deleting the operation container deletes all Operation instances in it, and
-// it must be guaranteed that no callbacks of ongoing method invocations are
-// invoked after the Operation instance they access is deleted. In order to
-// accomplish this, an Operation instance must only invoke methods on fidl
-// pointers that are either owned by the Operation instance, or that are owned
-// by the immediate owner of the operation container. This way, when the
-// operation container is deleted, the destructors of all involved fidl
-// pointers are called, close their channels, and cancel all pending method
-// callbacks. If a method is invoked on a fidl pointer that lives on beyond
-// the lifetime of the operation container, this is not guaranteed.
-class OperationBase {
- public:
- virtual ~OperationBase();
-
- // Derived classes implement this method. It is called by the container of
- // this Operation when it is ready. At some point after Run() is invoked,
- // |Done()| must be called to signal completion of this operation. This
- // usually happens implicitly from the destructor of a FlowToken that is
- // passed along the asynchronous flow of control of the Operation.
- virtual void Run() = 0;
-
- // Needed to guard callbacks to methods on FIDL pointers that are not owned by
- // this Operation instance.
- //
- // Callbacks on methods on FIDL pointers that are owned by Operation instance
- // are never invoked after the Operation instance is deleted, because they are
- // cancelled by the destructor of the FIDL pointer. However, if the FIDL
- // pointer is owned outside of the Operation instance, such a callback may be
- // invoked after the Operation instance was destroyed, if the FIDL pointer
- // lives longer.
- fxl::WeakPtr<OperationBase> GetWeakPtr();
-
- protected:
- // |trace_name| and |trace_info| are used to annotate performance traces.
- // |trace_name| must outlive *this.
- OperationBase(const char* trace_name, std::string trace_info);
-
- // Useful in log messages.
- const char* trace_name() const { return trace_name_; }
-
- class FlowTokenBase;
-
- private:
- // OperationContainer calls SetOwner(), InvalidateWeakPtrs() and Schedule().
- friend class OperationContainer;
-
- // Called only by OperationContainer::Add().
- void SetOwner(OperationContainer* c);
-
- // Called only by OperationContainer.
- void Schedule();
-
- // Called only by OperationContainer.
- void InvalidateWeakPtrs();
-
- // Operation<..> class DispatchCallback() and accesses trace info fields
- // below.
- template <typename... Args>
- friend class Operation;
-
- // Called only by Operation<...>.
- template <typename... Args,
- typename ResultCall = std::function<void(Args...)>>
- void DispatchCallback(ResultCall result_call, Args... result_args) {
- // Move |container| pointer out of this, because |this| gets deleted before
- // we stop using |container|.
- auto container = std::move(container_);
- if (container) {
- // Deletes |this|.
- container->Drop(this);
-
- // Can no longer refer to |this|.
- result_call(std::move(result_args)...);
-
- // The result callback may cause the container to be deleted, so we must
- // check it still exists before telling it to continue.
- if (container) {
- container->Cont();
- }
- }
- }
-
- // Traces the duration of the Operation excution. Begin() is called from
- // Schedule(), End() is called from Done().
- void TraceAsyncBegin();
- void TraceAsyncEnd();
-
- fxl::WeakPtr<OperationContainer> container_;
-
- // Used by FlowTokenBase to suppress Done() calls after the Operation instance
- // is deleted. The OperationContainer will invalidate all weak pointers to
- // this instance before the destructor is invoked, so it's not necessary that
- // this field is last.
- fxl::WeakPtrFactory<OperationBase> weak_ptr_factory_;
-
- // Name used to label traces for this operation.
- const char* const trace_name_;
-
- // Unique identifier used to correlate trace events for this operation.
- const uint64_t trace_id_;
-
- // Additional information added to trace events for this operation.
- const std::string trace_info_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(OperationBase);
-};
-
-template <typename... Args>
-class Operation : public OperationBase {
- public:
- ~Operation() override = default;
-
- using ResultCall = std::function<void(Args...)>;
-
- protected:
- Operation(const char* const trace_name, ResultCall result_call,
- const std::string& trace_info = "")
- : OperationBase(trace_name, trace_info),
- result_call_(std::move(result_call)) {}
-
- // Derived classes call this when they are prepared to be removed from the
- // container. Must be the last thing this instance does, as it results in
- // destructor invocation.
- void Done(Args... result_args) {
- TraceAsyncEnd();
- DispatchCallback(std::move(result_call_), std::move(result_args)...);
- }
-
- class FlowToken;
- class FlowTokenHolder;
-
- private:
- ResultCall result_call_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(Operation);
-};
-
-// The instance of FlowToken at which the refcount reaches zero in the
-// destructor calls Done() on the Operation it holds a reference of.
-//
-// It is an inner class of Operation so that it has access to Done(), which is
-// protected.
-//
-// Why this is ref counted, not moved:
-//
-// 1. Some flows of control branch into multiple parallel branches, and then its
-// subtle to figure out which one to move it along.
-//
-// 2. To move something onto a capture list is more verbose than to just copy
-// it, so it would defeat the purpose of being simpler to write than the
-// status quo.
-//
-// 3. A lambda with something that is moveonly on its capture list is not
-// copyable anymore, and one of the points of Operation was to only have
-// copyable continuations.
-//
-// NOTE: You cannot mix flow tokens and explicit Done() calls. Once an Operation
-// uses a flow token, this is how Done() is called, and calling Done()
-// explicitly would call it twice.
-//
-// The parts that are not dependent on the template parameter are factored off
-// into a base class as usual.
-class OperationBase::FlowTokenBase {
- public:
- explicit FlowTokenBase(OperationBase* op);
- FlowTokenBase(const FlowTokenBase& other);
- ~FlowTokenBase();
-
- protected:
- int refcount() const { return *refcount_; }
- bool weak_op() const { return weak_op_.get() != nullptr; }
-
- private:
- int* const refcount_; // shared between copies of FlowToken.
- fxl::WeakPtr<OperationBase> weak_op_;
-};
-
-template <typename... Args>
-class Operation<Args...>::FlowToken : OperationBase::FlowTokenBase {
- public:
- explicit FlowToken(Operation<Args...>* const op, Args* const... result)
- : FlowTokenBase(op), op_(op), result_(result...) {}
-
- FlowToken(const FlowToken& other)
- : FlowTokenBase(other), op_(other.op_), result_(other.result_) {}
-
- ~FlowToken() {
- // If refcount is 1 here, it will become 0 in ~FlowTokenBase.
- if (refcount() == 1 && weak_op()) {
- apply(std::make_index_sequence<
- std::tuple_size<decltype(result_)>::value>{});
- }
- }
-
- private:
- // This usage is based on the implementation of std::apply(), which is only
- // available in C++17: http://en.cppreference.com/w/cpp/utility/apply
- template <size_t... I>
- void apply(std::integer_sequence<size_t, I...> /*unused*/) {
- op_->Done(std::move((*std::get<I>(result_)))...);
- }
-
- Operation<Args...>* const op_; // not owned
-
- // The pointers that FlowToken() is constructed with are stored in this
- // std::tuple. They are then extracted and std::move()'d in the |apply()|
- // method.
- std::tuple<Args* const...> result_; // the values are not owned
-};
-
-// Sometimes the asynchronous flow of control that is represented by a FlowToken
-// branches, but is actually continued on exactly one branch. For example, when
-// a method is called on an external fidl service, and the callback from that
-// method is also scheduled as a timeout to avoid blocking the operation queue
-// in case the external service misbehaves and doesn't respond.
-//
-// In that situation, it would be wrong to place two copies of the flow token on
-// the capture list of both callbacks, because then the flow would only be
-// Done() once both callbacks are destroyed. In the case where the second
-// callback is a timeout, this might be really late.
-//
-// Instead, a single copy of the flow token is placed in a shared container, a
-// reference to which is placed on the capture list of both callbacks. The first
-// callback that is invoked removes the flow token from the shared container and
-// propagates it from there.
-//
-// That way, the flow token in the shared container also acts as call-once flag.
-//
-// The flow token holder is a simple wrapper of a shared ptr to a unique ptr. We
-// define it because such a nested smart pointer is rather unwieldy to write
-// every time.
-//
-// Example use:
-//
-// FlowTokenHolder branch{flow};
-//
-// auto kill_agent = [this, branch] {
-// std::unique_ptr<FlowToken> flow = branch.Continue();
-// if (!flow) {
-// return;
-// }
-//
-// stopped_ = true;
-// };
-//
-// StopAgent(kill_agent);
-// SetTimeout(kill_agent, 1);
-//
-template <typename... Args>
-class Operation<Args...>::FlowTokenHolder {
- public:
- using FlowToken = Operation<Args...>::FlowToken;
-
- explicit FlowTokenHolder(const FlowToken& flow)
- : ptr_(std::make_shared<std::unique_ptr<FlowToken>>(
- std::make_unique<FlowToken>(flow))) {}
-
- FlowTokenHolder(const FlowTokenHolder& other) : ptr_(other.ptr_) {}
-
- // Calling this method again on any copy of the same FlowTokenHolder yields a
- // nullptr. Clients can check for that to enforce call once semantics.
- //
- // The method is const because it only mutates the pointed to object. It's
- // useful to exploit this loophole because this way lambdas that have a
- // FlowTokenHolder on their capture list don't need to be mutable.
- std::unique_ptr<FlowToken> Continue() const { return std::move(*ptr_); }
-
- private:
- std::shared_ptr<std::unique_ptr<FlowToken>> ptr_;
-};
-
-// Following is a list of commonly used operations.
-
-// An operation which wraps a Future<>. See WrapFutureAsOperation() below.
-template <typename... Args>
-class FutureOperation : public Operation<Args...> {
- public:
- using ResultCall = std::function<void(Args...)>;
-
- FutureOperation(const char* trace_name, FuturePtr<> on_run,
- FuturePtr<Args...> done, ResultCall result_call)
- : Operation<Args...>(trace_name, std::move(result_call)),
- on_run_(on_run),
- done_(done) {}
-
- private:
- // |OperationBase|
- void Run() override {
- // FuturePtr is a shared ptr, so the Then() callback is not necessarily
- // cancelled by the destructor of this Operation instance. Hence the
- // callback must be protected against invocation after delete of this.
- done_->WeakThen(this->GetWeakPtr(), [this](Args&&... args) {
- this->Done(std::forward<Args>(args)...);
- // Can no longer refer to |this|.
- });
- on_run_->Complete();
- }
-
- FuturePtr<> on_run_;
- FuturePtr<Args...> done_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FutureOperation);
-};
-
-// EXPERIMENTAL
-//
-// This is useful to glue a FIDL call that expects its result as a callback with
-// a Future<>, but have the business logic of the Future<> run on an
-// OperationContainer.
-//
-// Usage:
-//
-// void MyFidlCall(args..., MyFidlCallResult result_call) {
-// auto on_run = Future<>::Create();
-// auto done = on_run->Map(...)->Then(...);
-// operation_container_.Add(WrapFutureAsOperation(
-// "MyFidlCall", on_run, done, result_call));
-// }
-//
-template <typename... ResultArgs, typename... FutureArgs>
-OperationBase* WrapFutureAsOperation(
- const char* const trace_name, FuturePtr<> on_run,
- FuturePtr<FutureArgs...> done,
- std::function<void(ResultArgs...)> result_call) {
- return new FutureOperation<ResultArgs...>(
- trace_name, std::move(on_run), std::move(done), std::move(result_call));
-}
-
-template <typename... Args>
-class FutureOperation2 : public Operation<Args...> {
- public:
- using ResultCall = std::function<void(Args...)>;
- using RunOpCall = std::function<FuturePtr<Args...>(OperationBase*)>;
-
- FutureOperation2(const char* const trace_name, RunOpCall run_op,
- ResultCall done)
- : Operation<Args...>(trace_name, std::move(done)), run_op_(run_op) {}
-
- private:
- // |OperationBase|
- void Run() override {
- // FuturePtr is a shared ptr, so the Then() callback is not necessarily
- // cancelled by the destructor of this Operation instance. Hence the
- // callback must be protected against invocation after delete of this.
- run_op_(this)->WeakThen(this->GetWeakPtr(), [this](Args&&... args) {
- this->Done(std::forward<Args>(args)...);
- });
- }
-
- RunOpCall run_op_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FutureOperation2);
-};
-
-// EXPERIMENTAL
-//
-// Glue code to define operations where the body of the operation is defined
-// inline to where the operation instance is created. It is an alternative to
-// WrapFutureAsOperation.
-//
-// The body of the operation is defined as a callback, and is expected to return
-// a Future<> that is completed when the operation is finished. If the Future<>
-// is completed with values, those values are used as the result of the
-// Operation.
-//
-// Usage:
-//
-// void MyFidlCall(args..., MyFidlCallResult result_call) {
-// operation_container.Add(NewCallbackOperation(
-// "MyFidlService::MyFidlCall",
-// [this] (OperationBase* op) {
-// // Use |op->GetWeakPtr()| to guard any async calls.
-// auto f = Future<>::Create();
-//
-// DoSomethingAsync(f->Completer());
-//
-// f->WeakMap(op->GetWeakPtr(), [] (int do_something_result) {
-// return do_something_result * 2;
-// });
-//
-// return f;
-// },
-// result_call);
-// }
-template <typename... ResultArgs>
-OperationBase* NewCallbackOperation(
- const char* const trace_name,
- typename FutureOperation2<ResultArgs...>::RunOpCall run,
- typename FutureOperation2<ResultArgs...>::ResultCall done) {
- return new FutureOperation2<ResultArgs...>(trace_name, std::move(run),
- std::move(done));
-}
-
-// An operation which immediately calls its result callback. This is useful for
-// making sure that all operations that run before this have completed.
-class SyncCall : public Operation<> {
- public:
- SyncCall(ResultCall result_call)
- : Operation("SyncCall", std::move(result_call)) {}
-
- void Run() override { Done(); }
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(SyncCall);
-};
-
-} // namespace modular
-
-#endif // LIB_ASYNC_CPP_OPERATION_H_
diff --git a/public/lib/async/cpp/operation_unittest.cc b/public/lib/async/cpp/operation_unittest.cc
deleted file mode 100644
index 16d7d05..0000000
--- a/public/lib/async/cpp/operation_unittest.cc
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/async/cpp/operation.h>
-
-#include <lib/async/cpp/future.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/gtest/test_loop_fixture.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-namespace {
-
-class TestContainer : public OperationContainer {
- public:
- TestContainer() : weak_ptr_factory_(this) {}
-
- fxl::WeakPtr<OperationContainer> GetWeakPtr() override {
- return weak_ptr_factory_.GetWeakPtr();
- }
-
- int hold_count{0};
- int drop_count{0};
- int cont_count{0};
- OperationBase* last_held = nullptr;
- OperationBase* last_dropped = nullptr;
-
- void Hold(OperationBase* o) override {
- ++hold_count;
- last_held = o;
- }
-
- void Drop(OperationBase* o) override {
- ++drop_count;
- last_dropped = o;
- }
-
- void Cont() override { ++cont_count; }
-
- void ScheduleTask(fit::pending_task task) override {}
-
- void PretendToDie() { weak_ptr_factory_.InvalidateWeakPtrs(); }
-
- using OperationContainer::InvalidateWeakPtrs; // Promote for testing.
- using OperationContainer::Schedule; // Promote for testing.
-
- private:
- fxl::WeakPtrFactory<OperationContainer> weak_ptr_factory_;
-};
-
-template <typename... Args>
-class TestOperation : public Operation<Args...> {
- public:
- using ResultCall = std::function<void(Args...)>;
- TestOperation(std::function<void()> task, ResultCall done)
- : Operation<Args...>("Test Operation", std::move(done)), task_(task) {}
-
- void SayDone(Args... args) { this->Done(args...); }
-
- private:
- void Run() override { task_(); }
-
- std::function<void()> task_;
-};
-
-class OperationTest : public gtest::TestLoopFixture {};
-
-// Test the lifecycle of a single Operation:
-// 1) Creating a new operation and adding it to a container
-// causes it to be scheduled (posted to the async task queue).
-// 2) When the operation states it is done, the container is told
-// to schedule the next task after the result callback is called.
-TEST_F(OperationTest, Lifecycle) {
- TestContainer container;
- bool op_ran = false;
- bool op_done = false;
- auto op =
- std::make_unique<TestOperation<>>([&op_ran] { op_ran = true; },
- [&op_done, &container] {
- op_done = true;
-
- // When our op is done, we
- // expect that the
- // OperationContainer that owns
- // it has already been told to
- // drop it, but we do not expect
- // Cont() to have been called.
- // That happens after the done
- // callback is executed.
- EXPECT_EQ(1, container.drop_count);
- EXPECT_EQ(0, container.cont_count);
- });
-
- // Add() calls Hold() on our OperationContainer implementation. Hold() is
- // supposed to manage the memory. Ours doesn't.
- // The task doesn't run until OperationContainer::Schedule is called with the
- // operation.
- // TODO(thatguy): TestContainer does not manage memory yet, so passing a
- // naked pointer backed by a unique_ptr<> is safe.
- container.Add(op.get());
- EXPECT_EQ(1, container.hold_count);
- EXPECT_EQ(op.get(), container.last_held);
- EXPECT_EQ(0, container.drop_count);
- EXPECT_EQ(0, container.cont_count);
- EXPECT_FALSE(op_ran);
- EXPECT_FALSE(op_done);
-
- // Add() does not enqueue the operation to be run, at least not in our
- // implementation of OperationContainer.
- RunLoopUntilIdle();
- EXPECT_FALSE(op_ran);
- EXPECT_FALSE(op_done);
- EXPECT_EQ(1, container.hold_count);
- EXPECT_EQ(0, container.drop_count);
- EXPECT_EQ(0, container.cont_count);
-
- // OperationContainer impls opt to call Schedule() when they are ready to
- // have an operation enqueued.
- container.Schedule(op.get());
-
- // So when we advance the async loop, we should see that it started running.
- RunLoopUntilIdle();
- EXPECT_TRUE(op_ran);
- EXPECT_FALSE(op_done);
- EXPECT_EQ(1, container.hold_count);
- EXPECT_EQ(0, container.drop_count);
- EXPECT_EQ(0, container.cont_count);
-
- // When the operation reports being done, we expect it to be dropped, our
- // done callback run, and the OperationContainer told to continue. These
- // happen in order. The order is verified in our done callback.
- op->SayDone();
- EXPECT_TRUE(op_ran);
- EXPECT_TRUE(op_done);
- EXPECT_EQ(1, container.hold_count);
- EXPECT_EQ(1, container.drop_count);
- EXPECT_EQ(op.get(), container.last_dropped);
- EXPECT_EQ(1, container.cont_count);
-}
-
-TEST_F(OperationTest, Lifecycle_ContainerGoesAway) {
- // In this test, we make the Operation think that its container's memory has
- // been cleaned up in its done callback. This manifests itself as the
- // Operation not invoking Cont() on the container.
- TestContainer container;
- bool op_ran = false;
- auto op = std::make_unique<TestOperation<>>(
- [&op_ran]() { op_ran = true; },
- [&container]() { container.PretendToDie(); });
-
- container.Add(op.get());
- container.Schedule(op.get());
- RunLoopUntilIdle();
-
- // When the operation reports being done, we expect it to be dropped, our
- // done callback run, and the OperationContainer told to continue. These
- // happen in order. The order is verified in our done callback.
- op->SayDone();
- EXPECT_TRUE(op_ran);
- EXPECT_EQ(1, container.hold_count);
- EXPECT_EQ(1, container.drop_count);
- EXPECT_EQ(op.get(), container.last_dropped);
- EXPECT_EQ(0, container.cont_count);
-}
-
-TEST_F(OperationTest, ResultsAreReceived) {
- // Show that when an operation calls Done(), its arguments are
- // passed to the done callback.
- TestContainer container;
-
- auto op = std::make_unique<TestOperation<int>>(
- [] {}, [](int result) { EXPECT_EQ(42, result); });
-
- container.Add(op.get());
- container.Schedule(op.get());
- RunLoopUntilIdle();
- op->SayDone(42);
-}
-
-class TestFlowTokenOperation : public Operation<int> {
- public:
- TestFlowTokenOperation(ResultCall done)
- : Operation("Test FlowToken Operation", std::move(done)) {}
-
- // |call_before_flow_dies| is invoked before the FlowToken goes out of scope.
- void SayDone(
- int result, std::function<void()> call_before_flow_dies = [] {}) {
- // When |flow| goes out of scope, it will call Done() for us.
- FlowToken flow{this, &result_};
-
- // Post the continuation of the operation to an async loop so that we
- // exercise the refcounting of FlowTokens.
- async::PostTask(async_get_default_dispatcher(),
- [this, flow, result, call_before_flow_dies] {
- result_ = result;
- call_before_flow_dies();
- });
- }
-
- private:
- void Run() override {}
-
- int result_;
-};
-
-TEST_F(OperationTest, Lifecycle_FlowToken) {
- // FlowTokens simply call Done() for you with whatever results you've pointed
- // it at. NOTE(thatguy): I haven't figured out a good way of testing the
- // refcount goodness of FlowTokens. That said, everything else in the world
- // will crash if they fail.
- TestContainer container;
-
- bool done_called{false};
- int result{0};
- auto op =
- std::make_unique<TestFlowTokenOperation>([&result, &done_called](int r) {
- done_called = true;
- result = r;
- });
-
- container.Add(op.get());
- container.Schedule(op.get());
- RunLoopUntilIdle();
- op->SayDone(42);
- // TestFlowTokenOperation posts to the async loop in SayDone(). We shouldn't
- // see Done() called until we run the loop and the FlowToken on the capture
- // list of the callback goes out of scope.
- EXPECT_FALSE(done_called);
- RunLoopUntilIdle();
- EXPECT_EQ(42, result);
-}
-
-TEST_F(OperationTest, Lifecycle_FlowToken_OperationGoesAway) {
- // Similar to Lifecycle_FlowToken, but FlowTokens have the behavior that if
- // their "owning" operation dies before they go out of scope (because, ie,
- // some callback is sitting in someone else's memory longer than the
- // operation lives), they don't call Done() on that operation.
- TestContainer container;
-
- bool done_called = false;
- auto op = std::make_unique<TestFlowTokenOperation>(
- [&done_called](int result) { done_called = true; });
-
- container.Add(op.get());
- container.Schedule(op.get());
- RunLoopUntilIdle();
- op->SayDone(42,
- [&container, &op]() { container.InvalidateWeakPtrs(op.get()); });
- RunLoopUntilIdle();
- EXPECT_FALSE(done_called);
-}
-
-TEST_F(OperationTest, OperationQueue) {
- // Here we test a specific implementation of OperationContainer
- // (OperationQueue), which should only allow one operation to "run" at a
- // given time.
- OperationQueue container;
-
- // OperationQueue, unlike TestContainer, does own the Operations.
- bool op1_ran = false;
- bool op1_done = false;
- auto* op1 = new TestOperation<>([&op1_ran]() { op1_ran = true; },
- [&op1_done]() { op1_done = true; });
-
- bool op3_ran = false;
- bool op3_done = false;
- auto* op3 = new TestOperation<>([&op3_ran]() { op3_ran = true; },
- [&op3_done]() { op3_done = true; });
-
- // We'll queue |op1|, then a fit::promise ("op2") and another Operation,
- // |op3|.
- container.Add(op1);
-
- bool op2_ran = false;
- bool op2_done = false;
- fit::suspended_task suspended_op2;
- container.ScheduleTask(
- fit::make_promise([&](fit::context& c) -> fit::result<> {
- if (op2_ran == true) {
- op2_done = true;
- return fit::ok();
- }
- op2_ran = true;
- suspended_op2 = c.suspend_task();
- return fit::pending();
- }));
-
- container.Add(op3);
-
- // Nothing has run yet because we haven't run the async loop.
- EXPECT_FALSE(op1_ran);
- EXPECT_FALSE(op1_done);
- EXPECT_FALSE(op2_ran);
- EXPECT_FALSE(op2_done);
- EXPECT_FALSE(op3_ran);
- EXPECT_FALSE(op3_done);
-
- // Running the loop we expect op1 to have run, but not completed.
- RunLoopUntilIdle();
- EXPECT_TRUE(op1_ran);
- EXPECT_FALSE(op1_done);
- EXPECT_FALSE(op2_ran);
- EXPECT_FALSE(op2_done);
- EXPECT_FALSE(op3_ran);
- EXPECT_FALSE(op3_done);
-
- // But even if we run more, we do not expect any other ops to run.
- RunLoopUntilIdle();
- EXPECT_TRUE(op1_ran);
- EXPECT_FALSE(op1_done);
- EXPECT_FALSE(op2_ran);
- EXPECT_FALSE(op2_done);
- EXPECT_FALSE(op3_ran);
- EXPECT_FALSE(op3_done);
-
- // If op1 says it's Done(), we expect op2 to run.
- op1->SayDone();
- RunLoopUntilIdle();
- EXPECT_TRUE(op1_done);
- EXPECT_TRUE(op2_ran);
- EXPECT_FALSE(op2_done);
- EXPECT_FALSE(op3_ran);
- EXPECT_FALSE(op3_done);
-
- // Running the loop again should do nothing, as op2 is still pending (until
- // we resume it manuall).
- RunLoopUntilIdle();
- EXPECT_TRUE(suspended_op2);
- EXPECT_FALSE(op2_done);
- EXPECT_FALSE(op3_ran);
- EXPECT_FALSE(op3_done);
-
- // Resume op2, and run the loop again. We expect op3 to start, but not
- // complete.
- suspended_op2.resume_task();
- RunLoopUntilIdle();
- EXPECT_TRUE(op2_done);
- EXPECT_TRUE(op3_ran);
- EXPECT_FALSE(op3_done);
-}
-
-TEST_F(OperationTest, OperationCollection) {
- // OperationCollection starts all operations immediately and lets them run in
- // parallel.
- OperationCollection container;
-
- // OperationQueue, unlike TestContainer, does manage its memory.
- bool op1_ran = false;
- bool op1_done = false;
- auto* op1 = new TestOperation<>([&op1_ran]() { op1_ran = true; },
- [&op1_done]() { op1_done = true; });
-
- bool op2_ran = false;
- bool op2_done = false;
- auto* op2 = new TestOperation<>([&op2_ran]() { op2_ran = true; },
- [&op2_done]() { op2_done = true; });
-
- container.Add(op1);
- container.Add(op2);
- bool op3_ran = false;
- container.ScheduleTask(fit::make_promise([&] { op3_ran = true; }));
-
- // Nothing has run yet because we haven't run the async loop.
- EXPECT_FALSE(op1_ran);
- EXPECT_FALSE(op1_done);
- EXPECT_FALSE(op2_ran);
- EXPECT_FALSE(op2_done);
- EXPECT_FALSE(op3_ran);
-
- // Running the loop we expect all ops to have run. TestOperations won't have
- // completed because they require us to call SayDone(). The fit::promise,
- // however, will have completed (it doesn't suspend).
- RunLoopUntilIdle();
- EXPECT_TRUE(op1_ran);
- EXPECT_FALSE(op1_done);
- EXPECT_TRUE(op2_ran);
- EXPECT_FALSE(op2_done);
- EXPECT_TRUE(op2_ran);
-}
-
-class TestOperationNotNullPtr : public Operation<> {
- public:
- TestOperationNotNullPtr(const FlowToken& parent_flow_token)
- : Operation("Test Operation on container is not nullptr", [] {}),
- parent_flow_token_(parent_flow_token) {}
-
- private:
- void Run() override { FlowToken flow{this}; }
-
- FlowToken parent_flow_token_;
-};
-
-class TestQueueNotNullPtr : public Operation<> {
- public:
- TestQueueNotNullPtr(ResultCall done)
- : Operation("TestQueueNotNullPtr", std::move(done)) {}
-
- private:
- void Run() override {
- // When |flow| goes out of scope, it will call Done() for us.
- FlowToken flow{this};
- operation_queue_.Add(new TestOperationNotNullPtr(flow));
- }
-
- OperationQueue operation_queue_;
-};
-
-class TestCollectionNotNullPtr : public Operation<> {
- public:
- TestCollectionNotNullPtr(ResultCall done)
- : Operation("TestCollectionNotNullPtr", std::move(done)) {}
-
- private:
- void Run() override {
- // When |flow| goes out of scope, it will call Done() for us.
- FlowToken flow{this};
- operation_collection_.Add(new TestOperationNotNullPtr(flow));
- }
-
- OperationCollection operation_collection_;
-};
-
-// See comments on OperationQueue::Drop.
-TEST_F(OperationTest, TestQueueNotNullPtr) {
- OperationQueue container;
-
- bool done_called{false};
- auto op = new TestQueueNotNullPtr([&done_called] { done_called = true; });
-
- container.Add(op);
-
- // Nothing has run yet because we haven't run the async loop.
- EXPECT_FALSE(done_called);
-
- // Running the loop we expect done_called to be set to true
- RunLoopUntilIdle();
- EXPECT_TRUE(done_called);
-}
-
-// See comments on OperationCollection::Drop.
-TEST_F(OperationTest, TestCollectionNotNullPtr) {
- OperationQueue container;
-
- bool done_called{false};
- auto op =
- new TestCollectionNotNullPtr([&done_called] { done_called = true; });
-
- container.Add(op);
-
- // Nothing has run yet because we haven't run the async loop.
- EXPECT_FALSE(done_called);
-
- // Running the loop we expect done_called to be set to true
- RunLoopUntilIdle();
- EXPECT_TRUE(done_called);
-}
-
-TEST_F(OperationTest, WrapFutureAsOperation_WithResult) {
- // Show that when we wrap a Future<> as an operation on a queue, it runs.
- bool op_did_start{};
- bool op_did_finish{};
-
- auto on_run = Future<>::Create(__PRETTY_FUNCTION__);
- auto done = on_run->Map([&]() -> int {
- EXPECT_FALSE(op_did_finish);
- op_did_start = true;
- return 10;
- });
-
- OperationCollection container;
- container.Add(WrapFutureAsOperation(__PRETTY_FUNCTION__, on_run, done,
- std::function<void(int)>([&](int result) {
- EXPECT_EQ(10, result);
- op_did_finish = true;
- })));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(op_did_start);
- EXPECT_TRUE(op_did_finish);
-}
-
-TEST_F(OperationTest, WrapFutureAsOperation_WithoutResult) {
- // Show that when we wrap a Future<> as an operation on a queue, it runs.
- bool op_did_start{};
- bool op_did_finish{};
-
- auto on_run = Future<>::Create(__PRETTY_FUNCTION__);
- auto done = on_run->Then([&] {
- EXPECT_FALSE(op_did_finish);
- op_did_start = true;
- });
-
- OperationCollection container;
- container.Add(WrapFutureAsOperation(
- __PRETTY_FUNCTION__, on_run, done,
- std::function<void()>([&] { op_did_finish = true; })));
-
- RunLoopUntilIdle();
- EXPECT_TRUE(op_did_start);
- EXPECT_TRUE(op_did_finish);
-}
-
-} // namespace
-} // namespace modular
diff --git a/public/lib/context/cpp/BUILD.gn b/public/lib/context/cpp/BUILD.gn
deleted file mode 100644
index de9d96a..0000000
--- a/public/lib/context/cpp/BUILD.gn
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("context_helper") {
- sources = [
- "context_helper.cc",
- "context_helper.h",
- ]
-
- deps = [
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("context_metadata_builder") {
- sources = [
- "context_metadata_builder.cc",
- "context_metadata_builder.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
diff --git a/public/lib/context/cpp/context_helper.cc b/public/lib/context/cpp/context_helper.cc
deleted file mode 100644
index ae71e81..0000000
--- a/public/lib/context/cpp/context_helper.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/context/cpp/context_helper.h>
-
-namespace modular {
-
-std::optional<std::vector<fuchsia::modular::ContextValue>> TakeContextValue(
- fuchsia::modular::ContextUpdate* const update, const std::string& key) {
- for (auto& it : update->values) {
- if (it.key == key) {
- return std::move(it.value);
- }
- }
- return std::nullopt;
-}
-
-void AddToContextQuery(fuchsia::modular::ContextQuery* const query,
- const std::string& key,
- fuchsia::modular::ContextSelector selector) {
- fuchsia::modular::ContextQueryEntry entry;
- entry.key = key;
- entry.value = std::move(selector);
- query->selector.push_back(std::move(entry));
-}
-
-bool HasSelectorKey(fuchsia::modular::ContextQuery* const query,
- const std::string& key) {
- for (auto& it : query->selector) {
- if (it.key == key) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace modular
diff --git a/public/lib/context/cpp/context_helper.h b/public/lib/context/cpp/context_helper.h
deleted file mode 100644
index ba1600c..0000000
--- a/public/lib/context/cpp/context_helper.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_CONTEXT_CPP_CONTEXT_HELPER_H_
-#define LIB_CONTEXT_CPP_CONTEXT_HELPER_H_
-
-#include <utility>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/vector.h>
-
-namespace modular {
-
-// Takes a single value specified by |key| from |update|, and sets
-// |update.values| to null."
-std::optional<std::vector<fuchsia::modular::ContextValue>> TakeContextValue(
- fuchsia::modular::ContextUpdate* update, const std::string& key);
-
-void AddToContextQuery(fuchsia::modular::ContextQuery* query,
- const std::string& key,
- fuchsia::modular::ContextSelector selector);
-
-bool HasSelectorKey(fuchsia::modular::ContextQuery* const query,
- const std::string& key);
-
-} // namespace modular
-
-#endif // LIB_CONTEXT_CPP_CONTEXT_HELPER_H_
diff --git a/public/lib/context/cpp/context_metadata_builder.cc b/public/lib/context/cpp/context_metadata_builder.cc
deleted file mode 100644
index 8b56273..0000000
--- a/public/lib/context/cpp/context_metadata_builder.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/context/cpp/context_metadata_builder.h>
-
-#include <lib/fidl/cpp/clone.h>
-
-namespace maxwell {
-
-ContextMetadataBuilder::ContextMetadataBuilder() {}
-ContextMetadataBuilder::ContextMetadataBuilder(
- fuchsia::modular::ContextMetadata initial_value)
- : m_(std::move(initial_value)) {}
-
-ContextMetadataBuilder& ContextMetadataBuilder::SetStoryId(
- const fidl::StringPtr& story_id) {
- StoryMetadata()->id = story_id;
- return *this;
-}
-
-ContextMetadataBuilder& ContextMetadataBuilder::SetStoryFocused(bool focused) {
- auto& story_meta = StoryMetadata();
- story_meta->focused = fuchsia::modular::FocusedState::New();
- story_meta->focused->state =
- focused ? fuchsia::modular::FocusedStateState::FOCUSED
- : fuchsia::modular::FocusedStateState::NOT_FOCUSED;
- return *this;
-}
-
-ContextMetadataBuilder& ContextMetadataBuilder::SetModuleUrl(
- const fidl::StringPtr& url) {
- ModuleMetadata()->url = url;
- return *this;
-}
-ContextMetadataBuilder& ContextMetadataBuilder::SetModulePath(
- const std::vector<std::string>& path) {
- ModuleMetadata()->path.reset(path);
- return *this;
-}
-
-ContextMetadataBuilder& ContextMetadataBuilder::SetModuleFocused(bool focused) {
- auto& module_meta = ModuleMetadata();
- module_meta->focused = fuchsia::modular::FocusedState::New();
- module_meta->focused->state =
- focused ? fuchsia::modular::FocusedStateState::FOCUSED
- : fuchsia::modular::FocusedStateState::NOT_FOCUSED;
- return *this;
-}
-
-ContextMetadataBuilder& ContextMetadataBuilder::SetEntityTopic(
- const fidl::StringPtr& topic) {
- EntityMetadata()->topic = topic;
- return *this;
-}
-ContextMetadataBuilder& ContextMetadataBuilder::AddEntityType(
- const fidl::StringPtr& type) {
- EntityMetadata()->type.push_back(type);
- return *this;
-}
-ContextMetadataBuilder& ContextMetadataBuilder::SetEntityTypes(
- const std::vector<std::string>& types) {
- EntityMetadata()->type.reset(types);
- return *this;
-}
-ContextMetadataBuilder& ContextMetadataBuilder::SetLinkPath(
- const std::vector<std::string>& module_path,
- const std::string& name) {
- LinkMetadata()->module_path.reset(module_path);
- LinkMetadata()->name = name;
- return *this;
-}
-
-fuchsia::modular::ContextMetadata ContextMetadataBuilder::Build() {
- return std::move(m_);
-}
-
-fuchsia::modular::ContextMetadataPtr ContextMetadataBuilder::BuildPtr() {
- auto meta = fuchsia::modular::ContextMetadata::New();
- *meta.get() = std::move(m_);
- return meta;
-}
-
-#define ENSURE_MEMBER(field, class_name) \
- if (!m_.field) { \
- m_.field = fuchsia::modular::class_name::New(); \
- } \
- return m_.field;
-
-fuchsia::modular::StoryMetadataPtr& ContextMetadataBuilder::StoryMetadata() {
- ENSURE_MEMBER(story, StoryMetadata);
-}
-
-fuchsia::modular::ModuleMetadataPtr& ContextMetadataBuilder::ModuleMetadata() {
- ENSURE_MEMBER(mod, ModuleMetadata);
-}
-
-fuchsia::modular::EntityMetadataPtr& ContextMetadataBuilder::EntityMetadata() {
- ENSURE_MEMBER(entity, EntityMetadata);
-}
-
-fuchsia::modular::LinkMetadataPtr& ContextMetadataBuilder::LinkMetadata() {
- ENSURE_MEMBER(link, LinkMetadata);
-}
-
-} // namespace maxwell
diff --git a/public/lib/context/cpp/context_metadata_builder.h b/public/lib/context/cpp/context_metadata_builder.h
deleted file mode 100644
index ebb3263..0000000
--- a/public/lib/context/cpp/context_metadata_builder.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_CONTEXT_CPP_CONTEXT_METADATA_BUILDER_H_
-#define LIB_CONTEXT_CPP_CONTEXT_METADATA_BUILDER_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-namespace maxwell {
-
-class ContextMetadataBuilder {
- public:
- ContextMetadataBuilder();
- explicit ContextMetadataBuilder(
- fuchsia::modular::ContextMetadata initial_value);
-
- ContextMetadataBuilder& SetStoryId(const fidl::StringPtr& story_id);
- ContextMetadataBuilder& SetStoryFocused(bool focused);
-
- ContextMetadataBuilder& SetModuleUrl(const fidl::StringPtr& url);
- ContextMetadataBuilder& SetModulePath(
- const std::vector<std::string>& path);
- ContextMetadataBuilder& SetModuleFocused(bool focused);
-
- ContextMetadataBuilder& SetEntityTopic(const fidl::StringPtr& topic);
- ContextMetadataBuilder& AddEntityType(const fidl::StringPtr& type);
- ContextMetadataBuilder& SetEntityTypes(
- const std::vector<std::string>& types);
-
- ContextMetadataBuilder& SetLinkPath(
- const std::vector<std::string>& module_path,
- const std::string& name);
-
- // Build() or BuildPtr() can be called only once, as they move |m_|.
- fuchsia::modular::ContextMetadata Build();
- fuchsia::modular::ContextMetadataPtr BuildPtr();
-
- private:
- fuchsia::modular::StoryMetadataPtr& StoryMetadata();
- fuchsia::modular::ModuleMetadataPtr& ModuleMetadata();
- fuchsia::modular::EntityMetadataPtr& EntityMetadata();
- fuchsia::modular::LinkMetadataPtr& LinkMetadata();
-
- fuchsia::modular::ContextMetadata m_;
-};
-
-} // namespace maxwell
-
-#endif // LIB_CONTEXT_CPP_CONTEXT_METADATA_BUILDER_H_
diff --git a/public/lib/entity/cpp/BUILD.gn b/public/lib/entity/cpp/BUILD.gn
deleted file mode 100644
index ef2b026..0000000
--- a/public/lib/entity/cpp/BUILD.gn
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("cpp") {
- deps = [
- ":json",
- ]
-}
-
-group("unittests") {
- testonly = true
-
- deps = [
- ":json_unittest",
- ]
-}
-
-source_set("json") {
- sources = [
- "json.cc",
- "json.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//third_party/rapidjson",
- ]
-}
-
-source_set("json_unittest") {
- testonly = true
-
- sources = [
- "json_unittest.cc",
- ]
-
- deps = [
- ":json",
- "//third_party/googletest:gtest",
- "//third_party/rapidjson",
- ]
-}
diff --git a/public/lib/entity/cpp/json.cc b/public/lib/entity/cpp/json.cc
deleted file mode 100644
index 20670f1..0000000
--- a/public/lib/entity/cpp/json.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/entity/cpp/json.h>
-
-#include <string>
-
-#include <lib/fxl/logging.h>
-
-#include "rapidjson/stringbuffer.h"
-#include "rapidjson/writer.h"
-
-namespace modular {
-
-constexpr char kEntityTypeProperty[] = "@type";
-constexpr char kEntityRefAttribute[] = "@entityRef";
-
-constexpr char kEntityTypeString[] = "com.google.fuchsia.string";
-// We use |kEntityTypeUnknown| if the entity doesn't have a type.
-constexpr char kEntityTypeUnknown[] = "com.google.fuchsia.unknown";
-
-std::string EntityReferenceToJson(const std::string& ref) {
- auto doc = EntityReferenceToJsonDoc(ref);
-
- rapidjson::StringBuffer buffer;
- rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
- doc.Accept(writer);
- return buffer.GetString();
-}
-
-rapidjson::Document EntityReferenceToJsonDoc(const std::string& ref) {
- // Create an object that looks like:
- // {
- // "@entityRef": "<ref string>"
- // }
- rapidjson::Document doc;
- doc.SetObject();
- rapidjson::Value str;
- str.SetString(ref, doc.GetAllocator());
- doc.AddMember(kEntityRefAttribute, str, doc.GetAllocator());
- return doc;
-}
-
-bool EntityReferenceFromJson(const std::string& json, std::string* ref) {
- rapidjson::Document doc;
- doc.Parse(json);
- if (doc.HasParseError())
- return false;
- return EntityReferenceFromJson(doc, ref);
-}
-bool EntityReferenceFromJson(const rapidjson::Value& value, std::string* ref) {
- if (!value.IsObject() || !value.HasMember(kEntityRefAttribute))
- return false;
-
- auto& attr = value[kEntityRefAttribute];
- if (!attr.IsString())
- return false;
- *ref = attr.GetString();
- return true;
-}
-
-bool ExtractEntityTypesFromJson(const std::string& json,
- std::vector<std::string>* const output) {
- FXL_CHECK(output != nullptr);
- // If the content has the @type attribute, take its contents and populate the
- // fuchsia::modular::EntityMetadata appropriately, overriding whatever is
- // there.
- rapidjson::Document doc;
- doc.Parse(json);
- if (doc.HasParseError()) {
- FXL_LOG(WARNING) << "Error parsing JSON: " << doc.GetParseError();
- return false;
- }
-
- return ExtractEntityTypesFromJson(doc, output);
-}
-
-bool ExtractEntityTypesFromJson(const rapidjson::Value& value,
- std::vector<std::string>* const output) {
- std::vector<std::string> entity_types;
-
- if (value.IsString()) {
- entity_types.emplace_back(kEntityTypeString);
- } else if (value.IsObject() && value.HasMember(kEntityTypeProperty)) {
- const auto& types = value[kEntityTypeProperty];
- if (types.IsString()) {
- entity_types.emplace_back(types.GetString());
- } else if (types.IsArray()) {
- for (uint32_t i = 0; i < types.Size(); ++i) {
- if (!types[i].IsString())
- return false;
- entity_types.emplace_back(types[i].GetString());
- }
- } else {
- return false;
- }
- } else {
- entity_types.push_back(kEntityTypeUnknown);
- }
-
- output->swap(entity_types);
- return true;
-}
-
-} // namespace modular
diff --git a/public/lib/entity/cpp/json.h b/public/lib/entity/cpp/json.h
deleted file mode 100644
index ebe9e55..0000000
--- a/public/lib/entity/cpp/json.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_ENTITY_CPP_JSON_H_
-#define LIB_ENTITY_CPP_JSON_H_
-
-#include <string>
-#include <vector>
-
-#include "rapidjson/document.h"
-
-namespace modular {
-
-// Returns a JSON string that can be used with EntityReferenceFromJson().
-std::string EntityReferenceToJson(const std::string& ref);
-// Like above but returns a rapidjson::Document.
-rapidjson::Document EntityReferenceToJsonDoc(const std::string& ref);
-
-// Returns false if |json| does not represent an fuchsia::modular::Entity
-// reference.
-bool EntityReferenceFromJson(const std::string& json, std::string* ref);
-// Like above but operates on a rapidjson::Value.
-bool EntityReferenceFromJson(const rapidjson::Value& value, std::string* ref);
-
-// Extracts the values of the JSON object |doc|'s "@type" attribute into
-// |types|. Returns false and leaves |types| untouched if |doc| is not JSON
-// or is not structured in a way that we can extract types.
-bool ExtractEntityTypesFromJson(const std::string& json,
- std::vector<std::string>* output);
-bool ExtractEntityTypesFromJson(const rapidjson::Value& value,
- std::vector<std::string>* output);
-
-} // namespace modular
-
-#endif // LIB_ENTITY_CPP_JSON_H_
diff --git a/public/lib/entity/cpp/json_unittest.cc b/public/lib/entity/cpp/json_unittest.cc
deleted file mode 100644
index 24f34f9..0000000
--- a/public/lib/entity/cpp/json_unittest.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/entity/cpp/json.h>
-
-#include <string>
-
-#include "gtest/gtest.h"
-#include "rapidjson/document.h"
-
-namespace modular {
-
-TEST(EntityJsonTest, EntityReferenceToJson) {
- auto ret = EntityReferenceToJson("reference");
- EXPECT_EQ(R"({"@entityRef":"reference"})", ret);
-}
-
-TEST(EntityJsonTest, EntityReferenceToJsonDoc) {
- auto ret = EntityReferenceToJsonDoc("reference");
- EXPECT_TRUE(ret.IsObject());
- EXPECT_TRUE(ret.HasMember("@entityRef"));
- EXPECT_EQ("reference", std::string(ret["@entityRef"].GetString()));
-}
-
-TEST(EntityJsonTest, EntityReferenceFromJson) {
- std::string ret;
- EXPECT_FALSE(EntityReferenceFromJson("invalid", &ret));
- EXPECT_FALSE(EntityReferenceFromJson("1", &ret));
- EXPECT_FALSE(EntityReferenceFromJson(R"({"@entityRoof":"reference"})", &ret));
- EXPECT_FALSE(EntityReferenceFromJson(R"({"@entityRef":12345})", &ret));
- EXPECT_FALSE(
- EntityReferenceFromJson(R"({"@entityRef":["reference"]})", &ret));
-
- EXPECT_TRUE(EntityReferenceFromJson(R"({"@entityRef":"reference"})", &ret));
- EXPECT_EQ("reference", ret);
-
- // EntityReferenceFromJson(rapidjson::Value) is tested implicitly with the
- // above.
-}
-
-TEST(EntityJsonTest, ExtractEntityTypesFromJson) {
- std::vector<std::string> types;
-
- // Unknown type cases.
- types = {"com.google.fuchsia.unknown"};
- EXPECT_TRUE(ExtractEntityTypesFromJson("1", &types));
- EXPECT_TRUE(ExtractEntityTypesFromJson("[1,2,3]", &types));
- EXPECT_TRUE(ExtractEntityTypesFromJson("{}", &types));
- EXPECT_TRUE(ExtractEntityTypesFromJson(R"({"type": "foo"})", &types));
- types.clear();
-
- // Types that have a bad format.
- EXPECT_FALSE(ExtractEntityTypesFromJson(R"({"@type": 1})", &types));
- EXPECT_FALSE(ExtractEntityTypesFromJson(R"({"@type": {}})", &types));
- EXPECT_FALSE(ExtractEntityTypesFromJson(R"({"@type": [1,"foo"]})", &types));
- types.clear();
-
- // JSON string case.
- EXPECT_TRUE(ExtractEntityTypesFromJson(R"("hello")", &types));
- EXPECT_EQ(1lu, types.size());
- EXPECT_EQ("com.google.fuchsia.string", types[0]);
- types.clear();
-
- // Explicit "@type" case.
- EXPECT_TRUE(ExtractEntityTypesFromJson(R"({"@type": "foo"})", &types));
- EXPECT_EQ(1lu, types.size());
- EXPECT_EQ("foo", types[0]);
- types.clear();
-
- EXPECT_TRUE(ExtractEntityTypesFromJson(R"({"@type":["foo","bar"]})", &types));
- EXPECT_EQ(2lu, types.size());
- EXPECT_EQ("foo", types[0]);
- EXPECT_EQ("bar", types[1]);
- types.clear();
-}
-
-} // namespace modular
diff --git a/public/lib/fostr/fidl/fuchsia.ledger/BUILD.gn b/public/lib/fostr/fidl/fuchsia.ledger/BUILD.gn
deleted file mode 100644
index 2427fd6..0000000
--- a/public/lib/fostr/fidl/fuchsia.ledger/BUILD.gn
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//garnet/public/build/fostr/fostr_fidl.gni")
-
-fostr_fidl("fuchsia.ledger") {
- fidl_target = "//peridot/public/fidl/fuchsia.ledger"
-
- deps = [
- "//garnet/public/lib/fostr/fidl/fuchsia.mem",
- ]
-}
diff --git a/public/lib/fostr/fidl/fuchsia.ledger/MAINTAINERS b/public/lib/fostr/fidl/fuchsia.ledger/MAINTAINERS
deleted file mode 100644
index d0e7ba7..0000000
--- a/public/lib/fostr/fidl/fuchsia.ledger/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-etiennej@google.com
-qsr@google.com
diff --git a/public/lib/fostr/fidl/fuchsia.modular.auth/BUILD.gn b/public/lib/fostr/fidl/fuchsia.modular.auth/BUILD.gn
deleted file mode 100644
index 04f05d3..0000000
--- a/public/lib/fostr/fidl/fuchsia.modular.auth/BUILD.gn
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//garnet/public/build/fostr/fostr_fidl.gni")
-
-fostr_fidl("fuchsia.modular.auth") {
- fidl_target = "//peridot/public/fidl/fuchsia.modular.auth"
-
- deps = [
- "//garnet/public/lib/fostr/fidl/fuchsia.ui.viewsv1token",
- ]
-}
diff --git a/public/lib/fostr/fidl/fuchsia.modular.internal/BUILD.gn b/public/lib/fostr/fidl/fuchsia.modular.internal/BUILD.gn
deleted file mode 100644
index d4293b8..0000000
--- a/public/lib/fostr/fidl/fuchsia.modular.internal/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//garnet/public/build/fostr/fostr_fidl.gni")
-
-fostr_fidl("fuchsia.modular.internal") {
- fidl_target = "//peridot/public/fidl/fuchsia.modular.internal"
-
- deps = [
- "//garnet/public/lib/fostr/fidl/fuchsia.auth",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular",
- ]
-}
diff --git a/public/lib/fostr/fidl/fuchsia.modular.storymodel/BUILD.gn b/public/lib/fostr/fidl/fuchsia.modular.storymodel/BUILD.gn
deleted file mode 100644
index f90f8c9..0000000
--- a/public/lib/fostr/fidl/fuchsia.modular.storymodel/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//garnet/public/build/fostr/fostr_fidl.gni")
-
-fostr_fidl("fuchsia.modular.storymodel") {
- fidl_target = "//peridot/public/fidl/fuchsia.modular.storymodel"
-
- deps = [
- "//garnet/public/lib/fostr/fidl/fuchsia.sys2",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular",
- ]
-}
diff --git a/public/lib/fostr/fidl/fuchsia.modular/BUILD.gn b/public/lib/fostr/fidl/fuchsia.modular/BUILD.gn
deleted file mode 100644
index b8ea12d..0000000
--- a/public/lib/fostr/fidl/fuchsia.modular/BUILD.gn
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//garnet/public/build/fostr/fostr_fidl.gni")
-
-fostr_fidl("fuchsia.modular") {
- fidl_target = "//peridot/public/fidl/fuchsia.modular"
-
- deps = [
- "//garnet/public/lib/fostr/fidl/fuchsia.auth",
- "//garnet/public/lib/fostr/fidl/fuchsia.images",
- "//garnet/public/lib/fostr/fidl/fuchsia.media",
- "//garnet/public/lib/fostr/fidl/fuchsia.mem",
- "//garnet/public/lib/fostr/fidl/fuchsia.ui.policy",
- "//garnet/public/lib/fostr/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fostr/fidl/fuchsia.ui.viewsv1token",
- "//peridot/public/lib/fostr/fidl/fuchsia.ledger",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular.auth",
- "//peridot/public/lib/fostr/fidl/fuchsia.speech",
- ]
-}
diff --git a/public/lib/fostr/fidl/fuchsia.speech/BUILD.gn b/public/lib/fostr/fidl/fuchsia.speech/BUILD.gn
deleted file mode 100644
index f4b4bd4..0000000
--- a/public/lib/fostr/fidl/fuchsia.speech/BUILD.gn
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//garnet/public/build/fostr/fostr_fidl.gni")
-
-fostr_fidl("fuchsia.speech") {
- fidl_target = "//peridot/public/fidl/fuchsia.speech"
-}
diff --git a/public/lib/integration_testing/cpp/BUILD.gn b/public/lib/integration_testing/cpp/BUILD.gn
deleted file mode 100644
index 51fbf52..0000000
--- a/public/lib/integration_testing/cpp/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("cpp") {
- sources = [
- "reporting.cc",
- "reporting.h",
- "testing.cc",
- "testing.h",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/lib/component/cpp",
- ]
-}
diff --git a/public/lib/integration_testing/cpp/reporting.cc b/public/lib/integration_testing/cpp/reporting.cc
deleted file mode 100644
index d89ee81..0000000
--- a/public/lib/integration_testing/cpp/reporting.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/integration_testing/cpp/reporting.h>
-
-namespace modular {
-namespace testing {
-
-TestPoint::TestPoint(std::string label) : label_(std::move(label)) {
- RegisterTestPoint(label_);
-}
-
-TestPoint::~TestPoint() {
- if (!value_)
- TEST_FAIL(label_);
-}
-
-void TestPoint::Pass() {
- value_ = true;
- TEST_PASS(label_);
- PassTestPoint(label_);
-}
-
-} // namespace testing
-} // namespace modular
diff --git a/public/lib/integration_testing/cpp/reporting.h b/public/lib/integration_testing/cpp/reporting.h
deleted file mode 100644
index e5ecbc6..0000000
--- a/public/lib/integration_testing/cpp/reporting.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_INTEGRATION_TESTING_CPP_REPORTING_H_
-#define LIB_INTEGRATION_TESTING_CPP_REPORTING_H_
-
-#include <iostream>
-
-#include <fuchsia/testing/runner/cpp/fidl.h>
-
-#include <lib/integration_testing/cpp/testing.h>
-
-#define TEST_PASS(label) std::cerr << "[TEST] PASS: " << (label) << std::endl
-#define TEST_FAIL(label) \
- { \
- std::cerr << "[TEST] FAIL: " << (label) << std::endl; \
- testing::Fail(label); \
- }
-
-namespace modular {
-namespace testing {
-
-// Helper class to record that a particular condition was reached sometime
-// in the life span of an object. If the test point is not marked with Pass()
-// by the time the destructor is called, the test point records failure.
-class TestPoint {
- public:
- explicit TestPoint(std::string label);
- ~TestPoint();
-
- void Pass();
-
- private:
- std::string label_;
- bool value_{};
-};
-
-} // namespace testing
-} // namespace modular
-
-#endif // LIB_INTEGRATION_TESTING_CPP_REPORTING_H_
diff --git a/public/lib/integration_testing/cpp/testing.cc b/public/lib/integration_testing/cpp/testing.cc
deleted file mode 100644
index 8866f7d..0000000
--- a/public/lib/integration_testing/cpp/testing.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/integration_testing/cpp/testing.h>
-
-#include <set>
-
-#include <fuchsia/testing/runner/cpp/fidl.h>
-#include <lib/fxl/logging.h>
-
-using fuchsia::testing::runner::TestRunner;
-using fuchsia::testing::runner::TestRunnerPtr;
-using fuchsia::testing::runner::TestRunnerStore;
-using fuchsia::testing::runner::TestRunnerStorePtr;
-
-namespace modular {
-namespace testing {
-
-namespace {
-TestRunnerPtr g_test_runner;
-TestRunnerStorePtr g_test_runner_store;
-std::set<std::string> g_test_points;
-bool g_connected;
-} // namespace
-
-void Init(component::StartupContext* context, const std::string& identity) {
- FXL_CHECK(context);
- FXL_CHECK(!g_test_runner.is_bound());
- FXL_CHECK(!g_test_runner_store.is_bound());
-
- g_test_runner = context->ConnectToEnvironmentService<TestRunner>();
- g_test_runner.set_error_handler([](zx_status_t status) {
- if (g_connected) {
- FXL_LOG(ERROR) << "Lost connection to TestRunner. This indicates that "
- "there was an observed process that was terminated "
- "without calling TestRunner.Done().";
- } else {
- FXL_LOG(ERROR) << "This application must be run under test_runner.";
- }
- exit(1);
- });
- g_test_runner->Identify(identity, [] { g_connected = true; });
- g_test_runner->SetTestPointCount(g_test_points.size());
- g_test_runner_store = context->ConnectToEnvironmentService<TestRunnerStore>();
-}
-
-void Fail(const std::string& log_msg) {
- if (g_test_runner.is_bound()) {
- g_test_runner->Fail(log_msg);
- }
-}
-
-void Done(const std::function<void()>& ack) {
- if (g_test_runner.is_bound()) {
- g_test_runner->Done([ack] {
- ack();
- g_test_runner.Unbind();
- });
- } else {
- ack();
- }
-
- if (g_test_runner_store.is_bound()) {
- g_test_runner_store.Unbind();
- }
-}
-
-void Teardown(const std::function<void()>& ack) {
- if (g_test_runner.is_bound()) {
- g_test_runner->Teardown([ack] {
- ack();
- g_test_runner.Unbind();
- });
- } else {
- ack();
- }
-
- if (g_test_runner_store.is_bound()) {
- g_test_runner_store.Unbind();
- }
-}
-
-TestRunnerStore* GetStore() {
- FXL_CHECK(g_test_runner_store.is_bound());
- return g_test_runner_store.get();
-}
-
-std::function<void(fidl::StringPtr)> NewBarrierClosure(
- const int limit, std::function<void()> proceed) {
- return [limit, count = std::make_shared<int>(0),
- proceed = std::move(proceed)](fidl::StringPtr value) {
- ++*count;
- if (*count == limit) {
- proceed();
- }
- };
-}
-
-void Put(const fidl::StringPtr& key, const fidl::StringPtr& value) {
- modular::testing::GetStore()->Put(key, value, [] {});
-}
-
-void Get(const fidl::StringPtr& key,
- std::function<void(fidl::StringPtr)> callback) {
- modular::testing::GetStore()->Get(key, std::move(callback));
-}
-
-void Signal(const fidl::StringPtr& condition) {
- modular::testing::GetStore()->Put(condition, condition, [] {});
-}
-
-void Await(const fidl::StringPtr& condition, std::function<void()> cont) {
- modular::testing::GetStore()->Get(
- condition, [cont = std::move(cont)](fidl::StringPtr) { cont(); });
-}
-
-void RegisterTestPoint(const std::string& label) {
- // Test points can only be registered before Init is called.
- FXL_CHECK(!g_test_runner.is_bound())
- << "Test Runner connection not bound. You must call "
- << "ComponentBase::TestInit() before registering "
- << "\"" << label << "\".";
-
- auto inserted = g_test_points.insert(label);
-
- // Test points must have unique labels.
- FXL_CHECK(inserted.second) << "Test points must have unique labels. "
- << "\"" << label << "\" is repeated.";
-}
-
-void PassTestPoint(const std::string& label) {
- // Test points can only be passed after initialization.
- FXL_CHECK(g_test_runner.is_bound())
- << "Test Runner connection not bound. You must call "
- << "ComponentBase::TestInit() before \"" << label << "\".Pass() can be "
- << "called.";
-
- // Test points can only be passed once.
- FXL_CHECK(g_test_points.erase(label))
- << "TEST FAILED: Test point can only be passed once. "
- << "\"" << label << "\".Pass() has been called twice.";
-
- g_test_runner->PassTestPoint();
-}
-
-} // namespace testing
-} // namespace modular
diff --git a/public/lib/integration_testing/cpp/testing.h b/public/lib/integration_testing/cpp/testing.h
deleted file mode 100644
index e8acde5..0000000
--- a/public/lib/integration_testing/cpp/testing.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_INTEGRATION_TESTING_CPP_TESTING_H_
-#define LIB_INTEGRATION_TESTING_CPP_TESTING_H_
-
-#include <string>
-
-#include <fuchsia/testing/runner/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-
-namespace modular {
-namespace testing {
-
-// TestStore key used to signal termination of the integration test suite to the
-// DevBaseShell, causing it to call Shutdown().
-constexpr char kTestShutdown[] = "test_shutdown";
-
-// Integration tests that run under DevBaseShell are cut off after this
-// timeout.
-constexpr int kTestTimeoutMilliseconds = 30000;
-
-// Connects to the TestRunner service in the caller's Environment.
-// This function must be invoked first before calling any of the ones below. A
-// test is expected to call either Done() or Teardown() before terminating
-// itself in order for the TestRunner service to know that a test process did
-// not crash, or that the test has completed and should be torn down.
-void Init(component::StartupContext* context, const std::string& identity);
-
-// Marks the test a failure with the given |log_msg| message, but does not tear
-// it down; the test may continue running. Once the test signals teardown by
-// calling Teardown(), the test is finished as a failure.
-void Fail(const std::string& log_msg);
-
-// A test must call Done() before it dies, to let the TestRunner service (which
-// has a channel connected to this application) know that this test process has
-// not crashed, otherwise it must call Teardown() to signal the TestRunner that
-// the test has finished altogether. If Done() is not called and the connection
-// to the TestService is broken, the test is declared as failed and is torn
-// down. If Done() is called, it is not possible to call Teardown().
-//
-// The calling test component should defer its own exit until test runner has
-// acknowledged the receipt of the message using the ack callback. Otherwise
-// there is a race between the teardown request and the close of the connection
-// to the application controller. If the close of the application controller is
-// noticed first by the test runner, it terminates the test as failed.
-void Done(const std::function<void()>& ack);
-
-// A test may call Teardown() to finish the test run and tear down the service.
-// Unless Fail() is called, the TestRunner will consider the test run as having
-// passed successfully.
-//
-// The calling test component should defer its own exit until test runner has
-// acknowledged the receipt of the message using the ack callback. Otherwise
-// there is a race between the teardown request and the close of the connection
-// to the application controller. If the close of the application controller is
-// noticed first by the test runner, it terminates the test as failed.
-void Teardown(const std::function<void()>& ack);
-
-// Returns the TestRunnerStore interface from the caller's
-// Environment. Init() must be called before GetStore().
-fuchsia::testing::runner::TestRunnerStore* GetStore();
-
-// Creates function that invokes the |proceed| callback after being called
-// |limit| times.
-std::function<void(fidl::StringPtr)> NewBarrierClosure(
- const int limit, std::function<void()> proceed);
-
-// Defined for convenience of using GetStore().
-void Put(const fidl::StringPtr& key, const fidl::StringPtr& value);
-
-// Defined for convenience of using GetStore(). Listens for the |key|; the value
-// is passed to the |callback| function.
-void Get(const fidl::StringPtr& key,
- std::function<void(fidl::StringPtr)> callback);
-
-// Defined for convenience of using GetStore(). The |condition| is used as both
-// the key and the value. When listening for the key using Get(), the value is
-// used by the receiver to display what key it was waiting on. That way the same
-// receiver function can be used to wait for multiple keys. Otherwise, Await()
-// can be used to listen for the key.
-void Signal(const fidl::StringPtr& condition);
-
-// Defined for convenience of using GetStore(). Waits for |condition| to be
-// present as a key in the TestRunnerStore before calling |cont|. The value on
-// that key is not exposed to the receiver function |cont|.
-void Await(const fidl::StringPtr& condition, std::function<void()> cont);
-
-// Registers a test point that should pass for a test to be considered
-// successful.
-void RegisterTestPoint(const std::string& label);
-
-// Signals that a test point has been passed.
-void PassTestPoint(const std::string& label);
-
-} // namespace testing
-} // namespace modular
-
-#endif // LIB_INTEGRATION_TESTING_CPP_TESTING_H_
diff --git a/public/lib/lifecycle/cpp/BUILD.gn b/public/lib/lifecycle/cpp/BUILD.gn
deleted file mode 100644
index 25d603c..0000000
--- a/public/lib/lifecycle/cpp/BUILD.gn
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-
-group("cpp") {
- public_deps = [
- ":lifecycle_impl",
- ]
-}
-
-source_set("lifecycle_impl") {
- sources = [
- "lifecycle_impl.cc",
- "lifecycle_impl.h",
- ]
-
- deps = [
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/svc/cpp",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
diff --git a/public/lib/lifecycle/cpp/lifecycle_impl.cc b/public/lib/lifecycle/cpp/lifecycle_impl.cc
deleted file mode 100644
index b65de12..0000000
--- a/public/lib/lifecycle/cpp/lifecycle_impl.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/lifecycle/cpp/lifecycle_impl.h>
-
-namespace modular {
-
-LifecycleImpl::LifecycleImpl(component::ServiceNamespace* service_namespace,
- LifecycleImpl::Delegate* delegate)
- : delegate_(delegate), binding_(this) {
- service_namespace->AddService<fuchsia::modular::Lifecycle>(
- [this](fidl::InterfaceRequest<fuchsia::modular::Lifecycle> request) {
- binding_.Bind(std::move(request));
- });
-}
-
-// |fuchsia::modular::Lifecycle|
-void LifecycleImpl::Terminate() {
- binding_.Unbind();
- delegate_->Terminate();
-}
-
-} // namespace modular
diff --git a/public/lib/lifecycle/cpp/lifecycle_impl.h b/public/lib/lifecycle/cpp/lifecycle_impl.h
deleted file mode 100644
index 61182c4..0000000
--- a/public/lib/lifecycle/cpp/lifecycle_impl.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_LIFECYCLE_CPP_LIFECYCLE_IMPL_H_
-#define LIB_LIFECYCLE_CPP_LIFECYCLE_IMPL_H_
-
-#include <functional>
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/macros.h>
-#include <lib/svc/cpp/service_namespace.h>
-
-namespace modular {
-
-class LifecycleImpl : fuchsia::modular::Lifecycle {
- public:
- // Users of LifecycleImpl register a delegate to receive Terminate().
- class Delegate {
- public:
- virtual void Terminate() = 0;
- };
-
- // |Delegate.Terminate()| is called when a
- // fuchsia::modular::Lifecycle.Terminate message is received.
- LifecycleImpl(component::ServiceNamespace* service_namespace,
- Delegate* delegate);
-
- private:
- // |fuchsia::modular::Lifecycle|
- void Terminate() override;
-
- Delegate* const delegate_;
- fidl::Binding<fuchsia::modular::Lifecycle> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LifecycleImpl);
-};
-
-} // namespace modular
-
-#endif // LIB_LIFECYCLE_CPP_LIFECYCLE_IMPL_H_
diff --git a/public/lib/message_queue/cpp/BUILD.gn b/public/lib/message_queue/cpp/BUILD.gn
deleted file mode 100644
index 04b245c..0000000
--- a/public/lib/message_queue/cpp/BUILD.gn
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("cpp") {
- public_deps = [
- ":message_queue_client",
- ":message_sender_client",
- ]
-}
-
-source_set("message_queue_client") {
- sources = [
- "message_queue_client.cc",
- "message_queue_client.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
-
-source_set("message_sender_client") {
- sources = [
- "message_sender_client.cc",
- "message_sender_client.h",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- ]
-}
diff --git a/public/lib/message_queue/cpp/message_queue_client.cc b/public/lib/message_queue/cpp/message_queue_client.cc
deleted file mode 100644
index cd051dd..0000000
--- a/public/lib/message_queue/cpp/message_queue_client.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/fsl/vmo/strings.h>
-#include <lib/message_queue/cpp/message_queue_client.h>
-
-namespace modular {
-
-MessageQueueClient::MessageQueueClient() : reader_(this) {}
-
-fidl::InterfaceRequest<fuchsia::modular::MessageQueue>
-MessageQueueClient::NewRequest() {
- if (reader_.is_bound()) {
- reader_.Unbind();
- receiver_ = nullptr;
- }
-
- return queue_.NewRequest();
-}
-
-void MessageQueueClient::GetToken(
- std::function<void(fidl::StringPtr)> callback) {
- queue_->GetToken(callback);
-}
-
-void MessageQueueClient::RegisterReceiver(ReceiverCallback receiver) {
- receiver_ = std::move(receiver);
-
- if (!receiver_) {
- reader_.Unbind();
- return;
- }
-
- if (!reader_.is_bound()) {
- queue_->RegisterReceiver(reader_.NewBinding());
- }
-}
-
-// |fuchsia::modular::MessageReader|
-void MessageQueueClient::OnReceive(fuchsia::mem::Buffer message,
- std::function<void()> ack) {
- FXL_DCHECK(reader_.is_bound());
-
- std::string str;
- FXL_CHECK(fsl::StringFromVmo(message, &str));
-
- receiver_(std::move(str), std::move(ack));
-}
-
-} // namespace modular
\ No newline at end of file
diff --git a/public/lib/message_queue/cpp/message_queue_client.h b/public/lib/message_queue/cpp/message_queue_client.h
deleted file mode 100644
index 1324f99..0000000
--- a/public/lib/message_queue/cpp/message_queue_client.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_MESSAGE_QUEUE_CPP_MESSAGE_QUEUE_CLIENT_H_
-#define LIB_MESSAGE_QUEUE_CPP_MESSAGE_QUEUE_CLIENT_H_
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fit/function.h>
-
-#include "lib/fxl/macros.h"
-
-namespace modular {
-
-// MessageQueueClient is a wrapper class for using fuchsia.modular.MessageQueue
-// in a more convinient way. This class represents messages as a std::string,
-// which the underlying fidl interface may not.
-//
-// Usage:
-//
-// // 1. Obtain message queue and use it with MessageQueueClient.
-// MessageQueueClient message_queue;
-// component_context->ObtainMessageQueue("my_msg_q",
-// message_queue.NewRequest());
-//
-// // 2. Register receiver. New messages are sent to the supplied callback until
-// // the MessageQueueClient goes out of scope, or the receiver is
-// // unregistered. To unregister the receiver, call this method with a
-// // |nullptr| receiver.
-// message_queue.RegisterReceiver([] (std::string msg, fit::function<void> ack){
-// ack(); // Acknowledge message receipt. We will continue to have new
-// // messages delivered to this callback.
-// FXL_LOG(INFO) << "new message: " << msg;
-// });
-class MessageQueueClient : public fuchsia::modular::MessageReader {
- public:
- using ReceiverCallback =
- fit::function<void(std::string message, fit::function<void()> ack)>;
-
- MessageQueueClient();
-
- // Creates a new interface pair, binds one end to this object and returns the
- // request side. The previous message queue and receiver are unbound.
- fidl::InterfaceRequest<fuchsia::modular::MessageQueue> NewRequest();
-
- // Register a receiver callback, which will be called everytime there is a new
- // message. The receiver is supplied the message and an acknowledgement
- // callback which the receiver must call, to acknowledge that the message has
- // been processed and does not need to be received again. Supplying a
- // |nullptr| will unregister the previous receiver.
- void RegisterReceiver(ReceiverCallback receiver);
-
- // Returns a token for this message queue, which is used to send messages
- // to this message queue.
- void GetToken(std::function<void(fidl::StringPtr)> callback);
-
- private:
- // |fuchsia::modular::MessageReader|
- void OnReceive(fuchsia::mem::Buffer message,
- std::function<void()> ack) override;
-
- fuchsia::modular::MessageQueuePtr queue_;
- fidl::Binding<fuchsia::modular::MessageReader> reader_;
- ReceiverCallback receiver_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(MessageQueueClient);
-};
-
-} // namespace modular
-
-#endif // LIB_MESSAGE_QUEUE_CPP_MESSAGE_QUEUE_CLIENT_H_
diff --git a/public/lib/message_queue/cpp/message_sender_client.cc b/public/lib/message_queue/cpp/message_sender_client.cc
deleted file mode 100644
index a3ac394..0000000
--- a/public/lib/message_queue/cpp/message_sender_client.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <lib/message_queue/cpp/message_sender_client.h>
-
-#include <lib/fsl/vmo/strings.h>
-
-namespace modular {
-
-MessageSenderClient::MessageSenderClient() = default;
-
-void MessageSenderClient::Send(fxl::StringView msg) {
- FXL_DCHECK(sender_);
-
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(msg, &vmo));
- sender_->Send(std::move(vmo).ToTransport());
-}
-
-fidl::InterfaceRequest<fuchsia::modular::MessageSender>
-MessageSenderClient::NewRequest() {
- return sender_.NewRequest();
-}
-
-} // namespace modular
\ No newline at end of file
diff --git a/public/lib/message_queue/cpp/message_sender_client.h b/public/lib/message_queue/cpp/message_sender_client.h
deleted file mode 100644
index 166e3f1..0000000
--- a/public/lib/message_queue/cpp/message_sender_client.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef LIB_MESSAGE_QUEUE_CPP_MESSAGE_SENDER_CLIENT_H_
-#define LIB_MESSAGE_QUEUE_CPP_MESSAGE_SENDER_CLIENT_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-namespace modular {
-
-// MessageSenderClient is a wrapper class for using
-// fuchsia.modular.MessageSender in a more convinient way. This class represents
-// messages as a std::string, which the underlying fidl interface may not.
-//
-// Usage:
-//
-// // 1. Given a message queue token (|msg_queue_token|), get a MessageSender
-// // out of it.
-// MessageSenderClient message_sender;
-// component_context->GetMessageSender(msg_queue_token,
-// message_sender.NewRequest());
-//
-// // 2. Send a message.
-// message_sender.Send("hello");
-class MessageSenderClient {
- public:
- MessageSenderClient();
-
- // A message sender must be bound (by calling NewRequest()) to this class
- // before Send() is called.
- void Send(fxl::StringView msg);
-
- // Binds a new interface connection and returns the request side.
- fidl::InterfaceRequest<fuchsia::modular::MessageSender> NewRequest();
-
- // Whether the underlying interface connection is currently bound.
- explicit operator bool() const { return sender_.is_bound(); }
-
- private:
- fuchsia::modular::MessageSenderPtr sender_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(MessageSenderClient);
-};
-
-} // namespace modular
-
-#endif // LIB_MESSAGE_QUEUE_CPP_MESSAGE_SENDER_CLIENT_H_
diff --git a/tests/BUILD.gn b/tests/BUILD.gn
deleted file mode 100644
index 612964d..0000000
--- a/tests/BUILD.gn
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# We follow these conventions for the organization of the sources, build rules,
-# and packages here:
-#
-# 1. All the binaries used in tests are run through a basemgr invocation
-# configured in modular_tests.json. It usually does not ever make sense to
-# run a test component binary directly, especially not as a test. Therefore,
-# all binaries are deployed in their own packages, so that they are not run
-# automatically by roller scripts. Instead, only the run_modular_tests.sh
-# script is present in /system/test/, which then invokes the test runner,
-# which in turn invokes all the test component binaries in the right
-# configuration.
-#
-# 2. The component binary as well as its package is named with a prefix that
-# tells the test it belongs to, followed by "_test", optionally followed by a
-# name component indicating its function if there are multiple components of
-# the same type in a single test, followed a suffix indicating the component
-# type. This way, all components belonging to the same test are
-# lexicographically sorted together.
-#
-# 3. Common components shared between tests are named after their function
-# followed by a suffix indicating the component type.
-#
-# 4. The suffix that indicates the component type (i.e. the primary service
-# provided by the component) is:
-#
-# - _module -- Module
-# - _agent -- Agent
-# - _session_shell -- SessionShell
-# - _base_shell -- BaseShell
-# - _story_shell -- StoryShell
-# - _service -- FIDL interfaces
-#
-# 5. The main sources of the components are named like the binaries they create.
-#
-#
-# HOW TO ADD A NEW INTEGRATION TEST
-#
-# 1. Add a new subdirectory with rules for the test components (session shells,
-# modules, agents). Define all test components as executable_package()s.
-#
-# 2. Add the newly defined packages for all test components to
-# //peridot/packages/tests/modular.
-#
-# 3. Add an entry for the test to modular_tests.json.
-
-import("//build/package.gni")
-
-package("modular_tests") {
- testonly = true
-
- tests = [
- {
- name = rebase_path("run_modular_tests.sh")
- dest = "run_modular_tests.sh"
- },
- ]
-
- resources = [
- {
- path = rebase_path("modular_tests.json")
- dest = "modular_tests.json"
- },
- ]
-}
diff --git a/tests/README.md b/tests/README.md
deleted file mode 100644
index 70c0107..0000000
--- a/tests/README.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Testing
-
-Modular has two types of tests, unit tests and integration tests.
-
-## Unit tests
-
-Unit tests are low-level tests written against the smallest testable parts of
-the code. Tests for `some_class.{h,cc}` are placed side-by-side the code being
-tested, in a `some_class_unittest.cc` file.
-
-Unit tests are regular [Google Test] tests, although most of them use our own
-[TestLoopFixture] base class to conveniently run delayed tasks with a
-timeout, ensuring that a failing test does not hang forever.
-
-All Modular unit tests in the peridot tree are built into a single
-`modular_unittests` binary, which can be executed on fuchsia by running
-`/system/test/modular_unittests`.
-
-## Integration tests
-
-Integration tests are written against client-facing FIDL services exposed by
-Modular and run through the [Test Runner] framework in a fuchsia instance
-running on either the build host using QEMU or on a target device.
-
-There are two ways to invoke the test suite, remotely from the build host or
-directly on the fuchsia instance.
-
-### Starting tests remotely from the build host
-
-The test runner discovers the running fuchsia instance automatically, but will
-stop with an error if there is more than one. To fix the problem, specify the
-device name with the `--server` parameter.
-
-In order to run tests from your workstation, a `test_runner` must be running
-under fuchsia. In order to start `test_runner`, you can either:
-
-* Use a gn module to automatically start `test_runner` at fuchsia boot
- time using [boot_test.config](boot_test.config). At build time on your
- workstation, do:
-
-```
-fx set x64 --packages peridot/packages/products/test_modular
-```
-
-* Alternatively, invoke `test_runner` manually after starting fuchsia. In a
- shell on your fuchsia device, do:
-
-```
-run test_runner
-```
-
-Each subdirectory of `peridot/tests` contains one integration test. They
-are all run together by the test runner as specified by the
-[modular_tests.json](modular_tests.json) configuration file:
-
-```
-fx exec garnet/bin/test_runner/run_test \
- --test_file=peridot/tests/modular_tests.json
-```
-
-### Starting the test suite directly under fuchsia
-
-`run_modular_tests.sh` is a command that runs all of the Modular tests. It is
-based on the [Test Runner] framework, but runs the tests without requiring
-`test_runner` to be running under fuchsia.
-
-Run it from the fuchsia shell:
-
-```
-$ /pkgfs/packages/modular_tests/0/test/run_modular_tests.sh
-```
-
-You can also run specific tests by using their name. For example this
-will run only the *link_update* test (as described in
-[modular_tests.json](modular_tests.json)).
-
-```
-$ /pkgfs/packages/modular_tests/0/test/run_modular_tests.sh link_update
-```
-
-
-[Test Runner]: https://fuchsia.googlesource.com/test_runner/ "Test Runner"
-[Google Test]: https://github.com/google/googletest "Google Test"
-[TestLoopFixture]: ../lib/gtest/test_loop_fixture.h
diff --git a/tests/benchmarks/BUILD.gn b/tests/benchmarks/BUILD.gn
deleted file mode 100644
index 2ee3049..0000000
--- a/tests/benchmarks/BUILD.gn
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-
-# We follow the conventions of ../BUILD.gn for the organization of the sources,
-# build rules, and packages, with the following modifications:
-#
-# 1. All the binaries used in tests are run through a basemgr invocation
-# configured in the .tspec file of the benchmark subdirectory.
-#
-# 2. The component binary as well as its package is named with a prefix that
-# tells the benchmark it belongs to, followed by "_benchmark", followed by
-# more name components as described in ../BUILD.gn. The tspec file is also
-# named like the benchmark, followed by "_benchmark", followed by ".tspec".
-#
-# 3. [unchanged]
-#
-# 4. [unchanged]
-#
-# 5. [unchanged]
-#
-#
-# HOW TO ADD A NEW BENCHMARK
-#
-# 1. Add a new subdirectory with rules for the test components (session shells,
-# modules, agents). Define all test components as executable_package()s.
-#
-# 2. Add the newly defined packages for all test components to
-# //peridot/packages/benchmarks/modular.
-#
-# 3. Add a tspec file for the benchmark in the newly added subdirectory.
-#
-# 4. Add an entry for the tspec file to the resources = field of the
-# modular_benchmarks build rule.
-#
-# 5. Add an entry for the test to run_modular_benchmarks.sh.
-
-package("modular_benchmarks") {
- testonly = true
-
- binaries = [
- {
- name = rebase_path("run_modular_benchmarks.sh")
- dest = "run_modular_benchmarks.sh"
- },
- ]
-
- resources = [
- {
- path = rebase_path("story/modular_benchmark_story.tspec")
- dest = "modular_benchmark_story.tspec"
- },
- ]
-}
-
-package("peridot_benchmarks") {
- testonly = true
-
- binaries = [
- {
- name = rebase_path("benchmarks.sh")
- dest = "benchmarks.sh"
- },
- ]
-}
diff --git a/tests/benchmarks/README.md b/tests/benchmarks/README.md
deleted file mode 100644
index aee523b..0000000
--- a/tests/benchmarks/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# benchmark
-
-This directory contains benchmark tests for modular. They follow the pattern
-established by the [benchmark tests for ledger].
-
-[benchmark tests for ledger]: /bin/ledger/tests/benchmark/README.md
diff --git a/tests/benchmarks/benchmarks.sh b/tests/benchmarks/benchmarks.sh
deleted file mode 100644
index a4d6578..0000000
--- a/tests/benchmarks/benchmarks.sh
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/boot/bin/sh
-#
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This script runs all benchmarks for the Peridot layer.
-#
-# For usage, see runbench_read_arguments in runbenchmarks.sh.
-
-# Import the runbenchmarks library.
-. /pkgfs/packages/runbenchmarks/0/data/runbenchmarks.sh
-
-runbench_read_arguments "$@"
-
-# Run "local" Ledger benchmarks. These don't need external services to function
-# properly.
-
-runbench_exec "${OUT_DIR}/ledger.add_new_page_precached.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/add_new_page_precached.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.add_new_page_precached.json"
-
-runbench_exec "${OUT_DIR}/ledger.add_new_page.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/add_new_page.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.add_new_page.json"
-
-runbench_exec "${OUT_DIR}/ledger.get_same_page.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/get_same_page.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.get_same_page.json"
-
-runbench_exec "${OUT_DIR}/ledger.get_page_id.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/get_page_id.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.get_page_id.json"
-
-runbench_exec "${OUT_DIR}/ledger.put.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/put.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.put.json"
-
-runbench_exec "${OUT_DIR}/ledger.put_as_reference.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/put_as_reference.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.put_as_reference.json"
-
-runbench_exec "${OUT_DIR}/ledger.put_big_entry.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/put_big_entry.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.put_big_entry.json"
-
-runbench_exec "${OUT_DIR}/ledger.transaction.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/transaction.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.transaction.json"
-
-runbench_exec "${OUT_DIR}/ledger.update_entry.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/update_entry.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.update_entry.json"
-
-runbench_exec "${OUT_DIR}/ledger.update_big_entry.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/update_big_entry.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.update_big_entry.json"
-
-runbench_exec "${OUT_DIR}/ledger.update_entry_transactions.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/update_entry_transactions.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.update_entry_transactions.json"
-
-runbench_exec "${OUT_DIR}/ledger.delete_entry.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/delete_entry.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.delete_entry.json"
-
-runbench_exec "${OUT_DIR}/ledger.delete_big_entry.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/delete_big_entry.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.delete_big_entry.json"
-
-runbench_exec "${OUT_DIR}/ledger.delete_entry_transactions.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/delete_entry_transactions.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.delete_entry_transactions.json"
-
-runbench_exec "${OUT_DIR}/ledger.disk_space_empty_ledger.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/disk_space_empty_ledger.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.disk_space_empty_ledger.json"
-
-runbench_exec "${OUT_DIR}/ledger.disk_space_empty_pages.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/disk_space_empty_pages.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.disk_space_empty_pages.json"
-
-runbench_exec "${OUT_DIR}/ledger.disk_space_entries.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/disk_space_entries.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.disk_space_entries.json"
-
-runbench_exec "${OUT_DIR}/ledger.disk_space_small_keys.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/disk_space_small_keys.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.disk_space_small_keys.json"
-
-runbench_exec "${OUT_DIR}/ledger.disk_space_updates.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/disk_space_updates.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.disk_space_updates.json"
-
-runbench_exec "${OUT_DIR}/ledger.disk_space_one_commit_per_entry.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/disk_space_one_commit_per_entry.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.disk_space_one_commit_per_entry.json"
-
-runbench_exec "${OUT_DIR}/ledger.disk_space_cleared_page.json" \
- trace record \
- --spec-file=/pkgfs/packages/ledger_benchmarks/0/data/disk_space_cleared_page.tspec \
- --benchmark-results-file="${OUT_DIR}/ledger.disk_space_cleared_page.json"
-
-runbench_exec "${OUT_DIR}/modular.story_runner.json" \
- trace record \
- --spec-file=/pkgfs/packages/modular_benchmarks/0/data/modular_benchmark_story.tspec \
- --test-suite=fuchsia.modular \
- --benchmark-results-file="${OUT_DIR}/modular.story_runner.json"
-
-# Exit with a code indicating whether any errors occurred.
-runbench_finish "${OUT_DIR}"
diff --git a/tests/benchmarks/run_modular_benchmarks.sh b/tests/benchmarks/run_modular_benchmarks.sh
deleted file mode 100644
index 1c2192f..0000000
--- a/tests/benchmarks/run_modular_benchmarks.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/boot/bin/sh
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This script runs the Modular benchmarks. It's intended for use in continuous
-# integration jobs. It must be run from the pathname to the file inside the
-# package, it cannot (yet) be run by the package name alone.
-
-set -e
-
-trace record --spec-file=/pkgfs/packages/modular_benchmarks/0/data/modular_benchmark_story.tspec
-
-# add more benchmark tests here
diff --git a/tests/benchmarks/story/BUILD.gn b/tests/benchmarks/story/BUILD.gn
deleted file mode 100644
index 26f2722..0000000
--- a/tests/benchmarks/story/BUILD.gn
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("modular_benchmark_story_module") {
-
- testonly = true
-
- meta = [
- {
- path = "meta/modular_benchmark_story_module.cmx"
- dest = "modular_benchmark_story_module.cmx"
- },
- ]
-
- sources = [
- "modular_benchmark_story_module.cc",
- ]
- deps = [
- ":tracing_waiter",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("modular_benchmark_story_session_shell") {
-
- testonly = true
-
- meta = [
- {
- path = "meta/modular_benchmark_story_session_shell.cmx"
- dest = "modular_benchmark_story_session_shell.cmx"
- },
- ]
-
- deps = [
- ":tracing_waiter",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/common:names",
- "//peridot/lib/fidl:single_service_app",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_impl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- ]
-
- sources = [
- "modular_benchmark_story_session_shell.cc",
- ]
-}
-
-source_set("tracing_waiter") {
- sources = [
- "tracing_waiter.cc",
- "tracing_waiter.h",
- ]
-
- public_deps = [
- "//zircon/public/lib/async",
- "//zircon/public/lib/trace",
- "//zircon/public/lib/trace-provider",
- ]
-
- deps = [
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- ]
-}
diff --git a/tests/benchmarks/story/README.md b/tests/benchmarks/story/README.md
deleted file mode 100644
index c57fd9d..0000000
--- a/tests/benchmarks/story/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-This benchmark runs everything related to a story. For a while, this could well
-be the only thing to benchmark around the framework at all, as everything the
-framework does has to do with stories. We might add other benchmarks later, and
-for the sheer possibility of that it is that this benchmark has a name of its
-own.
-
-We keep log output of past executions in RUNLOG so we can track evolution of
-numbers.
\ No newline at end of file
diff --git a/tests/benchmarks/story/RUNLOG b/tests/benchmarks/story/RUNLOG
deleted file mode 100644
index e4e76ca..0000000
--- a/tests/benchmarks/story/RUNLOG
+++ /dev/null
@@ -1,114 +0,0 @@
-$ /pkgfs/packages/modular_benchmarks/0/bin/run_modular_benchmarks.sh
-Launching basemgr
-Starting trace; will stop in 1200 seconds...
-Application exited with return code 0
-Stopping trace...
-Application terminated
-Trace file written to /data/trace.json
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. modular AgentContextImpl::InitializeCall
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. modular AgentRunnerStorageImpl::InitializeCall
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. modular WriteDataCall
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[WARNING:garnet/lib/measure/duration.cc(75)] Ignoring a trace event: async or flow end not preceded by begin. benchmark link/trans
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "AgentRunnerStorageImpl::InitializeCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "AgentRunnerStorageImpl::WriteTaskCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "AgentRunnerStorageImpl::DeleteTaskCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "LinkImpl::GetCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "LinkImpl::EraseCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "LinkImpl::GetEntityCallCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "SessionStorage::MutateStoryDataCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryControllerImpl::KillModuleCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryControllerImpl::InitializeChainCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryControllerImpl::StopModuleCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryControllerImpl::DeleteCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryControllerImpl::OnModuleDataUpdatedCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryControllerImpl::FocusCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryControllerImpl::DefocusCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryControllerImpl::ResolveParametersCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryProviderImpl::DeleteStoryCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryProviderImpl::GetLinkPeerCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryStorage::ReadLinkDataCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryStorage::WriteLinkDataCall (modular)".
-[ERROR:garnet/bin/trace/commands/record.cc(349)] No results for measurement "StoryStorage::UpdateLinkCall (modular)".
-link/set (benchmark) ->
- samples 0 to 9: avg 3.08537866915423ms out of 10 samples. (std dev 0.327364625011531, min 2.71797388059702, max 3.58024751243781)
- samples 10 to 2019: avg 3.11997304862503ms out of 2010 samples. (std dev 0.493919138663738, min 2.2520236318408, max 8.04235074626866)
-link/trans (benchmark) ->
- samples 0 to 9: avg 3.08896243781095ms out of 10 samples. (std dev 0.370484835949823, min 2.69241542288557, max 3.7780342039801)
- samples 10 to 2019: avg 3.09267429209673ms out of 2010 samples. (std dev 0.478776309955248, min 2.2346828358209, max 6.18221828358209)
-story/create (benchmark) ->
- samples 0 to 0: 378.436559079602ms
- samples 1 to 19: avg 424.684147911757ms out of 19 samples. (std dev 30.7204249072897, min 368.310649875622, max 469.822699626866)
-story/info (benchmark) ->
- samples 0 to 0: 69.3502133084577ms
- samples 1 to 19: avg 71.2043160513223ms out of 19 samples. (std dev 5.23282503949471, min 61.9065895522388, max 80.4358700248756)
-story/start (benchmark) ->
- samples 0 to 0: 2.34076243781095ms
- samples 1 to 19: avg 1.51073978790259ms out of 19 samples. (std dev 0.273893107650646, min 1.17197450248756, max 2.3538513681592)
-story/stop (benchmark) ->
- samples 0 to 0: 4.84000746268657ms
- samples 1 to 19: avg 4.90821445404556ms out of 19 samples. (std dev 4.03567707901002, min 1.54024502487562, max 11.5805155472637)
-user/logout (benchmark) -> 0.222438432835821ms
-ReadAllDataCall (modular) -> avg 0.760300497512438ms out of 20 samples. (std dev 0.269687537664423, min 0.46442039800995, max 1.73237748756219)
-ReadDataCall (modular) -> avg 43.7541292184909ms out of 60 samples. (std dev 31.8507898913188, min 0.503220771144279, max 79.0309141791045)
-WriteDataCall (modular) -> avg 1.95153236940298ms out of 40 samples. (std dev 0.595833307350367, min 1.56620957711443, max 5.28696206467662)
-SyncCall (modular) -> avg 0.197957195728674ms out of 123 samples. (std dev 1.38766809817586, min 0.00673445273631841, max 13.9288737562189)
-AgentContextImpl::InitializeCall (modular) -> avg 20.0031674662402ms out of 7 samples. (std dev 14.0494825376138, min 1.92740485074627, max 41.6166592039801)
-AgentContextImpl::StopCall (modular) -> avg 1.888375ms out of 2 samples. (std dev 0.0553687810945274, min 1.83300621890547, max 1.94374378109453)
-AgentRunnerStorageImpl::InitializeCall (modular) -> no results
-AgentRunnerStorageImpl::WriteTaskCall (modular) -> no results
-AgentRunnerStorageImpl::DeleteTaskCall (modular) -> no results
-LinkImpl::ReadLinkDataCall (modular) -> avg 0.405560385572139ms out of 20 samples. (std dev 0.142149907386102, min 0.240318407960199, max 0.845122512437811)
-LinkImpl::WriteLinkDataCall (modular) -> avg 1.82188344231811ms out of 2020 samples. (std dev 0.30470151052762, min 1.30627674129353, max 4.91131343283582)
-LinkImpl::FlushWatchersCall (modular) -> avg 1.141020868738ms out of 2020 samples. (std dev 0.179000152151604, min 0.819532960199005, max 2.34427425373134)
-LinkImpl::WriteCall (modular) -> avg 3.00742333998326ms out of 2020 samples. (std dev 0.46839227693992, min 2.16766666666667, max 5.99262873134328)
-LinkImpl::ReadCall (modular) -> avg 0.472000995024876ms out of 20 samples. (std dev 0.138630550437487, min 0.306875, max 0.900149253731343)
-LinkImpl::GetCall (modular) -> no results
-LinkImpl::SetCall (modular) -> avg 3.02955667577952ms out of 2020 samples. (std dev 0.469719692566121, min 2.18553047263682, max 6.04290422885572)
-LinkImpl::EraseCall (modular) -> no results
-LinkImpl::GetEntityCallCall (modular) -> no results
-LinkImpl::WatchCall (modular) -> avg 0.0248887852404643ms out of 60 samples. (std dev 0.0211014577205166, min 0.015410447761194, max 0.184106343283582)
-LinkImpl::ChangeCall (modular) -> avg 0.023023183894882ms out of 2020 samples. (std dev 0.00801060659066399, min 0.0139154228855721, max 0.15521828358209)
-SessionStorage::CreateStoryCall (modular) -> avg 349.324575808458ms out of 20 samples. (std dev 47.4617117678454, min 190.873377487562, max 403.758059079602)
-SessionStorage::MutateStoryDataCall (modular) -> no results
-StoryControllerImpl::LaunchModuleCall (modular) -> avg 0.531989365671642ms out of 20 samples. (std dev 0.279076421429912, min 0.36103855721393, max 1.57448383084577)
-StoryControllerImpl::KillModuleCall (modular) -> no results
-StoryControllerImpl::ConnectLinkCall (modular) -> avg 0.230094330431177ms out of 60 samples. (std dev 0.30272192373998, min 0.0132108208955224, max 1.13895584577114)
-StoryControllerImpl::InitializeChainCall (modular) -> no results
-StoryControllerImpl::LaunchModuleInShellCall (modular) -> avg 0.758289054726368ms out of 20 samples. (std dev 0.626946244651249, min 0.440429726368159, max 3.17082027363184)
-StoryControllerImpl::StopCall (modular) -> avg 4.29517719216418ms out of 40 samples. (std dev 3.27565806994589, min 0.0869558457711443, max 11.5320553482587)
-StoryControllerImpl::StopModuleCall (modular) -> no results
-StoryControllerImpl::DeleteCall (modular) -> no results
-StoryControllerImpl::OnModuleDataUpdatedCall (modular) -> no results
-StoryControllerImpl::FocusCall (modular) -> no results
-StoryControllerImpl::DefocusCall (modular) -> no results
-StoryControllerImpl::ResolveParametersCall (modular) -> no results
-StoryControllerImpl::ResolveModulesCall (modular) -> avg 9.71854449626866ms out of 20 samples. (std dev 39.7811895810035, min 0.136840796019901, max 183.077365049751)
-StoryProviderImpl::CreateStoryCall (modular) -> avg 422.163254415423ms out of 20 samples. (std dev 31.5918493734685, min 368.104149875622, max 469.629546641791)
-StoryProviderImpl::DeleteStoryCall (modular) -> no results
-StoryProviderImpl::GetControllerCall (modular) -> avg 0.519575668532338ms out of 40 samples. (std dev 0.49759768134132, min 0.050285447761194, max 1.60482587064677)
-StoryProviderImpl::StopAllStoriesCall (modular) -> 8.29005597014925ms
-StoryProviderImpl::StopStoryShellCall (modular) -> 0.0730634328358209ms
-StoryProviderImpl::GetLinkPeerCall (modular) -> no results
-StoryStorage::ReadLinkDataCall (modular) -> no results
-StoryStorage::WriteLinkDataCall (modular) -> no results
-StoryStorage::UpdateLinkCall (modular) -> no results
-[ERROR:garnet/bin/trace/commands/record.cc(356)] One or more measurements had empty results. Quitting.
diff --git a/tests/benchmarks/story/meta/modular_benchmark_story_module.cmx b/tests/benchmarks/story/meta/modular_benchmark_story_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/benchmarks/story/meta/modular_benchmark_story_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/benchmarks/story/meta/modular_benchmark_story_session_shell.cmx b/tests/benchmarks/story/meta/modular_benchmark_story_session_shell.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/benchmarks/story/meta/modular_benchmark_story_session_shell.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/benchmarks/story/modular_benchmark_story.tspec b/tests/benchmarks/story/modular_benchmark_story.tspec
deleted file mode 100644
index 8351e11..0000000
--- a/tests/benchmarks/story/modular_benchmark_story.tspec
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "test_suite_name": "fuchsia.modular",
- "app": "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "args": ["--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/modular_benchmark_story_session_shell#meta/modular_benchmark_story_session_shell.cmx",
- "--session_shell_args=--story_count=20",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx"],
- "categories": ["benchmark", "modular"],
- "duration": 120,
- "measure": [
- {
- "type": "duration",
- "event_name": "link/set",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "link/trans",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "story/create",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "story/info",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "story/start",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "story/stop",
- "event_category": "benchmark"
- },
- {
- "type": "duration",
- "event_name": "user/logout",
- "event_category": "benchmark"
- }
- ]
-}
diff --git a/tests/benchmarks/story/modular_benchmark_story_module.cc b/tests/benchmarks/story/modular_benchmark_story_module.cc
deleted file mode 100644
index 4e83172..0000000
--- a/tests/benchmarks/story/modular_benchmark_story_module.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fsl/vmo/strings.h>
-#include <trace-provider/provider.h>
-#include <trace/event.h>
-#include <trace/observer.h>
-
-#include "peridot/tests/benchmarks/story/tracing_waiter.h"
-
-namespace {
-
-// This Module updates its root link 100 times and then just sits there until
-// it's terminated.
-class NullModule : fuchsia::modular::LinkWatcher {
- public:
- NullModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : module_host_(module_host), link_watcher_binding_(this) {
- FXL_LOG(INFO) << "NullModule()";
- module_host_->module_context()->GetLink(nullptr, link_.NewRequest());
-
- // Will call Notify() with current value.
- link_->WatchAll(link_watcher_binding_.NewBinding());
- }
-
- NullModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : NullModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called by ModuleDriver.
- void Terminate(const std::function<void()>& done) { done(); }
-
- private:
- // |fuchsia::modular::LinkWatcher|
- void Notify(fuchsia::mem::Buffer content) override {
- std::string json;
- FXL_CHECK(fsl::StringFromVmo(content, &json));
- FXL_LOG(INFO) << "Notify() " << json;
-
- // First invocation is from WatchAll(); next from Set().
- if (count_ == -1) {
- count_ = 0;
- tracing_waiter_.WaitForTracing([this] { Set(); });
- return;
- }
-
- // Corresponding TRACE_ASYNC_BEGIN() is in Set().
- TRACE_ASYNC_END("benchmark", "link/set", count_);
-
- ++count_;
- if (count_ <= 100) {
- Set();
- }
- }
-
- void Set() {
- FXL_LOG(INFO) << "Set() " << count_;
-
- // Corresponding TRACE_ASYNC_END() is in Notify().
- TRACE_ASYNC_BEGIN("benchmark", "link/set", count_);
-
- // Corresponding TRACE_FLOW_END() is in the session shell.
- TRACE_FLOW_BEGIN("benchmark", "link/trans", count_);
-
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(std::to_string(count_), &vmo));
- link_->Set(nullptr, std::move(vmo).ToTransport());
- }
-
- modular::ModuleHost* const module_host_;
- modular::TracingWaiter tracing_waiter_;
- fuchsia::modular::LinkPtr link_;
- fidl::Binding<fuchsia::modular::LinkWatcher> link_watcher_binding_;
-
- int count_{-1};
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<NullModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/benchmarks/story/modular_benchmark_story_session_shell.cc b/tests/benchmarks/story/modular_benchmark_story_session_shell.cc
deleted file mode 100644
index 1e249a0..0000000
--- a/tests/benchmarks/story/modular_benchmark_story_session_shell.cc
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <utility>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_number_conversions.h>
-#include <trace-provider/provider.h>
-#include <trace/event.h>
-#include <trace/observer.h>
-
-#include "peridot/lib/common/names.h"
-#include "peridot/lib/fidl/single_service_app.h"
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_impl.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/benchmarks/story/tracing_waiter.h"
-
-namespace {
-
-const char kStoryNamePrefix[] = "story-";
-
-class Settings {
- public:
- explicit Settings(const fxl::CommandLine& command_line) {
- const auto story_count_str =
- command_line.GetOptionValueWithDefault("story_count", "1");
- if (!fxl::StringToNumberWithError(story_count_str, &story_count)) {
- FXL_LOG(ERROR) << "Unrecognized value [--story_count=" << story_count_str
- << "]: Using 0.";
- }
-
- module_url = command_line.GetOptionValueWithDefault(
- "module_url",
- "fuchsia-pkg://fuchsia.com/modular_benchmark_story_module#meta/modular_benchmark_story_module.cmx");
- }
-
- int story_count{0};
- std::string module_url;
-};
-
-// A simple story watcher implementation that invokes a "continue" callback when
-// it sees the watched story transition to the given state. Used to push the
-// test sequence forward when the test story reaches the next state.
-class StoryWatcherImpl : fuchsia::modular::StoryWatcher {
- public:
- StoryWatcherImpl() : binding_(this) {}
- ~StoryWatcherImpl() override = default;
-
- // Registers itself as a watcher on the given story. Only one story at a time
- // can be watched.
- void Watch(fuchsia::modular::StoryController* const story_controller) {
- story_controller->Watch(binding_.NewBinding());
- }
-
- // Deregisters itself from the watched story.
- void Reset() { binding_.Unbind(); }
-
- // Sets the function where to continue when the story is observed to be done.
- void Continue(fuchsia::modular::StoryState state, std::function<void()> at) {
- continue_state_ = state;
- continue_ = at;
- }
-
- private:
- // |fuchsia::modular::StoryWatcher|
- void OnStateChange(fuchsia::modular::StoryState state) override {
- if (state != continue_state_) {
- return;
- }
-
- continue_();
- }
-
- // |fuchsia::modular::StoryWatcher|
- void OnModuleAdded(fuchsia::modular::ModuleData module_data) override {}
-
- // |fuchsia::modular::StoryWatcher|
- void OnModuleFocused(std::vector<std::string> module_path) override {}
-
- fidl::Binding<fuchsia::modular::StoryWatcher> binding_;
-
- fuchsia::modular::StoryState continue_state_{
- fuchsia::modular::StoryState::STOPPED};
- std::function<void()> continue_{[] {}};
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryWatcherImpl);
-};
-
-// A simple link watcher implementation that invokes a "continue" callback when
-// it sees the watched link change.
-class LinkWatcherImpl : fuchsia::modular::LinkWatcher {
- public:
- LinkWatcherImpl() : binding_(this) {}
- ~LinkWatcherImpl() override = default;
-
- // Registers itself as a watcher on the given link. Only one story at a time
- // can be watched.
- void Watch(fuchsia::modular::Link* const link) {
- link->WatchAll(binding_.NewBinding());
- }
-
- // Deregisters itself from the watched story.
- void Reset() { binding_.Unbind(); }
-
- // Sets the function where to continue when the story is observed to be done.
- void Continue(std::function<void(fidl::StringPtr)> at) { continue_ = at; }
-
- private:
- // |fuchsia::modular::LinkWatcher|
- void Notify(fuchsia::mem::Buffer value) override {
- std::string json;
- FXL_CHECK(fsl::StringFromVmo(value, &json));
- continue_(json);
- }
-
- fidl::Binding<fuchsia::modular::LinkWatcher> binding_;
-
- std::function<void(fidl::StringPtr)> continue_{[](fidl::StringPtr) {}};
-
- FXL_DISALLOW_COPY_AND_ASSIGN(LinkWatcherImpl);
-};
-
-// Measures timing the machinery available to a session shell implementation.
-// This is invoked as a session shell from basemgr and executes a predefined
-// sequence of steps, rather than to expose a UI to be driven by user
-// interaction, as a session shell normally would.
-class TestApp : public modular::ViewApp {
- public:
- TestApp(component::StartupContext* const startup_context, Settings settings)
- : ViewApp(startup_context), settings_(std::move(settings)) {
- startup_context->ConnectToEnvironmentService(
- session_shell_context_.NewRequest());
- session_shell_context_->GetStoryProvider(story_provider_.NewRequest());
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
-
- startup_context->outgoing().AddPublicService(
- session_shell_impl_.GetHandler());
-
- tracing_waiter_.WaitForTracing([this] { Loop(); });
- }
-
- ~TestApp() override = default;
-
- // Called by AppDriver in ComponentMain(). NOTE(mesch): Even though it
- // overrides SingleServiceApp::Terminate(), it is called directly on TestApp
- // by AppDriver, so it must not be private.
- void Terminate(std::function<void()> done) override {
- // The corresponding BEGIN() call is in Loop(), below.
- TRACE_ASYNC_END("benchmark", "user/logout", 0);
- done();
- }
-
- private:
- void Loop() {
- if (story_count_ < settings_.story_count) {
- FXL_LOG(INFO) << "Loop at " << story_count_ << " of "
- << settings_.story_count;
- async::PostTask(async_get_default_dispatcher(),
- [this] { StoryCreate(); });
-
- } else {
- TRACE_ASYNC_BEGIN("benchmark", "user/logout", 0);
- session_shell_context_->Logout();
- }
- }
-
- void StoryCreate() {
- FXL_LOG(INFO) << "StoryCreate()";
- TRACE_ASYNC_BEGIN("benchmark", "story/create", 0);
- std::string story_name = std::string(kStoryNamePrefix) + std::to_string(story_count_);
- puppet_master_->ControlStory(story_name, story_puppet_master_.NewRequest());
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("root");
- add_mod.intent.handler = settings_.module_url;
- add_mod.intent.action = "action";
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this, story_name](fuchsia::modular::ExecuteResult result) {
- TRACE_ASYNC_END("benchmark", "story/create", 0);
- StoryInfo(story_name);
- });
- }
-
- void StoryInfo(fidl::StringPtr story_id) {
- FXL_LOG(INFO) << "StoryInfo()";
- story_provider_->GetController(story_id, story_controller_.NewRequest());
-
- TRACE_ASYNC_BEGIN("benchmark", "story/info", 0);
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo story_info,
- fuchsia::modular::StoryState state) {
- TRACE_ASYNC_END("benchmark", "story/info", 0);
- Link();
- });
- }
-
- void Link() {
- FXL_LOG(INFO) << "Link()";
-
- fuchsia::modular::LinkPath link_path = fuchsia::modular::LinkPath();
- std::vector<std::string> root_module_path;
- root_module_path.push_back(modular::kRootModuleName);
- link_path.module_path = std::move(root_module_path);
- link_path.link_name = nullptr;
- story_controller_->GetLink(std::move(link_path), link_.NewRequest());
-
- link_watcher_.Watch(link_.get());
- link_watcher_.Continue([this](fidl::StringPtr json) {
- FXL_LOG(INFO) << "Link() Watch: " << json;
- if (json == "") {
- return;
- }
-
- const int count = fxl::StringToNumber<int>(json.get());
-
- // Corresponding TRACE_FLOW_BEGIN() is in the module.
- TRACE_FLOW_END("benchmark", "link/trans", count);
-
- if (count == 100) {
- StoryStop();
- }
- });
-
- StoryStart();
- }
-
- void StoryStart() {
- FXL_LOG(INFO) << "StoryStart()";
- TRACE_ASYNC_BEGIN("benchmark", "story/start", 0);
- story_watcher_.Continue(fuchsia::modular::StoryState::RUNNING, [this] {
- TRACE_ASYNC_END("benchmark", "story/start", 0);
- });
-
- story_watcher_.Watch(story_controller_.get());
- story_controller_->RequestStart();
- }
-
- void StoryStop() {
- FXL_LOG(INFO) << "StoryStop()";
- TRACE_ASYNC_BEGIN("benchmark", "story/stop", 0);
- story_controller_->Stop([this] {
- TRACE_ASYNC_END("benchmark", "story/stop", 0);
- MaybeRepeat();
- });
- }
-
- void MaybeRepeat() {
- FXL_LOG(INFO) << "MaybeRepeat()";
- story_watcher_.Reset();
- story_controller_.Unbind();
-
- story_count_++;
- Loop();
- }
-
- modular::TracingWaiter tracing_waiter_;
-
- const Settings settings_;
-
- int story_count_{};
-
- StoryWatcherImpl story_watcher_;
- LinkWatcherImpl link_watcher_;
- modular::testing::SessionShellImpl session_shell_impl_;
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
-
- fuchsia::modular::SessionShellContextPtr session_shell_context_;
- fuchsia::modular::StoryProviderPtr story_provider_;
- fuchsia::modular::StoryControllerPtr story_controller_;
- fuchsia::modular::LinkPtr link_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int argc, const char** argv) {
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- Settings settings(command_line);
- modular::testing::ComponentMain<TestApp, Settings>(std::move(settings));
- return 0;
-}
diff --git a/tests/benchmarks/story/tracing_waiter.cc b/tests/benchmarks/story/tracing_waiter.cc
deleted file mode 100644
index 861f9ef..0000000
--- a/tests/benchmarks/story/tracing_waiter.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/tests/benchmarks/story/tracing_waiter.h"
-
-#include <lib/async/default.h>
-
-namespace modular {
-
-TracingWaiter::TracingWaiter() = default;
-TracingWaiter::~TracingWaiter() = default;
-
-void TracingWaiter::WaitForTracing(std::function<void()> cont) {
- // Cf. RunWithTracing() used by ledger benchmarks.
- trace_provider_ =
- std::make_unique<trace::TraceProvider>(async_get_default_dispatcher());
- trace_observer_ = std::make_unique<trace::TraceObserver>();
-
- std::function<void()> on_trace_state_changed = [this, cont] {
- if (TRACE_CATEGORY_ENABLED("benchmark") && !started_) {
- started_ = true;
- cont();
- }
- };
-
- // In case tracing has already started.
- on_trace_state_changed();
-
- if (!started_) {
- trace_observer_->Start(async_get_default_dispatcher(),
- on_trace_state_changed);
- }
-}
-
-} // namespace modular
diff --git a/tests/benchmarks/story/tracing_waiter.h b/tests/benchmarks/story/tracing_waiter.h
deleted file mode 100644
index 66ab0eb..0000000
--- a/tests/benchmarks/story/tracing_waiter.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_BENCHMARKS_STORY_TRACING_WAITER_H_
-#define PERIDOT_TESTS_BENCHMARKS_STORY_TRACING_WAITER_H_
-
-#include <functional>
-#include <memory>
-
-#include <lib/fxl/macros.h>
-#include <trace-provider/provider.h>
-#include <trace/event.h>
-#include <trace/observer.h>
-
-namespace modular {
-
-// An instance of this class can be used to wait for the tracing system to be
-// ready to use. A client calls WaitForTracing() on an instance of this class,
-// and is free to make tracing calls once the callback is invoked.
-class TracingWaiter {
- public:
- TracingWaiter();
- ~TracingWaiter();
-
- void WaitForTracing(std::function<void()>);
-
- private:
- bool started_{};
- std::unique_ptr<trace::TraceProvider> trace_provider_;
- std::unique_ptr<trace::TraceObserver> trace_observer_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TracingWaiter);
-};
-
-} // namespace modular
-
-#endif // PERIDOT_TESTS_BENCHMARKS_STORY_TRACING_WAITER_H_
diff --git a/tests/clipboard/BUILD.gn b/tests/clipboard/BUILD.gn
deleted file mode 100644
index 0cef4a8..0000000
--- a/tests/clipboard/BUILD.gn
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("clipboard_test_module") {
- testonly = true
-
- sources = [
- "clipboard_test_module.cc",
- ]
-
- meta = [
- {
- path = "meta/clipboard_test_module.cmx"
- dest = "clipboard_test_module.cmx"
- },
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
diff --git a/tests/clipboard/README.md b/tests/clipboard/README.md
deleted file mode 100644
index 823ec3f..0000000
--- a/tests/clipboard/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# clipboard integration test
-
-This test exercises the `fuchsia::modular::Clipboard` service exposed to Modules.
-
diff --git a/tests/clipboard/clipboard_test_module.cc b/tests/clipboard/clipboard_test_module.cc
deleted file mode 100644
index fc98f42..0000000
--- a/tests/clipboard/clipboard_test_module.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/connect.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/clipboard/defs.h"
-#include "peridot/tests/common/defs.h"
-
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"fuchsia::modular::Clipboard module initialized"};
- TestPoint successful_peek_{
- "fuchsia::modular::Clipboard pushed and peeked value"};
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : module_host_(module_host) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- initialized_.Pass();
-
- SetUp();
-
- const std::string expected_value = "hello there";
- clipboard_->Push(expected_value);
- clipboard_->Peek([this, expected_value](fidl::StringPtr text) {
- if (expected_value == text) {
- successful_peek_.Pass();
- }
- Signal(modular::testing::kTestShutdown);
- });
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- TestPoint stopped_{"fuchsia::modular::Clipboard module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- void SetUp() {
- module_host_->module_context()->GetComponentContext(
- component_context_.NewRequest());
-
- fuchsia::sys::ServiceProviderPtr agent_services;
- component_context_->ConnectToAgent(kClipboardAgentUrl,
- agent_services.NewRequest(),
- agent_controller_.NewRequest());
- component::ConnectToService(agent_services.get(), clipboard_.NewRequest());
- }
-
- modular::ModuleHost* const module_host_;
- fuchsia::modular::AgentControllerPtr agent_controller_;
- fuchsia::modular::ClipboardPtr clipboard_;
- fuchsia::modular::ComponentContextPtr component_context_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/clipboard/defs.h b/tests/clipboard/defs.h
deleted file mode 100644
index a073220..0000000
--- a/tests/clipboard/defs.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_CLIPBOARD_DEFS_H_
-#define PERIDOT_TESTS_CLIPBOARD_DEFS_H_
-
-namespace {
-
-// The url of the clipboard agent under test.
-constexpr char kClipboardAgentUrl[] =
- "fuchsia-pkg://fuchsia.com/clipboard_agent#meta/clipboard_agent.cmx";
-
-} // namespace
-
-#endif // PERIDOT_TESTS_CLIPBOARD_DEFS_H_
diff --git a/tests/clipboard/meta/clipboard_test_module.cmx b/tests/clipboard/meta/clipboard_test_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/clipboard/meta/clipboard_test_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/common/BUILD.gn b/tests/common/BUILD.gn
deleted file mode 100644
index 4e8ad87..0000000
--- a/tests/common/BUILD.gn
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/package.gni")
-import("//peridot/build/module_manifest.gni")
-
-group("common") {
- testonly = true
-
- public_deps = [
- ":common_active_module_bin",
- ":common_null_module_bin",
- ]
-}
-
-executable("common_null_module_bin") {
- testonly = true
-
- output_name = "common_null_module"
-
- sources = [
- "common_null_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-package("common_null_module") {
- testonly = true
-
- deps = [
- ":common_null_module_bin",
- ]
-
- binary = "common_null_module"
-
- meta = [
- {
- path = "common_null_module.cmx"
- dest = "common_null_module.cmx"
- },
- ]
-}
-
-executable("common_active_module_bin") {
- testonly = true
-
- output_name = "common_active_module"
-
- sources = [
- "common_active_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-package("common_active_module") {
- testonly = true
-
- deps = [
- ":common_active_module_bin",
- ]
-
- binary = "common_active_module"
-
- meta = [
- {
- path = "common_active_module.cmx"
- dest = "common_active_module.cmx"
- },
- ]
-}
-
-initial_module_packages("common_module_index") {
- packages = [
- "common_active_module",
- "common_null_module",
- ]
-}
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
diff --git a/tests/common/README.md b/tests/common/README.md
deleted file mode 100644
index de8a566..0000000
--- a/tests/common/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# common
-
-This directory contains components and configuration that are used by multiple
-integration tests.
-
-Specifically, there is a module `NullModule` which doesn't do anything and just
-sits there.
-
-It is deployed as its own package and has a module manifest in its package. It
-is added to the configuration of the `fuchsia::modular::ModuleResolver` so it can be started by an
-`fuchsia::modular::Intent`.
diff --git a/tests/common/common_active_module.cc b/tests/common/common_active_module.cc
deleted file mode 100644
index 63f0a1f..0000000
--- a/tests/common/common_active_module.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/fxl/tasks/task_runner.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// The ActiveModule issues Active() calls until it's terminated.
-class ActiveModule {
- public:
- TestPoint initialized_{"Active module initialized"};
-
- ActiveModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : module_host_(module_host), weak_ptr_factory_(this) {
- modular::testing::Init(module_host_->startup_context(), __FILE__);
- initialized_.Pass();
- Signal(kCommonActiveModuleStarted);
-
- ScheduleActive();
- }
-
- ActiveModule(
- modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : ActiveModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- void ScheduleActive() {
- async::PostDelayedTask(async_get_default_dispatcher(),
- [this, weak_this = weak_ptr_factory_.GetWeakPtr()] {
- if (!weak_this) {
- return;
- }
- module_host_->module_context()->Active();
- Signal(kCommonActiveModuleOngoing);
- ScheduleActive();
- },
- zx::duration(ZX_SEC(1)));
- }
-
- // Called by ModuleDriver.
- TestPoint stopped_{"Active module stopped"};
- void Terminate(const std::function<void()>& done) {
- Signal(kCommonActiveModuleStopped);
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- modular::ModuleHost* const module_host_;
- fxl::WeakPtrFactory<ActiveModule> weak_ptr_factory_;
- FXL_DISALLOW_COPY_AND_ASSIGN(ActiveModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<ActiveModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/common/common_active_module.cmx b/tests/common/common_active_module.cmx
deleted file mode 100644
index 44b48d2..0000000
--- a/tests/common/common_active_module.cmx
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore"
- ]
- },
- "facets": {
- "fuchsia.module": {
- "@version": 2,
- "intent_filters": [
- {
- "action": "com.google.fuchsia.common.active",
- "parameters": []
- }
- ],
- "suggestion_headline": "Active module"
- }
- }
-}
diff --git a/tests/common/common_null_module.cc b/tests/common/common_null_module.cc
deleted file mode 100644
index c406863..0000000
--- a/tests/common/common_null_module.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// The NullModule just sits there and does nothing until it's terminated.
-class NullModule {
- public:
- NullModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>
- view_provider_request)
- : module_host_(module_host),
- app_view_provider_(std::move(view_provider_request)) {
- modular::testing::Init(module_host_->startup_context(), __FILE__);
- initialized_.Pass();
- Signal(kCommonNullModuleStarted);
- }
-
- NullModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- view_provider_request)
- : NullModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {
- viewsv1_view_provider_ = std::move(view_provider_request);
- }
-
- // Called by ModuleDriver.
- void Terminate(const std::function<void()>& done) {
- Signal(kCommonNullModuleStopped);
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- TestPoint initialized_{"Null module initialized"};
- TestPoint stopped_{"Null module stopped"};
-
- modular::ModuleHost* const module_host_;
- // We keep the view provider around so that story shell can hold a view for
- // us, but don't do anything with it.
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- viewsv1_view_provider_;
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> app_view_provider_;
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<NullModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/common/common_null_module.cmx b/tests/common/common_null_module.cmx
deleted file mode 100644
index 0a98241..0000000
--- a/tests/common/common_null_module.cmx
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore"
- ]
- },
- "facets": {
- "fuchsia.module": {
- "@version": 2,
- "binary": "bin/app",
- "composition_pattern": "ticker",
- "intent_filters": [
- {
- "action": "com.google.fuchsia.common.null",
- "parameters": []
- }
- ],
- "suggestion_headline": "Null module"
- }
- }
-}
diff --git a/tests/common/defs.h b/tests/common/defs.h
deleted file mode 100644
index 12ec49d..0000000
--- a/tests/common/defs.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_COMMON_DEFS_H_
-#define PERIDOT_TESTS_COMMON_DEFS_H_
-
-namespace {
-
-constexpr char kCommonNullModule[] =
- "fuchsia-pkg://fuchsia.com/common_null_module#meta/common_null_module.cmx";
-constexpr char kCommonNullAction[] = "com.google.fuchsia.common.null";
-
-constexpr char kCommonNullModuleStarted[] = "common_null_module_started";
-constexpr char kCommonNullModuleStopped[] = "common_null_module_stopped";
-
-constexpr char kCommonActiveModule[] =
- "fuchsia-pkg://fuchsia.com/common_active_module#meta/common_active_module.cmx";
-constexpr char kCommonActiveAction[] = "com.google.fuchsia.common.active";
-
-constexpr char kCommonActiveModuleStarted[] = "common_active_module_started";
-constexpr char kCommonActiveModuleOngoing[] = "common_active_module_ongoing";
-constexpr char kCommonActiveModuleStopped[] = "common_active_module_stopped";
-
-} // namespace
-
-#endif // PERIDOT_TESTS_COMMON_DEFS_H_
diff --git a/tests/component_context/BUILD.gn b/tests/component_context/BUILD.gn
deleted file mode 100644
index 66c9fd5..0000000
--- a/tests/component_context/BUILD.gn
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-import("//peridot/build/executable_package.gni")
-
-executable_package("component_context_test_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/component_context_test_module.cmx"
- dest = "component_context_test_module.cmx"
- },
- ]
-
- sources = [
- "component_context_test_module.cc",
- ]
-
- deps = [
- ":component_context_test_service",
- ":defs",
- "//garnet/public/lib/callback",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/public/lib/message_queue/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("component_context_test_one_agent") {
- testonly = true
-
- meta = [
- {
- path = "meta/component_context_test_one_agent.cmx"
- dest = "component_context_test_one_agent.cmx"
- },
- ]
-
- sources = [
- "component_context_test_one_agent.cc",
- ]
-
- deps = [
- ":component_context_test_service",
- ":defs",
- "//garnet/public/lib/fsl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:agent_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/public/lib/message_queue/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("component_context_test_two_agent") {
- testonly = true
-
- meta = [
- {
- path = "meta/component_context_test_two_agent.cmx"
- dest = "component_context_test_two_agent.cmx"
- },
- ]
-
- sources = [
- "component_context_test_two_agent.cc",
- ]
-
- deps = [
- ":defs",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:agent_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("component_context_test_unstoppable_agent") {
- testonly = true
-
- meta = [
- {
- path = "meta/component_context_test_unstoppable_agent.cmx"
- dest = "component_context_test_unstoppable_agent.cmx"
- },
- ]
-
- sources = [
- "component_context_test_unstoppable_agent.cc",
- ]
-
- deps = [
- ":defs",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:agent_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-fidl("component_context_test_service") {
- testonly = true
- cpp_legacy_callbacks = true
-
- name = "test.peridot.tests.componentcontext"
-
- sources = [
- "component_context_test_service.fidl",
- ]
-}
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
diff --git a/tests/component_context/README.md b/tests/component_context/README.md
deleted file mode 100644
index 136d185..0000000
--- a/tests/component_context/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# component_context integration test
-
-The purpose of `fuchsia::modular::ComponentContext` is mainly to expose APIs that lets clients
-interact with Agents.
-
-This test exercises the APIs used to connect with Agents, influence their
-life cycle, and use their services.
diff --git a/tests/component_context/component_context_test_module.cc b/tests/component_context/component_context_test_module.cc
deleted file mode 100644
index 11f0e2f..0000000
--- a/tests/component_context/component_context_test_module.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <utility>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/message_queue/cpp/message_queue_client.h>
-#include <test/peridot/tests/componentcontext/cpp/fidl.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/component_context/defs.h"
-
-using ::modular::testing::Await;
-using ::modular::testing::Signal;
-using ::modular::testing::TestPoint;
-using ::test::peridot::tests::componentcontext::ComponentContextTestServicePtr;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"Root module initialized"};
-
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : weak_ptr_factory_(this) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
-
- initialized_.Pass();
-
- // Exercise fuchsia::modular::ComponentContext.ConnectToAgent()
- module_host->module_context()->GetComponentContext(
- component_context_.NewRequest());
-
- fuchsia::sys::ServiceProviderPtr one_agent_services;
- component_context_->ConnectToAgent(kOneAgentUrl,
- one_agent_services.NewRequest(),
- one_agent_controller.NewRequest());
- component::ConnectToService(one_agent_services.get(),
- one_agent_interface_.NewRequest());
-
- TestAgentConnected();
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called by ModuleDriver.
- TestPoint stopped_{"Root module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- TestPoint one_agent_connected_{"One agent accepted connection"};
-
- void TestAgentConnected() {
- Await("one_agent_connected", [this] {
- FXL_LOG(INFO) << "TestModule One Agent Connected";
- one_agent_connected_.Pass();
- TestMessageQueue();
- });
- }
-
- TestPoint msg_queue_communicated_{
- "Communicated message between Agent one using a MessageQueue"};
-
- // Tests message queues.
- void TestMessageQueue() {
- constexpr char kTestMessage[] = "test message!";
-
- component_context_->ObtainMessageQueue("root_msg_queue",
- msg_queue_.NewRequest());
-
- // MessageQueueManager shouldn't send us anything just yet.
- msg_queue_.RegisterReceiver(
- [this, kTestMessage](const std::string& msg,
- fit::function<void()> ack) {
- ack();
- // We only want one message.
- msg_queue_.RegisterReceiver(nullptr);
-
- if (msg == kTestMessage) {
- msg_queue_communicated_.Pass();
- }
- TestAgentController();
- });
-
- msg_queue_.GetToken([this, kTestMessage](const fidl::StringPtr& token) {
- one_agent_interface_->SendToMessageQueue(token, kTestMessage);
- });
- }
-
- TestPoint one_agent_stopped_{"One agent stopped"};
-
- // Tests fuchsia::modular::AgentController. Calls |done_cb| when completed
- // successfully.
- void TestAgentController() {
- // Closing the agent controller should trigger the agent to stop.
- one_agent_controller.Unbind();
-
- Await("one_agent_stopped", [this] {
- one_agent_stopped_.Pass();
- TestUnstoppableAgent();
- });
- }
-
- // Start an agent that will not stop of its own accord.
- void TestUnstoppableAgent() {
- fuchsia::sys::ServiceProviderPtr unstoppable_agent_services;
- component_context_->ConnectToAgent(
- kUnstoppableAgent, unstoppable_agent_services.NewRequest(),
- unstoppable_agent_controller_.NewRequest());
-
- // After 500ms close the fuchsia::modular::AgentController for the
- // unstoppable agent.
- // TODO(jimbe) We don't check if the agent started running in the allotted
- // time, so this test isn't reliable. We need to make a call to the agent
- // and wait for a response.
- async::PostDelayedTask(
- async_get_default_dispatcher(),
- callback::MakeScoped(weak_ptr_factory_.GetWeakPtr(),
- [this] {
- unstoppable_agent_controller_.Unbind();
- Signal(modular::testing::kTestShutdown);
- }),
- zx::msec(500));
- }
-
- fuchsia::modular::AgentControllerPtr one_agent_controller;
- ComponentContextTestServicePtr one_agent_interface_;
- fuchsia::modular::ComponentContextPtr component_context_;
- modular::MessageQueueClient msg_queue_;
-
- fuchsia::modular::AgentControllerPtr unstoppable_agent_controller_;
-
- fxl::WeakPtrFactory<TestModule> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/component_context/component_context_test_one_agent.cc b/tests/component_context/component_context_test_one_agent.cc
deleted file mode 100644
index e9dcc4b..0000000
--- a/tests/component_context/component_context_test_one_agent.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fxl/logging.h>
-#include <lib/message_queue/cpp/message_sender_client.h>
-#include <test/peridot/tests/componentcontext/cpp/fidl.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/component_context/defs.h"
-
-using ::modular::testing::Await;
-using ::modular::testing::Signal;
-using ::modular::testing::TestPoint;
-using ::test::peridot::tests::componentcontext::ComponentContextTestService;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestApp : ComponentContextTestService {
- public:
- TestApp(modular::AgentHost* const agent_host) {
- modular::testing::Init(agent_host->startup_context(), __FILE__);
- agent_host->agent_context()->GetComponentContext(
- component_context_.NewRequest());
- agent_services_.AddService<ComponentContextTestService>(
- [this](fidl::InterfaceRequest<ComponentContextTestService> request) {
- agent_interface_.AddBinding(this, std::move(request));
- });
-
- // Connecting to the agent should start it up.
- fuchsia::sys::ServiceProviderPtr agent_services;
- component_context_->ConnectToAgent(kTwoAgentUrl,
- agent_services.NewRequest(),
- two_agent_controller_.NewRequest());
- }
-
- // Called by AgentDriver.
- void Connect(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request) {
- agent_services_.AddBinding(std::move(request));
- Signal("one_agent_connected");
- }
-
- // Called by AgentDriver.
- void RunTask(const fidl::StringPtr& /*task_id*/,
- const std::function<void()>& /*callback*/) {}
-
- TestPoint two_agent_connected_{"Two agent accepted connection"};
-
- // Called by AgentDriver.
- void Terminate(const std::function<void()>& done) {
- FXL_LOG(INFO) << "TestOneAgent::Terminate()";
- // Before reporting that we stop, we wait until two_agent has connected.
- Await("two_agent_connected", [this, done] {
- FXL_LOG(INFO) << "TestOneAgent::Terminate() GET";
- // Killing the agent controller should stop it.
- two_agent_controller_.Unbind();
- two_agent_connected_.Pass();
- Signal("one_agent_stopped");
- modular::testing::Done(done);
- });
- }
-
- private:
- // |Agent1Interface|
- void SendToMessageQueue(std::string message_queue_token,
- std::string message_to_send) override {
- modular::MessageSenderClient message_sender;
- component_context_->GetMessageSender(message_queue_token,
- message_sender.NewRequest());
- message_sender.Send(message_to_send);
- }
-
- fuchsia::modular::ComponentContextPtr component_context_;
- fuchsia::modular::AgentControllerPtr two_agent_controller_;
-
- component::ServiceNamespace agent_services_;
- fidl::BindingSet<ComponentContextTestService> agent_interface_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<TestApp> driver(context.get(), [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/component_context/component_context_test_service.fidl b/tests/component_context/component_context_test_service.fidl
deleted file mode 100644
index 9e4aedb..0000000
--- a/tests/component_context/component_context_test_service.fidl
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library test.peridot.tests.componentcontext;
-
-// An interface implemented by component_context_test_one_agent.cc which the
-// root module uses.
-//
-// Cf. README.md for what this test does and how.
-[Discoverable]
-interface ComponentContextTestService {
- // Send |message_to_send| to the message queue backed by
- // |message_queue_token|.
- 1: SendToMessageQueue(string message_queue_token, string message_to_send);
-};
diff --git a/tests/component_context/component_context_test_two_agent.cc b/tests/component_context/component_context_test_two_agent.cc
deleted file mode 100644
index ffc24e9..0000000
--- a/tests/component_context/component_context_test_two_agent.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/component_context/defs.h"
-
-using ::modular::testing::Signal;
-using ::modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestApp {
- public:
- TestApp(modular::AgentHost* const agent_host) {
- modular::testing::Init(agent_host->startup_context(), __FILE__);
- }
-
- // Called by AgentDriver.
- void Connect(
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> /*services*/) {
- Signal("two_agent_connected");
- }
-
- // Called by AgentDriver.
- void RunTask(fidl::StringPtr /*task_id*/,
- const std::function<void()>& /*callback*/) {}
-
- TestPoint terminate_called_{"Terminate() called."};
-
- // Called by AgentDriver.
- void Terminate(const std::function<void()>& done) {
- terminate_called_.Pass();
- modular::testing::Done(done);
- }
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<TestApp> driver(context.get(), [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/component_context/component_context_test_unstoppable_agent.cc b/tests/component_context/component_context_test_unstoppable_agent.cc
deleted file mode 100644
index e0175dd..0000000
--- a/tests/component_context/component_context_test_unstoppable_agent.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fxl/logging.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/component_context/defs.h"
-
-using ::modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestApp {
- public:
- TestPoint initialized_{"Unstoppable agent initialized"};
-
- TestApp(modular::AgentHost* agent_host) {
- modular::testing::Init(agent_host->startup_context(), __FILE__);
- agent_host->agent_context()->GetComponentContext(
- component_context_.NewRequest());
- initialized_.Pass();
- }
-
- // Called by AgentDriver.
- void Connect(
- fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> /*services*/) {}
-
- // Called by AgentDriver.
- void RunTask(fidl::StringPtr /*task_id*/,
- const std::function<void()>& /*callback*/) {}
-
- TestPoint stopped_{"Unstoppable agent stopped"};
-
- // Called by AgentDriver.
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- fuchsia::modular::AgentContextPtr agent_context_;
- fuchsia::modular::ComponentContextPtr component_context_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<TestApp> driver(context.get(), [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/component_context/defs.h b/tests/component_context/defs.h
deleted file mode 100644
index f2f11c5..0000000
--- a/tests/component_context/defs.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_COMPONENT_CONTEXT_DEFS_H_
-#define PERIDOT_TESTS_COMPONENT_CONTEXT_DEFS_H_
-
-namespace {
-
-// Package URLs of the test components used here.
-constexpr char kOneAgentUrl[] =
- "fuchsia-pkg://fuchsia.com/component_context_test_one_agent#meta/component_context_test_one_agent.cmx";
-constexpr char kUnstoppableAgent[] =
- "fuchsia-pkg://fuchsia.com/component_context_test_unstoppable_agent#meta/component_context_test_unstoppable_agent.cmx";
-constexpr char kTwoAgentUrl[] =
- "fuchsia-pkg://fuchsia.com/component_context_test_two_agent#meta/component_context_test_two_agent.cmx";
-
-constexpr int kTotalSimultaneousTests = 2;
-
-} // namespace
-
-#endif // PERIDOT_TESTS_COMPONENT_CONTEXT_DEFS_H_
diff --git a/tests/component_context/meta/component_context_test_module.cmx b/tests/component_context/meta/component_context_test_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/component_context/meta/component_context_test_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/component_context/meta/component_context_test_one_agent.cmx b/tests/component_context/meta/component_context_test_one_agent.cmx
deleted file mode 100644
index 12bf3ba..0000000
--- a/tests/component_context/meta/component_context_test_one_agent.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.AgentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/component_context/meta/component_context_test_two_agent.cmx b/tests/component_context/meta/component_context_test_two_agent.cmx
deleted file mode 100644
index 12bf3ba..0000000
--- a/tests/component_context/meta/component_context_test_two_agent.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.AgentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/component_context/meta/component_context_test_unstoppable_agent.cmx b/tests/component_context/meta/component_context_test_unstoppable_agent.cmx
deleted file mode 100644
index 12bf3ba..0000000
--- a/tests/component_context/meta/component_context_test_unstoppable_agent.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.AgentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/embed_shell/BUILD.gn b/tests/embed_shell/BUILD.gn
deleted file mode 100644
index 9ad1c6e..0000000
--- a/tests/embed_shell/BUILD.gn
+++ /dev/null
@@ -1,122 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("embed_shell_test_child_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/embed_shell_test_child_module.cmx"
- dest = "embed_shell_test_child_module.cmx"
- },
- ]
-
- sources = [
- "embed_shell_test_child_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("embed_shell_test_session_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/embed_shell_test_session_shell.cmx"
- dest = "embed_shell_test_session_shell.cmx"
- },
- ]
-
- sources = [
- "embed_shell_test_session_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/callback",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("embed_shell_test_parent_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/embed_shell_test_parent_module.cmx"
- dest = "embed_shell_test_parent_module.cmx"
- },
- ]
-
- sources = [
- "embed_shell_test_parent_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/callback",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("embed_shell_test_story_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/embed_shell_test_story_shell.cmx"
- dest = "embed_shell_test_story_shell.cmx"
- },
- ]
-
- sources = [
- "embed_shell_test_story_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
diff --git a/tests/embed_shell/README.md b/tests/embed_shell/README.md
deleted file mode 100644
index 4e37d06..0000000
--- a/tests/embed_shell/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# embed_shell integration test
-
-This test executes the interaction of embedding modules with the story shell.
-
-Modules can start other modules. They can do this either by *embedding* the view
-of the other module into their own view, or by instructing the story runner to
-send the view of the newly started module to the story shell. In that case, the
-story shell is supplied with the view of the started module, an ID for it, the
-ID of the view of the parent module, and the *surface relationship* of the new
-module to its parent module. This information is used to layout the views of the
-modules and provide navigation between them.
-
-A subtlety arises when module one embeds module two, which starts module three,
-but in the story shell. In that case, the story shell doesn't know about the
-direct parent of module three, because it's embedded and its view is not sent to
-the story shell. Instead, module one must be used as the display parent module
-declared to the story shell for the view of module three.
-
-This test executes that behavior. In this test, we use the following concrete
-module implementations:
-
- * *one*: `embed_shell_test_parent_module`
- * *two*: `embed_shell_test_child_module`
- * *three*: `common_null_module`
-
diff --git a/tests/embed_shell/defs.h b/tests/embed_shell/defs.h
deleted file mode 100644
index 3cd0c37..0000000
--- a/tests/embed_shell/defs.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_EMBED_SHELL_DEFS_H_
-#define PERIDOT_TESTS_EMBED_SHELL_DEFS_H_
-
-namespace {
-
-constexpr char kStoryName[] = "story";
-
-constexpr char kChildModuleName[] = "child";
-
-// Package URLs of the test components used here.
-constexpr char kChildModuleUrl[] =
- "fuchsia-pkg://fuchsia.com/embed_shell_test_child_module#meta/"
- "embed_shell_test_child_module.cmx";
-
-constexpr char kParentModuleUrl[] =
- "fuchsia-pkg://fuchsia.com/embed_shell_test_parent_module#meta/"
- "embed_shell_test_parent_module.cmx";
-
-constexpr char kParentModuleAction[] = "action";
-constexpr char kChildModuleAction[] = "action";
-
-constexpr char kParentModuleDoneSignal[] = "parent_module_done";
-
-} // namespace
-
-#endif // PERIDOT_TESTS_EMBED_SHELL_DEFS_H_
diff --git a/tests/embed_shell/embed_shell_test_child_module.cc b/tests/embed_shell/embed_shell_test_child_module.cc
deleted file mode 100644
index fc77731..0000000
--- a/tests/embed_shell/embed_shell_test_child_module.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/embed_shell/defs.h"
-
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>
- view_provider_request)
- : module_host_(module_host),
- app_view_provider_(std::move(view_provider_request)) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- StartChildModule();
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- view_provider_request)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {
- views1_view_provider_ = std::move(view_provider_request);
- }
-
- // Called from ModuleDriver.
- void Terminate(const std::function<void()>& done) {
- modular::testing::Done(done);
- }
-
- private:
- void StartChildModule() {
- child_module_.events().OnStateChange =
- [this](fuchsia::modular::ModuleState new_state) {
- OnStateChange(std::move(new_state));
- };
-
- fuchsia::modular::Intent intent;
- intent.handler = kCommonNullModule;
- intent.action = kCommonNullAction;
- module_host_->module_context()->AddModuleToStory(
- kChildModuleName, std::move(intent), child_module_.NewRequest(),
- nullptr /* surface_relation */,
- [](const fuchsia::modular::StartModuleStatus) {});
- }
-
- void OnStateChange(fuchsia::modular::ModuleState state) {
- if (state == fuchsia::modular::ModuleState::RUNNING) {
- modular::testing::GetStore()->Put("child_module_done", "1", [] {});
- }
- }
-
- modular::ModuleHost* const module_host_;
-
- // We keep the view provider around so that story shell can hold a view for
- // us, but don't do anything with it.
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- views1_view_provider_;
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> app_view_provider_;
-
- fuchsia::modular::ModuleControllerPtr child_module_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/embed_shell/embed_shell_test_parent_module.cc b/tests/embed_shell/embed_shell_test_parent_module.cc
deleted file mode 100644
index d1dbcee..0000000
--- a/tests/embed_shell/embed_shell_test_parent_module.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/embed_shell/defs.h"
-
-using modular::testing::Await;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>
- view_provider_request)
- : module_host_(module_host),
- app_view_provider_(std::move(view_provider_request)) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- ScheduleDone();
- StartChildModule();
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- view_provider_request)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {
- views1_view_provider_ = std::move(view_provider_request);
- }
-
- void Terminate(const std::function<void()>& done) {
- modular::testing::Done(done);
- }
-
- private:
- void ScheduleDone() {
- auto check = [this, done = std::make_shared<int>(0)] {
- ++*done;
- if (*done == 2) {
- Signal(kParentModuleDoneSignal);
- }
- };
-
- Await("story_shell_done", check);
- Await("child_module_done", check);
- }
-
- void StartChildModule() {
- fuchsia::modular::Intent intent;
- intent.action = kChildModuleAction;
- intent.handler = kChildModuleUrl;
- FXL_LOG(INFO) << "Starting child module = " << intent.handler;
- module_host_->module_context()->EmbedModule(
- kChildModuleName, std::move(intent), child_module_.NewRequest(),
- child_view_.NewRequest(),
- [](const fuchsia::modular::StartModuleStatus status) {
- FXL_LOG(INFO) << "StartModuleStatus="
- << static_cast<uint32_t>(status);
- });
- }
-
- modular::ModuleHost* const module_host_;
- fuchsia::modular::ModuleControllerPtr child_module_;
- fuchsia::ui::viewsv1token::ViewOwnerPtr child_view_;
-
- // We keep the view provider around so that story shell can hold a view for
- // us, but don't do anything with it.
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- views1_view_provider_;
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> app_view_provider_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- FXL_LOG(INFO) << "embed_shell_test_parent_module";
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/embed_shell/embed_shell_test_session_shell.cc b/tests/embed_shell/embed_shell_test_session_shell.cc
deleted file mode 100644
index c5a2c4c..0000000
--- a/tests/embed_shell/embed_shell_test_session_shell.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/embed_shell/defs.h"
-
-using modular::testing::Await;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does in general and how. The test cases are
-// described in detail in comments below.
-class TestApp : public modular::testing::SessionShellBase {
- public:
- explicit TestApp(component::StartupContext* const startup_context)
- : SessionShellBase(startup_context) {
- TestInit(__FILE__);
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
-
- TestParentChild();
- }
-
- ~TestApp() override = default;
-
- private:
- void TestParentChild() {
- puppet_master_->ControlStory(kStoryName, story_puppet_master_.NewRequest());
-
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("root");
- add_mod.intent.handler = kParentModuleUrl;
- add_mod.intent.action = kParentModuleAction;
- add_mod.intent.parameters =
- fidl::VectorPtr<fuchsia::modular::IntentParameter>::New(0);
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(std::move(command));
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story_provider()->GetController(kStoryName,
- story_controller_.NewRequest());
- fidl::InterfaceHandle<fuchsia::ui::viewsv1token::ViewOwner>
- root_module_view;
- story_controller_->RequestStart();
- });
-
- Await(kParentModuleDoneSignal, [this] {
- story_controller_->Stop([this] { TestModuleReinflation(); });
- });
- }
-
- TestPoint modules_reinflated_correctly_{"Modules reinfated correctly"};
- // Test that embedded modules are not reinflated.
- void TestModuleReinflation() {
- story_controller_->RequestStart();
- story_controller_->GetActiveModules(
- [this](std::vector<fuchsia::modular::ModuleData> active_modules) {
- size_t num_embedded_mods = 0u;
- for (const fuchsia::modular::ModuleData& mod : active_modules) {
- num_embedded_mods += mod.is_embedded;
- }
- if (num_embedded_mods == 0 && active_modules.size() == 2u) {
- modules_reinflated_correctly_.Pass();
- }
- Await(kParentModuleDoneSignal, [this] { Logout(); });
- });
- }
-
- void Logout() { Signal(modular::testing::kTestShutdown); }
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- fuchsia::modular::StoryControllerPtr story_controller_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int argc, const char** argv) {
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/embed_shell/embed_shell_test_story_shell.cc b/tests/embed_shell/embed_shell_test_story_shell.cc
deleted file mode 100644
index 98aff2c..0000000
--- a/tests/embed_shell/embed_shell_test_story_shell.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implementation of the fuchsia::modular::StoryShell service that just lays out
-// the views of all modules side by side.
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/testing/component_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/embed_shell/defs.h"
-
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestApp
- : public modular::testing::ComponentBase<fuchsia::modular::StoryShell> {
- public:
- TestApp(component::StartupContext* const startup_context)
- : ComponentBase(startup_context) {
- TestInit(__FILE__);
- }
-
- ~TestApp() override = default;
-
- private:
- // |fuchsia::modular::StoryShell|
- void Initialize(fidl::InterfaceHandle<fuchsia::modular::StoryShellContext>
- story_shell_context) override {
- story_shell_context_.Bind(std::move(story_shell_context));
- }
-
- TestPoint add_surface_{"AddSurface root:child:child root"};
-
- // |fuchsia::modular::StoryShell|
- void AddSurface(fuchsia::modular::ViewConnection view_connection,
- fuchsia::modular::SurfaceInfo surface_info) override {
- FXL_LOG(INFO) << "surface_id=" << view_connection.surface_id
- << ", anchor_id=" << surface_info.parent_id;
- if (view_connection.surface_id == "root:child:child" &&
- surface_info.parent_id == "root") {
- add_surface_.Pass();
- modular::testing::GetStore()->Put("story_shell_done", "1", [] {});
- } else {
- FXL_LOG(WARNING) << "AddView " << view_connection.surface_id << " anchor "
- << surface_info.parent_id;
- }
- }
-
- // |fuchsia::modular::StoryShell|
- void FocusSurface(std::string /*surface_id*/) override {}
-
- // |fuchsia::modular::StoryShell|
- void DefocusSurface(std::string /*surface_id*/,
- DefocusSurfaceCallback callback) override {
- callback();
- }
-
- // |fuchsia::modular::StoryShell|
- void AddContainer(
- std::string /*container_name*/, fidl::StringPtr /*parent_id*/,
- fuchsia::modular::SurfaceRelation /*relation*/,
- std::vector<fuchsia::modular::ContainerLayout> /*layout*/,
- std::vector<fuchsia::modular::ContainerRelationEntry> /* relationships */,
- std::vector<fuchsia::modular::ContainerView> /* views */) override {}
-
- // |fuchsia::modular::StoryShell|
- void RemoveSurface(std::string /*surface_id*/) override {}
-
- // |fuchsia::modular::StoryShell|
- void ReconnectView(
- fuchsia::modular::ViewConnection view_connection) override {}
-
- // |fuchsia::modular::StoryShell|
- void UpdateSurface(fuchsia::modular::ViewConnection view_connection,
- fuchsia::modular::SurfaceInfo /*surface_info*/) override{};
-
- fuchsia::modular::StoryShellContextPtr story_shell_context_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /* argc */, const char** /* argv */) {
- FXL_LOG(INFO) << "Embed Story Shell main";
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/embed_shell/meta/embed_shell_test_child_module.cmx b/tests/embed_shell/meta/embed_shell_test_child_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/embed_shell/meta/embed_shell_test_child_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/embed_shell/meta/embed_shell_test_parent_module.cmx b/tests/embed_shell/meta/embed_shell_test_parent_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/embed_shell/meta/embed_shell_test_parent_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/embed_shell/meta/embed_shell_test_session_shell.cmx b/tests/embed_shell/meta/embed_shell_test_session_shell.cmx
deleted file mode 100644
index a2fe1c5..0000000
--- a/tests/embed_shell/meta/embed_shell_test_session_shell.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/embed_shell/meta/embed_shell_test_story_shell.cmx b/tests/embed_shell/meta/embed_shell_test_story_shell.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/embed_shell/meta/embed_shell_test_story_shell.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/intents/BUILD.gn b/tests/intents/BUILD.gn
deleted file mode 100644
index 6f8c2bd..0000000
--- a/tests/intents/BUILD.gn
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("intent_test_parent_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/intent_test_parent_module.cmx"
- dest = "intent_test_parent_module.cmx"
- },
- ]
-
- sources = [
- "intent_test_parent_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("intent_test_child_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/intent_test_child_module.cmx"
- dest = "intent_test_child_module.cmx"
- },
- ]
-
- sources = [
- "intent_test_child_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/callback",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
diff --git a/tests/intents/README.md b/tests/intents/README.md
deleted file mode 100644
index 14957a3..0000000
--- a/tests/intents/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Intents integration test
-
-This test exercises the IntentHandler API. It verifies that modules
-receive intents both when they are started as well as when they are
-running and new intents are received by the framework.
diff --git a/tests/intents/defs.h b/tests/intents/defs.h
deleted file mode 100644
index a527010..0000000
--- a/tests/intents/defs.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_INTENTS_DEFS_H_
-#define PERIDOT_TESTS_INTENTS_DEFS_H_
-
-namespace {
-
-constexpr char kChildModuleName[] = "child";
-
-// Package URLs of the test components used here.
-constexpr char kChildModuleUrl[] =
- "fuchsia-pkg://fuchsia.com/intent_test_child_module#meta/intent_test_child_module.cmx";
-
-// The action of the intent the parent module issues to the child module.
-constexpr char kChildModuleAction[] = "intent_test_child_module_action";
-
-// The signal which the child module sends when it has received an intent.
-constexpr char kChildModuleHandledIntent[] = "child_module_handled_intent";
-
-// The name of the intent parameter which contains a string which the child
-// module is to append to its signal.
-constexpr char kIntentParameterName[] = "intent_parameter";
-
-// The name of the intent parameter which contains a string which the child
-// module is to append to its signal.
-constexpr char kIntentParameterNameAlternate[] = "intent_parameter_alternate";
-
-constexpr int kTimeoutMilliseconds = 5000;
-
-} // namespace
-
-#endif // PERIDOT_TESTS_INTENTS_DEFS_H_
diff --git a/tests/intents/intent_test_child_module.cc b/tests/intents/intent_test_child_module.cc
deleted file mode 100644
index 709bb83..0000000
--- a/tests/intents/intent_test_child_module.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/intents/defs.h"
-
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule : fuchsia::modular::IntentHandler {
- public:
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- module_host->startup_context()
- ->outgoing()
- .AddPublicService<fuchsia::modular::IntentHandler>(
- [this](fidl::InterfaceRequest<fuchsia::modular::IntentHandler>
- request) {
- bindings_.AddBinding(this, std::move(request));
- });
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called from ModuleDriver.
- void Terminate(const std::function<void()>& done) {
- modular::testing::Done(done);
- }
-
- private:
- // |IntentHandler|
- void HandleIntent(fuchsia::modular::Intent intent) override {
- for (const auto& parameter : *intent.parameters) {
- if (parameter.data.is_json()) {
- if (parameter.name == kIntentParameterName ||
- parameter.name == kIntentParameterNameAlternate) {
- std::string parameter_data;
- FXL_CHECK(fsl::StringFromVmo(parameter.data.json(), ¶meter_data));
- Signal(kChildModuleHandledIntent + parameter_data);
- }
- }
- }
- }
-
- fidl::BindingSet<fuchsia::modular::IntentHandler> bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/intents/intent_test_parent_module.cc b/tests/intents/intent_test_parent_module.cc
deleted file mode 100644
index 10e819a..0000000
--- a/tests/intents/intent_test_parent_module.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/intents/defs.h"
-
-using modular::testing::Await;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-void StartModuleWithJsonParameter(
- fuchsia::modular::ModuleContext* const module_context,
- std::string module_name, std::string parameter_name,
- std::string parameter_content,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController> request) {
- fuchsia::modular::Intent intent;
- intent.handler = kChildModuleUrl;
- intent.action = kChildModuleAction;
-
- {
- fuchsia::modular::IntentParameter intent_parameter;
- intent_parameter.name = parameter_name;
- intent_parameter.data = fuchsia::modular::IntentParameterData();
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(parameter_content, &vmo));
- intent_parameter.data.set_json(std::move(vmo).ToTransport());
- intent.parameters.push_back(std::move(intent_parameter));
- }
-
- // This tests a null parameter name; it should be excluded from module
- // resolution altogether.
- {
- fuchsia::modular::IntentParameter intent_parameter;
- intent_parameter.name = nullptr;
- intent_parameter.data = fuchsia::modular::IntentParameterData();
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(R"("")", &vmo));
- intent_parameter.data.set_json(std::move(vmo).ToTransport());
- intent.parameters.push_back(std::move(intent_parameter));
- }
-
- module_context->AddModuleToStory(
- module_name, std::move(intent), std::move(request), nullptr,
- [](const fuchsia::modular::StartModuleStatus) {});
-}
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"Parent module initialized"};
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : module_host_(module_host) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- initialized_.Pass();
- TestStartWithModuleControllerRequest();
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Tests that a module which is started with an intent and exposes an intent
- // handler gets notified of the intent by the framework.
- TestPoint intent_was_handled_{"First intent was handled"};
- void TestStartWithModuleControllerRequest() {
- std::string json = "\"first\"";
- StartModuleWithJsonParameter(module_host_->module_context(),
- kChildModuleName, kIntentParameterName, json,
- child_module_.NewRequest());
- Await(kChildModuleHandledIntent + json, [this] {
- intent_was_handled_.Pass();
- TestStartSecondIntentSameParameter();
- });
- }
-
- // Tests that a second intent sent to an already running module with the same
- // parameters but different data notifies the intent handler of the new
- // intent.
- TestPoint second_intent_was_handled_{"Second intent was handled"};
- void TestStartSecondIntentSameParameter() {
- std::string json = "\"second\"";
- StartModuleWithJsonParameter(module_host_->module_context(),
- kChildModuleName, kIntentParameterName, json,
- child_module_second_.NewRequest());
- Await(kChildModuleHandledIntent + json, [this] {
- second_intent_was_handled_.Pass();
- TestStartThirdIntentDifferentParameter();
- });
- }
-
- // Tests that a third intent with different parameters is delivered to the
- // already running intent handler.
- TestPoint third_intent_was_handled_{"Third intent was handled"};
- void TestStartThirdIntentDifferentParameter() {
- std::string json = "\"third\"";
- StartModuleWithJsonParameter(
- module_host_->module_context(), kChildModuleName,
- kIntentParameterNameAlternate, json, child_module_second_.NewRequest());
- Await(kChildModuleHandledIntent + json, [this] {
- third_intent_was_handled_.Pass();
- Signal(modular::testing::kTestShutdown);
- });
- }
-
- // Called by ModuleDriver.
- TestPoint stopped_{"Parent module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- modular::ModuleHost* module_host_;
- fuchsia::modular::ModuleControllerPtr child_module_;
- fuchsia::modular::ModuleControllerPtr child_module_second_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/intents/meta/intent_test_child_module.cmx b/tests/intents/meta/intent_test_child_module.cmx
deleted file mode 100644
index 2bb255c..0000000
--- a/tests/intents/meta/intent_test_child_module.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.BasemgrMonitor",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/intents/meta/intent_test_parent_module.cmx b/tests/intents/meta/intent_test_parent_module.cmx
deleted file mode 100644
index 2bb255c..0000000
--- a/tests/intents/meta/intent_test_parent_module.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.BasemgrMonitor",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/last_focus_time/BUILD.gn b/tests/last_focus_time/BUILD.gn
deleted file mode 100644
index 161e3a9..0000000
--- a/tests/last_focus_time/BUILD.gn
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("last_focus_time_test_session_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/last_focus_time_test_session_shell.cmx"
- dest = "last_focus_time_test_session_shell.cmx"
- },
- ]
-
- sources = [
- "last_focus_time_test_session_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/common:story_provider_watcher_base",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- ]
-}
diff --git a/tests/last_focus_time/README.md b/tests/last_focus_time/README.md
deleted file mode 100644
index 589476e..0000000
--- a/tests/last_focus_time/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# last_focus_time integration test
-
-The story runner records the time a story was last focused in the user's root
-page as part of `fuchsia::modular::StoryInfo`.
-
-This test verifies that requesting focus for a story indeed increases the
-`last_focus_time` recorded for that story, and triggers the watchers for the
-story.
-
diff --git a/tests/last_focus_time/defs.h b/tests/last_focus_time/defs.h
deleted file mode 100644
index fef6a67..0000000
--- a/tests/last_focus_time/defs.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_LAST_FOCUS_TIME_DEFS_H_
-#define PERIDOT_TESTS_LAST_FOCUS_TIME_DEFS_H_
-
-namespace {
-
-// URLs of the modules used here.
-
-} // namespace
-
-#endif // PERIDOT_TESTS_LAST_FOCUS_TIME_DEFS_H_
diff --git a/tests/last_focus_time/last_focus_time_test_session_shell.cc b/tests/last_focus_time/last_focus_time_test_session_shell.cc
deleted file mode 100644
index 849df8e..0000000
--- a/tests/last_focus_time/last_focus_time_test_session_shell.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/common/story_provider_watcher_base.h"
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_base.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/last_focus_time/defs.h"
-
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-constexpr char kStoryName[] = "story1";
-
-// A simple story provider watcher implementation. It confirms that it sees an
-// increase in the last_focus_time in the fuchsia::modular::StoryInfo it
-// receives, and pushes the test through to the next step.
-class StoryProviderWatcherImpl : public modular::StoryProviderWatcherBase {
- public:
- StoryProviderWatcherImpl() = default;
- ~StoryProviderWatcherImpl() override = default;
-
- private:
- TestPoint last_focus_time_created_{
- "StoryInfo::last_focus_time increased after create"};
- TestPoint last_focus_time_focused_{
- "StoryInfo::last_focus_time increased after focus"};
-
- // |fuchsia::modular::StoryProviderWatcher|
- void OnChange(
- fuchsia::modular::StoryInfo story_info,
- fuchsia::modular::StoryState story_state,
- fuchsia::modular::StoryVisibilityState story_visibility_state) override {
- FXL_CHECK(story_info.last_focus_time >= last_focus_time_);
- if (story_info.last_focus_time <= last_focus_time_) {
- return;
- }
-
- // Every time we see an increase in last_focus_time, we push the test
- // sequence forward.
- //
- // We expect two last_focus_time transitions:
- //
- // -1 -> 0 on creation of the story.
- //
- // 0 -> Y where Y > 0 on focusing the story.
- //
- switch (++change_count_) {
- case 1:
- if (story_info.last_focus_time == 0) {
- last_focus_time_created_.Pass();
- }
- break;
- case 2:
- last_focus_time_focused_.Pass();
- break;
- default:
- FXL_CHECK(change_count_ == 1 || change_count_ == 2);
- break;
- }
-
- last_focus_time_ = story_info.last_focus_time;
- continue_();
- }
-
- int change_count_{};
- int64_t last_focus_time_{-1};
-};
-
-class StoryWatcherImpl : fuchsia::modular::StoryWatcher {
- public:
- StoryWatcherImpl() : binding_(this) {}
- ~StoryWatcherImpl() override = default;
-
- // Registers itself as a watcher on the given story. Only one story at a time
- // can be watched.
- void Watch(fuchsia::modular::StoryController* const story_controller) {
- story_controller->Watch(binding_.NewBinding());
- }
-
- // Deregisters itself from the watched story.
- void Reset() { binding_.Unbind(); }
-
- // Sets the function where to continue when the story is observed to be
- // running.
- void Continue(std::function<void()> at) { continue_ = at; }
-
- private:
- // |fuchsia::modular::StoryWatcher|
- void OnStateChange(fuchsia::modular::StoryState state) override {
- FXL_LOG(INFO) << "OnStateChange() " << fidl::ToUnderlying(state);
- if (state != fuchsia::modular::StoryState::RUNNING) {
- return;
- }
-
- continue_();
- }
-
- // |fuchsia::modular::StoryWatcher|
- void OnModuleAdded(fuchsia::modular::ModuleData /*module_data*/) override {}
-
- // |fuchsia::modular::StoryWatcher|
- void OnModuleFocused(
- std::vector<std::string> /*module_path*/) override {}
-
- fidl::Binding<fuchsia::modular::StoryWatcher> binding_;
- std::function<void()> continue_;
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryWatcherImpl);
-};
-
-// A simple focus watcher implementation that invokes a "continue" callback when
-// it sees the next focus change.
-class FocusWatcherImpl : fuchsia::modular::FocusWatcher {
- public:
- FocusWatcherImpl() : binding_(this) {}
- ~FocusWatcherImpl() override = default;
-
- // Registers itself as a watcher on the focus provider.
- void Watch(fuchsia::modular::FocusProvider* const focus_provider) {
- focus_provider->Watch(binding_.NewBinding());
- }
-
- // Deregisters itself from the watched focus provider.
- void Reset() { binding_.Unbind(); }
-
- private:
- // |fuchsia::modular::FocusWatcher|
- void OnFocusChange(fuchsia::modular::FocusInfoPtr info) override {
- FXL_LOG(INFO) << "OnFocusChange() " << info->focused_story_id;
- }
-
- fidl::Binding<fuchsia::modular::FocusWatcher> binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(FocusWatcherImpl);
-};
-
-// Cf. README.md for what this test does and how.
-class TestApp : public modular::testing::SessionShellBase {
- public:
- TestApp(component::StartupContext* const startup_context)
- : SessionShellBase(startup_context) {
- TestInit(__FILE__);
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
- story_provider_watcher_.Watch(story_provider());
-
- session_shell_context()->GetFocusController(focus_controller_.NewRequest());
- session_shell_context()->GetFocusProvider(focus_provider_.NewRequest());
- focus_watcher_.Watch(focus_provider_.get());
-
- CreateStory();
- }
-
- ~TestApp() override = default;
-
- private:
- TestPoint create_story_{"CreateStory()"};
-
- void CreateStory() {
- puppet_master_->ControlStory(kStoryName, story_puppet_master_.NewRequest());
-
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("mod1");
- add_mod.intent.handler = kCommonNullModule;
- add_mod.intent.action = kCommonNullAction;
-
- std::vector<fuchsia::modular::StoryCommand> commands(1);
- commands.at(0).set_add_mod(std::move(add_mod));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- create_story_.Pass();
- StartStory();
- });
- }
-
- TestPoint start_story_{"StartStory()"};
-
- void StartStory() {
- story_provider()->GetController(kStoryName, story_controller_.NewRequest());
- story_watcher_.Watch(story_controller_.get());
-
- // Request start of the new story.
- story_controller_->RequestStart();
-
- story_watcher_.Continue([this] {
- start_story_.Pass();
- story_watcher_.Reset();
- Focus();
- });
- }
-
- TestPoint focus_{"Focus()"};
-
- void Focus() {
- focus_controller_->Set(kStoryName);
-
- story_provider_watcher_.Continue([this] {
- focus_.Pass();
- story_provider_watcher_.Reset();
-
- Signal(modular::testing::kTestShutdown);
- });
- }
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- StoryProviderWatcherImpl story_provider_watcher_;
-
- fuchsia::modular::StoryControllerPtr story_controller_;
- StoryWatcherImpl story_watcher_;
-
- fuchsia::modular::FocusControllerPtr focus_controller_;
- fuchsia::modular::FocusProviderPtr focus_provider_;
- FocusWatcherImpl focus_watcher_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/last_focus_time/meta/last_focus_time_test_session_shell.cmx b/tests/last_focus_time/meta/last_focus_time_test_session_shell.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/last_focus_time/meta/last_focus_time_test_session_shell.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/link_context_entities/BUILD.gn b/tests/link_context_entities/BUILD.gn
deleted file mode 100644
index 736db1f..0000000
--- a/tests/link_context_entities/BUILD.gn
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("link_context_entities_test_session_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/link_context_entities_test_session_shell.cmx"
- dest = "link_context_entities_test_session_shell.cmx"
- },
- ]
-
- sources = [
- "link_context_entities_test_session_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:single_service_app",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/context/cpp:context_helper",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("link_context_entities_test_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/link_context_entities_test_module.cmx"
- dest = "link_context_entities_test_module.cmx"
- },
- ]
-
- sources = [
- "link_context_entities_test_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/lib/testing:component_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
diff --git a/tests/link_context_entities/README.md b/tests/link_context_entities/README.md
deleted file mode 100644
index 78db09e..0000000
--- a/tests/link_context_entities/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# link_context_entities integration test
-
-This test exercises the machinery that includes link values in the context
-exposed by `ContextService` in the case that the link values contain entities.
diff --git a/tests/link_context_entities/defs.h b/tests/link_context_entities/defs.h
deleted file mode 100644
index d7182a5..0000000
--- a/tests/link_context_entities/defs.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_LINK_CONTEXT_ENTITIES_DEFS_H_
-#define PERIDOT_TESTS_LINK_CONTEXT_ENTITIES_DEFS_H_
-
-namespace {
-
-// Package URLs of the test components used here.
-constexpr char kModuleUrl[] =
- "fuchsia-pkg://fuchsia.com/link_context_entities_test_module#meta/link_context_entities_test_module.cmx";
-constexpr char kModuleAction[] = "action";
-
-} // namespace
-
-#endif // PERIDOT_TESTS_LINK_CONTEXT_ENTITIES_DEFS_H_
diff --git a/tests/link_context_entities/link_context_entities_test_module.cc b/tests/link_context_entities/link_context_entities_test_module.cc
deleted file mode 100644
index 3189dc4..0000000
--- a/tests/link_context_entities/link_context_entities_test_module.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/time/time_delta.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/link_context_entities/defs.h"
-
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"Child module initialized"};
-
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- initialized_.Pass();
- module_host->module_context()->GetLink("link1", link1_.NewRequest());
- module_host->module_context()->GetLink("link2", link2_.NewRequest());
- Set1();
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called from ModuleDriver.
- TestPoint stopped_{"Child module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- void SetLink(fuchsia::modular::Link* link,
- fidl::VectorPtr<std::string> path,
- const std::string& value) {
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(value, &vmo));
- link->Set(std::move(path), std::move(vmo).ToTransport());
- }
-
- void Set1() {
- SetLink(link1_.get(), nullptr, R"({"@type": "type1", "value": "value1"})");
- SetLink(link2_.get(), nullptr, R"({"@type": "type2", "value": "value2"})");
- // TODO(thatguy): When we have fuchsia::modular::Entity support in
- // fuchsia::modular::ContextWriter, create a simple fuchsia::modular::Entity
- // reference and slap it into the fuchsia::modular::Link.
- }
-
- fuchsia::modular::LinkPtr link1_;
- fuchsia::modular::LinkPtr link2_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/link_context_entities/link_context_entities_test_session_shell.cc b/tests/link_context_entities/link_context_entities_test_session_shell.cc
deleted file mode 100644
index 918d37f..0000000
--- a/tests/link_context_entities/link_context_entities_test_session_shell.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <sstream>
-#include <string>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/context/cpp/context_helper.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fostr/fidl/fuchsia/modular/formatting.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/fidl/array_to_string.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/link_context_entities/defs.h"
-
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-const char kStoryName[] = "story";
-
-// A context reader watcher implementation.
-class ContextListenerImpl : fuchsia::modular::ContextListener {
- public:
- ContextListenerImpl() : binding_(this) {
- handler_ = [](const fuchsia::modular::ContextValue&) {};
- }
-
- ~ContextListenerImpl() override = default;
-
- // Registers itself a watcher on the given story provider. Only one story
- // provider can be watched at a time.
- void Listen(fuchsia::modular::ContextReader* const context_reader) {
- // Subscribe to all entity values.
- fuchsia::modular::ContextSelector selector;
- selector.type = fuchsia::modular::ContextValueType::ENTITY;
-
- fuchsia::modular::ContextQuery query;
- modular::AddToContextQuery(&query, "all", std::move(selector));
-
- context_reader->Subscribe(std::move(query), binding_.NewBinding());
- binding_.set_error_handler([](zx_status_t status) {
- FXL_LOG(ERROR) << "Lost fuchsia::modular::ContextListener connection to "
- "fuchsia::modular::ContextReader.";
- });
- }
-
- using Handler = std::function<void(const fuchsia::modular::ContextValue&)>;
-
- void Handle(const Handler& handler) { handler_ = handler; }
-
- // Deregisters itself from the watched story provider.
- void Reset() { binding_.Unbind(); }
-
- private:
- // |fuchsia::modular::ContextListener|
- void OnContextUpdate(fuchsia::modular::ContextUpdate update) override {
- FXL_LOG(INFO) << "ContextListenerImpl::OnUpdate()";
- if (auto values = modular::TakeContextValue(&update, "all")) {
- for (const auto& value : *values) {
- FXL_LOG(INFO) << "ContextListenerImpl::OnUpdate() " << value;
- handler_(value);
- }
- };
- }
-
- fidl::Binding<fuchsia::modular::ContextListener> binding_;
- Handler handler_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(ContextListenerImpl);
-};
-
-// Cf. README.md for what this test does and how.
-class TestApp : public modular::testing::SessionShellBase {
- public:
- TestApp(component::StartupContext* const startup_context)
- : SessionShellBase(startup_context) {
- TestInit(__FILE__);
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
-
- fuchsia::modular::IntelligenceServicesPtr intelligence_services;
- startup_context->ConnectToEnvironmentService(
- intelligence_services.NewRequest());
- intelligence_services->GetContextReader(context_reader_.NewRequest());
- context_listener_.Listen(context_reader_.get());
- context_reader_.set_error_handler([](zx_status_t status) {
- FXL_LOG(ERROR) << "Lost fuchsia::modular::ContextReader connection.";
- });
-
- CreateStory();
- }
-
- ~TestApp() override = default;
-
- private:
- TestPoint create_story_{"CreateStory()"};
-
- void CreateStory() {
- puppet_master_->ControlStory(kStoryName, story_puppet_master_.NewRequest());
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("root");
- add_mod.intent.handler = kModuleUrl;
- add_mod.intent.action = kModuleAction;
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- create_story_.Pass();
- StartStory();
- });
- }
-
- TestPoint start_story_enter_{"StartStory() Enter"};
- TestPoint start_story_exit_{"StartStory() Exit"};
-
- void StartStory() {
- start_story_enter_.Pass();
-
- context_listener_.Handle(
- [this](const fuchsia::modular::ContextValue& value) {
- ProcessContextValue(value);
- });
-
- story_provider()->GetController(kStoryName, story_controller_.NewRequest());
- story_controller_->RequestStart();
-
- start_story_exit_.Pass();
- }
-
- TestPoint get_context_topic_1_{"GetContextTopic() value=1"};
- int get_context_topic_1_called_{};
- TestPoint get_context_topic_2_{"GetContextTopic() value=2"};
- int get_context_topic_2_called_{};
-
- void ProcessContextValue(const fuchsia::modular::ContextValue& value) {
- // The context value has metadata that is derived from the story id in
- // which it was published.
- if (!value.meta.story || !value.meta.link || !value.meta.entity) {
- FXL_LOG(ERROR) << "fuchsia::modular::ContextValue missing metadata: "
- << value;
- return;
- }
-
- if (value.meta.story->id != kStoryName ||
- value.meta.entity->type.is_null() ||
- value.meta.entity->type->size() != 1) {
- FXL_LOG(ERROR) << "fuchsia::modular::ContextValue metadata is incorrect: "
- << value;
- return;
- }
-
- modular::JsonDoc doc;
- doc.Parse(value.content);
-
- if (doc.HasParseError()) {
- FXL_LOG(ERROR) << "JSON Parse Error" << value.content;
- Logout();
- return;
- }
-
- if (!doc.IsObject()) {
- FXL_LOG(ERROR) << "JSON not an Object" << value.content;
- Logout();
- return;
- }
-
- if (!doc.HasMember("value")) {
- FXL_LOG(ERROR) << "JSON missing 'value': " << value.content;
- Logout();
- return;
- }
-
- const std::string value_property{doc["value"].GetString()};
- const std::string type{value.meta.entity->type->at(0)};
- if (value_property != "value1" && value_property != "value2") {
- FXL_LOG(ERROR) << "JSON 'value' property (set by module) wrong: "
- << value_property;
- Logout();
- return;
- }
-
- if (value_property == "value1" && type == "type1" &&
- value.meta.link->name == "link1") {
- if (++get_context_topic_1_called_ == 1) {
- get_context_topic_1_.Pass();
- }
- } else if (value_property == "value2" && type == "type2" &&
- value.meta.link->name == "link2") {
- if (++get_context_topic_2_called_ == 1) {
- get_context_topic_2_.Pass();
- }
- }
-
- if (get_context_topic_1_called_ > 0 && get_context_topic_2_called_ > 0) {
- context_listener_.Reset();
- context_listener_.Handle(
- [this](const fuchsia::modular::ContextValue&) {});
- Logout();
- }
- }
-
- void Logout() {
- Signal(modular::testing::kTestShutdown);
- }
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
-
- fuchsia::modular::StoryControllerPtr story_controller_;
-
- fuchsia::modular::ContextReaderPtr context_reader_;
- ContextListenerImpl context_listener_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/link_context_entities/meta/link_context_entities_test_module.cmx b/tests/link_context_entities/meta/link_context_entities_test_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/link_context_entities/meta/link_context_entities_test_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/link_context_entities/meta/link_context_entities_test_session_shell.cmx b/tests/link_context_entities/meta/link_context_entities_test_session_shell.cmx
deleted file mode 100644
index 7efcca5..0000000
--- a/tests/link_context_entities/meta/link_context_entities_test_session_shell.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.IntelligenceServices",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/maxwell_integration/BUILD.gn b/tests/maxwell_integration/BUILD.gn
deleted file mode 100644
index c72a6a9..0000000
--- a/tests/maxwell_integration/BUILD.gn
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-hermetic_tests_package("maxwell_integration_tests") {
- deps = [
- ":context_engine_test",
- ":suggestion_engine_test",
- ]
-}
-
-executable("context_engine_test") {
- testonly = true
-
- sources = [
- "context_engine_test.cc",
- ]
-
- deps = [
- ":context_common",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fsl",
- "//peridot/bin/context_engine:scope_utils",
- "//peridot/lib/testing:entity_resolver_fake",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/context/cpp:context_helper",
- "//peridot/public/lib/context/cpp:context_metadata_builder",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-executable("suggestion_engine_test") {
- testonly = true
-
- sources = [
- "suggestion_engine_test.cc",
- ]
-
- deps = [
- ":context_common",
- ":test_suggestion_listener",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/fsl",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:story_provider_mock",
- "//peridot/lib/testing:wait_until_idle",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/context/cpp:context_helper",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-# TODO(rosswang): move utils to a subdirectory
-
-source_set("context_common") {
- testonly = true
-
- sources = [
- "context_engine_test_base.cc",
- "context_engine_test_base.h",
- ]
-
- deps = [
- ":common",
- "//peridot/lib/testing:wait_until_idle",
- ]
-
- public_deps = [
- "//peridot/public/fidl/fuchsia.modular",
- "//third_party/googletest:gtest",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-source_set("common") {
- testonly = true
-
- sources = [
- "test.cc",
- "test.h",
- ]
-
- deps = [
- "//peridot/lib/environment_host",
- "//peridot/lib/testing:component_context_fake",
- "//peridot/lib/testing:entity_resolver_fake",
- ]
-
- public_deps = [
- "//garnet/public/lib/component/cpp",
- "//third_party/googletest:gtest",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-source_set("test_suggestion_listener") {
- testonly = true
-
- sources = [
- "test_suggestion_listener.cc",
- "test_suggestion_listener.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/fostr/fidl/fuchsia.modular",
- ]
-
- public_deps = [
- "//third_party/googletest:gtest",
- ]
-}
diff --git a/tests/maxwell_integration/context_engine_test.cc b/tests/maxwell_integration/context_engine_test.cc
deleted file mode 100644
index 9c3cb4a..0000000
--- a/tests/maxwell_integration/context_engine_test.cc
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/context/cpp/context_helper.h>
-#include <lib/context/cpp/context_metadata_builder.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/clone.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/logging.h>
-#include "peridot/bin/context_engine/scope_utils.h"
-#include "peridot/tests/maxwell_integration/context_engine_test_base.h"
-
-namespace maxwell {
-namespace {
-
-fuchsia::modular::ComponentScope MakeGlobalScope() {
- fuchsia::modular::ComponentScope scope;
- scope.set_global_scope(fuchsia::modular::GlobalScope());
- return scope;
-}
-
-class TestListener : public fuchsia::modular::ContextListener {
- public:
- fuchsia::modular::ContextUpdatePtr last_update;
-
- TestListener() : binding_(this) {}
-
- void OnContextUpdate(fuchsia::modular::ContextUpdate update) override {
- last_update = fidl::MakeOptional(std::move(update));
- }
-
- fidl::InterfaceHandle<fuchsia::modular::ContextListener> GetHandle() {
- return binding_.NewBinding();
- }
-
- void Reset() { last_update.reset(); }
-
- private:
- fidl::Binding<fuchsia::modular::ContextListener> binding_;
-};
-
-class ContextEngineTest : public ContextEngineTestBase {
- public:
- void SetUp() override {
- ContextEngineTestBase::SetUp();
- InitAllGlobalScope();
- }
-
- protected:
- void InitAllGlobalScope() {
- InitReader(MakeGlobalScope());
- InitWriter(MakeGlobalScope());
- }
-
- void InitReader(fuchsia::modular::ComponentScope scope) {
- reader_.Unbind();
- context_engine()->GetReader(std::move(scope), reader_.NewRequest());
- }
-
- void InitWriter(fuchsia::modular::ComponentScope client_info) {
- writer_.Unbind();
- context_engine()->GetWriter(std::move(client_info), writer_.NewRequest());
- }
-
- fuchsia::modular::ContextReaderPtr reader_;
- fuchsia::modular::ContextWriterPtr writer_;
-};
-
-// Result ordering for |fuchsia::modular::ContextValue|s is not specified, and
-// ordering ends up depending on the order the
-// |fuchsia::modular::ContextValueWriter::Set| calls get handled, which is
-// nondeterministic since they are on separate channels.
-std::set<std::string> GetTopicSet(
- const std::vector<fuchsia::modular::ContextValue>& values) {
- std::set<std::string> topics;
- for (const auto& value : values) {
- topics.emplace(value.meta.entity->topic);
- }
- return topics;
-}
-
-} // namespace
-
-TEST_F(ContextEngineTest, ContextValueWriter) {
- // Use the fuchsia::modular::ContextValueWriter interface, available by
- // calling fuchsia::modular::ContextWriter.CreateValue().
- fuchsia::modular::ContextValueWriterPtr value1;
- writer_->CreateValue(value1.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- value1->Set(R"({ "@type": "someType", "foo": "bar" })",
- fidl::MakeOptional(
- ContextMetadataBuilder().SetEntityTopic("topic").Build()));
-
- fuchsia::modular::ContextValueWriterPtr value2;
- writer_->CreateValue(value2.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- value2->Set(R"({ "@type": ["someType", "alsoAnotherType"], "baz": "bang" })",
- fidl::MakeOptional(
- ContextMetadataBuilder().SetEntityTopic("frob").Build()));
-
- fuchsia::modular::ContextValueWriterPtr value3;
- writer_->CreateValue(value3.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- value3->Set(
- entity_resolver().AddEntity({{"someType", ""}, {"evenMoreType", ""}}),
- fidl::MakeOptional(
- ContextMetadataBuilder().SetEntityTopic("borf").Build()));
-
- // Subscribe to those values.
- fuchsia::modular::ContextSelector selector;
- selector.type = fuchsia::modular::ContextValueType::ENTITY;
- selector.meta = fidl::MakeOptional(
- ContextMetadataBuilder().AddEntityType("someType").Build());
-
- fuchsia::modular::ContextQuery query;
- modular::AddToContextQuery(&query, "a", std::move(selector));
-
- TestListener listener;
- reader_->Subscribe(std::move(query), listener.GetHandle());
-
- WaitUntilIdle();
- ASSERT_TRUE(listener.last_update);
- auto maybe_results =
- modular::TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_results.has_value());
- auto results = std::move(maybe_results.value());
- ASSERT_EQ(3u, results.size());
- EXPECT_EQ(std::set<std::string>({"topic", "frob", "borf"}),
- GetTopicSet(results));
-
- // Update value1 and value3 so they're no longer matches for the 'someType'
- // query.
- listener.Reset();
- value1->Set(R"({ "@type": "notSomeType", "foo": "bar" })", nullptr);
- value3.Unbind();
-
- WaitUntilIdle();
- ASSERT_TRUE(listener.last_update);
- maybe_results = modular::TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_results.has_value());
- results = std::move(maybe_results.value());
- ASSERT_EQ(1u, results.size());
- EXPECT_EQ("frob", results[0].meta.entity->topic);
-
- // Create two new values: A Story value and a child fuchsia::modular::Entity
- // value, where the fuchsia::modular::Entity value matches our query.
- listener.Reset();
- fuchsia::modular::ContextValueWriterPtr story_value;
- writer_->CreateValue(story_value.NewRequest(),
- fuchsia::modular::ContextValueType::STORY);
- story_value->Set(
- nullptr,
- fidl::MakeOptional(ContextMetadataBuilder().SetStoryId("story").Build()));
-
- WaitUntilIdle();
- FXL_LOG(INFO) << "should be null right now: " << listener.last_update;
-
- fuchsia::modular::ContextValueWriterPtr value4;
- story_value->CreateChildValue(value4.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- WaitUntilIdle();
- value4->Set(R"({"@type": "someType"})",
- fidl::MakeOptional(
- ContextMetadataBuilder().AddEntityType("someType").Build()));
-
- WaitUntilIdle();
- maybe_results = modular::TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_results.has_value());
- results = std::move(maybe_results.value());
- ASSERT_EQ(2u, results.size());
-
- fuchsia::modular::ContextValue entity_result, story_result;
- if (results[0].type == fuchsia::modular::ContextValueType::ENTITY) {
- entity_result = std::move(results[0]);
- story_result = std::move(results[1]);
- } else {
- story_result = std::move(results[0]);
- entity_result = std::move(results[1]);
- }
- EXPECT_EQ("frob", entity_result.meta.entity->topic);
- EXPECT_EQ(R"({"@type": "someType"})", story_result.content);
- EXPECT_EQ("story", story_result.meta.story->id);
-
- // Lastly remove one of the values by resetting the
- // fuchsia::modular::ContextValueWriter proxy.
- listener.Reset();
- value4.Unbind();
-
- WaitUntilIdle();
- ASSERT_TRUE(listener.last_update);
- maybe_results = modular::TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_results.has_value());
- results = std::move(maybe_results.value());
- ASSERT_EQ(1u, results.size());
- EXPECT_EQ("frob", results[0].meta.entity->topic);
-}
-
-TEST_F(ContextEngineTest, WriteNullEntity) {
- fuchsia::modular::ContextMetadata meta =
- ContextMetadataBuilder().SetEntityTopic("topic").Build();
-
- fuchsia::modular::ContextSelector selector;
- selector.type = fuchsia::modular::ContextValueType::ENTITY;
- selector.meta = fidl::MakeOptional(fidl::Clone(meta));
- fuchsia::modular::ContextQuery query;
- modular::AddToContextQuery(&query, "a", std::move(selector));
-
- fuchsia::modular::ContextValueWriterPtr value;
- writer_->CreateValue(value.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
-
- const std::string value1 = R"({ "@type": "someType", "foo": "frob" })";
- const std::string value2 = R"({ "@type": "someType", "foo": "borf" })";
-
- value->Set(value1, fidl::MakeOptional(fidl::Clone(meta)));
-
- TestListener listener;
- reader_->Subscribe(std::move(query), listener.GetHandle());
-
- WaitUntilIdle();
-
- ASSERT_TRUE(listener.last_update);
- auto maybe_result =
- modular::TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- auto result = std::move(maybe_result.value());
- ASSERT_EQ(1u, result.size());
- EXPECT_EQ(value1, result[0].content);
-
- listener.Reset();
-
- value->Set(nullptr, nullptr);
-
- // Ensure that this didn't cause a crash; the fidl further specifies that
- // previous values should be unchanged.
-
- value->Set(value2, fidl::MakeOptional(fidl::Clone(meta)));
-
- WaitUntilIdle();
- ASSERT_TRUE(listener.last_update);
-
- maybe_result = modular::TakeContextValue(listener.last_update.get(), "a");
- ASSERT_TRUE(maybe_result.has_value());
- result = std::move(maybe_result.value());
- ASSERT_EQ(1u, result.size());
- EXPECT_EQ(value2, result[0].content);
-}
-
-TEST_F(ContextEngineTest, CloseListenerAndReader) {
- // Ensure that listeners can be closed individually, and that the reader
- // itself can be closed and listeners are still valid.
- fuchsia::modular::ContextSelector selector;
- selector.type = fuchsia::modular::ContextValueType::ENTITY;
- selector.meta = fidl::MakeOptional(
- ContextMetadataBuilder().SetEntityTopic("topic").Build());
- fuchsia::modular::ContextQuery query;
- modular::AddToContextQuery(&query, "a", std::move(selector));
-
- TestListener listener2;
- {
- TestListener listener1;
- reader_->Subscribe(fidl::Clone(query), listener1.GetHandle());
- reader_->Subscribe(fidl::Clone(query), listener2.GetHandle());
- InitReader(MakeGlobalScope());
-
- WaitUntilIdle();
- EXPECT_TRUE(listener2.last_update);
- listener2.Reset();
- }
-
- // We don't want to crash. If the test below fails, context engine has
- // probably crashed.
- fuchsia::modular::ContextValueWriterPtr value;
- writer_->CreateValue(value.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- value->Set("foo",
- fidl::MakeOptional(
- ContextMetadataBuilder().SetEntityTopic("topic").Build()));
-
- WaitUntilIdle();
- EXPECT_TRUE(listener2.last_update);
-}
-
-TEST_F(ContextEngineTest, GetContext) {
- // Ensure fuchsia::modular::ContextReader::Get returns values in the context
- // we queried for.
- fuchsia::modular::ContextValueWriterPtr value1;
- writer_->CreateValue(value1.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- value1->Set(R"({ "@type": "someType", "foo": "bar" })",
- fidl::MakeOptional(
- ContextMetadataBuilder().SetEntityTopic("topic").Build()));
-
- fuchsia::modular::ContextValueWriterPtr value2;
- writer_->CreateValue(value2.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- value2->Set(R"({ "@type": ["someType", "alsoAnotherType"], "baz": "bang" })",
- fidl::MakeOptional(
- ContextMetadataBuilder().SetEntityTopic("frob").Build()));
-
- fuchsia::modular::ContextValueWriterPtr value3;
- writer_->CreateValue(value3.NewRequest(),
- fuchsia::modular::ContextValueType::ENTITY);
- value3->Set(R"({ "@type": ["otherType", "alsoAnotherType"], "qux": "quux" })",
- fidl::MakeOptional(
- ContextMetadataBuilder().SetEntityTopic("borf").Build()));
-
- // Query those values.
- fuchsia::modular::ContextSelector selector;
- selector.type = fuchsia::modular::ContextValueType::ENTITY;
- selector.meta = fidl::MakeOptional(
- ContextMetadataBuilder().AddEntityType("someType").Build());
- fuchsia::modular::ContextQuery query;
- modular::AddToContextQuery(&query, "a", std::move(selector));
-
- // Make sure context has been written.
- TestListener listener;
- reader_->Subscribe(fidl::Clone(query), listener.GetHandle());
-
- WaitUntilIdle();
- EXPECT_TRUE(listener.last_update);
-
- // Assert Get gives us the expected context.
- bool callback_called = false;
- reader_->Get(std::move(query), [&callback_called](
- fuchsia::modular::ContextUpdate update) {
- callback_called = true;
-
- auto maybe_results = modular::TakeContextValue(&update, "a");
- ASSERT_TRUE(maybe_results.has_value());
- auto results = std::move(maybe_results.value());
- ASSERT_EQ(2u, results.size());
- EXPECT_EQ(std::set<std::string>({"topic", "frob"}), GetTopicSet(results));
- });
-
- WaitUntilIdle();
- EXPECT_TRUE(callback_called);
-}
-
-} // namespace maxwell
diff --git a/tests/maxwell_integration/context_engine_test_base.cc b/tests/maxwell_integration/context_engine_test_base.cc
deleted file mode 100644
index 2e5600f..0000000
--- a/tests/maxwell_integration/context_engine_test_base.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/tests/maxwell_integration/context_engine_test_base.h"
-
-#include "peridot/lib/testing/wait_until_idle.h"
-
-namespace {
-
-constexpr char kContextEngineUrl[] =
- "fuchsia-pkg://fuchsia.com/context_engine#meta/context_engine.cmx";
-
-}
-
-namespace maxwell {
-
-void ContextEngineTestBase::SetUp() {
- context_engine_ =
- ConnectToService<fuchsia::modular::ContextEngine>(kContextEngineUrl);
- context_engine_->GetContextDebug(debug_.NewRequest());
-}
-
-void ContextEngineTestBase::StartContextAgent(const std::string& url) {
- auto agent_bridge =
- std::make_unique<MaxwellServiceProviderBridge>(root_environment());
- agent_bridge->AddService<fuchsia::modular::ContextWriter>(
- [this,
- url](fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request) {
- fuchsia::modular::ComponentScope scope;
- fuchsia::modular::AgentScope agent_scope;
- agent_scope.url = url;
- scope.set_agent_scope(std::move(agent_scope));
- context_engine_->GetWriter(std::move(scope), std::move(request));
- });
- agent_bridge->AddService<fuchsia::modular::ContextReader>(
- [this,
- url](fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) {
- fuchsia::modular::ComponentScope scope;
- fuchsia::modular::AgentScope agent_scope;
- agent_scope.url = url;
- scope.set_agent_scope(std::move(agent_scope));
- context_engine_->GetReader(std::move(scope), std::move(request));
- });
- StartAgent(url, std::move(agent_bridge));
-}
-
-void ContextEngineTestBase::WaitUntilIdle() {
- util::WaitUntilIdle(&debug_, &loop_);
-}
-
-} // namespace maxwell
diff --git a/tests/maxwell_integration/context_engine_test_base.h b/tests/maxwell_integration/context_engine_test_base.h
deleted file mode 100644
index 641ce9c..0000000
--- a/tests/maxwell_integration/context_engine_test_base.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_MAXWELL_INTEGRATION_CONTEXT_ENGINE_TEST_BASE_H_
-#define PERIDOT_TESTS_MAXWELL_INTEGRATION_CONTEXT_ENGINE_TEST_BASE_H_
-
-#include <fuchsia/modular/cpp/fidl.h>
-
-#include "peridot/tests/maxwell_integration/test.h"
-
-namespace maxwell {
-
-// Base fixture to support test cases requiring Context Engine.
-class ContextEngineTestBase : public MaxwellTestBase {
- public:
- void SetUp() override;
-
- protected:
- void StartContextAgent(const std::string& url);
- void WaitUntilIdle();
-
- fuchsia::modular::ContextEngine* context_engine() {
- return context_engine_.get();
- }
-
- private:
- fuchsia::modular::ContextEnginePtr context_engine_;
- fuchsia::modular::ContextDebugPtr debug_;
-};
-
-} // namespace maxwell
-
-#endif // PERIDOT_TESTS_MAXWELL_INTEGRATION_CONTEXT_ENGINE_TEST_BASE_H_
diff --git a/tests/maxwell_integration/meta/context_engine_test.cmx b/tests/maxwell_integration/meta/context_engine_test.cmx
deleted file mode 100644
index dd44b6c..0000000
--- a/tests/maxwell_integration/meta/context_engine_test.cmx
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "program": {
- "binary": "test/context_engine_test"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Environment"
- ]
- }
-}
diff --git a/tests/maxwell_integration/meta/suggestion_engine_test.cmx b/tests/maxwell_integration/meta/suggestion_engine_test.cmx
deleted file mode 100644
index 80566e2..0000000
--- a/tests/maxwell_integration/meta/suggestion_engine_test.cmx
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "program": {
- "binary": "test/suggestion_engine_test"
- },
- "sandbox": {
- "services": [
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Environment"
- ]
- }
-}
diff --git a/tests/maxwell_integration/suggestion_engine_test.cc b/tests/maxwell_integration/suggestion_engine_test.cc
deleted file mode 100644
index 278742c..0000000
--- a/tests/maxwell_integration/suggestion_engine_test.cc
+++ /dev/null
@@ -1,948 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/context/cpp/context_helper.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/optional.h>
-#include <lib/fxl/logging.h>
-#include <lib/svc/cpp/services.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/story_provider_mock.h"
-#include "peridot/lib/testing/wait_until_idle.h"
-#include "peridot/tests/maxwell_integration/context_engine_test_base.h"
-#include "peridot/tests/maxwell_integration/test_suggestion_listener.h"
-#include "rapidjson/document.h"
-#include "rapidjson/pointer.h"
-
-namespace maxwell {
-namespace {
-
-// context agent that publishes an int n
-class NWriter {
- public:
- NWriter(fuchsia::modular::ContextEngine* context_engine) {
- fuchsia::modular::ComponentScope scope;
- scope.set_global_scope(fuchsia::modular::GlobalScope());
- context_engine->GetWriter(std::move(scope), pub_.NewRequest());
- }
-
- void Publish(int n) { pub_->WriteEntityTopic("n", std::to_string(n)); }
-
- private:
- fuchsia::modular::ContextWriterPtr pub_;
-};
-
-fuchsia::modular::Proposal CreateProposal(
- const std::string& id, const std::string& headline,
- std::vector<fuchsia::modular::StoryCommand> commands,
- fuchsia::modular::AnnoyanceType annoyance) {
- fuchsia::modular::Proposal p;
- p.id = id;
- p.on_selected = std::move(commands);
- p.affinity.resize(0);
- fuchsia::modular::SuggestionDisplay d;
-
- d.headline = headline;
- d.color = 0x00aa00aa; // argb purple
- d.annoyance = annoyance;
-
- p.display = std::move(d);
- return p;
-}
-
-class Proposinator {
- public:
- Proposinator(fuchsia::modular::SuggestionEngine* suggestion_engine,
- fidl::StringPtr url = "Proposinator") {
- suggestion_engine->RegisterProposalPublisher("Proposinator",
- out_.NewRequest());
- }
-
- virtual ~Proposinator() = default;
-
- void Propose(const std::string& id,
- std::vector<fuchsia::modular::StoryCommand> commands ={}) {
- Propose(id, id, fuchsia::modular::AnnoyanceType::NONE, std::move(commands));
- }
-
- void Propose(const std::string& id, const std::string& headline,
- fuchsia::modular::AnnoyanceType annoyance =
- fuchsia::modular::AnnoyanceType::NONE,
- std::vector<fuchsia::modular::StoryCommand> commands = {}) {
- Propose(CreateProposal(id, headline, std::move(commands), annoyance));
- }
-
- void Propose(fuchsia::modular::Proposal proposal) {
- out_->Propose(std::move(proposal));
- }
-
- void Remove(const std::string& id) { out_->Remove(id); }
-
- void KillPublisher() { out_.Unbind(); }
-
- protected:
- fuchsia::modular::ProposalPublisherPtr out_;
-};
-
-class AskProposinator : public Proposinator,
- public fuchsia::modular::QueryHandler {
- public:
- AskProposinator(fuchsia::modular::SuggestionEngine* suggestion_engine,
- async::Loop* loop, fidl::StringPtr url = "AskProposinator")
- : Proposinator(suggestion_engine, url), loop_(loop), ask_binding_(this) {
- fidl::InterfaceHandle<fuchsia::modular::QueryHandler> query_handle;
- ask_binding_.Bind(query_handle.NewRequest());
- suggestion_engine->RegisterQueryHandler(url, std::move(query_handle));
- }
-
- void OnQuery(fuchsia::modular::UserInput query,
- OnQueryCallback callback) override {
- query_ = fidl::MakeOptional(query);
- query_callback_ = callback;
- query_proposals_.resize(0);
-
- if (waiting_for_query_) {
- waiting_for_query_ = false;
- async::PostTask(loop_->dispatcher(), [this] { loop_->Quit(); });
- }
- }
-
- void WaitForQuery() {
- waiting_for_query_ = true;
- loop_->Run();
- loop_->ResetQuit();
- }
-
- void Commit() {
- fuchsia::modular::QueryResponse response;
- response.proposals = std::move(query_proposals_);
- query_callback_(std::move(response));
- }
-
- fidl::StringPtr query() const { return query_ ? query_->text : nullptr; }
-
- void ProposeForAsk(const std::string& id) {
- std::vector<fuchsia::modular::StoryCommand> commands;
- ProposeForAsk(id, id, fuchsia::modular::AnnoyanceType::NONE,
- std::move(commands));
- }
-
- void ProposeForAsk(
- const std::string& id, const std::string& headline,
- fuchsia::modular::AnnoyanceType annoyance =
- fuchsia::modular::AnnoyanceType::NONE,
- std::vector<fuchsia::modular::StoryCommand> commands ={}) {
- query_proposals_.push_back(
- CreateProposal(id, headline, std::move(commands), annoyance));
- }
-
- private:
- async::Loop* const loop_;
- fidl::Binding<fuchsia::modular::QueryHandler> ask_binding_;
- fuchsia::modular::UserInputPtr query_;
- std::vector<fuchsia::modular::Proposal> query_proposals_;
- OnQueryCallback query_callback_;
- bool waiting_for_query_ = false;
-};
-
-// maintains the number of proposals specified by the context field "n"
-class NProposals : public Proposinator,
- public fuchsia::modular::ContextListener {
- public:
- NProposals(fuchsia::modular::ContextEngine* context_engine,
- fuchsia::modular::SuggestionEngine* suggestion_engine)
- : Proposinator(suggestion_engine, "NProposals"), listener_binding_(this) {
- fuchsia::modular::ComponentScope scope;
- scope.set_global_scope(fuchsia::modular::GlobalScope());
- context_engine->GetReader(std::move(scope), reader_.NewRequest());
-
- fuchsia::modular::ContextSelector selector;
- selector.type = fuchsia::modular::ContextValueType::ENTITY;
- selector.meta = fuchsia::modular::ContextMetadata::New();
- selector.meta->entity = fuchsia::modular::EntityMetadata::New();
- selector.meta->entity->topic = "n";
- fuchsia::modular::ContextQuery query;
- modular::AddToContextQuery(&query, "n", std::move(selector));
- reader_->Subscribe(std::move(query), listener_binding_.NewBinding());
- }
-
- void OnContextUpdate(fuchsia::modular::ContextUpdate update) override {
- auto maybe_result = modular::TakeContextValue(&update, "n");
- if (!maybe_result) {
- FXL_LOG(INFO) << "Expect an update key for every query key.";
- }
- auto& r = maybe_result.value();
- if (r.empty()) {
- return;
- }
- int n = std::stoi(r.at(0).content);
-
- for (int i = n_; i < n; i++) {
- Propose(std::to_string(i));
- }
- for (int i = n; i < n_; i++) {
- Remove(std::to_string(i));
- }
-
- n_ = n;
- }
-
- private:
- fuchsia::modular::ContextReaderPtr reader_;
- fidl::Binding<fuchsia::modular::ContextListener> listener_binding_;
-
- int n_ = 0;
-};
-
-class SuggestionEngineTest : public ContextEngineTestBase,
- fuchsia::modular::ProposalListener {
- public:
- SuggestionEngineTest() : story_provider_binding_(&story_provider_) {}
-
- void SetUp() override {
- ContextEngineTestBase::SetUp();
-
- component::Services suggestion_services =
- StartServices("fuchsia-pkg://fuchsia.com/suggestion_engine#meta/suggestion_engine.cmx");
- suggestion_engine_ =
- suggestion_services
- .ConnectToService<fuchsia::modular::SuggestionEngine>();
- suggestion_provider_ =
- suggestion_services
- .ConnectToService<fuchsia::modular::SuggestionProvider>();
- suggestion_debug_ =
- suggestion_services
- .ConnectToService<fuchsia::modular::SuggestionDebug>();
- }
-
- protected:
- fuchsia::modular::SuggestionEngine* suggestion_engine() {
- return suggestion_engine_.get();
- }
-
- fuchsia::modular::SuggestionProvider* suggestion_provider() {
- return suggestion_provider_.get();
- }
-
- fuchsia::modular::SuggestionDebug* suggestion_debug() {
- return suggestion_debug_.get();
- }
-
- modular::StoryProviderMock* story_provider() { return &story_provider_; }
-
- void StartSuggestionAgent(const std::string& url) {
- auto agent_bridge =
- std::make_unique<MaxwellServiceProviderBridge>(root_environment());
- agent_bridge->AddService<fuchsia::modular::ContextReader>(
- [this,
- url](fidl::InterfaceRequest<fuchsia::modular::ContextReader> request) {
- fuchsia::modular::ComponentScope scope;
- fuchsia::modular::AgentScope agent_scope;
- agent_scope.url = url;
- scope.set_agent_scope(std::move(agent_scope));
- context_engine()->GetReader(std::move(scope), std::move(request));
- });
- agent_bridge->AddService<fuchsia::modular::ProposalPublisher>(
- [this, url](fidl::InterfaceRequest<fuchsia::modular::ProposalPublisher>
- request) {
- suggestion_engine_->RegisterProposalPublisher(url,
- std::move(request));
- });
- StartAgent(url, std::move(agent_bridge));
- }
-
- void AcceptSuggestion(const std::string& suggestion_id) {
- Interact(suggestion_id, fuchsia::modular::InteractionType::SELECTED);
- }
-
- void DismissSuggestion(const std::string& suggestion_id) {
- Interact(suggestion_id, fuchsia::modular::InteractionType::DISMISSED);
- }
-
- void WaitUntilIdle() {
- ContextEngineTestBase::WaitUntilIdle();
- util::WaitUntilIdle(&suggestion_debug_, &loop_);
- }
-
- void RunUntilIdle() {
- suggestion_debug()->RunUntilIdle([this] { loop_.Quit(); });
- loop_.Run();
- loop_.ResetQuit();
- loop_.RunUntilIdle();
- }
-
- void AddProposalListenerBinding(
- fidl::InterfaceRequest<fuchsia::modular::ProposalListener> request) {
- proposal_listener_bindings_.AddBinding(this, std::move(request));
- }
-
- // The id of the most recently accepted proposal.
- std::string accepted_proposal_id_;
-
- // The amount of proposals that have been accepted, as indicated by calls to
- // |OnProposalAccepted|.
- int accepted_proposal_count_ = 0;
-
- // Whether or not a successful create story action has been observed.
- bool created_story_action_;
-
- // Story ID when a proposal is accepted. This is the ID of a story that was
- // created as result of the execution of a proposal actions, either through
- // AddModule or for a rich suggestion.
- std::string accepted_proposal_story_id_;
-
- private:
- void Interact(const std::string& suggestion_id,
- fuchsia::modular::InteractionType interaction_type) {
- fuchsia::modular::Interaction interaction;
- interaction.type = interaction_type;
- suggestion_provider_->NotifyInteraction(suggestion_id,
- std::move(interaction));
- }
-
- // |fuchsia::modular::ProposalListener|
- void OnProposalAccepted(std::string proposal_id,
- fidl::StringPtr story_id) override {
- accepted_proposal_id_ = proposal_id;
- if (!story_id->empty()) {
- created_story_action_ = true;
- accepted_proposal_story_id_ = story_id;
- }
- accepted_proposal_count_++;
- }
-
- fuchsia::modular::SuggestionEnginePtr suggestion_engine_;
- fuchsia::modular::SuggestionDebugPtr suggestion_debug_;
- fuchsia::modular::SuggestionProviderPtr suggestion_provider_;
-
- modular::StoryProviderMock story_provider_;
- fidl::Binding<fuchsia::modular::StoryProvider> story_provider_binding_;
- fidl::BindingSet<fuchsia::modular::ProposalListener>
- proposal_listener_bindings_;
-};
-
-class AskTest : public virtual SuggestionEngineTest {
- public:
- AskTest()
- : listener_binding_(&listener_),
- debug_listener_binding_(&debug_listener_) {}
-
- void SetUp() override {
- SuggestionEngineTest::SetUp();
-
- suggestion_debug()->WatchAskProposals(debug_listener_binding_.NewBinding());
- }
-
- void CloseAndResetListener() {
- if (listener_binding_.is_bound()) {
- listener_binding_.Unbind();
- listener_.ClearSuggestions();
- }
- }
-
- void Query(const std::string& query, int count = 10) {
- CloseAndResetListener();
- fuchsia::modular::UserInput input;
- input.type = fuchsia::modular::InputType::TEXT;
- input.text = query;
- suggestion_provider()->Query(listener_binding_.NewBinding(),
- std::move(input), count);
- }
-
- int suggestion_count() const { return listener_.suggestion_count(); }
-
- modular::TestSuggestionListener* listener() { return &listener_; }
-
- protected:
- void EnsureDebugMatches() {
- auto& subscriberAsks = listener_.GetSuggestions();
- auto& debugAsks = debug_listener_.GetProposals();
- EXPECT_GE(debugAsks.size(), subscriberAsks.size());
- for (size_t i = 0; i < subscriberAsks.size(); i++) {
- auto& suggestion = subscriberAsks[i];
- auto& proposal = debugAsks[i];
- EXPECT_EQ(suggestion->display.headline, proposal.display.headline);
- EXPECT_EQ(suggestion->display.subheadline, proposal.display.subheadline);
- EXPECT_EQ(suggestion->display.details, proposal.display.details);
- }
- }
-
- private:
- modular::TestSuggestionListener listener_;
- modular::TestDebugAskListener debug_listener_;
- fidl::Binding<fuchsia::modular::QueryListener> listener_binding_;
- fidl::Binding<fuchsia::modular::AskProposalListener> debug_listener_binding_;
-};
-
-class InterruptionTest : public virtual SuggestionEngineTest {
- public:
- InterruptionTest()
- : listener_binding_(&listener_),
- debug_listener_binding_(&debug_listener_) {}
-
- void SetUp() override {
- SuggestionEngineTest::SetUp();
-
- suggestion_provider()->SubscribeToInterruptions(
- listener_binding_.NewBinding());
- suggestion_debug()->WatchInterruptionProposals(
- debug_listener_binding_.NewBinding());
-
- // Make sure we're subscribed before we start the test.
- WaitUntilIdle();
- }
-
- modular::TestDebugInterruptionListener* debugListener() {
- return &debug_listener_;
- }
- modular::TestSuggestionListener* listener() { return &listener_; }
-
- protected:
- int suggestion_count() const { return listener_.suggestion_count(); }
-
- void EnsureDebugMatches() {
- auto& subscriberNexts = listener_.GetSuggestions();
- auto lastInterruption = debug_listener_.get_interrupt_proposal();
- ASSERT_GE(subscriberNexts.size(), 1u);
- auto& suggestion = subscriberNexts[0];
- EXPECT_EQ(suggestion->display.headline, lastInterruption.display.headline);
- EXPECT_EQ(suggestion->display.subheadline,
- lastInterruption.display.subheadline);
- EXPECT_EQ(suggestion->display.details, lastInterruption.display.details);
- }
-
- private:
- modular::TestSuggestionListener listener_;
- modular::TestDebugInterruptionListener debug_listener_;
-
- fidl::Binding<fuchsia::modular::InterruptionListener> listener_binding_;
- fidl::Binding<fuchsia::modular::InterruptionProposalListener>
- debug_listener_binding_;
-};
-
-class NextTest : public virtual SuggestionEngineTest {
- public:
- NextTest()
- : listener_binding_(&listener_),
- debug_listener_binding_(&debug_listener_) {}
-
- void SetUp() override {
- SuggestionEngineTest::SetUp();
-
- suggestion_debug()->WatchNextProposals(
- debug_listener_binding_.NewBinding());
- }
-
- modular::TestDebugNextListener* debugListener() { return &debug_listener_; }
- modular::TestSuggestionListener* listener() { return &listener_; }
-
- protected:
- void StartListening(int count) {
- suggestion_provider()->SubscribeToNext(listener_binding_.NewBinding(),
- count);
- }
-
- void CloseAndResetListener() {
- listener_binding_.Unbind();
- listener_.ClearSuggestions();
- }
-
- void SetResultCount(int count) {
- CloseAndResetListener();
- suggestion_provider()->SubscribeToNext(listener_binding_.NewBinding(),
- count);
- }
-
- int suggestion_count() const { return listener_.suggestion_count(); }
-
- const fuchsia::modular::Suggestion* GetOnlySuggestion() const {
- return listener_.GetOnlySuggestion();
- }
-
- void EnsureDebugMatches() {
- auto& subscriberNexts = listener_.GetSuggestions();
- auto& debugNexts = debug_listener_.GetProposals();
- EXPECT_GE(debugNexts.size(), subscriberNexts.size());
- for (size_t i = 0; i < subscriberNexts.size(); i++) {
- auto& suggestion = subscriberNexts[i];
- auto& proposal = debugNexts[i];
- EXPECT_EQ(suggestion->display.headline, proposal.display.headline);
- EXPECT_EQ(suggestion->display.subheadline, proposal.display.subheadline);
- EXPECT_EQ(suggestion->display.details, proposal.display.details);
- }
- }
-
- private:
- modular::TestSuggestionListener listener_;
- modular::TestDebugNextListener debug_listener_;
-
- fidl::Binding<fuchsia::modular::NextListener> listener_binding_;
- fidl::Binding<fuchsia::modular::NextProposalListener> debug_listener_binding_;
-};
-
-class ResultCountTest : public NextTest {
- public:
- void SetUp() override {
- NextTest::SetUp();
-
- pub_.reset(new NWriter(context_engine()));
- sub_.reset(new NProposals(context_engine(), suggestion_engine()));
- }
-
- protected:
- // Publishes signals for n new suggestions to context.
- void PublishNewSignal(int n = 1) { pub_->Publish(n_ += n); }
-
- private:
- std::unique_ptr<NWriter> pub_;
- std::unique_ptr<NProposals> sub_;
- int n_ = 0;
-};
-
-} // namespace
-
-// Macro rather than method to capture the expectation in the assertion message.
-#define CHECK_RESULT_COUNT(expected) ASYNC_EQ(expected, suggestion_count())
-
-TEST_F(ResultCountTest, InitiallyEmpty) {
- StartListening(10);
- WaitUntilIdle();
- EXPECT_EQ(0, suggestion_count());
-}
-
-TEST_F(ResultCountTest, OneByOne) {
- StartListening(10);
- PublishNewSignal();
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
-
- PublishNewSignal();
- WaitUntilIdle();
- EXPECT_EQ(2, suggestion_count());
-}
-
-TEST_F(ResultCountTest, AddOverLimit) {
- StartListening(0);
- PublishNewSignal(3);
- WaitUntilIdle();
- EXPECT_EQ(0, suggestion_count());
-
- SetResultCount(1);
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
-
- SetResultCount(3);
- WaitUntilIdle();
- EXPECT_EQ(3, suggestion_count());
-
- SetResultCount(5);
- WaitUntilIdle();
- EXPECT_EQ(3, suggestion_count());
-
- PublishNewSignal(4);
- WaitUntilIdle();
- EXPECT_EQ(5, suggestion_count());
-}
-
-TEST_F(ResultCountTest, Clear) {
- StartListening(10);
- PublishNewSignal(3);
- WaitUntilIdle();
- EXPECT_EQ(3, suggestion_count());
-
- SetResultCount(0);
- WaitUntilIdle();
- EXPECT_EQ(0, suggestion_count());
-
- SetResultCount(10);
- WaitUntilIdle();
- EXPECT_EQ(3, suggestion_count());
-}
-
-TEST_F(ResultCountTest, MultiRemove) {
- StartListening(10);
- PublishNewSignal(3);
- WaitUntilIdle();
- EXPECT_EQ(3, suggestion_count());
-
- SetResultCount(1);
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
-
- SetResultCount(10);
- WaitUntilIdle();
- EXPECT_EQ(3, suggestion_count());
-}
-
-// Tests the removal of earlier suggestions, ensuring that suggestion engine can
-// handle the case where an agent requests the removal of suggestions in a non-
-// LIFO ordering. This exercises some internal shuffling, especially when
-// rankings are likewise non-LIFO (where last = lowest-priority).
-//
-// TODO(rosswang): Currently this test also tests removing higher-ranked
-// suggestions. After we have real ranking, add a test for that.
-TEST_F(NextTest, Fifo) {
- Proposinator fifo(suggestion_engine());
-
- StartListening(10);
- fifo.Propose("1");
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
- auto uuid_1 = GetOnlySuggestion()->uuid;
-
- fifo.Propose("2");
- WaitUntilIdle();
- EXPECT_EQ(2, suggestion_count());
- fifo.Remove("1");
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
- auto suggestion = GetOnlySuggestion();
- EXPECT_NE(uuid_1, suggestion->uuid);
- EXPECT_EQ("2", suggestion->display.headline);
-}
-
-// Tests the removal of earlier suggestions while capped.
-// TODO(rosswang): see above TODO
-TEST_F(NextTest, CappedFifo) {
- Proposinator fifo(suggestion_engine());
-
- StartListening(1);
- fifo.Propose("1");
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
- auto uuid1 = GetOnlySuggestion()->uuid;
-
- fifo.Propose("2");
- WaitUntilIdle();
- EXPECT_EQ(uuid1, GetOnlySuggestion()->uuid)
- << "fuchsia::modular::Proposal 2 ranked over proposal 2; test invalid; "
- "update to test "
- "FIFO-ranked proposals.";
-
- fifo.Remove("1");
- WaitUntilIdle();
- ASSERT_EQ(1, suggestion_count());
- EXPECT_NE(uuid1, GetOnlySuggestion()->uuid);
-
- EXPECT_EQ("2", GetOnlySuggestion()->display.headline);
-}
-
-TEST_F(NextTest, RemoveBeforeSubscribe) {
- Proposinator zombinator(suggestion_engine());
-
- zombinator.Propose("brains");
- zombinator.Remove("brains");
- WaitUntilIdle();
-
- StartListening(10);
- WaitUntilIdle();
- EXPECT_EQ(0, suggestion_count());
-}
-
-TEST_F(NextTest, SubscribeBeyondController) {
- Proposinator p(suggestion_engine());
-
- StartListening(10);
- WaitUntilIdle();
- p.Propose("1");
- p.Propose("2");
- WaitUntilIdle();
- EXPECT_EQ(2, suggestion_count());
-}
-
-TEST_F(AskTest, DefaultAsk) {
- AskProposinator p(suggestion_engine(), &loop_);
-
- Query("test query");
- p.WaitForQuery();
- p.ProposeForAsk("1");
- p.Commit();
-
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
-
- Query("test query 2");
- p.WaitForQuery();
- p.ProposeForAsk("2");
- p.Commit();
-
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
- EnsureDebugMatches();
-}
-
-/* These tests assume that a string match between the proposal headline
- and the query text factors into suggestion ranking. That ranking
- feature is currently turned off and thus these tests fail, but they
- will pass with it turned on.
-
-#define CHECK_TOP_HEADLINE(h) \
- ASYNC_CHECK(listener()->GetTopSuggestion()->display->headline == h)
-
-TEST_F(AskTest, AskDifferentQueries) {
- AskProposinator p(suggestion_engine(), &loop_);
-
- Query("The Hottest Band on the Internet");
- p.WaitForQuery();
- p.ProposeForAsk("Mozart's Ghost");
- p.ProposeForAsk("The Hottest Band on the Internet");
- p.Commit();
- WaitUntilIdle();
-
- CHECK_TOP_HEADLINE("The Hottest Band on the Internet");
-
- Query("Mozart's Ghost");
- p.WaitForQuery();
- p.ProposeForAsk("Mozart's Ghost");
- p.ProposeForAsk("The Hottest Band on the Internet");
- p.Commit();
- WaitUntilIdle();
-
- CHECK_TOP_HEADLINE("Mozart's Ghost");
- EnsureDebugMatches();
-}
-
-TEST_F(AskTest, ChangeHeadlineRank) {
- AskProposinator p(suggestion_engine(), &loop_);
-
- Query("test query");
- p.WaitForQuery();
- p.ProposeForAsk("E-mail", "E-mail");
- p.ProposeForAsk("E-vite", "E-vite");
- p.ProposeForAsk("E-card", "E-card");
- p.ProposeForAsk("Music", "Music");
- p.Commit();
-
- WaitUntilIdle();
- EXPECT_EQ(4, suggestion_count());
-
- Query("Ca");
- p.WaitForQuery();
- p.ProposeForAsk("E-mail", "E-mail");
- p.ProposeForAsk("E-vite", "E-vite");
- p.ProposeForAsk("E-card", "E-card");
- p.ProposeForAsk("Music", "Music");
- p.Commit();
- WaitUntilIdle();
-
- // E-card has a 'ca' in the 3rd position, so should be ranked highest.
- CHECK_TOP_HEADLINE("E-card");
-
- Query("Ca");
- p.WaitForQuery();
- p.ProposeForAsk("E-mail", "E-mail");
- p.ProposeForAsk("E-mail", "Cam");
- p.ProposeForAsk("E-vite", "E-vite");
- p.ProposeForAsk("E-card", "E-card");
- p.ProposeForAsk("Music", "Music");
- p.Commit();
- WaitUntilIdle();
-
- CHECK_TOP_HEADLINE("Cam");
- EnsureDebugMatches();
- EXPECT_EQ(4, suggestion_count());
-}
-*/
-
-/* These tests make an assumption that timestamp factors into ranking, which
- it no longer does. It could be re-enabled if that factor is included again.
-
-#define HEADLINE_EQ(expected, index) \
- EXPECT_EQ(expected, (*listener())[index]->display->headline)
-
-TEST_F(AskTest, AskRanking) {
- AskProposinator p(suggestion_engine(), &loop_);
-
- Query("");
- p.WaitForQuery();
- p.ProposeForAsk("View E-mail");
- p.ProposeForAsk("Compose E-mail");
- p.ProposeForAsk("Reply to E-mail");
- p.ProposeForAsk("Send E-vites");
- p.ProposeForAsk("E-mail Guests");
- p.Commit();
-
- WaitUntilIdle();
- EXPECT_EQ(5, suggestion_count());
- // Results should be ranked by timestamp at this point.
- HEADLINE_EQ("View E-mail", 0);
- HEADLINE_EQ("Compose E-mail", 1);
- HEADLINE_EQ("Reply to E-mail", 2);
- HEADLINE_EQ("Send E-vites", 3);
- HEADLINE_EQ("E-mail Guests", 4);
- EnsureDebugMatches();
-
- Query("e-mail");
- p.WaitForQuery();
- p.ProposeForAsk("View E-mail");
- p.ProposeForAsk("Compose E-mail");
- p.ProposeForAsk("Reply to E-mail");
- p.ProposeForAsk("Send E-vites");
- p.ProposeForAsk("E-mail Guests");
- p.Commit();
-
- WaitUntilIdle();
- EXPECT_EQ(5, suggestion_count());
- HEADLINE_EQ("View E-mail", 0);
- HEADLINE_EQ("E-mail Guests", 1);
- HEADLINE_EQ("Compose E-mail", 2);
- HEADLINE_EQ("Reply to E-mail", 3);
- EnsureDebugMatches();
-
- Query("e-mail", 2);
- p.WaitForQuery();
- p.ProposeForAsk("View E-mail");
- p.ProposeForAsk("Compose E-mail");
- p.ProposeForAsk("Reply to E-mail");
- p.ProposeForAsk("Send E-vites");
- p.ProposeForAsk("E-mail Guests");
- p.Commit();
-
- WaitUntilIdle();
- EXPECT_EQ(2, suggestion_count());
- HEADLINE_EQ("View E-mail", 0);
- HEADLINE_EQ("E-mail Guests", 1);
-
- Query("Compose", 1);
- p.WaitForQuery();
- p.ProposeForAsk("View E-mail");
- p.ProposeForAsk("Compose E-mail");
- p.ProposeForAsk("Reply to E-mail");
- p.ProposeForAsk("Send E-vites");
- p.ProposeForAsk("E-mail Guests");
- p.Commit();
-
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
- HEADLINE_EQ("Compose E-mail", 0);
- EnsureDebugMatches();
-}
-*/
-
-// This test ensures that Suggestion Engine doesn't keep querying dead handlers.
-TEST_F(AskTest, DeadAgent) {
- AskProposinator p(suggestion_engine(), &loop_);
-
- { AskProposinator m(suggestion_engine(), &loop_); }
-
- Query("test query");
- p.WaitForQuery();
- p.ProposeForAsk("1");
- p.Commit();
-
- // RunUntilIdle rather than WaitUntilIdle to not wait for the query handler
- // timeout. If we'd need to wait for the timeout, the test should fail.
- RunUntilIdle();
-
- EXPECT_EQ(1, suggestion_count());
- EXPECT_TRUE(listener()->query_complete());
-}
-
-// This test ensures that if a query handler dies while handling a query,
-// Suggestion Engine stops waiting for it gracefully.
-TEST_F(AskTest, AgentKilledInAction) {
- AskProposinator p(suggestion_engine(), &loop_);
-
- {
- AskProposinator coulson(suggestion_engine(), &loop_);
-
- Query("test query");
- p.WaitForQuery();
- p.ProposeForAsk("1");
- p.Commit();
-
- RunUntilIdle();
-
- EXPECT_FALSE(listener()->query_complete());
- }
-
- RunUntilIdle();
-
- EXPECT_EQ(1, suggestion_count());
- EXPECT_TRUE(listener()->query_complete());
-}
-
-class SuggestionFilteringTest : public NextTest {};
-
-TEST_F(SuggestionFilteringTest, Baseline) {
- // Show that without any existing Stories, we see Proposals to launch
- // any story.
- Proposinator p(suggestion_engine());
- StartListening(10);
-
- fuchsia::modular::Intent intent;
- intent.handler = "foo://bar";
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("foo");
- add_mod.intent = std::move(intent);
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(std::move(command));
- p.Propose("1", std::move(commands));
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
-}
-
-TEST_F(SuggestionFilteringTest, Baseline_FilterDoesntMatch) {
- // Show that with an existing Story for a URL, we see Proposals to launch
- // other URLs.
- Proposinator p(suggestion_engine());
- StartListening(10);
-
- // First notify watchers of the fuchsia::modular::StoryProvider that a story
- // already exists.
- fuchsia::modular::StoryInfo story_info;
- story_info.url = "foo://bazzle_dazzle";
- story_info.id = "";
- story_provider()->NotifyStoryChanged(
- std::move(story_info), fuchsia::modular::StoryState::STOPPED,
- fuchsia::modular::StoryVisibilityState::DEFAULT);
-
- fuchsia::modular::Intent intent;
- intent.handler = "foo://bar";
- fuchsia::modular::AddMod add_mod;
- add_mod.intent = std::move(intent);
- add_mod.mod_name.push_back("foo");
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(std::move(command));
- p.Propose("1", std::move(commands));
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
-}
-
-TEST_F(InterruptionTest, SingleInterruption) {
- Proposinator p(suggestion_engine());
-
- p.Propose("1", "2", fuchsia::modular::AnnoyanceType::INTERRUPT);
-
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
- EnsureDebugMatches();
-}
-
-TEST_F(InterruptionTest, RemovedInterruption) {
- Proposinator p(suggestion_engine());
-
- p.Propose("1", "2", fuchsia::modular::AnnoyanceType::INTERRUPT);
-
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
- EnsureDebugMatches();
-
- // Removing shouldn't do anything to an interruption
- p.Remove("1");
-
- WaitUntilIdle();
- EXPECT_EQ(1, suggestion_count());
-}
-
-} // namespace maxwell
diff --git a/tests/maxwell_integration/test.cc b/tests/maxwell_integration/test.cc
deleted file mode 100644
index f2f2874..0000000
--- a/tests/maxwell_integration/test.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/tests/maxwell_integration/test.h"
-
-#include <lib/fxl/logging.h>
-
-namespace maxwell {
-namespace {
-
-constexpr char kEnvironmentLabel[] = "maxwell-test-env";
-
-}
-
-MaxwellTestBase::MaxwellTestBase() : loop_(&kAsyncLoopConfigAttachToThread) {
- startup_context_ = component::StartupContext::CreateFromStartupInfo();
-
- child_app_services_.AddService<fuchsia::modular::ComponentContext>(
- [this](
- fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request) {
- child_component_context_.Connect(std::move(request));
- });
-}
-
-void MaxwellTestBase::StartAgent(
- const std::string& url,
- std::unique_ptr<MaxwellServiceProviderBridge> bridge) {
- bridge_ = std::move(bridge);
-
- fuchsia::sys::ServiceListPtr service_list(new fuchsia::sys::ServiceList);
- service_list->names = bridge_->service_names();
- service_list->host_directory = bridge_->OpenAsDirectory();
- fuchsia::sys::EnvironmentPtr agent_env;
- startup_context_->environment()->CreateNestedEnvironment(
- agent_env.NewRequest(), environment_controller_.NewRequest(),
- kEnvironmentLabel, std::move(service_list), {});
-
- fuchsia::sys::LauncherPtr launcher;
- agent_env->GetLauncher(launcher.NewRequest());
-
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = url;
- component::Services services;
- launch_info.directory_request = services.NewRequest();
- FXL_LOG(INFO) << "Starting modular agent " << url;
- launcher->CreateComponent(std::move(launch_info), nullptr);
-}
-
-component::Services MaxwellTestBase::StartServices(const std::string& url) {
- component::Services services;
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = url;
- launch_info.directory_request = services.NewRequest();
-
- auto service_list = fuchsia::sys::ServiceList::New();
- service_list->names.push_back(fuchsia::modular::ComponentContext::Name_);
- child_app_services_.AddBinding(service_list->provider.NewRequest());
- launch_info.additional_services = std::move(service_list);
-
- fuchsia::sys::ComponentControllerPtr component_ptr;
- startup_context_->launcher()->CreateComponent(std::move(launch_info),
- component_ptr.NewRequest());
- component_ptrs_.push_back(std::move(component_ptr));
- return services;
-}
-
-fuchsia::sys::Environment* MaxwellTestBase::root_environment() {
- return startup_context_->environment().get();
-}
-
-} // namespace maxwell
diff --git a/tests/maxwell_integration/test.h b/tests/maxwell_integration/test.h
deleted file mode 100644
index d30c743..0000000
--- a/tests/maxwell_integration/test.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_MAXWELL_INTEGRATION_TEST_H_
-#define PERIDOT_TESTS_MAXWELL_INTEGRATION_TEST_H_
-
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/service_provider_impl.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/svc/cpp/services.h>
-
-#include "gtest/gtest.h"
-#include "peridot/lib/environment_host/maxwell_service_provider_bridge.h"
-#include "peridot/lib/testing/component_context_fake.h"
-#include "peridot/lib/testing/entity_resolver_fake.h"
-
-namespace maxwell {
-
-class MaxwellTestBase : public testing::Test {
- protected:
- MaxwellTestBase();
- ~MaxwellTestBase() override = default;
-
- void StartAgent(const std::string& url,
- std::unique_ptr<MaxwellServiceProviderBridge> bridge);
-
- component::Services StartServices(const std::string& url);
-
- template <typename Interface>
- fidl::InterfacePtr<Interface> ConnectToService(const std::string& url) {
- auto services = StartServices(url);
- return services.ConnectToService<Interface>();
- }
-
- fuchsia::sys::Environment* root_environment();
-
- modular::EntityResolverFake& entity_resolver() {
- return child_component_context_.entity_resolver_fake();
- }
-
- async::Loop loop_;
-
- private:
- std::unique_ptr<component::StartupContext> startup_context_;
- fuchsia::sys::EnvironmentControllerPtr environment_controller_;
- std::vector<fuchsia::sys::ComponentControllerPtr> component_ptrs_;
-
- std::unique_ptr<maxwell::MaxwellServiceProviderBridge> bridge_;
-
- component::ServiceProviderImpl child_app_services_;
- modular::ComponentContextFake child_component_context_;
-};
-
-} // namespace maxwell
-
-#endif // PERIDOT_TESTS_MAXWELL_INTEGRATION_TEST_H_
diff --git a/tests/maxwell_integration/test_suggestion_listener.cc b/tests/maxwell_integration/test_suggestion_listener.cc
deleted file mode 100644
index 534ba5c..0000000
--- a/tests/maxwell_integration/test_suggestion_listener.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/tests/maxwell_integration/test_suggestion_listener.h"
-
-#include <lib/fostr/fidl/fuchsia/modular/formatting.h>
-
-bool suggestion_less(const fuchsia::modular::Suggestion* a,
- const fuchsia::modular::Suggestion* b) {
- return a->confidence > b->confidence;
-}
-
-namespace modular {
-
-template <typename T>
-std::ostream& operator<<(std::ostream& os, const std::vector<T>& value) {
- os << "[ ";
- for (const T& element : value) {
- os << element << " ";
- }
- return os << "]";
-}
-
-void TestSuggestionListener::OnInterrupt(
- fuchsia::modular::Suggestion suggestion) {
- FXL_LOG(INFO) << "OnInterrupt(" << suggestion.uuid << ")";
-
- ClearSuggestions();
-
- auto insert_head = ordered_suggestions_.begin();
- insert_head = std::upper_bound(insert_head, ordered_suggestions_.end(),
- &suggestion, suggestion_less);
- suggestions_by_id_[suggestion.uuid] = fuchsia::modular::Suggestion();
- fidl::Clone(suggestion, &suggestions_by_id_[suggestion.uuid]);
- insert_head = ordered_suggestions_.insert(
- insert_head, &suggestions_by_id_[suggestion.uuid]) +
- 1;
-
- EXPECT_EQ((signed)ordered_suggestions_.size(),
- (signed)suggestions_by_id_.size());
-}
-
-void TestSuggestionListener::OnNextResults(
- std::vector<fuchsia::modular::Suggestion> suggestions) {
- FXL_LOG(INFO) << "OnNextResults(" << suggestions << ")";
-
- OnAnyResults(suggestions);
-}
-
-void TestSuggestionListener::OnQueryResults(
- std::vector<fuchsia::modular::Suggestion> suggestions) {
- FXL_LOG(INFO) << "OnQueryResults(" << suggestions << ")";
-
- OnAnyResults(suggestions);
-}
-
-void TestSuggestionListener::OnAnyResults(
- std::vector<fuchsia::modular::Suggestion>& suggestions) {
- ClearSuggestions();
-
- auto insert_head = ordered_suggestions_.begin();
- for (auto& suggestion : suggestions) {
- insert_head = std::upper_bound(insert_head, ordered_suggestions_.end(),
- &suggestion, suggestion_less);
- suggestions_by_id_[suggestion.uuid] = fuchsia::modular::Suggestion();
- fidl::Clone(suggestion, &suggestions_by_id_[suggestion.uuid]);
- insert_head = ordered_suggestions_.insert(
- insert_head, &suggestions_by_id_[suggestion.uuid]) +
- 1;
- }
-
- EXPECT_EQ((signed)ordered_suggestions_.size(),
- (signed)suggestions_by_id_.size());
-}
-
-void TestSuggestionListener::ClearSuggestions() {
- // For use when the listener_binding_ is reset
- ordered_suggestions_.clear();
- suggestions_by_id_.clear();
- query_complete_ = false;
-}
-
-void TestSuggestionListener::OnProcessingChange(bool processing) {
- FXL_LOG(INFO) << "OnProcessingChange to " << processing;
-}
-
-void TestSuggestionListener::OnQueryComplete() {
- FXL_LOG(INFO) << "OnQueryComplete";
- query_complete_ = true;
-}
-
-} // namespace modular
diff --git a/tests/maxwell_integration/test_suggestion_listener.h b/tests/maxwell_integration/test_suggestion_listener.h
deleted file mode 100644
index 326b781..0000000
--- a/tests/maxwell_integration/test_suggestion_listener.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_MAXWELL_INTEGRATION_TEST_SUGGESTION_LISTENER_H_
-#define PERIDOT_TESTS_MAXWELL_INTEGRATION_TEST_SUGGESTION_LISTENER_H_
-
-#include <map>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/fxl/logging.h>
-
-#include "gtest/gtest.h"
-
-namespace modular {
-
-class TestSuggestionListener : public fuchsia::modular::NextListener,
- public fuchsia::modular::QueryListener,
- public fuchsia::modular::InterruptionListener {
- public:
- // |fuchsia::modular::InterruptionListener|
- void OnInterrupt(fuchsia::modular::Suggestion suggestion) override;
-
- // |fuchsia::modular::NextListener|
- void OnNextResults(
- std::vector<fuchsia::modular::Suggestion> suggestions) override;
-
- // |fuchsia::modular::NextListener|
- void OnProcessingChange(bool processing) override;
-
- // |fuchsia::modular::QueryListener|
- void OnQueryResults(
- std::vector<fuchsia::modular::Suggestion> suggestions) override;
-
- // |fuchsia::modular::QueryListener|
- void OnQueryComplete() override;
-
- bool query_complete() const { return query_complete_; }
- int suggestion_count() const { return (signed)ordered_suggestions_.size(); }
-
- void ClearSuggestions();
-
- // Exposes a pointer to the only suggestion in this listener. Retains
- // ownership of the pointer.
- const fuchsia::modular::Suggestion* GetOnlySuggestion() const {
- EXPECT_EQ(1, suggestion_count());
- return GetTopSuggestion();
- }
-
- // Exposes a pointer to the top suggestion in this listener. Retains
- // ownership of the pointer.
- const fuchsia::modular::Suggestion* GetTopSuggestion() const {
- EXPECT_GE(suggestion_count(), 1);
- return ordered_suggestions_.front();
- }
-
- const fuchsia::modular::Suggestion* operator[](int index) const {
- return ordered_suggestions_[index];
- }
-
- const fuchsia::modular::Suggestion* operator[](const std::string& id) const {
- auto it = suggestions_by_id_.find(id);
- return it == suggestions_by_id_.end() ? NULL : &it->second;
- }
-
- const std::vector<fuchsia::modular::Suggestion*>& GetSuggestions() {
- return ordered_suggestions_;
- }
-
- private:
- void OnAnyResults(std::vector<fuchsia::modular::Suggestion>& suggestions);
-
- std::map<std::string, fuchsia::modular::Suggestion> suggestions_by_id_;
- std::vector<fuchsia::modular::Suggestion*> ordered_suggestions_;
- bool query_complete_ = false;
-};
-
-class TestProposalListener {
- public:
- const std::vector<fuchsia::modular::ProposalSummary>& GetProposals() {
- return proposals_;
- }
- int proposal_count() const { return proposals_.size(); }
-
- protected:
- void UpdateProposals(
- std::vector<fuchsia::modular::ProposalSummary> proposals) {
- proposals_.clear();
- for (size_t i = 0; i < proposals.size(); ++i) {
- proposals_.push_back(std::move(proposals.at(i)));
- }
- }
- std::vector<fuchsia::modular::ProposalSummary> proposals_;
-};
-
-class TestDebugNextListener : public fuchsia::modular::NextProposalListener,
- public TestProposalListener {
- public:
- void OnNextUpdate(
- std::vector<fuchsia::modular::ProposalSummary> proposals) override {
- FXL_LOG(INFO) << "In OnNextUpdate debug";
- UpdateProposals(std::move(proposals));
- }
-};
-
-class TestDebugAskListener : public fuchsia::modular::AskProposalListener,
- public TestProposalListener {
- public:
- void OnAskStart(
- std::string query,
- std::vector<fuchsia::modular::ProposalSummary> proposals) override {
- UpdateProposals(std::move(proposals));
- query_ = query;
- }
- void OnProposalSelected(
- fuchsia::modular::ProposalSummaryPtr selectedProposal) override {
- selected_proposal_ = selectedProposal.get();
- }
- const std::string get_query() { return query_; }
- fuchsia::modular::ProposalSummary* get_selected_proposal() {
- return selected_proposal_;
- }
-
- private:
- std::string query_;
- fuchsia::modular::ProposalSummary* selected_proposal_;
-};
-
-class TestDebugInterruptionListener
- : public fuchsia::modular::InterruptionProposalListener {
- public:
- void OnInterrupt(
- fuchsia::modular::ProposalSummary interruptionProposal) override {
- interrupt_proposal_ = std::move(interruptionProposal);
- }
- fuchsia::modular::ProposalSummary get_interrupt_proposal() {
- fuchsia::modular::ProposalSummary result;
- fidl::Clone(interrupt_proposal_, &result);
- return result;
- }
-
- private:
- fuchsia::modular::ProposalSummary interrupt_proposal_;
-};
-
-} // namespace modular
-
-#endif // PERIDOT_TESTS_MAXWELL_INTEGRATION_TEST_SUGGESTION_LISTENER_H_
diff --git a/tests/modular_tests.json b/tests/modular_tests.json
deleted file mode 100644
index af69f88..0000000
--- a/tests/modular_tests.json
+++ /dev/null
@@ -1,172 +0,0 @@
-{
- "tests": [
- {
- "name": "clipboard",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/dev_session_shell#meta/dev_session_shell.cmx",
- "--session_shell_args=--root_module=fuchsia-pkg://fuchsia.com/clipboard_test_module#meta/clipboard_test_module.cmx",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "component_context",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger",
- "--session_shell=fuchsia-pkg://fuchsia.com/dev_session_shell#meta/dev_session_shell.cmx",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--session_shell_args=--root_module=fuchsia-pkg://fuchsia.com/component_context_test_module#meta/component_context_test_module.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "embed_shell",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/embed_shell_test_session_shell#meta/embed_shell_test_session_shell.cmx",
- "--story_shell=fuchsia-pkg://fuchsia.com/embed_shell_test_story_shell#meta/embed_shell_test_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "last_focus_time",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/last_focus_time_test_session_shell#meta/last_focus_time_test_session_shell.cmx",
- "--session_shell_args=--use_memfs_for_ledger",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "link_context_entities",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/link_context_entities_test_session_shell#meta/link_context_entities_test_session_shell.cmx",
- "--session_shell_args=--use_memfs_for_ledger",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "parent_child",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/dev_session_shell#meta/dev_session_shell.cmx",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--session_shell_args=--root_module=fuchsia-pkg://fuchsia.com/parent_child_test_parent_module#meta/parent_child_test_parent_module.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "queue_persistence",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/dev_session_shell#meta/dev_session_shell.cmx",
- "--session_shell_args=--root_module=fuchsia-pkg://fuchsia.com/queue_persistence_test_module#meta/queue_persistence_test_module.cmx",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "story_shell",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/story_shell_test_session_shell#meta/story_shell_test_session_shell.cmx",
- "--session_shell_args=--use_memfs_for_ledger",
- "--story_shell=fuchsia-pkg://fuchsia.com/story_shell_test_story_shell#meta/story_shell_test_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "suggestion",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/suggestion_test_session_shell#meta/suggestion_test_session_shell.cmx",
- "--session_shell_args=--use_memfs_for_ledger",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "trigger",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/trigger_test_session_shell#meta/trigger_test_session_shell.cmx",
- "--session_shell_args=--use_memfs_for_ledger",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "module_context",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/module_context_test_session_shell#meta/module_context_test_session_shell.cmx",
- "--session_shell_args=--use_memfs_for_ledger",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "session_shell",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/session_shell_test_session_shell#meta/session_shell_test_session_shell.cmx",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- },
- {
- "name": "intents",
- "exec": [
- "fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx",
- "--test",
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/dev_token_manager.cmx",
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
- "--session_shell=fuchsia-pkg://fuchsia.com/dev_session_shell#meta/dev_session_shell.cmx",
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/dev_story_shell.cmx",
- "--session_shell_args=--root_module=fuchsia-pkg://fuchsia.com/intent_test_parent_module#meta/intent_test_parent_module.cmx",
- "--sessionmgr_args=--use_memfs_for_ledger"
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/tests/module_context/BUILD.gn b/tests/module_context/BUILD.gn
deleted file mode 100644
index 3cb69fa..0000000
--- a/tests/module_context/BUILD.gn
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-executable_package("module_context_test_session_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/module_context_test_session_shell.cmx"
- dest = "module_context_test_session_shell.cmx"
- },
- ]
-
- sources = [
- "module_context_test_session_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:single_service_app",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- ]
-}
-
-executable_package("module_context_test_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/module_context_test_module.cmx"
- dest = "module_context_test_module.cmx"
- },
- ]
-
- sources = [
- "module_context_test_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//peridot/tests/trigger:trigger_test_service",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("module_context_test_entity_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/module_context_test_entity_module.cmx"
- dest = "module_context_test_entity_module.cmx"
- },
- ]
-
- sources = [
- "module_context_test_entity_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/lib/entity:entity_watcher",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/tests/common:defs",
- "//peridot/tests/trigger:trigger_test_service",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
diff --git a/tests/module_context/README.md b/tests/module_context/README.md
deleted file mode 100644
index 2eb14bb..0000000
--- a/tests/module_context/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# ModuleContext integration test
-
-Tests that calls to ModuleContext.RemoveSelfFromStory() are handled correctly by the framework.
-
-The session shell starts a story and adds two modules to it. It then signals the
-first module to call ModuleContext.RemoveSelfFromStory and verifies that the
-module is stopped. The session shell then signals the second module to
-ModuleContext.RemoveSelfFromStory, and verifies that the story is stopped as
-well.
\ No newline at end of file
diff --git a/tests/module_context/defs.h b/tests/module_context/defs.h
deleted file mode 100644
index 91f2334..0000000
--- a/tests/module_context/defs.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_MODULE_CONTEXT_DEFS_H_
-#define PERIDOT_TESTS_MODULE_CONTEXT_DEFS_H_
-
-namespace {
-
-// The name of the link that the modules receive their startup parameters on.
-constexpr char kLinkName[] = "link";
-
-// The key the modules use to Get their name.
-constexpr char kLinkKey[] = "name";
-
-// The URL for the module under test.
-constexpr char kModuleUrl[] =
- "fuchsia-pkg://fuchsia.com/module_context_test_module#meta/module_context_test_module.cmx";
-
-// The intent action |kModuleUrl| accepts.
-constexpr char kIntentAction[] = "action";
-
-// The URL for the entity test module.
-constexpr char kEntityModuleUrl[] =
- "fuchsia-pkg://fuchsia.com/module_context_test_entity_module#meta/module_context_test_entity_module.cmx";
-
-// The intent action |kEntityModuleUrl| accepts.
-constexpr char kEntityIntentAction[] = "test";
-
-// The names of the first and second modules to be stopped.
-constexpr char kFirstModuleName[] = "first";
-constexpr char kSecondModuleName[] = "second";
-
-// The signal the modules wait for before calling done.
-constexpr char kFirstModuleCallDone[] = "first_done";
-constexpr char kSecondModuleCallDone[] = "second_done";
-
-// The signal the modules wait for before starting/stopping ongoing activity.
-constexpr char kFirstModuleCallStartActivity[] = "first_activity_start";
-constexpr char kSecondModuleCallStartActivity[] = "second_activity_start";
-constexpr char kFirstModuleCallStopActivity[] = "first_activity_stop";
-constexpr char kSecondModuleCallStopActivity[] = "second_activity_stop";
-
-// The signal the modules send when they have been terminated.
-constexpr char kFirstModuleTerminated[] = "first terminated";
-constexpr char kSecondModuleTerminated[] = "second terminated";
-
-// The signals the entity module sends once it's done verifying the entity
-// related methods on module context. Once all these have been signaled the
-// module is done.
-constexpr char kEntityModuleDoneFirstTask[] = "entity_module_done_first";
-constexpr char kEntityModuleDoneSecondTask[] = "entity_module_done_second";
-
-} // namespace
-
-#endif // PERIDOT_TESTS_MODULE_CONTEXT_DEFS_H_
diff --git a/tests/module_context/meta/module_context_test_entity_module.cmx b/tests/module_context/meta/module_context_test_entity_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/module_context/meta/module_context_test_entity_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/module_context/meta/module_context_test_module.cmx b/tests/module_context/meta/module_context_test_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/module_context/meta/module_context_test_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/module_context/meta/module_context_test_session_shell.cmx b/tests/module_context/meta/module_context_test_session_shell.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/module_context/meta/module_context_test_session_shell.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/module_context/module_context_test_entity_module.cc b/tests/module_context/module_context_test_entity_module.cc
deleted file mode 100644
index 484c1db..0000000
--- a/tests/module_context/module_context_test_entity_module.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/functional/make_copyable.h>
-#include <test/peridot/tests/trigger/cpp/fidl.h>
-
-#include "peridot/lib/entity/entity_watcher_impl.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/module_context/defs.h"
-
-using ::modular::testing::Await;
-using ::modular::testing::Signal;
-using ::modular::testing::TestPoint;
-using ::test::peridot::tests::trigger::TriggerTestServicePtr;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestApp {
- public:
- TestPoint initialized_{"Entity module initialized"};
- TestPoint created_entity_{"Created entity"};
- TestPoint entity_data_correct_{"Entity data correct"};
- TestPoint entity_data_correct_after_resolution_{
- "Entity data correct after entity resolution"};
- TestPoint watch_data_correct_{"Entity watch returned correct data"};
- TestApp(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : module_context_(module_host->module_context()),
- entity_watcher_binding_(&entity_watcher_) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- initialized_.Pass();
-
- const char kTestString[] = "test";
- const char kTestType[] = "com.fuchsia.test";
- const char kUpdatedString[] = "updated";
- fsl::SizedVmo vmo;
- fsl::VmoFromString(kTestString, &vmo);
- module_context_->CreateEntity(
- kTestType, std::move(vmo).ToTransport(), entity_.NewRequest(),
- fxl::MakeCopyable([this](fidl::StringPtr entity_reference) mutable {
- if (!entity_reference || entity_reference->empty()) {
- modular::testing::Fail("Failed to create entity.");
- return;
- } else {
- created_entity_.Pass();
- }
- }));
-
- // Register a watcher and make sure it is notified with the correct data
- // when the entity value is updated.
- entity_watcher_.SetOnUpdated(
- [this, kUpdatedString](std::unique_ptr<fuchsia::mem::Buffer> value) {
- if (value) {
- std::string data_string;
- fsl::StringFromVmo(*value, &data_string);
-
- if (data_string == kUpdatedString) {
- watch_data_correct_.Pass();
- Signal(kEntityModuleDoneSecondTask);
- }
- }
- });
-
- entity_->Watch(kTestType, entity_watcher_binding_.NewBinding());
-
- // Fetch the data and verify that it matches the data used to create the
- // entity.
- entity_->GetData(
- kTestType,
- fxl::MakeCopyable([this, kTestString](fuchsia::mem::BufferPtr data) {
- if (data) {
- std::string data_string;
- fsl::StringFromVmo(*data, &data_string);
- if (data_string == kTestString) {
- entity_data_correct_.Pass();
- }
- }
- Signal(kEntityModuleDoneFirstTask);
- }));
-
- // Fetch the reference from the entity to verify the round-trip
- // resolution.
- entity_->GetReference(
- fxl::MakeCopyable([this, kTestString, kTestType,
- kUpdatedString](fidl::StringPtr entity_reference) {
- // Grab the entity resolver from the component context.
- fuchsia::modular::EntityResolverPtr entity_resolver;
- fuchsia::modular::ComponentContextPtr component_context;
- module_context_->GetComponentContext(component_context.NewRequest());
- component_context->GetEntityResolver(entity_resolver.NewRequest());
-
- // Resolve the entity and verify the data is correct.
- fuchsia::modular::EntityPtr resolved_entity;
- entity_resolver->ResolveEntity(entity_reference,
- resolved_entity.NewRequest());
- resolved_entity->GetData(
- kTestType,
- fxl::MakeCopyable([this, kTestString, kTestType, kUpdatedString,
- resolved_entity = std::move(resolved_entity)](
- fuchsia::mem::BufferPtr data) {
- if (data) {
- std::string data_string;
- fsl::StringFromVmo(*data, &data_string);
- if (data_string == kTestString) {
- entity_data_correct_after_resolution_.Pass();
- }
- }
-
- fsl::SizedVmo vmo;
- fsl::VmoFromString(kUpdatedString, &vmo);
- entity_->WriteData(
- kTestType, std::move(vmo).ToTransport(),
- [](fuchsia::modular::EntityWriteStatus status) {});
- }));
- }));
- }
-
- TestApp(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestApp(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- TestPoint stopped_{"Entity module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- fuchsia::modular::EntityPtr entity_;
- std::string module_name_ = "";
- fuchsia::modular::OngoingActivityPtr ongoing_activity_;
- fuchsia::modular::ModuleContext* module_context_;
- modular::EntityWatcherImpl entity_watcher_;
- fidl::Binding<fuchsia::modular::EntityWatcher> entity_watcher_binding_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestApp> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/module_context/module_context_test_module.cc b/tests/module_context/module_context_test_module.cc
deleted file mode 100644
index bc88447..0000000
--- a/tests/module_context/module_context_test_module.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/fsl/vmo/strings.h>
-#include <test/peridot/tests/trigger/cpp/fidl.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/module_context/defs.h"
-
-using ::modular::testing::Await;
-using ::modular::testing::Signal;
-using ::modular::testing::TestPoint;
-using ::test::peridot::tests::trigger::TriggerTestServicePtr;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"Root module initialized"};
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- fuchsia::modular::ModuleContext* module_context =
- module_host->module_context();
- initialized_.Pass();
-
- module_host->module_context()->GetLink(kLinkName, link_.NewRequest());
- fidl::VectorPtr<std::string> name;
- name.push_back(kLinkKey);
- link_->Get(name.Clone(), [this, module_context](
- std::unique_ptr<fuchsia::mem::Buffer> value) {
- if (!value) {
- modular::testing::Fail("Did not receive a module name in link.");
- return;
- }
-
- std::string value_string;
- FXL_CHECK(fsl::StringFromVmo(*value, &value_string));
-
- rapidjson::Document document;
- document.Parse(value_string.c_str());
- module_name_ = document.GetString();
-
- Await(module_name_ == kFirstModuleName ? kFirstModuleCallDone
- : kSecondModuleCallDone,
- [this, module_context] { module_context->RemoveSelfFromStory(); });
- Await(module_name_ == kFirstModuleName ? kFirstModuleCallStartActivity
- : kSecondModuleCallStartActivity,
- [this, module_context] {
- module_context->StartOngoingActivity(
- fuchsia::modular::OngoingActivityType::VIDEO,
- ongoing_activity_.NewRequest());
- });
- Await(module_name_ == kFirstModuleName ? kFirstModuleCallStopActivity
- : kSecondModuleCallStopActivity,
- [this, module_context] { ongoing_activity_.Unbind(); });
- });
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called by ModuleDriver.
- TestPoint stopped_{"Root module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- std::string terminated = module_name_ == kFirstModuleName
- ? kFirstModuleTerminated
- : kSecondModuleTerminated;
- Signal(terminated);
- modular::testing::Done(done);
- }
-
- private:
- fuchsia::modular::LinkPtr link_;
- std::string module_name_ = "";
- fuchsia::modular::OngoingActivityPtr ongoing_activity_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/module_context/module_context_test_session_shell.cc b/tests/module_context/module_context_test_session_shell.cc
deleted file mode 100644
index 17f2238..0000000
--- a/tests/module_context/module_context_test_session_shell.cc
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/module_context/defs.h"
-
-using ::modular::testing::Await;
-using ::modular::testing::Signal;
-using ::modular::testing::TestPoint;
-
-namespace {
-
-const char kStoryName[] = "story";
-
-// A simple story activity watcher implementation.
-class StoryActivityWatcherImpl : fuchsia::modular::StoryActivityWatcher {
- public:
- StoryActivityWatcherImpl()
- : binding_(this),
- on_notify_(
- [](std::string,
- std::vector<fuchsia::modular::OngoingActivityType>) {}) {}
- ~StoryActivityWatcherImpl() override = default;
-
- void Watch(fuchsia::modular::StoryProvider* const story_provider) {
- story_provider->WatchActivity(binding_.NewBinding());
- }
-
- void OnNotify(std::function<
- void(std::string,
- std::vector<fuchsia::modular::OngoingActivityType>)>
- on_notify) {
- on_notify_ = std::move(on_notify);
- }
-
- private:
- // |fuchsia::modular::StoryActivityWatcher|
- void OnStoryActivityChange(
- std::string story_id,
- std::vector<fuchsia::modular::OngoingActivityType> activities)
- override {
- on_notify_(std::move(story_id), std::move(activities));
- }
-
- fidl::Binding<fuchsia::modular::StoryActivityWatcher> binding_;
- std::function<void(std::string,
- std::vector<fuchsia::modular::OngoingActivityType>)>
- on_notify_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryActivityWatcherImpl);
-};
-
-class TestApp : public modular::testing::SessionShellBase {
- public:
- TestApp(component::StartupContext* const startup_context)
- : SessionShellBase(startup_context), weak_ptr_factory_(this) {
- TestInit(__FILE__);
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
-
- CreateStory();
- }
-
- ~TestApp() override = default;
-
- private:
- TestPoint story_create_{"Created story."};
- void CreateStory() {
- std::vector<fuchsia::modular::StoryCommand> commands;
- {
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back(kFirstModuleName);
- add_mod.intent = IntentWithParameterString(kFirstModuleName);
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
- }
- {
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back(kSecondModuleName);
- add_mod.intent = IntentWithParameterString(kSecondModuleName);
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
- }
- {
- fuchsia::modular::Intent intent;
- intent.handler = kEntityModuleUrl;
- intent.action = kEntityIntentAction;
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("entity_module");
- add_mod.intent = std::move(intent);
- add_mod.surface_parent_mod_name.resize(0);
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
- }
-
- puppet_master_->ControlStory(kStoryName, story_puppet_master_.NewRequest());
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story_create_.Pass();
- StartStory();
- });
- }
-
- TestPoint story_get_controller_{"Story GetController()"};
- // Starts the story and adds two modules to it.
- void StartStory() {
- story_provider()->GetController(kStoryName, story_controller_.NewRequest());
- story_controller_.set_error_handler([this](zx_status_t status) {
- FXL_LOG(ERROR) << "Story controller for story " << kStoryName
- << " died. Does this story exist?";
- });
-
- story_controller_->RequestStart();
- story_controller_->GetInfo(
- [this](fuchsia::modular::StoryInfo, fuchsia::modular::StoryState) {
- story_get_controller_.Pass();
- PerformWatchActivity();
- });
- }
-
- TestPoint on_watch_ongoing_activities_dispatched{
- "When a watcher is registered, ongoing activities should be dispatched."};
- void PerformWatchActivity() {
- story_activity_watcher_.Watch(story_provider());
- story_activity_watcher_.OnNotify(
- [this](
- std::string story_id,
- std::vector<fuchsia::modular::OngoingActivityType> activities) {
- if (story_id == kStoryName && activities.empty()) {
- on_watch_ongoing_activities_dispatched.Pass();
- }
- PerformFirstModuleStartActivity();
- });
- }
-
- TestPoint on_start_ongoing_activity_dispatched{
- "When there is a new ongoing activity, the ongoing activity should be "
- "dispatched."};
- // Signals the first module to call ModuleContext.StartOngoingActivity().
- void PerformFirstModuleStartActivity() {
- Signal(kFirstModuleCallStartActivity);
- story_activity_watcher_.OnNotify(
- [this](
- std::string story_id,
- std::vector<fuchsia::modular::OngoingActivityType> activities) {
- if (story_id == kStoryName && activities.size() == 1 &&
- activities[0] ==
- fuchsia::modular::OngoingActivityType::VIDEO) {
- on_start_ongoing_activity_dispatched.Pass();
- }
- PerformSecondModuleStartActivity();
- });
- }
-
- TestPoint on_start_all_ongoing_activities_dispatched{
- "When there is a new ongoing activity, all ongoing activities should be "
- "dispatched."};
- // Signals the second module to call ModuleContext.StartOngoingActivity().
- void PerformSecondModuleStartActivity() {
- Signal(kSecondModuleCallStartActivity);
- story_activity_watcher_.OnNotify(
- [this](
- std::string story_id,
- std::vector<fuchsia::modular::OngoingActivityType> activities) {
- if (story_id == kStoryName && activities.size() == 2 &&
- activities[0] ==
- fuchsia::modular::OngoingActivityType::VIDEO &&
- activities[1] ==
- fuchsia::modular::OngoingActivityType::VIDEO) {
- on_start_all_ongoing_activities_dispatched.Pass();
- }
- PerformSecondModuleStopActivity();
- });
- }
-
- TestPoint on_stop_remaining_ongoing_activities_dispatched{
- "When an ongoing activity is stopped, all remaining ongoing activities "
- "should be dispatched."};
- // Signals the second module to stop ongoing activity.
- void PerformSecondModuleStopActivity() {
- Signal(kSecondModuleCallStopActivity);
- story_activity_watcher_.OnNotify(
- [this](
- std::string story_id,
- std::vector<fuchsia::modular::OngoingActivityType> activities) {
- if (story_id == kStoryName && activities.size() == 1 &&
- activities[0] ==
- fuchsia::modular::OngoingActivityType::VIDEO) {
- on_stop_remaining_ongoing_activities_dispatched.Pass();
- }
- TestModuleCreatingEntity();
- });
- }
-
- void TestModuleCreatingEntity() {
- Await(kEntityModuleDoneFirstTask, [this] {
- Await(kEntityModuleDoneSecondTask, [this] {
- fuchsia::modular::Intent intent;
- intent.handler = kEntityModuleUrl;
- intent.action = kEntityIntentAction;
- fuchsia::modular::RemoveMod remove_mod;
- remove_mod.mod_name.push_back("entity_module");
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::StoryCommand command;
- command.set_remove_mod(std::move(remove_mod));
- commands.push_back(std::move(command));
-
- puppet_master_->ControlStory(kStoryName,
- story_puppet_master_.NewRequest());
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- PerformFirstModuleDone();
- });
- });
- });
- }
-
- TestPoint on_done_ongoing_activities_stopped{
- "When a module is teared down, the ongoing activity should also be "
- "stopped"};
- TestPoint second_module_active_{
- "Only second module is still active after first calls "
- "RemoveSelfFromStory()"};
- // Signals the first module to call ModuleContext.RemoveSelfFromStory().
- void PerformFirstModuleDone() {
- Signal(kFirstModuleCallDone);
- Await(kFirstModuleTerminated, [this] {
- // Verify that the second module is still active, but the first one is
- // not.
- story_controller_->GetActiveModules(
- [this](std::vector<fuchsia::modular::ModuleData> module_data) {
- if (module_data.size() == 1) {
- second_module_active_.Pass();
- }
- VerifyStoryStillRunning();
- });
- });
-
- story_activity_watcher_.OnNotify(
- [this](
- std::string story_id,
- std::vector<fuchsia::modular::OngoingActivityType> activities) {
- if (story_id == kStoryName && activities.empty()) {
- on_done_ongoing_activities_stopped.Pass();
- }
- });
- }
-
- TestPoint story_still_active_{
- "The story is still active after first module calls "
- "RemoveSelfFromStory()"};
- // Verifies that the story is still running after the first module has called
- // done and been stopped.
- void VerifyStoryStillRunning() {
- IsStoryRunning([this](bool is_running) {
- if (is_running) {
- story_still_active_.Pass();
- }
- PerformSecondModuleDone();
- });
- }
-
- TestPoint no_module_active_{
- "No modules are active after second mod calls RemoveSelfFromStory()"};
- TestPoint story_stopped_{"The story was stopped."};
- // Signals the second module to call ModuleContext.Done.
- void PerformSecondModuleDone() {
- Signal(kSecondModuleCallDone);
- Await(kSecondModuleTerminated, [this] {
- // Verify that the second module is still active.
- story_controller_->GetActiveModules(
- [this](std::vector<fuchsia::modular::ModuleData> module_data) {
- if (module_data.empty()) {
- no_module_active_.Pass();
- }
- IsStoryRunning([this](bool is_running) {
- if (!is_running) {
- story_stopped_.Pass();
- }
-
- Signal(modular::testing::kTestShutdown);
- });
- });
- });
- }
-
- // Verifies that the story is stopped when the last module that is part of the
- // story calls ModuleContext.Done and is stopped.
- void IsStoryRunning(std::function<void(bool)> callback) {
- story_controller_->GetInfo(
- [this, callback](fuchsia::modular::StoryInfo story_info,
- fuchsia::modular::StoryState state) {
- callback(state == fuchsia::modular::StoryState::RUNNING);
- });
- }
-
- // Creates an intent with one parameter, kLinkName, with the following
- // contents: { |kLinkKey| : |parameter_string| }.
- fuchsia::modular::Intent IntentWithParameterString(
- std::string parameter_string) {
- fuchsia::modular::Intent intent;
- intent.handler = kModuleUrl;
- intent.action = kIntentAction;
-
- fuchsia::modular::IntentParameter parameter;
- parameter.name = kLinkName;
-
- rapidjson::Document document;
- document.SetObject();
- document.AddMember(kLinkKey, parameter_string, document.GetAllocator());
-
- fuchsia::modular::IntentParameterData parameter_data;
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(modular::JsonValueToString(document), &vmo));
- parameter_data.set_json(std::move(vmo).ToTransport());
- parameter.data = std::move(parameter_data);
- intent.parameters.push_back(std::move(parameter));
-
- return intent;
- }
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- fuchsia::modular::StoryControllerPtr story_controller_;
- StoryActivityWatcherImpl story_activity_watcher_;
-
- fxl::WeakPtrFactory<TestApp> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/parent_child/BUILD.gn b/tests/parent_child/BUILD.gn
deleted file mode 100644
index 31adf51..0000000
--- a/tests/parent_child/BUILD.gn
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("parent_child_test_child_module1") {
- testonly = true
-
- meta = [
- {
- path = "meta/parent_child_test_child_module1.cmx"
- dest = "parent_child_test_child_module1.cmx"
- },
- ]
-
- sources = [
- "parent_child_test_child_module1.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("parent_child_test_child_module2") {
- testonly = true
-
- meta = [
- {
- path = "meta/parent_child_test_child_module2.cmx"
- dest = "parent_child_test_child_module2.cmx"
- },
- ]
-
- sources = [
- "parent_child_test_child_module2.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("parent_child_test_parent_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/parent_child_test_parent_module.cmx"
- dest = "parent_child_test_parent_module.cmx"
- },
- ]
-
- sources = [
- "parent_child_test_parent_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/callback",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
diff --git a/tests/parent_child/README.md b/tests/parent_child/README.md
deleted file mode 100644
index 107bddf..0000000
--- a/tests/parent_child/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# parent_child integration test
-
-This test exercises the API that is exposed to Modules to start more modules and
-control the life cycle of the newly started modules.
diff --git a/tests/parent_child/defs.h b/tests/parent_child/defs.h
deleted file mode 100644
index 74e1152..0000000
--- a/tests/parent_child/defs.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_PARENT_CHILD_DEFS_H_
-#define PERIDOT_TESTS_PARENT_CHILD_DEFS_H_
-
-namespace {
-
-constexpr char kChildModuleName[] = "child";
-
-// Package URLs of the test components used here.
-constexpr char kChildModuleUrl1[] =
- "fuchsia-pkg://fuchsia.com/parent_child_test_child_module1#meta/parent_child_test_child_module1.cmx";
-constexpr char kChildModuleUrl2[] =
- "fuchsia-pkg://fuchsia.com/parent_child_test_child_module2#meta/parent_child_test_child_module2.cmx";
-constexpr char kChildModuleAction[] =
- "fuchsia-pkg://fuchsia.com/parent_child_test_child_module_action#meta/parent_child_test_child_module_action.cmx";
-
-constexpr int kTimeoutMilliseconds = 5000;
-
-} // namespace
-
-#endif // PERIDOT_TESTS_PARENT_CHILD_DEFS_H_
diff --git a/tests/parent_child/meta/parent_child_test_child_module1.cmx b/tests/parent_child/meta/parent_child_test_child_module1.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/parent_child/meta/parent_child_test_child_module1.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/parent_child/meta/parent_child_test_child_module2.cmx b/tests/parent_child/meta/parent_child_test_child_module2.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/parent_child/meta/parent_child_test_child_module2.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/parent_child/meta/parent_child_test_parent_module.cmx b/tests/parent_child/meta/parent_child_test_parent_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/parent_child/meta/parent_child_test_parent_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/parent_child/parent_child_test_child_module1.cc b/tests/parent_child/parent_child_test_child_module1.cc
deleted file mode 100644
index 3fe9c77..0000000
--- a/tests/parent_child/parent_child_test_child_module1.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/parent_child/defs.h"
-
-using modular::testing::Get;
-using modular::testing::Put;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
-
- FXL_LOG(INFO) << "Child module 1 initialized";
- Signal(std::string("child_module_1_init"));
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called from ModuleDriver.
- TestPoint stopped_{"Child module 1 stopped"};
- void Terminate(const std::function<void()>& done) {
- FXL_LOG(INFO) << "Child module 1 exiting.";
- stopped_.Pass();
-
- Signal("child_module_1_stop");
- modular::testing::Done(done);
- }
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/parent_child/parent_child_test_child_module2.cc b/tests/parent_child/parent_child_test_child_module2.cc
deleted file mode 100644
index 92f5923..0000000
--- a/tests/parent_child/parent_child_test_child_module2.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fsl/vmo/strings.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/parent_child/defs.h"
-
-using modular::testing::Get;
-using modular::testing::Put;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
-
- FXL_LOG(INFO) << "Child module 2 initialized";
- Signal(std::string("child_module_2_init"));
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called from ModuleDriver.
- TestPoint stopped_{"Child module 2 stopped"};
- void Terminate(const std::function<void()>& done) {
- FXL_LOG(INFO) << "Child module 2 exiting.";
- stopped_.Pass();
-
- Signal("child_module_2_stop");
- modular::testing::Done(done);
- }
-
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/parent_child/parent_child_test_parent_module.cc b/tests/parent_child/parent_child_test_parent_module.cc
deleted file mode 100644
index b4259ca..0000000
--- a/tests/parent_child/parent_child_test_parent_module.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/memory/weak_ptr.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/parent_child/defs.h"
-
-using modular::testing::Await;
-using modular::testing::Get;
-using modular::testing::Put;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-void AddModuleToStoryWithHandler(
- fuchsia::modular::ModuleContext* const module_context,
- fidl::InterfaceRequest<fuchsia::modular::ModuleController> request,
- fidl::StringPtr handler) {
- fuchsia::modular::Intent intent;
- intent.handler = handler;
- intent.action = kChildModuleAction;
- module_context->AddModuleToStory(
- kChildModuleName, std::move(intent), std::move(request),
- nullptr /* surface_relation */,
- [](const fuchsia::modular::StartModuleStatus) {});
-}
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"Parent module initialized"};
-
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : module_host_(module_host) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- initialized_.Pass();
-
- StartChildModuleTwice();
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called by ModuleDriver.
- TestPoint stopped_{"Parent module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- TestPoint second_child_module_controller_closed_{
- "Second child module controller closed"};
-
- void StartChildModuleTwice() {
- AddModuleToStoryWithHandler(module_host_->module_context(),
- child_module_.NewRequest(), kChildModuleUrl1);
- child_module_.set_error_handler(
- [this](zx_status_t status) { OnFirstChildModuleStopped(); });
-
- // Once the module starts, start the same module again with the same
- // Intent, and then again but with a different Intent.handler. The second
- // call stops the previous module instance and starts a new one.
- Await("child_module_1_init", [this] {
- AddModuleToStoryWithHandler(module_host_->module_context(),
- child_module_again_.NewRequest(),
- kChildModuleUrl1);
- child_module_again_.set_error_handler([this](zx_status_t status) {
- second_child_module_controller_closed_.Pass();
- });
- AddModuleToStoryWithHandler(module_host_->module_context(),
- child_module2_.NewRequest(),
- kChildModuleUrl2);
- });
- }
-
- TestPoint child_module1_stopped_{"Child module killed for restart"};
-
- void OnFirstChildModuleStopped() {
- child_module1_stopped_.Pass();
-
- // Confirm that the first module instance stopped, and then stop the second
- // module instance.
- Await("child_module_1_stop", [this] {
- Await("child_module_2_init", [this] {
- child_module2_->Stop([this] { OnChildModule2Stopped(); });
- });
- });
- }
-
- TestPoint child_module2_stopped_{"Second child module stopped"};
- void OnChildModule2Stopped() {
- child_module2_stopped_.Pass();
-
- TestPipelinedAddAndStop();
- }
-
- TestPoint child_module_3_started_{"Third child module started"};
- TestPoint child_module_3_stopped_{"Third child module stopped"};
- void TestPipelinedAddAndStop() {
- // New test case: start a third child module, and immediately stop it.
- // We expect that the child module will go through its full lifecycle,
- // since we serialize these requests in sessionmgr.
- AddModuleToStoryWithHandler(module_host_->module_context(),
- child_module3_.NewRequest(), kChildModuleUrl1);
- child_module3_->Stop([this] { /* do nothing */ });
- child_module3_.events().OnStateChange =
- [this](fuchsia::modular::ModuleState module_state) {
- if (module_state == fuchsia::modular::ModuleState::RUNNING) {
- child_module_3_started_.Pass();
- }
- if (module_state == fuchsia::modular::ModuleState::STOPPED) {
- child_module_3_stopped_.Pass();
- Signal(modular::testing::kTestShutdown);
- }
- };
- }
-
- modular::ModuleHost* module_host_;
- fuchsia::modular::ModuleControllerPtr child_module_;
- fuchsia::modular::ModuleControllerPtr child_module_again_;
- fuchsia::modular::ModuleControllerPtr child_module2_;
- fuchsia::modular::ModuleControllerPtr child_module3_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/queue_persistence/BUILD.gn b/tests/queue_persistence/BUILD.gn
deleted file mode 100644
index 23267e2..0000000
--- a/tests/queue_persistence/BUILD.gn
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("queue_persistence_test_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/queue_persistence_test_module.cmx"
- dest = "queue_persistence_test_module.cmx"
- },
- ]
-
- sources = [
- "queue_persistence_test_module.cc",
- ]
-
- deps = [
- ":defs",
- ":queue_persistence_test_service",
- "//garnet/public/lib/callback",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/public/lib/message_queue/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("queue_persistence_test_agent") {
- testonly = true
-
- meta = [
- {
- path = "meta/queue_persistence_test_agent.cmx"
- dest = "queue_persistence_test_agent.cmx"
- },
- ]
-
- sources = [
- "queue_persistence_test_agent.cc",
- ]
-
- deps = [
- ":defs",
- ":queue_persistence_test_service",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:agent_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/public/lib/message_queue/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-fidl("queue_persistence_test_service") {
- name = "test.peridot.tests.queuepersistence"
- cpp_legacy_callbacks = true
-
- sources = [
- "queue_persistence_test_service.fidl",
- ]
-}
diff --git a/tests/queue_persistence/README.md b/tests/queue_persistence/README.md
deleted file mode 100644
index 89af8ff..0000000
--- a/tests/queue_persistence/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# queue_persistence integration test
-
-This test exercises the APIs exposed to modules to connect to agents, and for
-Modules and Agents to exchange message queues.
-
-It specifically tests that message queues are persistent between invocations of
-agents, and that a message sent to the message queue of agent while the agent is
-not running can be received by the agent when it's started again.
diff --git a/tests/queue_persistence/defs.h b/tests/queue_persistence/defs.h
deleted file mode 100644
index b9c4bb7..0000000
--- a/tests/queue_persistence/defs.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_QUEUE_PERSISTENCE_DEFS_H_
-#define PERIDOT_TESTS_QUEUE_PERSISTENCE_DEFS_H_
-
-namespace {
-
-// This is how long we wait for the test to finish before we timeout and tear
-// down our test.
-constexpr int kTimeoutMilliseconds = 10000;
-
-// Package URLs of the test components used here.
-constexpr char kTestAgent[] =
- "fuchsia-pkg://fuchsia.com/queue_persistence_test_agent#meta/queue_persistence_test_agent.cmx";
-
-} // namespace
-
-#endif // PERIDOT_TESTS_QUEUE_PERSISTENCE_DEFS_H_
diff --git a/tests/queue_persistence/meta/queue_persistence_test_agent.cmx b/tests/queue_persistence/meta/queue_persistence_test_agent.cmx
deleted file mode 100644
index 12bf3ba..0000000
--- a/tests/queue_persistence/meta/queue_persistence_test_agent.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.AgentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/queue_persistence/meta/queue_persistence_test_module.cmx b/tests/queue_persistence/meta/queue_persistence_test_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/queue_persistence/meta/queue_persistence_test_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/queue_persistence/queue_persistence_test_agent.cc b/tests/queue_persistence/queue_persistence_test_agent.cc
deleted file mode 100644
index 8758656..0000000
--- a/tests/queue_persistence/queue_persistence_test_agent.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fxl/logging.h>
-#include <lib/message_queue/cpp/message_queue_client.h>
-#include <test/peridot/tests/queuepersistence/cpp/fidl.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/queue_persistence/defs.h"
-
-using modular::testing::TestPoint;
-using namespace test::peridot::tests::queuepersistence;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestApp : QueuePersistenceTestService {
- public:
- TestApp(modular::AgentHost* agent_host) {
- modular::testing::Init(agent_host->startup_context(), __FILE__);
- agent_host->agent_context()->GetComponentContext(
- component_context_.NewRequest());
-
- // Create a message queue and schedule a task to be run on receiving a
- // message on it.
- component_context_->ObtainMessageQueue("Test Queue",
- msg_queue_.NewRequest());
- msg_queue_.RegisterReceiver(
- [this](std::string message, fit::function<void()> ack) {
- ack();
- modular::testing::GetStore()->Put(
- "queue_persistence_test_agent_received_message", "", [] {});
- });
-
- services_.AddService<QueuePersistenceTestService>(
- [this](fidl::InterfaceRequest<QueuePersistenceTestService> request) {
- services_bindings_.AddBinding(this, std::move(request));
- });
-
- initialized_.Pass();
- }
-
- // Called by AgentDriver.
- void Connect(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services) {
- services_.AddBinding(std::move(services));
- modular::testing::GetStore()->Put("queue_persistence_test_agent_connected",
- "", [] {});
- }
-
- // Called by AgentDriver.
- void RunTask(const fidl::StringPtr& /*task_id*/,
- const std::function<void()>& /*callback*/) {}
-
- // Called by AgentDriver.
- void Terminate(const std::function<void()>& done) {
- // Stop processing messages, since we do async operations below and don't
- // want our receiver to fire.
- msg_queue_.RegisterReceiver(nullptr);
-
- modular::testing::GetStore()->Put("queue_persistence_test_agent_stopped",
- "",
- [done] { modular::testing::Done(done); });
- }
-
- private:
- // |QueuePersistenceTestService|
- void GetMessageQueueToken(GetMessageQueueTokenCallback callback) override {
- msg_queue_.GetToken(
- [callback](const fidl::StringPtr& token) { callback(token); });
- }
-
- TestPoint initialized_{"Queue persistence test agent initialized"};
-
- fuchsia::modular::ComponentContextPtr component_context_;
- modular::MessageQueueClient msg_queue_;
-
- component::ServiceNamespace services_;
- fidl::BindingSet<QueuePersistenceTestService> services_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<TestApp> driver(context.get(), [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/queue_persistence/queue_persistence_test_module.cc b/tests/queue_persistence/queue_persistence_test_module.cc
deleted file mode 100644
index 26c44bf..0000000
--- a/tests/queue_persistence/queue_persistence_test_module.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/fxl/memory/weak_ptr.h>
-#include <lib/message_queue/cpp/message_sender_client.h>
-#include <test/peridot/tests/queuepersistence/cpp/fidl.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/queue_persistence/defs.h"
-
-using modular::testing::Await;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-using namespace test::peridot::tests::queuepersistence;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"Root module initialized"};
-
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/)
- : module_host_(module_host), weak_ptr_factory_(this) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- initialized_.Pass();
-
- module_host_->module_context()->GetComponentContext(
- component_context_.NewRequest());
-
- fuchsia::sys::ServiceProviderPtr agent_services;
- component_context_->ConnectToAgent(kTestAgent, agent_services.NewRequest(),
- agent_controller_.NewRequest());
- component::ConnectToService(agent_services.get(),
- agent_service_.NewRequest());
-
- Await("queue_persistence_test_agent_connected",
- [this] { AgentConnected(); });
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- // Called by ModuleDriver.
- TestPoint stopped_{"Root module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- TestPoint agent_connected_{"fuchsia::modular::Agent accepted connection"};
-
- void AgentConnected() {
- agent_connected_.Pass();
- agent_service_->GetMessageQueueToken(
- [this](const fidl::StringPtr& token) { ReceivedQueueToken(token); });
- }
-
- TestPoint received_queue_persistence_token_{
- "Received queue_persistence token"};
-
- void ReceivedQueueToken(const fidl::StringPtr& token) {
- queue_token_ = token;
- received_queue_persistence_token_.Pass();
-
- // Stop the agent.
- agent_controller_.Unbind();
- agent_service_.Unbind();
- Await("queue_persistence_test_agent_stopped", [this] { AgentStopped(); });
- }
-
- TestPoint agent_stopped_{"fuchsia::modular::Agent stopped"};
-
- void AgentStopped() {
- agent_stopped_.Pass();
-
- // Send a message to the stopped agent which should be persisted to local
- // storage. No triggers are set so the agent won't be automatically started.
- modular::MessageSenderClient message_sender;
- component_context_->GetMessageSender(queue_token_,
- message_sender.NewRequest());
- message_sender.Send("Queued message...");
-
- // Start the agent again.
- fuchsia::sys::ServiceProviderPtr agent_services;
- component_context_->ConnectToAgent(kTestAgent, agent_services.NewRequest(),
- agent_controller_.NewRequest());
- component::ConnectToService(agent_services.get(),
- agent_service_.NewRequest());
-
- Await("queue_persistence_test_agent_connected",
- [this] { AgentConnectedAgain(); });
- }
-
- TestPoint agent_connected_again_{
- "fuchsia::modular::Agent accepted connection, again"};
-
- void AgentConnectedAgain() {
- agent_connected_again_.Pass();
- Await("queue_persistence_test_agent_received_message",
- [this] { AgentReceivedMessage(); });
- }
-
- TestPoint agent_received_message_{"fuchsia::modular::Agent received message"};
-
- void AgentReceivedMessage() {
- agent_received_message_.Pass();
-
- // Stop the agent again.
- agent_controller_.Unbind();
- agent_service_.Unbind();
- Await("queue_persistence_test_agent_stopped",
- [this] { Signal(modular::testing::kTestShutdown); });
- }
-
- modular::ModuleHost* module_host_;
- fuchsia::modular::AgentControllerPtr agent_controller_;
- QueuePersistenceTestServicePtr agent_service_;
- fuchsia::modular::ComponentContextPtr component_context_;
- fuchsia::modular::MessageQueuePtr msg_queue_;
-
- std::string queue_token_;
-
- fxl::WeakPtrFactory<TestModule> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/queue_persistence/queue_persistence_test_service.fidl b/tests/queue_persistence/queue_persistence_test_service.fidl
deleted file mode 100644
index c052117..0000000
--- a/tests/queue_persistence/queue_persistence_test_service.fidl
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library test.peridot.tests.queuepersistence;
-
-// Cf. README.md for what this test does and how.
-[Discoverable]
-interface QueuePersistenceTestService {
- 1: GetMessageQueueToken() -> (string message_queue_token);
-};
diff --git a/tests/run_modular_tests.sh b/tests/run_modular_tests.sh
deleted file mode 100644
index 66aa9a5..0000000
--- a/tests/run_modular_tests.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/boot/bin/sh
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-set -e
-
-run_integration_tests --test_file=/pkgfs/packages/modular_tests/0/data/modular_tests.json "$@"
-
diff --git a/tests/session_shell/BUILD.gn b/tests/session_shell/BUILD.gn
deleted file mode 100644
index a669070..0000000
--- a/tests/session_shell/BUILD.gn
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("session_shell_test_session_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/session_shell_test_session_shell.cmx"
- dest = "session_shell_test_session_shell.cmx"
- },
- ]
-
- sources = [
- "session_shell_test_session_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- ]
-}
diff --git a/tests/session_shell/README.md b/tests/session_shell/README.md
deleted file mode 100644
index 2e3f80a..0000000
--- a/tests/session_shell/README.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# session_shell integration test
-
-This test exercises the APIs exposed to the session shell:
-
-* Create, start, stop, delete stories.
-
-* See existing stories as long as they are not deleted.
-
-* Add modules to existing stories.
-
-* Be notified when story state changes.
-
-* Be notified through SessionShell.AttachView() of a new story view when story
- start is requested by RequestStart().
-
-* Be notified through SessionShell.DetachView() of a story going away.
-
-* StoryRunner tolerates a session shell not responding fast enough to
- SessionShell.DetachView().
-
-* On logout, no DetachView() calls are made for still running stories.
-
-The test code is invoked as a session shell from basemgr and executes a
-predefined sequence of steps, rather than to expose a UI to be driven by user
-interaction, as a session shell normally would. I.e. the test is implemented as a
-session shell component.
diff --git a/tests/session_shell/defs.h b/tests/session_shell/defs.h
deleted file mode 100644
index a314bcb..0000000
--- a/tests/session_shell/defs.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_SESSION_SHELL_DEFS_H_
-#define PERIDOT_TESTS_SESSION_SHELL_DEFS_H_
-
-namespace {
-
-// URLs of the modules used here.
-
-} // namespace
-
-#endif // PERIDOT_TESTS_SESSION_SHELL_DEFS_H_
diff --git a/tests/session_shell/meta/session_shell_test_session_shell.cmx b/tests/session_shell/meta/session_shell_test_session_shell.cmx
deleted file mode 100644
index a2fe1c5..0000000
--- a/tests/session_shell/meta/session_shell_test_session_shell.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/session_shell/session_shell_test_session_shell.cc b/tests/session_shell/session_shell_test_session_shell.cc
deleted file mode 100644
index 21613c2..0000000
--- a/tests/session_shell/session_shell_test_session_shell.cc
+++ /dev/null
@@ -1,819 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <set>
-#include <utility>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fsl/vmo/sized_vmo.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/time/time_delta.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/session_shell/defs.h"
-
-using modular::testing::Await;
-using modular::testing::Fail;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-using fuchsia::modular::ViewIdentifier;
-
-namespace {
-
-// A simple story provider watcher implementation. Just logs observed state
-// transitions.
-class StoryProviderStateWatcherImpl : fuchsia::modular::StoryProviderWatcher {
- public:
- StoryProviderStateWatcherImpl() : binding_(this) {}
- ~StoryProviderStateWatcherImpl() override = default;
-
- // Registers itself a watcher on the given story provider. Only one story
- // provider can be watched at a time.
- void Watch(fuchsia::modular::StoryProvider* const story_provider) {
- story_provider->Watch(binding_.NewBinding());
- }
-
- // Deregisters itself from the watched story provider.
- void Reset() { binding_.Unbind(); }
-
- void SetKindOfProtoStory(fidl::StringPtr story_id) {
- kind_of_proto_stories_.insert(story_id);
- }
-
- private:
- TestPoint on_delete_called_once_{"OnDelete() Called"};
- int on_delete_called_{};
-
- // |fuchsia::modular::StoryProviderWatcher|
- void OnDelete(std::string story_id) override {
- FXL_LOG(INFO) << "StoryProviderStateWatcherImpl::OnDelete() " << story_id;
-
- if (++on_delete_called_ == 1) {
- on_delete_called_once_.Pass();
- }
-
- deleted_stories_.emplace(story_id);
- }
-
- TestPoint on_running_called_once_{"OnChange() RUNNING Called"};
- int on_running_called_{};
-
- TestPoint on_stopping_called_once_{"OnChange() STOPPING Called"};
- int on_stopping_called_{};
-
- TestPoint on_stopped_called_once_{"OnChange() STOPPED Called"};
- int on_stopped_called_{};
-
- // |fuchsia::modular::StoryProviderWatcher|
- void OnChange(const fuchsia::modular::StoryInfo story_info,
- const fuchsia::modular::StoryState story_state,
- const fuchsia::modular::StoryVisibilityState
- story_visibility_state) override {
- FXL_LOG(INFO) << "StoryProviderStateWatcherImpl::OnChange() "
- << " id " << story_info.id << " state "
- << fidl::ToUnderlying(story_state) << " visibility state "
- << fidl::ToUnderlying(story_visibility_state) << " url "
- << story_info.url;
-
- if (deleted_stories_.find(story_info.id) != deleted_stories_.end()) {
- FXL_LOG(ERROR) << "Status change notification for deleted story "
- << story_info.id;
- modular::testing::Fail("Status change notification for deleted story");
- }
-
- if (kind_of_proto_stories_.find(story_info.id) !=
- kind_of_proto_stories_.end()) {
- modular::testing::Fail(
- "Stories with kind_of_proto_story option set shouldn't notify "
- "OnChange");
- }
-
- // Just check that all states are covered at least once, proving that we get
- // state notifications at all from the story provider.
- switch (story_state) {
- case fuchsia::modular::StoryState::RUNNING:
- if (++on_running_called_ == 1) {
- on_running_called_once_.Pass();
- }
- break;
- case fuchsia::modular::StoryState::STOPPING:
- if (++on_stopping_called_ == 1) {
- on_stopping_called_once_.Pass();
- }
- break;
- case fuchsia::modular::StoryState::STOPPED:
- if (++on_stopped_called_ == 1) {
- on_stopped_called_once_.Pass();
- }
- break;
- }
- }
-
- fidl::Binding<fuchsia::modular::StoryProviderWatcher> binding_;
-
- // Remember deleted stories. After a story is deleted, there must be no state
- // change notifications for it.
- std::set<std::string> deleted_stories_;
-
- std::set<std::string> kind_of_proto_stories_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(StoryProviderStateWatcherImpl);
-};
-
-// Cf. README.md for what this test does in general and how. The test cases are
-// described in detail in comments below.
-class TestApp : public modular::testing::SessionShellBase {
- public:
- using ViewId = fuchsia::modular::ViewIdentifier;
-
- explicit TestApp(component::StartupContext* const startup_context)
- : SessionShellBase(startup_context) {
- TestInit(__FILE__);
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
- startup_context->ConnectToEnvironmentService(
- component_context_.NewRequest());
- story_provider_state_watcher_.Watch(story_provider());
-
- TestComponentContext_GetPackageName_Works();
- }
-
- ~TestApp() override = default;
-
- private:
- TestPoint create_view_{"CreateView()"};
-
- // |SingleServiceApp|
- void CreateView(
- zx::eventpair /*view_token*/,
- fidl::InterfaceRequest<
- fuchsia::sys::ServiceProvider> /*incoming_services*/,
- fidl::InterfaceHandle<
- fuchsia::sys::ServiceProvider> /*outgoing_services*/) override {
- create_view_.Pass();
- }
-
- // Test Case GetPackageName:
- //
- // When we call GetPackageName() on ComponentContext acquired from our
- // environment, it works.
-
- TestPoint component_context_package_name_{
- "ComponentContext.GetPackageName() works"};
-
- void TestComponentContext_GetPackageName_Works() {
- component_context_->GetPackageName([this](fidl::StringPtr name) {
- if (name) {
- component_context_package_name_.Pass();
- }
-
- TestStoryProvider_GetStoryInfo_Null();
- });
- }
-
- // Test Case GetStoryInfo Null:
- //
- // The story info of a story that does not exist is null.
-
- TestPoint get_story_info_null_{"StoryProvider.GetStoryInfo() is null"};
-
- void TestStoryProvider_GetStoryInfo_Null() {
- story_provider()->GetStoryInfo(
- "X", [this](fuchsia::modular::StoryInfoPtr story_info) {
- if (!story_info) {
- get_story_info_null_.Pass();
- }
-
- TestSessionShellContext_GetLink();
- });
- }
-
- // Test Case SessionShellContext:
- //
- // The session shell can access a Link.
-
- TestPoint get_link_{"SessionShellContext.GetLink()"};
-
- void TestSessionShellContext_GetLink() {
- session_shell_context()->GetLink(session_shell_link_.NewRequest());
- session_shell_link_->Get(
- nullptr, [this](std::unique_ptr<fuchsia::mem::Buffer> value) {
- get_link_.Pass();
- TestStoryProvider_GetStories();
- });
- }
-
- // Test Case StoryProvider:
- //
- // The session shell can access the list of existing stories. This list is
- // empty at the outset.
-
- TestPoint previous_stories_{"StoryProvider.GetStories()"};
-
- void TestStoryProvider_GetStories() {
- story_provider()->GetStories(
- nullptr, [this](std::vector<fuchsia::modular::StoryInfo> stories) {
- previous_stories_.Pass();
- TestStoryProvider_GetStoryInfo(std::move(stories));
- });
- }
-
- TestPoint get_story_info_{"StoryProvider.GetStoryInfo()"};
-
- void TestStoryProvider_GetStoryInfo(
- std::vector<fuchsia::modular::StoryInfo> stories) {
- if (stories.empty()) {
- get_story_info_.Pass();
- } else {
- FXL_LOG(ERROR) << "StoryProvider.GetStoryInfo() " << stories.size();
- for (const auto& item : stories) {
- FXL_LOG(INFO) << item.id;
- }
- }
-
- TestStory1();
- }
-
- // Test Case Story1:
- //
- // Create a story with extra information, start, and stop it.
-
- TestPoint story1_create_{"Story1 Create"};
-
- void TestStory1() {
- const std::string initial_json = R"({"created-with-info": true})";
- puppet_master_->ControlStory("story1", story_puppet_master_.NewRequest());
-
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("mod1");
- add_mod.intent.handler = kCommonActiveModule;
-
- fuchsia::modular::IntentParameter param;
- param.name = "root";
- fsl::SizedVmo vmo;
- FXL_CHECK(fsl::VmoFromString(initial_json, &vmo));
- param.data.set_json(std::move(vmo).ToTransport());
- add_mod.intent.parameters.push_back(std::move(param));
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(std::move(command));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story1_create_.Pass();
- TestStory1_GetController("story1");
- });
- }
-
- TestPoint story1_get_controller_{"Story1 GetController"};
-
- void TestStory1_GetController(fidl::StringPtr story_id) {
- story_provider()->GetController(story_id, story_controller_.NewRequest());
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo story_info,
- fuchsia::modular::StoryState state) {
- story1_get_controller_.Pass();
- story_info_ = std::move(story_info);
- TestStory1_Run();
- });
- }
-
- TestPoint story1_run_{"Story1 Run"};
- void TestStory1_Run() {
- // Start and show the new story.
- story_controller_->RequestStart();
- story1_run_.Pass();
- TestStory1_Stop();
- }
-
- TestPoint story1_stop_{"Story1 Stop"};
-
- void TestStory1_Stop() {
- story_controller_->Stop([this] {
- TeardownStoryController();
- story1_stop_.Pass();
-
- // When the story is done, we start the next one.
- TestStory2();
- });
- }
-
- // Test Case Story2:
- //
- // Verify that when pipelining Start() and GetInfo() calls, GetInfo() yields
- // the run state after Start().
- //
- // Verify that after DeleteStory(), GetInfo() returns null again.
-
- TestPoint story2_create_{"Story2 Create"};
-
- void TestStory2() {
- puppet_master_->ControlStory("story2", story_puppet_master_.NewRequest());
-
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("mod1");
- add_mod.intent.handler = kCommonNullModule;
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(std::move(command));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story2_create_.Pass();
- TestStory2_GetController("story2");
- });
- }
-
- TestPoint story2_get_controller_{"Story2 Get Controller"};
-
- void TestStory2_GetController(fidl::StringPtr story_id) {
- story_provider()->GetController(story_id, story_controller_.NewRequest());
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo story_info,
- fuchsia::modular::StoryState state) {
- story_info_ = std::move(story_info);
- story2_get_controller_.Pass();
- TestStory2_GetModules();
- });
- }
-
- TestPoint story2_get_modules_{"Story2 Get Modules"};
-
- void TestStory2_GetModules() {
- story_controller_->GetModules(
- [this](std::vector<fuchsia::modular::ModuleData> modules) {
- if (modules.size() == 1) {
- story2_get_modules_.Pass();
- }
-
- TestStory2_Run();
- });
- }
-
- TestPoint story2_state_before_run_{"Story2 State before Run"};
- TestPoint story2_state_after_run_{"Story2 State after Run"};
-
- void TestStory2_Run() {
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- if (state == fuchsia::modular::StoryState::STOPPED) {
- story2_state_before_run_.Pass();
- }
- });
-
- // Start and show the new story *while* the GetInfo() call above is in
- // flight.
- story_controller_->RequestStart();
-
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- if (state == fuchsia::modular::StoryState::RUNNING) {
- story2_state_after_run_.Pass();
- }
-
- TestStory2_DeleteStory();
- });
- }
-
- TestPoint story2_delete_{"Story2 Delete"};
-
- void TestStory2_DeleteStory() {
- puppet_master_->DeleteStory(story_info_.id,
- [this] { story2_delete_.Pass(); });
-
- story_provider()->GetStoryInfo(
- story_info_.id, [this](fuchsia::modular::StoryInfoPtr info) {
- TestStory2_InfoAfterDeleteIsNull(std::move(info));
- });
- }
-
- TestPoint story2_info_after_delete_{"Story2 Info After Delete"};
-
- void TestStory2_InfoAfterDeleteIsNull(fuchsia::modular::StoryInfoPtr info) {
- story2_info_after_delete_.Pass();
- if (info) {
- modular::testing::Fail("StoryInfo after DeleteStory() must return null.");
- }
-
- TestStory3();
- }
-
- // Test Case Story3:
- //
- // Verify that a "kind of proto" story doesn't appear in the list of stories
- // of the story provider.
-
- TestPoint story3_create_{"Story3 Create"};
-
- void TestStory3() {
- story_provider_state_watcher_.Reset();
- story_provider_state_watcher_.Watch(story_provider());
-
- puppet_master_->ControlStory("story3", story_puppet_master_.NewRequest());
-
- fuchsia::modular::StoryOptions story_options;
- story_options.kind_of_proto_story = true;
- story_puppet_master_->SetCreateOptions(std::move(story_options));
-
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story_provider_state_watcher_.SetKindOfProtoStory("story3");
- story3_create_.Pass();
- TestStory3_GetController("story3");
- });
- }
-
- TestPoint story3_get_controller_{"Story3 GetController"};
-
- void TestStory3_GetController(fidl::StringPtr story_id) {
- story_provider()->GetController(story_id, story_controller_.NewRequest());
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo story_info,
- fuchsia::modular::StoryState state) {
- story_info_ = std::move(story_info);
- story3_get_controller_.Pass();
- TestStory3_GetStories();
- });
- }
-
- TestPoint story3_previous_stories_{"Story3 GetGetStories"};
-
- void TestStory3_GetStories() {
- story_provider()->GetStories(
- nullptr, [this](std::vector<fuchsia::modular::StoryInfo> stories) {
- // Since this is a kind-of-proto story, it shouldn't appear in
- // GetStories calls. Note that we still expect 1 story to be here
- // since Story1 wasn't deleted.
- if (stories.size() == 1 && stories.at(0).id != story_info_.id) {
- story3_previous_stories_.Pass();
- } else {
- FXL_LOG(ERROR) << "StoryProvider.GetStories() " << stories.size();
- for (const auto& item : stories) {
- FXL_LOG(INFO) << item.id;
- }
- }
- TestStory3_Run();
- });
- }
-
- TestPoint story3_run_{"Story3 Run"};
-
- void TestStory3_Run() {
- story_controller_->RequestStart();
-
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- if (state == fuchsia::modular::StoryState::RUNNING) {
- story3_run_.Pass();
- }
-
- TestStory3_Stop();
- });
- }
-
- TestPoint story3_stop_{"Story3 Stop"};
-
- void TestStory3_Stop() {
- story_controller_->Stop([this] {
- TeardownStoryController();
- story3_stop_.Pass();
- TestStory3_DeleteStory();
- });
- }
-
- TestPoint story3_delete_{"Story3 Delete"};
-
- void TestStory3_DeleteStory() {
- puppet_master_->DeleteStory(story_info_.id,
- [this] { story3_delete_.Pass(); });
-
- story_provider()->GetStoryInfo(
- story_info_.id, [this](fuchsia::modular::StoryInfoPtr info) {
- TestStory3_InfoAfterDeleteIsNull(std::move(info));
- });
- }
-
- TestPoint story3_info_after_delete_{"Story3 InfoAfterDeleteIsNull"};
-
- void TestStory3_InfoAfterDeleteIsNull(fuchsia::modular::StoryInfoPtr info) {
- if (!info) {
- story3_info_after_delete_.Pass();
- }
-
- TestStory4();
- }
-
- // Test Case Story4:
- //
- // Create a story and start it with RequestStart() rather than Start().
- //
- // Verify the view is received through SessionShell.AttachView().
- //
- // Verify that, when the story is stopped, a request for
- // SessionShell.DetachView() is received.
-
- TestPoint story4_create_{"Story4 Create"};
-
- void TestStory4() {
- puppet_master_->ControlStory("story4", story_puppet_master_.NewRequest());
-
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("mod1");
- add_mod.intent.handler = kCommonNullModule;
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(std::move(command));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story4_create_.Pass();
- TestStory4_Run();
- });
- }
-
- TestPoint story4_state_before_run_{"Story4 State before Run"};
- TestPoint story4_state_after_run_{"Story4 State after Run"};
- TestPoint story4_attach_view_{"Story4 attach View"};
-
- void TestStory4_Run() {
- story_provider()->GetController("story4", story_controller_.NewRequest());
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- story_info_ = std::move(info);
- if (state == fuchsia::modular::StoryState::STOPPED) {
- story4_state_before_run_.Pass();
- }
- });
-
- // Start and show the new story using RequestStart().
- story_controller_->RequestStart();
-
- session_shell_impl()->set_on_attach_view(
- [this](ViewId) { story4_attach_view_.Pass(); });
-
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- if (state == fuchsia::modular::StoryState::RUNNING) {
- story4_state_after_run_.Pass();
- TestStory4_Stop();
- }
- });
- }
-
- TestPoint story4_detach_view_{"Story4 detach View"};
- TestPoint story4_stop_{"Story4 Stop"};
-
- void TestStory4_Stop() {
- session_shell_impl()->set_on_detach_view(
- [this](ViewId) { story4_detach_view_.Pass(); });
-
- story_controller_->Stop([this] {
- TeardownStoryController();
- story4_stop_.Pass();
-
- TestStory4_DeleteStory();
- });
- }
-
- TestPoint story4_delete_{"Story4 Delete"};
-
- void TestStory4_DeleteStory() {
- puppet_master_->DeleteStory(story_info_.id,
- [this] { story4_delete_.Pass(); });
-
- story_provider()->GetStoryInfo(
- story_info_.id, [this](fuchsia::modular::StoryInfoPtr info) {
- TestStory4_InfoAfterDeleteIsNull(std::move(info));
- });
- }
-
- TestPoint story4_info_after_delete_{"Story4 Info after Delete is null"};
-
- void TestStory4_InfoAfterDeleteIsNull(fuchsia::modular::StoryInfoPtr info) {
- if (!info) {
- story4_info_after_delete_.Pass();
- }
-
- TestStory5();
- }
-
- // Test Case Story5:
- //
- // Create a story and start it with RequestStart() rather than Start().
- //
- // Verify that, when the story is stopped, a request for
- // SessionShell.DetachView() is received, and if the request is not answered,
- // the Stop() request proceeds anyway.
-
- TestPoint story5_create_{"Story5 Create"};
-
- void TestStory5() {
- puppet_master_->ControlStory("story5", story_puppet_master_.NewRequest());
-
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("mod1");
- add_mod.intent.handler = kCommonNullModule;
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(std::move(command));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story5_create_.Pass();
- TestStory5_Run();
- });
- }
-
- TestPoint story5_state_before_run_{"Story5 State before Run"};
- TestPoint story5_state_after_run_{"Story5 State after Run"};
-
- TestPoint story5_attach_view_{"Story5 attach View"};
-
- void TestStory5_Run() {
- story_provider()->GetController("story5", story_controller_.NewRequest());
-
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- story_info_ = std::move(info);
- if (state == fuchsia::modular::StoryState::STOPPED) {
- story5_state_before_run_.Pass();
- }
- });
-
- // Start and show the new story using RequestStart().
- story_controller_->RequestStart();
-
- session_shell_impl()->set_on_attach_view(
- [this](ViewId) { story5_attach_view_.Pass(); });
-
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- if (state == fuchsia::modular::StoryState::RUNNING) {
- story5_state_after_run_.Pass();
- TestStory5_Stop();
- }
- });
- }
-
- TestPoint story5_stop_{"Story5 Stop"};
-
- void TestStory5_Stop() {
- // Ignore the detach view. The delay is larger than the timeout for the
- // whole test configured in dev_base_shell.cc, so an attempt to wait for
- // this timeout would fail the whole test.
- session_shell_impl()->set_detach_delay(
- zx::msec(modular::testing::kTestTimeoutMilliseconds * 2));
- session_shell_impl()->set_on_detach_view([](ViewId) {});
-
- story_controller_->Stop([this] {
- TeardownStoryController();
- story5_stop_.Pass();
-
- TestStory5_DeleteStory();
- });
- }
-
- TestPoint story5_delete_{"Story5 Delete"};
-
- void TestStory5_DeleteStory() {
- puppet_master_->DeleteStory(story_info_.id,
- [this] { story5_delete_.Pass(); });
-
- story_provider()->GetStoryInfo(
- story_info_.id, [this](fuchsia::modular::StoryInfoPtr info) {
- TestStory5_InfoAfterDeleteIsNull(std::move(info));
- });
- }
-
- TestPoint story5_info_after_delete_{"Story5 Info after Delete is null"};
-
- void TestStory5_InfoAfterDeleteIsNull(fuchsia::modular::StoryInfoPtr info) {
- if (!info) {
- story5_info_after_delete_.Pass();
- }
-
- TestStory6();
- }
-
- // Test Case Story6:
- //
- // Create a story and start it with RequestStart() rather than Start().
- //
- // Verify that, when the story is NOT stopped when the SessionShell is stopped
- // (such as at Logout) NO request for SessionShell.DetachView() is received.
-
- TestPoint story6_create_{"Story6 Create"};
-
- void TestStory6() {
- puppet_master_->ControlStory("story6", story_puppet_master_.NewRequest());
-
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("mod1");
- add_mod.intent.handler = kCommonNullModule;
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
-
- std::vector<fuchsia::modular::StoryCommand> commands;
- commands.push_back(std::move(command));
-
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story6_create_.Pass();
- TestStory6_Run();
- });
- }
-
- TestPoint story6_state_before_run_{"Story6 State before Run"};
- TestPoint story6_state_after_run_{"Story6 State after Run"};
-
- TestPoint story6_attach_view_{"Story6 attach View"};
-
- void TestStory6_Run() {
- story_provider()->GetController("story6", story_controller_.NewRequest());
-
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- story_info_ = std::move(info);
- if (state == fuchsia::modular::StoryState::STOPPED) {
- story6_state_before_run_.Pass();
- }
- });
-
- // Start and show the new story using RequestStart().
- story_controller_->RequestStart();
-
- session_shell_impl()->set_on_attach_view(
- [this](ViewId) { story6_attach_view_.Pass(); });
-
- story_controller_->GetInfo([this](fuchsia::modular::StoryInfo info,
- fuchsia::modular::StoryState state) {
- if (state == fuchsia::modular::StoryState::RUNNING) {
- story6_state_after_run_.Pass();
- TestStory6_Logout();
- }
- });
- }
-
- void TestStory6_Logout() {
- // If we get a DetachView() call during logout, that's a failure.
- session_shell_impl()->set_detach_delay(zx::sec(0));
- session_shell_impl()->set_on_detach_view(
- [](ViewId) { Fail("DetachView() Received on Logout"); });
-
- Signal(modular::testing::kTestShutdown);
- }
-
- void TeardownStoryController() { story_controller_.Unbind(); }
-
- StoryProviderStateWatcherImpl story_provider_state_watcher_;
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::ComponentContextPtr component_context_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- fuchsia::modular::StoryControllerPtr story_controller_;
- fuchsia::modular::LinkPtr session_shell_link_;
- fuchsia::modular::StoryInfo story_info_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int argc, const char** argv) {
- auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/sessionctl/BUILD.gn b/tests/sessionctl/BUILD.gn
deleted file mode 100644
index e137c12..0000000
--- a/tests/sessionctl/BUILD.gn
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-executable("sessionctl_test") {
- testonly = true
- output_name = "sessionctl_test"
-
- sources = [
- "sessionctl_test.cc",
- ]
-
- deps = [
- "//garnet/public/fidl/fuchsia.sys",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/lib/component/cpp",
- "//garnet/public/lib/component/cpp/testing",
- "//garnet/public/lib/fxl",
- "//garnet/public/lib/fxl/test:gtest_main",
- "//garnet/public/lib/test_runner/cpp",
- "//peridot/bin/sessionctl:lib",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/fidl/fuchsia.modular.internal",
- "//peridot/public/lib/integration_testing/cpp",
- "//third_party/googletest:gtest",
- ]
-}
-
-hermetic_tests_package("sessionctl_integration_tests") {
- deps = [
- ":sessionctl_test",
- ]
-}
diff --git a/tests/sessionctl/README.md b/tests/sessionctl/README.md
deleted file mode 100644
index 131b6ec..0000000
--- a/tests/sessionctl/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# sessionctl integration test
-
-This ensures that the sessionctl service can be found in /hub after `basemgr`
-is launched.
\ No newline at end of file
diff --git a/tests/sessionctl/meta/sessionctl_test.cmx b/tests/sessionctl/meta/sessionctl_test.cmx
deleted file mode 100644
index a4f4810..0000000
--- a/tests/sessionctl/meta/sessionctl_test.cmx
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "facets": {
- "fuchsia.test": {
- "injected-services": {
- "fuchsia.devicesettings.DeviceSettingsManager": "fuchsia-pkg://fuchsia.com/device_settings_manager#meta/device_settings_manager.cmx",
- "fuchsia.tracelink.Registry": "fuchsia-pkg://fuchsia.com/trace_manager#meta/trace_manager.cmx"
- }
- }
- },
- "program": {
- "binary": "test/sessionctl_test"
- },
- "sandbox": {
- "features": [
- "shell"
- ],
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ComponentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/sessionctl/sessionctl_test.cc b/tests/sessionctl/sessionctl_test.cc
deleted file mode 100644
index b6f762c..0000000
--- a/tests/sessionctl/sessionctl_test.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/modular/internal/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/async/default.h>
-
-#include "lib/component/cpp/environment_services_helper.h"
-#include "lib/component/cpp/testing/test_util.h"
-#include "lib/component/cpp/testing/test_with_environment.h"
-#include "lib/fxl/files/directory.h"
-#include "lib/fxl/files/file.h"
-#include "lib/fxl/files/glob.h"
-#include "lib/fxl/strings/join_strings.h"
-
-#include "gtest/gtest.h"
-#include "peridot/bin/sessionctl/session_ctl_constants.h"
-
-namespace sessionctl {
-
-class SessionCtlTest : public component::testing::TestWithEnvironment {
- protected:
- void RunBasemgr() {
- std::vector<std::string> args;
- args.push_back("--test");
- args.push_back("--run_base_shell_with_test_runner=false");
- args.push_back(
- "--account_provider=fuchsia-pkg://fuchsia.com/dev_token_manager#meta/"
- "dev_token_manager.cmx");
- args.push_back(
- "--base_shell=fuchsia-pkg://fuchsia.com/dev_base_shell#meta/"
- "dev_base_shell.cmx");
- args.push_back(
- "--session_shell=fuchsia-pkg://fuchsia.com/dev_session_shell#meta/"
- "dev_session_shell.cmx");
- args.push_back(
- "--story_shell=fuchsia-pkg://fuchsia.com/dev_story_shell#meta/"
- "dev_story_shell.cmx");
- args.push_back("--sessionmgr_args=--use_memfs_for_ledger");
-
- RunComponent("fuchsia-pkg://fuchsia.com/basemgr#meta/basemgr.cmx", args);
- }
-
- void RunComponent(const std::string& component_url,
- const std::vector<std::string>& args) {
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url = component_url;
- for (auto arg : args) {
- launch_info.arguments.push_back(arg);
- }
-
- fuchsia::sys::ComponentControllerPtr controller;
- launcher_ptr()->CreateComponent(std::move(launch_info),
- controller.NewRequest());
- component_ptrs_.push_back(std::move(controller));
-
- RunLoopWithTimeout(zx::sec(10));
- }
-
- std::vector<fuchsia::sys::ComponentControllerPtr> component_ptrs_;
-};
-
-TEST_F(SessionCtlTest, FindSessionCtlService) {
- RunBasemgr();
-
- files::Glob sessionctl_service(modular::kSessionCtlServiceGlobPath);
- EXPECT_EQ(sessionctl_service.size(), 1u)
- << modular::kSessionCtlServiceGlobPath << " expected to match once.";
-}
-
-} // namespace sessionctl
diff --git a/tests/story_shell/BUILD.gn b/tests/story_shell/BUILD.gn
deleted file mode 100644
index 0fb4401..0000000
--- a/tests/story_shell/BUILD.gn
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("story_shell_test_story_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/story_shell_test_story_shell.cmx"
- dest = "story_shell_test_story_shell.cmx"
- },
- ]
-
- sources = [
- "story_shell_test_story_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/common:names",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- ]
-}
-
-executable_package("story_shell_test_session_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/story_shell_test_session_shell.cmx"
- dest = "story_shell_test_session_shell.cmx"
- },
- ]
-
- sources = [
- "story_shell_test_session_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/fidl/fuchsia.ui.policy",
- "//garnet/public/fidl/fuchsia.ui.viewsv1",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fsl",
- "//garnet/public/lib/fxl",
- "//peridot/lib/common:names",
- "//peridot/lib/fidl:array_to_string",
- "//peridot/lib/fidl:clone",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- ]
-}
diff --git a/tests/story_shell/README.md b/tests/story_shell/README.md
deleted file mode 100644
index 7465558..0000000
--- a/tests/story_shell/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# story_shell test
-
-This test executes the story shell. Below is the sequence of actions and
-verifications. All actions and verifications are driven by the session shell. The
-story shell just responds.
-
-* Create a story and start it.
-* Verify the contents of the link. The first time the story shell is created the
- link content is empty. If the content is empty, write to the link and verify
- those contents when the story shell is restarted.
-* Add a top level module to the story. The module is specified by an intent. The
- intent is resolved to a module that possesses a manifest. The manifest
- specifies a composition pattern.
-* We verify that the story shell receives the notification that the module has
- started, including the manifest.
-* Stop the story. Start the story again.
-* We verify that the story shell receives the same notification about the
- started module as before, including the manifest.
-
-We also verify that the story receives the manifest regardless of how the intent
-we use to add the module is resolved, i.e. regardless of whether it specifies
-the action or the package of the module. For that, we run the whole sequence
-above again, but use intents that specify handlers rather than actions to add
-the modules.
-
-For each event we would like to verify, the story shell writes to TestStore
-using Put(). The session shell uses Get() to register handlers for the keys it
-expects the story shell to Put(), and continues when it has seen all the keys.
diff --git a/tests/story_shell/defs.h b/tests/story_shell/defs.h
deleted file mode 100644
index 232d015..0000000
--- a/tests/story_shell/defs.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_STORY_SHELL_DEFS_H_
-#define PERIDOT_TESTS_STORY_SHELL_DEFS_H_
-
-namespace {
-
-// URLs of the modules used here.
-
-} // namespace
-
-#endif // PERIDOT_TESTS_STORY_SHELL_DEFS_H_
diff --git a/tests/story_shell/meta/story_shell_test_session_shell.cmx b/tests/story_shell/meta/story_shell_test_session_shell.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/story_shell/meta/story_shell_test_session_shell.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/story_shell/meta/story_shell_test_story_shell.cmx b/tests/story_shell/meta/story_shell_test_story_shell.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/story_shell/meta/story_shell_test_story_shell.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/story_shell/story_shell_test_session_shell.cc b/tests/story_shell/story_shell_test_session_shell.cc
deleted file mode 100644
index 5395d03..0000000
--- a/tests/story_shell/story_shell_test_session_shell.cc
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <set>
-#include <utility>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-#include <lib/fxl/tasks/task_runner.h>
-#include <lib/fxl/time/time_delta.h>
-
-#include "peridot/lib/common/names.h"
-#include "peridot/lib/fidl/clone.h"
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/story_shell/defs.h"
-
-using modular::testing::Get;
-using modular::testing::Put;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-const char kStoryName1[] = "story1";
-const char kStoryName2[] = "story2";
-
-// Cf. README.md for what this test does and how.
-class TestApp : public modular::testing::SessionShellBase,
- fuchsia::modular::SessionShellPresentationProvider {
- public:
- explicit TestApp(component::StartupContext* const startup_context)
- : SessionShellBase(startup_context) {
- TestInit(__FILE__);
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
-
- startup_context->outgoing()
- .AddPublicService<fuchsia::modular::SessionShellPresentationProvider>(
- [this](fidl::InterfaceRequest<
- fuchsia::modular::SessionShellPresentationProvider>
- request) {
- presentation_provider_bindings_.AddBinding(this,
- std::move(request));
- });
-
- Story1_Create();
- }
-
- ~TestApp() override = default;
-
- private:
- TestPoint story1_presentation_request_{"Story1 Presentation request"};
- bool story1_presentation_request_received_{};
-
- TestPoint story2_presentation_request_{"Story2 Presentation request"};
- bool story2_presentation_request_received_{};
-
- // |fuchsia::modular::SessionShellPresentationProvider|
- void GetPresentation(std::string story_id,
- fidl::InterfaceRequest<fuchsia::ui::policy::Presentation>
- request) override {
- if (story_id == kStoryName1 && !story1_presentation_request_received_) {
- story1_presentation_request_.Pass();
- story1_presentation_request_received_ = true;
- }
-
- if (story_id == kStoryName2 && !story2_presentation_request_received_) {
- story2_presentation_request_.Pass();
- story2_presentation_request_received_ = true;
- }
-
- MaybeLogout();
- }
-
- // |fuchsia::modular::SessionShellPresentationProvider|
- void WatchVisualState(
- std::string story_id,
- fidl::InterfaceHandle<fuchsia::modular::StoryVisualStateWatcher> watcher)
- override {}
-
- TestPoint create_view_{"CreateView()"};
-
- // |SingleServiceApp|
- void CreateView(
- zx::eventpair /*view_token*/,
- fidl::InterfaceRequest<
- fuchsia::sys::ServiceProvider> /*incoming_services*/,
- fidl::InterfaceHandle<
- fuchsia::sys::ServiceProvider> /*outgoing_services*/) override {
- create_view_.Pass();
- }
-
- TestPoint story1_create_{"Story1 Create"};
-
- void Story1_Create() {
- std::vector<fuchsia::modular::StoryCommand> commands;
- auto addMod = [&commands](fidl::StringPtr name,
- std::vector<fidl::StringPtr> parent) {
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back(name);
- add_mod.intent.action = kCommonNullAction;
- add_mod.intent.handler = kCommonNullModule;
-
- for (auto i : parent) {
- add_mod.surface_parent_mod_name.push_back(i);
- }
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
- };
-
- addMod("root", {});
- addMod("one", {"root"});
- addMod("two", {"root", "one"});
-
- puppet_master_->ControlStory(kStoryName1,
- story_puppet_master_.NewRequest());
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story1_create_.Pass();
- Story1_Run1();
- });
- }
-
- TestPoint story1_run1_{"Story1 Run1"};
-
- void Story1_Run1() {
- story_provider()->GetController(kStoryName1, story_controller_.NewRequest());
-
- // TODO(jphsiao|vardhan): remodel this |proceed_after_6| style of
- // continuation to use Futures instead.
- auto proceed_after_6 = modular::testing::NewBarrierClosure(6, [this] {
- story1_run1_.Pass();
- Story1_Stop1();
- });
-
- Get("story link data: null", proceed_after_6);
- Get("root:one", proceed_after_6);
- Get("root:one manifest", proceed_after_6);
- Get("root:one:two", proceed_after_6);
- Get("root:one:two manifest", proceed_after_6);
- Get("root:one:two ordering", proceed_after_6);
-
- story_controller_->RequestStart();
- }
-
- void Story1_Stop1() {
- story_controller_->Stop([this] { Story1_Run2(); });
- }
-
- TestPoint story1_run2_{"Story1 Run2"};
-
- void Story1_Run2() {
- auto proceed_after_6 = modular::testing::NewBarrierClosure(6, [this] {
- story1_run2_.Pass();
- Story1_Stop2();
- });
-
- Get("story link data: {\"label\":\"value\"}", proceed_after_6);
- Get("root:one", proceed_after_6);
- Get("root:one manifest", proceed_after_6);
- Get("root:one:two", proceed_after_6);
- Get("root:one:two manifest", proceed_after_6);
- Get("root:one:two ordering", proceed_after_6);
-
- story_controller_->RequestStart();
- }
-
- void Story1_Stop2() {
- story_controller_->Stop([this] { Story2_Create(); });
- }
-
- // We do the same sequence with Story2 that we did for Story1, except that the
- // modules are started with packages rather than actions in their Intents.
-
- TestPoint story2_create_{"Story2 Create"};
-
- void Story2_Create() {
- std::vector<fuchsia::modular::StoryCommand> commands;
- auto addMod = [&commands](fidl::StringPtr name,
- std::vector<fidl::StringPtr> parent) {
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back(name);
- add_mod.intent.action = kCommonNullAction;
- add_mod.intent.handler = kCommonNullModule;
-
- for (auto i : parent) {
- add_mod.surface_parent_mod_name.push_back(i);
- }
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
- };
-
- addMod("root", {});
- addMod("one", {"root"});
- addMod("two", {"root", "one"});
-
- puppet_master_->ControlStory(kStoryName2,
- story_puppet_master_.NewRequest());
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story2_create_.Pass();
- Story2_Run1();
- });
- }
-
- TestPoint story2_run1_{"Story2 Run1"};
-
- void Story2_Run1() {
- auto proceed_after_5 = modular::testing::NewBarrierClosure(5, [this] {
- story2_run1_.Pass();
- Story2_Stop1();
- });
-
- Get("root:one", proceed_after_5);
- Get("root:one manifest", proceed_after_5);
- Get("root:one:two", proceed_after_5);
- Get("root:one:two manifest", proceed_after_5);
- Get("root:one:two ordering", proceed_after_5);
-
- story_provider()->GetController(kStoryName2, story_controller_.NewRequest());
- story_controller_->RequestStart();
- }
-
- void Story2_Stop1() {
- story_controller_->Stop([this] { Story2_Run2(); });
- }
-
- TestPoint story2_run2_{"Story2 Run2"};
-
- void Story2_Run2() {
- auto proceed_after_5 = modular::testing::NewBarrierClosure(5, [this] {
- story2_run2_.Pass();
- Story2_Stop2();
- });
-
- Get("root:one", proceed_after_5);
- Get("root:one manifest", proceed_after_5);
- Get("root:one:two", proceed_after_5);
- Get("root:one:two manifest", proceed_after_5);
- Get("root:one:two ordering", proceed_after_5);
-
- story_controller_->RequestStart();
- }
-
- bool end_of_story2_{};
-
- void Story2_Stop2() {
- story_controller_->Stop([this] {
- end_of_story2_ = true;
- MaybeLogout();
- });
- }
-
- void MaybeLogout() {
- if (story1_presentation_request_received_ &&
- story2_presentation_request_received_ && end_of_story2_) {
- Signal(modular::testing::kTestShutdown);
- }
- }
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- fuchsia::modular::StoryControllerPtr story_controller_;
- fidl::BindingSet<fuchsia::modular::SessionShellPresentationProvider>
- presentation_provider_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /* argc */, const char** /* argv */) {
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/story_shell/story_shell_test_story_shell.cc b/tests/story_shell/story_shell_test_story_shell.cc
deleted file mode 100644
index 5480949..0000000
--- a/tests/story_shell/story_shell_test_story_shell.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implementation of the fuchsia::modular::StoryShell service that just lays out
-// the views of all modules side by side.
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/policy/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/app_driver/cpp/app_driver.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fsl/vmo/strings.h>
-#include <lib/fxl/command_line.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/rapidjson/rapidjson.h"
-#include "peridot/lib/testing/component_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/story_shell/defs.h"
-#include "rapidjson/document.h"
-
-using modular::testing::Signal;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestApp
- : public modular::testing::ComponentBase<fuchsia::modular::StoryShell> {
- public:
- TestApp(component::StartupContext* const startup_context)
- : ComponentBase(startup_context) {
- TestInit(__FILE__);
- }
-
- ~TestApp() override = default;
-
- private:
- // |fuchsia::modular::StoryShell|
- void Initialize(fidl::InterfaceHandle<fuchsia::modular::StoryShellContext>
- story_shell_context) override {
- story_shell_context_.Bind(std::move(story_shell_context));
- story_shell_context_->GetPresentation(presentation_.NewRequest());
- story_shell_context_->GetLink(story_shell_link_.NewRequest());
- fidl::VectorPtr<std::string> link_path;
- link_path.push_back("path");
-
- story_shell_link_->Get(
- link_path.Clone(),
- [this](std::unique_ptr<fuchsia::mem::Buffer> content) {
- std::string data_string;
- fsl::StringFromVmo(*content, &data_string);
- Signal("story link data: " + data_string);
-
- rapidjson::Document document;
- document.SetObject();
- document.AddMember("label", "value", document.GetAllocator());
- fsl::SizedVmo vmo;
- fidl::VectorPtr<std::string> path_to_write;
- path_to_write.push_back("path");
- fsl::VmoFromString(modular::JsonValueToString(document), &vmo);
- fuchsia::mem::Buffer buffer = std::move(vmo).ToTransport();
- story_shell_link_->Set(path_to_write.Clone(), std::move(buffer));
- });
- }
-
- // Keep state to check ordering. Cf. below.
- bool seen_root_one_{};
-
- // |fuchsia::modular::StoryShell|
- void AddSurface(
- fuchsia::modular::ViewConnection view_connection,
- fuchsia::modular::SurfaceInfo surface_info) override {
- fuchsia::modular::ModuleManifestPtr module_manifest = std::move(surface_info.module_manifest);
- FXL_LOG(INFO) << "AddSurface " << view_connection.surface_id << " " << surface_info.parent_id << " "
- << (module_manifest ? module_manifest->composition_pattern
- : " NO MANIFEST");
- if (view_connection.surface_id == "root:one" && surface_info.parent_id == "root") {
- Signal("root:one");
-
- if (module_manifest && module_manifest->composition_pattern == "ticker" &&
- module_manifest->intent_filters->size() == 1 &&
- module_manifest->intent_filters.get()[0].action ==
- kCommonNullAction) {
- Signal("root:one manifest");
- }
-
- seen_root_one_ = true;
- }
-
- if (view_connection.surface_id == "root:one:two" && surface_info.parent_id == "root:one") {
- Signal("root:one:two");
-
- if (module_manifest && module_manifest->composition_pattern == "ticker" &&
- module_manifest->intent_filters->size() == 1 &&
- module_manifest->intent_filters.get()[0].action ==
- kCommonNullAction) {
- Signal("root:one:two manifest");
- }
-
- if (seen_root_one_) {
- Signal("root:one:two ordering");
- }
- }
- }
-
- // |fuchsia::modular::StoryShell|
- void FocusSurface(std::string /*surface_id*/) override {}
-
- // |fuchsia::modular::StoryShell|
- void DefocusSurface(std::string /*surface_id*/,
- DefocusSurfaceCallback callback) override {
- callback();
- }
-
- // |fuchsia::modular::StoryShell|
- void AddContainer(
- std::string /*container_name*/, fidl::StringPtr /*parent_id*/,
- fuchsia::modular::SurfaceRelation /*relation*/,
- std::vector<fuchsia::modular::ContainerLayout> /*layout*/,
- std::vector<
- fuchsia::modular::ContainerRelationEntry> /* relationships */,
- std::vector<fuchsia::modular::ContainerView> /* views */) override {}
-
- // |fuchsia::modular::StoryShell|
- void RemoveSurface(std::string /*surface_id*/) override {}
-
- // |fuchsia::modular::StoryShell|
- void ReconnectView(fuchsia::modular::ViewConnection view_connection) override {}
-
- // |fuchsia::modular::StoryShell|
- void UpdateSurface(fuchsia::modular::ViewConnection view_connection,
- fuchsia::modular::SurfaceInfo /*surface_info*/) override {};
-
-
- fuchsia::modular::StoryShellContextPtr story_shell_context_;
- fuchsia::modular::LinkPtr story_shell_link_;
- fuchsia::ui::policy::PresentationPtr presentation_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /* argc */, const char** /* argv */) {
- FXL_LOG(INFO) << "Story Shell main";
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/suggestion/BUILD.gn b/tests/suggestion/BUILD.gn
deleted file mode 100644
index 675109b..0000000
--- a/tests/suggestion/BUILD.gn
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("suggestion_test_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/suggestion_test_module.cmx"
- dest = "suggestion_test_module.cmx"
- },
- ]
-
- sources = [
- "suggestion_test_module.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/lib/callback",
- "//peridot/lib/testing:component_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("suggestion_test_session_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/suggestion_test_session_shell.cmx"
- dest = "suggestion_test_session_shell.cmx"
- },
- ]
-
- sources = [
- "suggestion_test_session_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- ]
-}
diff --git a/tests/suggestion/README.md b/tests/suggestion/README.md
deleted file mode 100644
index 24d44b7..0000000
--- a/tests/suggestion/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# suggestion integration test
-
-This test exercises the API exposed to Modules to make suggestion proposals. It
-verifies that a suggestion proposal made by a module can be received by the user
-shell eventually.
diff --git a/tests/suggestion/defs.h b/tests/suggestion/defs.h
deleted file mode 100644
index 03aa224..0000000
--- a/tests/suggestion/defs.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_SUGGESTION_DEFS_H_
-#define PERIDOT_TESTS_SUGGESTION_DEFS_H_
-
-namespace {
-
-// Package URLs of the test components used here.
-constexpr char kSuggestionTestModule[] =
- "fuchsia-pkg://fuchsia.com/suggestion_test_module#meta/suggestion_test_module.cmx";
-
-constexpr char kSuggestionTestAction[] = "suggestion_test_action";
-
-constexpr char kSuggestionTestModuleDone[] = "suggestion_test_module_done";
-
-constexpr char kProposalId[] =
- "file:///system/bin/modular_tests/suggestion_proposal_test#proposal";
-
-} // namespace
-
-#endif // PERIDOT_TESTS_SUGGESTION_DEFS_H_
diff --git a/tests/suggestion/meta/suggestion_test_module.cmx b/tests/suggestion/meta/suggestion_test_module.cmx
deleted file mode 100644
index 7efcca5..0000000
--- a/tests/suggestion/meta/suggestion_test_module.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.IntelligenceServices",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/suggestion/meta/suggestion_test_session_shell.cmx b/tests/suggestion/meta/suggestion_test_session_shell.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/suggestion/meta/suggestion_test_session_shell.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/suggestion/suggestion_test_module.cc b/tests/suggestion/suggestion_test_module.cc
deleted file mode 100644
index 62a0757..0000000
--- a/tests/suggestion/suggestion_test_module.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/component/cpp/connect.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/suggestion/defs.h"
-
-using modular::testing::Await;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule : fuchsia::modular::ProposalListener {
- public:
- TestPoint initialized_{"Root module initialized"};
- TestPoint received_story_id_{"Root module received story id"};
- TestPoint proposal_was_accepted_{"fuchsia::modular::Proposal was accepted"};
-
- TestModule(modular::ModuleHost* module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>
- view_provider_request)
- : module_host_(module_host),
- app_view_provider_(std::move(view_provider_request)) {
- modular::testing::Init(module_host_->startup_context(), __FILE__);
- initialized_.Pass();
-
- fuchsia::modular::IntelligenceServicesPtr intelligence_services;
-
- module_host_->startup_context()->ConnectToEnvironmentService(
- intelligence_services.NewRequest());
- intelligence_services->GetProposalPublisher(
- proposal_publisher_.NewRequest());
-
- module_host_->module_context()->GetStoryId(
- [this](const fidl::StringPtr& story_id) {
- received_story_id_.Pass();
-
- fuchsia::modular::SetFocusState focus_story;
- focus_story.focused = true;
-
- fuchsia::modular::StoryCommand command;
- command.set_set_focus_state(std::move(focus_story));
-
- // Craft a minimal suggestion proposal.
- fuchsia::modular::SuggestionDisplay suggestion_display;
- suggestion_display.headline = "foo";
- suggestion_display.subheadline = "bar";
- suggestion_display.details = "baz";
- suggestion_display.color = 0xffff0000;
-
- fuchsia::modular::Proposal proposal;
- proposal.id = kProposalId;
- proposal.affinity.resize(0);
- proposal.story_name = story_id;
- proposal.display = std::move(suggestion_display);
- proposal.on_selected.push_back(std::move(command));
- proposal_listener_bindings_.AddBinding(
- this, proposal.listener.NewRequest());
-
- proposal_publisher_->Propose(std::move(proposal));
-
- Await("suggestion_proposal_received", [this] {
- Await("proposal_was_accepted", [this] {
- proposal_was_accepted_.Pass();
- Signal(kSuggestionTestModuleDone);
- });
- });
- });
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- view_provider_request)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {
- views1_view_provider_ = std::move(view_provider_request);
- }
-
- // Called by ModuleDriver.
- TestPoint stopped_{"Root module stopped"};
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- // |fuchsia::modular::ProposalListener|
- void OnProposalAccepted(std::string proposal_id,
- fidl::StringPtr story_id) override {
- Signal("proposal_was_accepted");
- }
-
- private:
- modular::ModuleHost* const module_host_;
- fuchsia::modular::ModuleContextPtr module_context_;
- fuchsia::modular::ProposalPublisherPtr proposal_publisher_;
- fidl::BindingSet<fuchsia::modular::ProposalListener>
- proposal_listener_bindings_;
-
- // We keep the view provider around so that story shell can hold a view for
- // us, but don't do anything with it.
- fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>
- views1_view_provider_;
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> app_view_provider_;
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/suggestion/suggestion_test_session_shell.cc b/tests/suggestion/suggestion_test_session_shell.cc
deleted file mode 100644
index 1f1ec76..0000000
--- a/tests/suggestion/suggestion_test_session_shell.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fidl/cpp/binding_set.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/suggestion/defs.h"
-
-using modular::testing::Await;
-using modular::testing::Signal;
-using modular::testing::TestPoint;
-
-namespace {
-
-const char kStoryName[] = "story";
-
-// Cf. README.md for what this test does and how.
-class TestApp : fuchsia::modular::NextListener,
- public modular::testing::SessionShellBase {
- public:
- TestApp(component::StartupContext* const startup_context)
- : SessionShellBase(startup_context) {
- TestInit(__FILE__);
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
-
- session_shell_context()->GetSuggestionProvider(
- suggestion_provider_.NewRequest());
-
- suggestion_provider_->SubscribeToNext(
- suggestion_listener_bindings_.AddBinding(this),
- 20 /* arbitrarily chosen */);
-
- CreateStory();
- }
-
- ~TestApp() override = default;
-
- private:
- void CreateStory() {
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("root");
- add_mod.intent.action = kSuggestionTestAction;
- add_mod.intent.handler = kSuggestionTestModule;
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
-
- puppet_master_->ControlStory(kStoryName, story_puppet_master_.NewRequest());
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) { StartStory(); });
-
- Await(kSuggestionTestModuleDone, [this] {
- story_controller_->Stop([this] {
- story_controller_.Unbind();
- Signal(modular::testing::kTestShutdown);
- });
- });
- }
-
- void StartStory() {
- story_provider()->GetController(kStoryName, story_controller_.NewRequest());
- story_controller_.set_error_handler([](zx_status_t status) {
- FXL_LOG(ERROR) << "Story controller for story " << kStoryName
- << " died. Does this story exist?";
- });
- story_controller_->RequestStart();
- }
-
- TestPoint received_suggestion_{
- "SuggestionTestSessionShell received suggestion"};
-
- // |fuchsia::modular::NextListener|
- void OnNextResults(
- std::vector<fuchsia::modular::Suggestion> suggestions) override {
- for (auto& suggestion : suggestions) {
- auto& display = suggestion.display;
- if (display.headline == "foo" && display.subheadline == "bar" &&
- display.details == "baz") {
- modular::testing::GetStore()->Put("suggestion_proposal_received", "",
- [] {});
- received_suggestion_.Pass();
- fuchsia::modular::Interaction interaction;
- interaction.type = fuchsia::modular::InteractionType::SELECTED;
- suggestion_provider_->NotifyInteraction(suggestion.uuid, interaction);
- break;
- }
- }
- }
-
- // |fuchsia::modular::NextListener|
- void OnProcessingChange(bool processing) override {}
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- fuchsia::modular::StoryControllerPtr story_controller_;
- fuchsia::modular::SuggestionProviderPtr suggestion_provider_;
- fidl::BindingSet<fuchsia::modular::NextListener>
- suggestion_listener_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/tests/trigger/BUILD.gn b/tests/trigger/BUILD.gn
deleted file mode 100644
index beca454..0000000
--- a/tests/trigger/BUILD.gn
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/fidl/fidl.gni")
-import("//peridot/build/executable_package.gni")
-
-source_set("defs") {
- testonly = true
-
- sources = [
- "defs.h",
- ]
-}
-
-executable_package("trigger_test_session_shell") {
- testonly = true
-
- meta = [
- {
- path = "meta/trigger_test_session_shell.cmx"
- dest = "trigger_test_session_shell.cmx"
- },
- ]
-
- sources = [
- "trigger_test_session_shell.cc",
- ]
-
- deps = [
- ":defs",
- "//garnet/public/fidl/fuchsia.testing.runner",
- "//garnet/public/lib/callback",
- "//garnet/public/lib/fidl/cpp",
- "//garnet/public/lib/fxl",
- "//peridot/lib/rapidjson",
- "//peridot/lib/testing:component_main",
- "//peridot/lib/testing:session_shell_base",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- ]
-}
-
-executable_package("trigger_test_module") {
- testonly = true
-
- meta = [
- {
- path = "meta/trigger_test_module.cmx"
- dest = "trigger_test_module.cmx"
- },
- ]
-
- sources = [
- "trigger_test_module.cc",
- ]
-
- deps = [
- ":defs",
- ":trigger_test_service",
- "//garnet/public/lib/callback",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:module_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/public/lib/message_queue/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-executable_package("trigger_test_agent") {
- testonly = true
-
- meta = [
- {
- path = "meta/trigger_test_agent.cmx"
- dest = "trigger_test_agent.cmx"
- },
- ]
-
- sources = [
- "trigger_test_agent.cc",
- ]
-
- deps = [
- ":defs",
- ":trigger_test_service",
- "//peridot/public/fidl/fuchsia.modular",
- "//peridot/public/lib/app_driver/cpp:agent_driver",
- "//peridot/public/lib/integration_testing/cpp",
- "//peridot/tests/common:defs",
- "//zircon/public/lib/async-loop-cpp",
- ]
-}
-
-fidl("trigger_test_service") {
- cpp_legacy_callbacks = true
-
- name = "test.peridot.tests.trigger"
-
- sources = [
- "trigger_test_service.fidl",
- ]
-}
diff --git a/tests/trigger/README.md b/tests/trigger/README.md
deleted file mode 100644
index 62ad5b3..0000000
--- a/tests/trigger/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# trigger integration test
-
-This test verifies that Agents are woken up on triggers for:
- 1. New messages on a queue.
- 2. An explicitly deleted message queue.
- 3. A message queue being deleted as part of story tear down.
-
-The general structure of the test is a session shell is created, which
-in turn creates a story and adds the test module to it.
-
-The test module then verifies (1) and (2) by interacting with the
-test agent. It also creates a message queue that it does not delete
-explicitly and hands the token to the session shell.
-
-Once (1) and (2) have been verified, the session shell deletes the story
-and waits for the token it was handed by the module to appear in the
-test store. This signals that the agent was woken by the deletion trigger
-for that queue.
diff --git a/tests/trigger/defs.h b/tests/trigger/defs.h
deleted file mode 100644
index 11a4a37..0000000
--- a/tests/trigger/defs.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PERIDOT_TESTS_TRIGGER_DEFS_H_
-#define PERIDOT_TESTS_TRIGGER_DEFS_H_
-
-namespace {
-
-// This is how long we wait for the test to finish before we timeout and tear
-// down our test.
-constexpr int kTimeoutMilliseconds = 10000;
-
-// Package URLs of the test components used here.
-constexpr char kTestAgent[] =
- "fuchsia-pkg://fuchsia.com/trigger_test_agent#meta/trigger_test_agent.cmx";
-
-const char kModuleUrl[] =
- "fuchsia-pkg://fuchsia.com/trigger_test_module#meta/trigger_test_module.cmx";
-
-const char kModuleAction[] = "trigger_test_action";
-
-} // namespace
-
-#endif // PERIDOT_TESTS_TRIGGER_DEFS_H_
diff --git a/tests/trigger/meta/trigger_test_agent.cmx b/tests/trigger/meta/trigger_test_agent.cmx
deleted file mode 100644
index 12bf3ba..0000000
--- a/tests/trigger/meta/trigger_test_agent.cmx
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.AgentContext",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/trigger/meta/trigger_test_module.cmx b/tests/trigger/meta/trigger_test_module.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/trigger/meta/trigger_test_module.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/trigger/meta/trigger_test_session_shell.cmx b/tests/trigger/meta/trigger_test_session_shell.cmx
deleted file mode 100644
index 5d578b5..0000000
--- a/tests/trigger/meta/trigger_test_session_shell.cmx
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "program": {
- "binary": "bin/app"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.modular.ModuleContext",
- "fuchsia.modular.PuppetMaster",
- "fuchsia.modular.SessionShellContext",
- "fuchsia.sys.Environment",
- "fuchsia.sys.Launcher",
- "fuchsia.sys.Loader",
- "fuchsia.testing.runner.TestRunner",
- "fuchsia.testing.runner.TestRunnerStore",
- "fuchsia.tracelink.Registry",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.ui.viewsv1.ViewManager",
- "fuchsia.ui.viewsv1.ViewSnapshot"
- ]
- }
-}
diff --git a/tests/trigger/trigger_test_agent.cc b/tests/trigger/trigger_test_agent.cc
deleted file mode 100644
index 2ac9cb3..0000000
--- a/tests/trigger/trigger_test_agent.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/agent_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/fxl/logging.h>
-#include <test/peridot/tests/trigger/cpp/fidl.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/trigger/defs.h"
-
-using ::modular::testing::TestPoint;
-using ::test::peridot::tests::trigger::TriggerTestService;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestApp : TriggerTestService {
- public:
- TestPoint initialized_{"Trigger test agent initialized"};
-
- TestApp(modular::AgentHost* const agent_host)
- : agent_context_(agent_host->agent_context()) {
- modular::testing::Init(agent_host->startup_context(), __FILE__);
- agent_context_->GetComponentContext(component_context_.NewRequest());
-
- // Create a message queue and schedule a task to be run on receiving a
- // message on it. This message queue is passed to the module.
- component_context_->ObtainMessageQueue("Trigger Queue",
- msg_queue_.NewRequest());
- fuchsia::modular::TaskInfo task_info;
- task_info.task_id = "message_queue_message";
- task_info.trigger_condition.set_message_on_queue("Trigger Queue");
- task_info.persistent = true;
- agent_host->agent_context()->ScheduleTask(std::move(task_info));
-
- agent_services_.AddService<TriggerTestService>(
- [this](fidl::InterfaceRequest<TriggerTestService> request) {
- service_bindings_.AddBinding(this, std::move(request));
- });
-
- initialized_.Pass();
- }
-
- // Called by AgentDriver.
- void Connect(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services) {
- agent_services_.AddBinding(std::move(services));
- modular::testing::GetStore()->Put("trigger_test_agent_connected", "",
- [] {});
- }
-
- // Called by AgentDriver.
- void RunTask(fidl::StringPtr task_id, const std::function<void()>& callback) {
- modular::testing::GetStore()->Put(task_id, "", callback);
- }
-
- // Called by AgentDriver.
- void Terminate(const std::function<void()>& done) {
- modular::testing::GetStore()->Put("trigger_test_agent_stopped", "",
- [done] { done(); });
- modular::testing::Done(done);
- }
-
- private:
- // |TriggerTestService|
- void GetMessageQueueToken(GetMessageQueueTokenCallback callback) override {
- msg_queue_->GetToken(
- [callback](fidl::StringPtr token) { callback(token); });
- }
-
- // |TriggerTestService|
- void ObserveMessageQueueDeletion(std::string queue_token) override {
- fuchsia::modular::TaskInfo task_info;
- task_info.task_id = queue_token;
- task_info.trigger_condition.set_queue_deleted(queue_token);
- task_info.persistent = true;
- agent_context_->ScheduleTask(std::move(task_info));
- modular::testing::GetStore()->Put("trigger_test_agent_token_received", "",
- [] {});
- }
-
- component::ServiceNamespace agent_services_;
-
- fuchsia::modular::ComponentContextPtr component_context_;
- fuchsia::modular::AgentContext* const agent_context_;
- fuchsia::modular::MessageQueuePtr msg_queue_;
-
- fidl::BindingSet<TriggerTestService> service_bindings_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::AgentDriver<TestApp> driver(context.get(), [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/trigger/trigger_test_module.cc b/tests/trigger/trigger_test_module.cc
deleted file mode 100644
index 53fdaec..0000000
--- a/tests/trigger/trigger_test_module.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <lib/app_driver/cpp/module_driver.h>
-#include <lib/async-loop/cpp/loop.h>
-#include <lib/async/cpp/task.h>
-#include <lib/async/default.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/message_queue/cpp/message_sender_client.h>
-#include <test/peridot/tests/trigger/cpp/fidl.h>
-
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/trigger/defs.h"
-
-using ::modular::testing::Await;
-using ::modular::testing::Signal;
-using ::modular::testing::TestPoint;
-using ::test::peridot::tests::trigger::TriggerTestServicePtr;
-
-namespace {
-
-// Cf. README.md for what this test does and how.
-class TestModule {
- public:
- TestPoint initialized_{"Root module initialized"};
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::app::ViewProvider> /*view_provider_request*/) {
- modular::testing::Init(module_host->startup_context(), __FILE__);
- initialized_.Pass();
-
- // Exercise fuchsia::modular::ComponentContext.ConnectToAgent()
- module_host->module_context()->GetComponentContext(
- component_context_.NewRequest());
-
- fuchsia::sys::ServiceProviderPtr agent_services;
- component_context_->ConnectToAgent(kTestAgent, agent_services.NewRequest(),
- agent_controller_.NewRequest());
- component::ConnectToService(agent_services.get(),
- agent_service_.NewRequest());
-
- // The message queue that is used to verify deletion triggers from explicit
- // deletes.
- component_context_->ObtainMessageQueue("explicit_test",
- explicit_msg_queue_.NewRequest());
- // The message queue that is used to verify deletion triggers from deletes
- // when the module's namespace is torn down. The test session shell will
- // verify that the agent is notified of this queues deletion.
- component_context_->ObtainMessageQueue("implicit_test",
- implicit_msg_queue_.NewRequest());
- implicit_msg_queue_->GetToken([this](fidl::StringPtr token) {
- modular::testing::GetStore()->Put("trigger_test_module_queue_token",
- token, [] {});
- agent_service_->ObserveMessageQueueDeletion(token);
- explicit_msg_queue_->GetToken([this](fidl::StringPtr token) {
- explicit_queue_token_ = token;
- agent_service_->ObserveMessageQueueDeletion(std::move(token));
-
- TestMessageQueueMessageTrigger();
- });
- });
- }
-
- TestModule(modular::ModuleHost* const module_host,
- fidl::InterfaceRequest<
- fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
- : TestModule(
- module_host,
- fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}
-
- TestPoint received_trigger_token_{"Received trigger token"};
- TestPoint agent_connected_{"fuchsia::modular::Agent accepted connection"};
- TestPoint agent_stopped_{"fuchsia::modular::Agent stopped"};
- TestPoint task_triggered_{"fuchsia::modular::Agent task triggered"};
- void TestMessageQueueMessageTrigger() {
- Await("trigger_test_agent_connected", [this] {
- agent_connected_.Pass();
- agent_service_->GetMessageQueueToken([this](fidl::StringPtr token) {
- received_trigger_token_.Pass();
-
- // Stop the agent.
- agent_controller_.Unbind();
-
- Await("trigger_test_agent_stopped", [this, token] {
- agent_stopped_.Pass();
-
- // Send a message to the stopped agent which should
- // trigger it.
- component_context_->GetMessageSender(token,
- message_sender_.NewRequest());
- message_sender_.Send("Time to wake up...");
-
- Await("message_queue_message", [this] {
- task_triggered_.Pass();
- Await("trigger_test_agent_stopped",
- [this] { TestMessageQueueDeletionTrigger(); });
- });
- });
- });
- });
- }
-
- TestPoint queue_deleted_{"Message queue deletion task triggered."};
- void TestMessageQueueDeletionTrigger() {
- fuchsia::sys::ServiceProviderPtr agent_services;
- component_context_->ConnectToAgent(kTestAgent, agent_services.NewRequest(),
- agent_controller_.NewRequest());
- component::ConnectToService(agent_services.get(),
- agent_service_.NewRequest());
-
- // First wait for the agent to connect, and then kill it.
- Await("trigger_test_agent_connected", [this] {
- Await("trigger_test_agent_token_received", [this] {
- agent_controller_.Unbind();
- Await("trigger_test_agent_stopped", [this] {
- // When the agent has stopped, delete the message queue and verify
- // that the agent is woken up and notified.
- component_context_->DeleteMessageQueue("explicit_test");
- Await(explicit_queue_token_, [this] {
- queue_deleted_.Pass();
- Signal("trigger_test_module_done");
- });
- });
- });
- });
- }
-
- TestPoint stopped_{"Root module stopped"};
- // Called by ModuleDriver.
- void Terminate(const std::function<void()>& done) {
- stopped_.Pass();
- modular::testing::Done(done);
- }
-
- private:
- fuchsia::modular::AgentControllerPtr agent_controller_;
- TriggerTestServicePtr agent_service_;
- fuchsia::modular::ComponentContextPtr component_context_;
- // The queue used for observing explicit queue deletion.
- fuchsia::modular::MessageQueuePtr explicit_msg_queue_;
- std::string explicit_queue_token_;
- // The queue used for observing queue deletion when module's namespace is torn
- // down.
- fuchsia::modular::MessageQueuePtr implicit_msg_queue_;
- modular::MessageSenderClient message_sender_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- async::Loop loop(&kAsyncLoopConfigAttachToThread);
- auto context = component::StartupContext::CreateFromStartupInfo();
- modular::ModuleDriver<TestModule> driver(context.get(),
- [&loop] { loop.Quit(); });
- loop.Run();
- return 0;
-}
diff --git a/tests/trigger/trigger_test_service.fidl b/tests/trigger/trigger_test_service.fidl
deleted file mode 100644
index e7ac5c3..0000000
--- a/tests/trigger/trigger_test_service.fidl
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-library test.peridot.tests.trigger;
-
-// Cf. README.md for what this test does and how.
-[Discoverable]
-interface TriggerTestService {
- 1: GetMessageQueueToken() -> (string message_queue_token);
- 2: ObserveMessageQueueDeletion(string token);
-};
diff --git a/tests/trigger/trigger_test_session_shell.cc b/tests/trigger/trigger_test_session_shell.cc
deleted file mode 100644
index 9aa7b2c..0000000
--- a/tests/trigger/trigger_test_session_shell.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include <fuchsia/modular/cpp/fidl.h>
-#include <fuchsia/ui/viewsv1token/cpp/fidl.h>
-#include <lib/callback/scoped_callback.h>
-#include <lib/component/cpp/connect.h>
-#include <lib/component/cpp/startup_context.h>
-#include <lib/fidl/cpp/binding.h>
-#include <lib/fxl/logging.h>
-#include <lib/fxl/macros.h>
-
-#include "peridot/lib/testing/component_main.h"
-#include "peridot/lib/testing/session_shell_base.h"
-#include "peridot/public/lib/integration_testing/cpp/reporting.h"
-#include "peridot/public/lib/integration_testing/cpp/testing.h"
-#include "peridot/tests/common/defs.h"
-#include "peridot/tests/trigger/defs.h"
-
-using ::modular::testing::Await;
-using ::modular::testing::Signal;
-using ::modular::testing::TestPoint;
-
-namespace {
-
-const char kStoryName[] = "story";
-
-class TestApp : public modular::testing::SessionShellBase {
- public:
- TestApp(component::StartupContext* const startup_context)
- : SessionShellBase(startup_context), weak_ptr_factory_(this) {
- TestInit(__FILE__);
-
- startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());
-
- CreateStory();
- }
-
- ~TestApp() override = default;
-
- private:
- TestPoint story_create_{"Created story."};
-
- void CreateStory() {
- std::vector<fuchsia::modular::StoryCommand> commands;
- fuchsia::modular::AddMod add_mod;
- add_mod.mod_name.push_back("root");
-
- add_mod.intent.action = kModuleAction;
- add_mod.intent.handler = kModuleUrl;
-
- fuchsia::modular::StoryCommand command;
- command.set_add_mod(std::move(add_mod));
- commands.push_back(std::move(command));
-
- puppet_master_->ControlStory(kStoryName, story_puppet_master_.NewRequest());
- story_puppet_master_->Enqueue(std::move(commands));
- story_puppet_master_->Execute(
- [this](fuchsia::modular::ExecuteResult result) {
- story_create_.Pass();
- StartStory();
- });
- }
-
- TestPoint got_queue_token_{"Got message queue token."};
- TestPoint module_finished_{"Trigger test module finished work."};
- TestPoint story_was_deleted_{"Story was deleted."};
- TestPoint agent_executed_delete_task_{
- "fuchsia::modular::Agent executed message queue task."};
- void StartStory() {
- story_provider()->GetController(kStoryName, story_controller_.NewRequest());
- story_controller_.set_error_handler([this](zx_status_t status) {
- FXL_LOG(ERROR) << "Story controller for story " << kStoryName
- << " died. Does this story exist?";
- });
-
- story_controller_->RequestStart();
-
- // Retrieve the message queue token for the messsage queue that the module
- // created.
- modular::testing::GetStore()->Get(
- "trigger_test_module_queue_token", [this](fidl::StringPtr value) {
- got_queue_token_.Pass();
- // Wait for the module to finish its test cases for communicating
- // with the agent.
- Await("trigger_test_module_done", [this, value] {
- module_finished_.Pass();
- // Delete the story to trigger the deletion of the message
- // queue that the module created.
- puppet_master_->DeleteStory(kStoryName, [this, value]() {
- story_was_deleted_.Pass();
- // Verify that the agent task was triggered, by checking
- // that the agent wrote the message queue token to the
- // test store.
- Await(value, [this] {
- agent_executed_delete_task_.Pass();
- Signal(modular::testing::kTestShutdown);
- });
- });
- });
- });
- }
-
- fuchsia::modular::PuppetMasterPtr puppet_master_;
- fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
- fuchsia::modular::StoryControllerPtr story_controller_;
-
- fxl::WeakPtrFactory<TestApp> weak_ptr_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
-};
-
-} // namespace
-
-int main(int /*argc*/, const char** /*argv*/) {
- modular::testing::ComponentMain<TestApp>();
- return 0;
-}
diff --git a/third_party/.nolint b/third_party/.nolint
deleted file mode 100644
index e69de29..0000000
--- a/third_party/.nolint
+++ /dev/null
diff --git a/third_party/bup/BUILD.gn b/third_party/bup/BUILD.gn
deleted file mode 100644
index af1cc73..0000000
--- a/third_party/bup/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//peridot/build/tests_package.gni")
-
-visibility = [ "//peridot/*" ]
-
-source_set("bup") {
- sources = [
- "bupsplit.cc",
- "bupsplit.h",
- ]
-
- public_deps = [
- "//garnet/public/lib/fxl",
- ]
-}
-
-executable("bupsplit_unittest") {
- testonly = true
-
- sources = [
- "bupsplit_unittest.cc",
- ]
-
- deps = [
- ":bup",
- "//third_party/googletest:gtest_main",
- ]
-}
-
-tests_package("bup_tests") {
- deps = [
- ":bupsplit_unittest",
- ]
-}
diff --git a/third_party/bup/LICENSE b/third_party/bup/LICENSE
deleted file mode 100644
index 8651d36..0000000
--- a/third_party/bup/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright 2011 Avery Pennarun. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY AVERY PENNARUN ``AS IS'' AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/bup/README.fuchsia b/third_party/bup/README.fuchsia
deleted file mode 100644
index ad33309..0000000
--- a/third_party/bup/README.fuchsia
+++ /dev/null
@@ -1,12 +0,0 @@
-Name: Bup
-URL: https://github.com/apenwarr/bup
-License: BSD
-License File: LICENSE
-
-This repository has the relevant components from Bup copied to handle rolling
-hashes.
-
-The code has been modified to:
-- Change from C to C++.
-- Allow to add data in multiple passes.
-- Have a minimal and maximal size for chunks.
diff --git a/third_party/bup/bupsplit.cc b/third_party/bup/bupsplit.cc
deleted file mode 100644
index 0ffe76e..0000000
--- a/third_party/bup/bupsplit.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2011 Avery Pennarun. All rights reserved.
- *
- * (This license applies to bupsplit.c and bupsplit.h only.)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AVERY PENNARUN ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "peridot/third_party/bup/bupsplit.h"
-
-#include <memory.h>
-#include <stdint.h>
-
-namespace bup {
-
-namespace {
-
-// According to librsync/rollsum.h:
-// "We should make this something other than zero to improve the
-// checksum algorithm: tridge suggests a prime number."
-// apenwarr: I unscientifically tried 0 and 7919, and they both ended up
-// slightly worse than the librsync value of 31 for my arbitrary test data.
-constexpr uint8_t kRollsumCharOffset = 31;
-
-} // namespace
-
-RollSumSplit::RollSumSplit(size_t min_length, size_t max_length)
- : min_length_(min_length), max_length_(max_length) {
- Reset();
-}
-
-RollSumSplit::RollSumSplit(const RollSumSplit& other) = default;
-
-void RollSumSplit::Reset() {
- current_length_ = 0u;
- s1_ = kWindowSize * kRollsumCharOffset;
- s2_ = kWindowSize * (kWindowSize - 1) * kRollsumCharOffset;
- window_index_ = 0;
- memset(window_, 0, kWindowSize);
-}
-
-size_t RollSumSplit::Feed(fxl::StringView buffer, size_t* bits) {
- for (size_t i = 0; i < buffer.size(); i++) {
- Roll(buffer[i]);
- ++current_length_;
- if (current_length_ >= min_length_ &&
- ((s2_ & (kBlobSize - 1)) == ((~0) & (kBlobSize - 1)) ||
- current_length_ >= max_length_)) {
- if (bits) {
- uint32_t rsum = Digest();
- *bits = kBlobBits;
- rsum >>= kBlobBits;
- while ((rsum >>= 1) & 1) {
- (*bits)++;
- }
- }
- current_length_ = 0;
- return i + 1;
- }
- }
- return 0;
-}
-
-void RollSumSplit::Add(uint8_t drop, uint8_t add) {
- s1_ += add - drop;
- s2_ += s1_ - (kWindowSize * (drop + kRollsumCharOffset));
-}
-
-void RollSumSplit::Roll(uint8_t c) {
- Add(window_[window_index_], c);
- window_[window_index_] = c;
- window_index_ = (window_index_ + 1) % kWindowSize;
-}
-
-uint32_t RollSumSplit::Digest() {
- return (s1_ << 16) | (s2_ & 0xffff);
-}
-
-} // namespace bup
diff --git a/third_party/bup/bupsplit.h b/third_party/bup/bupsplit.h
deleted file mode 100644
index e49c34e..0000000
--- a/third_party/bup/bupsplit.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2011 Avery Pennarun. All rights reserved.
- *
- * (This license applies to bupsplit.c and bupsplit.h only.)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AVERY PENNARUN ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef PERIDOT_BIN_LEDGER_THIRD_PARTY_BUP_BUPSPLIT_H_
-#define PERIDOT_BIN_LEDGER_THIRD_PARTY_BUP_BUPSPLIT_H_
-
-#include <stdint.h>
-
-#include <lib/fxl/macros.h>
-#include <lib/fxl/strings/string_view.h>
-
-namespace bup {
-
-constexpr uint8_t kBlobBits = 13;
-constexpr uint16_t kBlobSize = 1 << kBlobBits;
-constexpr uint8_t kWindowBits = 7;
-constexpr uint16_t kWindowSize = 1 << (kWindowBits - 1);
-
-// Splits data into chunks between |min_length| and |max_length| of size that
-// are "good" for de-duplication.
-//
-// It achieves that by calculating a rolling hash of the window of
-// |kWindowBits|. The split points are selected when the last |kBlobBits| of the
-// current hash are all 1s. This ensures that if data is removed or inserted in
-// the middle of data, only the 2 split points following the change are
-// modified, and all others stay identical.
-class RollSumSplit {
- public:
- // |min_length| is the minimal size of a chunk.
- // |max_length| is the maximal size of a chunk.
- RollSumSplit(size_t min_length, size_t max_length);
-
- // Copy constructor.
- RollSumSplit(const RollSumSplit& other);
-
- // Reset the state of the rolling hash.
- void Reset();
-
- // Returns a non-zero value indicating the size of the prefix that is the next
- // cut, or 0 if all data was consumed without finding the next cut.
- // If |bits| is not null, and a cut has been found, |*bits| will be the number
- // of trailing 1s in the current hash. It will always be greater of equals to
- // |kBlobBits|.
- size_t Feed(fxl::StringView buffer, size_t* bits);
-
- private:
- void Add(uint8_t drop, uint8_t add);
- void Roll(uint8_t c);
- uint32_t Digest();
-
- const size_t min_length_;
- const size_t max_length_;
- size_t current_length_;
- uint64_t s1_, s2_;
- uint8_t window_[kWindowSize];
- size_t window_index_;
-};
-
-} // namespace bup
-
-#endif // PERIDOT_BIN_LEDGER_THIRD_PARTY_BUP_BUPSPLIT_H_
diff --git a/third_party/bup/bupsplit_unittest.cc b/third_party/bup/bupsplit_unittest.cc
deleted file mode 100644
index ef6280c..0000000
--- a/third_party/bup/bupsplit_unittest.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "peridot/third_party/bup/bupsplit.h"
-
-#include <stdlib.h>
-#include <limits>
-
-#include <lib/fxl/logging.h>
-
-#include "gtest/gtest.h"
-
-namespace bup {
-namespace {
-
-class RollSumSplitTest : public ::testing::Test {
- protected:
- void SetUp() override { srand(0); }
-};
-
-std::string GetValue(size_t size) {
- std::string value(size, '\0');
- for (size_t i = 0; i < value.size(); ++i) {
- value[i] = rand();
- }
- return value;
-}
-
-TEST_F(RollSumSplitTest, CheckMinMax) {
- const size_t min = 4 * 1024;
- const size_t max = 8 * 1024;
-
- RollSumSplit rh(min, max);
-
- std::string value = GetValue(1024 * 1024);
- fxl::StringView view = value;
- while (!view.empty()) {
- size_t index = rh.Feed(view, nullptr);
- if (index > 0) {
- EXPECT_TRUE(index >= min);
- EXPECT_TRUE(index <= max);
- view = view.substr(index);
- } else {
- EXPECT_TRUE(view.size() <= max);
- view = "";
- }
- }
-}
-
-// Verifies that results are the same when we feed all data at once and when we
-// feed the data byte-by-byte.
-TEST_F(RollSumSplitTest, CheckSameResult) {
- struct Cut {
- size_t size;
- size_t bits;
- };
-
- RollSumSplit rh(4 * 1024, 64 * 1024 - 1);
-
- std::string value = GetValue(1024 * 1024);
- fxl::StringView view = value;
- std::vector<Cut> feed_all_cuts;
- while (!view.empty()) {
- Cut cut;
- cut.size = rh.Feed(view, &cut.bits);
- if (cut.size) {
- view = view.substr(cut.size);
- feed_all_cuts.push_back(cut);
- } else {
- view = "";
- }
- }
-
- view = value;
- rh.Reset();
- std::vector<Cut> feed_by_byte_cuts;
- size_t index = 0;
- for (size_t i = 0; i < view.size(); ++i) {
- Cut cut;
- size_t count = rh.Feed(view.substr(i, 1), &cut.bits);
- ++index;
- if (count) {
- cut.size = index;
- feed_by_byte_cuts.push_back(cut);
- index = 0;
- }
- }
-
- ASSERT_EQ(feed_all_cuts.size(), feed_by_byte_cuts.size());
- EXPECT_GT(feed_all_cuts.size(), 0u);
- for (size_t i = 0; i < feed_all_cuts.size(); ++i) {
- EXPECT_EQ(feed_all_cuts[i].size, feed_by_byte_cuts[i].size);
- EXPECT_EQ(feed_all_cuts[i].bits, feed_by_byte_cuts[i].bits);
- }
-}
-
-// Check that the roll sum hash only depends on the last |kWindowSize|
-// characters.
-TEST_F(RollSumSplitTest, CheckWindowed) {
- RollSumSplit r1(0, std::numeric_limits<size_t>::max());
- RollSumSplit r2(0, std::numeric_limits<size_t>::max());
-
- // Try different initial feeds for the first hasher until finding the case
- // where the 2 hashes do not agree at least once while consuming the
- // |kWindowSize| characters.
- bool finished = false;
- for (size_t initial_feed = 1026; !finished; ++initial_feed) {
- r1.Reset();
- r2.Reset();
-
- r1.Feed(GetValue(initial_feed), nullptr);
-
- // Feed kWindowSize characters.
- std::string value = GetValue(kWindowSize);
- fxl::StringView view = value;
- for (size_t i = 0; i < view.size(); ++i) {
- auto f1 = r1.Feed(view.substr(i, 1), nullptr);
- auto f2 = r2.Feed(view.substr(i, 1), nullptr);
- finished = finished || (f1 != f2);
- }
- value = GetValue(1024 * 1024);
- EXPECT_EQ(r1.Feed(value, nullptr), r2.Feed(value, nullptr));
- }
-}
-
-} // namespace
-} // namespace bup
diff --git a/third_party/modp_b64/BUILD.gn b/third_party/modp_b64/BUILD.gn
deleted file mode 100644
index c883c46..0000000
--- a/third_party/modp_b64/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-visibility = [ "//peridot/*" ]
-
-static_library("modp_b64") {
- sources = [
- "modp_b64.cc",
- "modp_b64.h",
- "modp_b64_data.h",
- ]
-
- deps = [
- "//garnet/public/lib/fxl",
- ]
-}
diff --git a/third_party/modp_b64/LICENSE b/third_party/modp_b64/LICENSE
deleted file mode 100644
index 55af76f..0000000
--- a/third_party/modp_b64/LICENSE
+++ /dev/null
@@ -1,33 +0,0 @@
- * MODP_B64 - High performance base64 encoder/decoder
- * Version 1.3 -- 17-Mar-2006
- * http://modp.com/release/base64
- *
- * Copyright (c) 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of the modp.com nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/modp_b64/README.fuchsia b/third_party/modp_b64/README.fuchsia
deleted file mode 100644
index 9da0eeb..0000000
--- a/third_party/modp_b64/README.fuchsia
+++ /dev/null
@@ -1,16 +0,0 @@
-Name: modp_b64
-URL: https://github.com/client9/stringencoders
-License: BSD
-License File: LICENSE
-
-The modp_b64.c file was modified to remove the inclusion of modp's config.h
-and to fix compilation errors that occur under VC8. The file was renamed
-modp_b64.cc to force it to be compiled as C++ so that the inclusion of
-basictypes.h could be possible.
-
-The modp_b64.cc and modp_b64.h files were modified to make them safe on
-64-bit systems.
-The modp_b64.cc was modified to avoid misaligned read/write on
-little-endian hardware.
-
-modp_b64 was modified to produce base64url.
diff --git a/third_party/modp_b64/modp_b64.cc b/third_party/modp_b64/modp_b64.cc
deleted file mode 100644
index dbfa0bb..0000000
--- a/third_party/modp_b64/modp_b64.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4: */
-/**
- * \file
- * <PRE>
- * MODP_B64 - High performance base64 encoder/decoder
- * Version 1.3 -- 17-Mar-2006
- * http://modp.com/release/base64
- *
- * Copyright © 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of the modp.com nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This is the standard "new" BSD license:
- * http://www.opensource.org/licenses/bsd-license.php
- * </PRE>
- */
-
-/* public header */
-#include "modp_b64.h"
-
-/*
- * If you are ripping this out of the library, comment out the next
- * line and uncomment the next lines as approrpiate
- */
-#include <lib/fxl/build_config.h>
-
-#ifndef ARCH_CPU_LITTLE_ENDIAN
-
-/* if on motoral, sun, ibm; uncomment this */
-#define WORDS_BIGENDIAN 1
-
-#else
-
-/* else for Intel, Amd; uncomment this */
-#undef WORDS_BIGENDIAN
-
-#endif // ARCH_CPU_LITTLE_ENDIAN
-
-#include "modp_b64_data.h"
-
-#define BADCHAR 0x01FFFFFF
-
-/**
- * you can control if we use padding by commenting out this
- * next line. However, I highly recommend you use padding and not
- * using it should only be for compatability with a 3rd party.
- * Also, 'no padding' is not tested!
- */
-#define DOPAD 1
-
-/*
- * if we aren't doing padding
- * set the pad character to NULL
- */
-#ifndef DOPAD
-#undef CHARPAD
-#define CHARPAD '\0'
-#endif
-
-size_t modp_b64_encode(char* dest, const char* str, size_t len)
-{
- size_t i = 0;
- uint8_t* p = (uint8_t*) dest;
-
- /* unsigned here is important! */
- uint8_t t1, t2, t3;
-
- if (len > 2) {
- for (; i < len - 2; i += 3) {
- t1 = str[i]; t2 = str[i+1]; t3 = str[i+2];
- *p++ = e0[t1];
- *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
- *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)];
- *p++ = e2[t3];
- }
- }
-
- switch (len - i) {
- case 0:
- break;
- case 1:
- t1 = str[i];
- *p++ = e0[t1];
- *p++ = e1[(t1 & 0x03) << 4];
- *p++ = CHARPAD;
- *p++ = CHARPAD;
- break;
- default: /* case 2 */
- t1 = str[i]; t2 = str[i+1];
- *p++ = e0[t1];
- *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
- *p++ = e2[(t2 & 0x0F) << 2];
- *p++ = CHARPAD;
- }
-
- *p = '\0';
- return p - (uint8_t*)dest;
-}
-
-#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */
-int modp_b64_decode(char* dest, const char* src, int len)
-{
- if (len == 0) return 0;
-
-#ifdef DOPAD
- /* if padding is used, then the message must be at least
- 4 chars and be a multiple of 4.
- there can be at most 2 pad chars at the end */
- if (len < 4 || (len % 4 != 0)) return MODP_B64_ERROR;
- if (src[len-1] == CHARPAD) {
- len--;
- if (src[len -1] == CHARPAD) {
- len--;
- }
- }
-#endif /* DOPAD */
-
- size_t i;
- int leftover = len % 4;
- size_t chunks = (leftover == 0) ? len / 4 - 1 : len /4;
-
- uint8_t* p = (uint8_t*) dest;
- uint32_t x = 0;
- uint32_t* destInt = (uint32_t*) p;
- uint32_t* srcInt = (uint32_t*) src;
- uint32_t y = *srcInt++;
- for (i = 0; i < chunks; ++i) {
- x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] |
- d2[y >> 8 & 0xff] | d3[y & 0xff];
-
- if (x >= BADCHAR) return MODP_B64_ERROR;
- *destInt = x << 8;
- p += 3;
- destInt = (uint32_t*)p;
- y = *srcInt++;
- }
-
- switch (leftover) {
- case 0:
- x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] |
- d2[y >> 8 & 0xff] | d3[y & 0xff];
- if (x >= BADCHAR) return MODP_B64_ERROR;
- *p++ = ((uint8_t*)&x)[1];
- *p++ = ((uint8_t*)&x)[2];
- *p = ((uint8_t*)&x)[3];
- return (chunks+1)*3;
- case 1:
- x = d3[y >> 24];
- *p = (uint8_t)x;
- break;
- case 2:
- x = d3[y >> 24] *64 + d3[(y >> 16) & 0xff];
- *p = (uint8_t)(x >> 4);
- break;
- default: /* case 3 */
- x = (d3[y >> 24] *64 + d3[(y >> 16) & 0xff])*64 +
- d3[(y >> 8) & 0xff];
- *p++ = (uint8_t) (x >> 10);
- *p = (uint8_t) (x >> 2);
- break;
- }
-
- if (x >= BADCHAR) return MODP_B64_ERROR;
- return 3*chunks + (6*leftover)/8;
-}
-
-#else /* LITTLE ENDIAN -- INTEL AND FRIENDS */
-
-size_t modp_b64_decode(char* dest, const char* src, size_t len)
-{
- if (len == 0) return 0;
-
-#ifdef DOPAD
- /*
- * if padding is used, then the message must be at least
- * 4 chars and be a multiple of 4
- */
- if (len < 4 || (len % 4 != 0)) return MODP_B64_ERROR; /* error */
- /* there can be at most 2 pad chars at the end */
- if (src[len-1] == CHARPAD) {
- len--;
- if (src[len -1] == CHARPAD) {
- len--;
- }
- }
-#endif
-
- size_t i;
- int leftover = len % 4;
- size_t chunks = (leftover == 0) ? len / 4 - 1 : len /4;
-
- uint8_t* p = (uint8_t*)dest;
- uint32_t x = 0;
- const uint8_t* y = (uint8_t*)src;
- for (i = 0; i < chunks; ++i, y += 4) {
- x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]];
- if (x >= BADCHAR) return MODP_B64_ERROR;
- *p++ = ((uint8_t*)(&x))[0];
- *p++ = ((uint8_t*)(&x))[1];
- *p++ = ((uint8_t*)(&x))[2];
- }
-
- switch (leftover) {
- case 0:
- x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]];
-
- if (x >= BADCHAR) return MODP_B64_ERROR;
- *p++ = ((uint8_t*)(&x))[0];
- *p++ = ((uint8_t*)(&x))[1];
- *p = ((uint8_t*)(&x))[2];
- return (chunks+1)*3;
- break;
- case 1: /* with padding this is an impossible case */
- x = d0[y[0]];
- *p = *((uint8_t*)(&x)); // i.e. first char/byte in int
- break;
- case 2: // * case 2, 1 output byte */
- x = d0[y[0]] | d1[y[1]];
- *p = *((uint8_t*)(&x)); // i.e. first char
- break;
- default: /* case 3, 2 output bytes */
- x = d0[y[0]] | d1[y[1]] | d2[y[2]]; /* 0x3c */
- *p++ = ((uint8_t*)(&x))[0];
- *p = ((uint8_t*)(&x))[1];
- break;
- }
-
- if (x >= BADCHAR) return MODP_B64_ERROR;
-
- return 3*chunks + (6*leftover)/8;
-}
-
-#endif /* if bigendian / else / endif */
diff --git a/third_party/modp_b64/modp_b64.h b/third_party/modp_b64/modp_b64.h
deleted file mode 100644
index 3270e5f..0000000
--- a/third_party/modp_b64/modp_b64.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4: */
-
-/**
- * \file
- * <PRE>
- * High performance base64 encoder / decoder
- * Version 1.3 -- 17-Mar-2006
- *
- * Copyright © 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com
- * All rights reserved.
- *
- * http://modp.com/release/base64
- *
- * Released under bsd license. See modp_b64.c for details.
- * </pre>
- *
- * The default implementation is the standard b64 encoding with padding.
- * It's easy to change this to use "URL safe" characters and to remove
- * padding. See the modp_b64.c source code for details.
- *
- */
-
-#ifndef MODP_B64
-#define MODP_B64
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Encode a raw binary string into base 64.
- * src contains the bytes
- * len contains the number of bytes in the src
- * dest should be allocated by the caller to contain
- * at least modp_b64_encode_len(len) bytes (see below)
- * This will contain the null-terminated b64 encoded result
- * returns length of the destination string plus the ending null byte
- * i.e. the result will be equal to strlen(dest) + 1
- *
- * Example
- *
- * \code
- * char* src = ...;
- * int srclen = ...; //the length of number of bytes in src
- * char* dest = (char*) malloc(modp_b64_encode_len);
- * int len = modp_b64_encode(dest, src, sourcelen);
- * if (len == -1) {
- * printf("Error\n");
- * } else {
- * printf("b64 = %s\n", dest);
- * }
- * \endcode
- *
- */
-size_t modp_b64_encode(char* dest, const char* str, size_t len);
-
-/**
- * Decode a base64 encoded string
- *
- * src should contain exactly len bytes of b64 characters.
- * if src contains -any- non-base characters (such as white
- * space, -1 is returned.
- *
- * dest should be allocated by the caller to contain at least
- * len * 3 / 4 bytes.
- *
- * Returns the length (strlen) of the output, or -1 if unable to
- * decode
- *
- * \code
- * char* src = ...;
- * int srclen = ...; // or if you don't know use strlen(src)
- * char* dest = (char*) malloc(modp_b64_decode_len(srclen));
- * int len = modp_b64_decode(dest, src, sourcelen);
- * if (len == -1) { error }
- * \endcode
- */
-size_t modp_b64_decode(char* dest, const char* src, size_t len);
-
-/**
- * Given a source string of length len, this returns the amount of
- * memory the destination string should have.
- *
- * remember, this is integer math
- * 3 bytes turn into 4 chars
- * ceiling[len / 3] * 4 + 1
- *
- * +1 is for any extra null.
- */
-#define modp_b64_encode_len(A) ((A+2)/3 * 4 + 1)
-
-/**
- * Given a base64 string of length len,
- * this returns the amount of memory required for output string
- * It maybe be more than the actual number of bytes written.
- * NOTE: remember this is integer math
- * this allocates a bit more memory than traditional versions of b64
- * decode 4 chars turn into 3 bytes
- * floor[len * 3/4] + 2
- */
-#define modp_b64_decode_len(A) (A / 4 * 3 + 2)
-
-/**
- * Will return the strlen of the output from encoding.
- * This may be less than the required number of bytes allocated.
- *
- * This allows you to 'deserialized' a struct
- * \code
- * char* b64encoded = "...";
- * int len = strlen(b64encoded);
- *
- * struct datastuff foo;
- * if (modp_b64_encode_strlen(sizeof(struct datastuff)) != len) {
- * // wrong size
- * return false;
- * } else {
- * // safe to do;
- * if (modp_b64_decode((char*) &foo, b64encoded, len) == -1) {
- * // bad characters
- * return false;
- * }
- * }
- * // foo is filled out now
- * \endcode
- */
-#define modp_b64_encode_strlen(A) ((A + 2)/ 3 * 4)
-
-#define MODP_B64_ERROR ((size_t)-1)
-
-#ifdef __cplusplus
-}
-
-#include <string>
-
-inline std::string& modp_b64_encode(std::string& s)
-{
- std::string x(modp_b64_encode_len(s.size()), '\0');
- size_t d = modp_b64_encode(const_cast<char*>(x.data()), s.data(), (int)s.size());
- x.erase(d, std::string::npos);
- s.swap(x);
- return s;
-}
-
-/**
- * base 64 decode a string (self-modifing)
- * On failure, the string is empty.
- *
- * This function is for C++ only (duh)
- *
- * \param[in,out] s the string to be decoded
- * \return a reference to the input string
- */
-inline std::string& modp_b64_decode(std::string& s)
-{
- std::string x(modp_b64_decode_len(s.size()), '\0');
- size_t d = modp_b64_decode(const_cast<char*>(x.data()), s.data(), (int)s.size());
- if (d == MODP_B64_ERROR) {
- x.clear();
- } else {
- x.erase(d, std::string::npos);
- }
- s.swap(x);
- return s;
-}
-
-#endif /* __cplusplus */
-
-#endif /* MODP_B64 */
diff --git a/third_party/modp_b64/modp_b64_data.h b/third_party/modp_b64/modp_b64_data.h
deleted file mode 100644
index ce3d68a..0000000
--- a/third_party/modp_b64/modp_b64_data.h
+++ /dev/null
@@ -1,481 +0,0 @@
-#include <stdint.h>
-
-#define CHAR62 '-'
-#define CHAR63 '_'
-#define CHARPAD '='
-static const char e0[256] = {
- 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C',
- 'C', 'C', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E',
- 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H',
- 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J',
- 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'M', 'M',
- 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O',
- 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R',
- 'R', 'R', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T',
- 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W',
- 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y',
- 'Z', 'Z', 'Z', 'Z', 'a', 'a', 'a', 'a', 'b', 'b',
- 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd',
- 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g',
- 'g', 'g', 'h', 'h', 'h', 'h', 'i', 'i', 'i', 'i',
- 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l',
- 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n',
- 'o', 'o', 'o', 'o', 'p', 'p', 'p', 'p', 'q', 'q',
- 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's',
- 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v',
- 'v', 'v', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x',
- 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0',
- '0', '0', '1', '1', '1', '1', '2', '2', '2', '2',
- '3', '3', '3', '3', '4', '4', '4', '4', '5', '5',
- '5', '5', '6', '6', '6', '6', '7', '7', '7', '7',
- '8', '8', '8', '8', '9', '9', '9', '9', '-', '-',
- '-', '-', '_', '_', '_', '_'
-};
-
-static const char e1[256] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', '-', '_', 'A', 'B', 'C', 'D', 'E', 'F',
- 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
- 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9', '-', '_', 'A', 'B',
- 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
- 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
- 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
- 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
- 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
- '6', '7', '8', '9', '-', '_'
-};
-
-static const char e2[256] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', '-', '_', 'A', 'B', 'C', 'D', 'E', 'F',
- 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
- 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9', '-', '_', 'A', 'B',
- 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
- 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
- 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
- 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
- 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
- '6', '7', '8', '9', '-', '_'
-};
-
-
-
-#ifdef WORDS_BIGENDIAN
-
-
-/* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */
-
-static const uint32_t d0[256] = {
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x00f80000, 0x01ffffff, 0x00f80000, 0x01ffffff, 0x00fc0000,
-0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000,
-0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
-0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000,
-0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000,
-0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000,
-0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000,
-0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000,
-0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000,
-0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000,
-0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000,
-0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000,
-0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
-};
-
-
-static const uint32_t d1[256] = {
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x0003e000, 0x01ffffff, 0x0003e000, 0x01ffffff, 0x0003f000,
-0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000,
-0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
-0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000,
-0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000,
-0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000,
-0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000,
-0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000,
-0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000,
-0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000,
-0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000,
-0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000,
-0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
-};
-
-
-static const uint32_t d2[256] = {
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x00000f80, 0x01ffffff, 0x00000f80, 0x01ffffff, 0x00000fc0,
-0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40,
-0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
-0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180,
-0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300,
-0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480,
-0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600,
-0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0,
-0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780,
-0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900,
-0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80,
-0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00,
-0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
-};
-
-
-static const uint32_t d3[256] = {
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x0000003e, 0x01ffffff, 0x0000003e, 0x01ffffff, 0x0000003f,
-0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039,
-0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
-0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006,
-0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c,
-0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012,
-0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018,
-0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f,
-0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e,
-0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024,
-0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a,
-0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030,
-0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
-};
-
-
-#else
-
-
-/* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */
-
-static const uint32_t d0[256] = {
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x000000f8, 0x01ffffff, 0x000000f8, 0x01ffffff, 0x000000fc,
-0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4,
-0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
-0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018,
-0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030,
-0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048,
-0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060,
-0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc,
-0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078,
-0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090,
-0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8,
-0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0,
-0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
-};
-
-
-static const uint32_t d1[256] = {
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x0000e003, 0x01ffffff, 0x0000e003, 0x01ffffff, 0x0000f003,
-0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003,
-0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
-0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000,
-0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000,
-0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001,
-0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001,
-0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003,
-0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001,
-0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002,
-0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002,
-0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003,
-0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
-};
-
-
-static const uint32_t d2[256] = {
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x00800f00, 0x01ffffff, 0x00800f00, 0x01ffffff, 0x00c00f00,
-0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00,
-0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
-0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100,
-0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300,
-0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400,
-0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600,
-0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00,
-0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700,
-0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900,
-0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00,
-0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00,
-0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
-};
-
-
-static const uint32_t d3[256] = {
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x003e0000, 0x01ffffff, 0x003e0000, 0x01ffffff, 0x003f0000,
-0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000,
-0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
-0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000,
-0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000,
-0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000,
-0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000,
-0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000,
-0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000,
-0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000,
-0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000,
-0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000,
-0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
-0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
-};
-
-
-#endif
diff --git a/web/cloud_dashboard/.clang-format b/web/cloud_dashboard/.clang-format
deleted file mode 100644
index fbcf2d7..0000000
--- a/web/cloud_dashboard/.clang-format
+++ /dev/null
@@ -1,4 +0,0 @@
-Language: JavaScript
-BasedOnStyle: Google
-ColumnLimit: 80
-ReflowComments: false
diff --git a/web/cloud_dashboard/.firebaserc b/web/cloud_dashboard/.firebaserc
deleted file mode 100644
index 9f910ec..0000000
--- a/web/cloud_dashboard/.firebaserc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "projects": {
- "default": "fuchsia-ledger"
- }
-}
diff --git a/web/cloud_dashboard/.gitignore b/web/cloud_dashboard/.gitignore
deleted file mode 100644
index 4b2c73e..0000000
--- a/web/cloud_dashboard/.gitignore
+++ /dev/null
@@ -1,18 +0,0 @@
-# See http://help.github.com/ignore-files/ for more about ignoring files.
-
-# compiled output
-/dist
-/tmp
-/out-tsc
-
-# dependencies
-/node_modules
-
-# misc
-/.sass-cache
-/connect.lock
-/coverage
-/libpeerconnection.log
-npm-debug.log
-testem.log
-/typings
diff --git a/web/cloud_dashboard/README.md b/web/cloud_dashboard/README.md
deleted file mode 100644
index d4580b7..0000000
--- a/web/cloud_dashboard/README.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Cloud dashboard
-
-Web dashboard allowing a signed-in user to inspect their Ledger state and
-trigger cloud erase if needed.
-
-This project is built using Angular and was scaffolded using
-[Angular CLI] version 6.0.8.
-
-## Prerequisites
-
- - make sure you have [nodejs] installed
- - install [Angular CLI]: `npm install -g @angular/cli`
- - install [Firebase CLI]: `npm install -g firebase-tools`
- - run `npm install` in the `cloud_dashboard` directory
-
-## Development workflow
-
- - run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The
- app will automatically reload if you change any of the source files
- - run `ng test` to execute the unit tests via [Karma]
-
-To get more help on the Angular CLI use `ng help` or go check out the [Angular
-CLI README]
-
-## Deployment
-
-Run `firebase login` at least once. Then:
-
- - run `ng build --prod` to build the project. The build artifacts will be stored
- in the `dist/` directory
- - run `firebase deploy`
-
-[Angular CLI]: https://github.com/angular/angular-cli
-[nodejs]: https://nodejs.org
-[Karma]: https://karma-runner.github.io
-[Angular CLI README]: https://github.com/angular/angular-cli/blob/master/README.md
-[Firebase CLI]: https://firebase.google.com/docs/cli/
diff --git a/web/cloud_dashboard/angular.json b/web/cloud_dashboard/angular.json
deleted file mode 100644
index b655ad1..0000000
--- a/web/cloud_dashboard/angular.json
+++ /dev/null
@@ -1,127 +0,0 @@
-{
- "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
- "version": 1,
- "newProjectRoot": "projects",
- "projects": {
- "cloud_dashboard": {
- "root": "",
- "sourceRoot": "src",
- "projectType": "application",
- "prefix": "app",
- "schematics": {},
- "architect": {
- "build": {
- "builder": "@angular-devkit/build-angular:browser",
- "options": {
- "outputPath": "dist/cloud_dashboard",
- "index": "src/index.html",
- "main": "src/main.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "src/tsconfig.app.json",
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ],
- "styles": [
- "src/styles.css"
- ],
- "scripts": []
- },
- "configurations": {
- "production": {
- "fileReplacements": [
- {
- "replace": "src/environments/environment.ts",
- "with": "src/environments/environment.prod.ts"
- }
- ],
- "optimization": true,
- "outputHashing": "all",
- "sourceMap": false,
- "extractCss": true,
- "namedChunks": false,
- "aot": true,
- "extractLicenses": true,
- "vendorChunk": false,
- "buildOptimizer": true
- }
- }
- },
- "serve": {
- "builder": "@angular-devkit/build-angular:dev-server",
- "options": {
- "browserTarget": "cloud_dashboard:build"
- },
- "configurations": {
- "production": {
- "browserTarget": "cloud_dashboard:build:production"
- }
- }
- },
- "extract-i18n": {
- "builder": "@angular-devkit/build-angular:extract-i18n",
- "options": {
- "browserTarget": "cloud_dashboard:build"
- }
- },
- "test": {
- "builder": "@angular-devkit/build-angular:karma",
- "options": {
- "main": "src/test.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "src/tsconfig.spec.json",
- "karmaConfig": "src/karma.conf.js",
- "styles": [
- "src/styles.css"
- ],
- "scripts": [],
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ]
- }
- },
- "lint": {
- "builder": "@angular-devkit/build-angular:tslint",
- "options": {
- "tsConfig": [
- "src/tsconfig.app.json",
- "src/tsconfig.spec.json"
- ],
- "exclude": [
- "**/node_modules/**"
- ]
- }
- }
- }
- },
- "cloud_dashboard-e2e": {
- "root": "e2e/",
- "projectType": "application",
- "architect": {
- "e2e": {
- "builder": "@angular-devkit/build-angular:protractor",
- "options": {
- "protractorConfig": "e2e/protractor.conf.js",
- "devServerTarget": "cloud_dashboard:serve"
- },
- "configurations": {
- "production": {
- "devServerTarget": "cloud_dashboard:serve:production"
- }
- }
- },
- "lint": {
- "builder": "@angular-devkit/build-angular:tslint",
- "options": {
- "tsConfig": "e2e/tsconfig.e2e.json",
- "exclude": [
- "**/node_modules/**"
- ]
- }
- }
- }
- }
- },
- "defaultProject": "cloud_dashboard"
-}
\ No newline at end of file
diff --git a/web/cloud_dashboard/firebase.json b/web/cloud_dashboard/firebase.json
deleted file mode 100644
index c26470b..0000000
--- a/web/cloud_dashboard/firebase.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "hosting": {
- "public": "dist/cloud_dashboard",
- "rewrites": [ {
- "source": "**",
- "destination": "/index.html"
- } ]
- }
-}
diff --git a/web/cloud_dashboard/package-lock.json b/web/cloud_dashboard/package-lock.json
deleted file mode 100644
index 2e5e9c0..0000000
--- a/web/cloud_dashboard/package-lock.json
+++ /dev/null
@@ -1,11304 +0,0 @@
-{
- "name": "cloud_dashboard",
- "version": "0.0.0",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "@angular-devkit/architect": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.6.8.tgz",
- "integrity": "sha512-ZKTm/zC61iY9IBHOEAKoMSzZpvhkmv+1O/HHzpHEuR551jCzu6vSyCmMY9Z7GBcccscCV+hjeSMwgFrFRcqlkw==",
- "dev": true,
- "requires": {
- "@angular-devkit/core": "0.6.8",
- "rxjs": "^6.0.0"
- }
- },
- "@angular-devkit/build-angular": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.6.8.tgz",
- "integrity": "sha512-VGqYAk8jpISraz2UHfsDre270NOUmV0CTSZw2p9sm5g/XIr5m+IHetFZz3gpoAr9+If2aFTs8Rt3sGdCRzwBqA==",
- "dev": true,
- "requires": {
- "@angular-devkit/architect": "0.6.8",
- "@angular-devkit/build-optimizer": "0.6.8",
- "@angular-devkit/core": "0.6.8",
- "@ngtools/webpack": "6.0.8",
- "ajv": "~6.4.0",
- "autoprefixer": "^8.4.1",
- "cache-loader": "^1.2.2",
- "chalk": "~2.2.2",
- "circular-dependency-plugin": "^5.0.2",
- "clean-css": "^4.1.11",
- "copy-webpack-plugin": "^4.5.1",
- "file-loader": "^1.1.11",
- "glob": "^7.0.3",
- "html-webpack-plugin": "^3.0.6",
- "istanbul": "^0.4.5",
- "istanbul-instrumenter-loader": "^3.0.1",
- "karma-source-map-support": "^1.2.0",
- "less": "^3.0.4",
- "less-loader": "^4.1.0",
- "license-webpack-plugin": "^1.3.1",
- "lodash": "^4.17.4",
- "memory-fs": "^0.4.1",
- "mini-css-extract-plugin": "~0.4.0",
- "minimatch": "^3.0.4",
- "node-sass": "^4.9.0",
- "opn": "^5.1.0",
- "parse5": "^4.0.0",
- "portfinder": "^1.0.13",
- "postcss": "^6.0.22",
- "postcss-import": "^11.1.0",
- "postcss-loader": "^2.1.5",
- "postcss-url": "^7.3.2",
- "raw-loader": "^0.5.1",
- "resolve": "^1.5.0",
- "rxjs": "^6.0.0",
- "sass-loader": "^7.0.1",
- "silent-error": "^1.1.0",
- "source-map-support": "^0.5.0",
- "stats-webpack-plugin": "^0.6.2",
- "style-loader": "^0.21.0",
- "stylus": "^0.54.5",
- "stylus-loader": "^3.0.2",
- "tree-kill": "^1.2.0",
- "uglifyjs-webpack-plugin": "^1.2.5",
- "url-loader": "^1.0.1",
- "webpack": "~4.8.1",
- "webpack-dev-middleware": "^3.1.3",
- "webpack-dev-server": "^3.1.4",
- "webpack-merge": "^4.1.2",
- "webpack-sources": "^1.1.0",
- "webpack-subresource-integrity": "^1.1.0-rc.4"
- }
- },
- "@angular-devkit/build-optimizer": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.6.8.tgz",
- "integrity": "sha512-of5syQbv3uNPp4AQkfRecfnp8AE8kvffbfYi+FFPZ6OGr7e59T1fGwk6+Zgb2qQFQg8HO2tzWI/uygtLIqmbmw==",
- "dev": true,
- "requires": {
- "loader-utils": "^1.1.0",
- "source-map": "^0.5.6",
- "typescript": "~2.9.1",
- "webpack-sources": "^1.1.0"
- },
- "dependencies": {
- "typescript": {
- "version": "2.9.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
- "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
- "dev": true
- }
- }
- },
- "@angular-devkit/core": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.6.8.tgz",
- "integrity": "sha512-rkIa1OSVWTt4g9leLSK/PsqOj3HZbDKHbZjqlslyfVa3AyCeiumFoOgViOVXlYgPX3HHDbE5uH24nyUWSD8uww==",
- "dev": true,
- "requires": {
- "ajv": "~6.4.0",
- "chokidar": "^2.0.3",
- "rxjs": "^6.0.0",
- "source-map": "^0.5.6"
- }
- },
- "@angular-devkit/schematics": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.6.8.tgz",
- "integrity": "sha512-R4YqAUdo62wtrhX/5HSRGSKXNTWqfQb66ZE6m8jj6GEJNFKdNXMdxOchxr07LCiKTxfh1w6G3nGzxIsu/+D4KA==",
- "dev": true,
- "requires": {
- "@angular-devkit/core": "0.6.8",
- "rxjs": "^6.0.0"
- }
- },
- "@angular/animations": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-6.0.7.tgz",
- "integrity": "sha512-yOig45sxzpEmlXy+eFgh2v2yxoE/Hh9rn7BX82uj71yobSpCYoe58AEOay1cu0FCcLi/P5qltHepDrRRxNxPMw==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@angular/cdk": {
- "version": "6.3.2",
- "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-6.3.2.tgz",
- "integrity": "sha512-iicOzxDRxRbsmu7QG6bQZOG3jWiZp6wwxGVmWWdodOPoPWLaWrx3EAKmbNvAZDT7DdwafOHu8m4qWPSVfsVb5A==",
- "requires": {
- "tslib": "^1.7.1"
- }
- },
- "@angular/cli": {
- "version": "6.0.8",
- "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-6.0.8.tgz",
- "integrity": "sha512-DhH1Zq5Yonthw6zh6W07fhf+9XrAZbD1fcQ0MrmbxlieCfLlTAdBqyK2LavFCKwSZkUMLF6UHM3+jiNRVZSSIg==",
- "dev": true,
- "requires": {
- "@angular-devkit/architect": "0.6.8",
- "@angular-devkit/core": "0.6.8",
- "@angular-devkit/schematics": "0.6.8",
- "@schematics/angular": "0.6.8",
- "@schematics/update": "0.6.8",
- "opn": "~5.3.0",
- "resolve": "^1.1.7",
- "rxjs": "^6.0.0",
- "semver": "^5.1.0",
- "silent-error": "^1.0.0",
- "symbol-observable": "^1.2.0",
- "yargs-parser": "^10.0.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true
- },
- "yargs-parser": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
- "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
- "dev": true,
- "requires": {
- "camelcase": "^4.1.0"
- }
- }
- }
- },
- "@angular/common": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/common/-/common-6.0.7.tgz",
- "integrity": "sha512-MUCCs3FLwqyp5wuvkUTHVGMTd3bNGDxD5IJNvaLgVliGe4r0IlETRXYqyRPs7gdVFPbiJ97P1DUONArj9xL9XA==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@angular/compiler": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-6.0.7.tgz",
- "integrity": "sha512-J9I2U4NiWIBXl0ZOJkBW5G7xXhphggSirTwFLD4yKCTeJXgyldZytJZRkDUx1uouZtI2/PycvaOZoRr85N67AA==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@angular/compiler-cli": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-6.0.7.tgz",
- "integrity": "sha512-nDIo4TtE3oXgZiQ5vJEcr5fi3FuXRDJQSOeOQinpCrtEt3s4pU5WAX5DLFGPSD2C/EXRDvHZgF9OTJeu5U4ErQ==",
- "dev": true,
- "requires": {
- "chokidar": "^1.4.2",
- "minimist": "^1.2.0",
- "reflect-metadata": "^0.1.2",
- "tsickle": "^0.29.0"
- },
- "dependencies": {
- "anymatch": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
- "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
- "dev": true,
- "requires": {
- "micromatch": "^2.1.5",
- "normalize-path": "^2.0.0"
- }
- },
- "arr-diff": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
- "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.0.1"
- }
- },
- "array-unique": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
- "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
- "dev": true
- },
- "braces": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
- "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
- "dev": true,
- "requires": {
- "expand-range": "^1.8.1",
- "preserve": "^0.2.0",
- "repeat-element": "^1.1.2"
- }
- },
- "chokidar": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
- "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
- "dev": true,
- "requires": {
- "anymatch": "^1.3.0",
- "async-each": "^1.0.0",
- "fsevents": "^1.0.0",
- "glob-parent": "^2.0.0",
- "inherits": "^2.0.1",
- "is-binary-path": "^1.0.0",
- "is-glob": "^2.0.0",
- "path-is-absolute": "^1.0.0",
- "readdirp": "^2.0.0"
- }
- },
- "expand-brackets": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
- "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
- "dev": true,
- "requires": {
- "is-posix-bracket": "^0.1.0"
- }
- },
- "extglob": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
- "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
- "dev": true,
- "requires": {
- "is-extglob": "^1.0.0"
- }
- },
- "glob-parent": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
- "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
- "dev": true,
- "requires": {
- "is-glob": "^2.0.0"
- }
- },
- "is-extglob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
- "dev": true
- },
- "is-glob": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
- "dev": true,
- "requires": {
- "is-extglob": "^1.0.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- },
- "micromatch": {
- "version": "2.3.11",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
- "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
- "dev": true,
- "requires": {
- "arr-diff": "^2.0.0",
- "array-unique": "^0.2.1",
- "braces": "^1.8.2",
- "expand-brackets": "^0.1.4",
- "extglob": "^0.3.1",
- "filename-regex": "^2.0.0",
- "is-extglob": "^1.0.0",
- "is-glob": "^2.0.1",
- "kind-of": "^3.0.2",
- "normalize-path": "^2.0.1",
- "object.omit": "^2.0.0",
- "parse-glob": "^3.0.4",
- "regex-cache": "^0.4.2"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
- }
- },
- "@angular/core": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/core/-/core-6.0.7.tgz",
- "integrity": "sha512-aZ0NvbYsMGqg0zUu7+9vuDxnGzwe++RsBBhlwHZHz1ZZwJmU6VJhUhaI+MuKC7rHyFFr9vUxvJ7ilhGaK2+J7A==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@angular/forms": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-6.0.7.tgz",
- "integrity": "sha512-bFRdWxLmTiG7z0yZaq22oBHTgVSpJwUJEbZ5ieu21JqTgIDYne+YR/xCJrPj+P2S5NDlEK84g/4y4GoNt/thhQ==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@angular/http": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/http/-/http-6.0.7.tgz",
- "integrity": "sha512-zk/kjsfEXjEQIRpmsjuJO5wgFNxj7JGY6Bq0nianZuyCuj/mlm0zflww2NLX4O22IMnvVSun2Kx+kDY44n4hfw==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@angular/language-service": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-6.0.7.tgz",
- "integrity": "sha512-R96kTy9Hpy5QPHirJz+5JjnzjJZdwbGwZ6rpq79Fe15RYaYfMjFTAAhmmOgWrnTFBug0QWBWyKV7950JcJIr3Q==",
- "dev": true
- },
- "@angular/material": {
- "version": "6.3.2",
- "resolved": "https://registry.npmjs.org/@angular/material/-/material-6.3.2.tgz",
- "integrity": "sha512-v5k6wyIDrEePU6NNtO/024LInIoZKvDJiO4nIfrXjOHjeHh6eHEtDRmaJUA/CruxX2ICdYkof7NfXvkrFn3wZA==",
- "requires": {
- "parse5": "^5.0.0",
- "tslib": "^1.7.1"
- },
- "dependencies": {
- "parse5": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.0.0.tgz",
- "integrity": "sha512-0ywuiUOnpWWeil5grH2rxjyTJoeQVwyBuO2si6QIU9dWtj2npjuyK1HaY1RbLnVfDhEbhyAPNUBKRK0Xj2xE0w==",
- "optional": true
- }
- }
- },
- "@angular/platform-browser": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-6.0.7.tgz",
- "integrity": "sha512-CASH1CDr2DD+aBrWN9qpDDFTI3H6p/oqH23h28bEV+LZl7F57r4sj8KXKgaE+mcrOFRQqXTAlPoq3hRCLmhtVA==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@angular/platform-browser-dynamic": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-6.0.7.tgz",
- "integrity": "sha512-8G45A9w8UJvX3vPEHqeJHt/sd0zu6w1M+rsnOCo78r35SjsLbrmDNhc4VkLZFJ+iNjgPWtNtdpeXQqtTHE46yw==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@angular/router": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/@angular/router/-/router-6.0.7.tgz",
- "integrity": "sha512-KuQBeIgfiwV3bLafepMhYVJQIAF8cTckCudFh5Z0OqckJgGsWSgtvEdtBctPi+lzt7OQBi7Ym2rOv3X0dOvu0Q==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "@firebase/app": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.3.3.tgz",
- "integrity": "sha512-V5fMC2Ysx1TlHD6x7vj7EOtoyJSU/ts+fp9qxt0E3TA+DbWgKFrkcL+o2jZhi30h0sXKV7oW0vh67YZdZylqOg==",
- "requires": {
- "@firebase/app-types": "0.3.2",
- "@firebase/util": "0.2.1",
- "dom-storage": "2.1.0",
- "tslib": "1.9.0",
- "xmlhttprequest": "1.8.0"
- },
- "dependencies": {
- "tslib": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
- "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
- }
- }
- },
- "@firebase/app-types": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.3.2.tgz",
- "integrity": "sha512-ZD8lTgW07NGgo75bTyBJA8Lt9+NweNzot7lrsBtIvfciwUzaFJLsv2EShqjBeuhF7RpG6YFucJ6m67w5buCtzw=="
- },
- "@firebase/auth": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.7.0.tgz",
- "integrity": "sha512-OUjjtq91VFALUjVYp9meHMNtG40mibzkPKIWKAVkc3zucXORShxsDBGRlXjrVSENrQDr7FLrOF2kWCZXwvjiFQ==",
- "requires": {
- "@firebase/auth-types": "0.3.4"
- }
- },
- "@firebase/auth-types": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.3.4.tgz",
- "integrity": "sha512-0r3gSQk9jw5orFHCTUIgao0zan6dHt2J0BO3t/uEzbod+uwqvUn/gh+yg+kK6HX92Fg8E7y030KX4Bw/aXt0Ew=="
- },
- "@firebase/database": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.3.4.tgz",
- "integrity": "sha512-xsQPk4MJq8KuuEq0QXYVWsQc+ksMeoYpmiYWM9UWIoT20PqmZ2WHmxLkVW7xFnM55wsawJ2FtW/Nan9uMhS1nw==",
- "requires": {
- "@firebase/database-types": "0.3.2",
- "@firebase/logger": "0.1.1",
- "@firebase/util": "0.2.1",
- "faye-websocket": "0.11.1",
- "tslib": "1.9.0"
- },
- "dependencies": {
- "faye-websocket": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
- "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=",
- "requires": {
- "websocket-driver": ">=0.5.1"
- }
- },
- "tslib": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
- "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
- }
- }
- },
- "@firebase/database-types": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.3.2.tgz",
- "integrity": "sha512-9ZYdvYQ6r3aaHJarhUM5Hf6lQWu3ZJme+RR0o8qfBb9L04TL3uNjt+AJFku1ysVPntTn+9GqJjiIB2/OC3JtwA=="
- },
- "@firebase/firestore": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-0.5.6.tgz",
- "integrity": "sha512-0D8HRi3S9sF+dDN2O7JwYe/tXSoQRwgO/q4DhbgS+Btd0KPgz+I/+TP6kEqA4g74PgpX06ND6LWvfE5eIUXcyA==",
- "requires": {
- "@firebase/firestore-types": "0.4.3",
- "@firebase/logger": "0.1.1",
- "@firebase/webchannel-wrapper": "0.2.8",
- "grpc": "1.11.3",
- "tslib": "1.9.0"
- },
- "dependencies": {
- "tslib": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
- "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
- }
- }
- },
- "@firebase/firestore-types": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-0.4.3.tgz",
- "integrity": "sha512-QdFBhH0Bcw7TRodN6nJ1pQq0AGAgMfpIUQguKcogTE/2L/lAECxbUfTWtBcGenKcSKpae5xJuuhGZxaPGkQv7A=="
- },
- "@firebase/functions": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.3.0.tgz",
- "integrity": "sha512-bCJmcniVbCdPcydI+CdeEkDidlBnJRsc667ETvljwfnp+df4Em2ZSqcEG8DApzuyd+uI+rYFCvwX5FS4pkFkcA==",
- "requires": {
- "@firebase/functions-types": "0.2.0",
- "@firebase/messaging-types": "0.2.3",
- "isomorphic-fetch": "2.2.1",
- "tslib": "1.9.0"
- },
- "dependencies": {
- "tslib": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
- "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
- }
- }
- },
- "@firebase/functions-types": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.2.0.tgz",
- "integrity": "sha512-q1FB3YKEAnWd+FpIL5Xn0B1BXO2IowrAdrSViXkFxNZVpp9iCzQ8Ytcbr3V1xUr3dnmoW/V7zkZJZGuwBgiVhw=="
- },
- "@firebase/logger": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.1.tgz",
- "integrity": "sha512-5jn3HHbEfdOwychyIEIkP1cik+MW/vvoOavTOzwDkH+fv6Bx+HBUOzh09M7sCYzXFtKzjbUax9+g39mJNBLklQ=="
- },
- "@firebase/messaging": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.3.5.tgz",
- "integrity": "sha512-+FkrW+li/QOqSXUGipOEvqPUSy1/ZH7zibB63UtRHy3LSwxn5PZ6lKgaeCVkWZBwCHm92riHrjR0cpRhE4+4SQ==",
- "requires": {
- "@firebase/messaging-types": "0.2.3",
- "@firebase/util": "0.2.1",
- "tslib": "1.9.0"
- },
- "dependencies": {
- "tslib": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
- "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
- }
- }
- },
- "@firebase/messaging-types": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.2.3.tgz",
- "integrity": "sha512-avwCgZzcx2uxIW/wT3p3G/EyHftIrvMyiTS7AA7dxDlzfx+8dpAeTsb1+jsHJT4F6foSh5HG17Nw8sDzYuxH1Q=="
- },
- "@firebase/polyfill": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.3.tgz",
- "integrity": "sha512-xs8IZf1WEbufYXyfV8YjmiFZOaujRRq0T03NteihYfuGVTTym7z5SmvLvEHLEUjf2fgeobPEzZ2JgrCQHS+QHw==",
- "requires": {
- "core-js": "2.5.5",
- "promise-polyfill": "7.1.2",
- "whatwg-fetch": "2.0.4"
- },
- "dependencies": {
- "core-js": {
- "version": "2.5.5",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz",
- "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs="
- }
- }
- },
- "@firebase/storage": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.2.3.tgz",
- "integrity": "sha512-2sq5jckWszW53gfQMkPNc7EumJ92oErRhzGJANbVzBumwR8qwKZU8/I+/uV9SPK1tVmSUc3S21jdoW5oOJVEuA==",
- "requires": {
- "@firebase/storage-types": "0.2.3",
- "tslib": "1.9.0"
- },
- "dependencies": {
- "tslib": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
- "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
- }
- }
- },
- "@firebase/storage-types": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.2.3.tgz",
- "integrity": "sha512-RaZeam2LgsB7xwAtOQr4G0Geoyf7D5TnLF3a12By6Rh0Z9PqBSlWn0SVYGW3SkmxIdqvWZMZvCyamUlqQvQzWw=="
- },
- "@firebase/util": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.1.tgz",
- "integrity": "sha512-KPNcIK5+bUUBMII87NqGu+tRUnMcY95xujS2z0QyAfoQCKe11DMHICv3M6uweiLSXqdQwrMTyFtiql1q+0UOYQ==",
- "requires": {
- "tslib": "1.9.0"
- },
- "dependencies": {
- "tslib": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
- "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
- }
- }
- },
- "@firebase/webchannel-wrapper": {
- "version": "0.2.8",
- "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.8.tgz",
- "integrity": "sha512-ToJbeJnxDc3O325FvcKVb3yHO1hvgHjCFvhKol6Z17GiB7vL104POjFQT4RnlLiAGSRCBAMxinDec9y9vQYdyg=="
- },
- "@ngtools/webpack": {
- "version": "6.0.8",
- "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-6.0.8.tgz",
- "integrity": "sha512-jorGpTd82ILbyUwg4JQekovHFaYwSMlZan4f7x+sd3+2WgyL3Z1+ZbVSGKvXZWKS/mAVx7eLkRikzJkuC4FgHw==",
- "dev": true,
- "requires": {
- "@angular-devkit/core": "0.6.8",
- "tree-kill": "^1.0.0",
- "webpack-sources": "^1.1.0"
- }
- },
- "@schematics/angular": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.6.8.tgz",
- "integrity": "sha512-9kRphqTYG5Df/I8fvnT1zMsw0YNDPO9tl18tQZXj4am4raT7l9UCr+WkwJdlBoA5pwG6baWE9sL0iGWV/bzF/g==",
- "dev": true,
- "requires": {
- "@angular-devkit/core": "0.6.8",
- "@angular-devkit/schematics": "0.6.8",
- "typescript": ">=2.6.2 <2.8"
- }
- },
- "@schematics/update": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.6.8.tgz",
- "integrity": "sha512-1Uq7LYnwL2wBwGVCgNz76QAR13ghAk+2vDDHOi+VX5+usHManxydrpoMGeX66OBPd+y5D3D2MFb+8mYHE7mygg==",
- "dev": true,
- "requires": {
- "@angular-devkit/core": "0.6.8",
- "@angular-devkit/schematics": "0.6.8",
- "npm-registry-client": "^8.5.1",
- "rxjs": "^6.0.0",
- "semver": "^5.3.0",
- "semver-intersect": "^1.1.2"
- }
- },
- "@types/jasmine": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.8.tgz",
- "integrity": "sha512-OJSUxLaxXsjjhob2DBzqzgrkLmukM3+JMpRp0r0E4HTdT1nwDCWhaswjYxazPij6uOdzHCJfNbDjmQ1/rnNbCg==",
- "dev": true
- },
- "@types/jasminewd2": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.3.tgz",
- "integrity": "sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==",
- "dev": true,
- "requires": {
- "@types/jasmine": "*"
- }
- },
- "@types/node": {
- "version": "8.9.5",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-8.9.5.tgz",
- "integrity": "sha512-jRHfWsvyMtXdbhnz5CVHxaBgnV6duZnPlQuRSo/dm/GnmikNcmZhxIES4E9OZjUmQ8C+HCl4KJux+cXN/ErGDQ==",
- "dev": true
- },
- "@types/q": {
- "version": "0.0.32",
- "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz",
- "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=",
- "dev": true
- },
- "@types/selenium-webdriver": {
- "version": "2.53.43",
- "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz",
- "integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==",
- "dev": true
- },
- "@webassemblyjs/ast": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.4.3.tgz",
- "integrity": "sha512-S6npYhPcTHDYe9nlsKa9CyWByFi8Vj8HovcAgtmMAQZUOczOZbQ8CnwMYKYC5HEZzxEE+oY0jfQk4cVlI3J59Q==",
- "dev": true,
- "requires": {
- "@webassemblyjs/helper-wasm-bytecode": "1.4.3",
- "@webassemblyjs/wast-parser": "1.4.3",
- "debug": "^3.1.0",
- "webassemblyjs": "1.4.3"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "@webassemblyjs/floating-point-hex-parser": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.4.3.tgz",
- "integrity": "sha512-3zTkSFswwZOPNHnzkP9ONq4bjJSeKVMcuahGXubrlLmZP8fmTIJ58dW7h/zOVWiFSuG2em3/HH3BlCN7wyu9Rw==",
- "dev": true
- },
- "@webassemblyjs/helper-buffer": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.4.3.tgz",
- "integrity": "sha512-e8+KZHh+RV8MUvoSRtuT1sFXskFnWG9vbDy47Oa166xX+l0dD5sERJ21g5/tcH8Yo95e9IN3u7Jc3NbhnUcSkw==",
- "dev": true,
- "requires": {
- "debug": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "@webassemblyjs/helper-code-frame": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.4.3.tgz",
- "integrity": "sha512-9FgHEtNsZQYaKrGCtsjswBil48Qp1agrzRcPzCbQloCoaTbOXLJ9IRmqT+uEZbenpULLRNFugz3I4uw18hJM8w==",
- "dev": true,
- "requires": {
- "@webassemblyjs/wast-printer": "1.4.3"
- }
- },
- "@webassemblyjs/helper-fsm": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.4.3.tgz",
- "integrity": "sha512-JINY76U+702IRf7ePukOt037RwmtH59JHvcdWbTTyHi18ixmQ+uOuNhcdCcQHTquDAH35/QgFlp3Y9KqtyJsCQ==",
- "dev": true
- },
- "@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.4.3.tgz",
- "integrity": "sha512-I7bS+HaO0K07Io89qhJv+z1QipTpuramGwUSDkwEaficbSvCcL92CUZEtgykfNtk5wb0CoLQwWlmXTwGbNZUeQ==",
- "dev": true
- },
- "@webassemblyjs/helper-wasm-section": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.4.3.tgz",
- "integrity": "sha512-p0yeeO/h2r30PyjnJX9xXSR6EDcvJd/jC6xa/Pxg4lpfcNi7JUswOpqDToZQ55HMMVhXDih/yqkaywHWGLxqyQ==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/helper-buffer": "1.4.3",
- "@webassemblyjs/helper-wasm-bytecode": "1.4.3",
- "@webassemblyjs/wasm-gen": "1.4.3",
- "debug": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "@webassemblyjs/leb128": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.4.3.tgz",
- "integrity": "sha512-4u0LJLSPzuRDWHwdqsrThYn+WqMFVqbI2ltNrHvZZkzFPO8XOZ0HFQ5eVc4jY/TNHgXcnwrHjONhPGYuuf//KQ==",
- "dev": true,
- "requires": {
- "leb": "^0.3.0"
- }
- },
- "@webassemblyjs/validation": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/validation/-/validation-1.4.3.tgz",
- "integrity": "sha512-R+rRMKfhd9mq0rj2mhU9A9NKI2l/Rw65vIYzz4lui7eTKPcCu1l7iZNi4b9Gen8D42Sqh/KGiaQNk/x5Tn/iBQ==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3"
- }
- },
- "@webassemblyjs/wasm-edit": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.4.3.tgz",
- "integrity": "sha512-qzuwUn771PV6/LilqkXcS0ozJYAeY/OKbXIWU3a8gexuqb6De2p4ya/baBeH5JQ2WJdfhWhSvSbu86Vienttpw==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/helper-buffer": "1.4.3",
- "@webassemblyjs/helper-wasm-bytecode": "1.4.3",
- "@webassemblyjs/helper-wasm-section": "1.4.3",
- "@webassemblyjs/wasm-gen": "1.4.3",
- "@webassemblyjs/wasm-opt": "1.4.3",
- "@webassemblyjs/wasm-parser": "1.4.3",
- "@webassemblyjs/wast-printer": "1.4.3",
- "debug": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "@webassemblyjs/wasm-gen": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.4.3.tgz",
- "integrity": "sha512-eR394T8dHZfpLJ7U/Z5pFSvxl1L63JdREebpv9gYc55zLhzzdJPAuxjBYT4XqevUdW67qU2s0nNA3kBuNJHbaQ==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/helper-wasm-bytecode": "1.4.3",
- "@webassemblyjs/leb128": "1.4.3"
- }
- },
- "@webassemblyjs/wasm-opt": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.4.3.tgz",
- "integrity": "sha512-7Gp+nschuKiDuAL1xmp4Xz0rgEbxioFXw4nCFYEmy+ytynhBnTeGc9W9cB1XRu1w8pqRU2lbj2VBBA4cL5Z2Kw==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/helper-buffer": "1.4.3",
- "@webassemblyjs/wasm-gen": "1.4.3",
- "@webassemblyjs/wasm-parser": "1.4.3",
- "debug": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "@webassemblyjs/wasm-parser": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.4.3.tgz",
- "integrity": "sha512-KXBjtlwA3BVukR/yWHC9GF+SCzBcgj0a7lm92kTOaa4cbjaTaa47bCjXw6cX4SGQpkncB9PU2hHGYVyyI7wFRg==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/helper-wasm-bytecode": "1.4.3",
- "@webassemblyjs/leb128": "1.4.3",
- "@webassemblyjs/wasm-parser": "1.4.3",
- "webassemblyjs": "1.4.3"
- }
- },
- "@webassemblyjs/wast-parser": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.4.3.tgz",
- "integrity": "sha512-QhCsQzqV0CpsEkRYyTzQDilCNUZ+5j92f+g35bHHNqS22FppNTywNFfHPq8ZWZfYCgbectc+PoghD+xfzVFh1Q==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/floating-point-hex-parser": "1.4.3",
- "@webassemblyjs/helper-code-frame": "1.4.3",
- "@webassemblyjs/helper-fsm": "1.4.3",
- "long": "^3.2.0",
- "webassemblyjs": "1.4.3"
- }
- },
- "@webassemblyjs/wast-printer": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.4.3.tgz",
- "integrity": "sha512-EgXk4anf8jKmuZJsqD8qy5bz2frEQhBvZruv+bqwNoLWUItjNSFygk8ywL3JTEz9KtxTlAmqTXNrdD1d9gNDtg==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/wast-parser": "1.4.3",
- "long": "^3.2.0"
- }
- },
- "@webpack-contrib/schema-utils": {
- "version": "1.0.0-beta.0",
- "resolved": "https://registry.npmjs.org/@webpack-contrib/schema-utils/-/schema-utils-1.0.0-beta.0.tgz",
- "integrity": "sha512-LonryJP+FxQQHsjGBi6W786TQB1Oym+agTpY0c+Kj8alnIw+DLUJb6SI8Y1GHGhLCH1yPRrucjObUmxNICQ1pg==",
- "dev": true,
- "requires": {
- "ajv": "^6.1.0",
- "ajv-keywords": "^3.1.0",
- "chalk": "^2.3.2",
- "strip-ansi": "^4.0.0",
- "text-table": "^0.2.0",
- "webpack-log": "^1.1.2"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
- "abbrev": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
- "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
- "dev": true
- },
- "accepts": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
- "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
- "dev": true,
- "requires": {
- "mime-types": "~2.1.18",
- "negotiator": "0.6.1"
- }
- },
- "acorn": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
- "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
- "dev": true
- },
- "acorn-dynamic-import": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz",
- "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==",
- "dev": true,
- "requires": {
- "acorn": "^5.0.0"
- }
- },
- "adm-zip": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz",
- "integrity": "sha1-ph7VrmkFw66lizplfSUDMJEFJzY=",
- "dev": true
- },
- "after": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
- "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
- "dev": true
- },
- "agent-base": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz",
- "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==",
- "dev": true,
- "requires": {
- "es6-promisify": "^5.0.0"
- }
- },
- "ajv": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz",
- "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=",
- "dev": true,
- "requires": {
- "fast-deep-equal": "^1.0.0",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.3.0",
- "uri-js": "^3.0.2"
- }
- },
- "ajv-keywords": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
- "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
- "dev": true
- },
- "align-text": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
- "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
- "requires": {
- "kind-of": "^3.0.2",
- "longest": "^1.0.1",
- "repeat-string": "^1.5.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "amdefine": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
- "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
- "dev": true
- },
- "angularfire2": {
- "version": "5.0.0-rc.11",
- "resolved": "https://registry.npmjs.org/angularfire2/-/angularfire2-5.0.0-rc.11.tgz",
- "integrity": "sha512-Jr6uEquMRuJSgYTw8YxNkDwpkvg2CDJtLlQD0AdMXYoUAwcgsIE4ar7qatIJ2/fwX12TO+oPooCyr0G4GjdwXQ=="
- },
- "ansi-html": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
- "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
- "dev": true
- },
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true
- },
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "requires": {
- "color-convert": "^1.9.0"
- }
- },
- "anymatch": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
- "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
- "dev": true,
- "requires": {
- "micromatch": "^3.1.4",
- "normalize-path": "^2.1.1"
- }
- },
- "app-root-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.1.0.tgz",
- "integrity": "sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo=",
- "dev": true
- },
- "append-transform": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz",
- "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==",
- "dev": true,
- "requires": {
- "default-require-extensions": "^2.0.0"
- }
- },
- "aproba": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
- "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
- "dev": true
- },
- "are-we-there-yet": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
- "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
- "dev": true,
- "requires": {
- "delegates": "^1.0.0",
- "readable-stream": "^2.0.6"
- }
- },
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "requires": {
- "sprintf-js": "~1.0.2"
- }
- },
- "arr-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
- "dev": true
- },
- "arr-flatten": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
- "dev": true
- },
- "arr-union": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
- "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
- "dev": true
- },
- "array-find-index": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
- "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
- "dev": true
- },
- "array-flatten": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz",
- "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=",
- "dev": true
- },
- "array-includes": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
- "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.2",
- "es-abstract": "^1.7.0"
- }
- },
- "array-slice": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
- "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
- "dev": true
- },
- "array-union": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
- "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
- "dev": true,
- "requires": {
- "array-uniq": "^1.0.1"
- }
- },
- "array-uniq": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
- "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
- "dev": true
- },
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
- },
- "arraybuffer.slice": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz",
- "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=",
- "dev": true
- },
- "arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
- "dev": true
- },
- "asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
- "dev": true,
- "optional": true
- },
- "ascli": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz",
- "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=",
- "requires": {
- "colour": "~0.7.1",
- "optjs": "~3.2.2"
- }
- },
- "asn1": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
- "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
- "dev": true
- },
- "asn1.js": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
- "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
- "dev": true,
- "requires": {
- "bn.js": "^4.0.0",
- "inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0"
- }
- },
- "assert": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
- "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
- "dev": true,
- "requires": {
- "util": "0.10.3"
- },
- "dependencies": {
- "inherits": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
- "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
- "dev": true
- },
- "util": {
- "version": "0.10.3",
- "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
- "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
- "dev": true,
- "requires": {
- "inherits": "2.0.1"
- }
- }
- }
- },
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
- "dev": true
- },
- "assign-symbols": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
- "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
- "dev": true
- },
- "async": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
- "dev": true
- },
- "async-each": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
- "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
- "dev": true
- },
- "async-foreach": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
- "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
- "dev": true,
- "optional": true
- },
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
- "dev": true
- },
- "atob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
- "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
- "dev": true
- },
- "autoprefixer": {
- "version": "8.6.4",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.4.tgz",
- "integrity": "sha512-9D0OoxWCqq9Okp9wD+igaCf6ZaNjYNFSCKxgMLAxAGqXwpapaZ+D0PBv265VHQLgam8a7gld4E6KgJJM6SKfQQ==",
- "dev": true,
- "requires": {
- "browserslist": "^3.2.8",
- "caniuse-lite": "^1.0.30000859",
- "normalize-range": "^0.1.2",
- "num2fraction": "^1.2.2",
- "postcss": "^6.0.23",
- "postcss-value-parser": "^3.2.3"
- }
- },
- "aws-sign2": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
- "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
- "dev": true
- },
- "aws4": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
- "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==",
- "dev": true
- },
- "babel-code-frame": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
- "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
- "dev": true,
- "requires": {
- "chalk": "^1.1.3",
- "esutils": "^2.0.2",
- "js-tokens": "^3.0.2"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "dev": true,
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true
- }
- }
- },
- "babel-generator": {
- "version": "6.26.1",
- "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
- "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
- "dev": true,
- "requires": {
- "babel-messages": "^6.23.0",
- "babel-runtime": "^6.26.0",
- "babel-types": "^6.26.0",
- "detect-indent": "^4.0.0",
- "jsesc": "^1.3.0",
- "lodash": "^4.17.4",
- "source-map": "^0.5.7",
- "trim-right": "^1.0.1"
- }
- },
- "babel-messages": {
- "version": "6.23.0",
- "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
- "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
- "dev": true,
- "requires": {
- "babel-runtime": "^6.22.0"
- }
- },
- "babel-runtime": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
- "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
- "dev": true,
- "requires": {
- "core-js": "^2.4.0",
- "regenerator-runtime": "^0.11.0"
- }
- },
- "babel-template": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
- "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
- "dev": true,
- "requires": {
- "babel-runtime": "^6.26.0",
- "babel-traverse": "^6.26.0",
- "babel-types": "^6.26.0",
- "babylon": "^6.18.0",
- "lodash": "^4.17.4"
- }
- },
- "babel-traverse": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
- "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
- "dev": true,
- "requires": {
- "babel-code-frame": "^6.26.0",
- "babel-messages": "^6.23.0",
- "babel-runtime": "^6.26.0",
- "babel-types": "^6.26.0",
- "babylon": "^6.18.0",
- "debug": "^2.6.8",
- "globals": "^9.18.0",
- "invariant": "^2.2.2",
- "lodash": "^4.17.4"
- }
- },
- "babel-types": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
- "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
- "dev": true,
- "requires": {
- "babel-runtime": "^6.26.0",
- "esutils": "^2.0.2",
- "lodash": "^4.17.4",
- "to-fast-properties": "^1.0.3"
- }
- },
- "babylon": {
- "version": "6.18.0",
- "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
- "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
- "dev": true
- },
- "backo2": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
- "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
- "dev": true
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "base": {
- "version": "0.11.2",
- "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
- "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
- "dev": true,
- "requires": {
- "cache-base": "^1.0.1",
- "class-utils": "^0.3.5",
- "component-emitter": "^1.2.1",
- "define-property": "^1.0.0",
- "isobject": "^3.0.1",
- "mixin-deep": "^1.2.0",
- "pascalcase": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "base64-arraybuffer": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
- "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
- "dev": true
- },
- "base64-js": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
- "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
- "dev": true
- },
- "base64id": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
- "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
- "dev": true
- },
- "batch": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
- "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
- "dev": true
- },
- "bcrypt-pbkdf": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
- "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
- "dev": true,
- "optional": true,
- "requires": {
- "tweetnacl": "^0.14.3"
- }
- },
- "better-assert": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
- "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
- "dev": true,
- "requires": {
- "callsite": "1.0.0"
- }
- },
- "big.js": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
- "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
- "dev": true
- },
- "binary-extensions": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
- "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
- "dev": true
- },
- "blob": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
- "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=",
- "dev": true
- },
- "block-stream": {
- "version": "0.0.9",
- "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
- "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
- "dev": true,
- "optional": true,
- "requires": {
- "inherits": "~2.0.0"
- }
- },
- "blocking-proxy": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz",
- "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==",
- "dev": true,
- "requires": {
- "minimist": "^1.2.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
- }
- },
- "bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
- "dev": true
- },
- "bn.js": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
- "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
- "dev": true
- },
- "body-parser": {
- "version": "1.18.2",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
- "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
- "dev": true,
- "requires": {
- "bytes": "3.0.0",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "~1.1.1",
- "http-errors": "~1.6.2",
- "iconv-lite": "0.4.19",
- "on-finished": "~2.3.0",
- "qs": "6.5.1",
- "raw-body": "2.3.2",
- "type-is": "~1.6.15"
- },
- "dependencies": {
- "qs": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
- "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
- "dev": true
- }
- }
- },
- "bonjour": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
- "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
- "dev": true,
- "requires": {
- "array-flatten": "^2.1.0",
- "deep-equal": "^1.0.1",
- "dns-equal": "^1.0.0",
- "dns-txt": "^2.0.2",
- "multicast-dns": "^6.0.1",
- "multicast-dns-service-types": "^1.1.0"
- }
- },
- "boolbase": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
- "dev": true
- },
- "boom": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
- "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
- "dev": true,
- "requires": {
- "hoek": "2.x.x"
- }
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "brorand": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
- "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
- "dev": true
- },
- "browserify-aes": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
- "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
- "dev": true,
- "requires": {
- "buffer-xor": "^1.0.3",
- "cipher-base": "^1.0.0",
- "create-hash": "^1.1.0",
- "evp_bytestokey": "^1.0.3",
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "browserify-cipher": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
- "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
- "dev": true,
- "requires": {
- "browserify-aes": "^1.0.4",
- "browserify-des": "^1.0.0",
- "evp_bytestokey": "^1.0.0"
- }
- },
- "browserify-des": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz",
- "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==",
- "dev": true,
- "requires": {
- "cipher-base": "^1.0.1",
- "des.js": "^1.0.0",
- "inherits": "^2.0.1"
- }
- },
- "browserify-rsa": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
- "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
- "dev": true,
- "requires": {
- "bn.js": "^4.1.0",
- "randombytes": "^2.0.1"
- }
- },
- "browserify-sign": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
- "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
- "dev": true,
- "requires": {
- "bn.js": "^4.1.1",
- "browserify-rsa": "^4.0.0",
- "create-hash": "^1.1.0",
- "create-hmac": "^1.1.2",
- "elliptic": "^6.0.0",
- "inherits": "^2.0.1",
- "parse-asn1": "^5.0.0"
- }
- },
- "browserify-zlib": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
- "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
- "dev": true,
- "requires": {
- "pako": "~1.0.5"
- }
- },
- "browserslist": {
- "version": "3.2.8",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
- "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
- "dev": true,
- "requires": {
- "caniuse-lite": "^1.0.30000844",
- "electron-to-chromium": "^1.3.47"
- }
- },
- "buffer": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
- "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
- "dev": true,
- "requires": {
- "base64-js": "^1.0.2",
- "ieee754": "^1.1.4",
- "isarray": "^1.0.0"
- }
- },
- "buffer-from": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
- "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==",
- "dev": true
- },
- "buffer-indexof": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
- "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
- "dev": true
- },
- "buffer-xor": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
- "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
- "dev": true
- },
- "builtin-modules": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
- "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
- "dev": true
- },
- "builtin-status-codes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
- "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
- "dev": true
- },
- "builtins": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
- "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
- "dev": true
- },
- "bytebuffer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz",
- "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=",
- "requires": {
- "long": "~3"
- }
- },
- "bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
- "dev": true
- },
- "cacache": {
- "version": "10.0.4",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
- "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
- "dev": true,
- "requires": {
- "bluebird": "^3.5.1",
- "chownr": "^1.0.1",
- "glob": "^7.1.2",
- "graceful-fs": "^4.1.11",
- "lru-cache": "^4.1.1",
- "mississippi": "^2.0.0",
- "mkdirp": "^0.5.1",
- "move-concurrently": "^1.0.1",
- "promise-inflight": "^1.0.1",
- "rimraf": "^2.6.2",
- "ssri": "^5.2.4",
- "unique-filename": "^1.1.0",
- "y18n": "^4.0.0"
- }
- },
- "cache-base": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
- "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
- "dev": true,
- "requires": {
- "collection-visit": "^1.0.0",
- "component-emitter": "^1.2.1",
- "get-value": "^2.0.6",
- "has-value": "^1.0.0",
- "isobject": "^3.0.1",
- "set-value": "^2.0.0",
- "to-object-path": "^0.3.0",
- "union-value": "^1.0.0",
- "unset-value": "^1.0.0"
- }
- },
- "cache-loader": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-1.2.2.tgz",
- "integrity": "sha512-rsGh4SIYyB9glU+d0OcHwiXHXBoUgDhHZaQ1KAbiXqfz1CDPxtTboh1gPbJ0q2qdO8a9lfcjgC5CJ2Ms32y5bw==",
- "dev": true,
- "requires": {
- "loader-utils": "^1.1.0",
- "mkdirp": "^0.5.1",
- "neo-async": "^2.5.0",
- "schema-utils": "^0.4.2"
- }
- },
- "callsite": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
- "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
- "dev": true
- },
- "camel-case": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
- "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
- "dev": true,
- "requires": {
- "no-case": "^2.2.0",
- "upper-case": "^1.1.1"
- }
- },
- "camelcase": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
- "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
- },
- "camelcase-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
- "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
- "dev": true,
- "requires": {
- "camelcase": "^2.0.0",
- "map-obj": "^1.0.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
- "dev": true
- }
- }
- },
- "caniuse-lite": {
- "version": "1.0.30000864",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000864.tgz",
- "integrity": "sha512-8fuGh8n3MIQ7oBkO/ck7J4LXhV5Sz5aLyFmfpChWpK+rJhqYrOsGDdbBVDdyKIRBWamZpy6iM4OmLCFVudOOhg==",
- "dev": true
- },
- "caseless": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
- "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
- "dev": true
- },
- "center-align": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
- "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
- "requires": {
- "align-text": "^0.1.3",
- "lazy-cache": "^1.0.3"
- }
- },
- "chalk": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz",
- "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.1.0",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^4.0.0"
- },
- "dependencies": {
- "has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
- "dev": true
- },
- "supports-color": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
- "dev": true,
- "requires": {
- "has-flag": "^2.0.0"
- }
- }
- }
- },
- "chokidar": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
- "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
- "dev": true,
- "requires": {
- "anymatch": "^2.0.0",
- "async-each": "^1.0.0",
- "braces": "^2.3.0",
- "fsevents": "^1.2.2",
- "glob-parent": "^3.1.0",
- "inherits": "^2.0.1",
- "is-binary-path": "^1.0.0",
- "is-glob": "^4.0.0",
- "lodash.debounce": "^4.0.8",
- "normalize-path": "^2.1.1",
- "path-is-absolute": "^1.0.0",
- "readdirp": "^2.0.0",
- "upath": "^1.0.5"
- }
- },
- "chownr": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
- "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
- "dev": true
- },
- "chrome-trace-event": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz",
- "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==",
- "dev": true
- },
- "cipher-base": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
- "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "circular-dependency-plugin": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.0.2.tgz",
- "integrity": "sha512-oC7/DVAyfcY3UWKm0sN/oVoDedQDQiw/vIiAnuTWTpE5s0zWf7l3WY417Xw/Fbi/QbAjctAkxgMiS9P0s3zkmA==",
- "dev": true
- },
- "class-utils": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
- "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "define-property": "^0.2.5",
- "isobject": "^3.0.0",
- "static-extend": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
- }
- },
- "clean-css": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz",
- "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=",
- "dev": true,
- "requires": {
- "source-map": "0.5.x"
- }
- },
- "cliui": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
- "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
- "requires": {
- "center-align": "^0.1.1",
- "right-align": "^0.1.1",
- "wordwrap": "0.0.2"
- },
- "dependencies": {
- "wordwrap": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
- "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
- }
- }
- },
- "clone": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
- "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
- "dev": true
- },
- "clone-deep": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz",
- "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==",
- "dev": true,
- "requires": {
- "for-own": "^1.0.0",
- "is-plain-object": "^2.0.4",
- "kind-of": "^6.0.0",
- "shallow-clone": "^1.0.0"
- }
- },
- "co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
- "dev": true
- },
- "code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
- "dev": true
- },
- "codelyzer": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.2.1.tgz",
- "integrity": "sha512-CKwfgpfkqi9dyzy4s6ELaxJ54QgJ6A8iTSsM4bzHbLuTpbKncvNc3DUlCvpnkHBhK47gEf4qFsWoYqLrJPhy6g==",
- "dev": true,
- "requires": {
- "app-root-path": "^2.0.1",
- "css-selector-tokenizer": "^0.7.0",
- "cssauron": "^1.4.0",
- "semver-dsl": "^1.0.1",
- "source-map": "^0.5.6",
- "sprintf-js": "^1.0.3"
- }
- },
- "collection-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
- "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
- "dev": true,
- "requires": {
- "map-visit": "^1.0.0",
- "object-visit": "^1.0.0"
- }
- },
- "color-convert": {
- "version": "1.9.2",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz",
- "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==",
- "dev": true,
- "requires": {
- "color-name": "1.1.1"
- }
- },
- "color-name": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz",
- "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=",
- "dev": true
- },
- "colors": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
- "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
- "dev": true
- },
- "colour": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz",
- "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g="
- },
- "combine-lists": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz",
- "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=",
- "dev": true,
- "requires": {
- "lodash": "^4.5.0"
- }
- },
- "combined-stream": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
- "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
- "dev": true,
- "requires": {
- "delayed-stream": "~1.0.0"
- }
- },
- "commander": {
- "version": "2.16.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz",
- "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==",
- "dev": true
- },
- "commondir": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
- "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
- "dev": true
- },
- "compare-versions": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.3.0.tgz",
- "integrity": "sha512-MAAAIOdi2s4Gl6rZ76PNcUa9IOYB+5ICdT41o5uMRf09aEu/F9RK+qhe8RjXNPwcTjGV7KU7h2P/fljThFVqyQ==",
- "dev": true
- },
- "component-bind": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
- "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
- "dev": true
- },
- "component-emitter": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
- "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
- "dev": true
- },
- "component-inherit": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
- "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
- "dev": true
- },
- "compressible": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz",
- "integrity": "sha1-MmxfUH+7BV9UEWeCuWmoG2einac=",
- "dev": true,
- "requires": {
- "mime-db": ">= 1.34.0 < 2"
- },
- "dependencies": {
- "mime-db": {
- "version": "1.34.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.34.0.tgz",
- "integrity": "sha1-RS0Oz/XDA0am3B5kseruDTcZ/5o=",
- "dev": true
- }
- }
- },
- "compression": {
- "version": "1.7.2",
- "resolved": "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz",
- "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=",
- "dev": true,
- "requires": {
- "accepts": "~1.3.4",
- "bytes": "3.0.0",
- "compressible": "~2.0.13",
- "debug": "2.6.9",
- "on-headers": "~1.0.1",
- "safe-buffer": "5.1.1",
- "vary": "~1.1.2"
- },
- "dependencies": {
- "safe-buffer": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
- "dev": true
- }
- }
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "concat-stream": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
- "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
- "dev": true,
- "requires": {
- "buffer-from": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^2.2.2",
- "typedarray": "^0.0.6"
- }
- },
- "connect": {
- "version": "3.6.6",
- "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
- "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "finalhandler": "1.1.0",
- "parseurl": "~1.3.2",
- "utils-merge": "1.0.1"
- },
- "dependencies": {
- "finalhandler": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
- "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.1",
- "escape-html": "~1.0.3",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.2",
- "statuses": "~1.3.1",
- "unpipe": "~1.0.0"
- }
- },
- "statuses": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
- "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
- "dev": true
- }
- }
- },
- "connect-history-api-fallback": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
- "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=",
- "dev": true
- },
- "console-browserify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
- "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
- "dev": true,
- "requires": {
- "date-now": "^0.1.4"
- }
- },
- "console-control-strings": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
- "dev": true
- },
- "constants-browserify": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
- "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
- "dev": true
- },
- "content-disposition": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
- "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
- "dev": true
- },
- "content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
- "dev": true
- },
- "convert-source-map": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
- "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
- "dev": true
- },
- "cookie": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
- "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
- "dev": true
- },
- "cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
- "dev": true
- },
- "copy-concurrently": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
- "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
- "dev": true,
- "requires": {
- "aproba": "^1.1.1",
- "fs-write-stream-atomic": "^1.0.8",
- "iferr": "^0.1.5",
- "mkdirp": "^0.5.1",
- "rimraf": "^2.5.4",
- "run-queue": "^1.0.0"
- }
- },
- "copy-descriptor": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
- "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
- "dev": true
- },
- "copy-webpack-plugin": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.2.tgz",
- "integrity": "sha512-zmC33E8FFSq3AbflTvqvPvBo621H36Afsxlui91d+QyZxPIuXghfnTsa1CuqiAaCPgJoSUWfTFbKJnadZpKEbQ==",
- "dev": true,
- "requires": {
- "cacache": "^10.0.4",
- "find-cache-dir": "^1.0.0",
- "globby": "^7.1.1",
- "is-glob": "^4.0.0",
- "loader-utils": "^1.1.0",
- "minimatch": "^3.0.4",
- "p-limit": "^1.0.0",
- "serialize-javascript": "^1.4.0"
- }
- },
- "core-js": {
- "version": "2.5.7",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
- "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
- },
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
- "dev": true
- },
- "cosmiconfig": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
- "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
- "dev": true,
- "requires": {
- "is-directory": "^0.3.1",
- "js-yaml": "^3.4.3",
- "minimist": "^1.2.0",
- "object-assign": "^4.1.0",
- "os-homedir": "^1.0.1",
- "parse-json": "^2.2.0",
- "require-from-string": "^1.1.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
- }
- },
- "create-ecdh": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
- "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
- "dev": true,
- "requires": {
- "bn.js": "^4.1.0",
- "elliptic": "^6.0.0"
- }
- },
- "create-hash": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
- "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
- "dev": true,
- "requires": {
- "cipher-base": "^1.0.1",
- "inherits": "^2.0.1",
- "md5.js": "^1.3.4",
- "ripemd160": "^2.0.1",
- "sha.js": "^2.4.0"
- }
- },
- "create-hmac": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
- "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
- "dev": true,
- "requires": {
- "cipher-base": "^1.0.3",
- "create-hash": "^1.1.0",
- "inherits": "^2.0.1",
- "ripemd160": "^2.0.0",
- "safe-buffer": "^5.0.1",
- "sha.js": "^2.4.8"
- }
- },
- "cross-spawn": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
- "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
- "dev": true,
- "optional": true,
- "requires": {
- "lru-cache": "^4.0.1",
- "which": "^1.2.9"
- }
- },
- "cryptiles": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
- "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
- "dev": true,
- "optional": true,
- "requires": {
- "boom": "2.x.x"
- }
- },
- "crypto-browserify": {
- "version": "3.12.0",
- "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
- "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
- "dev": true,
- "requires": {
- "browserify-cipher": "^1.0.0",
- "browserify-sign": "^4.0.0",
- "create-ecdh": "^4.0.0",
- "create-hash": "^1.1.0",
- "create-hmac": "^1.1.0",
- "diffie-hellman": "^5.0.0",
- "inherits": "^2.0.1",
- "pbkdf2": "^3.0.3",
- "public-encrypt": "^4.0.0",
- "randombytes": "^2.0.0",
- "randomfill": "^1.0.3"
- }
- },
- "css-parse": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz",
- "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=",
- "dev": true
- },
- "css-select": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
- "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
- "dev": true,
- "requires": {
- "boolbase": "~1.0.0",
- "css-what": "2.1",
- "domutils": "1.5.1",
- "nth-check": "~1.0.1"
- }
- },
- "css-selector-tokenizer": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
- "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
- "dev": true,
- "requires": {
- "cssesc": "^0.1.0",
- "fastparse": "^1.1.1",
- "regexpu-core": "^1.0.0"
- }
- },
- "css-what": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
- "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=",
- "dev": true
- },
- "cssauron": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz",
- "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=",
- "dev": true,
- "requires": {
- "through": "X.X.X"
- }
- },
- "cssesc": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
- "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
- "dev": true
- },
- "cuint": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
- "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=",
- "dev": true
- },
- "currently-unhandled": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
- "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
- "dev": true,
- "requires": {
- "array-find-index": "^1.0.1"
- }
- },
- "custom-event": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
- "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
- "dev": true
- },
- "cyclist": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
- "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
- "dev": true
- },
- "d": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
- "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
- "dev": true,
- "requires": {
- "es5-ext": "^0.10.9"
- }
- },
- "dashdash": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
- "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
- "dev": true,
- "requires": {
- "assert-plus": "^1.0.0"
- }
- },
- "date-now": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
- "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
- "dev": true
- },
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
- },
- "decode-uri-component": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
- "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
- "dev": true
- },
- "deep-equal": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
- "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
- "dev": true
- },
- "deep-is": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
- "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
- "dev": true
- },
- "default-require-extensions": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz",
- "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=",
- "dev": true,
- "requires": {
- "strip-bom": "^3.0.0"
- },
- "dependencies": {
- "strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
- "dev": true
- }
- }
- },
- "define-properties": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
- "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
- "dev": true,
- "requires": {
- "foreach": "^2.0.5",
- "object-keys": "^1.0.8"
- }
- },
- "define-property": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
- "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.2",
- "isobject": "^3.0.1"
- },
- "dependencies": {
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "del": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz",
- "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=",
- "dev": true,
- "requires": {
- "globby": "^6.1.0",
- "is-path-cwd": "^1.0.0",
- "is-path-in-cwd": "^1.0.0",
- "p-map": "^1.1.1",
- "pify": "^3.0.0",
- "rimraf": "^2.2.8"
- },
- "dependencies": {
- "globby": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
- "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
- "dev": true,
- "requires": {
- "array-union": "^1.0.1",
- "glob": "^7.0.3",
- "object-assign": "^4.0.1",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- },
- "dependencies": {
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- }
- }
- }
- }
- },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
- "dev": true
- },
- "delegates": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
- "dev": true
- },
- "depd": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
- "dev": true
- },
- "des.js": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
- "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
- "dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0"
- }
- },
- "destroy": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
- "dev": true
- },
- "detect-indent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
- "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
- "dev": true,
- "requires": {
- "repeating": "^2.0.0"
- }
- },
- "detect-node": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz",
- "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
- "dev": true
- },
- "di": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
- "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
- "dev": true
- },
- "diff": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
- "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
- "dev": true
- },
- "diffie-hellman": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
- "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
- "dev": true,
- "requires": {
- "bn.js": "^4.1.0",
- "miller-rabin": "^4.0.0",
- "randombytes": "^2.0.0"
- }
- },
- "dir-glob": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz",
- "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==",
- "dev": true,
- "requires": {
- "arrify": "^1.0.1",
- "path-type": "^3.0.0"
- }
- },
- "dns-equal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
- "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
- "dev": true
- },
- "dns-packet": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
- "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
- "dev": true,
- "requires": {
- "ip": "^1.1.0",
- "safe-buffer": "^5.0.1"
- }
- },
- "dns-txt": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
- "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
- "dev": true,
- "requires": {
- "buffer-indexof": "^1.0.0"
- }
- },
- "dom-converter": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz",
- "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=",
- "dev": true,
- "requires": {
- "utila": "~0.3"
- },
- "dependencies": {
- "utila": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz",
- "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=",
- "dev": true
- }
- }
- },
- "dom-serialize": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
- "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
- "dev": true,
- "requires": {
- "custom-event": "~1.0.0",
- "ent": "~2.2.0",
- "extend": "^3.0.0",
- "void-elements": "^2.0.0"
- }
- },
- "dom-serializer": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
- "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
- "dev": true,
- "requires": {
- "domelementtype": "~1.1.1",
- "entities": "~1.1.1"
- },
- "dependencies": {
- "domelementtype": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
- "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
- "dev": true
- }
- }
- },
- "dom-storage": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.1.0.tgz",
- "integrity": "sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q=="
- },
- "domain-browser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
- "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
- "dev": true
- },
- "domelementtype": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
- "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
- "dev": true
- },
- "domhandler": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz",
- "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=",
- "dev": true,
- "requires": {
- "domelementtype": "1"
- }
- },
- "domutils": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
- "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
- "dev": true,
- "requires": {
- "dom-serializer": "0",
- "domelementtype": "1"
- }
- },
- "duplexify": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz",
- "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.0.0",
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.0",
- "stream-shift": "^1.0.0"
- }
- },
- "ecc-jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
- "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
- "dev": true,
- "optional": true,
- "requires": {
- "jsbn": "~0.1.0"
- }
- },
- "ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
- "dev": true
- },
- "ejs": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz",
- "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==",
- "dev": true
- },
- "electron-to-chromium": {
- "version": "1.3.51",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.51.tgz",
- "integrity": "sha1-akK0nar38ipbN7mR2vlJ8029ubU=",
- "dev": true
- },
- "elliptic": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
- "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
- "dev": true,
- "requires": {
- "bn.js": "^4.4.0",
- "brorand": "^1.0.1",
- "hash.js": "^1.0.0",
- "hmac-drbg": "^1.0.0",
- "inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0",
- "minimalistic-crypto-utils": "^1.0.0"
- }
- },
- "emojis-list": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
- "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
- "dev": true
- },
- "encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
- "dev": true
- },
- "encoding": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
- "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
- "requires": {
- "iconv-lite": "~0.4.13"
- }
- },
- "end-of-stream": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
- "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
- "dev": true,
- "requires": {
- "once": "^1.4.0"
- }
- },
- "engine.io": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz",
- "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=",
- "dev": true,
- "requires": {
- "accepts": "1.3.3",
- "base64id": "1.0.0",
- "cookie": "0.3.1",
- "debug": "2.3.3",
- "engine.io-parser": "1.3.2",
- "ws": "1.1.2"
- },
- "dependencies": {
- "accepts": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
- "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
- "dev": true,
- "requires": {
- "mime-types": "~2.1.11",
- "negotiator": "0.6.1"
- }
- },
- "debug": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
- "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
- "dev": true,
- "requires": {
- "ms": "0.7.2"
- }
- },
- "ms": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
- "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
- "dev": true
- }
- }
- },
- "engine.io-client": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz",
- "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=",
- "dev": true,
- "requires": {
- "component-emitter": "1.2.1",
- "component-inherit": "0.0.3",
- "debug": "2.3.3",
- "engine.io-parser": "1.3.2",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "parsejson": "0.0.3",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "ws": "1.1.2",
- "xmlhttprequest-ssl": "1.5.3",
- "yeast": "0.1.2"
- },
- "dependencies": {
- "debug": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
- "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
- "dev": true,
- "requires": {
- "ms": "0.7.2"
- }
- },
- "ms": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
- "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
- "dev": true
- }
- }
- },
- "engine.io-parser": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz",
- "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=",
- "dev": true,
- "requires": {
- "after": "0.8.2",
- "arraybuffer.slice": "0.0.6",
- "base64-arraybuffer": "0.1.5",
- "blob": "0.0.4",
- "has-binary": "0.1.7",
- "wtf-8": "1.0.0"
- }
- },
- "enhanced-resolve": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz",
- "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "memory-fs": "^0.4.0",
- "tapable": "^1.0.0"
- }
- },
- "ent": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
- "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
- "dev": true
- },
- "entities": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
- "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
- "dev": true
- },
- "errno": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
- "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
- "dev": true,
- "requires": {
- "prr": "~1.0.1"
- }
- },
- "error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
- "requires": {
- "is-arrayish": "^0.2.1"
- }
- },
- "es-abstract": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
- "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
- "dev": true,
- "requires": {
- "es-to-primitive": "^1.1.1",
- "function-bind": "^1.1.1",
- "has": "^1.0.1",
- "is-callable": "^1.1.3",
- "is-regex": "^1.0.4"
- }
- },
- "es-to-primitive": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
- "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
- "dev": true,
- "requires": {
- "is-callable": "^1.1.1",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.1"
- }
- },
- "es5-ext": {
- "version": "0.10.45",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz",
- "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==",
- "dev": true,
- "requires": {
- "es6-iterator": "~2.0.3",
- "es6-symbol": "~3.1.1",
- "next-tick": "1"
- }
- },
- "es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
- "dev": true,
- "requires": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
- },
- "es6-promise": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
- "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
- "dev": true
- },
- "es6-promisify": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
- "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
- "dev": true,
- "requires": {
- "es6-promise": "^4.0.3"
- }
- },
- "es6-symbol": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
- "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
- "dev": true,
- "requires": {
- "d": "1",
- "es5-ext": "~0.10.14"
- }
- },
- "escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
- "dev": true
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
- },
- "escodegen": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
- "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
- "dev": true,
- "requires": {
- "esprima": "^2.7.1",
- "estraverse": "^1.9.1",
- "esutils": "^2.0.2",
- "optionator": "^0.8.1",
- "source-map": "~0.2.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
- "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
- "dev": true,
- "optional": true,
- "requires": {
- "amdefine": ">=0.0.4"
- }
- }
- }
- },
- "eslint-scope": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
- "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
- "dev": true,
- "requires": {
- "esrecurse": "^4.1.0",
- "estraverse": "^4.1.1"
- },
- "dependencies": {
- "estraverse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
- "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
- "dev": true
- }
- }
- },
- "esprima": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
- "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
- "dev": true
- },
- "esrecurse": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
- "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
- "dev": true,
- "requires": {
- "estraverse": "^4.1.0"
- },
- "dependencies": {
- "estraverse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
- "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
- "dev": true
- }
- }
- },
- "estraverse": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
- "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
- "dev": true
- },
- "esutils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
- "dev": true
- },
- "etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
- "dev": true
- },
- "eventemitter3": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
- "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
- "dev": true
- },
- "events": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
- "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
- "dev": true
- },
- "eventsource": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz",
- "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=",
- "dev": true,
- "requires": {
- "original": ">=0.0.5"
- }
- },
- "evp_bytestokey": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
- "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
- "dev": true,
- "requires": {
- "md5.js": "^1.3.4",
- "safe-buffer": "^5.1.1"
- }
- },
- "execa": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
- "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
- "dev": true,
- "requires": {
- "cross-spawn": "^5.0.1",
- "get-stream": "^3.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
- },
- "dependencies": {
- "cross-spawn": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
- "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
- "dev": true,
- "requires": {
- "lru-cache": "^4.0.1",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- }
- }
- },
- "exit": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
- "dev": true
- },
- "expand-braces": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
- "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=",
- "dev": true,
- "requires": {
- "array-slice": "^0.2.3",
- "array-unique": "^0.2.1",
- "braces": "^0.1.2"
- },
- "dependencies": {
- "array-unique": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
- "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
- "dev": true
- },
- "braces": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz",
- "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=",
- "dev": true,
- "requires": {
- "expand-range": "^0.1.0"
- }
- },
- "expand-range": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz",
- "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=",
- "dev": true,
- "requires": {
- "is-number": "^0.1.1",
- "repeat-string": "^0.2.2"
- }
- },
- "is-number": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz",
- "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=",
- "dev": true
- },
- "repeat-string": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz",
- "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=",
- "dev": true
- }
- }
- },
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "expand-range": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
- "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
- "dev": true,
- "requires": {
- "fill-range": "^2.1.0"
- },
- "dependencies": {
- "fill-range": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
- "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
- "dev": true,
- "requires": {
- "is-number": "^2.1.0",
- "isobject": "^2.0.0",
- "randomatic": "^3.0.0",
- "repeat-element": "^1.1.2",
- "repeat-string": "^1.5.2"
- }
- },
- "is-number": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
- "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- }
- },
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "dev": true,
- "requires": {
- "isarray": "1.0.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "express": {
- "version": "4.16.3",
- "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
- "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
- "dev": true,
- "requires": {
- "accepts": "~1.3.5",
- "array-flatten": "1.1.1",
- "body-parser": "1.18.2",
- "content-disposition": "0.5.2",
- "content-type": "~1.0.4",
- "cookie": "0.3.1",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.1.1",
- "fresh": "0.5.2",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.2",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.3",
- "qs": "6.5.1",
- "range-parser": "~1.2.0",
- "safe-buffer": "5.1.1",
- "send": "0.16.2",
- "serve-static": "1.13.2",
- "setprototypeof": "1.1.0",
- "statuses": "~1.4.0",
- "type-is": "~1.6.16",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "dependencies": {
- "array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
- "dev": true
- },
- "qs": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
- "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
- "dev": true
- },
- "safe-buffer": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
- "dev": true
- }
- }
- },
- "extend": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
- "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
- "dev": true
- },
- "extend-shallow": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
- "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
- "dev": true,
- "requires": {
- "assign-symbols": "^1.0.0",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "extsprintf": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
- "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
- "dev": true
- },
- "fast-deep-equal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
- "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
- "dev": true
- },
- "fast-json-stable-stringify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
- "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
- "dev": true
- },
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
- "dev": true
- },
- "fastparse": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
- "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
- "dev": true
- },
- "faye-websocket": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
- "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
- "dev": true,
- "requires": {
- "websocket-driver": ">=0.5.1"
- }
- },
- "file-loader": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
- "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==",
- "dev": true,
- "requires": {
- "loader-utils": "^1.0.2",
- "schema-utils": "^0.4.5"
- }
- },
- "filename-regex": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
- "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
- "dev": true
- },
- "fileset": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz",
- "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=",
- "dev": true,
- "requires": {
- "glob": "^7.0.3",
- "minimatch": "^3.0.3"
- }
- },
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "finalhandler": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
- "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.2",
- "statuses": "~1.4.0",
- "unpipe": "~1.0.0"
- }
- },
- "find-cache-dir": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
- "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
- "dev": true,
- "requires": {
- "commondir": "^1.0.1",
- "make-dir": "^1.0.0",
- "pkg-dir": "^2.0.0"
- }
- },
- "find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
- "dev": true,
- "requires": {
- "locate-path": "^2.0.0"
- }
- },
- "firebase": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/firebase/-/firebase-5.2.0.tgz",
- "integrity": "sha512-mWrQihqNXLhQWr1TuORN82wwoKDy5Z4OJyUSlv2wp9EaH0m6AkivFoVjHyEHzU54krP940z5PGF3d4nMlRs1gA==",
- "requires": {
- "@firebase/app": "0.3.3",
- "@firebase/auth": "0.7.0",
- "@firebase/database": "0.3.4",
- "@firebase/firestore": "0.5.6",
- "@firebase/functions": "0.3.0",
- "@firebase/messaging": "0.3.5",
- "@firebase/polyfill": "0.3.3",
- "@firebase/storage": "0.2.3"
- }
- },
- "flush-write-stream": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
- "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.4"
- }
- },
- "follow-redirects": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz",
- "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==",
- "dev": true,
- "requires": {
- "debug": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "for-in": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
- "dev": true
- },
- "for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "requires": {
- "for-in": "^1.0.1"
- }
- },
- "foreach": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
- "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
- "dev": true
- },
- "forever-agent": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
- "dev": true
- },
- "form-data": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
- "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
- "dev": true,
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "1.0.6",
- "mime-types": "^2.1.12"
- }
- },
- "forwarded": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
- "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
- "dev": true
- },
- "fragment-cache": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
- "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
- "dev": true,
- "requires": {
- "map-cache": "^0.2.2"
- }
- },
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
- "dev": true
- },
- "from2": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
- "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
- "dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.0"
- }
- },
- "fs-access": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
- "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=",
- "dev": true,
- "requires": {
- "null-check": "^1.0.0"
- }
- },
- "fs-write-stream-atomic": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
- "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "iferr": "^0.1.5",
- "imurmurhash": "^0.1.4",
- "readable-stream": "1 || 2"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "fsevents": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
- "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
- "dev": true,
- "optional": true,
- "requires": {
- "nan": "^2.9.2",
- "node-pre-gyp": "^0.10.0"
- },
- "dependencies": {
- "abbrev": {
- "version": "1.1.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "ansi-regex": {
- "version": "2.1.1",
- "bundled": true,
- "dev": true
- },
- "aproba": {
- "version": "1.2.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "are-we-there-yet": {
- "version": "1.1.4",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "delegates": "^1.0.0",
- "readable-stream": "^2.0.6"
- }
- },
- "balanced-match": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "brace-expansion": {
- "version": "1.1.11",
- "bundled": true,
- "dev": true,
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "chownr": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "code-point-at": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true
- },
- "concat-map": {
- "version": "0.0.1",
- "bundled": true,
- "dev": true
- },
- "console-control-strings": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true
- },
- "core-util-is": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "debug": {
- "version": "2.6.9",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "deep-extend": {
- "version": "0.5.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "delegates": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "detect-libc": {
- "version": "1.0.3",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "fs-minipass": {
- "version": "1.2.5",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "minipass": "^2.2.1"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "gauge": {
- "version": "2.7.4",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "aproba": "^1.0.3",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.0",
- "object-assign": "^4.1.0",
- "signal-exit": "^3.0.0",
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wide-align": "^1.1.0"
- }
- },
- "glob": {
- "version": "7.1.2",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "has-unicode": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "iconv-lite": {
- "version": "0.4.21",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "safer-buffer": "^2.1.0"
- }
- },
- "ignore-walk": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "minimatch": "^3.0.4"
- }
- },
- "inflight": {
- "version": "1.0.6",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "bundled": true,
- "dev": true
- },
- "ini": {
- "version": "1.3.5",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "minimatch": {
- "version": "3.0.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "bundled": true,
- "dev": true
- },
- "minipass": {
- "version": "2.2.4",
- "bundled": true,
- "dev": true,
- "requires": {
- "safe-buffer": "^5.1.1",
- "yallist": "^3.0.0"
- }
- },
- "minizlib": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "minipass": "^2.2.1"
- }
- },
- "mkdirp": {
- "version": "0.5.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "minimist": "0.0.8"
- }
- },
- "ms": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "needle": {
- "version": "2.2.0",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "debug": "^2.1.2",
- "iconv-lite": "^0.4.4",
- "sax": "^1.2.4"
- }
- },
- "node-pre-gyp": {
- "version": "0.10.0",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "detect-libc": "^1.0.2",
- "mkdirp": "^0.5.1",
- "needle": "^2.2.0",
- "nopt": "^4.0.1",
- "npm-packlist": "^1.1.6",
- "npmlog": "^4.0.2",
- "rc": "^1.1.7",
- "rimraf": "^2.6.1",
- "semver": "^5.3.0",
- "tar": "^4"
- }
- },
- "nopt": {
- "version": "4.0.1",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "abbrev": "1",
- "osenv": "^0.1.4"
- }
- },
- "npm-bundled": {
- "version": "1.0.3",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "npm-packlist": {
- "version": "1.1.10",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "ignore-walk": "^3.0.1",
- "npm-bundled": "^1.0.1"
- }
- },
- "npmlog": {
- "version": "4.1.2",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "are-we-there-yet": "~1.1.2",
- "console-control-strings": "~1.1.0",
- "gauge": "~2.7.3",
- "set-blocking": "~2.0.0"
- }
- },
- "number-is-nan": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true
- },
- "object-assign": {
- "version": "4.1.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "once": {
- "version": "1.4.0",
- "bundled": true,
- "dev": true,
- "requires": {
- "wrappy": "1"
- }
- },
- "os-homedir": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "osenv": {
- "version": "0.1.5",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "os-homedir": "^1.0.0",
- "os-tmpdir": "^1.0.0"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "process-nextick-args": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "rc": {
- "version": "1.2.7",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "deep-extend": "^0.5.1",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "bundled": true,
- "dev": true,
- "optional": true
- }
- }
- },
- "readable-stream": {
- "version": "2.3.6",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "rimraf": {
- "version": "2.6.2",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "glob": "^7.0.5"
- }
- },
- "safe-buffer": {
- "version": "5.1.1",
- "bundled": true,
- "dev": true
- },
- "safer-buffer": {
- "version": "2.1.2",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "sax": {
- "version": "1.2.4",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "semver": {
- "version": "5.5.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "set-blocking": {
- "version": "2.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "signal-exit": {
- "version": "3.0.2",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "string-width": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "strip-json-comments": {
- "version": "2.0.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "tar": {
- "version": "4.4.1",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "chownr": "^1.0.1",
- "fs-minipass": "^1.2.5",
- "minipass": "^2.2.4",
- "minizlib": "^1.1.0",
- "mkdirp": "^0.5.0",
- "safe-buffer": "^5.1.1",
- "yallist": "^3.0.2"
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "wide-align": {
- "version": "1.1.2",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "string-width": "^1.0.2"
- }
- },
- "wrappy": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true
- },
- "yallist": {
- "version": "3.0.2",
- "bundled": true,
- "dev": true
- }
- }
- },
- "fstream": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
- "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "inherits": "~2.0.0",
- "mkdirp": ">=0.5 0",
- "rimraf": "2"
- }
- },
- "function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "dev": true
- },
- "gauge": {
- "version": "2.7.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
- "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
- "dev": true,
- "requires": {
- "aproba": "^1.0.3",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.0",
- "object-assign": "^4.1.0",
- "signal-exit": "^3.0.0",
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wide-align": "^1.1.0"
- }
- },
- "gaze": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
- "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
- "dev": true,
- "optional": true,
- "requires": {
- "globule": "^1.0.0"
- }
- },
- "get-caller-file": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
- "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
- "dev": true
- },
- "get-stdin": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
- "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
- "dev": true
- },
- "get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
- "dev": true
- },
- "get-value": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
- "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
- "dev": true
- },
- "getpass": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
- "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
- "dev": true,
- "requires": {
- "assert-plus": "^1.0.0"
- }
- },
- "glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "glob-base": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
- "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
- "dev": true,
- "requires": {
- "glob-parent": "^2.0.0",
- "is-glob": "^2.0.0"
- },
- "dependencies": {
- "glob-parent": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
- "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
- "dev": true,
- "requires": {
- "is-glob": "^2.0.0"
- }
- },
- "is-extglob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
- "dev": true
- },
- "is-glob": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
- "dev": true,
- "requires": {
- "is-extglob": "^1.0.0"
- }
- }
- }
- },
- "glob-parent": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
- "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
- "dev": true,
- "requires": {
- "is-glob": "^3.1.0",
- "path-dirname": "^1.0.0"
- },
- "dependencies": {
- "is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.0"
- }
- }
- }
- },
- "globals": {
- "version": "9.18.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
- "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
- "dev": true
- },
- "globby": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
- "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
- "dev": true,
- "requires": {
- "array-union": "^1.0.1",
- "dir-glob": "^2.0.0",
- "glob": "^7.1.2",
- "ignore": "^3.3.5",
- "pify": "^3.0.0",
- "slash": "^1.0.0"
- }
- },
- "globule": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
- "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
- "dev": true,
- "optional": true,
- "requires": {
- "glob": "~7.1.1",
- "lodash": "~4.17.10",
- "minimatch": "~3.0.2"
- }
- },
- "graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
- "dev": true
- },
- "grpc": {
- "version": "1.11.3",
- "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.11.3.tgz",
- "integrity": "sha512-7fJ40USpnP7hxGK0uRoEhJz6unA5VUdwInfwAY2rK2+OVxdDJSdTZQ/8/M+1tW68pHZYgHvg2ohvJ+clhW3ANg==",
- "requires": {
- "lodash": "^4.15.0",
- "nan": "^2.0.0",
- "node-pre-gyp": "^0.10.0",
- "protobufjs": "^5.0.0"
- },
- "dependencies": {
- "abbrev": {
- "version": "1.1.1",
- "bundled": true
- },
- "ansi-regex": {
- "version": "2.1.1",
- "bundled": true
- },
- "aproba": {
- "version": "1.2.0",
- "bundled": true
- },
- "are-we-there-yet": {
- "version": "1.1.4",
- "bundled": true,
- "requires": {
- "delegates": "^1.0.0",
- "readable-stream": "^2.0.6"
- }
- },
- "balanced-match": {
- "version": "1.0.0",
- "bundled": true
- },
- "brace-expansion": {
- "version": "1.1.11",
- "bundled": true,
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "chownr": {
- "version": "1.0.1",
- "bundled": true
- },
- "code-point-at": {
- "version": "1.1.0",
- "bundled": true
- },
- "concat-map": {
- "version": "0.0.1",
- "bundled": true
- },
- "console-control-strings": {
- "version": "1.1.0",
- "bundled": true
- },
- "core-util-is": {
- "version": "1.0.2",
- "bundled": true
- },
- "debug": {
- "version": "2.6.9",
- "bundled": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "deep-extend": {
- "version": "0.5.1",
- "bundled": true
- },
- "delegates": {
- "version": "1.0.0",
- "bundled": true
- },
- "detect-libc": {
- "version": "1.0.3",
- "bundled": true
- },
- "fs-minipass": {
- "version": "1.2.5",
- "bundled": true,
- "requires": {
- "minipass": "^2.2.1"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "bundled": true
- },
- "gauge": {
- "version": "2.7.4",
- "bundled": true,
- "requires": {
- "aproba": "^1.0.3",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.0",
- "object-assign": "^4.1.0",
- "signal-exit": "^3.0.0",
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wide-align": "^1.1.0"
- }
- },
- "glob": {
- "version": "7.1.2",
- "bundled": true,
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "has-unicode": {
- "version": "2.0.1",
- "bundled": true
- },
- "iconv-lite": {
- "version": "0.4.19",
- "bundled": true
- },
- "ignore-walk": {
- "version": "3.0.1",
- "bundled": true,
- "requires": {
- "minimatch": "^3.0.4"
- }
- },
- "inflight": {
- "version": "1.0.6",
- "bundled": true,
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "bundled": true
- },
- "ini": {
- "version": "1.3.5",
- "bundled": true
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "bundled": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "bundled": true
- },
- "minimatch": {
- "version": "3.0.4",
- "bundled": true,
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "bundled": true
- },
- "minipass": {
- "version": "2.2.4",
- "bundled": true,
- "requires": {
- "safe-buffer": "^5.1.1",
- "yallist": "^3.0.0"
- }
- },
- "minizlib": {
- "version": "1.1.0",
- "bundled": true,
- "requires": {
- "minipass": "^2.2.1"
- }
- },
- "mkdirp": {
- "version": "0.5.1",
- "bundled": true,
- "requires": {
- "minimist": "0.0.8"
- },
- "dependencies": {
- "minimist": {
- "version": "0.0.8",
- "bundled": true
- }
- }
- },
- "ms": {
- "version": "2.0.0",
- "bundled": true
- },
- "needle": {
- "version": "2.2.1",
- "bundled": true,
- "requires": {
- "debug": "^2.1.2",
- "iconv-lite": "^0.4.4",
- "sax": "^1.2.4"
- }
- },
- "node-pre-gyp": {
- "version": "0.10.0",
- "bundled": true,
- "requires": {
- "detect-libc": "^1.0.2",
- "mkdirp": "^0.5.1",
- "needle": "^2.2.0",
- "nopt": "^4.0.1",
- "npm-packlist": "^1.1.6",
- "npmlog": "^4.0.2",
- "rc": "^1.1.7",
- "rimraf": "^2.6.1",
- "semver": "^5.3.0",
- "tar": "^4"
- }
- },
- "nopt": {
- "version": "4.0.1",
- "bundled": true,
- "requires": {
- "abbrev": "1",
- "osenv": "^0.1.4"
- }
- },
- "npm-bundled": {
- "version": "1.0.3",
- "bundled": true
- },
- "npm-packlist": {
- "version": "1.1.10",
- "bundled": true,
- "requires": {
- "ignore-walk": "^3.0.1",
- "npm-bundled": "^1.0.1"
- }
- },
- "npmlog": {
- "version": "4.1.2",
- "bundled": true,
- "requires": {
- "are-we-there-yet": "~1.1.2",
- "console-control-strings": "~1.1.0",
- "gauge": "~2.7.3",
- "set-blocking": "~2.0.0"
- }
- },
- "number-is-nan": {
- "version": "1.0.1",
- "bundled": true
- },
- "object-assign": {
- "version": "4.1.1",
- "bundled": true
- },
- "once": {
- "version": "1.4.0",
- "bundled": true,
- "requires": {
- "wrappy": "1"
- }
- },
- "os-homedir": {
- "version": "1.0.2",
- "bundled": true
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "bundled": true
- },
- "osenv": {
- "version": "0.1.5",
- "bundled": true,
- "requires": {
- "os-homedir": "^1.0.0",
- "os-tmpdir": "^1.0.0"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "bundled": true
- },
- "process-nextick-args": {
- "version": "2.0.0",
- "bundled": true
- },
- "rc": {
- "version": "1.2.7",
- "bundled": true,
- "requires": {
- "deep-extend": "^0.5.1",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- }
- },
- "readable-stream": {
- "version": "2.3.6",
- "bundled": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "rimraf": {
- "version": "2.6.2",
- "bundled": true,
- "requires": {
- "glob": "^7.0.5"
- }
- },
- "safe-buffer": {
- "version": "5.1.1",
- "bundled": true
- },
- "sax": {
- "version": "1.2.4",
- "bundled": true
- },
- "semver": {
- "version": "5.5.0",
- "bundled": true
- },
- "set-blocking": {
- "version": "2.0.0",
- "bundled": true
- },
- "signal-exit": {
- "version": "3.0.2",
- "bundled": true
- },
- "string-width": {
- "version": "1.0.2",
- "bundled": true,
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "bundled": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "bundled": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "strip-json-comments": {
- "version": "2.0.1",
- "bundled": true
- },
- "tar": {
- "version": "4.4.2",
- "bundled": true,
- "requires": {
- "chownr": "^1.0.1",
- "fs-minipass": "^1.2.5",
- "minipass": "^2.2.4",
- "minizlib": "^1.1.0",
- "mkdirp": "^0.5.0",
- "safe-buffer": "^5.1.2",
- "yallist": "^3.0.2"
- },
- "dependencies": {
- "safe-buffer": {
- "version": "5.1.2",
- "bundled": true
- }
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "bundled": true
- },
- "wide-align": {
- "version": "1.1.2",
- "bundled": true,
- "requires": {
- "string-width": "^1.0.2"
- }
- },
- "wrappy": {
- "version": "1.0.2",
- "bundled": true
- },
- "yallist": {
- "version": "3.0.2",
- "bundled": true
- }
- }
- },
- "handle-thing": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz",
- "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=",
- "dev": true
- },
- "handlebars": {
- "version": "4.0.11",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz",
- "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=",
- "dev": true,
- "requires": {
- "async": "^1.4.0",
- "optimist": "^0.6.1",
- "source-map": "^0.4.4",
- "uglify-js": "^2.6"
- },
- "dependencies": {
- "source-map": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
- "dev": true,
- "requires": {
- "amdefine": ">=0.0.4"
- }
- },
- "uglify-js": {
- "version": "2.8.29",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
- "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
- "dev": true,
- "optional": true,
- "requires": {
- "source-map": "~0.5.1",
- "uglify-to-browserify": "~1.0.0",
- "yargs": "~3.10.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true,
- "optional": true
- }
- }
- }
- }
- },
- "har-schema": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
- "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
- "dev": true
- },
- "har-validator": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
- "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
- "dev": true,
- "requires": {
- "ajv": "^5.1.0",
- "har-schema": "^2.0.0"
- },
- "dependencies": {
- "ajv": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
- "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
- "dev": true,
- "requires": {
- "co": "^4.6.0",
- "fast-deep-equal": "^1.0.0",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.3.0"
- }
- }
- }
- },
- "has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dev": true,
- "requires": {
- "function-bind": "^1.1.1"
- }
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "has-binary": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz",
- "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=",
- "dev": true,
- "requires": {
- "isarray": "0.0.1"
- },
- "dependencies": {
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
- "dev": true
- }
- }
- },
- "has-cors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
- "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
- "dev": true
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
- },
- "has-symbols": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
- "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
- "dev": true
- },
- "has-unicode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
- "dev": true
- },
- "has-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
- "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
- "dev": true,
- "requires": {
- "get-value": "^2.0.6",
- "has-values": "^1.0.0",
- "isobject": "^3.0.0"
- }
- },
- "has-values": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
- "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
- "dev": true,
- "requires": {
- "is-number": "^3.0.0",
- "kind-of": "^4.0.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "hash-base": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
- "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
- "dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "hash.js": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.4.tgz",
- "integrity": "sha512-A6RlQvvZEtFS5fLU43IDu0QUmBy+fDO9VMdTXvufKwIkt/rFfvICAViCax5fbDO4zdNzaC3/27ZhKUok5bAJyw==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "minimalistic-assert": "^1.0.0"
- }
- },
- "hawk": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
- "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
- "dev": true,
- "optional": true,
- "requires": {
- "boom": "2.x.x",
- "cryptiles": "2.x.x",
- "hoek": "2.x.x",
- "sntp": "1.x.x"
- }
- },
- "he": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
- "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
- "dev": true
- },
- "hmac-drbg": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
- "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
- "dev": true,
- "requires": {
- "hash.js": "^1.0.3",
- "minimalistic-assert": "^1.0.0",
- "minimalistic-crypto-utils": "^1.0.1"
- }
- },
- "hoek": {
- "version": "2.16.3",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
- "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
- "dev": true
- },
- "hosted-git-info": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.1.tgz",
- "integrity": "sha512-Ba4+0M4YvIDUUsprMjhVTU1yN9F2/LJSAl69ZpzaLT4l4j5mwTS6jqqW9Ojvj6lKz/veqPzpJBqGbXspOb533A==",
- "dev": true
- },
- "hpack.js": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
- "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
- "dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "obuf": "^1.0.0",
- "readable-stream": "^2.0.1",
- "wbuf": "^1.1.0"
- }
- },
- "html-entities": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
- "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
- "dev": true
- },
- "html-minifier": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.18.tgz",
- "integrity": "sha512-sczoq/9zeXiKZMj8tsQzHJE7EyjrpMHvblTLuh9o8h5923a6Ts5uQ/3YdY+xIqJYRjzHQPlrHjfjh0BtwPJG0g==",
- "dev": true,
- "requires": {
- "camel-case": "3.0.x",
- "clean-css": "4.1.x",
- "commander": "2.16.x",
- "he": "1.1.x",
- "param-case": "2.1.x",
- "relateurl": "0.2.x",
- "uglify-js": "3.4.x"
- }
- },
- "html-webpack-plugin": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
- "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=",
- "dev": true,
- "requires": {
- "html-minifier": "^3.2.3",
- "loader-utils": "^0.2.16",
- "lodash": "^4.17.3",
- "pretty-error": "^2.0.2",
- "tapable": "^1.0.0",
- "toposort": "^1.0.0",
- "util.promisify": "1.0.0"
- },
- "dependencies": {
- "loader-utils": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
- "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
- "dev": true,
- "requires": {
- "big.js": "^3.1.3",
- "emojis-list": "^2.0.0",
- "json5": "^0.5.0",
- "object-assign": "^4.0.1"
- }
- }
- }
- },
- "htmlparser2": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
- "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=",
- "dev": true,
- "requires": {
- "domelementtype": "1",
- "domhandler": "2.1",
- "domutils": "1.1",
- "readable-stream": "1.0"
- },
- "dependencies": {
- "domutils": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz",
- "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=",
- "dev": true,
- "requires": {
- "domelementtype": "1"
- }
- },
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
- "dev": true
- },
- "readable-stream": {
- "version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "dev": true
- }
- }
- },
- "http-deceiver": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
- "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
- "dev": true
- },
- "http-errors": {
- "version": "1.6.3",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
- "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
- "dev": true,
- "requires": {
- "depd": "~1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.0",
- "statuses": ">= 1.4.0 < 2"
- }
- },
- "http-parser-js": {
- "version": "0.4.13",
- "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz",
- "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc="
- },
- "http-proxy": {
- "version": "1.17.0",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
- "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
- "dev": true,
- "requires": {
- "eventemitter3": "^3.0.0",
- "follow-redirects": "^1.0.0",
- "requires-port": "^1.0.0"
- }
- },
- "http-proxy-middleware": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz",
- "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==",
- "dev": true,
- "requires": {
- "http-proxy": "^1.16.2",
- "is-glob": "^4.0.0",
- "lodash": "^4.17.5",
- "micromatch": "^3.1.9"
- }
- },
- "http-signature": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
- "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
- "dev": true,
- "requires": {
- "assert-plus": "^1.0.0",
- "jsprim": "^1.2.2",
- "sshpk": "^1.7.0"
- }
- },
- "https-browserify": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
- "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
- "dev": true
- },
- "https-proxy-agent": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
- "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
- "dev": true,
- "requires": {
- "agent-base": "^4.1.0",
- "debug": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "iconv-lite": {
- "version": "0.4.19",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
- "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
- },
- "ieee754": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
- "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==",
- "dev": true
- },
- "iferr": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
- "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
- "dev": true
- },
- "ignore": {
- "version": "3.3.10",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
- "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
- "dev": true
- },
- "image-size": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
- "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
- "dev": true,
- "optional": true
- },
- "immediate": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
- "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
- "dev": true
- },
- "import-local": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
- "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==",
- "dev": true,
- "requires": {
- "pkg-dir": "^2.0.0",
- "resolve-cwd": "^2.0.0"
- }
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
- "dev": true
- },
- "in-publish": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
- "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
- "dev": true,
- "optional": true
- },
- "indent-string": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
- "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
- "dev": true,
- "requires": {
- "repeating": "^2.0.0"
- }
- },
- "indexof": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
- "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
- "dev": true
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- },
- "ini": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
- "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
- "dev": true
- },
- "internal-ip": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz",
- "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=",
- "dev": true,
- "requires": {
- "meow": "^3.3.0"
- }
- },
- "invariant": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
- "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
- "dev": true,
- "requires": {
- "loose-envify": "^1.0.0"
- }
- },
- "invert-kv": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
- "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
- "dev": true
- },
- "ip": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
- "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
- "dev": true
- },
- "ipaddr.js": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
- "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=",
- "dev": true
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
- "dev": true
- },
- "is-binary-path": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
- "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
- "dev": true,
- "requires": {
- "binary-extensions": "^1.0.0"
- }
- },
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
- },
- "is-builtin-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
- "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
- "dev": true,
- "requires": {
- "builtin-modules": "^1.0.0"
- }
- },
- "is-callable": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
- "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
- "dev": true
- },
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-date-object": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
- "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
- "dev": true
- },
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
- "is-directory": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
- "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
- "dev": true
- },
- "is-dotfile": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
- "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
- "dev": true
- },
- "is-equal-shallow": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
- "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
- "dev": true,
- "requires": {
- "is-primitive": "^2.0.0"
- }
- },
- "is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
- "dev": true
- },
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "dev": true
- },
- "is-finite": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
- "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
- },
- "is-glob": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
- "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.1"
- }
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "is-path-cwd": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
- "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
- "dev": true
- },
- "is-path-in-cwd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
- "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
- "dev": true,
- "requires": {
- "is-path-inside": "^1.0.0"
- }
- },
- "is-path-inside": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
- "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
- "dev": true,
- "requires": {
- "path-is-inside": "^1.0.1"
- }
- },
- "is-plain-object": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
- "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
- "dev": true,
- "requires": {
- "isobject": "^3.0.1"
- }
- },
- "is-posix-bracket": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
- "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
- "dev": true
- },
- "is-primitive": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
- "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
- "dev": true
- },
- "is-regex": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
- "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
- "dev": true,
- "requires": {
- "has": "^1.0.1"
- }
- },
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
- },
- "is-symbol": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
- "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
- "dev": true
- },
- "is-typedarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
- "dev": true
- },
- "is-utf8": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
- "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
- "dev": true
- },
- "is-windows": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
- "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
- "dev": true
- },
- "is-wsl": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
- "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
- "dev": true
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "isbinaryfile": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz",
- "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=",
- "dev": true
- },
- "isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
- "dev": true
- },
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- },
- "isomorphic-fetch": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
- "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
- "requires": {
- "node-fetch": "^1.0.1",
- "whatwg-fetch": ">=0.10.0"
- }
- },
- "isstream": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
- "dev": true
- },
- "istanbul": {
- "version": "0.4.5",
- "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
- "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
- "dev": true,
- "requires": {
- "abbrev": "1.0.x",
- "async": "1.x",
- "escodegen": "1.8.x",
- "esprima": "2.7.x",
- "glob": "^5.0.15",
- "handlebars": "^4.0.1",
- "js-yaml": "3.x",
- "mkdirp": "0.5.x",
- "nopt": "3.x",
- "once": "1.x",
- "resolve": "1.1.x",
- "supports-color": "^3.1.0",
- "which": "^1.1.1",
- "wordwrap": "^1.0.0"
- },
- "dependencies": {
- "glob": {
- "version": "5.0.15",
- "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
- "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
- "dev": true,
- "requires": {
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "2 || 3",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "has-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
- "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
- "dev": true
- },
- "resolve": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
- "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
- "dev": true
- },
- "supports-color": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
- "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
- "dev": true,
- "requires": {
- "has-flag": "^1.0.0"
- }
- }
- }
- },
- "istanbul-api": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz",
- "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==",
- "dev": true,
- "requires": {
- "async": "^2.1.4",
- "compare-versions": "^3.1.0",
- "fileset": "^2.0.2",
- "istanbul-lib-coverage": "^1.2.0",
- "istanbul-lib-hook": "^1.2.0",
- "istanbul-lib-instrument": "^1.10.1",
- "istanbul-lib-report": "^1.1.4",
- "istanbul-lib-source-maps": "^1.2.4",
- "istanbul-reports": "^1.3.0",
- "js-yaml": "^3.7.0",
- "mkdirp": "^0.5.1",
- "once": "^1.4.0"
- },
- "dependencies": {
- "async": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
- "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
- "dev": true,
- "requires": {
- "lodash": "^4.17.10"
- }
- }
- }
- },
- "istanbul-instrumenter-loader": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz",
- "integrity": "sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w==",
- "dev": true,
- "requires": {
- "convert-source-map": "^1.5.0",
- "istanbul-lib-instrument": "^1.7.3",
- "loader-utils": "^1.1.0",
- "schema-utils": "^0.3.0"
- },
- "dependencies": {
- "ajv": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
- "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
- "dev": true,
- "requires": {
- "co": "^4.6.0",
- "fast-deep-equal": "^1.0.0",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.3.0"
- }
- },
- "schema-utils": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz",
- "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=",
- "dev": true,
- "requires": {
- "ajv": "^5.0.0"
- }
- }
- }
- },
- "istanbul-lib-coverage": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz",
- "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==",
- "dev": true
- },
- "istanbul-lib-hook": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.1.tgz",
- "integrity": "sha512-eLAMkPG9FU0v5L02lIkcj/2/Zlz9OuluaXikdr5iStk8FDbSwAixTK9TkYxbF0eNnzAJTwM2fkV2A1tpsIp4Jg==",
- "dev": true,
- "requires": {
- "append-transform": "^1.0.0"
- }
- },
- "istanbul-lib-instrument": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz",
- "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==",
- "dev": true,
- "requires": {
- "babel-generator": "^6.18.0",
- "babel-template": "^6.16.0",
- "babel-traverse": "^6.18.0",
- "babel-types": "^6.18.0",
- "babylon": "^6.18.0",
- "istanbul-lib-coverage": "^1.2.0",
- "semver": "^5.3.0"
- }
- },
- "istanbul-lib-report": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz",
- "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==",
- "dev": true,
- "requires": {
- "istanbul-lib-coverage": "^1.2.0",
- "mkdirp": "^0.5.1",
- "path-parse": "^1.0.5",
- "supports-color": "^3.1.2"
- },
- "dependencies": {
- "has-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
- "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
- "dev": true
- },
- "supports-color": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
- "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
- "dev": true,
- "requires": {
- "has-flag": "^1.0.0"
- }
- }
- }
- },
- "istanbul-lib-source-maps": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz",
- "integrity": "sha512-8O2T/3VhrQHn0XcJbP1/GN7kXMiRAlPi+fj3uEHrjBD8Oz7Py0prSC25C09NuAZS6bgW1NNKAvCSHZXB0irSGA==",
- "dev": true,
- "requires": {
- "debug": "^3.1.0",
- "istanbul-lib-coverage": "^1.2.0",
- "mkdirp": "^0.5.1",
- "rimraf": "^2.6.1",
- "source-map": "^0.5.3"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
- "istanbul-reports": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz",
- "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==",
- "dev": true,
- "requires": {
- "handlebars": "^4.0.3"
- }
- },
- "jasmine": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz",
- "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=",
- "dev": true,
- "requires": {
- "exit": "^0.1.2",
- "glob": "^7.0.6",
- "jasmine-core": "~2.8.0"
- },
- "dependencies": {
- "jasmine-core": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz",
- "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=",
- "dev": true
- }
- }
- },
- "jasmine-core": {
- "version": "2.99.1",
- "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
- "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
- "dev": true
- },
- "jasmine-spec-reporter": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz",
- "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==",
- "dev": true,
- "requires": {
- "colors": "1.1.2"
- }
- },
- "jasminewd2": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz",
- "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=",
- "dev": true
- },
- "js-base64": {
- "version": "2.4.5",
- "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.5.tgz",
- "integrity": "sha512-aUnNwqMOXw3yvErjMPSQu6qIIzUmT1e5KcU1OZxRDU1g/am6mzBvcrmLAYwzmB59BHPrh5/tKaiF4OPhqRWESQ==",
- "dev": true,
- "optional": true
- },
- "js-tokens": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
- "dev": true
- },
- "js-yaml": {
- "version": "3.12.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
- "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "dependencies": {
- "esprima": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
- "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
- "dev": true
- }
- }
- },
- "jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
- "dev": true,
- "optional": true
- },
- "jsesc": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
- "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
- "dev": true
- },
- "json-schema": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
- "dev": true
- },
- "json-schema-traverse": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
- "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
- "dev": true
- },
- "json-stable-stringify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
- "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
- "dev": true,
- "optional": true,
- "requires": {
- "jsonify": "~0.0.0"
- }
- },
- "json-stringify-safe": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
- "dev": true
- },
- "json3": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
- "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
- "dev": true
- },
- "json5": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
- "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
- "dev": true
- },
- "jsonify": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
- "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
- "dev": true,
- "optional": true
- },
- "jsprim": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
- "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
- "dev": true,
- "requires": {
- "assert-plus": "1.0.0",
- "extsprintf": "1.3.0",
- "json-schema": "0.2.3",
- "verror": "1.10.0"
- }
- },
- "jszip": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz",
- "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==",
- "dev": true,
- "requires": {
- "core-js": "~2.3.0",
- "es6-promise": "~3.0.2",
- "lie": "~3.1.0",
- "pako": "~1.0.2",
- "readable-stream": "~2.0.6"
- },
- "dependencies": {
- "core-js": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz",
- "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=",
- "dev": true
- },
- "es6-promise": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz",
- "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=",
- "dev": true
- },
- "process-nextick-args": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
- "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "~1.0.0",
- "process-nextick-args": "~1.0.6",
- "string_decoder": "~0.10.x",
- "util-deprecate": "~1.0.1"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "dev": true
- }
- }
- },
- "karma": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz",
- "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==",
- "dev": true,
- "requires": {
- "bluebird": "^3.3.0",
- "body-parser": "^1.16.1",
- "chokidar": "^1.4.1",
- "colors": "^1.1.0",
- "combine-lists": "^1.0.0",
- "connect": "^3.6.0",
- "core-js": "^2.2.0",
- "di": "^0.0.1",
- "dom-serialize": "^2.2.0",
- "expand-braces": "^0.1.1",
- "glob": "^7.1.1",
- "graceful-fs": "^4.1.2",
- "http-proxy": "^1.13.0",
- "isbinaryfile": "^3.0.0",
- "lodash": "^3.8.0",
- "log4js": "^0.6.31",
- "mime": "^1.3.4",
- "minimatch": "^3.0.2",
- "optimist": "^0.6.1",
- "qjobs": "^1.1.4",
- "range-parser": "^1.2.0",
- "rimraf": "^2.6.0",
- "safe-buffer": "^5.0.1",
- "socket.io": "1.7.3",
- "source-map": "^0.5.3",
- "tmp": "0.0.31",
- "useragent": "^2.1.12"
- },
- "dependencies": {
- "anymatch": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
- "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
- "dev": true,
- "requires": {
- "micromatch": "^2.1.5",
- "normalize-path": "^2.0.0"
- }
- },
- "arr-diff": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
- "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.0.1"
- }
- },
- "array-unique": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
- "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
- "dev": true
- },
- "braces": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
- "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
- "dev": true,
- "requires": {
- "expand-range": "^1.8.1",
- "preserve": "^0.2.0",
- "repeat-element": "^1.1.2"
- }
- },
- "chokidar": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
- "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
- "dev": true,
- "requires": {
- "anymatch": "^1.3.0",
- "async-each": "^1.0.0",
- "fsevents": "^1.0.0",
- "glob-parent": "^2.0.0",
- "inherits": "^2.0.1",
- "is-binary-path": "^1.0.0",
- "is-glob": "^2.0.0",
- "path-is-absolute": "^1.0.0",
- "readdirp": "^2.0.0"
- }
- },
- "expand-brackets": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
- "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
- "dev": true,
- "requires": {
- "is-posix-bracket": "^0.1.0"
- }
- },
- "extglob": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
- "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
- "dev": true,
- "requires": {
- "is-extglob": "^1.0.0"
- }
- },
- "glob-parent": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
- "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
- "dev": true,
- "requires": {
- "is-glob": "^2.0.0"
- }
- },
- "is-extglob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
- "dev": true
- },
- "is-glob": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
- "dev": true,
- "requires": {
- "is-extglob": "^1.0.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- },
- "lodash": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
- "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
- "dev": true
- },
- "micromatch": {
- "version": "2.3.11",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
- "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
- "dev": true,
- "requires": {
- "arr-diff": "^2.0.0",
- "array-unique": "^0.2.1",
- "braces": "^1.8.2",
- "expand-brackets": "^0.1.4",
- "extglob": "^0.3.1",
- "filename-regex": "^2.0.0",
- "is-extglob": "^1.0.0",
- "is-glob": "^2.0.1",
- "kind-of": "^3.0.2",
- "normalize-path": "^2.0.1",
- "object.omit": "^2.0.0",
- "parse-glob": "^3.0.4",
- "regex-cache": "^0.4.2"
- }
- }
- }
- },
- "karma-chrome-launcher": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz",
- "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==",
- "dev": true,
- "requires": {
- "fs-access": "^1.0.0",
- "which": "^1.2.1"
- }
- },
- "karma-coverage-istanbul-reporter": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.0.1.tgz",
- "integrity": "sha512-UcgrHkFehI5+ivMouD8NH/UOHiX4oCAtwaANylzPFdcAuD52fnCUuelacq2gh8tZ4ydhU3+xiXofSq7j5Ehygw==",
- "dev": true,
- "requires": {
- "istanbul-api": "^1.3.1",
- "minimatch": "^3.0.4"
- }
- },
- "karma-jasmine": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.2.tgz",
- "integrity": "sha1-OU8rJf+0pkS5rabyLUQ+L9CIhsM=",
- "dev": true
- },
- "karma-jasmine-html-reporter": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz",
- "integrity": "sha1-SKjl7xiAdhfuK14zwRlMNbQ5Ukw=",
- "dev": true,
- "requires": {
- "karma-jasmine": "^1.0.2"
- }
- },
- "karma-source-map-support": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.3.0.tgz",
- "integrity": "sha512-HcPqdAusNez/ywa+biN4EphGz62MmQyPggUsDfsHqa7tSe4jdsxgvTKuDfIazjL+IOxpVWyT7Pr4dhAV+sxX5Q==",
- "dev": true,
- "requires": {
- "source-map-support": "^0.5.5"
- }
- },
- "killable": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz",
- "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=",
- "dev": true
- },
- "kind-of": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
- "dev": true
- },
- "lazy-cache": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
- "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
- },
- "lcid": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
- "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
- "dev": true,
- "requires": {
- "invert-kv": "^1.0.0"
- }
- },
- "leb": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/leb/-/leb-0.3.0.tgz",
- "integrity": "sha1-Mr7p+tFoMo1q6oUi2DP0GA7tHaM=",
- "dev": true
- },
- "less": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/less/-/less-3.5.0.tgz",
- "integrity": "sha512-fLbJGxtoCV2FTDGeXlUXXUZ8sgMej2c5u8om8inOZt5M3tzXqF/aS7W0txWhCN6iA6qPtPGGzj0sp/vd8ztl6Q==",
- "dev": true,
- "requires": {
- "errno": "^0.1.1",
- "graceful-fs": "^4.1.2",
- "image-size": "~0.5.0",
- "mime": "^1.4.1",
- "mkdirp": "^0.5.0",
- "promise": "^7.1.1",
- "request": "^2.83.0",
- "source-map": "~0.6.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "optional": true
- }
- }
- },
- "less-loader": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.1.0.tgz",
- "integrity": "sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg==",
- "dev": true,
- "requires": {
- "clone": "^2.1.1",
- "loader-utils": "^1.1.0",
- "pify": "^3.0.0"
- }
- },
- "levn": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
- "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
- "dev": true,
- "requires": {
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2"
- }
- },
- "license-webpack-plugin": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.3.1.tgz",
- "integrity": "sha512-NqAFodJdpBUuf1iD+Ij8hQvF0rCFKlO2KaieoQzAPhFgzLCtJnC7Z7x5gQbGNjoe++wOKAtAmwVEIBLqq2Yp1A==",
- "dev": true,
- "requires": {
- "ejs": "^2.5.7"
- }
- },
- "lie": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
- "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
- "dev": true,
- "requires": {
- "immediate": "~3.0.5"
- }
- },
- "load-json-file": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
- "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^2.2.0",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0",
- "strip-bom": "^2.0.0"
- },
- "dependencies": {
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- }
- }
- },
- "loader-runner": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
- "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
- "dev": true
- },
- "loader-utils": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
- "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
- "dev": true,
- "requires": {
- "big.js": "^3.1.3",
- "emojis-list": "^2.0.0",
- "json5": "^0.5.0"
- }
- },
- "locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
- "dev": true,
- "requires": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
- }
- },
- "lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
- },
- "lodash.assign": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
- "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
- "dev": true,
- "optional": true
- },
- "lodash.clonedeep": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
- "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
- "dev": true
- },
- "lodash.debounce": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
- "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
- "dev": true
- },
- "lodash.mergewith": {
- "version": "4.6.1",
- "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
- "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==",
- "dev": true,
- "optional": true
- },
- "lodash.tail": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz",
- "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=",
- "dev": true
- },
- "log-symbols": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
- "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
- "dev": true,
- "requires": {
- "chalk": "^2.0.1"
- }
- },
- "log4js": {
- "version": "0.6.38",
- "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz",
- "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=",
- "dev": true,
- "requires": {
- "readable-stream": "~1.0.2",
- "semver": "~4.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
- "dev": true
- },
- "readable-stream": {
- "version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
- },
- "semver": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
- "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=",
- "dev": true
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "dev": true
- }
- }
- },
- "loglevel": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz",
- "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=",
- "dev": true
- },
- "loglevelnext": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz",
- "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==",
- "dev": true,
- "requires": {
- "es6-symbol": "^3.1.1",
- "object.assign": "^4.1.0"
- }
- },
- "long": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
- "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s="
- },
- "longest": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
- "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
- },
- "loose-envify": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
- "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
- "dev": true,
- "requires": {
- "js-tokens": "^3.0.0"
- }
- },
- "loud-rejection": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
- "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
- "dev": true,
- "requires": {
- "currently-unhandled": "^0.4.1",
- "signal-exit": "^3.0.0"
- }
- },
- "lower-case": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
- "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
- "dev": true
- },
- "lru-cache": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
- "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
- "dev": true,
- "requires": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
- "make-dir": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
- "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
- "dev": true,
- "requires": {
- "pify": "^3.0.0"
- }
- },
- "make-error": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz",
- "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==",
- "dev": true
- },
- "map-cache": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
- "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
- "dev": true
- },
- "map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
- "dev": true
- },
- "map-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
- "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
- "dev": true,
- "requires": {
- "object-visit": "^1.0.0"
- }
- },
- "math-random": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
- "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=",
- "dev": true
- },
- "md5.js": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
- "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
- "dev": true,
- "requires": {
- "hash-base": "^3.0.0",
- "inherits": "^2.0.1"
- }
- },
- "media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
- "dev": true
- },
- "mem": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
- "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
- "dev": true,
- "requires": {
- "mimic-fn": "^1.0.0"
- }
- },
- "memory-fs": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
- "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
- "dev": true,
- "requires": {
- "errno": "^0.1.3",
- "readable-stream": "^2.0.1"
- }
- },
- "meow": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
- "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
- "dev": true,
- "requires": {
- "camelcase-keys": "^2.0.0",
- "decamelize": "^1.1.2",
- "loud-rejection": "^1.0.0",
- "map-obj": "^1.0.1",
- "minimist": "^1.1.3",
- "normalize-package-data": "^2.3.4",
- "object-assign": "^4.0.1",
- "read-pkg-up": "^1.0.1",
- "redent": "^1.0.0",
- "trim-newlines": "^1.0.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
- }
- },
- "merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
- "dev": true
- },
- "methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
- "dev": true
- },
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
- }
- },
- "miller-rabin": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
- "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
- "dev": true,
- "requires": {
- "bn.js": "^4.0.0",
- "brorand": "^1.0.1"
- }
- },
- "mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
- "dev": true
- },
- "mime-db": {
- "version": "1.33.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
- "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
- "dev": true
- },
- "mime-types": {
- "version": "2.1.18",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
- "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
- "dev": true,
- "requires": {
- "mime-db": "~1.33.0"
- }
- },
- "mimic-fn": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
- "dev": true
- },
- "mini-css-extract-plugin": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.1.tgz",
- "integrity": "sha512-XWuB3G61Rtasq/gLe7cp5cuozehE6hN+E4sxCamRR/WDiHTg+f7ZIAS024r8UJQffY+e2gGELXQZgQoFDfNDCg==",
- "dev": true,
- "requires": {
- "@webpack-contrib/schema-utils": "^1.0.0-beta.0",
- "loader-utils": "^1.1.0",
- "webpack-sources": "^1.1.0"
- }
- },
- "minimalistic-assert": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
- "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
- "dev": true
- },
- "minimalistic-crypto-utils": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
- "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
- "dev": true
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
- "dev": true
- },
- "mississippi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz",
- "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==",
- "dev": true,
- "requires": {
- "concat-stream": "^1.5.0",
- "duplexify": "^3.4.2",
- "end-of-stream": "^1.1.0",
- "flush-write-stream": "^1.0.0",
- "from2": "^2.1.0",
- "parallel-transform": "^1.1.0",
- "pump": "^2.0.1",
- "pumpify": "^1.3.3",
- "stream-each": "^1.1.0",
- "through2": "^2.0.0"
- }
- },
- "mixin-deep": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
- "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
- "dev": true,
- "requires": {
- "for-in": "^1.0.2",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
- },
- "mixin-object": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
- "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=",
- "dev": true,
- "requires": {
- "for-in": "^0.1.3",
- "is-extendable": "^0.1.1"
- },
- "dependencies": {
- "for-in": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
- "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
- "dev": true
- }
- }
- },
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "dev": true,
- "requires": {
- "minimist": "0.0.8"
- }
- },
- "move-concurrently": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
- "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
- "dev": true,
- "requires": {
- "aproba": "^1.1.1",
- "copy-concurrently": "^1.0.0",
- "fs-write-stream-atomic": "^1.0.8",
- "mkdirp": "^0.5.1",
- "rimraf": "^2.5.4",
- "run-queue": "^1.0.3"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- },
- "multicast-dns": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
- "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
- "dev": true,
- "requires": {
- "dns-packet": "^1.3.1",
- "thunky": "^1.0.2"
- }
- },
- "multicast-dns-service-types": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
- "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
- "dev": true
- },
- "nan": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
- "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA=="
- },
- "nanomatch": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
- "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "fragment-cache": "^0.2.1",
- "is-windows": "^1.0.2",
- "kind-of": "^6.0.2",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- }
- },
- "negotiator": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
- "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
- "dev": true
- },
- "neo-async": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz",
- "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==",
- "dev": true
- },
- "next-tick": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
- "dev": true
- },
- "no-case": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
- "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
- "dev": true,
- "requires": {
- "lower-case": "^1.1.1"
- }
- },
- "node-fetch": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
- "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
- "requires": {
- "encoding": "^0.1.11",
- "is-stream": "^1.0.1"
- }
- },
- "node-forge": {
- "version": "0.7.5",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz",
- "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==",
- "dev": true
- },
- "node-gyp": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.7.0.tgz",
- "integrity": "sha512-qDQE/Ft9xXP6zphwx4sD0t+VhwV7yFaloMpfbL2QnnDZcyaiakWlLdtFGGQfTAwpFHdpbRhRxVhIHN1OKAjgbg==",
- "dev": true,
- "optional": true,
- "requires": {
- "fstream": "^1.0.0",
- "glob": "^7.0.3",
- "graceful-fs": "^4.1.2",
- "mkdirp": "^0.5.0",
- "nopt": "2 || 3",
- "npmlog": "0 || 1 || 2 || 3 || 4",
- "osenv": "0",
- "request": ">=2.9.0 <2.82.0",
- "rimraf": "2",
- "semver": "~5.3.0",
- "tar": "^2.0.0",
- "which": "1"
- },
- "dependencies": {
- "ajv": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
- "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
- "dev": true,
- "optional": true,
- "requires": {
- "co": "^4.6.0",
- "json-stable-stringify": "^1.0.1"
- }
- },
- "assert-plus": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
- "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
- "dev": true,
- "optional": true
- },
- "aws-sign2": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
- "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
- "dev": true,
- "optional": true
- },
- "form-data": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
- "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
- "dev": true,
- "optional": true,
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.5",
- "mime-types": "^2.1.12"
- }
- },
- "har-schema": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
- "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
- "dev": true,
- "optional": true
- },
- "har-validator": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
- "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
- "dev": true,
- "optional": true,
- "requires": {
- "ajv": "^4.9.1",
- "har-schema": "^1.0.5"
- }
- },
- "http-signature": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
- "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
- "dev": true,
- "optional": true,
- "requires": {
- "assert-plus": "^0.2.0",
- "jsprim": "^1.2.2",
- "sshpk": "^1.7.0"
- }
- },
- "performance-now": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
- "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
- "dev": true,
- "optional": true
- },
- "qs": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
- "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
- "dev": true,
- "optional": true
- },
- "request": {
- "version": "2.81.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
- "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
- "dev": true,
- "optional": true,
- "requires": {
- "aws-sign2": "~0.6.0",
- "aws4": "^1.2.1",
- "caseless": "~0.12.0",
- "combined-stream": "~1.0.5",
- "extend": "~3.0.0",
- "forever-agent": "~0.6.1",
- "form-data": "~2.1.1",
- "har-validator": "~4.2.1",
- "hawk": "~3.1.3",
- "http-signature": "~1.1.0",
- "is-typedarray": "~1.0.0",
- "isstream": "~0.1.2",
- "json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.7",
- "oauth-sign": "~0.8.1",
- "performance-now": "^0.2.0",
- "qs": "~6.4.0",
- "safe-buffer": "^5.0.1",
- "stringstream": "~0.0.4",
- "tough-cookie": "~2.3.0",
- "tunnel-agent": "^0.6.0",
- "uuid": "^3.0.0"
- }
- },
- "semver": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
- "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
- "dev": true,
- "optional": true
- }
- }
- },
- "node-libs-browser": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
- "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
- "dev": true,
- "requires": {
- "assert": "^1.1.1",
- "browserify-zlib": "^0.2.0",
- "buffer": "^4.3.0",
- "console-browserify": "^1.1.0",
- "constants-browserify": "^1.0.0",
- "crypto-browserify": "^3.11.0",
- "domain-browser": "^1.1.1",
- "events": "^1.0.0",
- "https-browserify": "^1.0.0",
- "os-browserify": "^0.3.0",
- "path-browserify": "0.0.0",
- "process": "^0.11.10",
- "punycode": "^1.2.4",
- "querystring-es3": "^0.2.0",
- "readable-stream": "^2.3.3",
- "stream-browserify": "^2.0.1",
- "stream-http": "^2.7.2",
- "string_decoder": "^1.0.0",
- "timers-browserify": "^2.0.4",
- "tty-browserify": "0.0.0",
- "url": "^0.11.0",
- "util": "^0.10.3",
- "vm-browserify": "0.0.4"
- },
- "dependencies": {
- "punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true
- }
- }
- },
- "node-sass": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.1.tgz",
- "integrity": "sha512-m6H1I6cHXsHsJ7BIWdnJsz9S9gVMyh+/H2cOTXgl2/2WqyyWlBcl4PHJcqrXo5RZVCfCUFqOtjPN0+0XbVHR5Q==",
- "dev": true,
- "optional": true,
- "requires": {
- "async-foreach": "^0.1.3",
- "chalk": "^1.1.1",
- "cross-spawn": "^3.0.0",
- "gaze": "^1.0.0",
- "get-stdin": "^4.0.1",
- "glob": "^7.0.3",
- "in-publish": "^2.0.0",
- "lodash.assign": "^4.2.0",
- "lodash.clonedeep": "^4.3.2",
- "lodash.mergewith": "^4.6.0",
- "meow": "^3.7.0",
- "mkdirp": "^0.5.1",
- "nan": "^2.10.0",
- "node-gyp": "^3.3.1",
- "npmlog": "^4.0.0",
- "request": "2.87.0",
- "sass-graph": "^2.2.4",
- "stdout-stream": "^1.4.0",
- "true-case-path": "^1.0.2"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true,
- "optional": true
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "dev": true,
- "optional": true,
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true,
- "optional": true
- }
- }
- },
- "nopt": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
- "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
- "dev": true,
- "requires": {
- "abbrev": "1"
- }
- },
- "normalize-package-data": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
- "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
- "dev": true,
- "requires": {
- "hosted-git-info": "^2.1.4",
- "is-builtin-module": "^1.0.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "normalize-path": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
- "dev": true,
- "requires": {
- "remove-trailing-separator": "^1.0.1"
- }
- },
- "normalize-range": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
- "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
- "dev": true
- },
- "npm-package-arg": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz",
- "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==",
- "dev": true,
- "requires": {
- "hosted-git-info": "^2.6.0",
- "osenv": "^0.1.5",
- "semver": "^5.5.0",
- "validate-npm-package-name": "^3.0.0"
- }
- },
- "npm-registry-client": {
- "version": "8.5.1",
- "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-8.5.1.tgz",
- "integrity": "sha512-7rjGF2eA7hKDidGyEWmHTiKfXkbrcQAsGL/Rh4Rt3x3YNRNHhwaTzVJfW3aNvvlhg4G62VCluif0sLCb/i51Hg==",
- "dev": true,
- "requires": {
- "concat-stream": "^1.5.2",
- "graceful-fs": "^4.1.6",
- "normalize-package-data": "~1.0.1 || ^2.0.0",
- "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0",
- "npmlog": "2 || ^3.1.0 || ^4.0.0",
- "once": "^1.3.3",
- "request": "^2.74.0",
- "retry": "^0.10.0",
- "safe-buffer": "^5.1.1",
- "semver": "2 >=2.2.1 || 3.x || 4 || 5",
- "slide": "^1.1.3",
- "ssri": "^5.2.4"
- }
- },
- "npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
- "dev": true,
- "requires": {
- "path-key": "^2.0.0"
- }
- },
- "npmlog": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
- "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
- "dev": true,
- "requires": {
- "are-we-there-yet": "~1.1.2",
- "console-control-strings": "~1.1.0",
- "gauge": "~2.7.3",
- "set-blocking": "~2.0.0"
- }
- },
- "nth-check": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
- "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
- "dev": true,
- "requires": {
- "boolbase": "~1.0.0"
- }
- },
- "null-check": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz",
- "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=",
- "dev": true
- },
- "num2fraction": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
- "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
- "dev": true
- },
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
- "dev": true
- },
- "oauth-sign": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
- "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
- "dev": true
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "dev": true
- },
- "object-component": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
- "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
- "dev": true
- },
- "object-copy": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
- "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
- "dev": true,
- "requires": {
- "copy-descriptor": "^0.1.0",
- "define-property": "^0.2.5",
- "kind-of": "^3.0.3"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "object-keys": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
- "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
- "dev": true
- },
- "object-visit": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
- "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
- "dev": true,
- "requires": {
- "isobject": "^3.0.0"
- }
- },
- "object.assign": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
- "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.2",
- "function-bind": "^1.1.1",
- "has-symbols": "^1.0.0",
- "object-keys": "^1.0.11"
- }
- },
- "object.getownpropertydescriptors": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
- "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.2",
- "es-abstract": "^1.5.1"
- }
- },
- "object.omit": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
- "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
- "dev": true,
- "requires": {
- "for-own": "^0.1.4",
- "is-extendable": "^0.1.1"
- },
- "dependencies": {
- "for-own": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
- "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
- "dev": true,
- "requires": {
- "for-in": "^1.0.1"
- }
- }
- }
- },
- "object.pick": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
- "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
- "dev": true,
- "requires": {
- "isobject": "^3.0.1"
- }
- },
- "obuf": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
- "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
- "dev": true
- },
- "on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
- "dev": true,
- "requires": {
- "ee-first": "1.1.1"
- }
- },
- "on-headers": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
- "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=",
- "dev": true
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "requires": {
- "wrappy": "1"
- }
- },
- "opn": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
- "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
- "dev": true,
- "requires": {
- "is-wsl": "^1.1.0"
- }
- },
- "optimist": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
- "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
- "dev": true,
- "requires": {
- "minimist": "~0.0.1",
- "wordwrap": "~0.0.2"
- },
- "dependencies": {
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
- "dev": true
- }
- }
- },
- "optionator": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
- "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
- "dev": true,
- "requires": {
- "deep-is": "~0.1.3",
- "fast-levenshtein": "~2.0.4",
- "levn": "~0.3.0",
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2",
- "wordwrap": "~1.0.0"
- }
- },
- "options": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
- "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=",
- "dev": true
- },
- "optjs": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz",
- "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4="
- },
- "original": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz",
- "integrity": "sha512-IEvtB5vM5ULvwnqMxWBLxkS13JIEXbakizMSo3yoPNPCIWzg8TG3Usn/UhXoZFM/m+FuEA20KdzPSFq/0rS+UA==",
- "dev": true,
- "requires": {
- "url-parse": "~1.4.0"
- }
- },
- "os-browserify": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
- "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
- "dev": true
- },
- "os-homedir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
- "dev": true
- },
- "os-locale": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
- "dev": true,
- "optional": true,
- "requires": {
- "lcid": "^1.0.0"
- }
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
- "dev": true
- },
- "osenv": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
- "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
- "dev": true,
- "requires": {
- "os-homedir": "^1.0.0",
- "os-tmpdir": "^1.0.0"
- }
- },
- "p-finally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
- "dev": true
- },
- "p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
- "dev": true,
- "requires": {
- "p-try": "^1.0.0"
- }
- },
- "p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
- "dev": true,
- "requires": {
- "p-limit": "^1.1.0"
- }
- },
- "p-map": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
- "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
- "dev": true
- },
- "p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
- "dev": true
- },
- "pako": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
- "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
- "dev": true
- },
- "parallel-transform": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
- "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
- "dev": true,
- "requires": {
- "cyclist": "~0.2.2",
- "inherits": "^2.0.3",
- "readable-stream": "^2.1.5"
- }
- },
- "param-case": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
- "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
- "dev": true,
- "requires": {
- "no-case": "^2.2.0"
- }
- },
- "parse-asn1": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
- "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
- "dev": true,
- "requires": {
- "asn1.js": "^4.0.0",
- "browserify-aes": "^1.0.0",
- "create-hash": "^1.1.0",
- "evp_bytestokey": "^1.0.0",
- "pbkdf2": "^3.0.3"
- }
- },
- "parse-glob": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
- "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
- "dev": true,
- "requires": {
- "glob-base": "^0.3.0",
- "is-dotfile": "^1.0.0",
- "is-extglob": "^1.0.0",
- "is-glob": "^2.0.0"
- },
- "dependencies": {
- "is-extglob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
- "dev": true
- },
- "is-glob": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
- "dev": true,
- "requires": {
- "is-extglob": "^1.0.0"
- }
- }
- }
- },
- "parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
- "dev": true,
- "requires": {
- "error-ex": "^1.2.0"
- }
- },
- "parse5": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
- "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
- "dev": true
- },
- "parsejson": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz",
- "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=",
- "dev": true,
- "requires": {
- "better-assert": "~1.0.0"
- }
- },
- "parseqs": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
- "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
- "dev": true,
- "requires": {
- "better-assert": "~1.0.0"
- }
- },
- "parseuri": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
- "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
- "dev": true,
- "requires": {
- "better-assert": "~1.0.0"
- }
- },
- "parseurl": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
- "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
- "dev": true
- },
- "pascalcase": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
- "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
- "dev": true
- },
- "path-browserify": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
- "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
- "dev": true
- },
- "path-dirname": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
- "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
- "dev": true
- },
- "path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
- "dev": true
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
- },
- "path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
- "dev": true
- },
- "path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
- "dev": true
- },
- "path-parse": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
- "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
- "dev": true
- },
- "path-to-regexp": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
- "dev": true
- },
- "path-type": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
- "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
- "dev": true,
- "requires": {
- "pify": "^3.0.0"
- }
- },
- "pbkdf2": {
- "version": "3.0.16",
- "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz",
- "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==",
- "dev": true,
- "requires": {
- "create-hash": "^1.1.2",
- "create-hmac": "^1.1.4",
- "ripemd160": "^2.0.1",
- "safe-buffer": "^5.0.1",
- "sha.js": "^2.4.8"
- }
- },
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
- "dev": true
- },
- "pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
- "dev": true
- },
- "pinkie": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
- "dev": true
- },
- "pinkie-promise": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
- "dev": true,
- "requires": {
- "pinkie": "^2.0.0"
- }
- },
- "pkg-dir": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
- "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
- "dev": true,
- "requires": {
- "find-up": "^2.1.0"
- }
- },
- "portfinder": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz",
- "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=",
- "dev": true,
- "requires": {
- "async": "^1.5.2",
- "debug": "^2.2.0",
- "mkdirp": "0.5.x"
- }
- },
- "posix-character-classes": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
- "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
- "dev": true
- },
- "postcss": {
- "version": "6.0.23",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
- "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
- "dev": true,
- "requires": {
- "chalk": "^2.4.1",
- "source-map": "^0.6.1",
- "supports-color": "^5.4.0"
- },
- "dependencies": {
- "chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
- }
- },
- "postcss-import": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz",
- "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==",
- "dev": true,
- "requires": {
- "postcss": "^6.0.1",
- "postcss-value-parser": "^3.2.3",
- "read-cache": "^1.0.0",
- "resolve": "^1.1.7"
- }
- },
- "postcss-load-config": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
- "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=",
- "dev": true,
- "requires": {
- "cosmiconfig": "^2.1.0",
- "object-assign": "^4.1.0",
- "postcss-load-options": "^1.2.0",
- "postcss-load-plugins": "^2.3.0"
- }
- },
- "postcss-load-options": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz",
- "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=",
- "dev": true,
- "requires": {
- "cosmiconfig": "^2.1.0",
- "object-assign": "^4.1.0"
- }
- },
- "postcss-load-plugins": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz",
- "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=",
- "dev": true,
- "requires": {
- "cosmiconfig": "^2.1.1",
- "object-assign": "^4.1.0"
- }
- },
- "postcss-loader": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.5.tgz",
- "integrity": "sha512-pV7kB5neJ0/1tZ8L1uGOBNTVBCSCXQoIsZMsrwvO8V2rKGa2tBl/f80GGVxow2jJnRJ2w1ocx693EKhZAb9Isg==",
- "dev": true,
- "requires": {
- "loader-utils": "^1.1.0",
- "postcss": "^6.0.0",
- "postcss-load-config": "^1.2.0",
- "schema-utils": "^0.4.0"
- }
- },
- "postcss-url": {
- "version": "7.3.2",
- "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.2.tgz",
- "integrity": "sha512-QMV5mA+pCYZQcUEPQkmor9vcPQ2MT+Ipuu8qdi1gVxbNiIiErEGft+eny1ak19qALoBkccS5AHaCaCDzh7b9MA==",
- "dev": true,
- "requires": {
- "mime": "^1.4.1",
- "minimatch": "^3.0.4",
- "mkdirp": "^0.5.0",
- "postcss": "^6.0.1",
- "xxhashjs": "^0.2.1"
- }
- },
- "postcss-value-parser": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
- "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
- "dev": true
- },
- "prelude-ls": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
- "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
- "dev": true
- },
- "preserve": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
- "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
- "dev": true
- },
- "pretty-error": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz",
- "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=",
- "dev": true,
- "requires": {
- "renderkid": "^2.0.1",
- "utila": "~0.4"
- }
- },
- "process": {
- "version": "0.11.10",
- "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
- "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
- "dev": true
- },
- "process-nextick-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
- "dev": true
- },
- "promise": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
- "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
- "dev": true,
- "optional": true,
- "requires": {
- "asap": "~2.0.3"
- }
- },
- "promise-inflight": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
- "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
- "dev": true
- },
- "promise-polyfill": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-7.1.2.tgz",
- "integrity": "sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ=="
- },
- "protobufjs": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz",
- "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==",
- "requires": {
- "ascli": "~1",
- "bytebuffer": "~5",
- "glob": "^7.0.5",
- "yargs": "^3.10.0"
- }
- },
- "protractor": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.3.2.tgz",
- "integrity": "sha512-pw4uwwiy5lHZjIguxNpkEwJJa7hVz+bJsvaTI+IbXlfn2qXwzbF8eghW/RmrZwE2sGx82I8etb8lVjQ+JrjejA==",
- "dev": true,
- "requires": {
- "@types/node": "^6.0.46",
- "@types/q": "^0.0.32",
- "@types/selenium-webdriver": "~2.53.39",
- "blocking-proxy": "^1.0.0",
- "chalk": "^1.1.3",
- "glob": "^7.0.3",
- "jasmine": "2.8.0",
- "jasminewd2": "^2.1.0",
- "optimist": "~0.6.0",
- "q": "1.4.1",
- "saucelabs": "^1.5.0",
- "selenium-webdriver": "3.6.0",
- "source-map-support": "~0.4.0",
- "webdriver-js-extender": "^1.0.0",
- "webdriver-manager": "^12.0.6"
- },
- "dependencies": {
- "@types/node": {
- "version": "6.0.113",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.113.tgz",
- "integrity": "sha512-f9XXUWFqryzjkZA1EqFvJHSFyqyasV17fq8zCDIzbRV4ctL7RrJGKvG+lcex86Rjbzd1GrER9h9VmF5sSjV0BQ==",
- "dev": true
- },
- "adm-zip": {
- "version": "0.4.11",
- "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz",
- "integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==",
- "dev": true
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "dev": true,
- "requires": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- }
- },
- "del": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
- "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
- "dev": true,
- "requires": {
- "globby": "^5.0.0",
- "is-path-cwd": "^1.0.0",
- "is-path-in-cwd": "^1.0.0",
- "object-assign": "^4.0.1",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0",
- "rimraf": "^2.2.8"
- }
- },
- "globby": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
- "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
- "dev": true,
- "requires": {
- "array-union": "^1.0.1",
- "arrify": "^1.0.0",
- "glob": "^7.0.3",
- "object-assign": "^4.0.1",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- },
- "source-map-support": {
- "version": "0.4.18",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
- "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
- "dev": true,
- "requires": {
- "source-map": "^0.5.6"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true
- },
- "webdriver-manager": {
- "version": "12.1.0",
- "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.0.tgz",
- "integrity": "sha512-oEc5fmkpz6Yh6udhwir5m0eN5mgRPq9P/NU5YWuT3Up5slt6Zz+znhLU7q4+8rwCZz/Qq3Fgpr/4oao7NPCm2A==",
- "dev": true,
- "requires": {
- "adm-zip": "^0.4.9",
- "chalk": "^1.1.1",
- "del": "^2.2.0",
- "glob": "^7.0.3",
- "ini": "^1.3.4",
- "minimist": "^1.2.0",
- "q": "^1.4.1",
- "request": "^2.87.0",
- "rimraf": "^2.5.2",
- "semver": "^5.3.0",
- "xml2js": "^0.4.17"
- }
- }
- }
- },
- "proxy-addr": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
- "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
- "dev": true,
- "requires": {
- "forwarded": "~0.1.2",
- "ipaddr.js": "1.6.0"
- }
- },
- "prr": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
- "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
- "dev": true
- },
- "pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
- },
- "public-encrypt": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
- "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==",
- "dev": true,
- "requires": {
- "bn.js": "^4.1.0",
- "browserify-rsa": "^4.0.0",
- "create-hash": "^1.1.0",
- "parse-asn1": "^5.0.0",
- "randombytes": "^2.0.1"
- }
- },
- "pump": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
- "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "pumpify": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
- "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
- "dev": true,
- "requires": {
- "duplexify": "^3.6.0",
- "inherits": "^2.0.3",
- "pump": "^2.0.0"
- }
- },
- "punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
- "dev": true
- },
- "q": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
- "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
- "dev": true
- },
- "qjobs": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
- "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
- "dev": true
- },
- "qs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
- "dev": true
- },
- "querystring": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
- "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
- "dev": true
- },
- "querystring-es3": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
- "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
- "dev": true
- },
- "querystringify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz",
- "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==",
- "dev": true
- },
- "randomatic": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz",
- "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==",
- "dev": true,
- "requires": {
- "is-number": "^4.0.0",
- "kind-of": "^6.0.0",
- "math-random": "^1.0.1"
- },
- "dependencies": {
- "is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
- "dev": true
- }
- }
- },
- "randombytes": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
- "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
- "dev": true,
- "requires": {
- "safe-buffer": "^5.1.0"
- }
- },
- "randomfill": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
- "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
- "dev": true,
- "requires": {
- "randombytes": "^2.0.5",
- "safe-buffer": "^5.1.0"
- }
- },
- "range-parser": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
- "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
- "dev": true
- },
- "raw-body": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
- "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
- "dev": true,
- "requires": {
- "bytes": "3.0.0",
- "http-errors": "1.6.2",
- "iconv-lite": "0.4.19",
- "unpipe": "1.0.0"
- },
- "dependencies": {
- "depd": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
- "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
- "dev": true
- },
- "http-errors": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
- "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
- "dev": true,
- "requires": {
- "depd": "1.1.1",
- "inherits": "2.0.3",
- "setprototypeof": "1.0.3",
- "statuses": ">= 1.3.1 < 2"
- }
- },
- "setprototypeof": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
- "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
- "dev": true
- }
- }
- },
- "raw-loader": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
- "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=",
- "dev": true
- },
- "read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
- "dev": true,
- "requires": {
- "pify": "^2.3.0"
- },
- "dependencies": {
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- }
- }
- },
- "read-pkg": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
- "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
- "dev": true,
- "requires": {
- "load-json-file": "^1.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^1.0.0"
- },
- "dependencies": {
- "path-type": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
- "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- }
- }
- },
- "read-pkg-up": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
- "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
- "dev": true,
- "requires": {
- "find-up": "^1.0.0",
- "read-pkg": "^1.0.0"
- },
- "dependencies": {
- "find-up": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
- "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
- "dev": true,
- "requires": {
- "path-exists": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- },
- "path-exists": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
- "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
- "dev": true,
- "requires": {
- "pinkie-promise": "^2.0.0"
- }
- }
- }
- },
- "readable-stream": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "readdirp": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
- "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "minimatch": "^3.0.2",
- "readable-stream": "^2.0.2",
- "set-immediate-shim": "^1.0.1"
- }
- },
- "redent": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
- "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
- "dev": true,
- "requires": {
- "indent-string": "^2.1.0",
- "strip-indent": "^1.0.1"
- }
- },
- "reflect-metadata": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.12.tgz",
- "integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==",
- "dev": true
- },
- "regenerate": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
- "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
- "dev": true
- },
- "regenerator-runtime": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
- "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
- "dev": true
- },
- "regex-cache": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
- "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
- "dev": true,
- "requires": {
- "is-equal-shallow": "^0.1.3"
- }
- },
- "regex-not": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
- "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
- "dev": true,
- "requires": {
- "extend-shallow": "^3.0.2",
- "safe-regex": "^1.1.0"
- }
- },
- "regexpu-core": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
- "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
- "dev": true,
- "requires": {
- "regenerate": "^1.2.1",
- "regjsgen": "^0.2.0",
- "regjsparser": "^0.1.4"
- }
- },
- "regjsgen": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
- "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
- "dev": true
- },
- "regjsparser": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
- "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
- "dev": true,
- "requires": {
- "jsesc": "~0.5.0"
- },
- "dependencies": {
- "jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
- "dev": true
- }
- }
- },
- "relateurl": {
- "version": "0.2.7",
- "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
- "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
- "dev": true
- },
- "remove-trailing-separator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
- "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
- "dev": true
- },
- "renderkid": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz",
- "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=",
- "dev": true,
- "requires": {
- "css-select": "^1.1.0",
- "dom-converter": "~0.1",
- "htmlparser2": "~3.3.0",
- "strip-ansi": "^3.0.0",
- "utila": "~0.3"
- },
- "dependencies": {
- "utila": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz",
- "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=",
- "dev": true
- }
- }
- },
- "repeat-element": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
- "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
- "dev": true
- },
- "repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
- },
- "repeating": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
- "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
- "dev": true,
- "requires": {
- "is-finite": "^1.0.0"
- }
- },
- "request": {
- "version": "2.87.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
- "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
- "dev": true,
- "requires": {
- "aws-sign2": "~0.7.0",
- "aws4": "^1.6.0",
- "caseless": "~0.12.0",
- "combined-stream": "~1.0.5",
- "extend": "~3.0.1",
- "forever-agent": "~0.6.1",
- "form-data": "~2.3.1",
- "har-validator": "~5.0.3",
- "http-signature": "~1.2.0",
- "is-typedarray": "~1.0.0",
- "isstream": "~0.1.2",
- "json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.17",
- "oauth-sign": "~0.8.2",
- "performance-now": "^2.1.0",
- "qs": "~6.5.1",
- "safe-buffer": "^5.1.1",
- "tough-cookie": "~2.3.3",
- "tunnel-agent": "^0.6.0",
- "uuid": "^3.1.0"
- }
- },
- "require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
- "dev": true
- },
- "require-from-string": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
- "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
- "dev": true
- },
- "require-main-filename": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
- "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
- "dev": true
- },
- "requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
- "dev": true
- },
- "resolve": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
- "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
- "dev": true,
- "requires": {
- "path-parse": "^1.0.5"
- }
- },
- "resolve-cwd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
- "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
- "dev": true,
- "requires": {
- "resolve-from": "^3.0.0"
- }
- },
- "resolve-from": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
- "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
- "dev": true
- },
- "resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
- "dev": true
- },
- "ret": {
- "version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
- "dev": true
- },
- "retry": {
- "version": "0.10.1",
- "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
- "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=",
- "dev": true
- },
- "right-align": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
- "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
- "requires": {
- "align-text": "^0.1.1"
- }
- },
- "rimraf": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
- "dev": true,
- "requires": {
- "glob": "^7.0.5"
- }
- },
- "ripemd160": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
- "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
- "dev": true,
- "requires": {
- "hash-base": "^3.0.0",
- "inherits": "^2.0.1"
- }
- },
- "run-queue": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
- "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
- "dev": true,
- "requires": {
- "aproba": "^1.1.1"
- }
- },
- "rxjs": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.1.tgz",
- "integrity": "sha512-OwMxHxmnmHTUpgO+V7dZChf3Tixf4ih95cmXjzzadULziVl/FKhHScGLj4goEw9weePVOH2Q0+GcCBUhKCZc/g==",
- "requires": {
- "tslib": "^1.9.0"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "safe-regex": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
- "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
- "dev": true,
- "requires": {
- "ret": "~0.1.10"
- }
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true
- },
- "sass-graph": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
- "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
- "dev": true,
- "optional": true,
- "requires": {
- "glob": "^7.0.0",
- "lodash": "^4.0.0",
- "scss-tokenizer": "^0.2.3",
- "yargs": "^7.0.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
- "dev": true,
- "optional": true
- },
- "cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
- "dev": true,
- "optional": true,
- "requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wrap-ansi": "^2.0.0"
- }
- },
- "y18n": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
- "dev": true,
- "optional": true
- },
- "yargs": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
- "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
- "dev": true,
- "optional": true,
- "requires": {
- "camelcase": "^3.0.0",
- "cliui": "^3.2.0",
- "decamelize": "^1.1.1",
- "get-caller-file": "^1.0.1",
- "os-locale": "^1.4.0",
- "read-pkg-up": "^1.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^1.0.2",
- "which-module": "^1.0.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^5.0.0"
- }
- }
- }
- },
- "sass-loader": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.0.3.tgz",
- "integrity": "sha512-iaSFtQcGo4SSgDw5Aes5p4VTrA5jCGSA7sGmhPIcOloBlgI1VktM2MUrk2IHHjbNagckXlPz+HWq1vAAPrcYxA==",
- "dev": true,
- "requires": {
- "clone-deep": "^2.0.1",
- "loader-utils": "^1.0.1",
- "lodash.tail": "^4.1.1",
- "neo-async": "^2.5.0",
- "pify": "^3.0.0"
- }
- },
- "saucelabs": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz",
- "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==",
- "dev": true,
- "requires": {
- "https-proxy-agent": "^2.2.1"
- }
- },
- "sax": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz",
- "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=",
- "dev": true
- },
- "schema-utils": {
- "version": "0.4.5",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz",
- "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==",
- "dev": true,
- "requires": {
- "ajv": "^6.1.0",
- "ajv-keywords": "^3.1.0"
- }
- },
- "scss-tokenizer": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
- "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
- "dev": true,
- "optional": true,
- "requires": {
- "js-base64": "^2.1.8",
- "source-map": "^0.4.2"
- },
- "dependencies": {
- "source-map": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
- "dev": true,
- "optional": true,
- "requires": {
- "amdefine": ">=0.0.4"
- }
- }
- }
- },
- "select-hose": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
- "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
- "dev": true
- },
- "selenium-webdriver": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz",
- "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==",
- "dev": true,
- "requires": {
- "jszip": "^3.1.3",
- "rimraf": "^2.5.4",
- "tmp": "0.0.30",
- "xml2js": "^0.4.17"
- },
- "dependencies": {
- "tmp": {
- "version": "0.0.30",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
- "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
- "dev": true,
- "requires": {
- "os-tmpdir": "~1.0.1"
- }
- }
- }
- },
- "selfsigned": {
- "version": "1.10.3",
- "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.3.tgz",
- "integrity": "sha512-vmZenZ+8Al3NLHkWnhBQ0x6BkML1eCP2xEi3JE+f3D9wW9fipD9NNJHYtE9XJM4TsPaHGZJIamrSI6MTg1dU2Q==",
- "dev": true,
- "requires": {
- "node-forge": "0.7.5"
- }
- },
- "semver": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
- "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
- "dev": true
- },
- "semver-dsl": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz",
- "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=",
- "dev": true,
- "requires": {
- "semver": "^5.3.0"
- }
- },
- "semver-intersect": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.3.1.tgz",
- "integrity": "sha1-j6hKnhAovSOeRTDRo+GB5pjYhLo=",
- "dev": true,
- "requires": {
- "semver": "^5.0.0"
- }
- },
- "send": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
- "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "destroy": "~1.0.4",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "~1.6.2",
- "mime": "1.4.1",
- "ms": "2.0.0",
- "on-finished": "~2.3.0",
- "range-parser": "~1.2.0",
- "statuses": "~1.4.0"
- },
- "dependencies": {
- "mime": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
- "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
- "dev": true
- }
- }
- },
- "serialize-javascript": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz",
- "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==",
- "dev": true
- },
- "serve-index": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
- "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
- "dev": true,
- "requires": {
- "accepts": "~1.3.4",
- "batch": "0.6.1",
- "debug": "2.6.9",
- "escape-html": "~1.0.3",
- "http-errors": "~1.6.2",
- "mime-types": "~2.1.17",
- "parseurl": "~1.3.2"
- }
- },
- "serve-static": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
- "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
- "dev": true,
- "requires": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.2",
- "send": "0.16.2"
- }
- },
- "set-blocking": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
- "dev": true
- },
- "set-immediate-shim": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
- "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
- "dev": true
- },
- "set-value": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
- "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.3",
- "split-string": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "setimmediate": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
- "dev": true
- },
- "setprototypeof": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
- "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
- "dev": true
- },
- "sha.js": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
- "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "shallow-clone": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz",
- "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.1",
- "kind-of": "^5.0.0",
- "mixin-object": "^2.0.1"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
- "shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
- "dev": true,
- "requires": {
- "shebang-regex": "^1.0.0"
- }
- },
- "shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
- "dev": true
- },
- "signal-exit": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
- "dev": true
- },
- "silent-error": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/silent-error/-/silent-error-1.1.0.tgz",
- "integrity": "sha1-IglwbxyFCp8dENDYQJGLRvJuG8k=",
- "dev": true,
- "requires": {
- "debug": "^2.2.0"
- }
- },
- "slash": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
- "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
- "dev": true
- },
- "slide": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
- "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=",
- "dev": true
- },
- "snapdragon": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
- "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
- "dev": true,
- "requires": {
- "base": "^0.11.1",
- "debug": "^2.2.0",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "map-cache": "^0.2.2",
- "source-map": "^0.5.6",
- "source-map-resolve": "^0.5.0",
- "use": "^3.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
- "snapdragon-node": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
- "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
- "dev": true,
- "requires": {
- "define-property": "^1.0.0",
- "isobject": "^3.0.0",
- "snapdragon-util": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "snapdragon-util": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
- "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
- "dev": true,
- "requires": {
- "kind-of": "^3.2.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "sntp": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
- "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
- "dev": true,
- "optional": true,
- "requires": {
- "hoek": "2.x.x"
- }
- },
- "socket.io": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz",
- "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=",
- "dev": true,
- "requires": {
- "debug": "2.3.3",
- "engine.io": "1.8.3",
- "has-binary": "0.1.7",
- "object-assign": "4.1.0",
- "socket.io-adapter": "0.5.0",
- "socket.io-client": "1.7.3",
- "socket.io-parser": "2.3.1"
- },
- "dependencies": {
- "debug": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
- "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
- "dev": true,
- "requires": {
- "ms": "0.7.2"
- }
- },
- "ms": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
- "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
- "dev": true
- },
- "object-assign": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
- "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=",
- "dev": true
- }
- }
- },
- "socket.io-adapter": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz",
- "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=",
- "dev": true,
- "requires": {
- "debug": "2.3.3",
- "socket.io-parser": "2.3.1"
- },
- "dependencies": {
- "debug": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
- "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
- "dev": true,
- "requires": {
- "ms": "0.7.2"
- }
- },
- "ms": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
- "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
- "dev": true
- }
- }
- },
- "socket.io-client": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz",
- "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=",
- "dev": true,
- "requires": {
- "backo2": "1.0.2",
- "component-bind": "1.0.0",
- "component-emitter": "1.2.1",
- "debug": "2.3.3",
- "engine.io-client": "1.8.3",
- "has-binary": "0.1.7",
- "indexof": "0.0.1",
- "object-component": "0.0.3",
- "parseuri": "0.0.5",
- "socket.io-parser": "2.3.1",
- "to-array": "0.1.4"
- },
- "dependencies": {
- "debug": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
- "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
- "dev": true,
- "requires": {
- "ms": "0.7.2"
- }
- },
- "ms": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
- "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
- "dev": true
- }
- }
- },
- "socket.io-parser": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz",
- "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=",
- "dev": true,
- "requires": {
- "component-emitter": "1.1.2",
- "debug": "2.2.0",
- "isarray": "0.0.1",
- "json3": "3.3.2"
- },
- "dependencies": {
- "component-emitter": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz",
- "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=",
- "dev": true
- },
- "debug": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
- "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
- "dev": true,
- "requires": {
- "ms": "0.7.1"
- }
- },
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
- "dev": true
- },
- "ms": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
- "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
- "dev": true
- }
- }
- },
- "sockjs": {
- "version": "0.3.19",
- "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
- "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
- "dev": true,
- "requires": {
- "faye-websocket": "^0.10.0",
- "uuid": "^3.0.1"
- }
- },
- "sockjs-client": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz",
- "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=",
- "dev": true,
- "requires": {
- "debug": "^2.6.6",
- "eventsource": "0.1.6",
- "faye-websocket": "~0.11.0",
- "inherits": "^2.0.1",
- "json3": "^3.3.2",
- "url-parse": "^1.1.8"
- },
- "dependencies": {
- "faye-websocket": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
- "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=",
- "dev": true,
- "requires": {
- "websocket-driver": ">=0.5.1"
- }
- }
- }
- },
- "source-list-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
- "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
- "dev": true
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
- },
- "source-map-resolve": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
- "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
- "dev": true,
- "requires": {
- "atob": "^2.1.1",
- "decode-uri-component": "^0.2.0",
- "resolve-url": "^0.2.1",
- "source-map-url": "^0.4.0",
- "urix": "^0.1.0"
- }
- },
- "source-map-support": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz",
- "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==",
- "dev": true,
- "requires": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
- }
- },
- "source-map-url": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
- "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
- "dev": true
- },
- "spdx-correct": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
- "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
- "dev": true,
- "requires": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-exceptions": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
- "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
- "dev": true
- },
- "spdx-expression-parse": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
- "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
- "dev": true,
- "requires": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-license-ids": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
- "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==",
- "dev": true
- },
- "spdy": {
- "version": "3.4.7",
- "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz",
- "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=",
- "dev": true,
- "requires": {
- "debug": "^2.6.8",
- "handle-thing": "^1.2.5",
- "http-deceiver": "^1.2.7",
- "safe-buffer": "^5.0.1",
- "select-hose": "^2.0.0",
- "spdy-transport": "^2.0.18"
- }
- },
- "spdy-transport": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz",
- "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==",
- "dev": true,
- "requires": {
- "debug": "^2.6.8",
- "detect-node": "^2.0.3",
- "hpack.js": "^2.1.6",
- "obuf": "^1.1.1",
- "readable-stream": "^2.2.9",
- "safe-buffer": "^5.0.1",
- "wbuf": "^1.7.2"
- }
- },
- "split-string": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
- "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
- "dev": true,
- "requires": {
- "extend-shallow": "^3.0.0"
- }
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
- },
- "sshpk": {
- "version": "1.14.2",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
- "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
- "dev": true,
- "requires": {
- "asn1": "~0.2.3",
- "assert-plus": "^1.0.0",
- "bcrypt-pbkdf": "^1.0.0",
- "dashdash": "^1.12.0",
- "ecc-jsbn": "~0.1.1",
- "getpass": "^0.1.1",
- "jsbn": "~0.1.0",
- "safer-buffer": "^2.0.2",
- "tweetnacl": "~0.14.0"
- }
- },
- "ssri": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz",
- "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "^5.1.1"
- }
- },
- "static-extend": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
- "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
- "dev": true,
- "requires": {
- "define-property": "^0.2.5",
- "object-copy": "^0.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
- }
- },
- "stats-webpack-plugin": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/stats-webpack-plugin/-/stats-webpack-plugin-0.6.2.tgz",
- "integrity": "sha1-LFlJtTHgf4eojm6k3PrFOqjHWis=",
- "dev": true,
- "requires": {
- "lodash": "^4.17.4"
- }
- },
- "statuses": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
- "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
- "dev": true
- },
- "stdout-stream": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
- "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=",
- "dev": true,
- "optional": true,
- "requires": {
- "readable-stream": "^2.0.1"
- }
- },
- "stream-browserify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
- "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
- "dev": true,
- "requires": {
- "inherits": "~2.0.1",
- "readable-stream": "^2.0.2"
- }
- },
- "stream-each": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
- "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "stream-shift": "^1.0.0"
- }
- },
- "stream-http": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
- "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
- "dev": true,
- "requires": {
- "builtin-status-codes": "^3.0.0",
- "inherits": "^2.0.1",
- "readable-stream": "^2.3.6",
- "to-arraybuffer": "^1.0.0",
- "xtend": "^4.0.0"
- }
- },
- "stream-shift": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
- "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
- "dev": true
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "dev": true,
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- },
- "stringstream": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",
- "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==",
- "dev": true,
- "optional": true
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- },
- "strip-bom": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
- "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
- "dev": true,
- "requires": {
- "is-utf8": "^0.2.0"
- }
- },
- "strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
- "dev": true
- },
- "strip-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
- "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
- "dev": true,
- "requires": {
- "get-stdin": "^4.0.1"
- }
- },
- "style-loader": {
- "version": "0.21.0",
- "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz",
- "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==",
- "dev": true,
- "requires": {
- "loader-utils": "^1.1.0",
- "schema-utils": "^0.4.5"
- }
- },
- "stylus": {
- "version": "0.54.5",
- "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz",
- "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=",
- "dev": true,
- "requires": {
- "css-parse": "1.7.x",
- "debug": "*",
- "glob": "7.0.x",
- "mkdirp": "0.5.x",
- "sax": "0.5.x",
- "source-map": "0.1.x"
- },
- "dependencies": {
- "glob": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
- "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
- "dev": true,
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.2",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "source-map": {
- "version": "0.1.43",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
- "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
- "dev": true,
- "requires": {
- "amdefine": ">=0.0.4"
- }
- }
- }
- },
- "stylus-loader": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz",
- "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==",
- "dev": true,
- "requires": {
- "loader-utils": "^1.0.2",
- "lodash.clonedeep": "^4.5.0",
- "when": "~3.6.x"
- }
- },
- "supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
- "symbol-observable": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
- "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
- "dev": true
- },
- "tapable": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz",
- "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==",
- "dev": true
- },
- "tar": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
- "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
- "dev": true,
- "optional": true,
- "requires": {
- "block-stream": "*",
- "fstream": "^1.0.2",
- "inherits": "2"
- }
- },
- "text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
- "dev": true
- },
- "through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
- "dev": true
- },
- "through2": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
- "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
- "dev": true,
- "requires": {
- "readable-stream": "^2.1.5",
- "xtend": "~4.0.1"
- }
- },
- "thunky": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz",
- "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=",
- "dev": true
- },
- "timers-browserify": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz",
- "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
- "dev": true,
- "requires": {
- "setimmediate": "^1.0.4"
- }
- },
- "tmp": {
- "version": "0.0.31",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
- "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
- "dev": true,
- "requires": {
- "os-tmpdir": "~1.0.1"
- }
- },
- "to-array": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
- "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
- "dev": true
- },
- "to-arraybuffer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
- "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
- "dev": true
- },
- "to-fast-properties": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
- "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
- "dev": true
- },
- "to-object-path": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
- "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "to-regex": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
- "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
- "dev": true,
- "requires": {
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "regex-not": "^1.0.2",
- "safe-regex": "^1.1.0"
- }
- },
- "to-regex-range": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
- "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
- "dev": true,
- "requires": {
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1"
- }
- },
- "toposort": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz",
- "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
- "dev": true
- },
- "tough-cookie": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
- "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
- "dev": true,
- "requires": {
- "punycode": "^1.4.1"
- },
- "dependencies": {
- "punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true
- }
- }
- },
- "tree-kill": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz",
- "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==",
- "dev": true
- },
- "trim-newlines": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
- "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
- "dev": true
- },
- "trim-right": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
- "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
- "dev": true
- },
- "true-case-path": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz",
- "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=",
- "dev": true,
- "optional": true,
- "requires": {
- "glob": "^6.0.4"
- },
- "dependencies": {
- "glob": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
- "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
- "dev": true,
- "optional": true,
- "requires": {
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "2 || 3",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- }
- }
- },
- "ts-node": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-5.0.1.tgz",
- "integrity": "sha512-XK7QmDcNHVmZkVtkiwNDWiERRHPyU8nBqZB1+iv2UhOG0q3RQ9HsZ2CMqISlFbxjrYFGfG2mX7bW4dAyxBVzUw==",
- "dev": true,
- "requires": {
- "arrify": "^1.0.0",
- "chalk": "^2.3.0",
- "diff": "^3.1.0",
- "make-error": "^1.1.1",
- "minimist": "^1.2.0",
- "mkdirp": "^0.5.1",
- "source-map-support": "^0.5.3",
- "yn": "^2.0.0"
- },
- "dependencies": {
- "chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
- }
- },
- "tsickle": {
- "version": "0.29.0",
- "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.29.0.tgz",
- "integrity": "sha512-JpID0Lv8/irRtPmqJJxb5fCwfZhjZeKmav9Zna7UjqVuJoSbI49Wue/c2PPybX1SbRrjl7bbI/JsCl0dSUJygA==",
- "dev": true,
- "requires": {
- "minimist": "^1.2.0",
- "mkdirp": "^0.5.1",
- "source-map": "^0.6.0",
- "source-map-support": "^0.5.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
- }
- },
- "tslib": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
- "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
- },
- "tslint": {
- "version": "5.9.1",
- "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz",
- "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=",
- "dev": true,
- "requires": {
- "babel-code-frame": "^6.22.0",
- "builtin-modules": "^1.1.1",
- "chalk": "^2.3.0",
- "commander": "^2.12.1",
- "diff": "^3.2.0",
- "glob": "^7.1.1",
- "js-yaml": "^3.7.0",
- "minimatch": "^3.0.4",
- "resolve": "^1.3.2",
- "semver": "^5.3.0",
- "tslib": "^1.8.0",
- "tsutils": "^2.12.1"
- },
- "dependencies": {
- "chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- }
- }
- },
- "tsutils": {
- "version": "2.27.2",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.27.2.tgz",
- "integrity": "sha512-qf6rmT84TFMuxAKez2pIfR8UCai49iQsfB7YWVjV1bKpy/d0PWT5rEOSM6La9PiHZ0k1RRZQiwVdVJfQ3BPHgg==",
- "dev": true,
- "requires": {
- "tslib": "^1.8.1"
- }
- },
- "tty-browserify": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
- "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
- "dev": true
- },
- "tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
- "dev": true,
- "requires": {
- "safe-buffer": "^5.0.1"
- }
- },
- "tweetnacl": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
- "dev": true,
- "optional": true
- },
- "type-check": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
- "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
- "dev": true,
- "requires": {
- "prelude-ls": "~1.1.2"
- }
- },
- "type-is": {
- "version": "1.6.16",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
- "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
- "dev": true,
- "requires": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.18"
- }
- },
- "typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
- "dev": true
- },
- "typescript": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz",
- "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==",
- "dev": true
- },
- "uglify-js": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.3.tgz",
- "integrity": "sha512-RbOgGjF04sFUNSi8xGOTB9AmtVmMmVVAL5a7lxIgJ8urejJen+priq0ooRIHHa8AXI/dSvNF9yYMz9OP4PhybQ==",
- "dev": true,
- "requires": {
- "commander": "~2.16.0",
- "source-map": "~0.6.1"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
- }
- },
- "uglify-to-browserify": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
- "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
- "dev": true,
- "optional": true
- },
- "uglifyjs-webpack-plugin": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz",
- "integrity": "sha512-1VicfKhCYHLS8m1DCApqBhoulnASsEoJ/BvpUpP4zoNAPpKzdH+ghk0olGJMmwX2/jprK2j3hAHdUbczBSy2FA==",
- "dev": true,
- "requires": {
- "cacache": "^10.0.4",
- "find-cache-dir": "^1.0.0",
- "schema-utils": "^0.4.5",
- "serialize-javascript": "^1.4.0",
- "source-map": "^0.6.1",
- "uglify-es": "^3.3.4",
- "webpack-sources": "^1.1.0",
- "worker-farm": "^1.5.2"
- },
- "dependencies": {
- "commander": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
- "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- },
- "uglify-es": {
- "version": "3.3.9",
- "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
- "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
- "dev": true,
- "requires": {
- "commander": "~2.13.0",
- "source-map": "~0.6.1"
- }
- }
- }
- },
- "ultron": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
- "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=",
- "dev": true
- },
- "union-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
- "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "get-value": "^2.0.6",
- "is-extendable": "^0.1.1",
- "set-value": "^0.4.3"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "set-value": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
- "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.1",
- "to-object-path": "^0.3.0"
- }
- }
- }
- },
- "unique-filename": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz",
- "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=",
- "dev": true,
- "requires": {
- "unique-slug": "^2.0.0"
- }
- },
- "unique-slug": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz",
- "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
- "dev": true,
- "requires": {
- "imurmurhash": "^0.1.4"
- }
- },
- "unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
- "dev": true
- },
- "unset-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
- "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
- "dev": true,
- "requires": {
- "has-value": "^0.3.1",
- "isobject": "^3.0.0"
- },
- "dependencies": {
- "has-value": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
- "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
- "dev": true,
- "requires": {
- "get-value": "^2.0.3",
- "has-values": "^0.1.4",
- "isobject": "^2.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "dev": true,
- "requires": {
- "isarray": "1.0.0"
- }
- }
- }
- },
- "has-values": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
- "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
- "dev": true
- }
- }
- },
- "upath": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
- "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==",
- "dev": true
- },
- "upper-case": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
- "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
- "dev": true
- },
- "uri-js": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz",
- "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=",
- "dev": true,
- "requires": {
- "punycode": "^2.1.0"
- }
- },
- "urix": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
- "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
- "dev": true
- },
- "url": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
- "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
- "dev": true,
- "requires": {
- "punycode": "1.3.2",
- "querystring": "0.2.0"
- },
- "dependencies": {
- "punycode": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
- "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
- "dev": true
- }
- }
- },
- "url-join": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz",
- "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=",
- "dev": true
- },
- "url-loader": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.0.1.tgz",
- "integrity": "sha512-rAonpHy7231fmweBKUFe0bYnlGDty77E+fm53NZdij7j/YOpyGzc7ttqG1nAXl3aRs0k41o0PC3TvGXQiw2Zvw==",
- "dev": true,
- "requires": {
- "loader-utils": "^1.1.0",
- "mime": "^2.0.3",
- "schema-utils": "^0.4.3"
- },
- "dependencies": {
- "mime": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
- "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
- "dev": true
- }
- }
- },
- "url-parse": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.1.tgz",
- "integrity": "sha512-x95Td74QcvICAA0+qERaVkRpTGKyBHHYdwL2LXZm5t/gBtCB9KQSO/0zQgSTYEV1p0WcvSg79TLNPSvd5IDJMQ==",
- "dev": true,
- "requires": {
- "querystringify": "^2.0.0",
- "requires-port": "^1.0.0"
- }
- },
- "use": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
- "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.2"
- }
- },
- "useragent": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
- "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
- "dev": true,
- "requires": {
- "lru-cache": "4.1.x",
- "tmp": "0.0.x"
- }
- },
- "util": {
- "version": "0.10.4",
- "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
- "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
- "dev": true,
- "requires": {
- "inherits": "2.0.3"
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
- "dev": true
- },
- "util.promisify": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
- "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
- "dev": true,
- "requires": {
- "define-properties": "^1.1.2",
- "object.getownpropertydescriptors": "^2.0.3"
- }
- },
- "utila": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
- "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
- "dev": true
- },
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
- "dev": true
- },
- "uuid": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
- "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
- "dev": true
- },
- "validate-npm-package-license": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
- "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==",
- "dev": true,
- "requires": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
- "validate-npm-package-name": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
- "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
- "dev": true,
- "requires": {
- "builtins": "^1.0.3"
- }
- },
- "vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
- "dev": true
- },
- "verror": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
- "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
- "dev": true,
- "requires": {
- "assert-plus": "^1.0.0",
- "core-util-is": "1.0.2",
- "extsprintf": "^1.2.0"
- }
- },
- "vm-browserify": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
- "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
- "dev": true,
- "requires": {
- "indexof": "0.0.1"
- }
- },
- "void-elements": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
- "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
- "dev": true
- },
- "watchpack": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
- "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
- "dev": true,
- "requires": {
- "chokidar": "^2.0.2",
- "graceful-fs": "^4.1.2",
- "neo-async": "^2.5.0"
- }
- },
- "wbuf": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
- "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
- "dev": true,
- "requires": {
- "minimalistic-assert": "^1.0.0"
- }
- },
- "webassemblyjs": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/webassemblyjs/-/webassemblyjs-1.4.3.tgz",
- "integrity": "sha512-4lOV1Lv6olz0PJkDGQEp82HempAn147e6BXijWDzz9g7/2nSebVP9GVg62Fz5ZAs55mxq13GA0XLyvY8XkyDjg==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/validation": "1.4.3",
- "@webassemblyjs/wasm-parser": "1.4.3",
- "@webassemblyjs/wast-parser": "1.4.3",
- "long": "^3.2.0"
- }
- },
- "webdriver-js-extender": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz",
- "integrity": "sha1-gcUzqeM9W/tZe05j4s2yW1R3dRU=",
- "dev": true,
- "requires": {
- "@types/selenium-webdriver": "^2.53.35",
- "selenium-webdriver": "^2.53.2"
- },
- "dependencies": {
- "sax": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/sax/-/sax-0.6.1.tgz",
- "integrity": "sha1-VjsZx8HeiS4Jv8Ty/DDjwn8JUrk=",
- "dev": true
- },
- "selenium-webdriver": {
- "version": "2.53.3",
- "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz",
- "integrity": "sha1-0p/1qVff8aG0ncRXdW5OS/vc4IU=",
- "dev": true,
- "requires": {
- "adm-zip": "0.4.4",
- "rimraf": "^2.2.8",
- "tmp": "0.0.24",
- "ws": "^1.0.1",
- "xml2js": "0.4.4"
- }
- },
- "tmp": {
- "version": "0.0.24",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz",
- "integrity": "sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=",
- "dev": true
- },
- "xml2js": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz",
- "integrity": "sha1-MREBAAMAiuGSQOuhdJe1fHKcVV0=",
- "dev": true,
- "requires": {
- "sax": "0.6.x",
- "xmlbuilder": ">=1.0.0"
- }
- }
- }
- },
- "webpack": {
- "version": "4.8.3",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.8.3.tgz",
- "integrity": "sha512-/hfAjBISycdK597lxONjKEFX7dSIU1PsYwC3XlXUXoykWBlv9QV5HnO+ql3HvrrgfBJ7WXdnjO9iGPR2aAc5sw==",
- "dev": true,
- "requires": {
- "@webassemblyjs/ast": "1.4.3",
- "@webassemblyjs/wasm-edit": "1.4.3",
- "@webassemblyjs/wasm-parser": "1.4.3",
- "acorn": "^5.0.0",
- "acorn-dynamic-import": "^3.0.0",
- "ajv": "^6.1.0",
- "ajv-keywords": "^3.1.0",
- "chrome-trace-event": "^0.1.1",
- "enhanced-resolve": "^4.0.0",
- "eslint-scope": "^3.7.1",
- "loader-runner": "^2.3.0",
- "loader-utils": "^1.1.0",
- "memory-fs": "~0.4.1",
- "micromatch": "^3.1.8",
- "mkdirp": "~0.5.0",
- "neo-async": "^2.5.0",
- "node-libs-browser": "^2.0.0",
- "schema-utils": "^0.4.4",
- "tapable": "^1.0.0",
- "uglifyjs-webpack-plugin": "^1.2.4",
- "watchpack": "^1.5.0",
- "webpack-sources": "^1.0.1"
- }
- },
- "webpack-core": {
- "version": "0.6.9",
- "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz",
- "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=",
- "dev": true,
- "requires": {
- "source-list-map": "~0.1.7",
- "source-map": "~0.4.1"
- },
- "dependencies": {
- "source-list-map": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz",
- "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=",
- "dev": true
- },
- "source-map": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
- "dev": true,
- "requires": {
- "amdefine": ">=0.0.4"
- }
- }
- }
- },
- "webpack-dev-middleware": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.1.3.tgz",
- "integrity": "sha512-I6Mmy/QjWU/kXwCSFGaiOoL5YEQIVmbb0o45xMoCyQAg/mClqZVTcsX327sPfekDyJWpCxb+04whNyLOIxpJdQ==",
- "dev": true,
- "requires": {
- "loud-rejection": "^1.6.0",
- "memory-fs": "~0.4.1",
- "mime": "^2.1.0",
- "path-is-absolute": "^1.0.0",
- "range-parser": "^1.0.3",
- "url-join": "^4.0.0",
- "webpack-log": "^1.0.1"
- },
- "dependencies": {
- "mime": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
- "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
- "dev": true
- }
- }
- },
- "webpack-dev-server": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.4.tgz",
- "integrity": "sha512-itcIUDFkHuj1/QQxzUFOEXXmxOj5bku2ScLEsOFPapnq2JRTm58gPdtnBphBJOKL2+M3p6+xygL64bI+3eyzzw==",
- "dev": true,
- "requires": {
- "ansi-html": "0.0.7",
- "array-includes": "^3.0.3",
- "bonjour": "^3.5.0",
- "chokidar": "^2.0.0",
- "compression": "^1.5.2",
- "connect-history-api-fallback": "^1.3.0",
- "debug": "^3.1.0",
- "del": "^3.0.0",
- "express": "^4.16.2",
- "html-entities": "^1.2.0",
- "http-proxy-middleware": "~0.18.0",
- "import-local": "^1.0.0",
- "internal-ip": "1.2.0",
- "ip": "^1.1.5",
- "killable": "^1.0.0",
- "loglevel": "^1.4.1",
- "opn": "^5.1.0",
- "portfinder": "^1.0.9",
- "selfsigned": "^1.9.1",
- "serve-index": "^1.7.2",
- "sockjs": "0.3.19",
- "sockjs-client": "1.1.4",
- "spdy": "^3.4.1",
- "strip-ansi": "^3.0.0",
- "supports-color": "^5.1.0",
- "webpack-dev-middleware": "3.1.3",
- "webpack-log": "^1.1.2",
- "yargs": "11.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true
- },
- "cliui": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
- "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
- "dev": true,
- "requires": {
- "string-width": "^2.1.1",
- "strip-ansi": "^4.0.0",
- "wrap-ansi": "^2.0.0"
- },
- "dependencies": {
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "os-locale": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
- "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
- "dev": true,
- "requires": {
- "execa": "^0.7.0",
- "lcid": "^1.0.0",
- "mem": "^1.1.0"
- }
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
- "which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
- "dev": true
- },
- "y18n": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
- "dev": true
- },
- "yargs": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz",
- "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==",
- "dev": true,
- "requires": {
- "cliui": "^4.0.0",
- "decamelize": "^1.1.1",
- "find-up": "^2.1.0",
- "get-caller-file": "^1.0.1",
- "os-locale": "^2.0.0",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^2.0.0",
- "which-module": "^2.0.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^9.0.2"
- }
- },
- "yargs-parser": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
- "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
- "dev": true,
- "requires": {
- "camelcase": "^4.1.0"
- }
- }
- }
- },
- "webpack-log": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz",
- "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==",
- "dev": true,
- "requires": {
- "chalk": "^2.1.0",
- "log-symbols": "^2.1.0",
- "loglevelnext": "^1.0.1",
- "uuid": "^3.1.0"
- }
- },
- "webpack-merge": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.3.tgz",
- "integrity": "sha512-zxwAIGK7nKdu5CIZL0BjTQoq3elV0t0MfB7rUC1zj668geid52abs6hN/ACwZdK6LeMS8dC9B6WmtF978zH5mg==",
- "dev": true,
- "requires": {
- "lodash": "^4.17.5"
- }
- },
- "webpack-sources": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz",
- "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==",
- "dev": true,
- "requires": {
- "source-list-map": "^2.0.0",
- "source-map": "~0.6.1"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
- }
- },
- "webpack-subresource-integrity": {
- "version": "1.1.0-rc.4",
- "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.4.tgz",
- "integrity": "sha1-xcTj1pD50vZKlVDgeodn+Xlqpdg=",
- "dev": true,
- "requires": {
- "webpack-core": "^0.6.8"
- }
- },
- "websocket-driver": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
- "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
- "requires": {
- "http-parser-js": ">=0.4.0",
- "websocket-extensions": ">=0.1.1"
- }
- },
- "websocket-extensions": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
- "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg=="
- },
- "whatwg-fetch": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
- "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
- },
- "when": {
- "version": "3.6.4",
- "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz",
- "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=",
- "dev": true
- },
- "which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
- },
- "which-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
- "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
- "dev": true,
- "optional": true
- },
- "wide-align": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
- "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
- "dev": true,
- "requires": {
- "string-width": "^1.0.2 || 2"
- }
- },
- "window-size": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
- "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
- },
- "wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
- "dev": true
- },
- "worker-farm": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
- "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==",
- "dev": true,
- "requires": {
- "errno": "~0.1.7"
- }
- },
- "wrap-ansi": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
- "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
- "dev": true,
- "requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1"
- }
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
- },
- "ws": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz",
- "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=",
- "dev": true,
- "requires": {
- "options": ">=0.0.5",
- "ultron": "1.0.x"
- }
- },
- "wtf-8": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz",
- "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=",
- "dev": true
- },
- "xml2js": {
- "version": "0.4.19",
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
- "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
- "dev": true,
- "requires": {
- "sax": ">=0.6.0",
- "xmlbuilder": "~9.0.1"
- },
- "dependencies": {
- "sax": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
- "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
- "dev": true
- }
- }
- },
- "xmlbuilder": {
- "version": "9.0.7",
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
- "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
- "dev": true
- },
- "xmlhttprequest": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
- "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw="
- },
- "xmlhttprequest-ssl": {
- "version": "1.5.3",
- "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
- "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=",
- "dev": true
- },
- "xtend": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
- "dev": true
- },
- "xxhashjs": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz",
- "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==",
- "dev": true,
- "requires": {
- "cuint": "^0.2.2"
- }
- },
- "y18n": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
- "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
- "dev": true
- },
- "yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
- "dev": true
- },
- "yargs": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
- "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
- "requires": {
- "camelcase": "^1.0.2",
- "cliui": "^2.1.0",
- "decamelize": "^1.0.0",
- "window-size": "0.1.0"
- }
- },
- "yargs-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
- "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
- "dev": true,
- "optional": true,
- "requires": {
- "camelcase": "^3.0.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
- "dev": true,
- "optional": true
- }
- }
- },
- "yeast": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
- "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
- "dev": true
- },
- "yn": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
- "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
- "dev": true
- },
- "zone.js": {
- "version": "0.8.26",
- "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.26.tgz",
- "integrity": "sha512-W9Nj+UmBJG251wkCacIkETgra4QgBo/vgoEkb4a2uoLzpQG7qF9nzwoLXWU5xj3Fg2mxGvEDh47mg24vXccYjA=="
- }
- }
-}
diff --git a/web/cloud_dashboard/package.json b/web/cloud_dashboard/package.json
deleted file mode 100644
index 50f67a6..0000000
--- a/web/cloud_dashboard/package.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
- "name": "cloud_dashboard",
- "version": "0.0.0",
- "scripts": {
- "ng": "ng",
- "start": "ng serve",
- "build": "ng build",
- "test": "ng test",
- "lint": "ng lint"
- },
- "private": true,
- "dependencies": {
- "@angular/animations": "^6.0.3",
- "@angular/cdk": "^6.3.2",
- "@angular/common": "^6.0.3",
- "@angular/compiler": "^6.0.3",
- "@angular/core": "^6.0.3",
- "@angular/forms": "^6.0.3",
- "@angular/http": "^6.0.3",
- "@angular/material": "^6.3.2",
- "@angular/platform-browser": "^6.0.3",
- "@angular/platform-browser-dynamic": "^6.0.3",
- "@angular/router": "^6.0.3",
- "angularfire2": "^5.0.0-rc.11",
- "core-js": "^2.5.4",
- "firebase": "^5.2.0",
- "rxjs": "^6.0.0",
- "zone.js": "^0.8.26"
- },
- "devDependencies": {
- "@angular/compiler-cli": "^6.0.3",
- "@angular-devkit/build-angular": "~0.6.8",
- "typescript": "~2.7.2",
- "@angular/cli": "~6.0.8",
- "@angular/language-service": "^6.0.3",
- "@types/jasmine": "~2.8.6",
- "@types/jasminewd2": "~2.0.3",
- "@types/node": "~8.9.4",
- "codelyzer": "~4.2.1",
- "jasmine-core": "~2.99.1",
- "jasmine-spec-reporter": "~4.2.1",
- "karma": "~1.7.1",
- "karma-chrome-launcher": "~2.2.0",
- "karma-coverage-istanbul-reporter": "~2.0.0",
- "karma-jasmine": "~1.1.1",
- "karma-jasmine-html-reporter": "^0.2.2",
- "protractor": "~5.3.0",
- "ts-node": "~5.0.1",
- "tslint": "~5.9.1"
- }
-}
diff --git a/web/cloud_dashboard/src/app/app.component.css b/web/cloud_dashboard/src/app/app.component.css
deleted file mode 100644
index e69de29..0000000
--- a/web/cloud_dashboard/src/app/app.component.css
+++ /dev/null
diff --git a/web/cloud_dashboard/src/app/app.component.html b/web/cloud_dashboard/src/app/app.component.html
deleted file mode 100644
index a4cf904..0000000
--- a/web/cloud_dashboard/src/app/app.component.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<mat-toolbar color="primary">
- <span>Ledger Cloud Dashboard</span>
-</mat-toolbar>
-<div class="lcd-container">
- <div *ngIf="!authenticated">
- <mat-card class="lcd-card">
- <mat-card-content>
- <h1>Authentication required</h1>
- <p>Please authenticate in order to use the dashboard.</p>
- </mat-card-content>
- <mat-card-actions>
- <button mat-raised-button color="accent" (click)="login()">Login</button>
- </mat-card-actions>
- </mat-card>
- </div>
-
- <div *ngIf="deleteInProgress">
- <mat-card class="lcd-card">
- <mat-card-content>
- <h1>Delete in progress</h1>
- <p>Please don't close the tab!!!</p>
- <mat-progress-spinner mode="indeterminate"></mat-progress-spinner>
- <p>Deleted documents: <b>{{ deletedDocumentCount }} </b></p>
- </mat-card-content>
- </mat-card>
- </div>
-
- <div *ngIf="authenticated && !deleteInProgress">
- <!-- Info about the user -->
- <mat-card class="lcd-card">
- <mat-card-content>
- <h1>User</h1>
- <p>You are signed in as <b>{{ (user | async)?.email }}</b>
- a.k.a <b>{{ uid }}</b> (Firebase user ID).</p>
- </mat-card-content>
- <mat-card-actions>
- <button mat-raised-button color="accent" (click)="logout()">Logout</button>
- </mat-card-actions>
- </mat-card>
-
- <!-- State -->
- <mat-card class="lcd-card">
- <mat-card-content>
- <h1>State</h1>
- <div *ngIf="loading">
- <p>Loading the state.</p>
- </div>
- <div *ngIf="!loading && !version">
- <p>Ledger is empty.</p>
- </div>
- <div *ngIf="!loading && version">
- <p>Looking at serialization version <b>{{ version }}</b>.</p>
- <p>There are <b>{{ (devices | async)?.length }}</b> devices syncing.</p>
- <ul>
- <li class="text" *ngFor="let device of devices | async">
- {{device.id}}
- <span *ngIf="device.connectionTimestamp">
- -- Last connection at
- {{device.connectionTimestamp | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>
- </li>
- </ul>
- <p>Device IDs are opaque and meaningful only to Ledger.</p>
- </div>
- </mat-card-content>
- </mat-card>
-
- <!-- Cloud delete -->
- <mat-card class="lcd-card">
- <mat-card-content>
- <h1>Reset Ledger state</h1>
- <p><i>Why do we even have this lever?</i></p>
- <p><b>This will also trigger erase of the local data, the next time each of
- the devices sync</b></p>
- <p>Collections to be erased:</p>
- <ul *ngFor="let collection of allCollections">
- <li>{{ collection.ref.path }}</li>
- </ul>
- </mat-card-content>
- <mat-card-actions>
- <button mat-raised-button color="warn" (click)="erase()">Permanently erase all my data</button>
- </mat-card-actions>
- </mat-card>
- </div>
-</div>
diff --git a/web/cloud_dashboard/src/app/app.component.spec.ts b/web/cloud_dashboard/src/app/app.component.spec.ts
deleted file mode 100644
index 19b4416..0000000
--- a/web/cloud_dashboard/src/app/app.component.spec.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import {async, TestBed} from '@angular/core/testing';
-
-import {AppComponent} from './app.component';
-
-describe('AppComponent', () => {
- beforeEach(async(() => {
- TestBed
- .configureTestingModule({
- declarations: [AppComponent],
- })
- .compileComponents();
- }));
- it('should create the app', async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- const app = fixture.debugElement.componentInstance;
- expect(app).toBeTruthy();
- }));
- it(`should have as title 'app'`, async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- const app = fixture.debugElement.componentInstance;
- expect(app.title).toEqual('app');
- }));
- it('should render title in a h1 tag', async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- fixture.detectChanges();
- const compiled = fixture.debugElement.nativeElement;
- expect(compiled.querySelector('h1').textContent)
- .toContain('Welcome to cloud_dashboard!');
- }));
-});
diff --git a/web/cloud_dashboard/src/app/app.component.ts b/web/cloud_dashboard/src/app/app.component.ts
deleted file mode 100644
index f152404..0000000
--- a/web/cloud_dashboard/src/app/app.component.ts
+++ /dev/null
@@ -1,191 +0,0 @@
-import {Component} from '@angular/core';
-import {AngularFireAuth} from 'angularfire2/auth';
-import {AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument, DocumentChangeAction, QueryDocumentSnapshot} from 'angularfire2/firestore';
-import * as firebase from 'firebase/app';
-import {from, Observable, Observer} from 'rxjs';
-import {bufferCount, concat, concatMap, map, mergeMap, take, tap, toArray} from 'rxjs/operators';
-
-@Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
-})
-export class AppComponent {
- readonly title = 'Ledger Cloud Dashboard';
- readonly batchSize = 25;
-
- authenticated = false;
- uid = null;
- version = '0';
- loading = true;
- deleteInProgress = false;
-
- user: Observable<firebase.User>;
- usersCollection: AngularFirestoreCollection;
- userDocument: AngularFirestoreDocument<any>;
- versionsCollection: AngularFirestoreCollection;
- versionDocument: AngularFirestoreDocument<any>;
- devicesCollection: AngularFirestoreCollection;
- devices: Observable<any>;
- allCollections: Array<AngularFirestoreCollection> = [];
- deletedDocumentCount = 0;
-
- constructor(public afAuth: AngularFireAuth, private db: AngularFirestore) {
- this.user = afAuth.authState;
-
- this.afAuth.authState.subscribe((state) => {
- this.authenticated = state != null;
- if (this.authenticated) {
- this.uid = state.uid;
- this.loadVersions();
- }
- });
- }
-
- login() {
- let provider = new firebase.auth.GoogleAuthProvider();
- provider.setCustomParameters({prompt: 'select_account'});
- this.afAuth.auth.signInWithPopup(provider);
- }
-
- logout() {
- this.afAuth.auth.signOut();
- }
-
- rootPath() {
- return 'users/' + this.uid;
- }
-
- versionDocumentPath(version: number) {
- let path = `${this.rootPath()}/${version}/default_document`;
- console.log(path);
- return path;
- }
-
- versionPath() {
- return this.rootPath() + '/' + this.version;
- }
-
- userDevicesPath() {
- return this.versionPath() + '/default_document/devices';
- }
-
- loadVersions() {
- this.usersCollection = this.db.collection('users');
- this.userDocument = this.usersCollection.doc(this.uid);
- this.versionsCollection = this.userDocument.collection('versions');
- this.versionsCollection.snapshotChanges()
- .pipe(this.unwrap())
- .subscribe(versionObjects => {
- let nextVersion = '0';
- for (const versionObject of versionObjects) {
- if (Number(versionObject.id) > Number(nextVersion)) {
- nextVersion = versionObject.id;
- }
- }
- this.version = nextVersion;
- this.versionDocument = this.versionsCollection.doc(this.version);
- this.loading = false;
- this.loadDevices();
- this.loadAllCollections();
- });
- }
-
- loadDevices() {
- this.devicesCollection = this.versionDocument.collection('devices');
- this.devices = this.devicesCollection.snapshotChanges().pipe(
- map(actions => actions.map(a => {
- const data = a.payload.doc.data();
- const id = a.payload.doc.id;
- return {id, ...data};
- })));
- }
-
- // Assembles the list of all collections of the user.
- loadAllCollections() {
- const schema = {
- 'devices': {},
- 'namespaces': {'pages': {'commit-log': {}, 'objects': {}}}
- };
- this.loadNested(this.versionsCollection, schema)
- .pipe(toArray())
- .subscribe((result) => this.allCollections = result);
- }
-
- // Returns an observable which recursively streams nested collections under
- // |collection| according to the given schema.
- loadNested(collection: AngularFirestoreCollection, schema):
- Observable<AngularFirestoreCollection> {
- return collection.snapshotChanges().pipe(
- this.unwrap(), take(1),
-
- mergeMap(documents => {
- let result = [from([collection])];
- for (const document of documents) {
- for (const subcollectionName in schema) {
- const subcollection =
- collection.doc(document.id).collection(subcollectionName);
- const subcollectionObservable =
- this.loadNested(subcollection, schema[subcollectionName]);
- result.push(subcollectionObservable);
- }
- }
- return result;
- }),
- mergeMap((a) => a));
- }
-
- // Pipeable operator which unwraps document snapshots so that they contain the
- // key as |id| along with data fields.
- unwrap() {
- return map((actions: DocumentChangeAction<any>[]) => actions.map(a => {
- const data = a.payload.doc.data();
- const id = a.payload.doc.id;
- return {id, ...data};
- }))
- }
-
- erase() {
- this.deleteInProgress = true;
- this.deletedDocumentCount = 0;
- this.eraseCollections(this.allCollections);
- }
-
- // Erases all documents in the given collection in batches.
- eraseCollections(collections: Array<AngularFirestoreCollection>) {
- from(collections)
- .pipe(
- concatMap(
- collection => collection.snapshotChanges().pipe(
- take(1), concatMap((v) => v))),
- bufferCount(this.batchSize),
- concatMap((documents) => this.deleteDocs(documents)))
- .subscribe(
- (count: number) => {
- this.deletedDocumentCount += count;
- },
- (err) => {
- console.log(err);
- },
- () => {
- this.deleteInProgress = false;
- this.loadVersions();
- });
- }
-
- // Returns an Observable which deletes the given documents and streams the
- // number of deleted documents.
- deleteDocs(documents: DocumentChangeAction<any>[]): Observable<number> {
- let result = Observable.create((o: Observer<number>) => {
- let batch = this.db.firestore.batch();
- for (const document in documents) {
- batch.delete(documents[document].payload.doc.ref);
- }
- batch.commit().then(() => {
- o.next(documents.length);
- o.complete();
- });
- });
- return result;
- }
-}
diff --git a/web/cloud_dashboard/src/app/app.module.ts b/web/cloud_dashboard/src/app/app.module.ts
deleted file mode 100644
index a870ec2..0000000
--- a/web/cloud_dashboard/src/app/app.module.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import {NgModule} from '@angular/core';
-import {MatButtonModule, MatCardModule, MatProgressSpinnerModule, MatToolbarModule} from '@angular/material';
-import {BrowserModule} from '@angular/platform-browser';
-import {AngularFireModule} from 'angularfire2';
-import {AngularFireAuthModule} from 'angularfire2/auth';
-import {AngularFirestoreModule} from 'angularfire2/firestore';
-
-import {environment} from '../environments/environment';
-
-import {AppComponent} from './app.component';
-
-@NgModule({
- declarations: [AppComponent],
- imports: [
- BrowserModule, //
- AngularFireModule.initializeApp(environment.firebase), //
- AngularFirestoreModule, //
- AngularFireAuthModule, //
- MatButtonModule, //
- MatCardModule, //
- MatProgressSpinnerModule, //
- MatToolbarModule //
- ],
- providers: [],
- bootstrap: [AppComponent]
-})
-export class AppModule {
-}
diff --git a/web/cloud_dashboard/src/assets/.gitkeep b/web/cloud_dashboard/src/assets/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/web/cloud_dashboard/src/assets/.gitkeep
+++ /dev/null
diff --git a/web/cloud_dashboard/src/browserslist b/web/cloud_dashboard/src/browserslist
deleted file mode 100644
index 8e09ab4..0000000
--- a/web/cloud_dashboard/src/browserslist
+++ /dev/null
@@ -1,9 +0,0 @@
-# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
-# For additional information regarding the format and rule options, please see:
-# https://github.com/browserslist/browserslist#queries
-# For IE 9-11 support, please uncomment the last line of the file and adjust as needed
-> 0.5%
-last 2 versions
-Firefox ESR
-not dead
-# IE 9-11
\ No newline at end of file
diff --git a/web/cloud_dashboard/src/environments/environment.prod.ts b/web/cloud_dashboard/src/environments/environment.prod.ts
deleted file mode 100644
index c840f72..0000000
--- a/web/cloud_dashboard/src/environments/environment.prod.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {firebase} from './firebase';
-
-export const environment = {
- production: true,
- firebase: firebase
-};
diff --git a/web/cloud_dashboard/src/environments/environment.ts b/web/cloud_dashboard/src/environments/environment.ts
deleted file mode 100644
index a66860e..0000000
--- a/web/cloud_dashboard/src/environments/environment.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// This file can be replaced during build by using the `fileReplacements` array.
-// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
-// The list of file replacements can be found in `angular.json`.
-
-import {firebase} from './firebase';
-
-export const environment = {
- production: false,
- firebase: firebase
-};
diff --git a/web/cloud_dashboard/src/environments/firebase.ts b/web/cloud_dashboard/src/environments/firebase.ts
deleted file mode 100644
index bf5ff62..0000000
--- a/web/cloud_dashboard/src/environments/firebase.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export const firebase = {
- apiKey: 'AIzaSyDzzuJILOn6riFPTXC36HlH6CEdliLapDA',
- authDomain: 'fuchsia-ledger.firebaseapp.com',
- databaseURL: 'https://fuchsia-ledger.firebaseio.com',
- projectId: 'fuchsia-ledger',
- storageBucket: 'fuchsia-ledger.appspot.com',
- messagingSenderId: '191622714118'
-};
diff --git a/web/cloud_dashboard/src/favicon.ico b/web/cloud_dashboard/src/favicon.ico
deleted file mode 100644
index 8081c7c..0000000
--- a/web/cloud_dashboard/src/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/web/cloud_dashboard/src/index.html b/web/cloud_dashboard/src/index.html
deleted file mode 100644
index b70f171..0000000
--- a/web/cloud_dashboard/src/index.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>CloudDashboard</title>
- <base href="/">
-
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="icon" type="image/x-icon" href="favicon.ico">
- <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
-</head>
-<body>
- <app-root></app-root>
-</body>
-</html>
diff --git a/web/cloud_dashboard/src/karma.conf.js b/web/cloud_dashboard/src/karma.conf.js
deleted file mode 100644
index b6e0042..0000000
--- a/web/cloud_dashboard/src/karma.conf.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Karma configuration file, see link for more information
-// https://karma-runner.github.io/1.0/config/configuration-file.html
-
-module.exports = function (config) {
- config.set({
- basePath: '',
- frameworks: ['jasmine', '@angular-devkit/build-angular'],
- plugins: [
- require('karma-jasmine'),
- require('karma-chrome-launcher'),
- require('karma-jasmine-html-reporter'),
- require('karma-coverage-istanbul-reporter'),
- require('@angular-devkit/build-angular/plugins/karma')
- ],
- client: {
- clearContext: false // leave Jasmine Spec Runner output visible in browser
- },
- coverageIstanbulReporter: {
- dir: require('path').join(__dirname, '../coverage'),
- reports: ['html', 'lcovonly'],
- fixWebpackSourcePaths: true
- },
- reporters: ['progress', 'kjhtml'],
- port: 9876,
- colors: true,
- logLevel: config.LOG_INFO,
- autoWatch: true,
- browsers: ['Chrome'],
- singleRun: false
- });
-};
\ No newline at end of file
diff --git a/web/cloud_dashboard/src/main.ts b/web/cloud_dashboard/src/main.ts
deleted file mode 100644
index b4badaa..0000000
--- a/web/cloud_dashboard/src/main.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import {enableProdMode} from '@angular/core';
-import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
-
-import {AppModule} from './app/app.module';
-import {environment} from './environments/environment';
-
-if (environment.production) {
- enableProdMode();
-}
-
-platformBrowserDynamic().bootstrapModule(AppModule).catch(
- err => console.log(err));
diff --git a/web/cloud_dashboard/src/polyfills.ts b/web/cloud_dashboard/src/polyfills.ts
deleted file mode 100644
index 663fa6d..0000000
--- a/web/cloud_dashboard/src/polyfills.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * This file includes polyfills needed by Angular and is loaded before the app.
- * You can add your own extra polyfills to this file.
- *
- * This file is divided into 2 sections:
- * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
- * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
- * file.
- *
- * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
- * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
- * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
- *
- * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
- */
-
-/***************************************************************************************************
- * BROWSER POLYFILLS
- */
-
-/** IE9, IE10 and IE11 requires all of the following polyfills. **/
-// import 'core-js/es6/symbol';
-// import 'core-js/es6/object';
-// import 'core-js/es6/function';
-// import 'core-js/es6/parse-int';
-// import 'core-js/es6/parse-float';
-// import 'core-js/es6/number';
-// import 'core-js/es6/math';
-// import 'core-js/es6/string';
-// import 'core-js/es6/date';
-// import 'core-js/es6/array';
-// import 'core-js/es6/regexp';
-// import 'core-js/es6/map';
-// import 'core-js/es6/weak-map';
-// import 'core-js/es6/set';
-
-/** IE10 and IE11 requires the following for NgClass support on SVG elements */
-// import 'classlist.js'; // Run `npm install --save classlist.js`.
-
-/** IE10 and IE11 requires the following for the Reflect API. */
-// import 'core-js/es6/reflect';
-
-
-/** Evergreen browsers require these. **/
-// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
-import 'core-js/es7/reflect';
-
-
-/**
- * Web Animations `@angular/platform-browser/animations`
- * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
- * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
- **/
-// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
-
-/**
- * By default, zone.js will patch all possible macroTask and DomEvents
- * user can disable parts of macroTask/DomEvents patch by setting following flags
- */
-
-// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
-// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
-// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
-
-/*
- * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
- * with the following flag, it will bypass `zone.js` patch for IE/Edge
- */
-// (window as any).__Zone_enable_cross_context_check = true;
-
-/***************************************************************************************************
- * Zone JS is required by default for Angular itself.
- */
-import 'zone.js/dist/zone'; // Included with Angular CLI.
-
-
-
-/***************************************************************************************************
- * APPLICATION IMPORTS
- */
diff --git a/web/cloud_dashboard/src/styles.css b/web/cloud_dashboard/src/styles.css
deleted file mode 100644
index f927449..0000000
--- a/web/cloud_dashboard/src/styles.css
+++ /dev/null
@@ -1,16 +0,0 @@
-/* You can add global styles to this file, and also import other style files */
-
-@import '~@angular/material/prebuilt-themes/indigo-pink.css';
-
-body {
- margin: 0;
-}
-
-.lcd-container {
- max-width: 1280px;
- margin: 0 auto;
-}
-
-.lcd-card {
- margin: 10px;
-}
diff --git a/web/cloud_dashboard/src/test.ts b/web/cloud_dashboard/src/test.ts
deleted file mode 100644
index ef0aef5..0000000
--- a/web/cloud_dashboard/src/test.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-// This file is required by karma.conf.js and loads recursively all the .spec and framework files
-
-import 'zone.js/dist/zone-testing';
-import {getTestBed} from '@angular/core/testing';
-import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
-
-declare const require: any;
-
-// First, initialize the Angular testing environment.
-getTestBed().initTestEnvironment(
- BrowserDynamicTestingModule, platformBrowserDynamicTesting());
-// Then we find all the tests.
-const context = require.context('./', true, /\.spec\.ts$/);
-// And load the modules.
-context.keys().map(context);
diff --git a/web/cloud_dashboard/src/tsconfig.app.json b/web/cloud_dashboard/src/tsconfig.app.json
deleted file mode 100644
index 722c370..0000000
--- a/web/cloud_dashboard/src/tsconfig.app.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "outDir": "../out-tsc/app",
- "module": "es2015",
- "types": []
- },
- "exclude": [
- "src/test.ts",
- "**/*.spec.ts"
- ]
-}
diff --git a/web/cloud_dashboard/src/tsconfig.spec.json b/web/cloud_dashboard/src/tsconfig.spec.json
deleted file mode 100644
index 8f7cede..0000000
--- a/web/cloud_dashboard/src/tsconfig.spec.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "outDir": "../out-tsc/spec",
- "module": "commonjs",
- "types": [
- "jasmine",
- "node"
- ]
- },
- "files": [
- "test.ts",
- "polyfills.ts"
- ],
- "include": [
- "**/*.spec.ts",
- "**/*.d.ts"
- ]
-}
diff --git a/web/cloud_dashboard/src/tslint.json b/web/cloud_dashboard/src/tslint.json
deleted file mode 100644
index 52e2c1a..0000000
--- a/web/cloud_dashboard/src/tslint.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "extends": "../tslint.json",
- "rules": {
- "directive-selector": [
- true,
- "attribute",
- "app",
- "camelCase"
- ],
- "component-selector": [
- true,
- "element",
- "app",
- "kebab-case"
- ]
- }
-}
diff --git a/web/cloud_dashboard/tsconfig.json b/web/cloud_dashboard/tsconfig.json
deleted file mode 100644
index ef44e28..0000000
--- a/web/cloud_dashboard/tsconfig.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "compileOnSave": false,
- "compilerOptions": {
- "baseUrl": "./",
- "outDir": "./dist/out-tsc",
- "sourceMap": true,
- "declaration": false,
- "moduleResolution": "node",
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "target": "es5",
- "typeRoots": [
- "node_modules/@types"
- ],
- "lib": [
- "es2017",
- "dom"
- ]
- }
-}
diff --git a/web/cloud_dashboard/tslint.json b/web/cloud_dashboard/tslint.json
deleted file mode 100644
index 3ea984c..0000000
--- a/web/cloud_dashboard/tslint.json
+++ /dev/null
@@ -1,130 +0,0 @@
-{
- "rulesDirectory": [
- "node_modules/codelyzer"
- ],
- "rules": {
- "arrow-return-shorthand": true,
- "callable-types": true,
- "class-name": true,
- "comment-format": [
- true,
- "check-space"
- ],
- "curly": true,
- "deprecation": {
- "severity": "warn"
- },
- "eofline": true,
- "forin": true,
- "import-blacklist": [
- true,
- "rxjs/Rx"
- ],
- "import-spacing": true,
- "indent": [
- true,
- "spaces"
- ],
- "interface-over-type-literal": true,
- "label-position": true,
- "max-line-length": [
- true,
- 140
- ],
- "member-access": false,
- "member-ordering": [
- true,
- {
- "order": [
- "static-field",
- "instance-field",
- "static-method",
- "instance-method"
- ]
- }
- ],
- "no-arg": true,
- "no-bitwise": true,
- "no-console": [
- true,
- "debug",
- "info",
- "time",
- "timeEnd",
- "trace"
- ],
- "no-construct": true,
- "no-debugger": true,
- "no-duplicate-super": true,
- "no-empty": false,
- "no-empty-interface": true,
- "no-eval": true,
- "no-inferrable-types": [
- true,
- "ignore-params"
- ],
- "no-misused-new": true,
- "no-non-null-assertion": true,
- "no-shadowed-variable": true,
- "no-string-literal": false,
- "no-string-throw": true,
- "no-switch-case-fall-through": true,
- "no-trailing-whitespace": true,
- "no-unnecessary-initializer": true,
- "no-unused-expression": true,
- "no-use-before-declare": true,
- "no-var-keyword": true,
- "object-literal-sort-keys": false,
- "one-line": [
- true,
- "check-open-brace",
- "check-catch",
- "check-else",
- "check-whitespace"
- ],
- "prefer-const": true,
- "quotemark": [
- true,
- "single"
- ],
- "radix": true,
- "semicolon": [
- true,
- "always"
- ],
- "triple-equals": [
- true,
- "allow-null-check"
- ],
- "typedef-whitespace": [
- true,
- {
- "call-signature": "nospace",
- "index-signature": "nospace",
- "parameter": "nospace",
- "property-declaration": "nospace",
- "variable-declaration": "nospace"
- }
- ],
- "unified-signatures": true,
- "variable-name": false,
- "whitespace": [
- true,
- "check-branch",
- "check-decl",
- "check-operator",
- "check-separator",
- "check-type"
- ],
- "no-output-on-prefix": true,
- "use-input-property-decorator": true,
- "use-output-property-decorator": true,
- "use-host-property-decorator": true,
- "no-input-rename": true,
- "no-output-rename": true,
- "use-life-cycle-interface": true,
- "use-pipe-transform-interface": true,
- "component-class-suffix": true,
- "directive-class-suffix": true
- }
-}