xref: /aosp_15_r20/hardware/interfaces/neuralnetworks/1.2/utils/test/DeviceTest.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
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