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 <map>
17 #include <memory>
18 #include <string>
19 #include <thread>
20 
21 #include <android-base/logging.h>
22 #include <grpc++/grpc++.h>
23 
24 #include "ClientConfig.pb.h"
25 #include "GrpcGraphServerImpl.h"
26 #include "GrpcPrebuiltGraphService.grpc.pb.h"
27 #include "GrpcPrebuiltGraphService.pb.h"
28 #include "Options.pb.h"
29 #include "PrebuiltEngineInterface.h"
30 #include "PrebuiltGraph.h"
31 #include "RunnerComponent.h"
32 #include "gmock/gmock-matchers.h"
33 #include "gmock/gmock.h"
34 #include "gtest/gtest.h"
35 #include "types/Status.h"
36 
37 using ::android::automotive::computepipe::runner::ClientConfig;
38 using ::android::automotive::computepipe::runner::RunnerComponentInterface;
39 using ::android::automotive::computepipe::runner::RunnerEvent;
40 using ::testing::HasSubstr;
41 
42 namespace android {
43 namespace automotive {
44 namespace computepipe {
45 namespace graph {
46 namespace {
47 
48 class GrpcGraphTest : public ::testing::Test {
49 private:
50     std::unique_ptr<GrpcGraphServerImpl> mServer;
51     std::shared_ptr<PrebuiltEngineInterfaceImpl> mEngine;
52     std::string mAddress = "[::]:10000";
53 
54 public:
55     std::unique_ptr<PrebuiltGraph> mGrpcGraph;
56 
SetUp()57     void SetUp() override {
58         mServer = std::make_unique<GrpcGraphServerImpl>(mAddress);
59         std::thread t = std::thread([this]() { mServer->startServer(); });
60         t.detach();
61         std::this_thread::sleep_for(std::chrono::seconds(1));
62 
63         mEngine = std::make_shared<PrebuiltEngineInterfaceImpl>();
64         mGrpcGraph = GetRemoteGraphFromAddress(mAddress, mEngine);
65         ASSERT_TRUE(mGrpcGraph != nullptr);
66         EXPECT_EQ(mGrpcGraph->GetSupportedGraphConfigs().graph_name(), kGraphName);
67         EXPECT_EQ(mGrpcGraph->GetGraphType(), PrebuiltGraphType::REMOTE);
68     }
69 
TearDown()70     void TearDown() override { mServer.reset(); }
71 
waitForTermination()72     bool waitForTermination() { return mEngine->waitForTermination(); }
73 
numPacketsForStream(int streamId)74     int numPacketsForStream(int streamId) { return mEngine->numPacketsForStream(streamId); }
75 };
76 
77 class TestRunnerEvent : public runner::RunnerEvent {
isPhaseEntry() const78     bool isPhaseEntry() const override { return true; }
isTransitionComplete() const79     bool isTransitionComplete() const override { return false; }
isAborted() const80     bool isAborted() const override { return false; }
dispatchToComponent(const std::shared_ptr<runner::RunnerComponentInterface> &)81     Status dispatchToComponent(const std::shared_ptr<runner::RunnerComponentInterface>&) override {
82         return Status::SUCCESS;
83     };
84 };
85 
86 // Test to see if stop with flush produces exactly as many packets as expected. The number
87 // of packets produced by stopImmediate is variable as the number of packets already dispatched
88 // when stop is called is variable.
TEST_F(GrpcGraphTest,EndToEndTestOnStopWithFlush)89 TEST_F(GrpcGraphTest, EndToEndTestOnStopWithFlush) {
90     std::map<int, int> outputConfigs = {{5, 1}, {6, 1}};
91     runner::ClientConfig clientConfig(0, 0, 0, outputConfigs, proto::ProfilingType::DISABLED);
92 
93     EXPECT_EQ(mGrpcGraph->handleConfigPhase(clientConfig), Status::SUCCESS);
94     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::STOPPED);
95     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
96 
97     TestRunnerEvent e;
98     EXPECT_EQ(mGrpcGraph->handleExecutionPhase(e), Status::SUCCESS);
99     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::RUNNING);
100     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
101 
102     EXPECT_EQ(mGrpcGraph->handleStopWithFlushPhase(e), Status::SUCCESS);
103     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::FLUSHING);
104     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
105 
106     EXPECT_TRUE(waitForTermination());
107     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::STOPPED);
108     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
109     EXPECT_EQ(numPacketsForStream(5), 5);
110     EXPECT_EQ(numPacketsForStream(6), 6);
111 }
112 
TEST_F(GrpcGraphTest,GraphStopCallbackProducedOnImmediateStop)113 TEST_F(GrpcGraphTest, GraphStopCallbackProducedOnImmediateStop) {
114     std::map<int, int> outputConfigs = {{5, 1}, {6, 1}};
115     runner::ClientConfig clientConfig(0, 0, 0, outputConfigs, proto::ProfilingType::DISABLED);
116 
117     EXPECT_EQ(mGrpcGraph->handleConfigPhase(clientConfig), Status::SUCCESS);
118     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::STOPPED);
119     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
120 
121     TestRunnerEvent e;
122     EXPECT_EQ(mGrpcGraph->handleExecutionPhase(e), Status::SUCCESS);
123     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::RUNNING);
124     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
125 
126     EXPECT_EQ(mGrpcGraph->handleStopImmediatePhase(e), Status::SUCCESS);
127     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::STOPPED);
128     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
129 
130     EXPECT_TRUE(waitForTermination());
131 }
132 
TEST_F(GrpcGraphTest,GraphStopCallbackProducedOnFlushedStopWithNoOutputStreams)133 TEST_F(GrpcGraphTest, GraphStopCallbackProducedOnFlushedStopWithNoOutputStreams) {
134     std::map<int, int> outputConfigs = {};
135     runner::ClientConfig clientConfig(0, 0, 0, outputConfigs, proto::ProfilingType::DISABLED);
136     EXPECT_EQ(mGrpcGraph->handleConfigPhase(clientConfig), Status::SUCCESS);
137     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::STOPPED);
138     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
139 
140     TestRunnerEvent e;
141     EXPECT_EQ(mGrpcGraph->handleExecutionPhase(e), Status::SUCCESS);
142     EXPECT_EQ(mGrpcGraph->GetGraphState(), PrebuiltGraphState::RUNNING);
143     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
144 
145     EXPECT_EQ(mGrpcGraph->handleStopWithFlushPhase(e), Status::SUCCESS);
146     EXPECT_EQ(mGrpcGraph->GetStatus(), Status::SUCCESS);
147 
148     EXPECT_TRUE(waitForTermination());
149 }
150 
TEST_F(GrpcGraphTest,SetInputStreamsFailAsExpected)151 TEST_F(GrpcGraphTest, SetInputStreamsFailAsExpected) {
152     runner::InputFrame frame(0, 0, static_cast<PixelFormat>(0), 0, nullptr);
153     EXPECT_EQ(mGrpcGraph->SetInputStreamData(0, 0, ""), Status::FATAL_ERROR);
154     EXPECT_EQ(mGrpcGraph->SetInputStreamPixelData(0, 0, frame), Status::FATAL_ERROR);
155 }
156 
157 }  // namespace
158 }  // namespace graph
159 }  // namespace computepipe
160 }  // namespace automotive
161 }  // namespace android
162