| /* |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "MockBuffer.h" |
| |
| #include <aidl/android/hardware/neuralnetworks/ErrorStatus.h> |
| #include <aidl/android/hardware/neuralnetworks/IBuffer.h> |
| #include <android/binder_auto_utils.h> |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| #include <nnapi/IBuffer.h> |
| #include <nnapi/SharedMemory.h> |
| #include <nnapi/TypeUtils.h> |
| #include <nnapi/Types.h> |
| #include <nnapi/hal/aidl/Buffer.h> |
| |
| #include <functional> |
| #include <memory> |
| |
| namespace aidl::android::hardware::neuralnetworks::utils { |
| namespace { |
| |
| using ::testing::_; |
| using ::testing::Invoke; |
| using ::testing::InvokeWithoutArgs; |
| using ::testing::Return; |
| |
| const auto kMemory = nn::createSharedMemory(4).value(); |
| const std::shared_ptr<IBuffer> kInvalidBuffer; |
| constexpr auto kInvalidToken = nn::Request::MemoryDomainToken{0}; |
| constexpr auto kToken = nn::Request::MemoryDomainToken{1}; |
| |
| constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); }; |
| |
| constexpr auto makeGeneralFailure = [] { |
| return ndk::ScopedAStatus::fromServiceSpecificError( |
| static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE)); |
| }; |
| constexpr auto makeGeneralTransportFailure = [] { |
| return ndk::ScopedAStatus::fromStatus(STATUS_NO_MEMORY); |
| }; |
| constexpr auto makeDeadObjectFailure = [] { |
| return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT); |
| }; |
| |
| } // namespace |
| |
| TEST(BufferTest, invalidBuffer) { |
| // run test |
| const auto result = Buffer::create(kInvalidBuffer, kToken); |
| |
| // verify result |
| ASSERT_FALSE(result.has_value()); |
| EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); |
| } |
| |
| TEST(BufferTest, invalidToken) { |
| // setup call |
| const auto mockBuffer = MockBuffer::create(); |
| |
| // run test |
| const auto result = Buffer::create(mockBuffer, kInvalidToken); |
| |
| // verify result |
| ASSERT_FALSE(result.has_value()); |
| EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); |
| } |
| |
| TEST(BufferTest, create) { |
| // setup call |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| |
| // run test |
| const auto token = buffer->getToken(); |
| |
| // verify result |
| EXPECT_EQ(token, kToken); |
| } |
| |
| TEST(BufferTest, copyTo) { |
| // setup call |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeStatusOk)); |
| |
| // run test |
| const auto result = buffer->copyTo(kMemory); |
| |
| // verify result |
| EXPECT_TRUE(result.has_value()) << result.error().message; |
| } |
| |
| TEST(BufferTest, copyToError) { |
| // setup test |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeGeneralFailure)); |
| |
| // run test |
| const auto result = buffer->copyTo(kMemory); |
| |
| // verify result |
| ASSERT_FALSE(result.has_value()); |
| EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); |
| } |
| |
| TEST(BufferTest, copyToTransportFailure) { |
| // setup test |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| EXPECT_CALL(*mockBuffer, copyTo(_)) |
| .Times(1) |
| .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); |
| |
| // run test |
| const auto result = buffer->copyTo(kMemory); |
| |
| // verify result |
| ASSERT_FALSE(result.has_value()); |
| EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); |
| } |
| |
| TEST(BufferTest, copyToDeadObject) { |
| // setup test |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); |
| |
| // run test |
| const auto result = buffer->copyTo(kMemory); |
| |
| // verify result |
| ASSERT_FALSE(result.has_value()); |
| EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); |
| } |
| |
| TEST(BufferTest, copyFrom) { |
| // setup call |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| EXPECT_CALL(*mockBuffer, copyFrom(_, _)).Times(1).WillOnce(InvokeWithoutArgs(makeStatusOk)); |
| |
| // run test |
| const auto result = buffer->copyFrom(kMemory, {}); |
| |
| // verify result |
| EXPECT_TRUE(result.has_value()); |
| } |
| |
| TEST(BufferTest, copyFromError) { |
| // setup test |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| EXPECT_CALL(*mockBuffer, copyFrom(_, _)) |
| .Times(1) |
| .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); |
| |
| // run test |
| const auto result = buffer->copyFrom(kMemory, {}); |
| |
| // verify result |
| ASSERT_FALSE(result.has_value()); |
| EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); |
| } |
| |
| TEST(BufferTest, copyFromTransportFailure) { |
| // setup test |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| EXPECT_CALL(*mockBuffer, copyFrom(_, _)) |
| .Times(1) |
| .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); |
| |
| // run test |
| const auto result = buffer->copyFrom(kMemory, {}); |
| |
| // verify result |
| ASSERT_FALSE(result.has_value()); |
| EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); |
| } |
| |
| TEST(BufferTest, copyFromDeadObject) { |
| // setup test |
| const auto mockBuffer = MockBuffer::create(); |
| const auto buffer = Buffer::create(mockBuffer, kToken).value(); |
| EXPECT_CALL(*mockBuffer, copyFrom(_, _)) |
| .Times(1) |
| .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); |
| |
| // run test |
| const auto result = buffer->copyFrom(kMemory, {}); |
| |
| // verify result |
| ASSERT_FALSE(result.has_value()); |
| EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); |
| } |
| |
| } // namespace aidl::android::hardware::neuralnetworks::utils |