1 #include <test.h>
2 
3 #include <item_lib.h>
4 #include <misc_lib.h>                                          /* xsnprintf */
5 #include <server.h>
6 #include <server_common.h>
7 
8 
9 #include <server.c>                                  /* PurgeOldConnections */
10 
11 
12 const int CONNECTION_MAX_AGE_SECONDS = SECONDS_PER_HOUR * 2;
13 
14 /* NOTE: Invalid memory access has been seen in PurgeOldConnections().
15          This does not always result in a segfault, but running this test
16          in valgrind will detect it.                                     */
17 
18 
test_purge_old_connections_nochange(void)19 static void test_purge_old_connections_nochange(void)
20 {
21     const time_t time_now = 100000;
22 
23     Item *connections = NULL;
24     char time_str[64];
25 
26     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS);
27     PrependItem(&connections, "123.123.123.3", time_str);
28 
29     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 1);
30     PrependItem(&connections, "123.123.123.2", time_str);
31 
32     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 100);
33     PrependItem(&connections, "123.123.123.1", time_str);
34 
35     assert_int_equal(ListLen(connections), 3);
36 
37     PurgeOldConnections(&connections, time_now);
38 
39     assert_int_equal(ListLen(connections), 3);
40 
41     assert_true(IsItemIn(connections, "123.123.123.1"));
42     assert_true(IsItemIn(connections, "123.123.123.2"));
43     assert_true(IsItemIn(connections, "123.123.123.3"));
44 
45     DeleteItemList(connections);
46 }
47 
48 
test_purge_old_connections_purge_first(void)49 static void test_purge_old_connections_purge_first(void)
50 {
51     const time_t time_now = 100000;
52 
53     Item *connections = NULL;
54     char time_str[64];
55 
56     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 100);
57     PrependItem(&connections, "123.123.123.3", time_str);
58 
59     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 2);
60     PrependItem(&connections, "123.123.123.2", time_str);
61 
62     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS - 5);
63     PrependItem(&connections, "123.123.123.1", time_str);
64 
65     assert_int_equal(ListLen(connections), 3);
66 
67     PurgeOldConnections(&connections, time_now);
68 
69     assert_int_equal(ListLen(connections), 2);
70 
71     assert_false(IsItemIn(connections, "123.123.123.1"));
72     assert_true(IsItemIn(connections, "123.123.123.2"));
73     assert_true(IsItemIn(connections, "123.123.123.3"));
74 
75     DeleteItemList(connections);
76 }
77 
78 
test_purge_old_connections_purge_middle(void)79 static void test_purge_old_connections_purge_middle(void)
80 {
81     const time_t time_now = 100000;
82 
83     Item *connections = NULL;
84     char time_str[64];
85 
86     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS);
87     PrependItem(&connections, "123.123.123.3", time_str);
88 
89     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS - 1);
90     PrependItem(&connections, "123.123.123.2", time_str);
91 
92     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 100);
93     PrependItem(&connections, "123.123.123.1", time_str);
94 
95     assert_int_equal(ListLen(connections), 3);
96 
97     PurgeOldConnections(&connections, time_now);
98 
99     assert_int_equal(ListLen(connections), 2);
100 
101     assert_true(IsItemIn(connections, "123.123.123.1"));
102     assert_false(IsItemIn(connections, "123.123.123.2"));
103     assert_true(IsItemIn(connections, "123.123.123.3"));
104 
105     DeleteItemList(connections);
106 }
107 
108 
test_purge_old_connections_purge_last(void)109 static void test_purge_old_connections_purge_last(void)
110 {
111     const time_t time_now = 100000;
112 
113     Item *connections = NULL;
114     char time_str[64];
115 
116     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS - 100);
117     PrependItem(&connections, "123.123.123.3", time_str);
118 
119     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 10);
120     PrependItem(&connections, "123.123.123.2", time_str);
121 
122     xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS);
123     PrependItem(&connections, "123.123.123.1", time_str);
124 
125     assert_int_equal(ListLen(connections), 3);
126 
127     PurgeOldConnections(&connections, time_now);
128 
129     assert_int_equal(ListLen(connections), 2);
130 
131     assert_true(IsItemIn(connections, "123.123.123.1"));
132     assert_true(IsItemIn(connections, "123.123.123.2"));
133     assert_false(IsItemIn(connections, "123.123.123.3"));
134 
135     DeleteItemList(connections);
136 }
137 
138 
main()139 int main()
140 {
141     PRINT_TEST_BANNER();
142     const UnitTest tests[] =
143     {
144         unit_test(test_purge_old_connections_nochange),
145         unit_test(test_purge_old_connections_purge_first),
146         unit_test(test_purge_old_connections_purge_middle),
147         unit_test(test_purge_old_connections_purge_last)
148     };
149 
150     return run_tests(tests);
151 }
152