15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <errno.h> 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <fcntl.h> 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <set> 968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <string> 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <gmock/gmock.h> 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <ppapi/c/ppb_file_io.h> 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <ppapi/c/pp_directory_entry.h> 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <ppapi/c/pp_errors.h> 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <ppapi/c/pp_instance.h> 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(WIN32) 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <windows.h> // For Sleep() 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "fake_ppapi/fake_pepper_interface_html5_fs.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "nacl_io/kernel_handle.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/html5fs/html5_fs.h" 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "nacl_io/osdirent.h" 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "nacl_io/osunistd.h" 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "nacl_io/pepper_interface_delegate.h" 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "sdk_util/scoped_ref.h" 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "mock_util.h" 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "pepper_interface_mock.h" 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using namespace nacl_io; 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using namespace sdk_util; 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::_; 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::DoAll; 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::Invoke; 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::Mock; 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::Return; 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace { 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Html5FsForTesting : public Html5Fs { 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Html5FsForTesting(StringMap_t& string_map, PepperInterface* ppapi, 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int expected_error = 0) { 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsInitArgs args; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.string_map = string_map; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.ppapi = ppapi; 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = Init(args); 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(expected_error, error); 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool Exists(const char* filename) { 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedNode node; 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (Open(Path(filename), O_RDONLY, &node)) 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct stat buf; 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return node->GetStat(&buf) == 0; 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Html5FsTest : public ::testing::Test { 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Html5FsTest(); 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) protected: 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FakePepperInterfaceHtml5Fs ppapi_html5_; 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PepperInterfaceMock ppapi_mock_; 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PepperInterfaceDelegate ppapi_; 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Html5FsTest::Html5FsTest() 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : ppapi_mock_(ppapi_html5_.GetInstance()), 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_(ppapi_html5_.GetInstance()) { 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Default delegation to the html5 pepper interface. 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_.SetCoreInterfaceDelegate(ppapi_html5_.GetCoreInterface()); 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_.SetFileSystemInterfaceDelegate(ppapi_html5_.GetFileSystemInterface()); 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_.SetFileRefInterfaceDelegate(ppapi_html5_.GetFileRefInterface()); 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_.SetFileIoInterfaceDelegate(ppapi_html5_.GetFileIoInterface()); 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_.SetVarInterfaceDelegate(ppapi_html5_.GetVarInterface()); 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, FilesystemType) { 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* filesystem_type_strings[] = {"", "PERSISTENT", "TEMPORARY", NULL}; 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_FileSystemType filesystem_type_values[] = { 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_FILESYSTEMTYPE_LOCALPERSISTENT, // Default to persistent. 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_FILESYSTEMTYPE_LOCALPERSISTENT, PP_FILESYSTEMTYPE_LOCALTEMPORARY}; 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* expected_size_strings[] = {"100", "12345", NULL}; 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const int expected_size_values[] = {100, 12345}; 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FileSystemInterfaceMock* filesystem_mock = 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_mock_.GetFileSystemInterface(); 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FakeFileSystemInterface* filesystem_fake = 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<FakeFileSystemInterface*>( 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_html5_.GetFileSystemInterface()); 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (int i = 0; filesystem_type_strings[i] != NULL; ++i) { 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* filesystem_type_string = filesystem_type_strings[i]; 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_FileSystemType expected_filesystem_type = filesystem_type_values[i]; 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (int j = 0; expected_size_strings[j] != NULL; ++j) { 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* expected_size_string = expected_size_strings[j]; 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64_t expected_expected_size = expected_size_values[j]; 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_.SetFileSystemInterfaceDelegate(filesystem_mock); 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ON_CALL(*filesystem_mock, Create(_, _)).WillByDefault( 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Invoke(filesystem_fake, &FakeFileSystemInterface::Create)); 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*filesystem_mock, 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Create(ppapi_.GetInstance(), expected_filesystem_type)); 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_CALL(*filesystem_mock, Open(_, expected_expected_size, _)) 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) .WillOnce(DoAll(CallCallback<2>(int32_t(PP_OK)), 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Return(int32_t(PP_OK_COMPLETIONPENDING)))); 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) map["type"] = filesystem_type_string; 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) map["expected_size"] = expected_size_string; 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Mock::VerifyAndClearExpectations(&filesystem_mock); 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(Html5FsTest, PassFilesystemResource) { 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Fail if given a bad resource. 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) { 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StringMap_t map; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) map["filesystem_resource"] = "0"; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs( 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new Html5FsForTesting(map, &ppapi_, EINVAL)); 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) { 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddEmptyFile("/foo", NULL)); 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PP_Resource filesystem = ppapi_html5_.GetFileSystemInterface()->Create( 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ppapi_html5_.GetInstance(), PP_FILESYSTEMTYPE_LOCALPERSISTENT); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_EQ(int32_t(PP_OK), ppapi_html5_.GetFileSystemInterface()->Open( 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) filesystem, 0, PP_BlockUntilComplete())); 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StringMap_t map; 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) char buffer[30]; 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) snprintf(buffer, 30, "%d", filesystem); 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) map["filesystem_resource"] = buffer; 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs( 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new Html5FsForTesting(map, &ppapi_)); 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(fs->Exists("/foo")); 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ppapi_html5_.GetCoreInterface()->ReleaseResource(filesystem); 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(Html5FsTest, MountSubtree) { 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddEmptyFile("/foo/bar", 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NULL)); 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) StringMap_t map; 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) map["SOURCE"] = "/foo"; 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(fs->Exists("/bar")); 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_FALSE(fs->Exists("/foo/bar")); 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, Mkdir) { 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // mkdir at the root should return EEXIST, not EACCES. 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(EEXIST, fs->Mkdir(Path("/"), 0644)); 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Path path("/foo"); 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_FALSE(fs->Exists("/foo")); 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Mkdir(path, 0644)); 1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) struct stat stat; 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(path, O_RDONLY, &node)); 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->GetStat(&stat)); 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(S_IFDIR, stat.st_mode & S_IFDIR); 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, Remove) { 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const char* kPath = "/foo"; 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddEmptyFile(kPath, NULL)); 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Path path(kPath); 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(fs->Exists(kPath)); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Remove(path)); 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(fs->Exists(kPath)); 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(Html5FsTest, Unlink) { 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddEmptyFile("/file", NULL)); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddDirectory("/dir", NULL)); 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(fs->Exists("/dir")); 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(fs->Exists("/file")); 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, fs->Unlink(Path("/file"))); 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(EISDIR, fs->Unlink(Path("/dir"))); 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(fs->Exists("/file")); 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(fs->Exists("/dir")); 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(Html5FsTest, Rmdir) { 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddEmptyFile("/file", NULL)); 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddDirectory("/dir", NULL)); 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(ENOTDIR, fs->Rmdir(Path("/file"))); 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, fs->Rmdir(Path("/dir"))); 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(fs->Exists("/dir")); 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(fs->Exists("/file")); 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, Rename) { 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddEmptyFile("/foo", NULL)); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringMap_t map; 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_TRUE(fs->Exists("/foo")); 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, fs->Rename(Path("/foo"), Path("/bar"))); 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(fs->Exists("/foo")); 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(fs->Exists("/bar")); 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, OpenForCreate) { 2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(fs->Exists("/foo")); 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Path path("/foo"); 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(path, O_CREAT | O_RDWR, &node)); 2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Write some data. 2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) char contents[] = "contents"; 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int bytes_written = 0; 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(0, node->Write(HandleAttr(), &contents[0], strlen(contents), 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &bytes_written)); 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(strlen(contents), bytes_written); 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Create again. 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(path, O_CREAT, &node)); 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Check that the file still has data. 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) off_t size; 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->GetSize(&size)); 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(strlen(contents), size); 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Open exclusively. 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(EEXIST, fs->Open(path, O_CREAT | O_EXCL, &node)); 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Try to truncate without write access. 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(EINVAL, fs->Open(path, O_CREAT | O_TRUNC, &node)); 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Open and truncate. 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(path, O_CREAT | O_TRUNC | O_WRONLY, &node)); 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // File should be empty. 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->GetSize(&size)); 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, size); 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, Read) { 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char contents[] = "contents"; 2848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_TRUE( 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_html5_.filesystem_template()->AddFile("/file", contents, NULL)); 2868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_TRUE(ppapi_html5_.filesystem_template()->AddDirectory("/dir", NULL)); 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/file"), O_RDONLY, &node)); 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) char buffer[10] = {0}; 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int bytes_read = 0; 2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HandleAttr attr; 2968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 2978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_EQ(strlen(contents), bytes_read); 2988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_STREQ(contents, buffer); 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Read nothing past the end of the file. 3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) attr.offs = 100; 3028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 3038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_EQ(0, bytes_read); 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Read part of the data. 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) attr.offs = 4; 3078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_EQ(strlen(contents) - 4, bytes_read); 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer[bytes_read] = 0; 3108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_STREQ("ents", buffer); 3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Writing should fail. 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int bytes_written = 1; // Set to a non-zero value. 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) attr.offs = 0; 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(EACCES, 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) node->Write(attr, &buffer[0], sizeof(buffer), &bytes_written)); 3178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_EQ(0, bytes_written); 3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Reading from a directory should fail. 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/dir"), O_RDONLY, &node)); 3218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ASSERT_EQ(EISDIR, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, Write) { 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char contents[] = "contents"; 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE( 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_html5_.filesystem_template()->AddFile("/file", contents, NULL)); 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddDirectory("/dir", NULL)); 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/file"), O_WRONLY, &node)); 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Reading should fail. 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) char buffer[10]; 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int bytes_read = 1; // Set to a non-zero value. 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HandleAttr attr; 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(EACCES, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, bytes_read); 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Reopen as read-write. 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/file"), O_RDWR, &node)); 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int bytes_written = 1; // Set to a non-zero value. 3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) attr.offs = 3; 3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(0, node->Write(attr, "struct", 6, &bytes_written)); 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(6, bytes_written); 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) attr.offs = 0; 3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(9, bytes_read); 3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer[bytes_read] = 0; 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_STREQ("construct", buffer); 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Writing to a directory should fail. 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, fs->Open(Path("/dir"), O_RDWR, &node)); 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(EISDIR, node->Write(attr, &buffer[0], sizeof(buffer), &bytes_read)); 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, GetStat) { 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const int creation_time = 1000; 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const int access_time = 2000; 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const int modified_time = 3000; 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char contents[] = "contents"; 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Create fake file. 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FakeHtml5FsNode* fake_node; 3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddFile( 3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "/file", contents, &fake_node)); 3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fake_node->set_creation_time(creation_time); 3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fake_node->set_last_access_time(access_time); 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fake_node->set_last_modified_time(modified_time); 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Create fake directory. 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE( 3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_html5_.filesystem_template()->AddDirectory("/dir", &fake_node)); 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fake_node->set_creation_time(creation_time); 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fake_node->set_last_access_time(access_time); 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) fake_node->set_last_modified_time(modified_time); 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/file"), O_RDONLY, &node)); 3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) struct stat statbuf; 3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->GetStat(&statbuf)); 3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EXPECT_EQ(S_IFREG, statbuf.st_mode & S_IFMT); 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(S_IRALL | S_IWALL | S_IXALL, statbuf.st_mode & ~S_IFMT); 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(strlen(contents), statbuf.st_size); 3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(access_time, statbuf.st_atime); 3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(creation_time, statbuf.st_ctime); 3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(modified_time, statbuf.st_mtime); 3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Test Get* and Isa* methods. 399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) off_t size; 4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->GetSize(&size)); 4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(strlen(contents), size); 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_FALSE(node->IsaDir()); 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(node->IsaFile()); 404effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(ENOTTY, node->Isatty()); 4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // GetStat on a directory... 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, fs->Open(Path("/dir"), O_RDONLY, &node)); 4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->GetStat(&statbuf)); 4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EXPECT_EQ(S_IFDIR, statbuf.st_mode & S_IFMT); 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(S_IRALL | S_IWALL | S_IXALL, statbuf.st_mode & ~S_IFMT); 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, statbuf.st_size); 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(access_time, statbuf.st_atime); 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(creation_time, statbuf.st_ctime); 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(modified_time, statbuf.st_mtime); 4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Test Get* and Isa* methods. 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->GetSize(&size)); 4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, size); 4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(node->IsaDir()); 4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_FALSE(node->IsaFile()); 421effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(ENOTTY, node->Isatty()); 4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, FTruncate) { 4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char contents[] = "contents"; 4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE( 4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_html5_.filesystem_template()->AddFile("/file", contents, NULL)); 4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(ppapi_html5_.filesystem_template()->AddDirectory("/dir", NULL)); 4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/file"), O_RDWR, &node)); 4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HandleAttr attr; 4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) char buffer[10] = {0}; 4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int bytes_read = 0; 4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // First make the file shorter... 4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->FTruncate(4)); 4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(4, bytes_read); 4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer[bytes_read] = 0; 4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_STREQ("cont", buffer); 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Now make the file longer... 4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, node->FTruncate(8)); 4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); 4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(8, bytes_read); 4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer[bytes_read] = 0; 4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_STREQ("cont\0\0\0\0", buffer); 4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Ftruncate should fail for a directory. 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0, fs->Open(Path("/dir"), O_RDONLY, &node)); 4563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(EISDIR, node->FTruncate(4)); 4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(Html5FsTest, GetDents) { 4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char contents[] = "contents"; 4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE( 4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ppapi_html5_.filesystem_template()->AddFile("/file", contents, NULL)); 4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t map; 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedRef<Html5FsForTesting> fs(new Html5FsForTesting(map, &ppapi_)); 4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode root; 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/"), O_RDONLY, &root)); 4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/file"), O_RDWR, &node)); 4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct stat stat; 4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, node->GetStat(&stat)); 4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ino_t file1_ino = stat.st_ino; 4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Should fail for regular files. 47868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const size_t kMaxDirents = 5; 47968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dirent dirents[kMaxDirents]; 4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int bytes_read = 1; // Set to a non-zero value. 4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) memset(&dirents[0], 0, sizeof(dirents)); 4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(ENOTDIR, 4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) node->GetDents(0, &dirents[0], sizeof(dirents), &bytes_read)); 4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, bytes_read); 4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Should work with root directory. 4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // +2 to test a size that is not a multiple of sizeof(dirent). 4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Expect it to round down. 4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) memset(&dirents[0], 0, sizeof(dirents)); 49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ( 49268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 0, root->GetDents(0, &dirents[0], sizeof(dirent) * 3 + 2, &bytes_read)); 49368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) { 49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t num_dirents = bytes_read / sizeof(dirent); 49668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(3, num_dirents); 49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(sizeof(dirent) * num_dirents, bytes_read); 49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 49968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::multiset<std::string> dirnames; 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < num_dirents; ++i) { 50168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(sizeof(dirent), dirents[i].d_off); 50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(sizeof(dirent), dirents[i].d_reclen); 50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dirnames.insert(dirents[i].d_name); 50468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 50568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1, dirnames.count("file")); 50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1, dirnames.count(".")); 50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1, dirnames.count("..")); 50968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Add another file... 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(0, fs->Open(Path("/file2"), O_CREAT, &node)); 5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(0, node->GetStat(&stat)); 5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ino_t file2_ino = stat.st_ino; 5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // These files SHOULD not hash to the same value but COULD. 5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_NE(file1_ino, file2_ino); 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Read the root directory again. 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) memset(&dirents[0], 0, sizeof(dirents)); 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, root->GetDents(0, &dirents[0], sizeof(dirents), &bytes_read)); 52268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 52368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) { 52468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t num_dirents = bytes_read / sizeof(dirent); 52568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(4, num_dirents); 52668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(sizeof(dirent) * num_dirents, bytes_read); 52768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 52868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::multiset<std::string> dirnames; 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < num_dirents; ++i) { 53068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(sizeof(dirent), dirents[i].d_off); 53168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(sizeof(dirent), dirents[i].d_reclen); 53268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dirnames.insert(dirents[i].d_name); 5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!strcmp(dirents[i].d_name, "file")) { 5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(dirents[i].d_ino, file1_ino); 5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!strcmp(dirents[i].d_name, "file2")) { 5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(dirents[i].d_ino, file2_ino); 5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 54068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 54168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 54268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1, dirnames.count("file")); 54368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1, dirnames.count("file2")); 54468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1, dirnames.count(".")); 54568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1, dirnames.count("..")); 5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 548