| OLD | NEW |
| 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 */ | 4 */ |
| 5 | 5 |
| 6 #include <errno.h> | 6 #include <errno.h> |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 | 8 |
| 9 #include "nacl_io/error.h" |
| 9 #include "nacl_io/kernel_proxy.h" | 10 #include "nacl_io/kernel_proxy.h" |
| 10 #include "nacl_io/mount_node.h" | 11 #include "nacl_io/mount_node.h" |
| 11 #include "nacl_io/mount_node_dir.h" | 12 #include "nacl_io/mount_node_dir.h" |
| 12 #include "nacl_io/mount_node_mem.h" | 13 #include "nacl_io/mount_node_mem.h" |
| 13 #include "nacl_io/osdirent.h" | 14 #include "nacl_io/osdirent.h" |
| 14 | 15 |
| 15 #include "gtest/gtest.h" | 16 #include "gtest/gtest.h" |
| 16 | 17 |
| 17 #define NULL_NODE ((MountNode *) NULL) | 18 #define NULL_NODE ((MountNode*) NULL) |
| 18 | 19 |
| 19 static int s_AllocNum = 0; | 20 static int s_AllocNum = 0; |
| 20 | 21 |
| 21 class MockMemory : public MountNodeMem { | 22 class MockMemory : public MountNodeMem { |
| 22 public: | 23 public: |
| 23 MockMemory() : MountNodeMem(NULL) { | 24 MockMemory() : MountNodeMem(NULL) { s_AllocNum++; } |
| 24 s_AllocNum++; | |
| 25 } | |
| 26 | 25 |
| 27 ~MockMemory() { | 26 ~MockMemory() { s_AllocNum--; } |
| 28 s_AllocNum--; | |
| 29 } | |
| 30 | 27 |
| 31 bool Init(int mode) { | 28 Error Init(int mode) { return MountNodeMem::Init(mode); } |
| 32 return MountNodeMem::Init(mode); | 29 Error AddChild(const std::string& name, MountNode* node) { |
| 33 } | |
| 34 int AddChild(const std::string& name, MountNode *node) { | |
| 35 return MountNodeMem::AddChild(name, node); | 30 return MountNodeMem::AddChild(name, node); |
| 36 } | 31 } |
| 37 int RemoveChild(const std::string& name) { | 32 Error RemoveChild(const std::string& name) { |
| 38 return MountNodeMem::RemoveChild(name); | 33 return MountNodeMem::RemoveChild(name); |
| 39 } | 34 } |
| 40 MountNode* FindChild(const std::string& name) { | 35 Error FindChild(const std::string& name, MountNode** out_node) { |
| 41 return MountNodeMem::FindChild(name); | 36 return MountNodeMem::FindChild(name, out_node); |
| 42 } | 37 } |
| 43 void Link() { MountNodeMem::Link(); } | 38 void Link() { MountNodeMem::Link(); } |
| 44 void Unlink() { MountNodeMem::Unlink(); } | 39 void Unlink() { MountNodeMem::Unlink(); } |
| 45 | 40 |
| 46 protected: | 41 protected: |
| 47 using MountNodeMem::Init; | 42 using MountNodeMem::Init; |
| 48 }; | 43 }; |
| 49 | 44 |
| 50 class MockDir : public MountNodeDir { | 45 class MockDir : public MountNodeDir { |
| 51 public: | 46 public: |
| 52 MockDir() : MountNodeDir(NULL) { | 47 MockDir() : MountNodeDir(NULL) { s_AllocNum++; } |
| 53 s_AllocNum++; | |
| 54 } | |
| 55 | 48 |
| 56 ~MockDir() { | 49 ~MockDir() { s_AllocNum--; } |
| 57 s_AllocNum--; | |
| 58 } | |
| 59 | 50 |
| 60 bool Init(int mode) { | 51 Error Init(int mode) { return MountNodeDir::Init(mode); } |
| 61 return MountNodeDir::Init(mode); | 52 Error AddChild(const std::string& name, MountNode* node) { |
| 62 } | |
| 63 int AddChild(const std::string& name, MountNode *node) { | |
| 64 return MountNodeDir::AddChild(name, node); | 53 return MountNodeDir::AddChild(name, node); |
| 65 } | 54 } |
| 66 int RemoveChild(const std::string& name) { | 55 Error RemoveChild(const std::string& name) { |
| 67 return MountNodeDir::RemoveChild(name); | 56 return MountNodeDir::RemoveChild(name); |
| 68 } | 57 } |
| 69 MountNode* FindChild(const std::string& name) { | 58 Error FindChild(const std::string& name, MountNode** out_node) { |
| 70 return MountNodeDir::FindChild(name); | 59 return MountNodeDir::FindChild(name, out_node); |
| 71 } | 60 } |
| 72 void Link() { MountNodeDir::Link(); } | 61 void Link() { MountNodeDir::Link(); } |
| 73 void Unlink() { MountNodeDir::Unlink(); } | 62 void Unlink() { MountNodeDir::Unlink(); } |
| 74 | 63 |
| 75 protected: | 64 protected: |
| 76 using MountNodeDir::Init; | 65 using MountNodeDir::Init; |
| 77 }; | 66 }; |
| 78 | 67 |
| 79 TEST(MountNodeTest, File) { | 68 TEST(MountNodeTest, File) { |
| 80 MockMemory *file = new MockMemory; | 69 MockMemory* file = new MockMemory; |
| 70 MountNode* result_node = NULL; |
| 71 size_t result_size = 0; |
| 72 int result_bytes = 0; |
| 81 | 73 |
| 82 EXPECT_TRUE(file->Init(S_IREAD | S_IWRITE)); | 74 EXPECT_EQ(0, file->Init(S_IREAD | S_IWRITE)); |
| 83 | 75 |
| 84 // Test properties | 76 // Test properties |
| 85 EXPECT_EQ(0, file->GetLinks()); | 77 EXPECT_EQ(0, file->GetLinks()); |
| 86 EXPECT_EQ(S_IREAD | S_IWRITE, file->GetMode()); | 78 EXPECT_EQ(S_IREAD | S_IWRITE, file->GetMode()); |
| 87 EXPECT_EQ(S_IFREG, file->GetType()); | 79 EXPECT_EQ(S_IFREG, file->GetType()); |
| 88 EXPECT_FALSE(file->IsaDir()); | 80 EXPECT_FALSE(file->IsaDir()); |
| 89 EXPECT_TRUE(file->IsaFile()); | 81 EXPECT_TRUE(file->IsaFile()); |
| 90 EXPECT_FALSE(file->IsaTTY()); | 82 EXPECT_FALSE(file->IsaTTY()); |
| 91 EXPECT_EQ(1, file->RefCount()); | 83 EXPECT_EQ(1, file->RefCount()); |
| 92 | 84 |
| 93 // Test IO | 85 // Test IO |
| 94 char buf1[1024]; | 86 char buf1[1024]; |
| 95 char buf2[1024 * 2]; | 87 char buf2[1024 * 2]; |
| 96 for (size_t a = 0; a < sizeof(buf1); a++) | 88 for (size_t a = 0; a < sizeof(buf1); a++) |
| 97 buf1[a] = a; | 89 buf1[a] = a; |
| 98 memset(buf2, 0, sizeof(buf2)); | 90 memset(buf2, 0, sizeof(buf2)); |
| 99 | 91 |
| 100 EXPECT_EQ(0, file->GetSize()); | 92 EXPECT_EQ(0, file->GetSize(&result_size)); |
| 101 EXPECT_EQ(0, file->Read(0, buf2, sizeof(buf2))); | 93 EXPECT_EQ(0, result_size); |
| 102 EXPECT_EQ(0, file->GetSize()); | 94 EXPECT_EQ(0, file->Read(0, buf2, sizeof(buf2), &result_bytes)); |
| 103 EXPECT_EQ(sizeof(buf1), file->Write(0, buf1, sizeof(buf1))); | 95 EXPECT_EQ(0, result_bytes); |
| 104 EXPECT_EQ(sizeof(buf1), file->GetSize()); | 96 EXPECT_EQ(0, file->GetSize(&result_size)); |
| 105 EXPECT_EQ(sizeof(buf1), file->Read(0, buf2, sizeof(buf2))); | 97 EXPECT_EQ(0, result_size); |
| 98 EXPECT_EQ(0, file->Write(0, buf1, sizeof(buf1), &result_bytes)); |
| 99 EXPECT_EQ(sizeof(buf1), result_bytes); |
| 100 EXPECT_EQ(0, file->GetSize(&result_size)); |
| 101 EXPECT_EQ(sizeof(buf1), result_size); |
| 102 EXPECT_EQ(0, file->Read(0, buf2, sizeof(buf2), &result_bytes)); |
| 103 EXPECT_EQ(sizeof(buf1), result_bytes); |
| 106 EXPECT_EQ(0, memcmp(buf1, buf2, sizeof(buf1))); | 104 EXPECT_EQ(0, memcmp(buf1, buf2, sizeof(buf1))); |
| 107 | 105 |
| 108 struct stat s; | 106 struct stat s; |
| 109 EXPECT_EQ(0, file->GetStat(&s)); | 107 EXPECT_EQ(0, file->GetStat(&s)); |
| 110 EXPECT_LT(0, s.st_ino); // 0 is an invalid inode number. | 108 EXPECT_LT(0, s.st_ino); // 0 is an invalid inode number. |
| 111 EXPECT_EQ(sizeof(buf1), s.st_size); | 109 EXPECT_EQ(sizeof(buf1), s.st_size); |
| 112 | 110 |
| 113 // Directory operations should fail | 111 // Directory operations should fail |
| 114 struct dirent d; | 112 struct dirent d; |
| 115 EXPECT_EQ(-1, file->GetDents(0, &d, sizeof(d))); | 113 EXPECT_EQ(ENOTDIR, file->GetDents(0, &d, sizeof(d), &result_bytes)); |
| 116 EXPECT_EQ(errno, ENOTDIR); | 114 EXPECT_EQ(ENOTDIR, file->AddChild("", file)); |
| 117 EXPECT_EQ(-1, file->AddChild("", file)); | 115 EXPECT_EQ(ENOTDIR, file->RemoveChild("")); |
| 118 EXPECT_EQ(errno, ENOTDIR); | 116 EXPECT_EQ(ENOTDIR, file->FindChild("", &result_node)); |
| 119 EXPECT_EQ(-1, file->RemoveChild("")); | 117 EXPECT_EQ(NULL_NODE, result_node); |
| 120 EXPECT_EQ(errno, ENOTDIR); | |
| 121 EXPECT_EQ(NULL_NODE, file->FindChild("")); | |
| 122 EXPECT_EQ(errno, ENOTDIR); | |
| 123 | 118 |
| 124 delete file; | 119 delete file; |
| 125 } | 120 } |
| 126 | 121 |
| 127 TEST(MountNodeTest, Directory) { | 122 TEST(MountNodeTest, Directory) { |
| 128 MockDir *root = new MockDir(); | 123 MockDir* root = new MockDir(); |
| 124 MountNode* result_node = NULL; |
| 125 size_t result_size = 0; |
| 126 int result_bytes = 0; |
| 127 |
| 129 root->Init(S_IREAD | S_IWRITE); | 128 root->Init(S_IREAD | S_IWRITE); |
| 130 | 129 |
| 131 // Test properties | 130 // Test properties |
| 132 EXPECT_EQ(0, root->GetLinks()); | 131 EXPECT_EQ(0, root->GetLinks()); |
| 133 EXPECT_EQ(S_IREAD | S_IWRITE, root->GetMode()); | 132 EXPECT_EQ(S_IREAD | S_IWRITE, root->GetMode()); |
| 134 EXPECT_EQ(S_IFDIR, root->GetType()); | 133 EXPECT_EQ(S_IFDIR, root->GetType()); |
| 135 EXPECT_TRUE(root->IsaDir()); | 134 EXPECT_TRUE(root->IsaDir()); |
| 136 EXPECT_FALSE(root->IsaFile()); | 135 EXPECT_FALSE(root->IsaFile()); |
| 137 EXPECT_FALSE(root->IsaTTY()); | 136 EXPECT_FALSE(root->IsaTTY()); |
| 138 EXPECT_EQ(1, root->RefCount()); | 137 EXPECT_EQ(1, root->RefCount()); |
| 139 | 138 |
| 140 // IO operations should fail | 139 // IO operations should fail |
| 141 char buf1[1024]; | 140 char buf1[1024]; |
| 142 EXPECT_EQ(0, root->GetSize()); | 141 EXPECT_EQ(0, root->GetSize(&result_size)); |
| 143 EXPECT_EQ(-1, root->Read(0, buf1, sizeof(buf1))); | 142 EXPECT_EQ(0, result_size); |
| 144 EXPECT_EQ(errno, EISDIR); | 143 EXPECT_EQ(EISDIR, root->Read(0, buf1, sizeof(buf1), &result_bytes)); |
| 145 EXPECT_EQ(-1, root->Write(0, buf1, sizeof(buf1))); | 144 EXPECT_EQ(EISDIR, root->Write(0, buf1, sizeof(buf1), &result_bytes)); |
| 146 EXPECT_EQ(errno, EISDIR); | |
| 147 | 145 |
| 148 // Test directory operations | 146 // Test directory operations |
| 149 MockMemory* file = new MockMemory; | 147 MockMemory* file = new MockMemory; |
| 150 EXPECT_TRUE(file->Init(S_IREAD | S_IWRITE)); | 148 EXPECT_EQ(0, file->Init(S_IREAD | S_IWRITE)); |
| 151 | 149 |
| 152 EXPECT_EQ(1, root->RefCount()); | 150 EXPECT_EQ(1, root->RefCount()); |
| 153 EXPECT_EQ(1, file->RefCount()); | 151 EXPECT_EQ(1, file->RefCount()); |
| 154 EXPECT_EQ(0, root->AddChild("F1", file)); | 152 EXPECT_EQ(0, root->AddChild("F1", file)); |
| 155 EXPECT_EQ(1, file->GetLinks()); | 153 EXPECT_EQ(1, file->GetLinks()); |
| 156 EXPECT_EQ(2, file->RefCount()); | 154 EXPECT_EQ(2, file->RefCount()); |
| 157 | 155 |
| 158 // Test that the directory is there | 156 // Test that the directory is there |
| 159 struct dirent d; | 157 struct dirent d; |
| 160 EXPECT_EQ(sizeof(d), root->GetDents(0, &d, sizeof(d))); | 158 EXPECT_EQ(0, root->GetDents(0, &d, sizeof(d), &result_bytes)); |
| 159 EXPECT_EQ(sizeof(d), result_bytes); |
| 161 EXPECT_LT(0, d.d_ino); // 0 is an invalid inode number. | 160 EXPECT_LT(0, d.d_ino); // 0 is an invalid inode number. |
| 162 EXPECT_EQ(sizeof(d), d.d_off); | 161 EXPECT_EQ(sizeof(d), d.d_off); |
| 163 EXPECT_EQ(sizeof(d), d.d_reclen); | 162 EXPECT_EQ(sizeof(d), d.d_reclen); |
| 164 EXPECT_EQ(0, strcmp("F1", d.d_name)); | 163 EXPECT_EQ(0, strcmp("F1", d.d_name)); |
| 165 EXPECT_EQ(0, root->GetDents(sizeof(d), &d, sizeof(d))); | 164 EXPECT_EQ(0, root->GetDents(sizeof(d), &d, sizeof(d), &result_bytes)); |
| 165 EXPECT_EQ(0, result_bytes); |
| 166 | 166 |
| 167 EXPECT_EQ(0, root->AddChild("F2", file)); | 167 EXPECT_EQ(0, root->AddChild("F2", file)); |
| 168 EXPECT_EQ(2, file->GetLinks()); | 168 EXPECT_EQ(2, file->GetLinks()); |
| 169 EXPECT_EQ(3, file->RefCount()); | 169 EXPECT_EQ(3, file->RefCount()); |
| 170 EXPECT_EQ(-1, root->AddChild("F1", file)); | 170 EXPECT_EQ(EEXIST, root->AddChild("F1", file)); |
| 171 EXPECT_EQ(EEXIST, errno); | |
| 172 EXPECT_EQ(2, file->GetLinks()); | 171 EXPECT_EQ(2, file->GetLinks()); |
| 173 | 172 |
| 174 EXPECT_EQ(2, s_AllocNum); | 173 EXPECT_EQ(2, s_AllocNum); |
| 175 EXPECT_NE(NULL_NODE, root->FindChild("F1")); | 174 EXPECT_EQ(0, root->FindChild("F1", &result_node)); |
| 176 EXPECT_NE(NULL_NODE, root->FindChild("F2")); | 175 EXPECT_NE(NULL_NODE, result_node); |
| 177 EXPECT_EQ(NULL_NODE, root->FindChild("F3")); | 176 EXPECT_EQ(0, root->FindChild("F2", &result_node)); |
| 178 EXPECT_EQ(errno, ENOENT); | 177 EXPECT_NE(NULL_NODE, result_node); |
| 178 EXPECT_EQ(ENOENT, root->FindChild("F3", &result_node)); |
| 179 EXPECT_EQ(NULL_NODE, result_node); |
| 179 | 180 |
| 180 EXPECT_EQ(2, s_AllocNum); | 181 EXPECT_EQ(2, s_AllocNum); |
| 181 EXPECT_EQ(0, root->RemoveChild("F1")); | 182 EXPECT_EQ(0, root->RemoveChild("F1")); |
| 182 EXPECT_EQ(1, file->GetLinks()); | 183 EXPECT_EQ(1, file->GetLinks()); |
| 183 EXPECT_EQ(2, file->RefCount()); | 184 EXPECT_EQ(2, file->RefCount()); |
| 184 EXPECT_EQ(0, root->RemoveChild("F2")); | 185 EXPECT_EQ(0, root->RemoveChild("F2")); |
| 185 EXPECT_EQ(0, file->GetLinks()); | 186 EXPECT_EQ(0, file->GetLinks()); |
| 186 EXPECT_EQ(1, file->RefCount()); | 187 EXPECT_EQ(1, file->RefCount()); |
| 187 EXPECT_EQ(2, s_AllocNum); | 188 EXPECT_EQ(2, s_AllocNum); |
| 188 | 189 |
| 189 file->Release(); | 190 file->Release(); |
| 190 EXPECT_EQ(1, s_AllocNum); | 191 EXPECT_EQ(1, s_AllocNum); |
| 191 root->Release(); | 192 root->Release(); |
| 192 EXPECT_EQ(0, s_AllocNum); | 193 EXPECT_EQ(0, s_AllocNum); |
| 193 } | 194 } |
| 194 | 195 |
| OLD | NEW |