-
Notifications
You must be signed in to change notification settings - Fork 67
/
Copy pathtest_stack.c
182 lines (139 loc) · 5.17 KB
/
test_stack.c
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
182
/*
* Copyright 2020 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#include "nr_axiom.h"
#include "util_stack.h"
#include "tlib_main.h"
static void test_bad_parameters(void) {
tlib_pass_if_true("A NULL stack is empty", nr_stack_is_empty(NULL),
"Expected true");
nr_stack_push(NULL, (void*)1);
tlib_pass_if_null("A NULL stack pops NULL", nr_stack_pop(NULL));
nr_stack_destroy_fields(NULL);
}
static void test_create_destroy(void) {
nr_stack_t s;
tlib_pass_if_true("A well-formed set of args must create a stack",
nr_stack_init(&s, 5), "Expected true");
nr_stack_destroy_fields(&s);
tlib_pass_if_int_equal("A destroyed stack should have 0 capacity", s.capacity,
0);
tlib_pass_if_int_equal("A destroyed stack should have 0 size", s.used, 0);
tlib_pass_if_false(
"An ill-formed set of args cannot create a stack (no capacity)",
nr_stack_init(&s, 0), "Expected false");
tlib_pass_if_false(
"An ill-formed set of args cannot create a stack (NULL ptr)",
nr_stack_init(NULL, 5), "Expected false");
}
static void test_push_pop(void) {
nr_stack_t s;
nr_stack_init(&s, 3);
tlib_pass_if_true("A newly-formed stack must be empty", nr_stack_is_empty(&s),
"Expected true");
tlib_pass_if_not_null(
"A newly-formed stack must have allocated memory for its elements",
s.elements);
tlib_pass_if_int_equal("A newly formed stack has a size of 0", s.used, 0);
tlib_pass_if_int_equal("A newly formed stack must have the stated capacity",
s.capacity, 3);
tlib_pass_if_null("Popping the top of an empty stack must yield NULL",
nr_stack_pop(&s));
nr_stack_push(&s, (void*)1);
nr_stack_push(&s, (void*)2);
nr_stack_push(&s, (void*)3);
tlib_pass_if_ptr_equal(
"Popping the top of the stack must yield the most-recently pushed item "
"(3)",
nr_stack_pop(&s), (void*)3);
tlib_pass_if_ptr_equal(
"Popping the top of the stack must yield the most-recently pushed item "
"(2)",
nr_stack_pop(&s), (void*)2);
tlib_pass_if_ptr_equal(
"Popping the top of the stack must yield the most-recently pushed item "
"(1)",
nr_stack_pop(&s), (void*)1);
tlib_pass_if_true("The stack must be empty", nr_stack_is_empty(&s),
"Expected true");
nr_stack_destroy_fields(&s);
}
static void test_push_pop_extended(void) {
nr_stack_t s;
intptr_t i = 0;
/* According to customer data research, the average depth of a trace is approx
* 32 segments. */
nr_stack_init(&s, 32);
for (i = 1; i < 100; i++) {
nr_stack_push(&s, (void*)i);
}
for (i = 99; i > 0; i--) {
tlib_pass_if_ptr_equal(
"Popping the top of the stack must yield the most-recently pushed "
"item ",
nr_stack_pop(&s), (void*)i);
}
nr_stack_destroy_fields(&s);
}
static void test_get(void) {
nr_stack_t s;
nr_stack_init(&s, 15);
tlib_pass_if_null("Getting the top of an empty stack must yield NULL",
nr_stack_get_top(&s));
nr_stack_push(&s, (void*)1);
tlib_pass_if_ptr_equal(
"Getting the top of a stack must yield the most recently pushed value",
nr_stack_get_top(&s), (void*)1);
tlib_pass_if_ptr_equal(
"Getting the top of a stack must yield the most recently pushed value "
"(again)",
nr_stack_get_top(&s), (void*)1);
nr_stack_destroy_fields(&s);
}
static void test_remove_topmost(void) {
nr_stack_t s;
nr_stack_init(&s, 15);
tlib_pass_if_bool_equal(
"Removing the topmost instance of an element on a NULL stack must fail",
false, nr_stack_remove_topmost(NULL, NULL));
tlib_pass_if_bool_equal(
"Removing the topmost instance of an element on an empty stack must fail",
false, nr_stack_remove_topmost(&s, NULL));
nr_stack_push(&s, (void*)1);
nr_stack_push(&s, (void*)2);
nr_stack_push(&s, (void*)3);
tlib_pass_if_bool_equal(
"Removing the topmost instance of an element that does not exist must "
"fail",
false, nr_stack_remove_topmost(&s, (void*)4));
tlib_pass_if_size_t_equal(
"Removing the topmost instance of an element that does not exist must "
"leave the stack in its original state",
3, s.used);
tlib_pass_if_bool_equal(
"Removing the topmost instance of an extant element must succeed", true,
nr_stack_remove_topmost(&s, (void*)2));
tlib_pass_if_size_t_equal(
"Removing the topmost instance of an extant element must actually remove "
"it",
2, s.used);
tlib_pass_if_ptr_equal(
"Removing the topmost instance of an extant element must not touch the "
"other elements",
(void*)1, nr_vector_get(&s, 0));
tlib_pass_if_ptr_equal(
"Removing the topmost instance of an extant element must not touch the "
"other elements",
(void*)3, nr_vector_get(&s, 1));
nr_stack_destroy_fields(&s);
}
tlib_parallel_info_t parallel_info = {.suggested_nthreads = 2, .state_size = 0};
void test_main(void* p NRUNUSED) {
test_bad_parameters();
test_create_destroy();
test_push_pop();
test_push_pop_extended();
test_get();
test_remove_topmost();
}