read_file_unittest.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <string> 6 7#include "base/files/file.h" 8#include "base/files/file_path.h" 9#include "base/memory/ref_counted.h" 10#include "base/memory/scoped_ptr.h" 11#include "base/memory/scoped_vector.h" 12#include "base/values.h" 13#include "chrome/browser/chromeos/file_system_provider/operations/read_file.h" 14#include "chrome/common/extensions/api/file_system_provider.h" 15#include "chrome/common/extensions/api/file_system_provider_internal.h" 16#include "extensions/browser/event_router.h" 17#include "net/base/io_buffer.h" 18#include "testing/gtest/include/gtest/gtest.h" 19#include "webkit/browser/fileapi/async_file_util.h" 20 21namespace chromeos { 22namespace file_system_provider { 23namespace operations { 24namespace { 25 26const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj"; 27const char kFileSystemId[] = "testing-file-system"; 28const int kRequestId = 2; 29const int kFileHandle = 3; 30const int kOffset = 10; 31const int kLength = 5; 32 33// Fake event dispatcher implementation with extra logging capability. Acts as 34// a providing extension end-point. 35class LoggingDispatchEventImpl { 36 public: 37 explicit LoggingDispatchEventImpl(bool dispatch_reply) 38 : dispatch_reply_(dispatch_reply) {} 39 virtual ~LoggingDispatchEventImpl() {} 40 41 bool OnDispatchEventImpl(scoped_ptr<extensions::Event> event) { 42 events_.push_back(event->DeepCopy()); 43 return dispatch_reply_; 44 } 45 46 ScopedVector<extensions::Event>& events() { return events_; } 47 48 private: 49 ScopedVector<extensions::Event> events_; 50 bool dispatch_reply_; 51 52 DISALLOW_COPY_AND_ASSIGN(LoggingDispatchEventImpl); 53}; 54 55// Callback invocation logger. Acts as a fileapi end-point. 56class CallbackLogger { 57 public: 58 class Event { 59 public: 60 Event(int chunk_length, bool has_more, base::File::Error result) 61 : chunk_length_(chunk_length), has_more_(has_more), result_(result) {} 62 virtual ~Event() {} 63 64 int chunk_length() const { return chunk_length_; } 65 bool has_more() const { return has_more_; } 66 base::File::Error result() const { return result_; } 67 68 private: 69 int chunk_length_; 70 bool has_more_; 71 base::File::Error result_; 72 73 DISALLOW_COPY_AND_ASSIGN(Event); 74 }; 75 76 CallbackLogger() : weak_ptr_factory_(this) {} 77 virtual ~CallbackLogger() {} 78 79 void OnReadFile(int chunk_length, bool has_more, base::File::Error result) { 80 events_.push_back(new Event(chunk_length, has_more, result)); 81 } 82 83 ScopedVector<Event>& events() { return events_; } 84 85 base::WeakPtr<CallbackLogger> GetWeakPtr() { 86 return weak_ptr_factory_.GetWeakPtr(); 87 } 88 89 private: 90 ScopedVector<Event> events_; 91 bool dispatch_reply_; 92 base::WeakPtrFactory<CallbackLogger> weak_ptr_factory_; 93 94 DISALLOW_COPY_AND_ASSIGN(CallbackLogger); 95}; 96 97} // namespace 98 99class FileSystemProviderOperationsReadFileTest : public testing::Test { 100 protected: 101 FileSystemProviderOperationsReadFileTest() {} 102 virtual ~FileSystemProviderOperationsReadFileTest() {} 103 104 virtual void SetUp() OVERRIDE { 105 file_system_info_ = 106 ProvidedFileSystemInfo(kExtensionId, 107 kFileSystemId, 108 "" /* file_system_name */, 109 base::FilePath() /* mount_path */); 110 io_buffer_ = make_scoped_refptr(new net::IOBuffer(kOffset + kLength)); 111 } 112 113 ProvidedFileSystemInfo file_system_info_; 114 scoped_refptr<net::IOBuffer> io_buffer_; 115}; 116 117TEST_F(FileSystemProviderOperationsReadFileTest, Execute) { 118 LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); 119 CallbackLogger callback_logger; 120 121 ReadFile read_file( 122 NULL, 123 file_system_info_, 124 kFileHandle, 125 io_buffer_.get(), 126 kOffset, 127 kLength, 128 base::Bind(&CallbackLogger::OnReadFile, callback_logger.GetWeakPtr())); 129 read_file.SetDispatchEventImplForTesting( 130 base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl, 131 base::Unretained(&dispatcher))); 132 133 EXPECT_TRUE(read_file.Execute(kRequestId)); 134 135 ASSERT_EQ(1u, dispatcher.events().size()); 136 extensions::Event* event = dispatcher.events()[0]; 137 EXPECT_EQ( 138 extensions::api::file_system_provider::OnReadFileRequested::kEventName, 139 event->event_name); 140 base::ListValue* event_args = event->event_args.get(); 141 ASSERT_EQ(5u, event_args->GetSize()); 142 143 std::string event_file_system_id; 144 EXPECT_TRUE(event_args->GetString(0, &event_file_system_id)); 145 EXPECT_EQ(kFileSystemId, event_file_system_id); 146 147 int event_request_id = -1; 148 EXPECT_TRUE(event_args->GetInteger(1, &event_request_id)); 149 EXPECT_EQ(kRequestId, event_request_id); 150 151 int event_file_handle = -1; 152 EXPECT_TRUE(event_args->GetInteger(2, &event_file_handle)); 153 EXPECT_EQ(kFileHandle, event_file_handle); 154 155 double event_offset = -1; 156 EXPECT_TRUE(event_args->GetDouble(3, &event_offset)); 157 EXPECT_EQ(kOffset, static_cast<double>(event_offset)); 158 159 int event_length = -1; 160 EXPECT_TRUE(event_args->GetInteger(4, &event_length)); 161 EXPECT_EQ(kLength, event_length); 162} 163 164TEST_F(FileSystemProviderOperationsReadFileTest, Execute_NoListener) { 165 LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */); 166 CallbackLogger callback_logger; 167 168 ReadFile read_file( 169 NULL, 170 file_system_info_, 171 kFileHandle, 172 io_buffer_.get(), 173 kOffset, 174 kLength, 175 base::Bind(&CallbackLogger::OnReadFile, callback_logger.GetWeakPtr())); 176 read_file.SetDispatchEventImplForTesting( 177 base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl, 178 base::Unretained(&dispatcher))); 179 180 EXPECT_FALSE(read_file.Execute(kRequestId)); 181} 182 183TEST_F(FileSystemProviderOperationsReadFileTest, OnSuccess) { 184 using extensions::api::file_system_provider_internal:: 185 ReadFileRequestedSuccess::Params; 186 187 LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); 188 CallbackLogger callback_logger; 189 190 ReadFile read_file( 191 NULL, 192 file_system_info_, 193 kFileHandle, 194 io_buffer_.get(), 195 kOffset, 196 kLength, 197 base::Bind(&CallbackLogger::OnReadFile, callback_logger.GetWeakPtr())); 198 read_file.SetDispatchEventImplForTesting( 199 base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl, 200 base::Unretained(&dispatcher))); 201 202 EXPECT_TRUE(read_file.Execute(kRequestId)); 203 204 const std::string data = "ABCDE"; 205 const bool has_more = false; 206 207 base::ListValue value_as_list; 208 value_as_list.Set(0, new base::StringValue(kFileSystemId)); 209 value_as_list.Set(1, new base::FundamentalValue(kRequestId)); 210 value_as_list.Set( 211 2, base::BinaryValue::CreateWithCopiedBuffer(data.c_str(), data.size())); 212 value_as_list.Set(3, new base::FundamentalValue(has_more)); 213 214 scoped_ptr<Params> params(Params::Create(value_as_list)); 215 ASSERT_TRUE(params.get()); 216 scoped_ptr<RequestValue> request_value( 217 RequestValue::CreateForReadFileSuccess(params.Pass())); 218 ASSERT_TRUE(request_value.get()); 219 220 read_file.OnSuccess(kRequestId, request_value.Pass(), has_more); 221 222 ASSERT_EQ(1u, callback_logger.events().size()); 223 CallbackLogger::Event* event = callback_logger.events()[0]; 224 EXPECT_EQ(kLength, event->chunk_length()); 225 EXPECT_FALSE(event->has_more()); 226 EXPECT_EQ(data, std::string(io_buffer_->data(), kLength)); 227 EXPECT_EQ(base::File::FILE_OK, event->result()); 228} 229 230TEST_F(FileSystemProviderOperationsReadFileTest, OnError) { 231 using extensions::api::file_system_provider_internal::ReadFileRequestedError:: 232 Params; 233 234 LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); 235 CallbackLogger callback_logger; 236 237 ReadFile read_file( 238 NULL, 239 file_system_info_, 240 kFileHandle, 241 io_buffer_.get(), 242 kOffset, 243 kLength, 244 base::Bind(&CallbackLogger::OnReadFile, callback_logger.GetWeakPtr())); 245 read_file.SetDispatchEventImplForTesting( 246 base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl, 247 base::Unretained(&dispatcher))); 248 249 EXPECT_TRUE(read_file.Execute(kRequestId)); 250 251 read_file.OnError(kRequestId, base::File::FILE_ERROR_TOO_MANY_OPENED); 252 253 ASSERT_EQ(1u, callback_logger.events().size()); 254 CallbackLogger::Event* event = callback_logger.events()[0]; 255 EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, event->result()); 256} 257 258} // namespace operations 259} // namespace file_system_provider 260} // namespace chromeos 261