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 |