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