1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "MockBuffer.h"
18 
19 #include <aidl/android/hardware/neuralnetworks/ErrorStatus.h>
20 #include <aidl/android/hardware/neuralnetworks/IBuffer.h>
21 #include <android/binder_auto_utils.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include <nnapi/IBuffer.h>
25 #include <nnapi/SharedMemory.h>
26 #include <nnapi/TypeUtils.h>
27 #include <nnapi/Types.h>
28 #include <nnapi/hal/aidl/Buffer.h>
29 
30 #include <functional>
31 #include <memory>
32 
33 namespace aidl::android::hardware::neuralnetworks::utils {
34 namespace {
35 
36 using ::testing::_;
37 using ::testing::Invoke;
38 using ::testing::InvokeWithoutArgs;
39 using ::testing::Return;
40 
41 const auto kMemory = nn::createSharedMemory(4).value();
42 const std::shared_ptr<IBuffer> kInvalidBuffer;
43 constexpr auto kInvalidToken = nn::Request::MemoryDomainToken{0};
44 constexpr auto kToken = nn::Request::MemoryDomainToken{1};
45 
__anond089dc450202null46 constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); };
47 
__anond089dc450302null48 constexpr auto makeGeneralFailure = [] {
49     return ndk::ScopedAStatus::fromServiceSpecificError(
50             static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
51 };
__anond089dc450402null52 constexpr auto makeGeneralTransportFailure = [] {
53     return ndk::ScopedAStatus::fromStatus(STATUS_NO_MEMORY);
54 };
__anond089dc450502null55 constexpr auto makeDeadObjectFailure = [] {
56     return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT);
57 };
58 
59 }  // namespace
60 
TEST(BufferTest,invalidBuffer)61 TEST(BufferTest, invalidBuffer) {
62     // run test
63     const auto result = Buffer::create(kInvalidBuffer, kToken);
64 
65     // verify result
66     ASSERT_FALSE(result.has_value());
67     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
68 }
69 
TEST(BufferTest,invalidToken)70 TEST(BufferTest, invalidToken) {
71     // setup call
72     const auto mockBuffer = MockBuffer::create();
73 
74     // run test
75     const auto result = Buffer::create(mockBuffer, kInvalidToken);
76 
77     // verify result
78     ASSERT_FALSE(result.has_value());
79     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
80 }
81 
TEST(BufferTest,create)82 TEST(BufferTest, create) {
83     // setup call
84     const auto mockBuffer = MockBuffer::create();
85     const auto buffer = Buffer::create(mockBuffer, kToken).value();
86 
87     // run test
88     const auto token = buffer->getToken();
89 
90     // verify result
91     EXPECT_EQ(token, kToken);
92 }
93 
TEST(BufferTest,copyTo)94 TEST(BufferTest, copyTo) {
95     // setup call
96     const auto mockBuffer = MockBuffer::create();
97     const auto buffer = Buffer::create(mockBuffer, kToken).value();
98     EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeStatusOk));
99 
100     // run test
101     const auto result = buffer->copyTo(kMemory);
102 
103     // verify result
104     EXPECT_TRUE(result.has_value()) << result.error().message;
105 }
106 
TEST(BufferTest,copyToError)107 TEST(BufferTest, copyToError) {
108     // setup test
109     const auto mockBuffer = MockBuffer::create();
110     const auto buffer = Buffer::create(mockBuffer, kToken).value();
111     EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeGeneralFailure));
112 
113     // run test
114     const auto result = buffer->copyTo(kMemory);
115 
116     // verify result
117     ASSERT_FALSE(result.has_value());
118     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
119 }
120 
TEST(BufferTest,copyToTransportFailure)121 TEST(BufferTest, copyToTransportFailure) {
122     // setup test
123     const auto mockBuffer = MockBuffer::create();
124     const auto buffer = Buffer::create(mockBuffer, kToken).value();
125     EXPECT_CALL(*mockBuffer, copyTo(_))
126             .Times(1)
127             .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
128 
129     // run test
130     const auto result = buffer->copyTo(kMemory);
131 
132     // verify result
133     ASSERT_FALSE(result.has_value());
134     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
135 }
136 
TEST(BufferTest,copyToDeadObject)137 TEST(BufferTest, copyToDeadObject) {
138     // setup test
139     const auto mockBuffer = MockBuffer::create();
140     const auto buffer = Buffer::create(mockBuffer, kToken).value();
141     EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
142 
143     // run test
144     const auto result = buffer->copyTo(kMemory);
145 
146     // verify result
147     ASSERT_FALSE(result.has_value());
148     EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
149 }
150 
TEST(BufferTest,copyFrom)151 TEST(BufferTest, copyFrom) {
152     // setup call
153     const auto mockBuffer = MockBuffer::create();
154     const auto buffer = Buffer::create(mockBuffer, kToken).value();
155     EXPECT_CALL(*mockBuffer, copyFrom(_, _)).Times(1).WillOnce(InvokeWithoutArgs(makeStatusOk));
156 
157     // run test
158     const auto result = buffer->copyFrom(kMemory, {});
159 
160     // verify result
161     EXPECT_TRUE(result.has_value());
162 }
163 
TEST(BufferTest,copyFromError)164 TEST(BufferTest, copyFromError) {
165     // setup test
166     const auto mockBuffer = MockBuffer::create();
167     const auto buffer = Buffer::create(mockBuffer, kToken).value();
168     EXPECT_CALL(*mockBuffer, copyFrom(_, _))
169             .Times(1)
170             .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
171 
172     // run test
173     const auto result = buffer->copyFrom(kMemory, {});
174 
175     // verify result
176     ASSERT_FALSE(result.has_value());
177     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
178 }
179 
TEST(BufferTest,copyFromTransportFailure)180 TEST(BufferTest, copyFromTransportFailure) {
181     // setup test
182     const auto mockBuffer = MockBuffer::create();
183     const auto buffer = Buffer::create(mockBuffer, kToken).value();
184     EXPECT_CALL(*mockBuffer, copyFrom(_, _))
185             .Times(1)
186             .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
187 
188     // run test
189     const auto result = buffer->copyFrom(kMemory, {});
190 
191     // verify result
192     ASSERT_FALSE(result.has_value());
193     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
194 }
195 
TEST(BufferTest,copyFromDeadObject)196 TEST(BufferTest, copyFromDeadObject) {
197     // setup test
198     const auto mockBuffer = MockBuffer::create();
199     const auto buffer = Buffer::create(mockBuffer, kToken).value();
200     EXPECT_CALL(*mockBuffer, copyFrom(_, _))
201             .Times(1)
202             .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
203 
204     // run test
205     const auto result = buffer->copyFrom(kMemory, {});
206 
207     // verify result
208     ASSERT_FALSE(result.has_value());
209     EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
210 }
211 
212 }  // namespace aidl::android::hardware::neuralnetworks::utils
213