/* * Copyright 2017, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #include "KPathTest.h" #include #include #include #include #include typedef void* mutex; // Kernel stubs extern "C" team_id team_get_kernel_team_id(void) { return 0; } extern "C" team_id team_get_current_team_id(void) { return 0; } extern "C" status_t vfs_normalize_path(const char* path, char* buffer, size_t bufferSize, bool traverseLink, bool kernel) { return B_NOT_SUPPORTED; } // #pragma mark - DEBUG only extern "C" void* memalign_etc(size_t alignment, size_t size, uint32 flags) { return malloc(size); } extern "C" status_t _mutex_lock(mutex* lock, void* locker) { return B_OK; } extern "C" status_t _mutex_trylock(mutex* lock) { return B_OK; } extern "C" void _mutex_unlock(mutex* lock) { } // #pragma mark - KPathTest::KPathTest() { } KPathTest::~KPathTest() { } void KPathTest::TestSetToAndPath() { KPath path; status_t status = path.InitCheck(); CPPUNIT_ASSERT_MESSAGE("1. ", status == B_OK); status = path.SetTo("a/b/c"); CPPUNIT_ASSERT_MESSAGE("2. ", status == B_OK); CPPUNIT_ASSERT(strcmp(path.Path(), "a/b/c") == 0); CPPUNIT_ASSERT(path.Length() == 5); CPPUNIT_ASSERT(path.BufferSize() == B_PATH_NAME_LENGTH + 1); status = path.SetPath("abc/def"); CPPUNIT_ASSERT_MESSAGE("3. ", status == B_OK); CPPUNIT_ASSERT(strcmp(path.Path(), "abc/def") == 0); CPPUNIT_ASSERT(path.Length() == 7); CPPUNIT_ASSERT(path.BufferSize() == B_PATH_NAME_LENGTH + 1); status = path.SetTo("a/b/c", false, 10); CPPUNIT_ASSERT_MESSAGE("4. ", status == B_OK); CPPUNIT_ASSERT(strcmp(path.Path(), "a/b/c") == 0); CPPUNIT_ASSERT(path.Length() == 5); CPPUNIT_ASSERT(path.BufferSize() == 10); status = path.SetPath("sorry/i'm/too/long"); CPPUNIT_ASSERT(status == B_BUFFER_OVERFLOW); CPPUNIT_ASSERT(strcmp(path.Path(), "a/b/c") == 0); CPPUNIT_ASSERT(path.Length() == 5); status = path.SetTo(NULL, KPath::DEFAULT, SIZE_MAX); CPPUNIT_ASSERT(status == B_NO_MEMORY); } void KPathTest::TestLazyAlloc() { KPath path(NULL, KPath::LAZY_ALLOC); CPPUNIT_ASSERT(path.Path() == NULL); CPPUNIT_ASSERT(path.Length() == 0); CPPUNIT_ASSERT(path.BufferSize() == B_PATH_NAME_LENGTH + 1); CPPUNIT_ASSERT(path.InitCheck() == B_OK); path.SetPath("/b"); CPPUNIT_ASSERT(path.Path() != NULL); CPPUNIT_ASSERT(strcmp(path.Path(), "/b") == 0); CPPUNIT_ASSERT(path.Length() == 2); CPPUNIT_ASSERT(path.BufferSize() == B_PATH_NAME_LENGTH + 1); KPath second("yo", KPath::LAZY_ALLOC); CPPUNIT_ASSERT(second.Path() != NULL); CPPUNIT_ASSERT(strcmp(second.Path(), "yo") == 0); CPPUNIT_ASSERT(second.Length() == 2); CPPUNIT_ASSERT(second.BufferSize() == B_PATH_NAME_LENGTH + 1); status_t status = path.SetTo(NULL, KPath::LAZY_ALLOC, SIZE_MAX); CPPUNIT_ASSERT(status == B_OK); status = path.SetPath("test"); CPPUNIT_ASSERT(status == B_NO_MEMORY); CPPUNIT_ASSERT(path.InitCheck() == B_NO_MEMORY); } void KPathTest::TestLeaf() { KPath path("a"); CPPUNIT_ASSERT(strcmp(path.Path(), "a") == 0); CPPUNIT_ASSERT(strcmp(path.Leaf(), "a") == 0); path.SetTo(""); CPPUNIT_ASSERT(strcmp(path.Path(), "") == 0); CPPUNIT_ASSERT(strcmp(path.Leaf(), "") == 0); path.SetTo("/"); CPPUNIT_ASSERT(strcmp(path.Path(), "/") == 0); CPPUNIT_ASSERT(strcmp(path.Leaf(), "") == 0); path.SetTo("a/b"); CPPUNIT_ASSERT(strcmp(path.Path(), "a/b") == 0); CPPUNIT_ASSERT(strcmp(path.Leaf(), "b") == 0); path.SetTo("a/b/"); CPPUNIT_ASSERT(strcmp(path.Path(), "a/b") == 0); CPPUNIT_ASSERT(strcmp(path.Leaf(), "b") == 0); path.SetTo("/a/b//c"); CPPUNIT_ASSERT(strcmp(path.Path(), "/a/b//c") == 0); CPPUNIT_ASSERT(strcmp(path.Leaf(), "c") == 0); } void KPathTest::TestReplaceLeaf() { KPath path; status_t status = path.ReplaceLeaf("x"); CPPUNIT_ASSERT(status == B_OK); path.SetTo("/a/b/c"); CPPUNIT_ASSERT(path.Length() == 6); status = path.ReplaceLeaf(NULL); CPPUNIT_ASSERT(status == B_OK); CPPUNIT_ASSERT(path.Length() == 4); CPPUNIT_ASSERT(strcmp(path.Path(), "/a/b") == 0); status = path.ReplaceLeaf(""); CPPUNIT_ASSERT(status == B_OK); CPPUNIT_ASSERT(path.Length() == 2); CPPUNIT_ASSERT(strcmp(path.Path(), "/a") == 0); status = path.ReplaceLeaf("c"); CPPUNIT_ASSERT(status == B_OK); CPPUNIT_ASSERT(path.Length() == 2); CPPUNIT_ASSERT(strcmp(path.Path(), "/c") == 0); } void KPathTest::TestRemoveLeaf() { KPath path; bool removed = path.RemoveLeaf(); CPPUNIT_ASSERT(!removed); path.SetTo("a//b/c"); removed = path.RemoveLeaf(); CPPUNIT_ASSERT_MESSAGE("1. removed", removed); CPPUNIT_ASSERT(strcmp(path.Path(), "a//b") == 0); CPPUNIT_ASSERT(path.Length() == 4); removed = path.RemoveLeaf(); CPPUNIT_ASSERT_MESSAGE("2. removed", removed); CPPUNIT_ASSERT(strcmp(path.Path(), "a") == 0); CPPUNIT_ASSERT(path.Length() == 1); removed = path.RemoveLeaf(); CPPUNIT_ASSERT_MESSAGE("3. !removed", !removed); CPPUNIT_ASSERT(strcmp(path.Path(), "a") == 0); CPPUNIT_ASSERT(path.Length() == 1); path.SetTo("/a"); removed = path.RemoveLeaf(); CPPUNIT_ASSERT_MESSAGE("4. removed", removed); CPPUNIT_ASSERT(strcmp(path.Path(), "/") == 0); CPPUNIT_ASSERT(path.Length() == 1); removed = path.RemoveLeaf(); CPPUNIT_ASSERT_MESSAGE("5. !removed", !removed); CPPUNIT_ASSERT(strcmp(path.Path(), "/") == 0); CPPUNIT_ASSERT(path.Length() == 1); } void KPathTest::TestAdopt() { KPath one("first", false, 10); CPPUNIT_ASSERT(one.InitCheck() == B_OK); CPPUNIT_ASSERT(one.BufferSize() == 10); CPPUNIT_ASSERT(one.Length() == 5); KPath two("second", false, 20); CPPUNIT_ASSERT(two.InitCheck() == B_OK); CPPUNIT_ASSERT(two.BufferSize() == 20); one.Adopt(two); CPPUNIT_ASSERT(one.InitCheck() == B_OK); CPPUNIT_ASSERT(one.BufferSize() == 20); CPPUNIT_ASSERT(one.Length() == 6); CPPUNIT_ASSERT(strcmp(one.Path(), "second") == 0); CPPUNIT_ASSERT(two.Length() == 0); CPPUNIT_ASSERT(two.BufferSize() == 0); CPPUNIT_ASSERT(two.InitCheck() == B_NO_INIT); two.SetTo(NULL, KPath::LAZY_ALLOC); CPPUNIT_ASSERT(two.InitCheck() == B_OK); CPPUNIT_ASSERT(two.Path() == NULL); CPPUNIT_ASSERT(two.Length() == 0); one.Adopt(two); CPPUNIT_ASSERT(two.InitCheck() == B_OK); CPPUNIT_ASSERT(one.Path() == NULL); CPPUNIT_ASSERT(one.Length() == 0); one.SetPath("test"); CPPUNIT_ASSERT(one.Path() != NULL); CPPUNIT_ASSERT(strcmp(one.Path(), "test") == 0); CPPUNIT_ASSERT(one.Length() == 4); } void KPathTest::TestLockBuffer() { KPath path; CPPUNIT_ASSERT(path.Path() != NULL); CPPUNIT_ASSERT(path.Length() == 0); char* buffer = path.LockBuffer(); CPPUNIT_ASSERT(path.Path() == buffer); strcpy(buffer, "test"); CPPUNIT_ASSERT(path.Length() == 0); path.UnlockBuffer(); CPPUNIT_ASSERT(path.Length() == 4); KPath second(NULL, KPath::LAZY_ALLOC); CPPUNIT_ASSERT(second.Path() == NULL); CPPUNIT_ASSERT(second.Length() == 0); buffer = second.LockBuffer(); CPPUNIT_ASSERT(second.Path() == NULL); CPPUNIT_ASSERT(buffer == NULL); KPath third(NULL, KPath::LAZY_ALLOC); CPPUNIT_ASSERT(third.Path() == NULL); buffer = third.LockBuffer(true); CPPUNIT_ASSERT(third.Path() != NULL); CPPUNIT_ASSERT(buffer != NULL); strcpy(buffer, "test"); CPPUNIT_ASSERT(third.Length() == 0); third.UnlockBuffer(); CPPUNIT_ASSERT(third.Length() == 4); } void KPathTest::TestDetachBuffer() { KPath path("test"); CPPUNIT_ASSERT(path.InitCheck() == B_OK); char* buffer = path.DetachBuffer(); CPPUNIT_ASSERT(buffer != NULL); CPPUNIT_ASSERT(strcmp(buffer, "test") == 0); CPPUNIT_ASSERT(path.Path() == NULL); CPPUNIT_ASSERT(path.InitCheck() == B_NO_INIT); } void KPathTest::TestNormalize() { // Outside the kernel, we only test the error case. KPath path("test/../out"); CPPUNIT_ASSERT(path.InitCheck() == B_OK); status_t status = path.Normalize(true); CPPUNIT_ASSERT(status == B_NOT_SUPPORTED); CPPUNIT_ASSERT(path.Path() != NULL); CPPUNIT_ASSERT(path.Path()[0] == '\0'); CPPUNIT_ASSERT(path.Path() == path.Leaf()); status = path.SetTo("test/../in", KPath::NORMALIZE); CPPUNIT_ASSERT(status == B_NOT_SUPPORTED); CPPUNIT_ASSERT(path.Path() != NULL); CPPUNIT_ASSERT(path.Path()[0] == '\0'); CPPUNIT_ASSERT(path.Path() == path.Leaf()); } void KPathTest::TestAssign() { KPath one("first", false, 10); CPPUNIT_ASSERT(one.Length() == 5); KPath two("second", false, 20); two = one; CPPUNIT_ASSERT(strcmp(two.Path(), one.Path()) == 0); CPPUNIT_ASSERT(two.Path() != one.Path()); CPPUNIT_ASSERT(two.BufferSize() == one.BufferSize()); CPPUNIT_ASSERT(two.Length() == one.Length()); one = "/whatever"; CPPUNIT_ASSERT(one.Length() == 9); CPPUNIT_ASSERT(one.BufferSize() == two.BufferSize()); CPPUNIT_ASSERT(strcmp(one.Path(), "/whatever") == 0); } void KPathTest::TestEquals() { KPath a("one"); KPath b("two"); CPPUNIT_ASSERT_MESSAGE("1.", !(a == b)); b = a; CPPUNIT_ASSERT_MESSAGE("2.", a == b); b = "ones"; CPPUNIT_ASSERT_MESSAGE("3.", !(a == b)); } void KPathTest::TestNotEquals() { KPath a("one"); KPath b("two"); CPPUNIT_ASSERT_MESSAGE("1.", a != b); b = a; CPPUNIT_ASSERT_MESSAGE("2.", !(a != b)); b = "ones"; CPPUNIT_ASSERT_MESSAGE("3.", a != b); } /*static*/ void KPathTest::AddTests(BTestSuite& parent) { CppUnit::TestSuite& suite = *new CppUnit::TestSuite("KPathTest"); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestSetToAndPath", &KPathTest::TestSetToAndPath)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestLazyAlloc", &KPathTest::TestLazyAlloc)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestLeaf", &KPathTest::TestLeaf)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestReplaceLeaf", &KPathTest::TestReplaceLeaf)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestRemoveLeaf", &KPathTest::TestRemoveLeaf)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestAdopt", &KPathTest::TestAdopt)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestLockBuffer", &KPathTest::TestLockBuffer)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestDetachBuffer", &KPathTest::TestDetachBuffer)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestNormalize", &KPathTest::TestNormalize)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestAssign", &KPathTest::TestAssign)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestEquals", &KPathTest::TestEquals)); suite.addTest(new CppUnit::TestCaller( "KPathTest::TestNotEquals", &KPathTest::TestNotEquals)); parent.addTest("KPathTest", &suite); }