//
// Copyright 2018 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 "hidl_handle_driver/VtsHidlHandleDriver.h"
#include <errno.h>
#include <fcntl.h>
#include <gtest/gtest.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
using namespace std;
static constexpr const char* kTestFilePath = "/data/local/tmp/test.txt";
namespace android {
namespace vts {
// Unit test to test operations on hidl_memory_driver.
class HidlHandleDriverUnitTest : public ::testing::Test {
protected:
virtual void SetUp() {
// Register handle objects.
client1_id_ = handle_driver_.CreateFileHandle(string(kTestFilePath),
O_RDWR | O_CREAT | O_TRUNC,
S_IRWXG, vector<int>());
client2_id_ = handle_driver_.CreateFileHandle(string(kTestFilePath),
O_RDONLY, 0, vector<int>());
ASSERT_NE(client1_id_, -1);
ASSERT_NE(client2_id_, -1);
}
virtual void TearDown() {
ASSERT_TRUE(handle_driver_.UnregisterHidlHandle(client1_id_));
ASSERT_TRUE(handle_driver_.UnregisterHidlHandle(client2_id_));
// Delete files for testing.
remove(kTestFilePath);
}
VtsHidlHandleDriver handle_driver_;
int client1_id_;
int client2_id_;
};
// Tests trying to write to an invalid handle object.
TEST_F(HidlHandleDriverUnitTest, InvalidHandleId) {
// Invalid ID: 42, tries to read 10 bytes.
ASSERT_EQ(handle_driver_.WriteFile(42, nullptr, 10), -1);
}
// Tests reader doesn't have the permission to edit test.txt.
TEST_F(HidlHandleDriverUnitTest, ReaderInvalidWrite) {
char write_data[10];
ASSERT_EQ(handle_driver_.WriteFile(client2_id_, write_data, 10), -1);
}
// Tests unregistering a handle and using that handle after returns error.
TEST_F(HidlHandleDriverUnitTest, UnregisterHandle) {
int new_id = handle_driver_.CreateFileHandle(string(kTestFilePath), O_RDONLY,
0, vector<int>());
// Reading 0 bytes should work, because handle object is found.
ASSERT_EQ(handle_driver_.ReadFile(new_id, nullptr, 0), 0);
// Now unregister the handle.
ASSERT_TRUE(handle_driver_.UnregisterHidlHandle(new_id));
// Read 0 bytes again, this time should fail because handle object is deleted.
ASSERT_EQ(handle_driver_.ReadFile(new_id, nullptr, 0), -1);
}
// Tests simple read/write operations on the same file from two clients.
TEST_F(HidlHandleDriverUnitTest, SimpleReadWrite) {
string write_data = "Hello World!";
// Writer writes to test.txt.
ASSERT_EQ(handle_driver_.WriteFile(
client1_id_, static_cast<const void*>(write_data.c_str()),
write_data.length()),
write_data.length());
// Reader reads from test.txt.
char read_data[write_data.length()];
ASSERT_EQ(handle_driver_.ReadFile(client2_id_, static_cast<void*>(read_data),
write_data.length()),
write_data.length());
ASSERT_TRUE(write_data == string(read_data, write_data.length()));
}
// Tests large read/write interaction between reader and writer.
// Writer keeps adding "abcd" at the end of the file.
// After every iteration, reader should read back one extra repeated "abcd".
TEST_F(HidlHandleDriverUnitTest, LargeReadWrite) {
static constexpr size_t NUM_ITERS = 10;
const string write_data = "abcd";
string curr_correct_data = "";
char read_data[write_data.length() * NUM_ITERS];
char* curr_read_data_ptr = read_data;
for (int i = 0; i < NUM_ITERS; i++) {
// Writer writes to test1.txt.
ASSERT_EQ(handle_driver_.WriteFile(
client1_id_, static_cast<const void*>(write_data.c_str()),
write_data.length()),
write_data.length());
// Reader reads from test1.txt.
ASSERT_EQ(handle_driver_.ReadFile(client2_id_,
static_cast<void*>(curr_read_data_ptr),
write_data.length()),
write_data.length());
string curr_read_data = string(read_data, write_data.length() * (i + 1));
curr_correct_data += write_data;
curr_read_data_ptr += write_data.length();
ASSERT_TRUE(curr_read_data == curr_correct_data);
}
}
} // namespace vts
} // namespace android