brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 08d7ff8 Raw
280 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: can-create-symlinks10// UNSUPPORTED: c++03, c++11, c++1411// UNSUPPORTED: no-filesystem12 13// <filesystem>14 15// class directory_iterator16 17//18// explicit recursive_directory_iterator(const path& p);19// recursive_directory_iterator(const path& p, directory_options options);20// recursive_directory_iterator(const path& p, error_code& ec);21// recursive_directory_iterator(const path& p, directory_options options, error_code& ec);22 23#include <filesystem>24#include <type_traits>25#include <set>26#include <cassert>27 28#include "assert_macros.h"29#include "test_macros.h"30#include "filesystem_test_helper.h"31namespace fs = std::filesystem;32using namespace fs;33 34using RDI = recursive_directory_iterator;35 36static void test_constructor_signatures()37{38    using D = recursive_directory_iterator;39 40    // explicit directory_iterator(path const&);41    static_assert(!std::is_convertible<path, D>::value, "");42    static_assert(std::is_constructible<D, path>::value, "");43    static_assert(!std::is_nothrow_constructible<D, path>::value, "");44 45    // directory_iterator(path const&, error_code&)46    static_assert(std::is_constructible<D, path,47        std::error_code&>::value, "");48    static_assert(!std::is_nothrow_constructible<D, path,49        std::error_code&>::value, "");50 51    // directory_iterator(path const&, directory_options);52    static_assert(std::is_constructible<D, path, directory_options>::value, "");53    static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, "");54 55    // directory_iterator(path const&, directory_options, error_code&)56    static_assert(std::is_constructible<D, path, directory_options, std::error_code&>::value, "");57    static_assert(!std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, "");58}59 60static void test_construction_from_bad_path()61{62    static_test_env static_env;63    std::error_code ec;64    directory_options opts = directory_options::none;65    const RDI endIt;66 67    const path testPaths[] = { static_env.DNE, static_env.BadSymlink };68    for (path const& testPath : testPaths)69    {70        {71            RDI it(testPath, ec);72            assert(ec);73            assert(it == endIt);74        }75        {76            RDI it(testPath, opts, ec);77            assert(ec);78            assert(it == endIt);79        }80        {81            TEST_THROWS_TYPE(filesystem_error, RDI(testPath));82            TEST_THROWS_TYPE(filesystem_error, RDI(testPath, opts));83        }84    }85}86 87static void access_denied_test_case()88{89    using namespace fs;90#ifdef _WIN3291    // Windows doesn't support setting perms::none to trigger failures92    // reading directories; test using a special inaccessible directory93    // instead.94    const path testDir = GetWindowsInaccessibleDir();95    if (testDir.empty())96        return;97#else98    scoped_test_env env;99    path const testDir = env.make_env_path("dir1");100    path const testFile = testDir / "testFile";101    env.create_dir(testDir);102    env.create_file(testFile, 42);103 104    // Test that we can iterator over the directory before changing the perms105    {106        RDI it(testDir);107        assert(it != RDI{});108    }109 110    // Change the permissions so we can no longer iterate111    permissions(testDir, perms::none);112#endif113 114    // Check that the construction fails when skip_permissions_denied is115    // not given.116    {117        std::error_code ec;118        RDI it(testDir, ec);119        assert(ec);120        assert(it == RDI{});121    }122    // Check that construction does not report an error when123    // 'skip_permissions_denied' is given.124    {125        std::error_code ec;126        RDI it(testDir, directory_options::skip_permission_denied, ec);127        assert(!ec);128        assert(it == RDI{});129    }130}131 132 133static void access_denied_to_file_test_case()134{135    using namespace fs;136#ifdef _WIN32137    // Windows doesn't support setting perms::none to trigger failures138    // reading directories; test using a special inaccessible directory139    // instead.140    const path testDir = GetWindowsInaccessibleDir();141    if (testDir.empty())142        return;143    path const testFile = testDir / "inaccessible_file";144#else145    scoped_test_env env;146    path const testFile = env.make_env_path("file1");147    env.create_file(testFile, 42);148 149    // Change the permissions so we can no longer iterate150    permissions(testFile, perms::none);151#endif152 153    // Check that the construction fails when skip_permissions_denied is154    // not given.155    {156        std::error_code ec;157        RDI it(testFile, ec);158        assert(ec);159        assert(it == RDI{});160    }161    // Check that construction still fails when 'skip_permissions_denied' is given162    // because we tried to open a file and not a directory.163    {164        std::error_code ec;165        RDI it(testFile, directory_options::skip_permission_denied, ec);166        assert(ec);167        assert(it == RDI{});168    }169}170 171static void test_open_on_empty_directory_equals_end()172{173    scoped_test_env env;174    const path testDir = env.make_env_path("dir1");175    env.create_dir(testDir);176 177    const RDI endIt;178    {179        std::error_code ec;180        RDI it(testDir, ec);181        assert(!ec);182        assert(it == endIt);183    }184    {185        RDI it(testDir);186        assert(it == endIt);187    }188}189 190static void test_open_on_directory_succeeds()191{192    static_test_env static_env;193    const path testDir = static_env.Dir;194    std::set<path> dir_contents(static_env.DirIterationList.begin(),195                                static_env.DirIterationList.end());196    const RDI endIt{};197 198    {199        std::error_code ec;200        RDI it(testDir, ec);201        assert(!ec);202        assert(it != endIt);203        assert(dir_contents.count(*it));204    }205    {206        RDI it(testDir);207        assert(it != endIt);208        assert(dir_contents.count(*it));209    }210}211 212static void test_open_on_file_fails()213{214    static_test_env static_env;215    const path testFile = static_env.File;216    const RDI endIt{};217    {218        std::error_code ec;219        RDI it(testFile, ec);220        assert(ec);221        assert(it == endIt);222    }223    {224        TEST_THROWS_TYPE(filesystem_error, RDI(testFile));225    }226}227 228static void test_options_post_conditions()229{230    static_test_env static_env;231    const path goodDir = static_env.Dir;232    const path badDir = static_env.DNE;233 234    {235        std::error_code ec;236 237        RDI it1(goodDir, ec);238        assert(!ec);239        assert(it1.options() == directory_options::none);240 241        RDI it2(badDir, ec);242        assert(ec);243        assert(it2 == RDI{});244    }245    {246        std::error_code ec;247        const directory_options opts = directory_options::skip_permission_denied;248 249        RDI it1(goodDir, opts, ec);250        assert(!ec);251        assert(it1.options() == opts);252 253        RDI it2(badDir, opts, ec);254        assert(ec);255        assert(it2 == RDI{});256    }257    {258        RDI it(goodDir);259        assert(it.options() == directory_options::none);260    }261    {262        const directory_options opts = directory_options::follow_directory_symlink;263        RDI it(goodDir, opts);264        assert(it.options() == opts);265    }266}267 268int main(int, char**) {269    test_constructor_signatures();270    test_construction_from_bad_path();271    access_denied_test_case();272    access_denied_to_file_test_case();273    test_open_on_empty_directory_equals_end();274    test_open_on_directory_succeeds();275    test_open_on_file_fails();276    test_options_post_conditions();277 278    return 0;279}280