bool do_tests(int repeat, int max_num_phases, double max_rate, long long trials)
{
    boost::mt19937 gen;
    boost::random::uniform_int_distribution<> num_phases_dist(BOOST_RANDOM_HYPEREXP_NUM_PHASES_MIN, max_num_phases);

    int errors = 0;
    for (int i = 0; i < repeat; ++i)
    {
        const int num_phases = num_phases_dist(gen);
        boost::random::uniform_real_distribution<> prob_dist(BOOST_RANDOM_HYPEREXP_PROBABILITY_MIN, BOOST_RANDOM_HYPEREXP_PROBABILITY_MAX);
        boost::random::uniform_real_distribution<> rate_dist(BOOST_RANDOM_HYPEREXP_RATE_MIN, max_rate);

        const std::vector<double> probabilities = detail::normalize_copy(detail::make_random_vector<double>(num_phases, prob_dist, gen));
        const std::vector<double> rates = detail::make_random_vector<double>(num_phases, rate_dist, gen);

        if (!do_test(probabilities, rates, trials, gen))
        {
            ++errors;
        }
    }
    if (errors != 0)
    {
        std::cout << "*** " << errors << " errors detected ***" << std::endl;
    }

    return errors == 0;
}
Example #2
0
static void test(securefs::BtreeDirectory& dir,
                 securefs::Directory& reference,
                 unsigned rounds,
                 double prob_get,
                 double prob_add,
                 double prob_del,
                 unsigned sequence)
{
    (void)sequence;    // May be used later
    bool is_prob_valid = (prob_get >= 0 && prob_add >= 0 && prob_del >= 0
                          && prob_get + prob_add + prob_del <= 1.0);
    REQUIRE(is_prob_valid);

    std::mt19937 engine{std::random_device{}()};
    std::uniform_real_distribution<> prob_dist(0, 1);
    std::uniform_int_distribution<int> name_dist(0, 65535);
    std::vector<std::string> filenames, filenames_prime;

    securefs::Directory::callback inserter
        = [&](const std::string& name, const securefs::id_type&, int) -> bool {
        filenames.push_back(name);
        return true;
    };

    securefs::Directory::callback inserter_prime
        = [&](const std::string& name, const securefs::id_type&, int) -> bool {
        filenames_prime.push_back(name);
        return true;
    };

    dir.iterate_over_entries(inserter);
    reference.iterate_over_entries(inserter_prime);

    std::sort(filenames.begin(), filenames.end());
    std::sort(filenames_prime.begin(), filenames_prime.end());
    bool equal_filenames = (filenames == filenames_prime);
    REQUIRE(equal_filenames);

    securefs::id_type id, id_prime;
    int type, type_prime;
    for (unsigned i = 0; i < rounds; ++i)
    {
        auto p = prob_dist(engine);
        if (p < prob_get)
        {
            filenames.clear();
            dir.iterate_over_entries(inserter);
            for (const std::string& n : filenames)
            {
                bool got = dir.get_entry(n, id, type);
                bool got_prime = reference.get_entry(n, id_prime, type_prime);
                REQUIRE(got == got_prime);
                REQUIRE(id == id_prime);
                REQUIRE(type == type_prime);
            }
        }
        else if (p < prob_get + prob_add)
        {
            auto name = fmt::format("{0:12d}", name_dist(engine));
            securefs::generate_random(id.data(), id.size());
            type = S_IFREG;
            bool added = dir.add_entry(name, id, type);
            bool added_prime = reference.add_entry(name, id, type);
            REQUIRE(added == added_prime);
            filenames.push_back(std::move(name));
        }
        else if (p < prob_get + prob_add + prob_del)
        {
            if (filenames.empty())
                continue;
            std::uniform_int_distribution<size_t> index_dist(0, filenames.size() - 1);
            size_t idx = index_dist(engine);
            bool removed = dir.remove_entry(filenames[idx], id, type);
            bool removed_prime = reference.remove_entry(filenames[idx], id_prime, type_prime);
            REQUIRE(removed == removed_prime);
            filenames.erase(filenames.begin() + idx);
        }
        else
        {
            REQUIRE(dir.validate_free_list());
            REQUIRE(dir.validate_btree_structure());
        }
    }
}