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