1 /* 2 * Copyright 2017, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "KPathTest.h" 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include <fs/KPath.h> 13 14 #include <cppunit/TestCaller.h> 15 #include <cppunit/TestSuite.h> 16 17 18 typedef void* mutex; 19 20 21 // Kernel stubs 22 23 24 extern "C" team_id 25 team_get_kernel_team_id(void) 26 { 27 return 0; 28 } 29 30 31 extern "C" team_id 32 team_get_current_team_id(void) 33 { 34 return 0; 35 } 36 37 38 extern "C" status_t 39 vfs_normalize_path(const char* path, char* buffer, size_t bufferSize, 40 bool traverseLink, bool kernel) 41 { 42 return B_NOT_SUPPORTED; 43 } 44 45 46 // #pragma mark - DEBUG only 47 48 49 extern "C" void* 50 memalign_etc(size_t alignment, size_t size, uint32 flags) 51 { 52 return malloc(size); 53 } 54 55 56 extern "C" status_t 57 _mutex_lock(mutex* lock, void* locker) 58 { 59 return B_OK; 60 } 61 62 63 extern "C" status_t 64 _mutex_trylock(mutex* lock) 65 { 66 return B_OK; 67 } 68 69 70 extern "C" void 71 _mutex_unlock(mutex* lock) 72 { 73 } 74 75 76 // #pragma mark - 77 78 79 KPathTest::KPathTest() 80 { 81 } 82 83 84 KPathTest::~KPathTest() 85 { 86 } 87 88 89 void 90 KPathTest::TestSetToAndPath() 91 { 92 KPath path; 93 status_t status = path.InitCheck(); 94 CPPUNIT_ASSERT_MESSAGE("1. ", status == B_OK); 95 96 status = path.SetTo("a/b/c"); 97 CPPUNIT_ASSERT_MESSAGE("2. ", status == B_OK); 98 CPPUNIT_ASSERT(strcmp(path.Path(), "a/b/c") == 0); 99 CPPUNIT_ASSERT(path.Length() == 5); 100 CPPUNIT_ASSERT(path.BufferSize() == B_PATH_NAME_LENGTH + 1); 101 102 status = path.SetPath("abc/def"); 103 CPPUNIT_ASSERT_MESSAGE("3. ", status == B_OK); 104 CPPUNIT_ASSERT(strcmp(path.Path(), "abc/def") == 0); 105 CPPUNIT_ASSERT(path.Length() == 7); 106 CPPUNIT_ASSERT(path.BufferSize() == B_PATH_NAME_LENGTH + 1); 107 108 status = path.SetTo("a/b/c", false, 10); 109 CPPUNIT_ASSERT_MESSAGE("4. ", status == B_OK); 110 CPPUNIT_ASSERT(strcmp(path.Path(), "a/b/c") == 0); 111 CPPUNIT_ASSERT(path.Length() == 5); 112 CPPUNIT_ASSERT(path.BufferSize() == 10); 113 114 status = path.SetPath("sorry/i'm/too/long"); 115 CPPUNIT_ASSERT(status == B_BUFFER_OVERFLOW); 116 CPPUNIT_ASSERT(strcmp(path.Path(), "a/b/c") == 0); 117 CPPUNIT_ASSERT(path.Length() == 5); 118 119 status = path.SetTo(NULL, KPath::DEFAULT, SIZE_MAX); 120 CPPUNIT_ASSERT(status == B_NO_MEMORY); 121 } 122 123 124 void 125 KPathTest::TestLazyAlloc() 126 { 127 KPath path(NULL, KPath::LAZY_ALLOC); 128 CPPUNIT_ASSERT(path.Path() == NULL); 129 CPPUNIT_ASSERT(path.Length() == 0); 130 CPPUNIT_ASSERT(path.BufferSize() == B_PATH_NAME_LENGTH + 1); 131 CPPUNIT_ASSERT(path.InitCheck() == B_OK); 132 133 path.SetPath("/b"); 134 CPPUNIT_ASSERT(path.Path() != NULL); 135 CPPUNIT_ASSERT(strcmp(path.Path(), "/b") == 0); 136 CPPUNIT_ASSERT(path.Length() == 2); 137 CPPUNIT_ASSERT(path.BufferSize() == B_PATH_NAME_LENGTH + 1); 138 139 KPath second("yo", KPath::LAZY_ALLOC); 140 CPPUNIT_ASSERT(second.Path() != NULL); 141 CPPUNIT_ASSERT(strcmp(second.Path(), "yo") == 0); 142 CPPUNIT_ASSERT(second.Length() == 2); 143 CPPUNIT_ASSERT(second.BufferSize() == B_PATH_NAME_LENGTH + 1); 144 145 status_t status = path.SetTo(NULL, KPath::LAZY_ALLOC, SIZE_MAX); 146 CPPUNIT_ASSERT(status == B_OK); 147 status = path.SetPath("test"); 148 CPPUNIT_ASSERT(status == B_NO_MEMORY); 149 CPPUNIT_ASSERT(path.InitCheck() == B_NO_MEMORY); 150 } 151 152 153 void 154 KPathTest::TestLeaf() 155 { 156 KPath path("a"); 157 CPPUNIT_ASSERT(strcmp(path.Path(), "a") == 0); 158 CPPUNIT_ASSERT(strcmp(path.Leaf(), "a") == 0); 159 160 path.SetTo(""); 161 CPPUNIT_ASSERT(strcmp(path.Path(), "") == 0); 162 CPPUNIT_ASSERT(strcmp(path.Leaf(), "") == 0); 163 164 path.SetTo("/"); 165 CPPUNIT_ASSERT(strcmp(path.Path(), "/") == 0); 166 CPPUNIT_ASSERT(strcmp(path.Leaf(), "") == 0); 167 168 path.SetTo("a/b"); 169 CPPUNIT_ASSERT(strcmp(path.Path(), "a/b") == 0); 170 CPPUNIT_ASSERT(strcmp(path.Leaf(), "b") == 0); 171 172 path.SetTo("a/b/"); 173 CPPUNIT_ASSERT(strcmp(path.Path(), "a/b") == 0); 174 CPPUNIT_ASSERT(strcmp(path.Leaf(), "b") == 0); 175 176 path.SetTo("/a/b//c"); 177 CPPUNIT_ASSERT(strcmp(path.Path(), "/a/b//c") == 0); 178 CPPUNIT_ASSERT(strcmp(path.Leaf(), "c") == 0); 179 } 180 181 182 void 183 KPathTest::TestReplaceLeaf() 184 { 185 KPath path; 186 status_t status = path.ReplaceLeaf("x"); 187 CPPUNIT_ASSERT(status == B_OK); 188 189 path.SetTo("/a/b/c"); 190 CPPUNIT_ASSERT(path.Length() == 6); 191 192 status = path.ReplaceLeaf(NULL); 193 CPPUNIT_ASSERT(status == B_OK); 194 CPPUNIT_ASSERT(path.Length() == 4); 195 CPPUNIT_ASSERT(strcmp(path.Path(), "/a/b") == 0); 196 197 status = path.ReplaceLeaf(""); 198 CPPUNIT_ASSERT(status == B_OK); 199 CPPUNIT_ASSERT(path.Length() == 2); 200 CPPUNIT_ASSERT(strcmp(path.Path(), "/a") == 0); 201 202 status = path.ReplaceLeaf("c"); 203 CPPUNIT_ASSERT(status == B_OK); 204 CPPUNIT_ASSERT(path.Length() == 2); 205 CPPUNIT_ASSERT(strcmp(path.Path(), "/c") == 0); 206 } 207 208 209 void 210 KPathTest::TestRemoveLeaf() 211 { 212 KPath path; 213 bool removed = path.RemoveLeaf(); 214 CPPUNIT_ASSERT(!removed); 215 216 path.SetTo("a//b/c"); 217 removed = path.RemoveLeaf(); 218 CPPUNIT_ASSERT_MESSAGE("1. removed", removed); 219 CPPUNIT_ASSERT(strcmp(path.Path(), "a//b") == 0); 220 CPPUNIT_ASSERT(path.Length() == 4); 221 222 removed = path.RemoveLeaf(); 223 CPPUNIT_ASSERT_MESSAGE("2. removed", removed); 224 CPPUNIT_ASSERT(strcmp(path.Path(), "a") == 0); 225 CPPUNIT_ASSERT(path.Length() == 1); 226 227 removed = path.RemoveLeaf(); 228 CPPUNIT_ASSERT_MESSAGE("3. !removed", !removed); 229 CPPUNIT_ASSERT(strcmp(path.Path(), "a") == 0); 230 CPPUNIT_ASSERT(path.Length() == 1); 231 232 path.SetTo("/a"); 233 removed = path.RemoveLeaf(); 234 CPPUNIT_ASSERT_MESSAGE("4. removed", removed); 235 CPPUNIT_ASSERT(strcmp(path.Path(), "/") == 0); 236 CPPUNIT_ASSERT(path.Length() == 1); 237 238 removed = path.RemoveLeaf(); 239 CPPUNIT_ASSERT_MESSAGE("5. !removed", !removed); 240 CPPUNIT_ASSERT(strcmp(path.Path(), "/") == 0); 241 CPPUNIT_ASSERT(path.Length() == 1); 242 } 243 244 245 void 246 KPathTest::TestAdopt() 247 { 248 KPath one("first", false, 10); 249 CPPUNIT_ASSERT(one.InitCheck() == B_OK); 250 CPPUNIT_ASSERT(one.BufferSize() == 10); 251 CPPUNIT_ASSERT(one.Length() == 5); 252 KPath two("second", false, 20); 253 CPPUNIT_ASSERT(two.InitCheck() == B_OK); 254 CPPUNIT_ASSERT(two.BufferSize() == 20); 255 256 one.Adopt(two); 257 CPPUNIT_ASSERT(one.InitCheck() == B_OK); 258 CPPUNIT_ASSERT(one.BufferSize() == 20); 259 CPPUNIT_ASSERT(one.Length() == 6); 260 CPPUNIT_ASSERT(strcmp(one.Path(), "second") == 0); 261 CPPUNIT_ASSERT(two.Length() == 0); 262 CPPUNIT_ASSERT(two.BufferSize() == 0); 263 CPPUNIT_ASSERT(two.InitCheck() == B_NO_INIT); 264 265 two.SetTo(NULL, KPath::LAZY_ALLOC); 266 CPPUNIT_ASSERT(two.InitCheck() == B_OK); 267 CPPUNIT_ASSERT(two.Path() == NULL); 268 CPPUNIT_ASSERT(two.Length() == 0); 269 one.Adopt(two); 270 271 CPPUNIT_ASSERT(two.InitCheck() == B_OK); 272 CPPUNIT_ASSERT(one.Path() == NULL); 273 CPPUNIT_ASSERT(one.Length() == 0); 274 one.SetPath("test"); 275 CPPUNIT_ASSERT(one.Path() != NULL); 276 CPPUNIT_ASSERT(strcmp(one.Path(), "test") == 0); 277 CPPUNIT_ASSERT(one.Length() == 4); 278 } 279 280 281 void 282 KPathTest::TestLockBuffer() 283 { 284 KPath path; 285 CPPUNIT_ASSERT(path.Path() != NULL); 286 CPPUNIT_ASSERT(path.Length() == 0); 287 char* buffer = path.LockBuffer(); 288 CPPUNIT_ASSERT(path.Path() == buffer); 289 strcpy(buffer, "test"); 290 CPPUNIT_ASSERT(path.Length() == 0); 291 path.UnlockBuffer(); 292 CPPUNIT_ASSERT(path.Length() == 4); 293 294 KPath second(NULL, KPath::LAZY_ALLOC); 295 CPPUNIT_ASSERT(second.Path() == NULL); 296 CPPUNIT_ASSERT(second.Length() == 0); 297 buffer = second.LockBuffer(); 298 CPPUNIT_ASSERT(second.Path() == NULL); 299 CPPUNIT_ASSERT(buffer == NULL); 300 301 KPath third(NULL, KPath::LAZY_ALLOC); 302 CPPUNIT_ASSERT(third.Path() == NULL); 303 buffer = third.LockBuffer(true); 304 CPPUNIT_ASSERT(third.Path() != NULL); 305 CPPUNIT_ASSERT(buffer != NULL); 306 strcpy(buffer, "test"); 307 CPPUNIT_ASSERT(third.Length() == 0); 308 third.UnlockBuffer(); 309 CPPUNIT_ASSERT(third.Length() == 4); 310 } 311 312 313 void 314 KPathTest::TestDetachBuffer() 315 { 316 KPath path("test"); 317 CPPUNIT_ASSERT(path.InitCheck() == B_OK); 318 319 char* buffer = path.DetachBuffer(); 320 CPPUNIT_ASSERT(buffer != NULL); 321 CPPUNIT_ASSERT(strcmp(buffer, "test") == 0); 322 323 CPPUNIT_ASSERT(path.Path() == NULL); 324 CPPUNIT_ASSERT(path.InitCheck() == B_NO_INIT); 325 } 326 327 328 void 329 KPathTest::TestNormalize() 330 { 331 // Outside the kernel, we only test the error case. 332 KPath path("test/../out"); 333 CPPUNIT_ASSERT(path.InitCheck() == B_OK); 334 335 status_t status = path.Normalize(true); 336 CPPUNIT_ASSERT(status == B_NOT_SUPPORTED); 337 CPPUNIT_ASSERT(path.Path() != NULL); 338 CPPUNIT_ASSERT(path.Path()[0] == '\0'); 339 CPPUNIT_ASSERT(path.Path() == path.Leaf()); 340 341 status = path.SetTo("test/../in", KPath::NORMALIZE); 342 CPPUNIT_ASSERT(status == B_NOT_SUPPORTED); 343 CPPUNIT_ASSERT(path.Path() != NULL); 344 CPPUNIT_ASSERT(path.Path()[0] == '\0'); 345 CPPUNIT_ASSERT(path.Path() == path.Leaf()); 346 } 347 348 349 void 350 KPathTest::TestAssign() 351 { 352 KPath one("first", false, 10); 353 CPPUNIT_ASSERT(one.Length() == 5); 354 KPath two("second", false, 20); 355 356 two = one; 357 CPPUNIT_ASSERT(strcmp(two.Path(), one.Path()) == 0); 358 CPPUNIT_ASSERT(two.Path() != one.Path()); 359 CPPUNIT_ASSERT(two.BufferSize() == one.BufferSize()); 360 CPPUNIT_ASSERT(two.Length() == one.Length()); 361 362 one = "/whatever"; 363 CPPUNIT_ASSERT(one.Length() == 9); 364 CPPUNIT_ASSERT(one.BufferSize() == two.BufferSize()); 365 CPPUNIT_ASSERT(strcmp(one.Path(), "/whatever") == 0); 366 } 367 368 369 void 370 KPathTest::TestEquals() 371 { 372 KPath a("one"); 373 KPath b("two"); 374 CPPUNIT_ASSERT_MESSAGE("1.", !(a == b)); 375 376 b = a; 377 CPPUNIT_ASSERT_MESSAGE("2.", a == b); 378 379 b = "ones"; 380 CPPUNIT_ASSERT_MESSAGE("3.", !(a == b)); 381 } 382 383 384 void 385 KPathTest::TestNotEquals() 386 { 387 KPath a("one"); 388 KPath b("two"); 389 CPPUNIT_ASSERT_MESSAGE("1.", a != b); 390 391 b = a; 392 CPPUNIT_ASSERT_MESSAGE("2.", !(a != b)); 393 394 b = "ones"; 395 CPPUNIT_ASSERT_MESSAGE("3.", a != b); 396 } 397 398 399 /*static*/ void 400 KPathTest::AddTests(BTestSuite& parent) 401 { 402 CppUnit::TestSuite& suite = *new CppUnit::TestSuite("KPathTest"); 403 404 suite.addTest(new CppUnit::TestCaller<KPathTest>( 405 "KPathTest::TestSetToAndPath", &KPathTest::TestSetToAndPath)); 406 suite.addTest(new CppUnit::TestCaller<KPathTest>( 407 "KPathTest::TestLazyAlloc", &KPathTest::TestLazyAlloc)); 408 suite.addTest(new CppUnit::TestCaller<KPathTest>( 409 "KPathTest::TestLeaf", &KPathTest::TestLeaf)); 410 suite.addTest(new CppUnit::TestCaller<KPathTest>( 411 "KPathTest::TestReplaceLeaf", &KPathTest::TestReplaceLeaf)); 412 suite.addTest(new CppUnit::TestCaller<KPathTest>( 413 "KPathTest::TestRemoveLeaf", &KPathTest::TestRemoveLeaf)); 414 suite.addTest(new CppUnit::TestCaller<KPathTest>( 415 "KPathTest::TestAdopt", &KPathTest::TestAdopt)); 416 suite.addTest(new CppUnit::TestCaller<KPathTest>( 417 "KPathTest::TestLockBuffer", &KPathTest::TestLockBuffer)); 418 suite.addTest(new CppUnit::TestCaller<KPathTest>( 419 "KPathTest::TestDetachBuffer", &KPathTest::TestDetachBuffer)); 420 suite.addTest(new CppUnit::TestCaller<KPathTest>( 421 "KPathTest::TestNormalize", &KPathTest::TestNormalize)); 422 suite.addTest(new CppUnit::TestCaller<KPathTest>( 423 "KPathTest::TestAssign", &KPathTest::TestAssign)); 424 suite.addTest(new CppUnit::TestCaller<KPathTest>( 425 "KPathTest::TestEquals", &KPathTest::TestEquals)); 426 suite.addTest(new CppUnit::TestCaller<KPathTest>( 427 "KPathTest::TestNotEquals", &KPathTest::TestNotEquals)); 428 429 parent.addTest("KPathTest", &suite); 430 } 431