blob: d7befa8d1a3bd1e7a35c87aeea5ca6c306c184f0 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mtpd/device_manager.h"
#include <string>
#include <vector>
#include <gtest/gtest.h>
#include <base/compiler_specific.h>
#include <base/stl_util.h>
#include <base/test/task_environment.h>
#include "mtpd/device_event_delegate.h"
namespace mtpd {
namespace {
class DeviceManagerTest : public testing::Test {
public:
DeviceManagerTest() = default;
DeviceManagerTest(const DeviceManagerTest&) = delete;
DeviceManagerTest& operator=(const DeviceManagerTest&) = delete;
private:
// DeviceManager needs the current thread to have a task runner.
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
};
TEST_F(DeviceManagerTest, ParseStorageName) {
struct ParseStorageNameTestCase {
const char* input;
bool expected_result;
const char* expected_bus;
uint32_t expected_storage_id;
} test_cases[] = {
{"usb:123:4", true, "usb:123", 4},
{"usb:1,2,3:4", true, "usb:1,2,3", 4},
{"notusb:123:4", false, "", 0},
{"usb:123:4:badfield", false, "", 0},
{"usb:123:not_number", false, "", 0},
};
for (size_t i = 0; i < base::size(test_cases); ++i) {
std::string bus;
uint32_t storage_id = static_cast<uint32_t>(-1);
bool result =
DeviceManager::ParseStorageName(test_cases[i].input, &bus, &storage_id);
EXPECT_EQ(test_cases[i].expected_result, result);
if (test_cases[i].expected_result) {
EXPECT_EQ(test_cases[i].expected_bus, bus);
EXPECT_EQ(test_cases[i].expected_storage_id, storage_id);
}
}
}
class TestDeviceEventDelegate : public DeviceEventDelegate {
public:
TestDeviceEventDelegate() {}
TestDeviceEventDelegate(const TestDeviceEventDelegate&) = delete;
TestDeviceEventDelegate& operator=(const TestDeviceEventDelegate&) = delete;
~TestDeviceEventDelegate() {}
// DeviceEventDelegate implementation.
void StorageAttached(const std::string& storage_name) override {}
void StorageDetached(const std::string& storage_name) override {}
};
class TestDeviceManager : public DeviceManager {
public:
explicit TestDeviceManager(DeviceEventDelegate* delegate)
: DeviceManager(delegate) {}
TestDeviceManager(const TestDeviceManager&) = delete;
TestDeviceManager& operator=(const TestDeviceManager&) = delete;
~TestDeviceManager() {}
bool AddStorage(const std::string& storage_name,
const StorageInfo& storage_info) {
return AddStorageForTest(storage_name, storage_info);
}
};
// Devices do not actually have a root node, so one is synthesized.
TEST_F(DeviceManagerTest, GetFileInfoForSynthesizedRootNode) {
const std::string kDummyStorageName = "usb:1,2:65432";
StorageInfo dummy_storage_info;
TestDeviceEventDelegate dummy_device_event_delegate;
TestDeviceManager device_manager(&dummy_device_event_delegate);
bool ret = device_manager.AddStorage(kDummyStorageName, dummy_storage_info);
EXPECT_TRUE(ret);
std::vector<FileEntry> file_entries;
std::vector<uint32_t> file_ids;
file_ids.push_back(0);
ret = device_manager.GetFileInfo(kDummyStorageName, file_ids, &file_entries);
EXPECT_TRUE(ret);
ASSERT_EQ(1U, file_entries.size());
const FileEntry& file_entry = file_entries[0];
EXPECT_EQ(0, file_entry.item_id());
EXPECT_EQ(0, file_entry.parent_id());
EXPECT_EQ("/", file_entry.file_name());
EXPECT_EQ(0, file_entry.file_size());
EXPECT_EQ(0, file_entry.modification_time());
EXPECT_EQ(LIBMTP_FILETYPE_FOLDER, file_entry.file_type());
}
// Devices do not actually have a root node, and it is not possible to read
// from the synthesized one.
TEST_F(DeviceManagerTest, ReadFileFromSynthesizedRootNodeFails) {
const std::string kDummyStorageName = "usb:1,2:65432";
StorageInfo dummy_storage_info;
TestDeviceEventDelegate dummy_device_event_delegate;
TestDeviceManager device_manager(&dummy_device_event_delegate);
bool ret = device_manager.AddStorage(kDummyStorageName, dummy_storage_info);
EXPECT_TRUE(ret);
std::vector<uint8_t> data;
ret = device_manager.ReadFileChunk(kDummyStorageName, 0 /* node id */,
0 /* offset */, 1 /* byte */, &data);
EXPECT_FALSE(ret);
EXPECT_TRUE(data.empty());
}
} // namespace
} // namespace mtpd