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 18typedef void* mutex; 19 20 21// Kernel stubs 22 23 24extern "C" team_id 25team_get_kernel_team_id(void) 26{ 27 return 0; 28} 29 30 31extern "C" team_id 32team_get_current_team_id(void) 33{ 34 return 0; 35} 36 37 38extern "C" status_t 39vfs_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 49extern "C" void* 50memalign_etc(size_t alignment, size_t size, uint32 flags) 51{ 52 return malloc(size); 53} 54 55 56extern "C" status_t 57_mutex_lock(mutex* lock, void* locker) 58{ 59 return B_OK; 60} 61 62 63extern "C" status_t 64_mutex_trylock(mutex* lock) 65{ 66 return B_OK; 67} 68 69 70extern "C" void 71_mutex_unlock(mutex* lock) 72{ 73} 74 75 76// #pragma mark - 77 78 79KPathTest::KPathTest() 80{ 81} 82 83 84KPathTest::~KPathTest() 85{ 86} 87 88 89void 90KPathTest::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 124void 125KPathTest::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 153void 154KPathTest::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 182void 183KPathTest::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 209void 210KPathTest::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 245void 246KPathTest::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 281void 282KPathTest::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 313void 314KPathTest::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 328void 329KPathTest::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 349void 350KPathTest::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 369void 370KPathTest::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 384void 385KPathTest::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 400KPathTest::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