1 /*
2 * Copyright (C) 2021 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 "MockBurst.h"
18 #include "MockFencedExecutionCallback.h"
19 #include "MockPreparedModel.h"
20
21 #include <aidl/android/hardware/neuralnetworks/IFencedExecutionCallback.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include <nnapi/IExecution.h>
25 #include <nnapi/IPreparedModel.h>
26 #include <nnapi/TypeUtils.h>
27 #include <nnapi/Types.h>
28 #include <nnapi/hal/aidl/PreparedModel.h>
29
30 #include <functional>
31 #include <memory>
32
33 namespace aidl::android::hardware::neuralnetworks::utils {
34 namespace {
35
36 using ::testing::_;
37 using ::testing::DoAll;
38 using ::testing::Invoke;
39 using ::testing::InvokeWithoutArgs;
40 using ::testing::SetArgPointee;
41
42 const std::shared_ptr<IPreparedModel> kInvalidPreparedModel;
43 constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1};
44
__anon2b5db16f0202null45 constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); };
46
__anon2b5db16f0302null47 constexpr auto makeGeneralFailure = [] {
48 return ndk::ScopedAStatus::fromServiceSpecificError(
49 static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
50 };
__anon2b5db16f0402null51 constexpr auto makeGeneralTransportFailure = [] {
52 return ndk::ScopedAStatus::fromStatus(STATUS_NO_MEMORY);
53 };
__anon2b5db16f0502null54 constexpr auto makeDeadObjectFailure = [] {
55 return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT);
56 };
57
makeFencedExecutionResult(const std::shared_ptr<MockFencedExecutionCallback> & callback)58 auto makeFencedExecutionResult(const std::shared_ptr<MockFencedExecutionCallback>& callback) {
59 return [callback](const Request& /*request*/,
60 const std::vector<ndk::ScopedFileDescriptor>& /*waitFor*/,
61 bool /*measureTiming*/, int64_t /*deadline*/, int64_t /*loopTimeoutDuration*/,
62 int64_t /*duration*/, FencedExecutionResult* fencedExecutionResult) {
63 *fencedExecutionResult = FencedExecutionResult{.callback = callback,
64 .syncFence = ndk::ScopedFileDescriptor(-1)};
65 return ndk::ScopedAStatus::ok();
66 };
67 }
68
69 } // namespace
70
TEST(PreparedModelTest,invalidPreparedModel)71 TEST(PreparedModelTest, invalidPreparedModel) {
72 // run test
73 const auto result = PreparedModel::create(kInvalidPreparedModel);
74
75 // verify result
76 ASSERT_FALSE(result.has_value());
77 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
78 }
79
TEST(PreparedModelTest,executeSync)80 TEST(PreparedModelTest, executeSync) {
81 // setup call
82 const auto mockPreparedModel = MockPreparedModel::create();
83 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
84 const auto mockExecutionResult = ExecutionResult{
85 .outputSufficientSize = true,
86 .outputShapes = {},
87 .timing = kNoTiming,
88 };
89 EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
90 .Times(1)
91 .WillOnce(
92 DoAll(SetArgPointee<4>(mockExecutionResult), InvokeWithoutArgs(makeStatusOk)));
93
94 // run test
95 const auto result = preparedModel->execute({}, {}, {}, {});
96
97 // verify result
98 EXPECT_TRUE(result.has_value())
99 << "Failed with " << result.error().code << ": " << result.error().message;
100 }
101
TEST(PreparedModelTest,executeSyncError)102 TEST(PreparedModelTest, executeSyncError) {
103 // setup test
104 const auto mockPreparedModel = MockPreparedModel::create();
105 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
106 EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
107 .Times(1)
108 .WillOnce(Invoke(makeGeneralFailure));
109
110 // run test
111 const auto result = preparedModel->execute({}, {}, {}, {});
112
113 // verify result
114 ASSERT_FALSE(result.has_value());
115 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
116 }
117
TEST(PreparedModelTest,executeSyncTransportFailure)118 TEST(PreparedModelTest, executeSyncTransportFailure) {
119 // setup test
120 const auto mockPreparedModel = MockPreparedModel::create();
121 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
122 EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
123 .Times(1)
124 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
125
126 // run test
127 const auto result = preparedModel->execute({}, {}, {}, {});
128
129 // verify result
130 ASSERT_FALSE(result.has_value());
131 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
132 }
133
TEST(PreparedModelTest,executeSyncDeadObject)134 TEST(PreparedModelTest, executeSyncDeadObject) {
135 // setup test
136 const auto mockPreparedModel = MockPreparedModel::create();
137 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
138 EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
139 .Times(1)
140 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
141
142 // run test
143 const auto result = preparedModel->execute({}, {}, {}, {});
144
145 // verify result
146 ASSERT_FALSE(result.has_value());
147 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
148 }
149
TEST(PreparedModelTest,executeFenced)150 TEST(PreparedModelTest, executeFenced) {
151 // setup call
152 const auto mockPreparedModel = MockPreparedModel::create();
153 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
154 const auto mockCallback = MockFencedExecutionCallback::create();
155 EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
156 .Times(1)
157 .WillOnce(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming),
158 SetArgPointee<2>(ErrorStatus::NONE), Invoke(makeStatusOk)));
159 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
160 .Times(1)
161 .WillOnce(Invoke(makeFencedExecutionResult(mockCallback)));
162
163 // run test
164 const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {});
165
166 // verify result
167 ASSERT_TRUE(result.has_value())
168 << "Failed with " << result.error().code << ": " << result.error().message;
169 const auto& [syncFence, callback] = result.value();
170 EXPECT_EQ(syncFence.syncWait({}), nn::SyncFence::FenceState::SIGNALED);
171 ASSERT_NE(callback, nullptr);
172
173 // get results from callback
174 const auto callbackResult = callback();
175 ASSERT_TRUE(callbackResult.has_value()) << "Failed with " << callbackResult.error().code << ": "
176 << callbackResult.error().message;
177 }
178
TEST(PreparedModelTest,executeFencedCallbackError)179 TEST(PreparedModelTest, executeFencedCallbackError) {
180 // setup call
181 const auto mockPreparedModel = MockPreparedModel::create();
182 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
183 const auto mockCallback = MockFencedExecutionCallback::create();
184 EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
185 .Times(1)
186 .WillOnce(Invoke(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming),
187 SetArgPointee<2>(ErrorStatus::GENERAL_FAILURE),
188 Invoke(makeStatusOk))));
189 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
190 .Times(1)
191 .WillOnce(Invoke(makeFencedExecutionResult(mockCallback)));
192
193 // run test
194 const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {});
195
196 // verify result
197 ASSERT_TRUE(result.has_value())
198 << "Failed with " << result.error().code << ": " << result.error().message;
199 const auto& [syncFence, callback] = result.value();
200 EXPECT_NE(syncFence.syncWait({}), nn::SyncFence::FenceState::ACTIVE);
201 ASSERT_NE(callback, nullptr);
202
203 // verify callback failure
204 const auto callbackResult = callback();
205 ASSERT_FALSE(callbackResult.has_value());
206 EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
207 }
208
TEST(PreparedModelTest,executeFencedError)209 TEST(PreparedModelTest, executeFencedError) {
210 // setup test
211 const auto mockPreparedModel = MockPreparedModel::create();
212 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
213 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
214 .Times(1)
215 .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
216
217 // run test
218 const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {});
219
220 // verify result
221 ASSERT_FALSE(result.has_value());
222 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
223 }
224
TEST(PreparedModelTest,executeFencedTransportFailure)225 TEST(PreparedModelTest, executeFencedTransportFailure) {
226 // setup test
227 const auto mockPreparedModel = MockPreparedModel::create();
228 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
229 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
230 .Times(1)
231 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
232
233 // run test
234 const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {});
235
236 // verify result
237 ASSERT_FALSE(result.has_value());
238 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
239 }
240
TEST(PreparedModelTest,executeFencedDeadObject)241 TEST(PreparedModelTest, executeFencedDeadObject) {
242 // setup test
243 const auto mockPreparedModel = MockPreparedModel::create();
244 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
245 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
246 .Times(1)
247 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
248
249 // run test
250 const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {});
251
252 // verify result
253 ASSERT_FALSE(result.has_value());
254 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
255 }
256
TEST(PreparedModelTest,reusableExecuteSync)257 TEST(PreparedModelTest, reusableExecuteSync) {
258 // setup call
259 const uint32_t kNumberOfComputations = 2;
260 const auto mockPreparedModel = MockPreparedModel::create();
261 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
262 const auto mockExecutionResult = ExecutionResult{
263 .outputSufficientSize = true,
264 .outputShapes = {},
265 .timing = kNoTiming,
266 };
267 EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
268 .Times(kNumberOfComputations)
269 .WillRepeatedly(
270 DoAll(SetArgPointee<4>(mockExecutionResult), InvokeWithoutArgs(makeStatusOk)));
271
272 // create execution
273 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
274 ASSERT_TRUE(createResult.has_value())
275 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
276 ASSERT_NE(createResult.value(), nullptr);
277
278 // invoke compute repeatedly
279 for (uint32_t i = 0; i < kNumberOfComputations; i++) {
280 const auto computeResult = createResult.value()->compute({});
281 EXPECT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code
282 << ": " << computeResult.error().message;
283 }
284 }
285
TEST(PreparedModelTest,reusableExecuteSyncError)286 TEST(PreparedModelTest, reusableExecuteSyncError) {
287 // setup test
288 const auto mockPreparedModel = MockPreparedModel::create();
289 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
290 EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
291 .Times(1)
292 .WillOnce(Invoke(makeGeneralFailure));
293
294 // create execution
295 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
296 ASSERT_TRUE(createResult.has_value())
297 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
298 ASSERT_NE(createResult.value(), nullptr);
299
300 // invoke compute
301 const auto computeResult = createResult.value()->compute({});
302 ASSERT_FALSE(computeResult.has_value());
303 EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
304 }
305
TEST(PreparedModelTest,reusableExecuteSyncTransportFailure)306 TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) {
307 // setup test
308 const auto mockPreparedModel = MockPreparedModel::create();
309 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
310 EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
311 .Times(1)
312 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
313
314 // create execution
315 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
316 ASSERT_TRUE(createResult.has_value())
317 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
318 ASSERT_NE(createResult.value(), nullptr);
319
320 // invoke compute
321 const auto computeResult = createResult.value()->compute({});
322 ASSERT_FALSE(computeResult.has_value());
323 EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
324 }
325
TEST(PreparedModelTest,reusableExecuteSyncDeadObject)326 TEST(PreparedModelTest, reusableExecuteSyncDeadObject) {
327 // setup test
328 const auto mockPreparedModel = MockPreparedModel::create();
329 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
330 EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
331 .Times(1)
332 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
333
334 // create execution
335 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
336 ASSERT_TRUE(createResult.has_value())
337 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
338 ASSERT_NE(createResult.value(), nullptr);
339
340 // invoke compute
341 const auto computeResult = createResult.value()->compute({});
342 ASSERT_FALSE(computeResult.has_value());
343 EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT);
344 }
345
TEST(PreparedModelTest,reusableExecuteFenced)346 TEST(PreparedModelTest, reusableExecuteFenced) {
347 // setup call
348 const uint32_t kNumberOfComputations = 2;
349 const auto mockPreparedModel = MockPreparedModel::create();
350 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
351 const auto mockCallback = MockFencedExecutionCallback::create();
352 EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
353 .Times(kNumberOfComputations)
354 .WillRepeatedly(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming),
355 SetArgPointee<2>(ErrorStatus::NONE), Invoke(makeStatusOk)));
356 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
357 .Times(kNumberOfComputations)
358 .WillRepeatedly(Invoke(makeFencedExecutionResult(mockCallback)));
359
360 // create execution
361 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
362 ASSERT_TRUE(createResult.has_value())
363 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
364 ASSERT_NE(createResult.value(), nullptr);
365
366 // invoke compute repeatedly
367 for (uint32_t i = 0; i < kNumberOfComputations; i++) {
368 const auto computeResult = createResult.value()->computeFenced({}, {}, {});
369 ASSERT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code
370 << ": " << computeResult.error().message;
371 const auto& [syncFence, callback] = computeResult.value();
372 EXPECT_EQ(syncFence.syncWait({}), nn::SyncFence::FenceState::SIGNALED);
373 ASSERT_NE(callback, nullptr);
374
375 // get results from callback
376 const auto callbackResult = callback();
377 ASSERT_TRUE(callbackResult.has_value()) << "Failed with " << callbackResult.error().code
378 << ": " << callbackResult.error().message;
379 }
380 }
381
TEST(PreparedModelTest,reusableExecuteFencedCallbackError)382 TEST(PreparedModelTest, reusableExecuteFencedCallbackError) {
383 // setup call
384 const auto mockPreparedModel = MockPreparedModel::create();
385 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
386 const auto mockCallback = MockFencedExecutionCallback::create();
387 EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
388 .Times(1)
389 .WillOnce(Invoke(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming),
390 SetArgPointee<2>(ErrorStatus::GENERAL_FAILURE),
391 Invoke(makeStatusOk))));
392 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
393 .Times(1)
394 .WillOnce(Invoke(makeFencedExecutionResult(mockCallback)));
395
396 // create execution
397 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
398 ASSERT_TRUE(createResult.has_value())
399 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
400 ASSERT_NE(createResult.value(), nullptr);
401
402 // invoke compute
403 const auto computeResult = createResult.value()->computeFenced({}, {}, {});
404 ASSERT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code << ": "
405 << computeResult.error().message;
406 const auto& [syncFence, callback] = computeResult.value();
407 EXPECT_NE(syncFence.syncWait({}), nn::SyncFence::FenceState::ACTIVE);
408 ASSERT_NE(callback, nullptr);
409
410 // verify callback failure
411 const auto callbackResult = callback();
412 ASSERT_FALSE(callbackResult.has_value());
413 EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
414 }
415
TEST(PreparedModelTest,reusableExecuteFencedError)416 TEST(PreparedModelTest, reusableExecuteFencedError) {
417 // setup test
418 const auto mockPreparedModel = MockPreparedModel::create();
419 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
420 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
421 .Times(1)
422 .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
423
424 // create execution
425 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
426 ASSERT_TRUE(createResult.has_value())
427 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
428 ASSERT_NE(createResult.value(), nullptr);
429
430 // invoke compute
431 const auto computeResult = createResult.value()->computeFenced({}, {}, {});
432 ASSERT_FALSE(computeResult.has_value());
433 EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
434 }
435
TEST(PreparedModelTest,reusableExecuteFencedTransportFailure)436 TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) {
437 // setup test
438 const auto mockPreparedModel = MockPreparedModel::create();
439 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
440 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
441 .Times(1)
442 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
443
444 // create execution
445 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
446 ASSERT_TRUE(createResult.has_value())
447 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
448 ASSERT_NE(createResult.value(), nullptr);
449
450 // invoke compute
451 const auto computeResult = createResult.value()->computeFenced({}, {}, {});
452 ASSERT_FALSE(computeResult.has_value());
453 EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
454 }
455
TEST(PreparedModelTest,reusableExecuteFencedDeadObject)456 TEST(PreparedModelTest, reusableExecuteFencedDeadObject) {
457 // setup test
458 const auto mockPreparedModel = MockPreparedModel::create();
459 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
460 EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
461 .Times(1)
462 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
463
464 // create execution
465 const auto createResult = preparedModel->createReusableExecution({}, {}, {});
466 ASSERT_TRUE(createResult.has_value())
467 << "Failed with " << createResult.error().code << ": " << createResult.error().message;
468 ASSERT_NE(createResult.value(), nullptr);
469
470 // invoke compute
471 const auto computeResult = createResult.value()->computeFenced({}, {}, {});
472 ASSERT_FALSE(computeResult.has_value());
473 EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT);
474 }
475
TEST(PreparedModelTest,configureExecutionBurst)476 TEST(PreparedModelTest, configureExecutionBurst) {
477 // setup test
478 const auto mockPreparedModel = MockPreparedModel::create();
479 const auto mockBurst = ndk::SharedRefBase::make<MockBurst>();
480 EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_))
481 .Times(1)
482 .WillOnce(DoAll(SetArgPointee<0>(mockBurst), Invoke(makeStatusOk)));
483 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
484
485 // run test
486 const auto result = preparedModel->configureExecutionBurst();
487
488 // verify result
489 ASSERT_TRUE(result.has_value())
490 << "Failed with " << result.error().code << ": " << result.error().message;
491 EXPECT_NE(result.value(), nullptr);
492 }
493
TEST(PreparedModelTest,configureExecutionBurstError)494 TEST(PreparedModelTest, configureExecutionBurstError) {
495 // setup test
496 const auto mockPreparedModel = MockPreparedModel::create();
497 EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_))
498 .Times(1)
499 .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
500 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
501
502 // run test
503 const auto result = preparedModel->configureExecutionBurst();
504
505 // verify result
506 ASSERT_FALSE(result.has_value());
507 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
508 }
509
TEST(PreparedModelTest,configureExecutionBurstTransportFailure)510 TEST(PreparedModelTest, configureExecutionBurstTransportFailure) {
511 // setup test
512 const auto mockPreparedModel = MockPreparedModel::create();
513 EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_))
514 .Times(1)
515 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
516 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
517
518 // run test
519 const auto result = preparedModel->configureExecutionBurst();
520
521 // verify result
522 ASSERT_FALSE(result.has_value());
523 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
524 }
525
TEST(PreparedModelTest,configureExecutionBurstDeadObject)526 TEST(PreparedModelTest, configureExecutionBurstDeadObject) {
527 // setup test
528 const auto mockPreparedModel = MockPreparedModel::create();
529 EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_))
530 .Times(1)
531 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
532 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
533
534 // run test
535 const auto result = preparedModel->configureExecutionBurst();
536
537 // verify result
538 ASSERT_FALSE(result.has_value());
539 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
540 }
541
TEST(PreparedModelTest,getUnderlyingResource)542 TEST(PreparedModelTest, getUnderlyingResource) {
543 // setup test
544 const auto mockPreparedModel = MockPreparedModel::create();
545 const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
546
547 // run test
548 const auto resource = preparedModel->getUnderlyingResource();
549
550 // verify resource
551 const std::shared_ptr<IPreparedModel>* maybeMock =
552 std::any_cast<std::shared_ptr<IPreparedModel>>(&resource);
553 ASSERT_NE(maybeMock, nullptr);
554 EXPECT_EQ(maybeMock->get(), mockPreparedModel.get());
555 }
556
557 } // namespace aidl::android::hardware::neuralnetworks::utils
558