1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <string>
17
18 #include "ClientConfig.pb.h"
19 #include "LocalPrebuiltGraph.h"
20 #include "PrebuiltEngineInterface.h"
21 #include "PrebuiltEngineInterfaceImpl.h"
22 #include "ProfilingType.pb.h"
23 #include "RunnerComponent.h"
24 #include "gmock/gmock-matchers.h"
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
27 #include "types/Status.h"
28
29 using ::android::automotive::computepipe::runner::ClientConfig;
30 using ::android::automotive::computepipe::runner::RunnerComponentInterface;
31 using ::android::automotive::computepipe::runner::RunnerEvent;
32 using ::testing::HasSubstr;
33
34 namespace android {
35 namespace automotive {
36 namespace computepipe {
37 namespace graph {
38 namespace {
39
40 // The stub graph implementation is a passthrough implementation that does not run
41 // any graph and returns success for all implementations. The only useful things that
42 // it does for the tests are
43 //
44 // 1. Stores the name of the function last visited and returns that with GetErrorMessage call
45 // 2. When an input stream is set, it immediately returns an output callback with the same input
46 // data and timestamp. Similar callback is issued for when input stream pixel data is set too
47 //
48 // The above two properties are used to test that the prebuilt graph wrapper calls the correct
49 // functions and callbacks are issued as expected. These tests do not test the internals of the
50 // graph themselves and such tests must be written along with the graph implementation.
TEST(LocalPrebuiltGraphTest,FunctionMappingFromLibraryIsSuccessful)51 TEST(LocalPrebuiltGraphTest, FunctionMappingFromLibraryIsSuccessful) {
52 PrebuiltEngineInterfaceImpl callback;
53 std::shared_ptr<PrebuiltEngineInterface> engineInterface =
54 std::static_pointer_cast<PrebuiltEngineInterface, PrebuiltEngineInterfaceImpl>(
55 std::make_shared<PrebuiltEngineInterfaceImpl>(callback));
56 PrebuiltGraph* graph = GetLocalGraphFromLibrary("libstubgraphimpl.so", engineInterface);
57 ASSERT_TRUE(graph);
58 EXPECT_EQ(graph->GetGraphType(), PrebuiltGraphType::LOCAL);
59 EXPECT_NE(graph->GetGraphState(), PrebuiltGraphState::UNINITIALIZED);
60 EXPECT_EQ(graph->GetSupportedGraphConfigs().graph_name(), "stub_graph");
61 }
62
TEST(LocalPrebuiltGraphTest,GraphConfigurationIssuesCorrectFunctionCalls)63 TEST(LocalPrebuiltGraphTest, GraphConfigurationIssuesCorrectFunctionCalls) {
64 PrebuiltEngineInterfaceImpl callback;
65 std::shared_ptr<PrebuiltEngineInterface> engineInterface =
66 std::static_pointer_cast<PrebuiltEngineInterface, PrebuiltEngineInterfaceImpl>(
67 std::make_shared<PrebuiltEngineInterfaceImpl>(callback));
68 PrebuiltGraph* graph = GetLocalGraphFromLibrary("libstubgraphimpl.so", engineInterface);
69 ASSERT_TRUE(graph);
70 EXPECT_EQ(graph->GetGraphType(), PrebuiltGraphType::LOCAL);
71 ASSERT_NE(graph->GetGraphState(), PrebuiltGraphState::UNINITIALIZED);
72
73 graph->GetSupportedGraphConfigs();
74 std::string functionVisited = graph->GetErrorMessage();
75 EXPECT_THAT(functionVisited, HasSubstr("GetSupportedGraphConfigs"));
76
77 std::map<int, int> maxOutputPacketsPerStream;
78 ClientConfig e(0, 0, 0, maxOutputPacketsPerStream, proto::ProfilingType::DISABLED);
79 e.setPhaseState(runner::PhaseState::ENTRY);
80 EXPECT_EQ(graph->handleConfigPhase(e), Status::SUCCESS);
81 functionVisited = graph->GetErrorMessage();
82
83 EXPECT_EQ(graph->GetStatus(), Status::SUCCESS);
84 functionVisited = graph->GetErrorMessage();
85 EXPECT_THAT(functionVisited, HasSubstr("GetErrorCode"));
86 }
87
TEST(LocalPrebuiltGraphTest,GraphOperationEndToEndIsSuccessful)88 TEST(LocalPrebuiltGraphTest, GraphOperationEndToEndIsSuccessful) {
89 bool graphHasTerminated = false;
90 int numOutputStreamCallbacksReceived[4] = {0, 0, 0, 0};
91
92 PrebuiltEngineInterfaceImpl callback;
93 callback.SetGraphTerminationCallback(
94 [&graphHasTerminated](Status, std::string) { graphHasTerminated = true; });
95
96 // Add multiple pixel stream callback functions to see if all of them register.
97 callback.SetPixelCallback([&numOutputStreamCallbacksReceived](int streamIndex, int64_t,
98 const runner::InputFrame&) {
99 ASSERT_TRUE(streamIndex == 0 || streamIndex == 1);
100 numOutputStreamCallbacksReceived[streamIndex]++;
101 });
102
103 // Add multiple stream callback functions to see if all of them register.
104 callback.SetSerializedStreamCallback(
105 [&numOutputStreamCallbacksReceived](int streamIndex, int64_t, std::string&&) {
106 ASSERT_TRUE(streamIndex == 2 || streamIndex == 3);
107 numOutputStreamCallbacksReceived[streamIndex]++;
108 });
109
110 std::shared_ptr<PrebuiltEngineInterface> engineInterface =
111 std::static_pointer_cast<PrebuiltEngineInterface, PrebuiltEngineInterfaceImpl>(
112 std::make_shared<PrebuiltEngineInterfaceImpl>(callback));
113
114 PrebuiltGraph* graph = GetLocalGraphFromLibrary("libstubgraphimpl.so", engineInterface);
115
116 EXPECT_EQ(graph->GetGraphType(), PrebuiltGraphType::LOCAL);
117 ASSERT_NE(graph->GetGraphState(), PrebuiltGraphState::UNINITIALIZED);
118
119 graph->GetSupportedGraphConfigs();
120 std::string functionVisited = graph->GetErrorMessage();
121 EXPECT_THAT(functionVisited, HasSubstr("GetSupportedGraphConfigs"));
122
123 std::map<int, int> maxOutputPacketsPerStream;
124 ClientConfig e(0, 0, 0, maxOutputPacketsPerStream, proto::ProfilingType::DISABLED);
125 e.setPhaseState(runner::PhaseState::ENTRY);
126 EXPECT_EQ(graph->handleConfigPhase(e), Status::SUCCESS);
127 functionVisited = graph->GetErrorMessage();
128
129 EXPECT_EQ(graph->handleExecutionPhase(e), Status::SUCCESS);
130 functionVisited = graph->GetErrorMessage();
131 EXPECT_THAT(functionVisited, HasSubstr("StartGraphExecution"));
132
133 runner::InputFrame inputFrame(0, 0, PixelFormat::RGB, 0, nullptr);
134 EXPECT_EQ(graph->SetInputStreamPixelData(
135 /*streamIndex =*/0, /*timestamp =*/0, /*inputFrame =*/inputFrame),
136 Status::SUCCESS);
137 EXPECT_EQ(graph->SetInputStreamPixelData(
138 /*streamIndex =*/0, /*timestamp =*/0, /*inputFrame =*/inputFrame),
139 Status::SUCCESS);
140 EXPECT_EQ(graph->SetInputStreamPixelData(
141 /*streamIndex =*/0, /*timestamp =*/0, /*inputFrame =*/inputFrame),
142 Status::SUCCESS);
143 EXPECT_EQ(graph->SetInputStreamPixelData(
144 /*streamIndex =*/1, /*timestamp =*/0, /*inputFrame =*/inputFrame),
145 Status::SUCCESS);
146 EXPECT_EQ(graph->SetInputStreamPixelData(
147 /*streamIndex =*/1, /*timestamp =*/0, /*inputFrame =*/inputFrame),
148 Status::SUCCESS);
149 functionVisited = graph->GetErrorMessage();
150 EXPECT_THAT(functionVisited, HasSubstr("SetInputStreamPixelData"));
151
152 EXPECT_EQ(graph->SetInputStreamData(/*streamIndex =*/2, /* timestamp =*/0, /* data =*/""),
153 Status::SUCCESS);
154 EXPECT_EQ(graph->SetInputStreamData(/*streamIndex =*/2, /* timestamp =*/0, /* data =*/""),
155 Status::SUCCESS);
156 EXPECT_EQ(graph->SetInputStreamData(/*streamIndex =*/2, /* timestamp =*/0, /* data =*/""),
157 Status::SUCCESS);
158 EXPECT_EQ(graph->SetInputStreamData(/*streamIndex =*/3, /* timestamp =*/0, /* data =*/""),
159 Status::SUCCESS);
160 EXPECT_EQ(graph->SetInputStreamData(/*streamIndex =*/3, /* timestamp =*/0, /* data =*/""),
161 Status::SUCCESS);
162 functionVisited = graph->GetErrorMessage();
163 EXPECT_THAT(functionVisited, HasSubstr("SetInputStreamData"));
164
165 EXPECT_EQ(numOutputStreamCallbacksReceived[0], 3);
166 EXPECT_EQ(numOutputStreamCallbacksReceived[1], 2);
167 EXPECT_EQ(numOutputStreamCallbacksReceived[2], 3);
168 EXPECT_EQ(numOutputStreamCallbacksReceived[3], 2);
169
170 EXPECT_FALSE(graphHasTerminated);
171 EXPECT_EQ(graph->handleStopImmediatePhase(e), Status::SUCCESS);
172
173 EXPECT_EQ(graph->handleResetPhase(e), Status::SUCCESS);
174 functionVisited = graph->GetErrorMessage();
175 EXPECT_THAT(functionVisited, HasSubstr("ResetGraph"));
176
177 EXPECT_TRUE(graphHasTerminated);
178 }
179
180 } // namespace
181 } // namespace graph
182 } // namespace computepipe
183 } // namespace automotive
184 } // namespace android
185