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
183
184
185
186
187
188
189
|
/*
Copyright (c) 2018-2019 AT&T Intellectual Property.
SPDX-License-Identifier: GPL-2.0-only
*/
#include <assert.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include "utils.h"
#define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
extern int *_tac_connect_fds;
extern int _tac_connect_fds_len;
struct tac_connect_call {
struct sockaddr server_addr;
struct sockaddr source_addr;
const char *key;
int timeout;
};
extern struct tac_connect_call *_tac_connect_calls;
extern int _tac_connect_call_count;
bool
ut_tac_connect_call_eq(struct tac_connect_call *a, struct tac_connect_call *b)
{
if (a->timeout != b->timeout)
return false;
if (a->key && b->key) {
if (strcmp(a->key, b->key) != 0)
return false;
}
else if (! (!a->key && !b->key)) {
return false;
}
if (memcmp(&a->server_addr, &b->server_addr, sizeof a->server_addr))
return false;
if (memcmp(&a->source_addr, &b->source_addr, sizeof a->source_addr))
return false;
return true;
}
void
ut_reset_tac_connect_wrapper()
{
for (int i = 0; i < _tac_connect_fds_len; i++)
free((void *)_tac_connect_calls[i].key);
free(_tac_connect_calls);
_tac_connect_calls = NULL;
_tac_connect_call_count = 0;
_tac_connect_fds = NULL;
_tac_connect_fds_len = 0;
}
void
ut_set_tac_connect_fds(int *fds, int fds_len)
{
_tac_connect_fds = fds;
_tac_connect_fds_len = fds_len;
assert(! _tac_connect_calls);
_tac_connect_calls = (struct tac_connect_call *) calloc(_tac_connect_fds_len,
sizeof(struct tac_connect_call));
assert(_tac_connect_calls);
}
int
ut_get_tac_connect_calls(struct tac_connect_call **calls)
{
*calls = _tac_connect_calls;
return _tac_connect_call_count;
}
/*
* Wrapper function for tac_connect_single()
*
* Use ut_set_tac_connect_fds() to set an array of return values for this
* function.
*
* Use ut_get_tac_connect_calls() to retrieve an array of tac_connect_call
* structs with the arguments from each call to tac_connect_single().
*/
int
__wrap_tac_connect_single(const struct addrinfo *server,
const char *key,
struct addrinfo *srcaddr,
int timeout)
{
if (! _tac_connect_fds)
return 9999;
assert(_tac_connect_call_count < _tac_connect_fds_len);
struct tac_connect_call *call = &_tac_connect_calls[_tac_connect_call_count];
if (server)
call->server_addr = *server->ai_addr;
if (srcaddr)
call->source_addr = *srcaddr->ai_addr;
call->key = key ? strdup(key) : NULL;
call->timeout = timeout;
return _tac_connect_fds[_tac_connect_call_count++];
}
#define CHECK_TIMESPEC_VALS(T,S,N) \
{ \
LONGS_EQUAL(S, T.tv_sec); \
LONGS_EQUAL(N, T.tv_nsec); \
}
extern struct timespec _cur_time;
void
__wrap_cur_mono_time(struct timespec *ts)
{
*ts = _cur_time;
}
void
ut_set_cur_mono_time(time_t sec, long nsec)
{
_cur_time.tv_sec = sec;
_cur_time.tv_nsec = nsec;
}
void
ut_inc_cur_mono_time(time_t sec, long nsec)
{
ut_set_cur_mono_time(_cur_time.tv_sec + sec,
_cur_time.tv_nsec + nsec);
}
/*
* Wrapper around the online/offline APIs
*
* Piggybacking on the simulated UT "time" (_cur_time) gives a simple mechanism
* to simulate the service going on and offline in UTs.
*
* Upon request to go offline we store the "time" we expect to go back online
* ie. the current UT "time" plus the offline interval.
*
* Conversely on a request to go online we store the current UT "time".
*
* To determine whether we are on or offline we then simply check whether
* the current UT "time" is past the stored time (ie. when we expected to be
* offline until).
*/
extern struct timespec _offline_until;
bool
__wrap_tacplusd_go_online() {
_offline_until = _cur_time;
return true;
}
bool
__wrap_tacplusd_go_offline(const struct timespec *ts) {
struct timespec ts_copy = *ts;
timespec_normalise(&ts_copy);
_offline_until = _cur_time;
timespec_normalise(&_offline_until);
_offline_until.tv_sec += ts_copy.tv_sec;
_offline_until.tv_nsec += ts_copy.tv_nsec;
timespec_normalise(&_offline_until);
return true;
}
bool
__wrap_tacplusd_online() {
return timespec_cmp(&_cur_time, &_offline_until) >= 0;
}
|