|
|
- #include "test_scaffold.h"
- #include "allocator.hpp"
- #include "gp/array.hpp"
- #include "gp/indexed_array.hpp"
- #include "gp/allocator/aggregator.hpp"
- #include "gp/allocator/buddy.hpp"
- #include "gp/allocator/dummy.hpp"
- #include "gp/algorithm/repeat.hpp"
- #include "gp/algorithm/rotate.hpp"
- #include "gp/ring_list.hpp"
- #include <thread>
- #include <chrono>
- #include <set>
- #include <stack>
- #include <numeric>
- #include <chrono>
- #include <random>
- #include <iomanip>
- #include <iostream>
- #include <fstream>
- #include <algorithm>
- #include "gp/vfs/vfs.hpp"
-
-
-
- #ifndef FUZZ_STRENGTH
- #define FUZZ_STRENGTH 2048
- #endif
-
- #define MACRO_STRGEN(X) #X
- #define MACRO_STR(X) MACRO_STRGEN(X)
-
- constexpr bool time_fuzzes = true;
-
-
- struct arraysum_test : public test_scaffold {
- arraysum_test() {
- name = __FILE__ ":1";
- }
-
- virtual int run() {
- gp::array<uint32_t, 16> test;
-
- for(auto& elem : test)
- {
- elem = 12;
- }
-
- return std::accumulate(test.begin(), test.end(), 0) != 12*test.size();
- }
- };
-
- append_test dummy_sd45uisd3(new arraysum_test{});
-
-
- struct optional_test : public test_scaffold {
- optional_test() {
- name = __FILE__ ":1";
- }
-
- virtual int run() {
- int res = 0;
- {
- gp::optional<uint32_t> test;
-
- if(test.has_value())
- {
- res++;
- }
-
- test = 12;
-
- if(test.has_value())
- {
- if(test.value()!=12)
- {
- res++;
- }
- }
- else
- {
- res++;
- }
- }
- {
- gp::optional<std::ifstream> test;
-
- if(test.has_value())
- {
- res++;
- }
-
- test = std::ifstream("/proc/cpuinfo");
-
- if(!test.has_value())
- {
- res++;
- }
- }
- return res;
- }
- };
-
- append_test dummy_mlyusisd3(new optional_test{});
-
-
- struct buddy_test : public test_scaffold {
- buddy_test() {
- name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":3";
- rng.seed(seed);
- }
-
- std::mt19937 rng{};
- int seed = std::random_device{}();
-
- virtual int run() {
- int res = 0;
- gp::repeat(10, [&](){
- gp::array<char, 4096> store;
- {
- gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
- gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> dum_bud{store.size()};
- gp::buddy<static_mapper> inner_bud{2048};
- gp::dummy_allocator dummyall;
- {
- gp_config::assertion(!dummyall.try_reallocate(nullptr, 0), "reallocation works wut?");
- gp_config::assertion(!bud.try_reallocate(nullptr, 0), "reallocation works wut?");
- gp_config::assertion(!inner_bud.try_reallocate(nullptr, 0), "reallocation works wut?");
- std::set<void*> ptr_set;
- for(int i = 0; i < 2048 / 16; i++)
- {
- void* v = inner_bud.allocate(16);
- gp_config::assertion(!inner_bud.empty(), "allocator should have elements");
- if(v == nullptr) throw gp::runtime_error("allocation failed");
- ptr_set.insert(v);
- }
- bool wut = ptr_set.count(nullptr)!=0 || ptr_set.size()!=(2048/16);
- if(wut) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
- if(nullptr != inner_bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
-
- for(auto elem : ptr_set) {
- gp_config::assertion(!inner_bud.empty(), "allocator should have elements");
- if(inner_bud.deallocate(elem) == false)
- {
- res += 1;
- }
- }
- gp_config::assertion(inner_bud.empty(), "allocator should be empty");
- }
- {
- gp_config::assertion(!dummyall.try_reallocate(nullptr, 0), "reallocation works wut?");
- gp_config::assertion(!bud.try_reallocate(nullptr, 0), "reallocation works wut?");
- std::set<void*> ptr_set;
- for(int i = 0; i < 4096 / 16; i++)
- {
- void* v = bud.allocate(16);
- gp_config::assertion(!bud.empty(), "allocator should have elements");
- if(v == nullptr) throw gp::runtime_error("allocation failed");
- ptr_set.insert(v);
- }
- if(ptr_set.count(nullptr)!=0 || ptr_set.size()!=(4096/16)) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
- if(nullptr != bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
-
- for(auto elem : ptr_set) {
- gp_config::assertion(!bud.empty(), "allocator should have elements");
- if(bud.deallocate(elem) == false)
- {
- res += 1;
- }
- }
- gp_config::assertion(bud.empty(), "allocator should be empty");
- }
- {
- std::set<void*> ptr_set;
- for(int i = 0; i < 4096 / 8; i++)
- {
- void* v = bud.allocate(8);
- gp_config::assertion(!bud.empty(), "allocator should have elements");
- if(v == nullptr) throw gp::runtime_error("allocation failed");
- ptr_set.insert(v);
- }
- if(ptr_set.count(nullptr)!=0 || ptr_set.size()!=(4096/8)) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
- if(nullptr != bud.allocate(8)) throw gp::runtime_error("allocation succeeded, failure was expected");
-
- for(auto elem : ptr_set) {
- gp_config::assertion(!bud.empty(), "allocator should have elements");
- if(bud.deallocate(elem) == false)
- {
- res += 1;
- }
- }
- gp_config::assertion(bud.empty(), "allocator should be empty");
- }
- {
- std::set<void*> ptr_set;
- std::vector<size_t> infill;
- std::insert_iterator< std::vector<size_t> > inserter{infill, std::end(infill)};
- std::fill_n(inserter, 4096 / 16 / 4, 16);
- inserter = std::insert_iterator< std::vector<size_t> >{infill, std::end(infill)};
- std::fill_n(inserter, 4096 / 8 / 4, 8);
- std::shuffle(infill.begin(), infill.end(), rng);
- for(auto sz : infill)
- {
- void* v = bud.allocate(sz);
- gp_config::assertion(!bud.empty(), "allocator should have elements");
- if(v == nullptr) throw gp::runtime_error("allocation failed");
- ptr_set.insert(v);
- }
- if(ptr_set.count(nullptr)!=0) throw gp::runtime_error("some allocations failed line: " MACRO_STR(__LINE__));
-
- gp_config::assertion(!bud.deallocate((char*)store.begin().data + 1), "misaligned deallocation fails");
- for(auto elem : ptr_set) {
- gp_config::assertion(!bud.empty(), "allocator should have elements");
- if(bud.deallocate(elem) == false)
- {
- res += 1;
- }
- }
- gp_config::assertion(!bud.deallocate(nullptr), "deallocating out of scope returns false");
- gp_config::assertion(bud.empty(), "allocator should be empty");
- }
- }
- });
- return res;
- }
- };
-
- append_test dummy_654sisd3(new buddy_test{});
-
-
-
- // TODO: should implement a test that tries to wrongly remove pointers as well as to allocate them correctly
- struct buddy_fuzz_test : public test_scaffold {
- buddy_fuzz_test() {
- name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":4";
- rng.seed(seed);
- }
-
- buddy_fuzz_test(size_t _seed) {
- seed = _seed;
- name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":4";
- rng.seed(seed);
- }
-
- std::mt19937 rng{};
- int seed = std::random_device{}();
-
- virtual int run() {
- int res = 0;
- alignas(8) gp::array<char, 4096> store;
- gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)> bud{&*store.begin(), store.size()};
- std::vector<void*> ptr_set;
- auto get_random_mem_qt = [&]() -> size_t {
- return 1+rng()%(store.size()-1);
- };
-
- auto start = std::chrono::steady_clock::now();
- {
- gp::repeat(FUZZ_STRENGTH, [&](){
- void* ptr;
- auto sz = get_random_mem_qt();
- size_t tries = 0;
- std::shuffle(
- ptr_set.begin(),
- ptr_set.end(),
- rng
- );
- while(!(ptr = bud.allocate(sz)))
- {
- void* free_ptr = ptr_set.back();
- ptr_set.pop_back();
- gp_config::assertion(bud.deallocate(free_ptr), "could not free sample");
- gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
- }
- ptr_set.emplace_back(ptr);
- });
- for(auto ptr : ptr_set)
- {
- bud.deallocate(ptr);
- }
- ptr_set.resize(0);
- }
- auto duration = std::chrono::steady_clock::now() - start;
-
- start = std::chrono::steady_clock::now();
- {
- size_t acc = 0;
- gp::repeat(FUZZ_STRENGTH, [&](){
- void* ptr;
- auto sz = get_random_mem_qt();
- size_t tries = 0;
- std::shuffle(
- ptr_set.begin(),
- ptr_set.end(),
- rng
- );
- ptr = malloc(sz);
- acc+=1;
- while(acc > 20)
- {
- void* free_ptr = ptr_set.back();
- free(free_ptr);
- acc -= 1;
- ptr_set.pop_back();
- gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
- }
- ptr_set.emplace_back(ptr);
- });
- for(auto ptr : ptr_set)
- {
- free(ptr);
- }
- }
- auto reference = std::chrono::steady_clock::now() - start;
-
-
- std::cout
- << "Fuzzing timed at "
- << std::chrono::duration_cast<std::chrono::microseconds>(duration).count()
- << "µs for "
- << FUZZ_STRENGTH
- << " (reference: "
- << std::chrono::duration_cast<std::chrono::microseconds>(reference).count()
- << "µs)"
- << std::endl;
-
- return res;
- }
- };
-
- append_test dummy_df987sd3(new buddy_fuzz_test{781017366});
- append_test dummy_df4sisd3(new buddy_fuzz_test{});
-
- struct ring_list_test : public test_scaffold {
- ring_list_test() {
- name = __FILE__ ":5";
- }
-
- virtual int run() {
- int res = 0;
- alignas(8) gp::array<char, 4096> store;
- using local_allocator = gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)>;
- local_allocator bud{&*store.begin(), store.size()};
- {
- using string_ring = gp::ring_list<std::string, local_allocator, false>;
- auto p = new(bud.allocate(sizeof(std::string))) std::string("Hello");
- auto orig = new(bud.allocate(sizeof(string_ring::node))) string_ring::node(p);
- string_ring ring{orig, bud};
- ring.insert("World");
- auto it = ring.explore();
- std::string test = "";
- do{
- test += *it;
- ++it;
- }while(it != ring.explore());
- res += (test != "HelloWorld");
- }
- return res;
- }
- };
-
- append_test dummy_867fdrgsd3(new ring_list_test{});
-
-
- struct aggregator_test : public test_scaffold {
- aggregator_test() {
- name = std::string(__FILE__ "seed_") + std::to_string(seed) + ":6";
- rng.seed(seed);
- }
-
- std::mt19937 rng{};
- int seed = std::random_device{}();
-
- virtual int run() {
- int res = 0;
- alignas(8) gp::array<char, 4096> store;
- using local_allocator = gp::buddy<gp::dummy_allocator, gp::math::msb<uint64_t>(4096)>;
- local_allocator bud{&*store.begin(), store.size()};
- alignas(8) gp::array<char, 4096> store2;
- local_allocator bud2{&*store2.begin(), store2.size()};
-
- gp::aggregator allocator{bud};
- allocator.insert(bud2);
- {
- std::vector<void*> ptr_set;
- auto get_random_mem_qt = [&]() -> size_t {
- return 1+rng()%(store.size()-1);
- };
-
- auto start = std::chrono::steady_clock::now();
- {
- gp::repeat(FUZZ_STRENGTH, [&](){
- void* ptr;
- auto sz = get_random_mem_qt();
- size_t tries = 0;
- std::shuffle(
- ptr_set.begin(),
- ptr_set.end(),
- rng
- );
- while(!(ptr = allocator.allocate(sz)))
- {
- void* free_ptr = ptr_set.back();
- ptr_set.pop_back();
- gp_config::assertion(allocator.deallocate(free_ptr), "could not free sample");
- gp_config::assertion(++tries <= store.size(), "infinite fuzzing");
- }
- ptr_set.emplace_back(ptr);
- });
- for(auto ptr : ptr_set)
- {
- bud.deallocate(ptr);
- }
- ptr_set.resize(0);
- }
- auto duration = std::chrono::steady_clock::now() - start;
- }
- return res;
- }
- };
-
- append_test dummy_8ijfsd658(new aggregator_test{});
-
-
- struct array_test : public test_scaffold {
- array_test() {
- name = __FILE__ ":7";
- }
-
- virtual int run() {
- int res = 0;
- gp::array<int, 8> store;
- {
- int i = 0;
- for(auto& p : store)
- {
- p = i++;
- }
- for(auto it = store.rbegin(); it != store.rend(); ++it)
- {
- gp_config::assertion(*it == --i, "array error");
- }
- for(const auto& p : store)
- {
- gp_config::assertion(p == i++, "array error");
- }
- for(auto it = store.crbegin(); it != store.crend(); ++it)
- {
- gp_config::assertion(*it == --i, "array error");
- }
- size_t cnt = 0;
- for(const auto& p : store)
- {
- cnt++;
- }
- gp_config::assertion(cnt == store.size(), "array error");
- cnt = 0;
- for(auto& p : store)
- {
- cnt++;
- }
- gp_config::assertion(cnt == store.size(), "array error");
- cnt = 0;
- for(auto it = store.crbegin(); it != store.crend(); ++it)
- {
- cnt++;
- }
- gp_config::assertion(cnt == store.size(), "array error");
- cnt = 0;
- for(auto it = store.rbegin(); it != store.rend(); ++it)
- {
- cnt++;
- }
- gp_config::assertion(cnt == store.size(), "array error");
- gp::rotate(store.begin(), store.begin()+1, store.end());
- gp::array<int, 8> rotated({1,2,3,4,5,6,7,0});
- gp_config::assertion(store == rotated, "rotate error");
- gp::rotate(store.begin(), store.end()-1, store.end());
- gp_config::assertion(store[0] == 0, "rotate error");
-
- }
- return res;
- }
- };
-
- append_test dummy_ajcurgsd3(new array_test{});
-
- struct indexed_array_test : public test_scaffold {
- indexed_array_test() {
- name = __FILE__ ":7";
- }
-
- virtual int run() {
- int res = 0;
- {
- gp::indexed_array<int, 8> store;
- size_t idx = store.push (112);
- store.push (113);
- store.push (114);
- gp_config::assertion(store[idx] == 112, "Bad value in indexed array");
-
- store.mark_for_removal(idx);
- store.sweep_removed();
- for(auto& p : store) {
- if(p == 112) res++;
- }
-
- gp_config::assertion(store.size() == 2, "Bad size of indexed array");
- }
- {
- gp::indexed_array<std::string, 8> store;
- size_t idx = store.push ("112");
- store.push ("113");
- store.push ("114");
- gp_config::assertion(store[idx] == "112", "Bad value in indexed array");
-
- store.mark_for_removal(idx);
- store.sweep_removed();
- for(auto& p : store) {
- if(p == "112") res++;
- }
-
- gp_config::assertion(store.size() == 2, "Bad size of indexed array");
-
- {
- // TODO: write a concrete implementation and test it
- // gp::vfs fs;
- }
- }
- return res;
- }
- };
-
- append_test dummy_khxurgsd3(new indexed_array_test{});
|