From 0e3e3ea793dcc40431ae3889df333484db8828c5 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 30 Aug 2015 20:14:55 -0400 Subject: [PATCH] add simple unit test for creating hard links --- src/file.cpp | 18 ++++++++++----- test/test_dht.cpp | 2 +- test/test_file.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/file.cpp b/src/file.cpp index c86db2465..9d02e7735 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -493,7 +493,7 @@ namespace libtorrent std::string n_exist = convert_to_native(file); std::string n_link = convert_to_native(link); #endif - BOOL ret = CreateHardLink(n_link.c_str(), n_exist.c_str(), NULL); + BOOL ret = CreateHardLink_(n_link.c_str(), n_exist.c_str(), NULL); if (ret) { ec.clear(); @@ -503,11 +503,16 @@ namespace libtorrent // something failed. Does the filesystem not support hard links? // TODO: 3 find out what error code is reported when the filesystem // does not support hard links. + DWORD error = GetLastError(); + if (error != ERROR_NOT_SUPPORTED || error != ERROR_ACCESS_DENIED) + { + // it's possible CreateHardLink will copy the file internally too, + // if the filesystem does not support it. + ec.assign(GetLastError(), system_category()); + return; + } - // it's possible CreateHardLink will copy the file internally too, - // if the filesystem does not support it. - ec.assign(GetLastError(), system_category()); - return; + // fall back to making a copy #else @@ -532,6 +537,9 @@ namespace libtorrent ec.assign(errno, generic_category()); return; } + + // fall back to making a copy + #endif // if we get here, we should copy the file diff --git a/test/test_dht.cpp b/test/test_dht.cpp index 19f692638..1d7d942e2 100644 --- a/test/test_dht.cpp +++ b/test/test_dht.cpp @@ -452,7 +452,7 @@ dht_settings test_settings() } // TODO: test obfuscated_get_peers -// TODO: 3 split this test up into smaller test cases +// TODO: 2 split this test up into smaller test cases TORRENT_TEST(dht) { dht_settings sett = test_settings(); diff --git a/test/test_file.cpp b/test/test_file.cpp index 69e99ac77..f5f9fa88f 100644 --- a/test/test_file.cpp +++ b/test/test_file.cpp @@ -290,7 +290,7 @@ TORRENT_TEST(file) #endif if (ec) fprintf(stderr, "open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); - TEST_CHECK(!ec); + TEST_EQUAL(ec, error_code()); if (ec) fprintf(stderr, "%s\n", ec.message().c_str()); file::iovec_t b = {(void*)"test", 4}; TEST_EQUAL(f.writev(0, &b, 1, ec), 4); @@ -303,8 +303,60 @@ TORRENT_TEST(file) TEST_EQUAL(f.readv(0, &b, 1, ec), 4); if (ec) fprintf(stderr, "readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); - TEST_CHECK(!ec); + TEST_EQUAL(ec, error_code()); TEST_CHECK(strcmp(test_buf, "test") == 0); f.close(); } +TORRENT_TEST(hard_link) +{ + // try to create a hard link to see what happens + // first create a regular file to then add another link to. + + // create a file, write some stuff to it, create a hard link to that file, + // read that file and assert we get the same stuff we wrote to the first file + error_code ec; + file f; + TEST_CHECK(f.open("original_file", file::read_write, ec)); + if (ec) + fprintf(stderr, "open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); + TEST_EQUAL(ec, error_code()); + + file::iovec_t b = {(void*)"abcdefghijklmnopqrstuvwxyz", 26}; + TEST_EQUAL(f.writev(0, &b, 1, ec), 26); + if (ec) + fprintf(stderr, "writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); + TEST_EQUAL(ec, error_code()); + f.close(); + + hard_link("original_file", "second_link", ec); + + if (ec) + fprintf(stderr, "hard_link failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); + TEST_EQUAL(ec, error_code()); + + + TEST_CHECK(f.open("second_link", file::read_write, ec)); + if (ec) + fprintf(stderr, "open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); + TEST_EQUAL(ec, error_code()); + + char test_buf[27] = {0}; + b.iov_base = test_buf; + b.iov_len = 27; + TEST_EQUAL(f.readv(0, &b, 1, ec), 26); + if (ec) + fprintf(stderr, "readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); + TEST_EQUAL(ec, error_code()); + TEST_CHECK(strcmp(test_buf, "abcdefghijklmnopqrstuvwxyz") == 0); + f.close(); + + remove("original_file", ec); + if (ec) + fprintf(stderr, "remove failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); + + remove("second_link", ec); + if (ec) + fprintf(stderr, "remove failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); +} +