1 /*
2 * Copyright (C) 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
17 #include "MockDevice.h"
18 #include "MockPreparedModel.h"
19
20 #include <android/hardware/neuralnetworks/1.2/IDevice.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <nnapi/IDevice.h>
24 #include <nnapi/TypeUtils.h>
25 #include <nnapi/Types.h>
26 #include <nnapi/hal/1.2/Device.h>
27
28 #include <functional>
29 #include <memory>
30 #include <string>
31
32 namespace android::hardware::neuralnetworks::V1_2::utils {
33 namespace {
34
35 using ::testing::_;
36 using ::testing::Invoke;
37 using ::testing::InvokeWithoutArgs;
38
39 const nn::Model kSimpleModel = {
40 .main = {.operands = {{.type = nn::OperandType::TENSOR_FLOAT32,
41 .dimensions = {1},
42 .lifetime = nn::Operand::LifeTime::SUBGRAPH_INPUT},
43 {.type = nn::OperandType::TENSOR_FLOAT32,
44 .dimensions = {1},
45 .lifetime = nn::Operand::LifeTime::SUBGRAPH_OUTPUT}},
46 .operations = {{.type = nn::OperationType::RELU, .inputs = {0}, .outputs = {1}}},
47 .inputIndexes = {0},
48 .outputIndexes = {1}}};
49
50 const std::string kName = "Google-MockV1";
51 const std::string kInvalidName = "";
52 const sp<V1_2::IDevice> kInvalidDevice;
53 constexpr V1_0::PerformanceInfo kNoPerformanceInfo = {
54 .execTime = std::numeric_limits<float>::max(),
55 .powerUsage = std::numeric_limits<float>::max()};
56
57 // FIXME: This function causes Clang to hang indefinitely when building with
58 // -O1. Turn off optimization as a temporary workaround.
59 // http://b/296850773
60 #pragma clang optimize off
61 template <typename... Args>
makeCallbackReturn(Args &&...args)62 auto makeCallbackReturn(Args&&... args) {
63 return [argPack = std::make_tuple(std::forward<Args>(args)...)](const auto& cb) {
64 std::apply(cb, argPack);
65 return Void();
66 };
67 }
68 #pragma clang optimize on
69
createMockDevice()70 sp<MockDevice> createMockDevice() {
71 const auto mockDevice = MockDevice::create();
72
73 // Setup default actions for each relevant call.
74 const auto getVersionString_ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, kName);
75 const auto getType_ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, V1_2::DeviceType::OTHER);
76 const auto getSupportedExtensions_ret =
77 makeCallbackReturn(V1_0::ErrorStatus::NONE, hidl_vec<V1_2::Extension>{});
78 const auto getNumberOfCacheFilesNeeded_ret = makeCallbackReturn(
79 V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles, nn::kMaxNumberOfCacheFiles);
80 const auto getCapabilities_ret = makeCallbackReturn(
81 V1_0::ErrorStatus::NONE,
82 V1_2::Capabilities{
83 .relaxedFloat32toFloat16PerformanceScalar = kNoPerformanceInfo,
84 .relaxedFloat32toFloat16PerformanceTensor = kNoPerformanceInfo,
85 });
86
87 // Setup default actions for each relevant call.
88 ON_CALL(*mockDevice, getVersionString(_)).WillByDefault(Invoke(getVersionString_ret));
89 ON_CALL(*mockDevice, getType(_)).WillByDefault(Invoke(getType_ret));
90 ON_CALL(*mockDevice, getSupportedExtensions(_))
91 .WillByDefault(Invoke(getSupportedExtensions_ret));
92 ON_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_))
93 .WillByDefault(Invoke(getNumberOfCacheFilesNeeded_ret));
94 ON_CALL(*mockDevice, getCapabilities_1_2(_)).WillByDefault(Invoke(getCapabilities_ret));
95
96 // Ensure that older calls are not used.
97 EXPECT_CALL(*mockDevice, getCapabilities(_)).Times(0);
98 EXPECT_CALL(*mockDevice, getCapabilities_1_1(_)).Times(0);
99 EXPECT_CALL(*mockDevice, getSupportedOperations(_, _)).Times(0);
100 EXPECT_CALL(*mockDevice, getSupportedOperations_1_1(_, _)).Times(0);
101 EXPECT_CALL(*mockDevice, prepareModel(_, _)).Times(0);
102 EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)).Times(0);
103
104 // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the
105 // uninteresting methods calls.
106 EXPECT_CALL(*mockDevice, getVersionString(_)).Times(testing::AnyNumber());
107 EXPECT_CALL(*mockDevice, getType(_)).Times(testing::AnyNumber());
108 EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(testing::AnyNumber());
109 EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(testing::AnyNumber());
110 EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)).Times(testing::AnyNumber());
111
112 return mockDevice;
113 }
114
makePreparedModelReturn(V1_0::ErrorStatus launchStatus,V1_0::ErrorStatus returnStatus,const sp<MockPreparedModel> & preparedModel)115 auto makePreparedModelReturn(V1_0::ErrorStatus launchStatus, V1_0::ErrorStatus returnStatus,
116 const sp<MockPreparedModel>& preparedModel) {
117 return [launchStatus, returnStatus, preparedModel](
118 const V1_2::Model& /*model*/, V1_1::ExecutionPreference /*preference*/,
119 const hardware::hidl_vec<hardware::hidl_handle>& /*modelCache*/,
120 const hardware::hidl_vec<hardware::hidl_handle>& /*dataCache*/,
121 const CacheToken& /*token*/, const sp<V1_2::IPreparedModelCallback>& cb)
122 -> hardware::Return<V1_0::ErrorStatus> {
123 cb->notify_1_2(returnStatus, preparedModel).isOk();
124 return launchStatus;
125 };
126 }
makePreparedModelFromCacheReturn(V1_0::ErrorStatus launchStatus,V1_0::ErrorStatus returnStatus,const sp<MockPreparedModel> & preparedModel)127 auto makePreparedModelFromCacheReturn(V1_0::ErrorStatus launchStatus,
128 V1_0::ErrorStatus returnStatus,
129 const sp<MockPreparedModel>& preparedModel) {
130 return [launchStatus, returnStatus, preparedModel](
131 const hardware::hidl_vec<hardware::hidl_handle>& /*modelCache*/,
132 const hardware::hidl_vec<hardware::hidl_handle>& /*dataCache*/,
133 const CacheToken& /*token*/, const sp<V1_2::IPreparedModelCallback>& cb)
134 -> hardware::Return<V1_0::ErrorStatus> {
135 cb->notify_1_2(returnStatus, preparedModel).isOk();
136 return launchStatus;
137 };
138 }
139
makeTransportFailure(status_t status)140 std::function<hardware::Status()> makeTransportFailure(status_t status) {
141 return [status] { return hardware::Status::fromStatusT(status); };
142 }
143
144 const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY);
145 const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT);
146
147 } // namespace
148
TEST(DeviceTest,invalidName)149 TEST(DeviceTest, invalidName) {
150 // run test
151 const auto device = MockDevice::create();
152 const auto result = Device::create(kInvalidName, device);
153
154 // verify result
155 ASSERT_FALSE(result.has_value());
156 EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT);
157 }
158
TEST(DeviceTest,invalidDevice)159 TEST(DeviceTest, invalidDevice) {
160 // run test
161 const auto result = Device::create(kName, kInvalidDevice);
162
163 // verify result
164 ASSERT_FALSE(result.has_value());
165 EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT);
166 }
167
TEST(DeviceTest,getVersionStringError)168 TEST(DeviceTest, getVersionStringError) {
169 // setup call
170 const auto mockDevice = createMockDevice();
171 const auto ret = makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, "");
172 EXPECT_CALL(*mockDevice, getVersionString(_)).Times(1).WillOnce(Invoke(ret));
173
174 // run test
175 const auto result = Device::create(kName, mockDevice);
176
177 // verify result
178 ASSERT_FALSE(result.has_value());
179 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
180 }
181
TEST(DeviceTest,getVersionStringTransportFailure)182 TEST(DeviceTest, getVersionStringTransportFailure) {
183 // setup call
184 const auto mockDevice = createMockDevice();
185 EXPECT_CALL(*mockDevice, getVersionString(_))
186 .Times(1)
187 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
188
189 // run test
190 const auto result = Device::create(kName, mockDevice);
191
192 // verify result
193 ASSERT_FALSE(result.has_value());
194 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
195 }
196
TEST(DeviceTest,getVersionStringDeadObject)197 TEST(DeviceTest, getVersionStringDeadObject) {
198 // setup call
199 const auto mockDevice = createMockDevice();
200 EXPECT_CALL(*mockDevice, getVersionString(_))
201 .Times(1)
202 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
203
204 // run test
205 const auto result = Device::create(kName, mockDevice);
206
207 // verify result
208 ASSERT_FALSE(result.has_value());
209 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
210 }
211
TEST(DeviceTest,getTypeError)212 TEST(DeviceTest, getTypeError) {
213 // setup call
214 const auto mockDevice = createMockDevice();
215 const auto ret =
216 makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, V1_2::DeviceType::OTHER);
217 EXPECT_CALL(*mockDevice, getType(_)).Times(1).WillOnce(Invoke(ret));
218
219 // run test
220 const auto result = Device::create(kName, mockDevice);
221
222 // verify result
223 ASSERT_FALSE(result.has_value());
224 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
225 }
226
TEST(DeviceTest,getTypeTransportFailure)227 TEST(DeviceTest, getTypeTransportFailure) {
228 // setup call
229 const auto mockDevice = createMockDevice();
230 EXPECT_CALL(*mockDevice, getType(_))
231 .Times(1)
232 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
233
234 // run test
235 const auto result = Device::create(kName, mockDevice);
236
237 // verify result
238 ASSERT_FALSE(result.has_value());
239 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
240 }
241
TEST(DeviceTest,getTypeDeadObject)242 TEST(DeviceTest, getTypeDeadObject) {
243 // setup call
244 const auto mockDevice = createMockDevice();
245 EXPECT_CALL(*mockDevice, getType(_))
246 .Times(1)
247 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
248
249 // run test
250 const auto result = Device::create(kName, mockDevice);
251
252 // verify result
253 ASSERT_FALSE(result.has_value());
254 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
255 }
256
TEST(DeviceTest,getSupportedExtensionsError)257 TEST(DeviceTest, getSupportedExtensionsError) {
258 // setup call
259 const auto mockDevice = createMockDevice();
260 const auto ret =
261 makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, hidl_vec<V1_2::Extension>{});
262 EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(1).WillOnce(Invoke(ret));
263
264 // run test
265 const auto result = Device::create(kName, mockDevice);
266
267 // verify result
268 ASSERT_FALSE(result.has_value());
269 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
270 }
271
TEST(DeviceTest,getSupportedExtensionsTransportFailure)272 TEST(DeviceTest, getSupportedExtensionsTransportFailure) {
273 // setup call
274 const auto mockDevice = createMockDevice();
275 EXPECT_CALL(*mockDevice, getSupportedExtensions(_))
276 .Times(1)
277 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
278
279 // run test
280 const auto result = Device::create(kName, mockDevice);
281
282 // verify result
283 ASSERT_FALSE(result.has_value());
284 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
285 }
286
TEST(DeviceTest,getSupportedExtensionsDeadObject)287 TEST(DeviceTest, getSupportedExtensionsDeadObject) {
288 // setup call
289 const auto mockDevice = createMockDevice();
290 EXPECT_CALL(*mockDevice, getSupportedExtensions(_))
291 .Times(1)
292 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
293
294 // run test
295 const auto result = Device::create(kName, mockDevice);
296
297 // verify result
298 ASSERT_FALSE(result.has_value());
299 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
300 }
301
TEST(DeviceTest,getNumberOfCacheFilesNeededError)302 TEST(DeviceTest, getNumberOfCacheFilesNeededError) {
303 // setup call
304 const auto mockDevice = createMockDevice();
305 const auto ret = makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE,
306 nn::kMaxNumberOfCacheFiles, nn::kMaxNumberOfCacheFiles);
307 EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret));
308
309 // run test
310 const auto result = Device::create(kName, mockDevice);
311
312 // verify result
313 ASSERT_FALSE(result.has_value());
314 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
315 }
316
TEST(DeviceTest,dataCacheFilesExceedsSpecifiedMax)317 TEST(DeviceTest, dataCacheFilesExceedsSpecifiedMax) {
318 // setup test
319 const auto mockDevice = createMockDevice();
320 const auto ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles + 1,
321 nn::kMaxNumberOfCacheFiles);
322 EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret));
323
324 // run test
325 const auto result = Device::create(kName, mockDevice);
326
327 // verify result
328 ASSERT_FALSE(result.has_value());
329 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
330 }
331
TEST(DeviceTest,modelCacheFilesExceedsSpecifiedMax)332 TEST(DeviceTest, modelCacheFilesExceedsSpecifiedMax) {
333 // setup test
334 const auto mockDevice = createMockDevice();
335 const auto ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles,
336 nn::kMaxNumberOfCacheFiles + 1);
337 EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret));
338
339 // run test
340 const auto result = Device::create(kName, mockDevice);
341
342 // verify result
343 ASSERT_FALSE(result.has_value());
344 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
345 }
346
TEST(DeviceTest,getNumberOfCacheFilesNeededTransportFailure)347 TEST(DeviceTest, getNumberOfCacheFilesNeededTransportFailure) {
348 // setup call
349 const auto mockDevice = createMockDevice();
350 EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_))
351 .Times(1)
352 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
353
354 // run test
355 const auto result = Device::create(kName, mockDevice);
356
357 // verify result
358 ASSERT_FALSE(result.has_value());
359 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
360 }
361
TEST(DeviceTest,getNumberOfCacheFilesNeededDeadObject)362 TEST(DeviceTest, getNumberOfCacheFilesNeededDeadObject) {
363 // setup call
364 const auto mockDevice = createMockDevice();
365 EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_))
366 .Times(1)
367 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
368
369 // run test
370 const auto result = Device::create(kName, mockDevice);
371
372 // verify result
373 ASSERT_FALSE(result.has_value());
374 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
375 }
376
TEST(DeviceTest,getCapabilitiesError)377 TEST(DeviceTest, getCapabilitiesError) {
378 // setup call
379 const auto mockDevice = createMockDevice();
380 const auto ret = makeCallbackReturn(
381 V1_0::ErrorStatus::GENERAL_FAILURE,
382 V1_2::Capabilities{
383 .relaxedFloat32toFloat16PerformanceScalar = kNoPerformanceInfo,
384 .relaxedFloat32toFloat16PerformanceTensor = kNoPerformanceInfo,
385 });
386 EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)).Times(1).WillOnce(Invoke(ret));
387
388 // run test
389 const auto result = Device::create(kName, mockDevice);
390
391 // verify result
392 ASSERT_FALSE(result.has_value());
393 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
394 }
395
TEST(DeviceTest,getCapabilitiesTransportFailure)396 TEST(DeviceTest, getCapabilitiesTransportFailure) {
397 // setup call
398 const auto mockDevice = createMockDevice();
399 EXPECT_CALL(*mockDevice, getCapabilities_1_2(_))
400 .Times(1)
401 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
402
403 // run test
404 const auto result = Device::create(kName, mockDevice);
405
406 // verify result
407 ASSERT_FALSE(result.has_value());
408 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
409 }
410
TEST(DeviceTest,getCapabilitiesDeadObject)411 TEST(DeviceTest, getCapabilitiesDeadObject) {
412 // setup call
413 const auto mockDevice = createMockDevice();
414 EXPECT_CALL(*mockDevice, getCapabilities_1_2(_))
415 .Times(1)
416 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
417
418 // run test
419 const auto result = Device::create(kName, mockDevice);
420
421 // verify result
422 ASSERT_FALSE(result.has_value());
423 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
424 }
425
TEST(DeviceTest,linkToDeathError)426 TEST(DeviceTest, linkToDeathError) {
427 // setup call
428 const auto mockDevice = createMockDevice();
429 const auto ret = []() -> Return<bool> { return false; };
430 EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(1).WillOnce(InvokeWithoutArgs(ret));
431
432 // run test
433 const auto result = Device::create(kName, mockDevice);
434
435 // verify result
436 ASSERT_FALSE(result.has_value());
437 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
438 }
439
TEST(DeviceTest,linkToDeathTransportFailure)440 TEST(DeviceTest, linkToDeathTransportFailure) {
441 // setup call
442 const auto mockDevice = createMockDevice();
443 EXPECT_CALL(*mockDevice, linkToDeathRet())
444 .Times(1)
445 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
446
447 // run test
448 const auto result = Device::create(kName, mockDevice);
449
450 // verify result
451 ASSERT_FALSE(result.has_value());
452 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
453 }
454
TEST(DeviceTest,linkToDeathDeadObject)455 TEST(DeviceTest, linkToDeathDeadObject) {
456 // setup call
457 const auto mockDevice = createMockDevice();
458 EXPECT_CALL(*mockDevice, linkToDeathRet())
459 .Times(1)
460 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
461
462 // run test
463 const auto result = Device::create(kName, mockDevice);
464
465 // verify result
466 ASSERT_FALSE(result.has_value());
467 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
468 }
469
TEST(DeviceTest,getName)470 TEST(DeviceTest, getName) {
471 // setup call
472 const auto mockDevice = createMockDevice();
473 const auto device = Device::create(kName, mockDevice).value();
474
475 // run test
476 const auto& name = device->getName();
477
478 // verify result
479 EXPECT_EQ(name, kName);
480 }
481
TEST(DeviceTest,getFeatureLevel)482 TEST(DeviceTest, getFeatureLevel) {
483 // setup call
484 const auto mockDevice = createMockDevice();
485 const auto device = Device::create(kName, mockDevice).value();
486
487 // run test
488 const auto featureLevel = device->getFeatureLevel();
489
490 // verify result
491 EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel3);
492 }
493
TEST(DeviceTest,getCachedData)494 TEST(DeviceTest, getCachedData) {
495 // setup call
496 const auto mockDevice = createMockDevice();
497 EXPECT_CALL(*mockDevice, getVersionString(_)).Times(1);
498 EXPECT_CALL(*mockDevice, getType(_)).Times(1);
499 EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(1);
500 EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1);
501 EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)).Times(1);
502
503 const auto result = Device::create(kName, mockDevice);
504 ASSERT_TRUE(result.has_value())
505 << "Failed with " << result.error().code << ": " << result.error().message;
506 const auto& device = result.value();
507
508 // run test and verify results
509 EXPECT_EQ(device->getVersionString(), device->getVersionString());
510 EXPECT_EQ(device->getType(), device->getType());
511 EXPECT_EQ(device->getSupportedExtensions(), device->getSupportedExtensions());
512 EXPECT_EQ(device->getNumberOfCacheFilesNeeded(), device->getNumberOfCacheFilesNeeded());
513 EXPECT_EQ(device->getCapabilities(), device->getCapabilities());
514 }
515
TEST(DeviceTest,wait)516 TEST(DeviceTest, wait) {
517 // setup call
518 const auto mockDevice = createMockDevice();
519 const auto ret = []() -> Return<void> { return {}; };
520 EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(ret));
521 const auto device = Device::create(kName, mockDevice).value();
522
523 // run test
524 const auto result = device->wait();
525
526 // verify result
527 ASSERT_TRUE(result.has_value())
528 << "Failed with " << result.error().code << ": " << result.error().message;
529 }
530
TEST(DeviceTest,waitTransportFailure)531 TEST(DeviceTest, waitTransportFailure) {
532 // setup call
533 const auto mockDevice = createMockDevice();
534 EXPECT_CALL(*mockDevice, ping())
535 .Times(1)
536 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
537 const auto device = Device::create(kName, mockDevice).value();
538
539 // run test
540 const auto result = device->wait();
541
542 // verify result
543 ASSERT_FALSE(result.has_value());
544 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
545 }
546
TEST(DeviceTest,waitDeadObject)547 TEST(DeviceTest, waitDeadObject) {
548 // setup call
549 const auto mockDevice = createMockDevice();
550 EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
551 const auto device = Device::create(kName, mockDevice).value();
552
553 // run test
554 const auto result = device->wait();
555
556 // verify result
557 ASSERT_FALSE(result.has_value());
558 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
559 }
560
TEST(DeviceTest,getSupportedOperations)561 TEST(DeviceTest, getSupportedOperations) {
562 // setup call
563 const auto mockDevice = createMockDevice();
564 const auto device = Device::create(kName, mockDevice).value();
565 const auto ret = [](const auto& model, const auto& cb) {
566 cb(V1_0::ErrorStatus::NONE, std::vector<bool>(model.operations.size(), true));
567 return hardware::Void();
568 };
569 EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _)).Times(1).WillOnce(Invoke(ret));
570
571 // run test
572 const auto result = device->getSupportedOperations(kSimpleModel);
573
574 // verify result
575 ASSERT_TRUE(result.has_value())
576 << "Failed with " << result.error().code << ": " << result.error().message;
577 const auto& supportedOperations = result.value();
578 EXPECT_EQ(supportedOperations.size(), kSimpleModel.main.operations.size());
579 EXPECT_THAT(supportedOperations, Each(testing::IsTrue()));
580 }
581
TEST(DeviceTest,getSupportedOperationsError)582 TEST(DeviceTest, getSupportedOperationsError) {
583 // setup call
584 const auto mockDevice = createMockDevice();
585 const auto device = Device::create(kName, mockDevice).value();
586 const auto ret = [](const auto& /*model*/, const auto& cb) {
587 cb(V1_0::ErrorStatus::GENERAL_FAILURE, {});
588 return hardware::Void();
589 };
590 EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _)).Times(1).WillOnce(Invoke(ret));
591
592 // run test
593 const auto result = device->getSupportedOperations(kSimpleModel);
594
595 // verify result
596 ASSERT_FALSE(result.has_value());
597 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
598 }
599
TEST(DeviceTest,getSupportedOperationsTransportFailure)600 TEST(DeviceTest, getSupportedOperationsTransportFailure) {
601 // setup call
602 const auto mockDevice = createMockDevice();
603 const auto device = Device::create(kName, mockDevice).value();
604 EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _))
605 .Times(1)
606 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
607
608 // run test
609 const auto result = device->getSupportedOperations(kSimpleModel);
610
611 // verify result
612 ASSERT_FALSE(result.has_value());
613 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
614 }
615
TEST(DeviceTest,getSupportedOperationsDeadObject)616 TEST(DeviceTest, getSupportedOperationsDeadObject) {
617 // setup call
618 const auto mockDevice = createMockDevice();
619 const auto device = Device::create(kName, mockDevice).value();
620 EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _))
621 .Times(1)
622 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
623
624 // run test
625 const auto result = device->getSupportedOperations(kSimpleModel);
626
627 // verify result
628 ASSERT_FALSE(result.has_value());
629 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
630 }
631
TEST(DeviceTest,prepareModel)632 TEST(DeviceTest, prepareModel) {
633 // setup call
634 const auto mockDevice = createMockDevice();
635 const auto device = Device::create(kName, mockDevice).value();
636 const auto mockPreparedModel = MockPreparedModel::create();
637 EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _))
638 .Times(1)
639 .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE,
640 V1_0::ErrorStatus::NONE, mockPreparedModel)));
641
642 // run test
643 const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT,
644 nn::Priority::DEFAULT, {}, {}, {}, {}, {}, {});
645
646 // verify result
647 ASSERT_TRUE(result.has_value())
648 << "Failed with " << result.error().code << ": " << result.error().message;
649 EXPECT_NE(result.value(), nullptr);
650 }
651
TEST(DeviceTest,prepareModelLaunchError)652 TEST(DeviceTest, prepareModelLaunchError) {
653 // setup call
654 const auto mockDevice = createMockDevice();
655 const auto device = Device::create(kName, mockDevice).value();
656 EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _))
657 .Times(1)
658 .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::GENERAL_FAILURE,
659 V1_0::ErrorStatus::GENERAL_FAILURE, nullptr)));
660
661 // run test
662 const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT,
663 nn::Priority::DEFAULT, {}, {}, {}, {}, {}, {});
664
665 // verify result
666 ASSERT_FALSE(result.has_value());
667 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
668 }
669
TEST(DeviceTest,prepareModelReturnError)670 TEST(DeviceTest, prepareModelReturnError) {
671 // setup call
672 const auto mockDevice = createMockDevice();
673 const auto device = Device::create(kName, mockDevice).value();
674 EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _))
675 .Times(1)
676 .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE,
677 V1_0::ErrorStatus::GENERAL_FAILURE, nullptr)));
678
679 // run test
680 const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT,
681 nn::Priority::DEFAULT, {}, {}, {}, {}, {}, {});
682
683 // verify result
684 ASSERT_FALSE(result.has_value());
685 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
686 }
687
TEST(DeviceTest,prepareModelNullptrError)688 TEST(DeviceTest, prepareModelNullptrError) {
689 // setup call
690 const auto mockDevice = createMockDevice();
691 const auto device = Device::create(kName, mockDevice).value();
692 EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _))
693 .Times(1)
694 .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE,
695 V1_0::ErrorStatus::NONE, nullptr)));
696
697 // run test
698 const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT,
699 nn::Priority::DEFAULT, {}, {}, {}, {}, {}, {});
700
701 // verify result
702 ASSERT_FALSE(result.has_value());
703 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
704 }
705
TEST(DeviceTest,prepareModelTransportFailure)706 TEST(DeviceTest, prepareModelTransportFailure) {
707 // setup call
708 const auto mockDevice = createMockDevice();
709 const auto device = Device::create(kName, mockDevice).value();
710 EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _))
711 .Times(1)
712 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
713
714 // run test
715 const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT,
716 nn::Priority::DEFAULT, {}, {}, {}, {}, {}, {});
717
718 // verify result
719 ASSERT_FALSE(result.has_value());
720 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
721 }
722
TEST(DeviceTest,prepareModelDeadObject)723 TEST(DeviceTest, prepareModelDeadObject) {
724 // setup call
725 const auto mockDevice = createMockDevice();
726 const auto device = Device::create(kName, mockDevice).value();
727 EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _))
728 .Times(1)
729 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
730
731 // run test
732 const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT,
733 nn::Priority::DEFAULT, {}, {}, {}, {}, {}, {});
734
735 // verify result
736 ASSERT_FALSE(result.has_value());
737 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
738 }
739
TEST(DeviceTest,prepareModelAsyncCrash)740 TEST(DeviceTest, prepareModelAsyncCrash) {
741 // setup test
742 const auto mockDevice = createMockDevice();
743 const auto device = Device::create(kName, mockDevice).value();
744 const auto ret = [&mockDevice]() -> hardware::Return<V1_0::ErrorStatus> {
745 mockDevice->simulateCrash();
746 return V1_0::ErrorStatus::NONE;
747 };
748 EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _))
749 .Times(1)
750 .WillOnce(InvokeWithoutArgs(ret));
751
752 // run test
753 const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT,
754 nn::Priority::DEFAULT, {}, {}, {}, {}, {}, {});
755
756 // verify result
757 ASSERT_FALSE(result.has_value());
758 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
759 }
760
TEST(DeviceTest,prepareModelFromCache)761 TEST(DeviceTest, prepareModelFromCache) {
762 // setup call
763 const auto mockDevice = createMockDevice();
764 const auto device = Device::create(kName, mockDevice).value();
765 const auto mockPreparedModel = MockPreparedModel::create();
766 EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _))
767 .Times(1)
768 .WillOnce(Invoke(makePreparedModelFromCacheReturn(
769 V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::NONE, mockPreparedModel)));
770
771 // run test
772 const auto result = device->prepareModelFromCache({}, {}, {}, {});
773
774 // verify result
775 ASSERT_TRUE(result.has_value())
776 << "Failed with " << result.error().code << ": " << result.error().message;
777 EXPECT_NE(result.value(), nullptr);
778 }
779
TEST(DeviceTest,prepareModelFromCacheLaunchError)780 TEST(DeviceTest, prepareModelFromCacheLaunchError) {
781 // setup call
782 const auto mockDevice = createMockDevice();
783 const auto device = Device::create(kName, mockDevice).value();
784 EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _))
785 .Times(1)
786 .WillOnce(Invoke(makePreparedModelFromCacheReturn(V1_0::ErrorStatus::GENERAL_FAILURE,
787 V1_0::ErrorStatus::GENERAL_FAILURE,
788 nullptr)));
789
790 // run test
791 const auto result = device->prepareModelFromCache({}, {}, {}, {});
792
793 // verify result
794 ASSERT_FALSE(result.has_value());
795 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
796 }
797
TEST(DeviceTest,prepareModelFromCacheReturnError)798 TEST(DeviceTest, prepareModelFromCacheReturnError) {
799 // setup call
800 const auto mockDevice = createMockDevice();
801 const auto device = Device::create(kName, mockDevice).value();
802 EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _))
803 .Times(1)
804 .WillOnce(Invoke(makePreparedModelFromCacheReturn(
805 V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::GENERAL_FAILURE, nullptr)));
806
807 // run test
808 const auto result = device->prepareModelFromCache({}, {}, {}, {});
809
810 // verify result
811 ASSERT_FALSE(result.has_value());
812 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
813 }
814
TEST(DeviceTest,prepareModelFromCacheNullptrError)815 TEST(DeviceTest, prepareModelFromCacheNullptrError) {
816 // setup call
817 const auto mockDevice = createMockDevice();
818 const auto device = Device::create(kName, mockDevice).value();
819 EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _))
820 .Times(1)
821 .WillOnce(Invoke(makePreparedModelFromCacheReturn(V1_0::ErrorStatus::NONE,
822 V1_0::ErrorStatus::NONE, nullptr)));
823
824 // run test
825 const auto result = device->prepareModelFromCache({}, {}, {}, {});
826
827 // verify result
828 ASSERT_FALSE(result.has_value());
829 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
830 }
831
TEST(DeviceTest,prepareModelFromCacheTransportFailure)832 TEST(DeviceTest, prepareModelFromCacheTransportFailure) {
833 // setup call
834 const auto mockDevice = createMockDevice();
835 const auto device = Device::create(kName, mockDevice).value();
836 EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _))
837 .Times(1)
838 .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
839
840 // run test
841 const auto result = device->prepareModelFromCache({}, {}, {}, {});
842
843 // verify result
844 ASSERT_FALSE(result.has_value());
845 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
846 }
847
TEST(DeviceTest,prepareModelFromCacheDeadObject)848 TEST(DeviceTest, prepareModelFromCacheDeadObject) {
849 // setup call
850 const auto mockDevice = createMockDevice();
851 const auto device = Device::create(kName, mockDevice).value();
852 EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _))
853 .Times(1)
854 .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
855
856 // run test
857 const auto result = device->prepareModelFromCache({}, {}, {}, {});
858
859 // verify result
860 ASSERT_FALSE(result.has_value());
861 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
862 }
863
TEST(DeviceTest,prepareModelFromCacheAsyncCrash)864 TEST(DeviceTest, prepareModelFromCacheAsyncCrash) {
865 // setup test
866 const auto mockDevice = createMockDevice();
867 const auto device = Device::create(kName, mockDevice).value();
868 const auto ret = [&mockDevice]() -> hardware::Return<V1_0::ErrorStatus> {
869 mockDevice->simulateCrash();
870 return V1_0::ErrorStatus::NONE;
871 };
872 EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _))
873 .Times(1)
874 .WillOnce(InvokeWithoutArgs(ret));
875
876 // run test
877 const auto result = device->prepareModelFromCache({}, {}, {}, {});
878
879 // verify result
880 ASSERT_FALSE(result.has_value());
881 EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
882 }
883
TEST(DeviceTest,allocateNotSupported)884 TEST(DeviceTest, allocateNotSupported) {
885 // setup call
886 const auto mockDevice = createMockDevice();
887 const auto device = Device::create(kName, mockDevice).value();
888
889 // run test
890 const auto result = device->allocate({}, {}, {}, {});
891
892 // verify result
893 ASSERT_FALSE(result.has_value());
894 EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
895 }
896
897 } // namespace android::hardware::neuralnetworks::V1_2::utils
898