TensorFlow Serving C++ API Documentation
aspired_versions_manager_builder_test.cc
1 /* Copyright 2016 Google Inc. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7  http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #include "tensorflow_serving/core/aspired_versions_manager_builder.h"
17 
18 #include <functional>
19 #include <memory>
20 #include <utility>
21 #include <vector>
22 
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include "tensorflow/core/lib/strings/strcat.h"
26 #include "tensorflow_serving/core/availability_preserving_policy.h"
27 #include "tensorflow_serving/core/servable_data.h"
28 #include "tensorflow_serving/core/servable_handle.h"
29 #include "tensorflow_serving/core/servable_state_monitor.h"
30 #include "tensorflow_serving/core/simple_loader.h"
31 #include "tensorflow_serving/core/storage_path.h"
32 #include "tensorflow_serving/core/test_util/availability_test_util.h"
33 #include "tensorflow_serving/core/test_util/fake_loader_source_adapter.h"
34 #include "tensorflow_serving/core/test_util/fake_storage_path_source_adapter.h"
35 #include "tensorflow_serving/util/event_bus.h"
36 
37 namespace tensorflow {
38 namespace serving {
39 namespace {
40 
41 using ::testing::ElementsAre;
42 using test_util::FakeLoaderSourceAdapter;
43 using test_util::FakeStoragePathSourceAdapter;
44 using test_util::WaitUntilServableManagerStateIsOneOf;
45 
46 class AspiredVersionsManagerBuilderTest : public ::testing::Test {
47  protected:
48  AspiredVersionsManagerBuilderTest()
49  : servable_event_bus_(EventBus<ServableState>::CreateEventBus()),
50  servable_state_monitor_(servable_event_bus_.get()) {
51  AspiredVersionsManagerBuilder::Options manager_options;
52  manager_options.servable_event_bus = servable_event_bus_.get();
53  manager_options.aspired_version_policy.reset(
54  new AvailabilityPreservingPolicy());
55  TF_CHECK_OK(AspiredVersionsManagerBuilder::Create(
56  std::move(manager_options), &builder_));
57  }
58 
59  std::unique_ptr<AspiredVersionsManagerBuilder> builder_;
60  std::shared_ptr<EventBus<ServableState>> servable_event_bus_;
61  ServableStateMonitor servable_state_monitor_;
62 };
63 
64 TEST_F(AspiredVersionsManagerBuilderTest, AddSourceConnection) {
65  auto* const adapter = new FakeLoaderSourceAdapter("adapter");
66  builder_->AddSource(std::unique_ptr<FakeLoaderSourceAdapter>(adapter));
67  std::unique_ptr<Manager> manager = builder_->Build();
68 
69  const ServableId id = {"servable", 1};
70  adapter->SetAspiredVersions(
71  id.name, {CreateServableData(id, StoragePath("/storage/path"))});
72  WaitUntilServableManagerStateIsOneOf(
73  servable_state_monitor_, id, {ServableState::ManagerState::kAvailable});
74 }
75 
76 TEST_F(AspiredVersionsManagerBuilderTest, AddSourceChainConnection) {
77  auto* const adapter0 = new FakeStoragePathSourceAdapter("adapter0");
78  auto adapter1 = std::unique_ptr<FakeStoragePathSourceAdapter>(
79  new FakeStoragePathSourceAdapter("adapter1"));
80  auto adapter2 = std::unique_ptr<FakeLoaderSourceAdapter>(
81  new FakeLoaderSourceAdapter("adapter2"));
82  builder_->AddSourceChain(
83  std::unique_ptr<FakeStoragePathSourceAdapter>(adapter0),
84  std::move(adapter1), std::move(adapter2));
85  std::unique_ptr<Manager> manager = builder_->Build();
86 
87  const ServableId id = {"servable", 1};
88  adapter0->SetAspiredVersions(
89  id.name, {CreateServableData(id, StoragePath("/storage/path"))});
90  WaitUntilServableManagerStateIsOneOf(
91  servable_state_monitor_, id, {ServableState::ManagerState::kAvailable});
92 
93  ServableHandle<StoragePath> handle;
94  const Status status =
95  manager->GetServableHandle(ServableRequest::FromId(id), &handle);
96  EXPECT_EQ(StoragePath("/storage/path/adapter0/adapter1/adapter2"), *handle);
97 }
98 
99 TEST_F(AspiredVersionsManagerBuilderTest, AddSourceChainDestructionOrder) {
100  // The destructor of each adapter pushes its own name into this vector, and we
101  // use it to verify the destruction order.
102  std::vector<string> destruct_order;
103  std::function<void(const string&)> call_on_destruct =
104  [&](const string& suffix) { destruct_order.push_back(suffix); };
105  auto* const adapter0 =
106  new FakeStoragePathSourceAdapter("adapter0", call_on_destruct);
107  auto adapter1 = std::unique_ptr<FakeStoragePathSourceAdapter>(
108  new FakeStoragePathSourceAdapter("adapter1", call_on_destruct));
109  auto adapter2 = std::unique_ptr<FakeLoaderSourceAdapter>(
110  new FakeLoaderSourceAdapter("adapter2", call_on_destruct));
111  builder_->AddSourceChain(
112  std::unique_ptr<FakeStoragePathSourceAdapter>(adapter0),
113  std::move(adapter1), std::move(adapter2));
114  std::unique_ptr<Manager> manager = builder_->Build();
115 
116  manager.reset();
117  EXPECT_THAT(destruct_order, ElementsAre("adapter0", "adapter1", "adapter2"));
118 }
119 
120 } // namespace
121 } // namespace serving
122 } // namespace tensorflow