File: Tests.hpp

package info (click to toggle)
memkind 1.14.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 8,508 kB
  • sloc: ansic: 72,572; cpp: 39,493; sh: 4,594; perl: 4,250; xml: 2,044; python: 1,753; makefile: 1,393; csh: 7
file content (181 lines) | stat: -rw-r--r-- 5,082 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// SPDX-License-Identifier: BSD-2-Clause
/* Copyright (C) 2015 - 2021 Intel Corporation. */

/*
This file contain self-tests for Allocator Perf Tool.
*/
#pragma once

#include <unistd.h>

#include "AllocationSizes.hpp"
#include "AllocatorFactory.hpp"
#include "Configuration.hpp"
#include "ScenarioWorkload.h"
#include "StandardAllocatorWithTimer.hpp"
#include "Task.hpp"
#include "TaskFactory.hpp"
#include "VectorIterator.hpp"

// Basic test for allocators. Allocate 32 bytes by malloc, then deallocate it by
// free.
void test_allocator(Allocator &allocator, const char *allocator_name)
{
    printf("\n============= Allocator (%s) test ============= \n",
           allocator_name);

    memory_operation data = allocator.wrapped_malloc(32);
    printf("malloc: %p \n", data.ptr);

    assert(data.ptr != NULL);

    allocator.wrapped_free(data.ptr);
    printf("free: %p \n", data.ptr);

    printf("\n==================================================== \n");
}

// Test for the workload classes. This test count and validate the number or
// runs.
void test_workload(Workload &workload, const int N, const char *workload_name)
{
    printf("\n============= Work load (%s) test ============= \n",
           workload_name);

    assert(
        workload
            .run()); // Do "single" memory operation (allocate or deallocate).

    int i;
    for (i = 1; workload.run(); i++)
        ; // Do the rest of operations.
    assert(i == N);

    printf("\n==================================================== \n");
}

// Simulate time consuming memory operation.
memory_operation time_consuming_memory_operation(unsigned int seconds)
{
    size_t size;

    START_TEST(0, 0)
    sleep(seconds);
    END_TEST
}

// This test check if timer has measured time.
void test_timer()
{
    float total_time = time_consuming_memory_operation(2).total_time;

    bool test_res = (total_time >= 2.0) && (total_time < 2.2);
    if (!test_res)
        printf("test_timer(): unexpected timing %f", total_time);
    assert(test_res);
}

// Test for iterators. Check the number of iterations, such as:
// N == number of iterations.
template <class T>
void test_iterator(Iterator<T> &it, const int N)
{
    printf("\n================= Iterator test ==================== \n");

    assert(it.size() == N);
    int i;
    for (i = 0; it.has_next(); i++) {
        it.next();
    }
    printf("iterations=%d/%d\n", i, N);
    assert(i == N);

    printf("\n==================================================== \n");
}

// This test validate range of values generated by random generators.
template <class T, class C>
void test_iterator_values(VectorIterator<T> &it, const C from, const C to)
{
    for (int i = 0; it.has_next(); i++) {
        T val = it.next();

        if (val < from)
            std::cout << "ivalid value: actual=" << val
                      << ", expected= >=" << from << std::endl;

        if (val > to)
            std::cout << "ivalid value: actual=" << val
                      << ", expected= <=" << to << std::endl;
    }
}

// Test time counting instrumentation in StandardAllocatorWithTimer.
// The instrumentation is made with START_TEST and END_TEST macros from
// WrapperMacros.h.
void test_allocator_with_timer(int N, int seed)
{
    printf("\n============= Allocator with timer test ============= \n");

    StandardAllocatorWithTimer allocator;
    VectorIterator<size_t> allocation_sizes =
        AllocationSizes::generate_random_sizes(N, 32, 2048, seed);
    memory_operation data;

    double elaspsed_time = 0;
    for (int i = 0; i < N; i++) {
        data = allocator.wrapped_malloc(allocation_sizes.next());
        elaspsed_time += data.total_time;
        allocator.wrapped_free(data.ptr);
    }

    printf("%d allocations and frees done in time: %f \n", N, elaspsed_time);

    printf("\n==================================================== \n");
}

// Test behavior of TypesConfiguration class, by enabling and disabling types.
void test_types_conf()
{
    TypesConf types;

    for (unsigned i = 0; i < FunctionCalls::NUM_OF_FUNCTIONS; i++) {
        types.enable_type(i);
        assert(types.is_enabled(i));
        types.disable_type(i);
        assert(!types.is_enabled(i));
    }
}

void execute_self_tests()
{
    const int N = 10000;
    const size_t size_from = 32, size_to = 2048;
    const unsigned seed = 11;

    test_types_conf();

    {
        VectorIterator<size_t> it =
            AllocationSizes::generate_random_sizes(N, size_from, size_to, seed);
        test_iterator_values(it, size_from, size_to);
    }

    {
        TypesConf enable_func_calls;
        enable_func_calls.enable_type(FunctionCalls::MALLOC);

        VectorIterator<int> it =
            FunctionCalls::generate_random_allocator_func_calls(
                N, seed, enable_func_calls);
        test_iterator(it, N);
    }

// Timer implementation __cplusplus < 201100L is based on CPU clocks counting
// and it will fail on this test.
#if __cplusplus > 201100L
    test_timer();
#endif

    printf("Test completed! (press ENTER to continue)\n");
}