1 /*
2 * Copyright (C) 2016 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
17 #include "request_tracker.h"
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 using testing::AtMost;
23 using testing::Expectation;
24 using testing::Return;
25 using testing::SetArgPointee;
26 using testing::Test;
27 using testing::_;
28
29 namespace default_camera_hal {
30
31 class RequestTrackerTest : public Test {
32 protected:
SetUp()33 void SetUp() {
34 stream1_.max_buffers = 3;
35 stream2_.max_buffers = 3;
36 dut_.reset(new RequestTracker());
37 streams_ = {&stream1_, &stream2_};
38 camera3_stream_configuration_t config{static_cast<uint32_t>(streams_.size()), streams_.data(), 0};
39 dut_->SetStreamConfiguration(config);
40 }
41
GenerateCaptureRequest(uint32_t frame,std::vector<camera3_stream_t * > streams)42 std::shared_ptr<CaptureRequest> GenerateCaptureRequest(
43 uint32_t frame, std::vector<camera3_stream_t*> streams) {
44 std::shared_ptr<CaptureRequest> request =
45 std::make_shared<CaptureRequest>();
46
47 // Set the frame number and buffers.
48 request->frame_number = frame;
49 for (const auto stream : streams) {
50 // All we really care about for the buffers is which stream they're for.
51 camera3_stream_buffer_t buffer{stream, nullptr, 0, -1, -1};
52 request->output_buffers.push_back(buffer);
53 }
54
55 return request;
56 }
57
AddRequest(uint32_t frame,std::vector<camera3_stream_t * > streams,bool expected=true)58 void AddRequest(uint32_t frame,
59 std::vector<camera3_stream_t*> streams,
60 bool expected = true) {
61 std::shared_ptr<CaptureRequest> request =
62 GenerateCaptureRequest(frame, streams);
63 EXPECT_EQ(dut_->CanAddRequest(*request), expected);
64 if (expected) {
65 EXPECT_FALSE(dut_->InFlight(frame));
66 }
67 EXPECT_EQ(dut_->Add(request), expected);
68 if (expected) {
69 EXPECT_TRUE(dut_->InFlight(frame));
70 }
71 }
72
73 camera3_stream_t stream1_;
74 camera3_stream_t stream2_;
75 std::vector<camera3_stream_t*> streams_;
76 std::shared_ptr<RequestTracker> dut_;
77 };
78
TEST_F(RequestTrackerTest,AddValid)79 TEST_F(RequestTrackerTest, AddValid) {
80 uint32_t frame = 34;
81 EXPECT_FALSE(dut_->InFlight(frame));
82 AddRequest(frame, {&stream1_});
83 }
84
TEST_F(RequestTrackerTest,AddInput)85 TEST_F(RequestTrackerTest, AddInput) {
86 EXPECT_TRUE(dut_->Empty());
87
88 // Add a request
89 uint32_t frame = 42;
90 std::shared_ptr<CaptureRequest> expected = GenerateCaptureRequest(frame, {});
91 // Set the input buffer instead of any outputs.
92 expected->input_buffer.reset(
93 new camera3_stream_buffer_t{&stream1_, nullptr, 0, -1, -1});
94 stream1_.max_buffers = 1;
95
96 EXPECT_TRUE(dut_->Add(expected));
97 EXPECT_TRUE(dut_->InFlight(frame));
98 // Should have added to the count of buffers for stream 1.
99 EXPECT_TRUE(dut_->StreamFull(&stream1_));
100 }
101
TEST_F(RequestTrackerTest,AddMultipleStreams)102 TEST_F(RequestTrackerTest, AddMultipleStreams) {
103 stream1_.max_buffers = 1;
104 stream2_.max_buffers = 1;
105
106 EXPECT_FALSE(dut_->StreamFull(&stream1_));
107 EXPECT_FALSE(dut_->StreamFull(&stream2_));
108
109 // Add a request using both streams.
110 AddRequest(99, {&stream1_, &stream2_});
111
112 // Should both have been counted.
113 EXPECT_TRUE(dut_->StreamFull(&stream1_));
114 EXPECT_TRUE(dut_->StreamFull(&stream2_));
115 }
116
TEST_F(RequestTrackerTest,AddUnconfigured)117 TEST_F(RequestTrackerTest, AddUnconfigured) {
118 camera3_stream_t stream;
119 // Unconfigured should be considered full.
120 EXPECT_TRUE(dut_->StreamFull(&stream));
121 AddRequest(1, {&stream}, false);
122 }
123
TEST_F(RequestTrackerTest,AddPastCapacity)124 TEST_F(RequestTrackerTest, AddPastCapacity) {
125 // Set the limit of stream 2 to 1.
126 stream2_.max_buffers = 1;
127
128 for (size_t i = 0; i < stream1_.max_buffers; ++i) {
129 EXPECT_FALSE(dut_->StreamFull(&stream1_));
130 EXPECT_FALSE(dut_->StreamFull(&stream2_));
131 AddRequest(i, {&stream1_});
132 }
133 // Filled up stream 1.
134 EXPECT_TRUE(dut_->StreamFull(&stream1_));
135 // Stream 2 should still not be full since nothing was added.
136 EXPECT_FALSE(dut_->StreamFull(&stream2_));
137
138 // Limit has been hit, can't add more.
139 AddRequest(stream1_.max_buffers, {&stream1_, &stream2_}, false);
140 EXPECT_TRUE(dut_->StreamFull(&stream1_));
141 // Should not have added to the count of stream 2.
142 EXPECT_FALSE(dut_->StreamFull(&stream2_));
143 }
144
TEST_F(RequestTrackerTest,AddDuplicate)145 TEST_F(RequestTrackerTest, AddDuplicate) {
146 uint32_t frame = 42;
147 AddRequest(frame, {&stream1_});
148 // Can't add a duplicate.
149 AddRequest(frame, {&stream2_}, false);
150 }
151
TEST_F(RequestTrackerTest,RemoveValid)152 TEST_F(RequestTrackerTest, RemoveValid) {
153 EXPECT_TRUE(dut_->Empty());
154
155 // Add a request
156 uint32_t frame = 42;
157 std::shared_ptr<CaptureRequest> request =
158 GenerateCaptureRequest(frame, {&stream1_});
159 EXPECT_TRUE(dut_->Add(request));
160 EXPECT_TRUE(dut_->InFlight(frame));
161 AddRequest(frame + 1, {&stream1_});
162 EXPECT_FALSE(dut_->Empty());
163
164 // Remove it.
165 EXPECT_TRUE(dut_->Remove(request));
166 // Should have removed only the desired request.
167 EXPECT_FALSE(dut_->Empty());
168 }
169
TEST_F(RequestTrackerTest,RemoveInvalidFrame)170 TEST_F(RequestTrackerTest, RemoveInvalidFrame) {
171 EXPECT_TRUE(dut_->Empty());
172
173 // Add a request
174 uint32_t frame = 42;
175 AddRequest(frame, {&stream1_});
176 EXPECT_FALSE(dut_->Empty());
177
178 // Try to remove a different one.
179 uint32_t bad_frame = frame + 1;
180 std::shared_ptr<CaptureRequest> bad_request =
181 GenerateCaptureRequest(bad_frame, {&stream1_});
182 EXPECT_FALSE(dut_->InFlight(bad_frame));
183 EXPECT_FALSE(dut_->Remove(bad_request));
184 EXPECT_FALSE(dut_->Empty());
185 }
186
TEST_F(RequestTrackerTest,RemoveInvalidData)187 TEST_F(RequestTrackerTest, RemoveInvalidData) {
188 EXPECT_TRUE(dut_->Empty());
189
190 // Add a request
191 uint32_t frame = 42;
192 AddRequest(frame, {&stream1_});
193 EXPECT_FALSE(dut_->Empty());
194
195 // Try to remove a different one.
196 // Even though this request looks the same, that fact that it is
197 // a pointer to a different object means it should fail.
198 std::shared_ptr<CaptureRequest> bad_request =
199 GenerateCaptureRequest(frame, {&stream1_});
200 EXPECT_TRUE(dut_->InFlight(frame));
201 EXPECT_FALSE(dut_->Remove(bad_request));
202 EXPECT_FALSE(dut_->Empty());
203 }
204
TEST_F(RequestTrackerTest,RemoveNull)205 TEST_F(RequestTrackerTest, RemoveNull) {
206 EXPECT_FALSE(dut_->Remove(nullptr));
207 }
208
TEST_F(RequestTrackerTest,ClearRequests)209 TEST_F(RequestTrackerTest, ClearRequests) {
210 // Create some requests.
211 uint32_t frame1 = 42;
212 uint32_t frame2 = frame1 + 1;
213 std::shared_ptr<CaptureRequest> request1 =
214 GenerateCaptureRequest(frame1, {&stream1_});
215 std::shared_ptr<CaptureRequest> request2 =
216 GenerateCaptureRequest(frame2, {&stream2_});
217 std::set<std::shared_ptr<CaptureRequest>> expected;
218 expected.insert(request1);
219 expected.insert(request2);
220
221 // Insert them.
222 EXPECT_TRUE(dut_->Add(request1));
223 EXPECT_TRUE(dut_->Add(request2));
224 EXPECT_TRUE(dut_->InFlight(frame1));
225 EXPECT_TRUE(dut_->InFlight(frame2));
226 EXPECT_FALSE(dut_->Empty());
227 std::set<std::shared_ptr<CaptureRequest>> actual;
228
229 // Clear them out.
230 dut_->Clear(&actual);
231 EXPECT_TRUE(dut_->Empty());
232 EXPECT_EQ(actual, expected);
233
234 // Configuration (max values) should not have been cleared.
235 EXPECT_TRUE(dut_->Add(request1));
236 }
237
TEST_F(RequestTrackerTest,ClearRequestsNoResult)238 TEST_F(RequestTrackerTest, ClearRequestsNoResult) {
239 // Add some requests.
240 EXPECT_TRUE(dut_->Empty());
241 AddRequest(1, {&stream1_});
242 AddRequest(2, {&stream2_});
243 EXPECT_FALSE(dut_->Empty());
244 // Don't bother getting the cleared requests.
245 dut_->Clear();
246 EXPECT_TRUE(dut_->Empty());
247 }
248
TEST_F(RequestTrackerTest,ClearConfiguration)249 TEST_F(RequestTrackerTest, ClearConfiguration) {
250 EXPECT_FALSE(dut_->StreamFull(&stream1_));
251 EXPECT_FALSE(dut_->StreamFull(&stream2_));
252
253 // Clear the configuration.
254 dut_->ClearStreamConfiguration();
255
256 // Both streams should be considered full now, since neither is configured.
257 EXPECT_TRUE(dut_->StreamFull(&stream1_));
258 EXPECT_TRUE(dut_->StreamFull(&stream2_));
259 }
260
261 } // namespace default_camera_hal
262