libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

copy_file_large.pass.cpp (3276B)


      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03
     11 // REQUIRES: long_tests
     12 
     13 // <filesystem>
     14 
     15 // bool copy_file(const path& from, const path& to);
     16 // bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
     17 // bool copy_file(const path& from, const path& to, copy_options options);
     18 // bool copy_file(const path& from, const path& to, copy_options options,
     19 //           error_code& ec) noexcept;
     20 
     21 #include "filesystem_include.hpp"
     22 #include <type_traits>
     23 #include <chrono>
     24 #include <cassert>
     25 
     26 #include "test_macros.h"
     27 #include "rapid-cxx-test.hpp"
     28 #include "filesystem_test_helper.hpp"
     29 
     30 using namespace fs;
     31 
     32 TEST_SUITE(filesystem_copy_file_test_suite)
     33 
     34 static std::string random_hex_chars(uintmax_t size) {
     35   std::string data;
     36   data.reserve(size);
     37   for (uintmax_t I = 0; I < size; ++I)
     38     data.push_back(random_utils::random_hex_char());
     39   return data;
     40 }
     41 
     42 // This test is intended to test 'sendfile's 2gb limit for a single call, and
     43 // to ensure that libc++ correctly copies files larger than that limit.
     44 // However it requires allocating ~5GB of filesystem space. This might not
     45 // be acceptable on all systems.
     46 TEST_CASE(large_file) {
     47   using namespace fs;
     48   constexpr uintmax_t sendfile_size_limit = 2147479552ull;
     49   constexpr uintmax_t additional_size = 1024;
     50   constexpr uintmax_t test_file_size = sendfile_size_limit + additional_size;
     51   static_assert(test_file_size > sendfile_size_limit, "");
     52 
     53   scoped_test_env env;
     54 
     55   // Check that we have more than sufficient room to create the files needed
     56   // to perform the test.
     57   if (space(env.test_root).available < 3 * test_file_size) {
     58     TEST_UNSUPPORTED();
     59   }
     60 
     61   // Use python to create a file right at the size limit.
     62   const path file = env.create_file("source", sendfile_size_limit);
     63   // Create some random data that looks different than the data before the
     64   // size limit.
     65   const std::string additional_data = random_hex_chars(additional_size);
     66   // Append this known data to the end of the source file.
     67   {
     68     std::ofstream outf(file.native(), std::ios_base::app);
     69     TEST_REQUIRE(outf.good());
     70     outf << additional_data;
     71     TEST_REQUIRE(outf);
     72   }
     73   TEST_REQUIRE(file_size(file) == test_file_size);
     74   const path dest = env.make_env_path("dest");
     75 
     76   std::error_code ec = GetTestEC();
     77   TEST_CHECK(copy_file(file, dest, ec));
     78   TEST_CHECK(!ec);
     79 
     80   TEST_REQUIRE(is_regular_file(dest));
     81   TEST_CHECK(file_size(dest) == test_file_size);
     82 
     83   // Read the data from the end of the destination file, and ensure it matches
     84   // the data at the end of the source file.
     85   std::string out_data;
     86   out_data.reserve(additional_size);
     87   {
     88     std::ifstream dest_file(dest.native());
     89     TEST_REQUIRE(dest_file);
     90     dest_file.seekg(sendfile_size_limit);
     91     TEST_REQUIRE(dest_file);
     92     dest_file >> out_data;
     93     TEST_CHECK(dest_file.eof());
     94   }
     95   TEST_CHECK(out_data.size() == additional_data.size());
     96   TEST_CHECK(out_data == additional_data);
     97 }
     98 
     99 TEST_SUITE_END()