mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 07:55:06 -05:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5828426977 | ||
|
|
d04fb4b7fa | ||
|
|
f5fe3ab4a1 | ||
|
|
6b6b097fe8 | ||
|
|
4998afc9bb | ||
|
|
80f4d75968 | ||
|
|
910663c37b | ||
|
|
34a4695e81 | ||
|
|
fe00319f45 | ||
|
|
4c77d18416 | ||
|
|
a63e18edb8 | ||
|
|
8b676502de | ||
|
|
cf5b344ea8 | ||
|
|
4ab98f62e9 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -22,3 +22,6 @@ tags
|
||||
/version.h
|
||||
/test/simulation/clknetsim
|
||||
/test/simulation/tmp
|
||||
/test/unit/Makefile
|
||||
/test/unit/*.test
|
||||
/test/unit/*.o
|
||||
|
||||
@@ -120,6 +120,7 @@ install: chronyd chronyc
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -S $<
|
||||
|
||||
check : chronyd chronyc
|
||||
$(MAKE) -C test/unit check
|
||||
cd test/simulation && ./run
|
||||
|
||||
install-docs : docs
|
||||
|
||||
114
addrfilt.c
114
addrfilt.c
@@ -401,117 +401,3 @@ ADF_IsAnyAllowed(ADF_AuthTable table, int family)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#if defined TEST
|
||||
|
||||
static void print_node(TableNode *node, uint32_t *addr, int ip_len, int shift, int subnet_bits)
|
||||
{
|
||||
uint32_t new_addr[4];
|
||||
int i;
|
||||
TableNode *sub_node;
|
||||
|
||||
for (i=0; i<subnet_bits; i++) putchar(' ');
|
||||
|
||||
if (ip_len == 1)
|
||||
printf("%d.%d.%d.%d",
|
||||
((addr[0] >> 24) & 255),
|
||||
((addr[0] >> 16) & 255),
|
||||
((addr[0] >> 8) & 255),
|
||||
((addr[0] ) & 255));
|
||||
else {
|
||||
for (i=0; i<4; i++) {
|
||||
if (addr[i])
|
||||
printf("%d.%d.%d.%d",
|
||||
((addr[i] >> 24) & 255),
|
||||
((addr[i] >> 16) & 255),
|
||||
((addr[i] >> 8) & 255),
|
||||
((addr[i] ) & 255));
|
||||
putchar(i < 3 ? ':' : '\0');
|
||||
}
|
||||
}
|
||||
printf("/%d : %s\n",
|
||||
subnet_bits,
|
||||
(node->state == ALLOW) ? "allow" :
|
||||
(node->state == DENY) ? "deny" : "as parent");
|
||||
if (node->extended) {
|
||||
for (i=0; i<16; i++) {
|
||||
sub_node = &(node->extended[i]);
|
||||
new_addr[0] = addr[0];
|
||||
new_addr[1] = addr[1];
|
||||
new_addr[2] = addr[2];
|
||||
new_addr[3] = addr[3];
|
||||
new_addr[ip_len - 1 - shift / 32] |= ((uint32_t)i << (shift % 32));
|
||||
print_node(sub_node, new_addr, ip_len, shift - 4, subnet_bits + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void print_table(ADF_AuthTable table)
|
||||
{
|
||||
uint32_t addr[4];
|
||||
|
||||
memset(addr, 0, sizeof (addr));
|
||||
printf("IPv4 table:\n");
|
||||
print_node(&table->base4, addr, 1, 28, 0);
|
||||
|
||||
memset(addr, 0, sizeof (addr));
|
||||
printf("IPv6 table:\n");
|
||||
print_node(&table->base6, addr, 4, 124, 0);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
IPAddr ip;
|
||||
ADF_AuthTable table;
|
||||
table = ADF_CreateTable();
|
||||
|
||||
ip.family = IPADDR_INET4;
|
||||
|
||||
ip.addr.in4 = 0x7e800000;
|
||||
ADF_Allow(table, &ip, 9);
|
||||
ip.addr.in4 = 0x7ecc0000;
|
||||
ADF_Deny(table, &ip, 14);
|
||||
#if 0
|
||||
ip.addr.in4 = 0x7f000001;
|
||||
ADF_Deny(table, &ip, 32);
|
||||
ip.addr.in4 = 0x7f000000;
|
||||
ADF_Allow(table, &ip, 8);
|
||||
#endif
|
||||
|
||||
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||
ip.addr.in4 ^= 1;
|
||||
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||
|
||||
ip.family = IPADDR_INET6;
|
||||
|
||||
memcpy(ip.addr.in6, "abcdefghijklmnop", 16);
|
||||
ADF_Deny(table, &ip, 66);
|
||||
ADF_Allow(table, &ip, 59);
|
||||
|
||||
memcpy(ip.addr.in6, "xbcdefghijklmnop", 16);
|
||||
ADF_Deny(table, &ip, 128);
|
||||
ip.addr.in6[15] ^= 3;
|
||||
ADF_Allow(table, &ip, 127);
|
||||
|
||||
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||
ip.addr.in4 ^= 1;
|
||||
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||
|
||||
print_table(table);
|
||||
|
||||
ADF_DestroyTable(table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* defined TEST */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -339,9 +339,16 @@ for C-family shells.
|
||||
If the software cannot (yet) be built on your system, an error message
|
||||
will be shown. Otherwise, @file{Makefile} will be generated.
|
||||
|
||||
If editline or readline library is available, chronyc will be built with line
|
||||
editing support. If you don't want this, specify the --disable-readline flag
|
||||
to configure. Please refer to @pxref{line editing support} for more information.
|
||||
On Linux, if development files for the libcap library are available,
|
||||
@code{chronyd} will be built with support for dropping root privileges.
|
||||
On other systems no extra library is needed. The default user which
|
||||
@code{chronyd} should run as can be specified with the @code{--with-user}
|
||||
option of the configure script.
|
||||
|
||||
If development files for the editline or readline library are available,
|
||||
@code{chronyc} will be built with line editing support. If you don't want
|
||||
this, specify the --disable-readline flag to configure. Please refer to
|
||||
@pxref{line editing support} for more information.
|
||||
|
||||
If a @file{timepps.h} header is available (e.g. from the
|
||||
@uref{http://linuxpps.org/, LinuxPPS project}), @code{chronyd} will be built with PPS API
|
||||
@@ -407,7 +414,11 @@ makestep 1.0 3
|
||||
rtcsync
|
||||
@end example
|
||||
|
||||
Then, @code{chronyd} can be run.
|
||||
Then, @code{chronyd} can be run. For security reasons, it's recommended to
|
||||
create an unprivileged user for @code{chronyd} and specify it with the
|
||||
@code{-u} command-line option or the @code{user} directive in the configuration
|
||||
file, or set the default user with the @code{--with-user} configure option
|
||||
before building.
|
||||
@c }}}
|
||||
@menu
|
||||
* line editing support:: If libraries are in a non-standard place
|
||||
@@ -2790,9 +2801,9 @@ Prefer this source over sources without prefer option.
|
||||
Never select this source. This is useful for monitoring or with sources
|
||||
which are not very accurate, but are locked with a PPS refclock.
|
||||
@item trust
|
||||
Assume time from this source is always true. It can't be rejected as a
|
||||
falseticker in the source selection if sources that are specified without this
|
||||
option don't agree with it.
|
||||
Assume time from this source is always true. It can be rejected as a
|
||||
falseticker in the source selection only if another source with this option
|
||||
doesn't agree with it.
|
||||
@item require
|
||||
Require that at least one of the sources specified with this option is
|
||||
selectable (i.e. recently reachable and not a falseticker) before updating the
|
||||
@@ -3106,9 +3117,9 @@ Prefer this source over sources without prefer option.
|
||||
Never select this source. This is particularly useful for monitoring.
|
||||
|
||||
@item trust
|
||||
Assume time from this source is always true. It can't be rejected as a
|
||||
falseticker in the source selection if sources that are specified without this
|
||||
option don't agree with it.
|
||||
Assume time from this source is always true. It can be rejected as a
|
||||
falseticker in the source selection only if another source with this option
|
||||
doesn't agree with it.
|
||||
|
||||
@item require
|
||||
Require that at least one of the sources specified with this option is
|
||||
|
||||
2
configure
vendored
2
configure
vendored
@@ -848,7 +848,7 @@ fi
|
||||
|
||||
add_def CHRONY_VERSION "\"${CHRONY_VERSION}\""
|
||||
|
||||
for f in Makefile chrony.conf.5 chrony.texi chronyc.1 chronyd.8
|
||||
for f in Makefile test/unit/Makefile chrony.conf.5 chrony.texi chronyc.1 chronyd.8
|
||||
do
|
||||
echo Creating $f
|
||||
sed -e "s%@EXTRA_OBJECTS@%${EXTRA_OBJECTS}%;\
|
||||
|
||||
@@ -51,7 +51,7 @@ awk '/^[1-9] Installation$/{p=1}
|
||||
/^[1-9]\.. Support for line editing/{exit}; p' chrony.txt | \
|
||||
tail -n +4 > INSTALL
|
||||
|
||||
if [ $(wc -l < INSTALL) -gt 100 -o $(wc -l < INSTALL) -lt 85 ]; then
|
||||
if [ $(wc -l < INSTALL) -gt 120 -o $(wc -l < INSTALL) -lt 85 ]; then
|
||||
echo "INSTALL generated incorrectly?"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "default test settings"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "large network"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "large frequency offset"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "large time offset"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "external time step"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "large jitter"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "large wander"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "NTP eras"
|
||||
|
||||
# Assume NTP_ERA_SPLIT is between years 1960 and 1990
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "source selection"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "minpoll/maxpoll options"
|
||||
|
||||
wander=0.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "iburst option"
|
||||
|
||||
freq_offset=1e-4
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "initstepslew directive"
|
||||
|
||||
freq_offset=0.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "driftfile directive"
|
||||
|
||||
servers=0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "NTP authentication"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "SHM refclock"
|
||||
|
||||
servers=0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "allow/deny directives"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "NTP peers"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "makestep directive"
|
||||
|
||||
client_conf="makestep 0 -1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "chronyc"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "reply to client configured as server"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "port and acquisitionport directives"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "leap second"
|
||||
|
||||
export CLKNETSIM_START_DATE=$(TZ=UTC date -d 'Dec 30 2008 0:00:00' +'%s')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "presend option"
|
||||
|
||||
min_sync_time=140
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "cmdmon timestamps"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "minsources directive"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "fallback drift"
|
||||
|
||||
limit=100000
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "maxdelay options"
|
||||
|
||||
max_sync_time=2000
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
test_start "smoothtime option"
|
||||
|
||||
server_strata=2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
test_start "source selection options"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
# Test fix in commit 60d0fa299307076143da94d36deb7b908fa9bdb7
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
. ./test.common
|
||||
|
||||
# Test fix in commit 4253075a97141edfa62043ab71bd0673587e6629
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
This is a collection of simulation tests. They use clknetsim to simulate
|
||||
multiple systems connected in a network. It's available at
|
||||
This is a collection of simulation tests using the clknetsim simulator
|
||||
(supported on Linux only).
|
||||
|
||||
https://github.com/mlichvar/clknetsim
|
||||
|
||||
If this directory doesn't have a clknetsim subdirectory, a known working
|
||||
revision will be downloaded and compiled automatically.
|
||||
|
||||
Currently it runs only on Linux.
|
||||
The CLKNETSIM_PATH environment variable should point to the directory where
|
||||
clknetsim was downloaded and compiled. If the variable is not set, the tests
|
||||
will look for clknetsim in ./clknetsim in the current directory.
|
||||
|
||||
The tests are written in bash and they can be run directly. The ./run script
|
||||
runs all tests.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
. test.common
|
||||
|
||||
passed=() failed=() skipped=()
|
||||
|
||||
[ $# -gt 0 ] && tests=($@) || tests=([0-9]*-*[^_])
|
||||
|
||||
@@ -15,27 +15,11 @@
|
||||
|
||||
export LC_ALL=C
|
||||
export PATH=../../:$PATH
|
||||
export CLKNETSIM_PATH=clknetsim
|
||||
export CLKNETSIM_PATH=${CLKNETSIM_PATH:-clknetsim}
|
||||
|
||||
# Known working clknetsim revision
|
||||
clknetsim_revision=1e56224dee1db69c0027e9bd63c2a202d4765959
|
||||
clknetsim_url=https://github.com/mlichvar/clknetsim/archive/$clknetsim_revision.tar.gz
|
||||
|
||||
# Only Linux is supported
|
||||
if [ "$(uname -s)" != Linux ]; then
|
||||
echo "Simulation tests supported only on Linux"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# Try to download clknetsim if not found
|
||||
if [ ! -e $CLKNETSIM_PATH ]; then
|
||||
curl -L "$clknetsim_url" | tar xz || exit 3
|
||||
ln -s clknetsim-$clknetsim_revision clknetsim || exit 3
|
||||
fi
|
||||
|
||||
# Try to build clknetsim if not built
|
||||
if [ ! -x $CLKNETSIM_PATH/clknetsim -o ! -e $CLKNETSIM_PATH/clknetsim.so ]; then
|
||||
make -C clknetsim || exit 3
|
||||
if [ ! -x $CLKNETSIM_PATH/clknetsim ]; then
|
||||
echo "SKIP (clknetsim not found)"
|
||||
exit 9
|
||||
fi
|
||||
|
||||
. $CLKNETSIM_PATH/clknetsim.bash
|
||||
|
||||
42
test/unit/Makefile.in
Normal file
42
test/unit/Makefile.in
Normal file
@@ -0,0 +1,42 @@
|
||||
TEST_WRAPPER =
|
||||
CHRONY_SRCDIR = ../..
|
||||
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = -I$(CHRONY_SRCDIR) @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@ @LIBS@ @EXTRA_LIBS@
|
||||
|
||||
SHARED_OBJS = test.o
|
||||
|
||||
TEST_OBJS := $(sort $(patsubst %.c,%.o,$(wildcard *.c)))
|
||||
TESTS := $(patsubst %.o,%.test,$(filter-out $(SHARED_OBJS),$(TEST_OBJS)))
|
||||
|
||||
FILTER_OBJS = %/main.o %/client.o %/getdate.o
|
||||
CHRONY_OBJS := $(filter-out $(FILTER_OBJS),$(wildcard $(CHRONY_SRCDIR)/*.o))
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
%.test: %.o $(SHARED_OBJS)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(CHRONY_OBJS:%/$*.o=) $(LDFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $<
|
||||
|
||||
check: $(TESTS)
|
||||
@ret=0; \
|
||||
for t in $^; do \
|
||||
$(TEST_WRAPPER) ./$$t || ret=1; \
|
||||
done; \
|
||||
exit $$ret
|
||||
|
||||
clean:
|
||||
rm -f *.o $(TESTS)
|
||||
rm -rf .deps
|
||||
|
||||
.deps:
|
||||
@mkdir .deps
|
||||
|
||||
.deps/%.d: %.c | .deps
|
||||
@$(CC) -MM $(CPPFLAGS) -MT '$(<:%.c=%.o) $@' $< -o $@
|
||||
|
||||
-include $(TEST_OBJS:%.o=.deps/%.d)
|
||||
83
test/unit/addrfilt.c
Normal file
83
test/unit/addrfilt.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2016
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <addrfilt.c>
|
||||
#include <logging.h>
|
||||
#include <util.h>
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_unit(void)
|
||||
{
|
||||
int i, j, sub, maxsub;
|
||||
IPAddr ip;
|
||||
ADF_AuthTable table;
|
||||
|
||||
table = ADF_CreateTable();
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
for (j = 0; j < 1000; j++) {
|
||||
if (j % 2) {
|
||||
maxsub = 32;
|
||||
TST_GetRandomAddress(&ip, IPADDR_INET4, -1);
|
||||
} else {
|
||||
maxsub = 128;
|
||||
TST_GetRandomAddress(&ip, IPADDR_INET6, -1);
|
||||
}
|
||||
|
||||
DEBUG_LOG(0, "address %s", UTI_IPToString(&ip));
|
||||
|
||||
sub = random() % (maxsub + 1);
|
||||
|
||||
TEST_CHECK(!ADF_IsAllowed(table, &ip));
|
||||
ADF_Allow(table, &ip, sub);
|
||||
TEST_CHECK(ADF_IsAllowed(table, &ip));
|
||||
|
||||
if (sub < maxsub) {
|
||||
TST_SwapAddressBit(&ip, sub);
|
||||
TEST_CHECK(ADF_IsAllowed(table, &ip));
|
||||
}
|
||||
|
||||
if (sub > 0) {
|
||||
TST_SwapAddressBit(&ip, sub - 1);
|
||||
TEST_CHECK(!ADF_IsAllowed(table, &ip));
|
||||
if (sub % 4 != 1) {
|
||||
ADF_Deny(table, &ip, sub - 1);
|
||||
TST_SwapAddressBit(&ip, sub - 1);
|
||||
TEST_CHECK(!ADF_IsAllowed(table, &ip));
|
||||
}
|
||||
}
|
||||
|
||||
if (sub > 4) {
|
||||
ADF_AllowAll(table, &ip, sub - 4);
|
||||
TEST_CHECK(ADF_IsAllowed(table, &ip));
|
||||
}
|
||||
|
||||
ADF_DenyAll(table, &ip, 0);
|
||||
}
|
||||
|
||||
ip.family = IPADDR_INET4;
|
||||
ADF_DenyAll(table, &ip, 0);
|
||||
ip.family = IPADDR_INET6;
|
||||
ADF_DenyAll(table, &ip, 0);
|
||||
}
|
||||
|
||||
ADF_DestroyTable(table);
|
||||
}
|
||||
84
test/unit/clientlog.c
Normal file
84
test/unit/clientlog.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2016
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <clientlog.c>
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_unit(void)
|
||||
{
|
||||
int i, j, index;
|
||||
struct timeval tv;
|
||||
IPAddr ip;
|
||||
char conf[][100] = {
|
||||
"clientloglimit 10000",
|
||||
"ratelimit interval 3 burst 4 leak 3",
|
||||
"cmdratelimit interval 3 burst 4 leak 3",
|
||||
};
|
||||
|
||||
CNF_Initialise(0);
|
||||
for (i = 0; i < sizeof conf / sizeof conf[0]; i++)
|
||||
CNF_ParseLine(NULL, i + 1, conf[i]);
|
||||
|
||||
CLG_Initialise();
|
||||
|
||||
TEST_CHECK(ARR_GetSize(records) == 16);
|
||||
|
||||
for (i = 0; i < 500; i++) {
|
||||
DEBUG_LOG(0, "iteration %d", i);
|
||||
|
||||
tv.tv_sec = (time_t)random() & 0x0fffffff;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
for (j = 0; j < 1000; j++) {
|
||||
TST_GetRandomAddress(&ip, IPADDR_UNSPEC, i % 8 ? -1 : i / 8 % 9);
|
||||
DEBUG_LOG(0, "address %s", UTI_IPToString(&ip));
|
||||
|
||||
if (random() % 2) {
|
||||
index = CLG_LogNTPAccess(&ip, &tv);
|
||||
TEST_CHECK(index >= 0);
|
||||
CLG_LimitNTPResponseRate(index);
|
||||
} else {
|
||||
index = CLG_LogCommandAccess(&ip, &tv);
|
||||
TEST_CHECK(index >= 0);
|
||||
CLG_LimitCommandResponseRate(index);
|
||||
}
|
||||
|
||||
UTI_AddDoubleToTimeval(&tv, (1 << random() % 14) / 100.0, &tv);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(0, "records %d", ARR_GetSize(records));
|
||||
TEST_CHECK(ARR_GetSize(records) == 128);
|
||||
|
||||
for (i = j = 0; i < 10000; i++) {
|
||||
tv.tv_sec += 1;
|
||||
index = CLG_LogNTPAccess(&ip, &tv);
|
||||
TEST_CHECK(index >= 0);
|
||||
if (!CLG_LimitNTPResponseRate(index))
|
||||
j++;
|
||||
}
|
||||
|
||||
DEBUG_LOG(0, "requests %u responses %u", i, j);
|
||||
TEST_CHECK(j * 4 < i && j * 6 > i);
|
||||
|
||||
CLG_Finalise();
|
||||
CNF_Finalise();
|
||||
}
|
||||
99
test/unit/ntp_sources.c
Normal file
99
test/unit/ntp_sources.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2016
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <ntp_sources.c>
|
||||
#include <conf.h>
|
||||
#include <ntp_io.h>
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_unit(void)
|
||||
{
|
||||
int i, j, k, slot, found;
|
||||
uint32_t hash = 0;
|
||||
NTP_Remote_Address addrs[256], addr;
|
||||
SourceParameters params;
|
||||
char conf[] = "port 0";
|
||||
|
||||
memset(¶ms, 0, sizeof (params));
|
||||
|
||||
CNF_Initialise(0);
|
||||
CNF_ParseLine(NULL, 1, conf);
|
||||
|
||||
LCL_Initialise();
|
||||
SCH_Initialise();
|
||||
SRC_Initialise();
|
||||
NIO_Initialise(IPADDR_UNSPEC);
|
||||
NCR_Initialise();
|
||||
NSR_Initialise();
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
TEST_CHECK(ARR_GetSize(records) == 1);
|
||||
|
||||
DEBUG_LOG(0, "collision mod %u", 1U << i);
|
||||
|
||||
for (j = 0; j < sizeof (addrs) / sizeof (addrs[0]); j++) {
|
||||
do {
|
||||
TST_GetRandomAddress(&addrs[j].ip_addr, IPADDR_UNSPEC, -1);
|
||||
} while (UTI_IPToHash(&addrs[j].ip_addr) % (1U << i) != hash % (1U << i));
|
||||
|
||||
addrs[j].port = random() % 1024;
|
||||
|
||||
if (!j)
|
||||
hash = UTI_IPToHash(&addrs[j].ip_addr);
|
||||
|
||||
DEBUG_LOG(0, "adding source %s hash %"PRIu32, UTI_IPToString(&addrs[j].ip_addr),
|
||||
UTI_IPToHash(&addrs[j].ip_addr) % (1U << i));
|
||||
|
||||
NSR_AddSource(&addrs[j], random() % 2 ? NTP_SERVER : NTP_PEER, ¶ms);
|
||||
|
||||
for (k = 0; k < j; k++) {
|
||||
addr = addrs[k];
|
||||
find_slot(&addr, &slot, &found);
|
||||
TEST_CHECK(found == 2);
|
||||
TEST_CHECK(!UTI_CompareIPs(&get_record(slot)->remote_addr->ip_addr,
|
||||
&addr.ip_addr, NULL));
|
||||
addr.port++;
|
||||
find_slot(&addr, &slot, &found);
|
||||
TEST_CHECK(found == 1);
|
||||
TEST_CHECK(!UTI_CompareIPs(&get_record(slot)->remote_addr->ip_addr,
|
||||
&addr.ip_addr, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < sizeof (addrs) / sizeof (addrs[0]); j++) {
|
||||
DEBUG_LOG(0, "removing source %s", UTI_IPToString(&addrs[j].ip_addr));
|
||||
NSR_RemoveSource(&addrs[j]);
|
||||
|
||||
for (k = 0; k < sizeof (addrs) / sizeof (addrs[0]); k++) {
|
||||
find_slot(&addrs[k], &slot, &found);
|
||||
TEST_CHECK(found == (k <= j ? 0 : 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSR_Finalise();
|
||||
NCR_Finalise();
|
||||
NIO_Finalise();
|
||||
SRC_Finalise();
|
||||
SCH_Finalise();
|
||||
LCL_Finalise();
|
||||
CNF_Finalise();
|
||||
}
|
||||
137
test/unit/sources.c
Normal file
137
test/unit/sources.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2016
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <sources.c>
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_unit(void)
|
||||
{
|
||||
SRC_Instance srcs[16];
|
||||
RPT_SourceReport report;
|
||||
IPAddr addr;
|
||||
int i, j, k, l, samples, sel_options;
|
||||
double offset, delay, disp;
|
||||
struct timeval tv;
|
||||
|
||||
CNF_Initialise(0);
|
||||
LCL_Initialise();
|
||||
TST_RegisterDummyDrivers();
|
||||
SCH_Initialise();
|
||||
SRC_Initialise();
|
||||
REF_Initialise();
|
||||
|
||||
REF_SetMode(REF_ModeIgnore);
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
DEBUG_LOG(0, "iteration %d", i);
|
||||
|
||||
for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) {
|
||||
TEST_CHECK(n_sources == j);
|
||||
|
||||
TST_GetRandomAddress(&addr, IPADDR_UNSPEC, -1);
|
||||
|
||||
sel_options = i & random() & (SRC_SELECT_NOSELECT | SRC_SELECT_PREFER |
|
||||
SRC_SELECT_TRUST | SRC_SELECT_REQUIRE);
|
||||
|
||||
DEBUG_LOG(0, "added source %d options %d", j, sel_options);
|
||||
srcs[j] = SRC_CreateNewInstance(UTI_IPToRefid(&addr), SRC_NTP, sel_options, &addr,
|
||||
SRC_DEFAULT_MINSAMPLES, SRC_DEFAULT_MAXSAMPLES);
|
||||
SRC_UpdateReachability(srcs[j], 1);
|
||||
|
||||
samples = (i + j) % 5 + 3;
|
||||
|
||||
offset = TST_GetRandomDouble(-1.0, 1.0);
|
||||
|
||||
for (k = 0; k < samples; k++) {
|
||||
SCH_GetLastEventTime(&tv, NULL, NULL);
|
||||
UTI_AddDoubleToTimeval(&tv, TST_GetRandomDouble(k - samples, k - samples + 1), &tv);
|
||||
|
||||
offset += TST_GetRandomDouble(-1.0e-2, 1.0e-2);
|
||||
delay = TST_GetRandomDouble(1.0e-6, 1.0e-1);
|
||||
disp = TST_GetRandomDouble(1.0e-6, 1.0e-1);
|
||||
|
||||
DEBUG_LOG(0, "source %d sample %d offset %f delay %f disp %f", j, k,
|
||||
offset, delay, disp);
|
||||
|
||||
SRC_AccumulateSample(srcs[j], &tv, offset, delay, disp, delay, disp,
|
||||
1, LEAP_Normal);
|
||||
}
|
||||
|
||||
for (k = 0; k <= j; k++) {
|
||||
int passed = 0, trusted = 0, trusted_passed = 0, required = 0, required_passed = 0;
|
||||
double trusted_lo = DBL_MAX, trusted_hi = DBL_MIN;
|
||||
double passed_lo = DBL_MAX, passed_hi = DBL_MIN;
|
||||
|
||||
SRC_SelectSource(srcs[k]);
|
||||
DEBUG_LOG(0, "source %d status %d", k, sources[k]->status);
|
||||
|
||||
for (l = 0; l <= j; l++) {
|
||||
TEST_CHECK(sources[l]->status > SRC_OK && sources[l]->status <= SRC_SELECTED);
|
||||
if (sources[l]->sel_options & SRC_SELECT_NOSELECT) {
|
||||
TEST_CHECK(sources[l]->status == SRC_UNSELECTABLE);
|
||||
} else if (sources[l]->status != SRC_BAD_DISTANCE) {
|
||||
if (sources[l]->status >= SRC_NONPREFERRED) {
|
||||
passed++;
|
||||
if (passed_lo > sources[l]->sel_info.lo_limit)
|
||||
passed_lo = sources[l]->sel_info.lo_limit;
|
||||
if (passed_hi < sources[l]->sel_info.hi_limit)
|
||||
passed_hi = sources[l]->sel_info.hi_limit;
|
||||
}
|
||||
if (sources[l]->sel_options & SRC_SELECT_TRUST) {
|
||||
trusted++;
|
||||
if (trusted_lo > sources[l]->sel_info.lo_limit)
|
||||
trusted_lo = sources[l]->sel_info.lo_limit;
|
||||
if (trusted_hi < sources[l]->sel_info.hi_limit)
|
||||
trusted_hi = sources[l]->sel_info.hi_limit;
|
||||
if (sources[l]->status >= SRC_NONPREFERRED)
|
||||
trusted_passed++;
|
||||
}
|
||||
if (sources[l]->sel_options & SRC_SELECT_REQUIRE) {
|
||||
required++;
|
||||
if (sources[l]->status >= SRC_NONPREFERRED)
|
||||
required_passed++;
|
||||
}
|
||||
if (sources[l]->sel_options & SRC_SELECT_PREFER)
|
||||
TEST_CHECK(sources[l]->status != SRC_NONPREFERRED);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(0, "sources %d passed %d trusted %d/%d required %d/%d", j, passed,
|
||||
trusted_passed, trusted, required_passed, required);
|
||||
|
||||
TEST_CHECK(!trusted || !passed || (passed_lo >= trusted_lo && passed_hi <= trusted_hi));
|
||||
TEST_CHECK(!passed || trusted != 1 || (trusted == 1 && trusted_passed == 1));
|
||||
TEST_CHECK(!passed || !required || required_passed > 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) {
|
||||
SRC_ReportSource(j, &report, &tv);
|
||||
SRC_DestroyInstance(srcs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
REF_Finalise();
|
||||
SRC_Finalise();
|
||||
SCH_Finalise();
|
||||
LCL_Finalise();
|
||||
CNF_Finalise();
|
||||
}
|
||||
165
test/unit/test.c
Normal file
165
test/unit/test.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2016
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <sysincl.h>
|
||||
#include <logging.h>
|
||||
#include <localp.h>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
TST_Fail(int line)
|
||||
{
|
||||
printf("FAIL (on line %d)\n", line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *test_name, *s;
|
||||
int i, seed = 0;
|
||||
struct timeval tv;
|
||||
|
||||
test_name = argv[0];
|
||||
s = strrchr(test_name, '.');
|
||||
if (s)
|
||||
*s = '\0';
|
||||
s = strrchr(test_name, '/');
|
||||
if (s)
|
||||
test_name = s + 1;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "-d")) {
|
||||
LOG_SetDebugLevel(2);
|
||||
} else if (!strcmp(argv[i], "-s") && i + 1 < argc) {
|
||||
seed = atoi(argv[++i]);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown option\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
srandom(seed ? seed : tv.tv_sec ^ (tv.tv_usec << 10));
|
||||
|
||||
printf("Testing %-30s ", test_name);
|
||||
fflush(stdout);
|
||||
|
||||
test_unit();
|
||||
|
||||
printf("PASS\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double
|
||||
TST_GetRandomDouble(double min, double max)
|
||||
{
|
||||
return min + (double)random() / RAND_MAX * (max - min);
|
||||
}
|
||||
|
||||
void
|
||||
TST_GetRandomAddress(IPAddr *ip, int family, int bits)
|
||||
{
|
||||
if (family != IPADDR_INET4 && family != IPADDR_INET6)
|
||||
family = random() % 2 ? IPADDR_INET4 : IPADDR_INET6;
|
||||
|
||||
ip->family = family;
|
||||
|
||||
if (family == IPADDR_INET4) {
|
||||
if (bits < 0)
|
||||
bits = 32;
|
||||
assert(bits <= 32);
|
||||
|
||||
if (bits > 16)
|
||||
ip->addr.in4 = (uint32_t)random() % (1U << (bits - 16)) << 16 |
|
||||
(uint32_t)random() % (1U << 16);
|
||||
else
|
||||
ip->addr.in4 = (uint32_t)random() % (1U << bits);
|
||||
} else {
|
||||
int i, b;
|
||||
|
||||
if (bits < 0)
|
||||
bits = 128;
|
||||
assert(bits <= 128);
|
||||
|
||||
for (i = 0, b = 120; i < 16; i++, b -= 8) {
|
||||
if (b >= bits) {
|
||||
ip->addr.in6[i] = 0;
|
||||
} else {
|
||||
ip->addr.in6[i] = random() % (1U << MIN(bits - b, 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TST_SwapAddressBit(IPAddr *ip, unsigned int b)
|
||||
{
|
||||
if (ip->family == IPADDR_INET4) {
|
||||
assert(b < 32);
|
||||
ip->addr.in4 ^= 1U << (31 - b);
|
||||
} else if (ip->family == IPADDR_INET6) {
|
||||
assert(b < 128);
|
||||
ip->addr.in6[b / 8] ^= 1U << (7 - b % 8);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static double
|
||||
read_frequency(void)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static double
|
||||
set_frequency(double freq_ppm)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static void
|
||||
accrue_offset(double offset, double corr_rate)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
apply_step_offset(double offset)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
offset_convert(struct timeval *raw, double *corr, double *err)
|
||||
{
|
||||
*corr = 0.0;
|
||||
if (err)
|
||||
*err = 0.0;
|
||||
}
|
||||
|
||||
void
|
||||
TST_RegisterDummyDrivers(void)
|
||||
{
|
||||
lcl_RegisterSystemDrivers(read_frequency, set_frequency, accrue_offset,
|
||||
apply_step_offset, offset_convert, NULL, NULL);
|
||||
}
|
||||
43
test/unit/test.h
Normal file
43
test/unit/test.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2016
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef GOT_TEST_H
|
||||
#define GOT_TEST_H
|
||||
|
||||
#include <addressing.h>
|
||||
|
||||
extern void test_unit(void);
|
||||
|
||||
#define TEST_CHECK(expr) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
TST_Fail(__LINE__); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
extern void TST_Fail(int line);
|
||||
|
||||
extern double TST_GetRandomDouble(double min, double max);
|
||||
extern void TST_GetRandomAddress(IPAddr *ip, int family, int bits);
|
||||
extern void TST_SwapAddressBit(IPAddr *ip, unsigned int b);
|
||||
extern void TST_RegisterDummyDrivers(void);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user