diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:09:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:09:41 +0000 |
commit | 3271d1ac389d2ec93db9c5b9ce0991ce478476cf (patch) | |
tree | 35ff7d180e1ccc061f28535d7435b5ba1789e734 /test/simulation | |
parent | Initial commit. (diff) | |
download | chrony-3271d1ac389d2ec93db9c5b9ce0991ce478476cf.tar.xz chrony-3271d1ac389d2ec93db9c5b9ce0991ce478476cf.zip |
Adding upstream version 4.3.upstream/4.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/simulation')
62 files changed, 3731 insertions, 0 deletions
diff --git a/test/simulation/001-defaults b/test/simulation/001-defaults new file mode 100755 index 0000000..b39d95c --- /dev/null +++ b/test/simulation/001-defaults @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "default test settings" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/002-largenetwork b/test/simulation/002-largenetwork new file mode 100755 index 0000000..a9e0ad8 --- /dev/null +++ b/test/simulation/002-largenetwork @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "large network" + +time_rms_limit=5e-4 + +server_strata=3 +servers=4 +clients=5 + +client_start=2000 +min_sync_time=2100 +max_sync_time=2300 + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/003-largefreqoffset b/test/simulation/003-largefreqoffset new file mode 100755 index 0000000..9381b1a --- /dev/null +++ b/test/simulation/003-largefreqoffset @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "large frequency offset" + +max_sync_time=1000 + +for freq_offset in -5e-2 -5e-3 5e-3 5e-2; do + # Adjust offset so it's close to 0 on first clock update + time_offset=$(awk "BEGIN {print -($freq_offset * 130)}") + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +test_pass diff --git a/test/simulation/004-largetimeoffset b/test/simulation/004-largetimeoffset new file mode 100755 index 0000000..4aebdd3 --- /dev/null +++ b/test/simulation/004-largetimeoffset @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "large time offset" + +min_sync_time=1300 +max_sync_time=1400 + +for time_offset in -1e2 1e2; do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +test_pass diff --git a/test/simulation/005-externalstep b/test/simulation/005-externalstep new file mode 100755 index 0000000..e6fff26 --- /dev/null +++ b/test/simulation/005-externalstep @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "external time step" + +min_sync_time=1500 +max_sync_time=1550 + +for step in -1e2 1e2; do + # Make one step in 150th second + client_step="(* $step (equal 0.1 (sum 1.0) 150))" + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +min_sync_time=5120 +max_sync_time=6200 +client_conf="makestep 1 -1" + +for step in -1e8 -1e5 1e5 1e8; do + # Make one step in 5000th second + client_step="(* $step (equal 0.1 (sum 1.0) 5000))" + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +min_sync_time=$default_min_sync_time +max_sync_time=$default_max_sync_time +time_max_limit=2e4 +time_rms_limit=8e3 + +for step in -1e4 1e4; do + # Make a step every 500 seconds + client_step="(* $step (equal 0.1 (% (sum 1.0) 500) 0))" + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +test_pass diff --git a/test/simulation/006-largejitter b/test/simulation/006-largejitter new file mode 100755 index 0000000..36ae5e2 --- /dev/null +++ b/test/simulation/006-largejitter @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "large jitter" + +time_offset=1e0 +jitter=1e-1 + +time_max_limit=5e-1 +freq_max_limit=2e-1 +time_rms_limit=1e-1 +freq_rms_limit=5e-3 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/007-largewander b/test/simulation/007-largewander new file mode 100755 index 0000000..af0c599 --- /dev/null +++ b/test/simulation/007-largewander @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "large wander" + +wander=1e-7 + +time_max_limit=5e-3 +freq_max_limit=5e-3 +time_rms_limit=1e-3 +freq_rms_limit=1e-4 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/008-ntpera b/test/simulation/008-ntpera new file mode 100755 index 0000000..2eea63b --- /dev/null +++ b/test/simulation/008-ntpera @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "NTP eras" + +if check_config_h 'HAVE_LONG_TIME_T 1'; then + ntp_start=$(awk "BEGIN {print $(grep NTP_ERA_SPLIT ../../config.h | tr -dc '0-9*+-')}") +else + ntp_start="-2147483648" +fi + +# Set the starting test date to 500 seconds before the second NTP era. +# This should work with 32-bit time_t and also with 64-bit time_t if the +# configured NTP interval covers the test interval. +export CLKNETSIM_START_DATE=$(date -d 'Feb 7 06:19:56 UTC 2036' +'%s') + +if awk "BEGIN {exit !($ntp_start <= $CLKNETSIM_START_DATE && \ + $CLKNETSIM_START_DATE + $limit < $ntp_start + 2^32)}"; then + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +fi + +# The following tests need 64-bit time_t and ntp_start not before 1970 +check_config_h 'HAVE_LONG_TIME_T 1' || test_skip +echo "$ntp_start" | grep -q '-' && test_skip + +for time_offset in -1e-1 1e-1; do + for start_offset in 0 "2^32 - $limit"; do + export CLKNETSIM_START_DATE=$(awk "BEGIN {printf \"%.0f\", $ntp_start + $start_offset}") + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail + done + + for start_offset in -$limit "2^32"; do + export CLKNETSIM_START_DATE=$(awk "BEGIN {printf \"%.0f\", $ntp_start + $start_offset}") + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync && test_fail + done +done + +test_pass diff --git a/test/simulation/009-sourceselection b/test/simulation/009-sourceselection new file mode 100755 index 0000000..547c376 --- /dev/null +++ b/test/simulation/009-sourceselection @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "source selection" + +# Falsetickers should be detected if their number is less than half of all + +base_delay=1e-3 +servers=5 + +for falsetickers in 1 2; do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +for falsetickers in 3 4; do + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_interval || test_fail + # These check are expected to fail + check_source_selection && test_fail + check_sync && test_fail +done + +# Sources with large asymmetric delay should be excluded + +servers=3 +falsetickers=0 +base_delay="(+ 1e-3 (equal 0.1 to 2) (equal 0.1 to 3))" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/010-multrecv b/test/simulation/010-multrecv new file mode 100755 index 0000000..36e7476 --- /dev/null +++ b/test/simulation/010-multrecv @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +. ./test.common + +export CLKNETSIM_RECV_MULTIPLY=4 + +test_start "multiple received packets" + +limit=50000 +client_server_options="minpoll 6 maxpoll 6" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/011-asymjitter b/test/simulation/011-asymjitter new file mode 100755 index 0000000..9fb5567 --- /dev/null +++ b/test/simulation/011-asymjitter @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "asymmetric jitter" + +jitter=5e-4 +jitter_asymmetry=0.47 +limit=100000 +max_sync_time=2000 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/012-daemonts b/test/simulation/012-daemonts new file mode 100755 index 0000000..a1b90e3 --- /dev/null +++ b/test/simulation/012-daemonts @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "daemon timestamping" + +export CLKNETSIM_TIMESTAMPING=0 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/013-nameserv b/test/simulation/013-nameserv new file mode 100755 index 0000000..941026b --- /dev/null +++ b/test/simulation/013-nameserv @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "name resolving" + +dns=1 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/101-poll b/test/simulation/101-poll new file mode 100755 index 0000000..1416b22 --- /dev/null +++ b/test/simulation/101-poll @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "minpoll/maxpoll options" + +wander=0.0 +jitter=1e-6 + +time_max_limit=1e-5 +freq_max_limit=1e-5 +time_rms_limit=5e-6 +freq_rms_limit=5e-6 +client_conf="makestep 1e-2 1" + +for poll in $(seq 1 14); do + client_server_options="minpoll $poll maxpoll $poll" + limit=$[2**$poll * 10] + min_sync_time=$[2**$poll * 2] + max_sync_time=$[2**$poll * 21 / 10 + 1] + client_max_min_out_interval=$(awk "BEGIN {print 2^$poll * 1.1}") + client_min_mean_out_interval=$(awk "BEGIN {print 2^$poll * 0.99}") + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +min_sync_time=$default_min_sync_time +max_sync_time=$default_max_sync_time +client_max_min_out_interval=$default_client_max_min_out_interval +client_min_mean_out_interval=$default_client_min_mean_out_interval + +limit=10 + +for poll in $(seq -7 2 -1); do + client_server_options="minpoll $poll maxpoll $poll" + + base_delay=1e-4 + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_file_messages " 2 1 " \ + $[2**-poll * limit * 9 / 10] $[2**-poll * limit] log.packets || test_fail + + base_delay=2e-2 + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_file_messages " 2 1 " $[limit * 9 / 10] $limit log.packets || test_fail +done + +test_pass diff --git a/test/simulation/102-iburst b/test/simulation/102-iburst new file mode 100755 index 0000000..9936572 --- /dev/null +++ b/test/simulation/102-iburst @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "iburst option" + +freq_offset=1e-4 + +client_conf="makestep 1e-2 1 +driftfile tmp/drift" +client_server_options="iburst" + +min_sync_time=4 +max_sync_time=6 + +echo "100 1.0" > tmp/drift + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/103-initstepslew b/test/simulation/103-initstepslew new file mode 100755 index 0000000..fe47b68 --- /dev/null +++ b/test/simulation/103-initstepslew @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "initstepslew directive" + +freq_offset=0.0 +wander=0.0 +time_rms_limit=1e-3 +limit=100 + +client_conf="initstepslew 5 192.168.123.1" +client_server_conf="#" + +min_sync_time=6 +max_sync_time=35 + +for time_offset in -2.0 -0.2 0.2 2.0; do + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_interval || test_fail + check_sync || test_fail + check_log_messages "00:00:0.Z System's initial.*slew" 1 1 || test_fail +done + +min_sync_time=5 +max_sync_time=5 + +for time_offset in -1e8 -1e2 1e2 1e8; do + run_test || test_fail + check_packet_interval || test_fail + check_sync || test_fail + check_log_messages "System's initial.*step" 1 1 || test_fail +done + +time_offset=3 +limit=500 +servers=2 +falsetickers=1 +client_conf="initstepslew 5 192.168.123.1 192.168.123.2" +client_server_conf="server 192.168.123.2" + +min_sync_time=360 +max_sync_time=450 + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +check_sync || test_fail +check_log_messages "00:03:2.Z No suitable source for initstepslew" 1 1 || test_fail + +client_conf="initstepslew 5 192.168.123.1 192.168.123.2" + +min_sync_time=1 +max_sync_time=500 +server_conf="deny all" + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +check_sync && test_fail +check_log_messages "00:00:1.Z No suitable source for initstepslew" 1 1 || test_fail + +test_pass diff --git a/test/simulation/104-driftfile b/test/simulation/104-driftfile new file mode 100755 index 0000000..93d4363 --- /dev/null +++ b/test/simulation/104-driftfile @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "driftfile directive" + +servers=0 +time_offset=0.0 +wander=0.0 +limit=10 +freq_max_limit=1e-9 +min_sync_time=1 +max_sync_time=1 +client_conf="driftfile tmp/drift" + +for freq_offset in -5e-2 -5e-4 -5e-6 5e-6 5e-4 5e-2; do + awk "BEGIN {printf \"%.9e 1\", 1e6 - 1 / (1 + $freq_offset) * 1e6}" > tmp/drift + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +test_pass diff --git a/test/simulation/105-ntpauth b/test/simulation/105-ntpauth new file mode 100755 index 0000000..1f228f5 --- /dev/null +++ b/test/simulation/105-ntpauth @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "NTP authentication" + +server_conf="keyfile tmp/server.keys" +client_conf="keyfile tmp/client.keys" + +cat > tmp/server.keys <<-EOF +1 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E +2 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E +3 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E +4 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E +EOF + +cat > tmp/client.keys <<-EOF +1 k]<j.Jtw^Oo;z5E>n\_0-x=)yP\f<)Z^ +2 ASCII:k]<j.Jtw^Oo;z5E>n\_0-x=)yP\f<)Z^ +3 MD5 ASCII:k]<j.Jtw^Oo;z5E>n\_0-x=)yP\f<)Z^ +4 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E +EOF + +keys=4 + +types="MD5" +check_config_h 'FEAT_SECHASH 1' && types="$types SHA1 SHA256 SHA384 SHA512" +check_config_h 'HAVE_CMAC 1' && types="$types AES128 AES256" + +for type in $types; do + keys=$[$keys + 1] + case $type in + AES128) length=16;; + AES256) length=32;; + *) length=$[$RANDOM % 32 + 1];; + esac + + key=$(echo $keys $type HEX:$(tr -c -d '0-9A-F' < /dev/urandom 2> /dev/null | \ + head -c $[$length * 2])) + echo "$key" >> tmp/server.keys + echo "$key" >> tmp/client.keys +done + +for version in 3 4; do + for key in $(seq $keys); do + client_server_options="version $version key $key" + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail + done +done + +server_conf="" + +run_test || test_fail +check_chronyd_exit || test_fail +# This check must fail as the server doesn't know the key +check_sync && test_fail +check_packet_interval || test_fail + +server_conf="keyfile tmp/server.keys" +client_conf="" + +run_test || test_fail +check_chronyd_exit || test_fail +# This check must fail as the client doesn't know the key +check_sync && test_fail +check_packet_interval || test_fail + +client_conf="keyfile tmp/client.keys" +clients=2 +peers=2 +max_sync_time=500 +base_delay="$default_base_delay (* -1 (equal 0.1 from 3) (equal 0.1 to 1))" + +for versions in "3 3" "3 4" "4 3" "4 4"; do + for key in 1 $keys; do + client_lpeer_options="version ${versions% *} key $key" + client_rpeer_options="version ${versions#* } key $key" + run_test || test_fail + check_chronyd_exit || test_fail + check_sync || test_fail + done +done + +client_lpeer_options="key 1" +client_rpeer_options="key 2" + +run_test || test_fail +check_chronyd_exit || test_fail +# This check must fail as the peers are using different keys" +check_sync && test_fail + +test_pass diff --git a/test/simulation/106-refclock b/test/simulation/106-refclock new file mode 100755 index 0000000..f09f170 --- /dev/null +++ b/test/simulation/106-refclock @@ -0,0 +1,143 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "SHM refclock" + +check_config_h 'FEAT_REFCLOCK 1' || test_skip +check_config_h 'FEAT_PHC 1' || test_skip +check_config_h 'FEAT_CMDMON 1' || test_skip + +export CLKNETSIM_PHC_DELAY=1e-6 +export CLKNETSIM_PHC_JITTER=1e-7 + +servers=0 +limit=1000 +refclock_jitter=$jitter +min_sync_time=45 +max_sync_time=70 +chronyc_start=70 +chronyc_conf="tracking" + +for refclock in "SHM 0" "PHC /dev/ptp0" "PHC /dev/ptp0:nocrossts"; do + client_conf="refclock $refclock stratum 3 delay 1e-3 refid GPS +logdir tmp +log refclocks" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + check_chronyc_output "^Reference ID.*47505300 \(GPS\) +Stratum.*: 4 +.* +Root delay : 0.001000000 seconds +.* +Update interval : 16\.. seconds +.*$" || test_fail + + if echo "$refclock" | grep -q 'PHC.*nocrossts'; then + check_file_messages "20.* GPS.*[0-9] N " 650 750 refclocks.log || test_fail + else + check_file_messages "20.* GPS.*[0-9] N " 997 1001 refclocks.log || test_fail + fi + check_file_messages "20.* GPS.*- N " 61 63 refclocks.log || test_fail + rm -f tmp/refclocks.log +done + +if check_config_h 'FEAT_PPS 1'; then + refclock_offset=0.35 + refclock_jitter=0.05 + + client_conf=" +refclock SHM 0 refid NMEA noselect +refclock PPS /dev/pps0 lock NMEA +logdir tmp +log refclocks" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + check_chronyc_output "^Reference ID.*50505331 \(PPS1\) +Stratum.*: 1 +.* +Root delay : 0\.000000001 seconds +.*$" || test_fail + + check_file_messages "20.* PPS1.*[0-9] N " 620 740 refclocks.log || test_fail + check_file_messages "20.* PPS1.*- N " 60 63 refclocks.log || test_fail + rm -f tmp/refclocks.log + + client_conf=" +refclock SHM 0 noselect +refclock PPS /dev/pps0 +local +logdir tmp +log refclocks" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + check_chronyc_output "^Reference ID.*50505331 \(PPS1\) +Stratum.*: 10 +.* +Root delay : 0\.000000001 seconds +.*$" || test_fail + + check_file_messages "20.* PPS1.*[0-9] N " 997 1001 refclocks.log || test_fail + check_file_messages "20.* PPS1.*- N " 60 63 refclocks.log || test_fail + rm -f tmp/refclocks.log + + min_sync_time=100 + max_sync_time=220 + chronyc_start=220 + client_conf=" +refclock SHM 0 refid NMEA offset 0.35 delay 0.1 +refclock PPS /dev/pps0 +logdir tmp +log refclocks" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + check_chronyc_output "^Reference ID.*50505331 \(PPS1\) +Stratum.*: 1 +.* +Root delay : 0\.000000001 seconds +.*$" || test_fail + + check_file_messages "20.* PPS1.*[0-9] N " 800 940 refclocks.log || test_fail + check_file_messages "20.* PPS1.*- N " 50 63 refclocks.log || test_fail + rm -f tmp/refclocks.log +fi + +refclock_offset="(+ 0.399 (sum 1e-3))" +refclock_jitter=1e-6 +servers=1 +freq_offset="(* 1e-4 (sine 1000))" +base_delay="(* -1.0 (equal 0.1 (min time 5000) 5000))" +client_server_options="minpoll 4 maxpoll 4 filter 5 minsamples 64" +client_conf=" +refclock PHC /dev/ptp0 local poll 2 +logdir tmp +log refclocks tracking" +chronyc_conf="" +limit=10000 +max_sync_time=5000 +time_max_limit=1e-3 +time_rms_limit=5e-4 +freq_max_limit=2e-5 +freq_rms_limit=5e-6 + +run_test || test_fail +check_chronyd_exit || test_fail +check_sync || test_fail + +check_file_messages "20.* PHC0 .* [0-9] ? " 9999 10001 refclocks.log || test_fail +check_file_messages "20.* PHC0 .* - ? " 2499 2501 refclocks.log || test_fail +check_file_messages "20.* PHC0 " 0 0 tracking.log || test_fail +rm -f tmp/refclocks.log tmp/tracking.log + +test_pass diff --git a/test/simulation/107-allowdeny b/test/simulation/107-allowdeny new file mode 100755 index 0000000..4665337 --- /dev/null +++ b/test/simulation/107-allowdeny @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "allow/deny directives" + +check_config_h 'FEAT_CMDMON 1' || test_skip + +limit=500 + +# Note that start_client in clknetsim.bash always adds allow to the config + +for server_conf in \ + "deny" \ + "deny all" \ + "deny 192.168.0.0/16" \ + "deny 192.168.123" \ + "deny 192.168.123.2" \ + "deny all +allow 192.168.124.0/24" +do + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_interval || test_fail + # These checks are expected to fail + check_source_selection && test_fail + check_sync && test_fail +done + +for server_conf in \ + "deny all +allow" \ + "deny all +allow all" \ + "deny all +allow 192.168.123" \ + "deny all +allow 192.168.123/24" \ + "deny 192.168.124.0/24" +do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +test_pass diff --git a/test/simulation/108-peer b/test/simulation/108-peer new file mode 100755 index 0000000..906de17 --- /dev/null +++ b/test/simulation/108-peer @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "NTP peers" + +# Allow and drop packets to the server in 1000 second intervals, so only one +# client has access to it and the other is forced to switch to the peer. +base_delay=$(cat <<-EOF | tr -d '\n' + (+ 1e-4 + (* -1 + (equal 0.1 from 2) + (equal 0.1 to 1) + (equal 0.1 (min (% time 2000) 1000) 1000)) + (* -1 + (equal 0.1 from 3) + (equal 0.1 to 1) + (equal 0.1 (max (% time 2000) 1000) 1000))) +EOF +) + +clients=2 +peers=2 +max_sync_time=1000 +client_server_options="minpoll 6 maxpoll 6" +client_peer_options="minpoll 6 maxpoll 6" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +base_delay="(+ 1e-4 (* -1 (equal 0.1 from 3) (equal 0.1 to 1)))" +client_peer_options="" + +while read lminpoll lmaxpoll rminpoll rmaxpoll max_sync_time; do + client_lpeer_options="minpoll $lminpoll maxpoll $lmaxpoll" + client_rpeer_options="minpoll $rminpoll maxpoll $rmaxpoll" + limit=$[$max_sync_time * 10] + + run_test || test_fail + check_chronyd_exit || test_fail + check_sync || test_fail +done <<-EOF + 3 6 3 6 400 + 3 3 6 6 450 + 6 6 3 3 450 + 3 6 6 6 450 + 6 6 3 6 450 + -2 -2 2 2 220 + 2 2 -2 -2 220 +EOF + +test_pass diff --git a/test/simulation/109-makestep b/test/simulation/109-makestep new file mode 100755 index 0000000..78d8d59 --- /dev/null +++ b/test/simulation/109-makestep @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "makestep directive" + +client_conf="makestep 0 -1 +corrtimeratio 1e10" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +limit=200 +jitter=1e-5 +client_conf="makestep 2 1" + +min_sync_time=130 +max_sync_time=150 + +for time_offset in -1.0 -0.1 0.1 1.0; do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +min_sync_time=120 +max_sync_time=140 + +for time_offset in -1e8 -1e2 1e2 1e8; do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +test_pass diff --git a/test/simulation/110-chronyc b/test/simulation/110-chronyc new file mode 100755 index 0000000..b78f0d8 --- /dev/null +++ b/test/simulation/110-chronyc @@ -0,0 +1,496 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "chronyc" + +check_config_h 'FEAT_REFCLOCK 1' || test_skip +check_config_h 'FEAT_CMDMON 1' || test_skip + +refclock_jitter=$jitter +client_server_conf=" +server node1.net1.clk +server 192.168.123.2" +client_conf=" +refclock SHM 0 noselect +smoothtime 400 0.001 leaponly" +cmdmon_unix=0 + +chronyc_conf="activity +tracking +sourcename 192.168.123.1 +sourcename 192.168.123.2 +sources +sourcestats +manual list +smoothing +waitsync +rtcdata" + +run_test || test_fail +check_chronyd_exit || test_fail + +check_chronyc_output "^200 OK +2 sources online +0 sources offline +0 sources doing burst \(return to online\) +0 sources doing burst \(return to offline\) +0 sources with unknown address +Reference ID : C0A87B01 \(192\.168\.123\.1\) +Stratum : 2 +Ref time \(UTC\) : Fri Jan 01 00:1.:.. 2010 +System time : 0\.0000..... seconds (slow|fast) of NTP time +Last offset : [+-]0\.000...... seconds +RMS offset : 0\.000...... seconds +Frequency : (99|100)\.... ppm fast +Residual freq : [+-][0-9]\.... ppm +Skew : [0-9]\.... ppm +Root delay : 0\.000...... seconds +Root dispersion : 0\.000...... seconds +Update interval : [0-9]+\.. seconds +Leap status : Normal +node1\.net1\.clk +192\.168\.123\.2 +MS Name/IP address Stratum Poll Reach LastRx Last sample +=============================================================================== +#\? SHM0 0 4 377 [0-9]+ [0-9 +-]+[un]s\[[0-9 +-]+[un]s\] \+/-[ 0-9]+[un]s +\^\* 192\.168\.123\.1 1 [67] 377 [0-9]+ [0-9 +-]+[un]s\[[0-9 +-]+[un]s\] \+/-[ 0-9]+[un]s +\^\? 192\.168\.123\.2 0 [0-9]+ 0 - \+0ns\[ \+0ns\] \+/- 0ns +Name/IP Address NP NR Span Frequency Freq Skew Offset Std Dev +============================================================================== +SHM0 [0-9 ]+ [0-9 ]+ [0-9 ]+ [ +-][01]\.... [0-9 ]+\.... [0-9 +-]+[un]s [0-9 ]+[un]s +192\.168\.123\.1 [0-9 ]+ [0-9 ]+ [0-9 ]+ [ +-][01]\.... [0-9 ]+\.... [0-9 +-]+[un]s [0-9 ]+[un]s +192\.168\.123\.2 0 0 0 \+0\.000 2000\.000 \+0ns 4000ms +210 n_samples = 0 +# Date Time\(UTC\) Slewed Original Residual +======================================================= +Active : Yes \(leap second only\) +Offset : \+0\.000000000 seconds +Frequency : \+0\.000000 ppm +Wander : \+0\.000000 ppm per second +Last update : [0-9]+\.. seconds ago +Remaining time : 0\.0 seconds +try: 1, refid: C0A87B01, correction: 0\.000......, skew: .\.... +513 RTC driver not running$" \ +|| test_fail + +chronyc_conf="tracking" +dns=1 + +run_test || test_fail +check_chronyd_exit || test_fail + +check_chronyc_output "^Reference ID : C0A87B01 \(node1\.net1\.clk\)" \ + || test_fail + +chronyc_options="-c" + +run_test || test_fail +check_chronyd_exit || test_fail + +check_chronyc_output "^C0A87B01,192\.168\.123\.1,2,12623049..\..........,-?0\.0000.....,-?0\.000......,0\.000......,(99|100)\....,-?[0-9]\....,[0-9]\....,0\.000......,0\.000......,[0-9]+\..,Normal$" \ + || test_fail + +chronyc_options="" +server_strata=0 +chronyc_start=0.5 +client_server_conf="" +client_conf="" +server_conf="server 192.168.123.1" +limit=1 + +for chronyc_conf in \ + "accheck 1.2.3.4" \ + "add peer 10.0.0.0 minpoll 2 maxpoll 6" \ + "add server 10.0.0.0 minpoll 6 maxpoll 10 iburst burst key 1 certset 2 maxdelay 1e-3 maxdelayratio 10.0 maxdelaydevratio 10.0 maxdelayquant 0.5 mindelay 1e-4 asymmetry 0.5 offset 1e-5 minsamples 6 maxsamples 6 filter 3 offline auto_offline prefer noselect trust require xleave polltarget 20 port 123 presend 7 minstratum 3 version 4 nts ntsport 4460 copy extfield F323" \ + "add server node1.net1.clk" \ + "allow 1.2.3.4" \ + "allow 1.2" \ + "allow 3.4.5" \ + "allow 6.7.8/22" \ + "allow 6.7.8.9/22" \ + "allow 0/0" \ + "allow" \ + "allow all 10/24" \ + "authdata" \ + "burst 5/10" \ + "burst 3/5 255.255.255.0/1.2.3.0" \ + "burst 1/2 1.2.3.0/24" \ + "clients" \ + "clients -k" \ + "clients -p 100" \ + "clients -r" \ + "cmdaccheck 1.2.3.4" \ + "cmdallow 1.2.3.4" \ + "cmdallow all 1.2.3.0/24" \ + "cmddeny 1.2.3.4" \ + "cmddeny all 1.2.3.0/24" \ + "cyclelogs" \ + "delete 10.0.0.0" \ + "delete ID#0000000001" \ + "deny 1.2.3.4" \ + "deny all 1.2.3.0/24" \ + "dfreq 1.0e-3" \ + "doffset -1.0" \ + "dump" \ + "local stratum 5 distance 1.0 orphan" \ + "local off" \ + "makestep 10.0 3" \ + "makestep" \ + "manual delete 0" \ + "manual off" \ + "manual on" \ + "manual reset" \ + "maxdelay 1.2.3.4 1e-2" \ + "maxdelaydevratio 1.2.3.4 5.0" \ + "maxdelayratio 1.2.3.4 3.0" \ + "maxpoll 1.2.3.4 5" \ + "maxupdateskew 1.2.3.4 10.0" \ + "minpoll 1.2.3.4 3" \ + "minstratum 1.2.3.4 1" \ + "minstratum ID#0000000001 1" \ + "ntpdata 1.2.3.4" \ + "offline" \ + "offline 255.255.255.0/1.2.3.0" \ + "offline 1.2.3.0/24" \ + "online" \ + "online 1.2.3.0/24" \ + "onoffline" \ + "polltarget 1.2.3.4 10" \ + "refresh" \ + "rekey" \ + "reload sources" \ + "reselect" \ + "reselectdist 1e-3" \ + "reset sources" \ + "selectdata" \ + "settime 16:30" \ + "settime 16:30:05" \ + "settime Nov 21, 2015 16:30:05" \ + "serverstats" \ + "shutdown" \ + "smoothtime reset" \ + "smoothtime activate" \ + "trimrtc" \ + "writertc" +do + run_test || test_fail + check_chronyd_exit || test_fail + check_chronyc_output "501 Not authorised$" || test_fail +done + +cmdmon_unix=1 + +chronyc_conf=" +authdata +clients -k -p 2 +clients -r +clients +ntpdata +selectdata +serverstats" + +run_test || test_fail +check_chronyd_exit || test_fail + +check_chronyc_output "^Name/IP address Mode KeyID Type KLen Last Atmp NAK Cook CLen +========================================================================= +node1\.net1\.clk - 0 0 0 - 0 0 0 0 +Hostname NTP Drop Int IntL Last NTS-KE Drop Int Last +=============================================================================== +Hostname NTP Drop Int IntL Last Cmd Drop Int Last +=============================================================================== +node1\.net1\.clk 1 0 - - 0 0 0 - - +Hostname NTP Drop Int IntL Last Cmd Drop Int Last +=============================================================================== +node1\.net1\.clk 0 0 - - 0 0 0 - - + +Remote address : 192\.168\.123\.1 \(C0A87B01\) +Remote port : 123 +Local address : 192\.168\.123\.1 \(C0A87B01\) +Leap status : Normal +Version : 4 +Mode : Server +Stratum : 1 +Poll interval : 6 \(64 seconds\) +Precision : -23 \(0\.000000119 seconds\) +Root delay : 0\.000000 seconds +Root dispersion : 0\.000000 seconds +Reference ID : 7F7F0101 \(\) +Reference time : Thu Dec 31 23:59:5[89] 2009 +Offset : [-+]0\.000...... seconds +Peer delay : 0\.00....... seconds +Peer dispersion : 0\.00000.... seconds +Response time : 0\.000000... seconds +Jitter asymmetry: \+0\.00 +NTP tests : 111 111 1110 +Interleaved : No +Authenticated : No +TX timestamping : Kernel +RX timestamping : Kernel +Total TX : 1 +Total RX : 1 +Total valid RX : 1 +Total good RX : 0 +S Name/IP Address Auth COpts EOpts Last Score Interval Leap +======================================================================= +M node1\.net1\.clk N ----- ----- 0 1\.0 \+0ns \+0ns N +NTP packets received : 1 +NTP packets dropped : 0 +Command packets received : 12 +Command packets dropped : 0 +Client log records dropped : 0 +NTS-KE connections accepted: 0 +NTS-KE connections dropped : 0 +Authenticated NTP packets : 0 +Interleaved NTP packets : 0 +NTP timestamps held : 0 +NTP timestamp span : 0$" || test_fail + +chronyc_conf=" +deny all +cmdallow all +allow 1.2.3.4 +allow 1.2.3.0/28 +deny 1.2.3.0/27 +allow 1.2.4.5 +deny all 1.2.4.0/27 +cmddeny 5.6.7.8 +cmdallow all 5.6.7.0/28 +accheck 1.2.3.4 +accheck 1.2.3.5 +accheck 1.2.4.5 +cmdaccheck 5.6.7.8" + +run_test || test_fail +check_chronyd_exit || test_fail + +check_chronyc_output "^200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +208 Access allowed +209 Access denied +209 Access denied +208 Access allowed$" || test_fail + +if check_config_h 'FEAT_IPV6 1'; then + chronyc_conf=" + deny all + cmdallow all + allow 2001:db8::1 + allow 2001:db8::/64 + deny 2001:db8::/63 + allow 2001:db8:1::1 + deny all 2001:db8:1::/63 + cmddeny 2001:db9::1 + cmdallow all 2001:db9::/64 + accheck 2001:db8::1 + accheck 2001:db8::2 + accheck 2001:db8:1::1 + cmdaccheck 2001:db9::1" + + run_test || test_fail + check_chronyd_exit || test_fail + + check_chronyc_output "^200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +208 Access allowed +209 Access denied +209 Access denied +208 Access allowed$" || test_fail +fi + +chronyc_conf=" +delete 192.168.123.1 +add server node1.net1.clk minpoll 6 maxpoll 10 iburst +offline 192.168.123.1 +burst 1/1 192.168.123.1 +online 192.168.123.1 +maxdelay 192.168.123.1 1e-2 +maxdelaydevratio 192.168.123.1 5.0 +maxdelayratio 192.168.123.1 3.0 +maxpoll 192.168.123.1 5 +maxupdateskew 192.168.123.1 10.0 +minpoll 192.168.123.1 3 +minstratum 192.168.123.1 1 +polltarget 192.168.123.1 10 +delete 192.168.123.1" + +run_test || test_fail +check_chronyd_exit || test_fail + +check_chronyc_output "^200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK$" || test_fail + +chronyc_conf=" +cyclelogs +dump +dfreq 1.0e-3 +doffset -0.01 +local stratum 5 distance 1.0 orphan +local off +makestep 10.0 3 +makestep +manual on +settime now +manual delete 0 +manual reset +manual off +onoffline +refresh +rekey +reload sources +reselect +reselectdist 1e-3 +reset sources +shutdown" + +run_test || test_fail +check_chronyd_exit || test_fail + +check_chronyc_output "^200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +Clock was .\... seconds fast. Frequency change = 0.00ppm, new frequency = 0.00ppm +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK +200 OK$" || test_fail + +server_conf=" +server 192.168.123.1 +noclientlog" + +commands=( + "add server nosuchnode.net1.clk" "^Invalid host/IP address$" + "allow nosuchnode.net1.clk" "^Could not read address$" + "allow 192.168.123.0/2 4" "^Could not read address$" + "allow 192.168.123.0/2e" "^Could not read address$" + "allow 192.168.12e" "^Could not read address$" + "allow 192.168123" "^Could not read address$" + "allow 192.168.123.2/33" "^507 Bad subnet$" + "clients" "Hostname.*519 Client logging is not active in the daemon$" + "delete 192.168.123.2" "^503 No such source$" + "minpoll 192.168.123.2 5" "^503 No such source$" + "ntpdata 192.168.123.2" "^503 No such source$" + "settime now" "^505 Facility not enabled in daemon$" + "smoothing" "^505 Facility not enabled in daemon$" + "smoothtime activate" "^505 Facility not enabled in daemon$" + "smoothtime reset" "^505 Facility not enabled in daemon$" + "sourcename 192.168.123.2" "^503 No such source$" + "trimrtc" "^513 RTC driver not running$" + "writertc" "^513 RTC driver not running$" +) + +for i in $(seq 0 $[${#commands[*]} / 2]); do + chronyc_conf=${commands[$[i * 2]]} + run_test || test_fail + check_chronyd_exit || test_fail + check_chronyc_output "${commands[$[i * 2 + 1]]}" || test_fail +done + +cmdmon_unix=0 +server_conf="server 192.168.123.1" + +chronyc_conf="dns -n +dns +n +dns -4 +dns -6 +dns -46 +timeout 200 +retries 1 +keygen +keygen 10 MD5 128 +keygen 11 MD5 40 +help +quit +nosuchcommand" + +run_test || test_fail + +check_chronyc_output "^1 (MD5|SHA1) HEX:........................................ +10 MD5 HEX:................................ +11 MD5 HEX:.................... +System clock:.*this help + *$" || test_fail + +chronyc_conf="keygen 10 NOSUCHTYPE 128 +help" +run_test || test_fail +check_chronyc_output "^Unknown hash function or cipher NOSUCHTYPE\$" || test_fail + +if check_config_h 'FEAT_SECHASH 1'; then + for hash in MD5 SHA1 SHA256 SHA384 SHA512; do + chronyc_conf="keygen 5 $hash" + run_test || test_fail + check_chronyc_output "^5 $hash HEX:........................................\$" || test_fail + done +fi + +if check_config_h 'HAVE_CMAC 1'; then + chronyc_conf="keygen 6 AES128 +keygen 7 AES256" + run_test || test_fail + check_chronyc_output "^6 AES128 HEX:................................ +7 AES256 HEX:................................................................\$" || test_fail +fi + +# Pass every fourth request +base_delay=$(cat <<-EOF | tr -d '\n' + (+ 1e-4 + (* -1 + (equal 0.1 from 2) + (equal 0.1 (min (% (sum 1) 4) 1) 1))) +EOF +) +limit=15 + +chronyc_conf="sources" +run_test || test_fail +check_chronyc_output "^506 Cannot talk to daemon$" || test_fail + +chronyc_conf="retries 3 +sources" +run_test || test_fail +check_chronyc_output "^MS.*0ns$" || test_fail + +test_pass diff --git a/test/simulation/111-knownclient b/test/simulation/111-knownclient new file mode 100755 index 0000000..92bad54 --- /dev/null +++ b/test/simulation/111-knownclient @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "reply to client configured as server" + +server_conf="server 192.168.123.2 noselect +acquisitionport 123" +client_conf="acquisitionport 123" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_port || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/112-port b/test/simulation/112-port new file mode 100755 index 0000000..2f10eed --- /dev/null +++ b/test/simulation/112-port @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "port and acquisitionport directives" + +check_config_h 'FEAT_CMDMON 1' || test_skip + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail +# This check is expected to fail +check_packet_port && test_fail + +client_conf="acquisitionport 123" +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_port || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +client_conf="" +for server_conf in \ + "port 0" \ + "acquisitionport 123 +port 0" +do + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_port || test_fail + check_packet_interval || test_fail + # These checks are expected to fail + check_source_selection && test_fail + check_sync && test_fail +done + +server_conf="port 124 +acquisitionport 123" +client_server_options="port 124" +for client_conf in \ + "acquisitionport 0" \ + "acquisitionport 123" \ + "acquisitionport 124" +do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail + # This check is expected to fail + check_packet_port && test_fail +done + +test_pass diff --git a/test/simulation/113-leapsecond b/test/simulation/113-leapsecond new file mode 100755 index 0000000..394440b --- /dev/null +++ b/test/simulation/113-leapsecond @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "leap second" + +check_config_h 'FEAT_REFCLOCK 1' || test_skip + +export CLKNETSIM_START_DATE=$(TZ=UTC date -d 'Dec 30 2008 0:00:00' +'%s') + +leap=$[2 * 24 * 3600] +limit=$[4 * 24 * 3600] +client_start=$[2 * 3600] +server_conf="refclock SHM 0 dpoll 10 poll 10 +leapsectz right/UTC" +refclock_jitter=1e-9 +refclock_offset="(* -1.0 (equal 0.1 (max (sum 1.0) $leap) $leap))" + +for leapmode in system step slew; do + client_conf="leapsecmode $leapmode" + if [ $leapmode = slew ]; then + max_sync_time=$[$leap + 12] + else + max_sync_time=$[$leap] + fi + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +client_server_options="trust" +client_conf="refclock SHM 0 dpoll 10 poll 10 delay 1e-3" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +client_server_options="" +client_conf="leapsecmode system" +min_sync_time=230000 +max_sync_time=240000 + +for smoothmode in "" "leaponly"; do + server_conf="refclock SHM 0 dpoll 10 poll 10 + leapsectz right/UTC + leapsecmode slew + smoothtime 400 0.001 $smoothmode" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +test_pass diff --git a/test/simulation/114-presend b/test/simulation/114-presend new file mode 100755 index 0000000..4fd89f8 --- /dev/null +++ b/test/simulation/114-presend @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "presend option" + +min_sync_time=136 +max_sync_time=260 +client_server_options="presend 6 maxdelay 16" +client_conf="maxdistance 10" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +base_delay=5 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/115-cmdmontime b/test/simulation/115-cmdmontime new file mode 100755 index 0000000..525062d --- /dev/null +++ b/test/simulation/115-cmdmontime @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "cmdmon timestamps" + +# The following tests need 64-bit time_t +check_config_h 'HAVE_LONG_TIME_T 1' || test_skip +check_config_h 'FEAT_CMDMON 1' || test_skip + +limit=2 +client_server_options="noselect" +client_conf="local stratum 1" +chronyc_start="1.5" +chronyc_conf="tracking" + +for year in `seq 1850 100 2300`; do + export CLKNETSIM_START_DATE=$(date -d "Jan 01 00:00:05 $year UTC" +'%s') + run_test || test_fail + check_chronyd_exit || test_fail + check_chronyc_output "^.*Ref time \(UTC\).*Jan 01 00:00:0. $year.*$" || test_fail +done + +test_pass diff --git a/test/simulation/116-minsources b/test/simulation/116-minsources new file mode 100755 index 0000000..f576423 --- /dev/null +++ b/test/simulation/116-minsources @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "minsources directive" + +client_conf="minsources 3" + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +# These check are expected to fail +check_source_selection && test_fail +check_sync && test_fail + +servers=3 + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +check_source_selection || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/117-fallbackdrift b/test/simulation/117-fallbackdrift new file mode 100755 index 0000000..21f6963 --- /dev/null +++ b/test/simulation/117-fallbackdrift @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "fallback drift" + +limit=100000 +wander=0.0 +jitter=1e-6 +time_offset=10 +freq_offset="(* 1e-4 (sine 1000))" +base_delay="(* -1.0 (equal 0.1 (min time 4250) 4250))" +client_server_options="minpoll 4 maxpoll 4" +client_conf="fallbackdrift 6 10" +max_sync_time=4500 +time_max_limit=1e0 +time_rms_limit=1e0 +freq_max_limit=2e-4 +freq_rms_limit=1e-4 + +run_test || test_fail +check_chronyd_exit || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/118-maxdelay b/test/simulation/118-maxdelay new file mode 100755 index 0000000..117b170 --- /dev/null +++ b/test/simulation/118-maxdelay @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "maxdelay options" + +max_sync_time=2000 +base_delay=1e-5 +jitter=1e-5 +wander=0.0 +freq_offset="(sum 1e-10)" +time_rms_limit=2e-4 + +client_server_options="maxpoll 6 maxdelay 3e-5 maxdelayratio 2.0 maxdelaydevratio 2.0" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +for client_server_options in "maxpoll 6 maxdelay 2e-5"; do + run_test || test_fail + check_chronyd_exit || test_fail + check_packet_interval || test_fail + check_sync && test_fail +done + +min_sync_time=10 +client_conf=" +logdir tmp +log rawmeasurements" +client_server_options="minpoll 2 maxpoll 2 maxdelayquant 0.1" + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_file_messages "20.*123\.1.* 111 111 1111" 200 500 measurements.log || test_fail +check_file_messages "20.*123\.1.* 111 111 1101" 2000 2300 measurements.log || test_fail + +test_pass diff --git a/test/simulation/119-smoothtime b/test/simulation/119-smoothtime new file mode 100755 index 0000000..7f5114c --- /dev/null +++ b/test/simulation/119-smoothtime @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "smoothtime option" + +check_config_h 'FEAT_REFCLOCK 1' || test_skip + +server_strata=2 +server_conf="smoothtime 400 0.001" +server_server_options="minpoll 8" +min_sync_time=600 +max_sync_time=800 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +limit=10000 +refclock_jitter=1e-4 +refclock_offset="(* 10.0 (equal 0.1 (max (sum 1.0) 1000) 1000))" +server_step="(* -10.0 (equal 0.1 (sum 1.0) 1))" +server_strata=1 +server_conf="refclock SHM 0 dpoll 4 poll 6 +smoothtime 2000 1 +maxjitter 10.0" +time_offset=-10 +server_server_options="" +client_server_options="minpoll 6 maxpoll 6" +client_conf="corrtimeratio 100" +min_sync_time=8000 +max_sync_time=9000 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +client_server_options="minpoll 6 maxpoll 6 xleave maxdelay 1e-1" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +client_server_options="minpoll 6 maxpoll 6" +min_sync_time=$default_min_sync_time +max_sync_time=$default_max_sync_time +time_max_limit=11 +time_rms_limit=11 +freq_max_limit=1e-2 +freq_rms_limit=2e-3 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +refclock_jitter=1e-9 +refclock_offset="(* 1e-1 (triangle 1000) (+ -1.0 (pulse 1000 10000)))" +server_step="" +server_conf="refclock SHM 0 dpoll 4 poll 6 minsamples 4 maxsamples 4 +smoothtime 1e4 1e-6" +client_server_options="minpoll 4 maxpoll 4" +time_offset=0.1 +jitter=1e-6 +wander=0.0 +min_sync_time=30 +max_sync_time=40 +time_max_limit=1e-5 +time_rms_limit=5e-6 +freq_max_limit=1e-6 +freq_rms_limit=1e-7 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/120-selectoptions b/test/simulation/120-selectoptions new file mode 100755 index 0000000..611815e --- /dev/null +++ b/test/simulation/120-selectoptions @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "source selection options" + +servers=3 +falsetickers=2 + +base_delay=0.6 +client_server_conf=" +server 192.168.123.1 +server 192.168.123.2 +server 192.168.123.3 trust" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +client_server_conf=" +server 192.168.123.1 +server 192.168.123.2 +server 192.168.123.3 prefer" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +# This check is expected to fail +check_sync && test_fail + +base_delay=1.1 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +base_delay=1e-3 +falsetickers=1 + +client_server_conf=" +server 192.168.123.1 +server 192.168.123.2 +server 192.168.123.3 require" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +client_server_conf=" +server 192.168.123.1 require +server 192.168.123.2 +server 192.168.123.3" + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +# These checks are expected to fail +check_source_selection && test_fail +check_sync && test_fail + +cat > tmp/keys <<-EOF +1 MD5 HEX:1B81CBF88D4A73F2E8CE59647F6E5C1719B6CAF5 +EOF + +server_conf="keyfile tmp/keys" +client_server_conf=" +server 192.168.123.1 key 1 +server 192.168.123.2 +server 192.168.123.3" + +for authselectmode in require prefer mix ignore; do + client_conf="keyfile tmp/keys + authselectmode $authselectmode" + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + if [ $authselectmode = ignore ]; then + check_sync || test_fail + else + check_sync && test_fail + fi +done + +test_pass diff --git a/test/simulation/121-orphan b/test/simulation/121-orphan new file mode 100755 index 0000000..7579997 --- /dev/null +++ b/test/simulation/121-orphan @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "orphan option" + +check_config_h 'FEAT_CMDMON 1' || test_skip + +server_strata=3 +server_conf="local stratum 5 orphan +server 192.168.123.1 +server 192.168.123.2 +server 192.168.123.3" +max_sync_time=900 +client_start=140 +chronyc_start=700 +chronyc_conf="tracking" +time_rms_limit=5e-4 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail +check_chronyc_output "^.*Stratum *: 7.*$" || test_fail + +test_pass diff --git a/test/simulation/122-xleave b/test/simulation/122-xleave new file mode 100755 index 0000000..c19063a --- /dev/null +++ b/test/simulation/122-xleave @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "interleaved mode" + +client_server_options="xleave" +client_conf=" +logdir tmp +log rawmeasurements" + +server_conf="noclientlog" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_file_messages "111 111 .111.* 4I [DKH] [DKH]\$" 0 0 measurements.log || test_fail +rm -f tmp/measurements.log + +server_conf="" +max_sync_time=270 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_file_messages "111 111 1111.* 4B [DKH] [DKH]\$" 2 2 measurements.log || test_fail +check_file_messages "111 111 1111.* 4I [DKH] [DKH]\$" 30 200 measurements.log || test_fail +check_file_messages "111 111 0111.* 4I [DKH] [DKH]\$" 1 1 measurements.log || test_fail +rm -f tmp/measurements.log + +clients=2 +peers=2 +max_sync_time=500 +base_delay="(+ 1e-4 (* -1 (equal 0.1 from 2) (equal 0.1 to 1)))" + +client_lpeer_options="xleave minpoll 5 maxpoll 5" +client_rpeer_options="minpoll 5 maxpoll 5" + +run_test || test_fail +check_chronyd_exit || test_fail +# These checks are expected to fail +check_source_selection && test_fail +check_sync && test_fail + +rm -f tmp/measurements.log + +for rpoll in 4 5 6; do + client_rpeer_options="xleave minpoll $rpoll maxpoll $rpoll" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + + if [ $rpoll -le 5 ]; then + check_file_messages "111 111 1111.* 1B [DKH] [DKH]\$" 0 0 measurements.log || test_fail + check_file_messages "111 111 1111.* 1I [DKH] [DKH]\$" 200 310 measurements.log || test_fail + else + check_file_messages "111 111 1111.* 1B [DKH] [DKH]\$" 125 135 measurements.log || test_fail + check_file_messages "111 111 1111.* 1I [DKH] [DKH]\$" 20 30 measurements.log || test_fail + fi + rm -f tmp/measurements.log +done + +if check_config_h 'FEAT_CMDMON 1'; then + # test client timestamp selection and server timestamp correction + base_delay="(+ 1.25e-6 (* -1 (equal 0.1 from 5)))" + jitter=1e-9 + wander=1e-12 + client_lpeer_options="xleave minpoll 5 maxpoll 5 noselect" + client_rpeer_options="xleave minpoll 5 maxpoll 5 noselect" + chronyc_conf="doffset -0.1" + chronyc_start=7200 + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync && test_fail + + check_file_messages "\.2 N 2 111 111 .... 5 5 .\... ..\....e-.. 2\....e-06" \ + 290 310 measurements.log || test_fail + check_file_messages "\.2 N 2 111 111 .... 5 5 .\... ..\....e-.. .\....e-0[0123]" \ + 0 0 measurements.log || test_fail + rm -f tmp/measurements.log +fi + +test_pass diff --git a/test/simulation/123-mindelay b/test/simulation/123-mindelay new file mode 100755 index 0000000..89a9f33 --- /dev/null +++ b/test/simulation/123-mindelay @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "mindelay and asymmetry options" + +jitter_asymmetry=0.499 +time_rms_limit=1e-6 +time_freq_limit=1e-9 +wander=1e-12 + +for client_server_options in "mindelay 2e-4 asymmetry 0.499"; do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_packet_interval || test_fail + check_sync || test_fail +done + +for client_server_options in "mindelay 1e-4 asymmetry 0.499" "mindelay 2e-4 asymmetry 0.0"; do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync && test_fail +done + +test_pass diff --git a/test/simulation/124-tai b/test/simulation/124-tai new file mode 100755 index 0000000..97064f7 --- /dev/null +++ b/test/simulation/124-tai @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "tai option" + +check_config_h 'FEAT_REFCLOCK 1' || test_skip + +export CLKNETSIM_START_DATE=$(TZ=UTC date -d 'Dec 31 2008 23:50:00' +'%s') + +leap=$[10 * 60] +limit=$[20 * 60] +min_sync_time=2 +max_sync_time=15 +refclock_jitter=1e-6 +servers=0 + +refclock_offset="(+ -34 (equal 0.1 (max (sum 1.0) $leap) $leap))" +client_conf=" +refclock SHM 0 dpoll 0 poll 0 tai +leapsectz right/UTC +leapsecmode ignore +maxchange 1e-3 1 0" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +export CLKNETSIM_START_DATE=$(TZ=UTC date -d 'Jan 01 2009 00:10:00' +'%s') + +time_offset=-1000 +refclock_offset="(+ -34)" +client_conf=" +refclock SHM 0 dpoll 0 poll 0 tai +leapsectz right/UTC +makestep 1 1 +maxchange 1e-3 1 0" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/125-packetloss b/test/simulation/125-packetloss new file mode 100755 index 0000000..505e4fa --- /dev/null +++ b/test/simulation/125-packetloss @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "packet loss" + +# Drop 33% of packets by default and 100% on the 3->1 path +base_delay=$(cat <<-EOF | tr -d '\n' + (+ 1e-4 + (* -1 (equal 0.33 (uniform) 1.0)) + (* -1 (equal 0.1 from 3) (equal 0.1 to 1))) +EOF +) +clients=2 +peers=2 +jitter=1e-5 +limit=20000 +max_sync_time=10000 + +for options in "maxpoll 8" "maxpoll 8 xleave"; do + client_server_options=$options + client_peer_options=$options + + run_test || test_fail + check_chronyd_exit || test_fail + check_sync || test_fail +done + +test_pass diff --git a/test/simulation/126-burst b/test/simulation/126-burst new file mode 100755 index 0000000..1cb6f9c --- /dev/null +++ b/test/simulation/126-burst @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "burst option" + +# Pass every fourth packet on the 2->1 path +base_delay=$(cat <<-EOF | tr -d '\n' + (+ 1e-4 + (* -1 + (equal 0.1 from 2) + (equal 0.1 to 1) + (equal 0.1 (min (% (sum 1) 4) 1) 1))) +EOF +) + +client_server_options="burst polltarget 1" +min_sync_time=700 +max_sync_time=730 +client_max_min_out_interval=2.2 +client_min_mean_out_interval=150.0 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +# Add a significant delay to 70% of packets on the 2->1 path after 6th packet +base_delay=$(cat <<-EOF | tr -d '\n' + (+ 1e-4 + (* 0.15 + (equal 0.1 from 2) + (equal 0.1 to 1) + (equal 0.1 (min (sum 1) 7) 7) + (equal 0.7 (uniform) 0.0))) +EOF +) + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail + +test_pass diff --git a/test/simulation/127-filter b/test/simulation/127-filter new file mode 100755 index 0000000..739dd91 --- /dev/null +++ b/test/simulation/127-filter @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "filter option" + +client_server_options="minpoll 4 maxpoll 4 filter 15 maxdelay 3.5e-4" +min_sync_time=710 +max_sync_time=720 +client_max_min_out_interval=16.1 +client_min_mean_out_interval=15.9 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +base_delay="(+ 1e-4 (* -1 (equal 0.3 (uniform) 0.0)))" +client_server_options="minpoll 4 maxpoll 4 filter 3" +min_sync_time=130 + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +limit=10 +client_server_options="minpoll -6 maxpoll -6 filter 1" + +base_delay=1e-4 + +run_test || test_fail +check_chronyd_exit || test_fail +check_file_messages " 2 1 " 590 640 log.packets || test_fail + +base_delay=2e-2 + +run_test || test_fail +check_chronyd_exit || test_fail +check_file_messages " 2 1 " 9 10 log.packets || test_fail + +test_pass diff --git a/test/simulation/128-nocontrol b/test/simulation/128-nocontrol new file mode 100755 index 0000000..3f0d18d --- /dev/null +++ b/test/simulation/128-nocontrol @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "-x option" + +check_config_h 'FEAT_CMDMON 1' || test_skip + +wander=0.0 +time_offset=0.0 +freq_offset=0.0 +time_max_limit=1e-6 +freq_max_limit=1e-9 +min_sync_time=0 +max_sync_time=0 +client_chronyd_options="-x" +chronyc_start=300 +chronyc_conf="tracking" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail +check_chronyc_output "^.*Stratum *: 2.*$" || test_fail + +test_pass diff --git a/test/simulation/129-reload b/test/simulation/129-reload new file mode 100755 index 0000000..56bc3da --- /dev/null +++ b/test/simulation/129-reload @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "-r option" + +wander=0.0 +limit=100 +min_sync_time=100 +max_sync_time=104 +client_chronyd_options="-r" +client_conf="dumpdir tmp +maxupdateskew 10000" + +run_test || test_fail +check_chronyd_exit || test_fail + +check_log_messages "Loaded dump file" 0 0 || test_fail +check_file_messages "." 6 6 192.168.123.1.dat || test_fail + +client_start=$limit +limit=1000 + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_log_messages "Loaded dump file" 1 1 || test_fail +check_file_messages "." 10 30 192.168.123.1.dat || test_fail + +rm -f tmp/*.dat + +client_start=0 +limit=200 +jitter=1e-6 +client_conf="dumpdir tmp +maxupdateskew 1e-6 +maxslewrate 1e-6" + +run_test || test_fail +check_chronyd_exit || test_fail + +check_log_messages "Loaded dump file" 0 0 || test_fail +check_file_messages "." 8 8 192.168.123.1.dat || test_fail +cp tmp/192.168.123.1.dat tmp/backup.dat + +client_start=$limit +limit=1000 +min_sync_time=201 +max_sync_time=203 +client_server_options="offline" +client_conf="dumpdir tmp" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_log_messages "Loaded dump file" 1 1 || test_fail +check_file_messages "." 8 8 192.168.123.1.dat || test_fail + +cp -f tmp/backup.dat tmp/192.168.123.1.dat + +client_server_options="key 1" + +run_test || test_fail +check_chronyd_exit || test_fail +check_sync && test_fail + +check_log_messages "Could not load dump file" 1 1 || test_fail +check_log_messages "Loaded dump file" 0 0 || test_fail + +client_server_options="" + +if check_config_h 'FEAT_REFCLOCK 1'; then + refclock_jitter=1e-6 + servers=0 + client_start=0 + limit=40 + min_sync_time=56 + max_sync_time=58 + client_chronyd_options="-r" + client_conf="dumpdir tmp + refclock SHM 0" + + run_test || test_fail + check_chronyd_exit || test_fail + + check_log_messages "Loaded dump file" 0 0 || test_fail + check_file_messages "." 6 6 refid:53484d30.dat || test_fail + + client_start=$limit + limit=300 + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + + check_log_messages "Loaded dump file" 1 1 || test_fail + check_file_messages "." 6 23 refid:53484d30.dat || test_fail + + rm -f tmp/*.dat +fi + +test_pass diff --git a/test/simulation/130-quit b/test/simulation/130-quit new file mode 100755 index 0000000..da2b8cf --- /dev/null +++ b/test/simulation/130-quit @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "-q/-Q option" + +wander=0.0 +freq_offset=0.0 +min_sync_time=5 +max_sync_time=10 +client_chronyd_options="-q" +client_server_options="iburst" + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +min_sync_time=1 +max_sync_time=1 +client_server_options="iburst maxsamples 1" + +run_test || test_fail +check_chronyd_exit || test_fail +check_sync || test_fail + +client_chronyd_options="-Q" +run_test || test_fail +check_sync && test_fail + +test_pass diff --git a/test/simulation/131-maxchange b/test/simulation/131-maxchange new file mode 100755 index 0000000..59cc0c1 --- /dev/null +++ b/test/simulation/131-maxchange @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "maxchange directive" + +time_offset=2 +max_sync_time=5000 +client_conf="maxchange 0.1 1 3" +client_step="(* $step (equal 0.1 (sum 1.0) 300))" + +run_test || test_fail +check_chronyd_exit && test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync && test_fail +check_log_messages "seconds exceeds.*ignored" 3 3 || test_fail +check_log_messages "seconds exceeds.*exiting" 1 1 || test_fail + +test_pass diff --git a/test/simulation/132-logchange b/test/simulation/132-logchange new file mode 100755 index 0000000..59ddf7c --- /dev/null +++ b/test/simulation/132-logchange @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "logchange directive" + +time_offset=2 +min_sync_time=590 +max_sync_time=700 +client_server_options="maxsamples 6" +client_conf="logchange 0.1" +client_step="(* $step (equal 0.1 (sum 1.0) 300))" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail +check_log_messages "clock wrong by" 4 8 || test_fail + +test_pass diff --git a/test/simulation/133-hwtimestamp b/test/simulation/133-hwtimestamp new file mode 100755 index 0000000..d3cce6d --- /dev/null +++ b/test/simulation/133-hwtimestamp @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "hwtimestamp directive" + +check_config_h 'HAVE_LINUX_TIMESTAMPING 1' || test_skip + +export CLKNETSIM_TIMESTAMPING=2 +export CLKNETSIM_PHC_DELAY=1e-6 +export CLKNETSIM_PHC_JITTER=1e-7 +export CLKNETSIM_PHC_JITTER_ASYM=0.4 + +refclock_jitter=1e-8 +refclock_offset=10.0 +min_sync_time=4 +max_sync_time=20 +time_rms_limit=1e-7 +freq_rms_limit=3e-8 +jitter=1e-8 +freq_offset=1e-5 +limit=200 +server_conf=" +clockprecision 1e-9 +hwtimestamp eth0" +client_server_options="minpoll 0 maxpoll 0 xleave" +client_chronyd_options="-d" + +for client_conf in \ + "hwtimestamp eth0 nocrossts + clockprecision 1e-9" \ + "hwtimestamp eth0 + clockprecision 1e-9 + acquisitionport 123"; do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + + if check_config_h 'FEAT_DEBUG 1'; then + check_log_messages "Accepted reading" 0 2 || test_fail + check_log_messages "Combined .* readings" 190 220 || test_fail + check_log_messages "HW clock samples" 190 200 || test_fail + check_log_messages "HW clock reset" 0 0 || test_fail + check_log_messages "Missing TX timestamp" 1 1 || test_fail + check_log_messages "Received message.*tss=KH" 195 200 || test_fail + check_log_messages "Received error.*message.*tss=KH" 195 200 || test_fail + check_log_messages "Updated RX timestamp.*tss=1" 1 1 || test_fail + check_log_messages "Updated RX timestamp.*tss=2" 195 200 || test_fail + if echo "$client_conf" | grep -q nocrossts; then + check_log_messages "update_tx_timestamp.*Updated" 180 200 || test_fail + check_log_messages "update_tx_timestamp.*Unacceptable" 0 10 || test_fail + else + check_log_messages "update_tx_timestamp.*Updated" 50 140 || test_fail + check_log_messages "update_tx_timestamp.*Unacceptable" 50 140 || test_fail + fi + fi +done + +test_pass diff --git a/test/simulation/134-log b/test/simulation/134-log new file mode 100755 index 0000000..ab1ced2 --- /dev/null +++ b/test/simulation/134-log @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "log directive" + +check_config_h 'FEAT_PHC 1' || test_skip + +refclock_jitter=$jitter +client_server_options="maxpoll 6" +client_conf="refclock PHC /dev/ptp0 dpoll 4 poll 6 noselect +logbanner 10 +logdir tmp +log tracking rawmeasurements measurements selection statistics rtc refclocks tempcomp +tempcomp tmp/tempcomp 64 0.0 0.0 0.0 0.0" + +echo 0.0 > tmp/tempcomp + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_file_messages "=============" 31 33 \ + tracking.log measurements.log tempcomp.log || test_fail +check_file_messages "20.*192\.168\.123\.1" 150 160 \ + tracking.log measurements.log statistics.log || test_fail +check_file_messages "20.*PHC0 * N " 300 320 selection.log || test_fail +check_file_messages "20.*192\.168\.123\.1 *[M*]" 300 320 selection.log || test_fail +check_file_messages "20.*PHC0" 150 160 statistics.log || test_fail +check_file_messages "20.*PHC0" 750 800 refclocks.log || test_fail +check_file_messages "20.* 0\.0000" 150 160 tempcomp.log || test_fail + +test_pass diff --git a/test/simulation/135-ratelimit b/test/simulation/135-ratelimit new file mode 100755 index 0000000..86c435d --- /dev/null +++ b/test/simulation/135-ratelimit @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "ratelimit directive" + +server_conf="ratelimit interval 6 burst 2 leak 4" +client_server_options="minpoll 3 maxpoll 3" +min_sync_time=16 + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_file_messages " 2 1 " 1200 1300 log.packets || test_fail +check_file_messages " 1 2 " 180 220 log.packets || test_fail + +test_pass diff --git a/test/simulation/136-broadcast b/test/simulation/136-broadcast new file mode 100755 index 0000000..1488c53 --- /dev/null +++ b/test/simulation/136-broadcast @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "broadcast directive" + +server_conf="broadcast 64 192.168.123.255" +client_server_options="offline" + +run_test || test_fail +check_chronyd_exit || test_fail +check_packet_interval && test_fail + +check_file_messages " 1 2 " 150 160 log.packets || test_fail + +test_pass diff --git a/test/simulation/137-pool b/test/simulation/137-pool new file mode 100755 index 0000000..de8d77d --- /dev/null +++ b/test/simulation/137-pool @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "pool directive" + +limit=500 +client_conf="logdir tmp +log measurements" + +servers=3 +client_server_conf="pool nodes-1-2-3.net1.clk" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_file_messages "20.*192.168.123.1" 5 10 measurements.log || test_fail +check_file_messages "20.*192.168.123.2" 5 10 measurements.log || test_fail +check_file_messages "20.*192.168.123.3" 5 10 measurements.log || test_fail +rm -f tmp/measurements.log + +servers=6 +client_server_conf="pool nodes-1-2-3-4-5-6.net1.clk minpoll 6 maxpoll 6" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_file_messages "20.*192.168.123.*" 30 35 measurements.log || test_fail +rm -f tmp/measurements.log + +servers=6 +client_server_conf="pool nodes-1-2-3-4-5-6.net1.clk maxsources 2 minpoll 6 maxpoll 6" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_file_messages "20.*192.168.123.*" 15 17 measurements.log || test_fail +rm -f tmp/measurements.log + +test_pass diff --git a/test/simulation/138-syncloop b/test/simulation/138-syncloop new file mode 100755 index 0000000..2d3999e --- /dev/null +++ b/test/simulation/138-syncloop @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "loop prevention" + +mkdir tmp/logdir1 tmp/logdir2 + +server_conf=" +server 192.168.123.1 +server 192.168.123.2 +logdir tmp/logdir1 +log measurements" +client_server_conf=" +server 192.168.123.1 +server 192.168.123.2 +logdir tmp/logdir2 +log measurements +allow" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_file_messages "20.*123\.1.* 111 111 1110" 30 200 logdir1/measurements.log || test_fail +check_file_messages "20.*123\.2.* 111 111 1110" 30 200 logdir1/measurements.log || test_fail +check_file_messages "20.*123\...* 111 111 1111" 0 0 logdir1/measurements.log || test_fail +check_file_messages "20.*123\.1.* 111 111 1111" 30 200 logdir2/measurements.log || test_fail +check_file_messages "20.*123\.1.* 111 111 1110" 0 0 logdir2/measurements.log || test_fail +check_file_messages "20.*123\.2.* 111 111 1110" 30 200 logdir2/measurements.log || test_fail +check_file_messages "20.*123\.2.* 111 111 1111" 0 0 logdir1/measurements.log || test_fail + +test_pass diff --git a/test/simulation/139-nts b/test/simulation/139-nts new file mode 100755 index 0000000..6a2112d --- /dev/null +++ b/test/simulation/139-nts @@ -0,0 +1,312 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "NTP authentication with NTS" + +check_config_h 'FEAT_NTS 1' || test_skip +certtool --help &> /dev/null || test_skip + +export CLKNETSIM_START_DATE=$(date -d 'Jan 1 00:00:00 UTC 2010' +'%s') + +for i in 1 2; do + cat > tmp/cert$i.cfg <<-EOF + cn = "node$i.net1.clk" + dns_name = "node$i.net1.clk" + ip_address = "192.168.123.$i" + serial = 001 + activation_date = "2010-01-01 00:00:00 UTC" + expiration_date = "2010-01-02 00:00:00 UTC" + signing_key + encryption_key + EOF + + certtool --generate-privkey --key-type=ed25519 --outfile tmp/server$i.key &> \ + tmp/log.certtool$i + certtool --generate-self-signed --load-privkey tmp/server$i.key \ + --template tmp/cert$i.cfg --outfile tmp/server$i.crt &>> tmp/log.certtool$i +done + +max_sync_time=400 +dns=1 +server_conf=" +ntsserverkey tmp/server1.key +ntsservercert tmp/server1.crt +ntsprocesses 0 +ntsrotate 66 +ntsdumpdir tmp +" +client_server_options="minpoll 6 maxpoll 6 nts" +client_conf=" +nosystemcert +ntstrustedcerts /dev/null +ntstrustedcerts tmp/server1.crt +ntstrustedcerts /dev/null +logdir tmp +log rawmeasurements" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_file_messages "20.*123\.1.* 111 111 1111" 75 80 measurements.log || test_fail +check_file_messages "20.*123\.1.* 111 001 0000" 37 39 measurements.log || test_fail +check_file_messages " 2 1 .* 4460 " 260 300 log.packets || test_fail +check_file_messages "." 6 6 ntskeys || test_fail +rm -f tmp/measurements.log + +client_conf+=" +ntsrefresh 120 +ntsdumpdir tmp" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_file_messages "20.*123\.1.* 111 111 1111" 99 103 measurements.log || test_fail +check_file_messages "20.*123\.1.* 111 001 0000" 0 0 measurements.log || test_fail +check_file_messages " 2 1 .* 4460 " 350 390 log.packets || test_fail +check_file_messages "." 6 6 ntskeys || test_fail +check_file_messages "." 12 13 192.168.123.1.nts || test_fail +rm -f tmp/measurements.log + +export CLKNETSIM_START_DATE=$(date -d 'Jan 1 00:00:00 UTC 2010 + 40000 sec' +'%s') + +server_conf+=" +ntsrotate 100000" +client_conf+=" +ntsrefresh 39500" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_file_messages "20.*123\.1.* 111 111 1111" 150 160 measurements.log || test_fail +check_file_messages "20.*123\.1.* 111 001 0000" 0 0 measurements.log || test_fail +check_file_messages " 2 1 .* 4460 " 6 10 log.packets || test_fail +check_file_messages "^9\.......e+03 2 1 .* 4460 " 6 10 log.packets || test_fail +check_file_messages "." 6 6 ntskeys || test_fail +check_file_messages "." 12 13 192.168.123.1.nts || test_fail +rm -f tmp/measurements.log + +client_conf=" +nosystemcert" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection && test_fail +check_sync && test_fail + +check_file_messages " 2 1 .* 123 " 0 0 log.packets || test_fail +check_file_messages " 2 1 .* 4460 " 10 20 log.packets || test_fail + +export CLKNETSIM_START_DATE=$(date -d 'Jan 2 00:00:01 UTC 2010' +'%s') + +client_conf=" +nosystemcert +ntstrustedcerts tmp/server1.crt" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection && test_fail +check_sync && test_fail + +check_file_messages " 2 1 .* 123 " 0 0 log.packets || test_fail +check_file_messages " 2 1 .* 4460 " 10 20 log.packets || test_fail +check_log_messages "expired certificate" 4 4 || test_fail + +client_conf+=" +nocerttimecheck 1" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +export CLKNETSIM_START_DATE=$(date -d 'Jan 1 00:00:00 UTC 2010' +'%s') + +client_conf=" +nosystemcert +ntstrustedcerts tmp/server1.crt +ntsrefresh 500" + +for dns in 1 0; do + server_conf=" + ntsserverkey tmp/server1.key + ntsservercert tmp/server1.crt + ntsprocesses 0 + ntsrotate 0 + ntsdumpdir tmp" + + if [ $dns != 0 ]; then + server_conf+=" + ntsntpserver node2.net1.clk" + client_server_conf="server node1.net1.clk $client_server_options" + else + server_conf+=" + ntsntpserver 192.168.123.2" + client_server_conf="server 192.168.123.1 $client_server_options" + fi + + servers=1 + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection && test_fail + check_sync && test_fail + + check_file_messages " 2 1 .* 4460 " 50 100 log.packets || test_fail + check_file_messages " 2 2 .* 4460 " 0 0 log.packets || test_fail + check_log_messages "Source 192.168.123.1 changed to 192.168.123.2" 6 8 || test_fail + check_log_messages "Source 192.168.123.2 replaced with 192.168.123.1" 6 8 || test_fail + + servers=2 + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + + check_file_messages " 3 1 .* 4460 " 100 150 log.packets || test_fail + check_file_messages " 3 2 .* 4460 " 0 0 log.packets || test_fail + check_log_messages "Source 192.168.123.1 changed to 192.168.123.2" 1 1 || test_fail + check_log_messages "Source 192.168.123.2 replaced with 192.168.123.1" 0 0 || test_fail + + server_conf+=" + ntsratelimit interval 12 burst 1 leak 4" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection && test_fail + + check_file_messages " 3 1 .* 4460 1 0 2" 25 50 log.packets || test_fail + check_file_messages " 3 2 .* 4460 " 0 0 log.packets || test_fail + check_log_messages "Source 192.168.123.1 changed to 192.168.123.2" 2 6 || test_fail + check_log_messages "Source 192.168.123.2 replaced with 192.168.123.1" 1 6 || test_fail +done + +servers=2 +server_conf=" +ntsserverkey tmp/server1.key +ntsservercert tmp/server1.crt +ntsprocesses 0 +ntsrotate 0 +ntsntpserver node2.net1.clk +port 11123 +ntsdumpdir tmp" +client_conf=" +nosystemcert +ntstrustedcerts tmp/server1.crt +ntsdumpdir tmp" +client_server_conf="server 192.168.123.1 $client_server_options" + +rm -f tmp/*.nts + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_log_messages "Could not change" 0 0 || test_fail +check_file_messages " 3 1 .* 4460 1 0 2" 1 1 log.packets || test_fail +check_file_messages " 3 2 .* 4460 " 0 0 log.packets || test_fail + +for dns in 1 0; do + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + + check_log_messages "Could not change" 0 0 || test_fail + check_file_messages " 3 1 .* 4460 1 0 2" 0 0 log.packets || test_fail + check_file_messages " 3 2 .* 4460 " 0 0 log.packets || test_fail +done + +server_conf=" +ntsserverkey tmp/server1.key +ntsservercert tmp/server1.crt +ntsprocesses 0 +ntsrotate 0 +ntsdumpdir tmp" + +head -n 8 tmp/192.168.123.1.nts > tmp/192.168.123.1.nts_ +mv tmp/192.168.123.1.nts_ tmp/192.168.123.1.nts + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_log_messages "Could not change" 0 0 || test_fail +check_file_messages " 3 1 .* 4460 1 0 2" 1 1 log.packets || test_fail +check_file_messages " 3 2 .* 4460 " 0 0 log.packets || test_fail +check_file_messages " 3 1 .* 11123 " 0 0 log.packets || test_fail +check_file_messages " 3 2 .* 123 " 0 0 log.packets || test_fail +check_file_messages " 3 2 .* 11123 " 3 3 log.packets || test_fail + +dns=1 +server_conf=" +ntsserverkey tmp/server1.key +ntsservercert tmp/server1.crt +ntsserverkey tmp/server2.key +ntsservercert tmp/server2.crt +ntsprocesses 0" +client_conf=" +nosystemcert +ntstrustedcerts tmp/server1.crt +ntstrustedcerts tmp/server2.crt +minsources 2" +client_server_conf="" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +client_conf=" +nosystemcert +ntstrustedcerts tmp/server1.crt +ntstrustedcerts 1 tmp/server1.crt +ntstrustedcerts 2 tmp/server2.crt +ntstrustedcerts 3 tmp/server2.crt" +client_server_conf=" +server node1.net1.clk $client_server_options certset 0 +server node2.net1.clk $client_server_options certset 2" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_file_messages " 3 1 .* 123 " 100 200 log.packets || test_fail +check_file_messages " 3 2 .* 123 " 100 200 log.packets || test_fail + +client_server_conf=" +server node1.net1.clk $client_server_options certset 2 +server node2.net1.clk $client_server_options" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection && test_fail +check_sync && test_fail + +check_file_messages " 3 1 .* 123 " 0 0 log.packets || test_fail +check_file_messages " 3 2 .* 123 " 0 0 log.packets || test_fail + +client_conf=" +nosystemcert +ntstrustedcerts tmp/nosuch.crt +ntstrustedcerts 2 tmp/nosuch.crt" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection && test_fail +check_sync && test_fail + +check_file_messages " 3 1 .* 123 " 0 0 log.packets || test_fail +check_file_messages " 3 2 .* 123 " 0 0 log.packets || test_fail + +test_pass diff --git a/test/simulation/140-noclientlog b/test/simulation/140-noclientlog new file mode 100755 index 0000000..502398f --- /dev/null +++ b/test/simulation/140-noclientlog @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +. ./test.common +test_start "noclientlog option" + +server_conf="noclientlog" +client_server_options="xleave" +client_conf=" +logdir tmp +log rawmeasurements" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +check_file_messages "111 111 1111.* 4B " 30 200 measurements.log || test_fail +check_file_messages "111 111 1111.* 4I " 0 0 measurements.log || test_fail + +test_pass diff --git a/test/simulation/141-copy b/test/simulation/141-copy new file mode 100755 index 0000000..80e56bc --- /dev/null +++ b/test/simulation/141-copy @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "copy option" + +check_config_h 'FEAT_CMDMON 1' || test_skip + +client_server_options="copy" +chronyc_conf="tracking" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail +check_chronyc_output "^Reference ID *: 7F7F0101 \(192\.168\.123\.1\) +Stratum *: 1" || test_fail + +test_pass diff --git a/test/simulation/142-ptpport b/test/simulation/142-ptpport new file mode 100755 index 0000000..060932c --- /dev/null +++ b/test/simulation/142-ptpport @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "PTP port" + +# Block communication between 3 and 1 +base_delay="(+ 1e-4 (* -1 (equal 0.1 from 3) (equal 0.1 to 1)))" + +cat > tmp/peer.keys <<-EOF +1 MD5 1234567890 +EOF + +clients=2 +peers=2 +max_sync_time=420 + +server_conf=" +ptpport 319" +client_conf=" +ptpport 319 +authselectmode ignore +keyfile tmp/peer.keys" +client_server_options="minpoll 6 maxpoll 6 port 319" +client_peer_options="minpoll 6 maxpoll 6 port 319 key 1" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_sync || test_fail + +check_file_messages " 2 1 .* 319 319 1 96 " 150 160 \ + log.packets || test_fail +check_file_messages " 1 2 .* 319 319 1 96 " 150 160 \ + log.packets || test_fail +check_file_messages " 2 3 .* 319 319 1 116 " 150 160 \ + log.packets || test_fail +check_file_messages " 3 2 .* 319 319 1 116 " 150 160 \ + log.packets || test_fail + +test_pass diff --git a/test/simulation/143-manual b/test/simulation/143-manual new file mode 100755 index 0000000..618cee6 --- /dev/null +++ b/test/simulation/143-manual @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +. ./test.common + +export TZ=UTC + +test_start "manual input" + +check_config_h 'FEAT_CMDMON 1' || test_skip + +limit=$[12 * 3600] +client_server_conf=" " +client_conf="manual" +chronyc_conf="timeout 4000000 +settime 1:00:00 +settime 2:00:00 +settime 3:00:00 +settime 4:00:00 +manual delete 2 +settime 6:00:00 +manual list +settime 8:00:00 +manual reset +settime 10:00:00 +manual list" +chronyc_start=1800 +base_delay=1800 +jitter=1e-6 + +time_max_limit=4e-3 +freq_max_limit=4e-3 +time_rms_limit=2e-3 +freq_rms_limit=2e-5 +min_sync_time=7204 +max_sync_time=7206 + +run_test || test_fail +check_chronyd_exit || test_fail +check_sync || test_fail + +check_chronyc_output "^200 OK +Clock was 0\.4. seconds fast\. Frequency change = 0\.00ppm, new frequency = 0\.00ppm +200 OK +Clock was 0\.3. seconds fast\. Frequency change = (99|100)\...ppm, new frequency = (99|100)\...ppm +200 OK +Clock was \-?0\.0. seconds fast\. Frequency change = \-?0\.[01].ppm, new frequency = (99|100)\...ppm +200 OK +Clock was \-?0\.0. seconds fast\. Frequency change = \-?0\.[01].ppm, new frequency = (99|100)\...ppm +200 OK +200 OK +Clock was \-?0\.0. seconds fast\. Frequency change = \-?0\.[012].ppm, new frequency = (99|100)\...ppm +210 n_samples = 4 +# Date Time\(UTC\) Slewed Original Residual +======================================================= + 0 2010-01-01 (00:59:59|01:00:00) [- ]0\.00 0\.46 [- ]0\.00 + 1 2010-01-01 (01:59:59|02:00:00) [- ]0\.00 0\.36 [- ]0\.00 + 2 2010-01-01 (03:59:59|04:00:00) [- ]0\.00 [- ]0\.00 [- ]0\.00 + 3 2010-01-01 (05:59:59|06:00:00) [- ]0\.00 [- ]0\.00 [- ]0\.00 +200 OK +Clock was \-?0\.0. seconds fast\. Frequency change = \-?0\.[012].ppm, new frequency = (99|100)\...ppm +200 OK +200 OK +Clock was \-?0\.0. seconds fast\. Frequency change = \-?0\.00ppm, new frequency = (99|100)\...ppm +210 n_samples = 1 +# Date Time\(UTC\) Slewed Original Residual +======================================================= + 0 2010-01-01 (09:59:59|10:00:00) [- ]0\.00 [- ]0\.00 [- ]0\.00$" \ + || test_fail + +test_pass diff --git a/test/simulation/144-exp1 b/test/simulation/144-exp1 new file mode 100755 index 0000000..4a2042d --- /dev/null +++ b/test/simulation/144-exp1 @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +. ./test.common + +test_start "experimental extension field" + +check_config_h 'FEAT_CMDMON 1' || test_skip + +primary_time_offset=0.1 +server_strata=4 +min_sync_time=2000 +max_sync_time=2300 +chronyc_conf="doffset 0.1" +chronyc_options="-h /clknetsim/unix/1:1" +chronyc_start=2000 + +for options in "extfield F323" "xleave extfield F323"; do + client_server_options="minpoll 6 maxpoll 6 $options" + server_server_options="$client_server_options" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail +done + +server_server_options="" +server_strata=1 +clients=4 +peers=4 +max_sync_time=2400 +# chain of peers and one enabled chronyc +base_delay=$(cat <<-EOF | tr -d '\n' + (+ 1e-4 -1 + (equal 0.1 from (+ to 1)) + (equal 0.1 from (+ to -1)) + (equal 0.1 from 6) + (equal 0.1 to 6)) +EOF +) + +for lpoll in 5 6 7; do + for options in "minsamples 16 extfield F323" "minsamples 16 xleave extfield F323"; do + client_lpeer_options="minpoll $lpoll maxpoll $lpoll $options" + client_rpeer_options="minpoll 6 maxpoll 6 $options" + client_server_options="$client_rpeer_options" + + run_test || test_fail + check_chronyd_exit || test_fail + check_source_selection || test_fail + check_sync || test_fail + done +done + +test_pass diff --git a/test/simulation/201-freqaccumulation b/test/simulation/201-freqaccumulation new file mode 100755 index 0000000..6f14246 --- /dev/null +++ b/test/simulation/201-freqaccumulation @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +. ./test.common + +# Test fix in commit 60d0fa299307076143da94d36deb7b908fa9bdb7 + +test_start "frequency accumulation" + +time_offset=100.0 +jitter=1e-6 +base_delay=1e-6 +wander=0.0 + +limit=180 +time_max_limit=1e-5 +freq_max_limit=1e-7 +time_rms_limit=1e-5 +freq_rms_limit=1e-7 +min_sync_time=120 +max_sync_time=140 + +client_server_options="minpoll 6 maxpoll 6" +client_conf="driftfile tmp/drift +makestep 1 1" + +for freq_offset in -5e-2 -5e-4 5e-4 5e-2; do + for drift in -1e+4 -1e+2 1e+2 1e+4; do + echo "$drift 100000" > tmp/drift + run_test || test_fail + check_chronyd_exit || test_fail + check_sync || test_fail + done +done + +test_pass diff --git a/test/simulation/202-prefer b/test/simulation/202-prefer new file mode 100755 index 0000000..207c800 --- /dev/null +++ b/test/simulation/202-prefer @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +. ./test.common + +# Test fix in commit 4253075a97141edfa62043ab71bd0673587e6629 + +test_start "prefer option" + +servers=3 +client_server_conf=" +server 192.168.123.1 +server 192.168.123.2 +server 192.168.123.3 prefer" + +run_test || test_fail +check_chronyd_exit || test_fail +check_source_selection || test_fail +check_packet_interval || test_fail +check_sync || test_fail + +test_pass diff --git a/test/simulation/README b/test/simulation/README new file mode 100644 index 0000000..e174500 --- /dev/null +++ b/test/simulation/README @@ -0,0 +1,11 @@ +This is a collection of simulation tests using the clknetsim simulator +(supported on Linux only). + +https://github.com/mlichvar/clknetsim + +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. diff --git a/test/simulation/run b/test/simulation/run new file mode 100755 index 0000000..0954438 --- /dev/null +++ b/test/simulation/run @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +print_help() { + echo "$1 [-a] [-i ITERATIONS] [-m MAXFAILS] [-s SEED] [TEST]..." +} + +run_test() { + local result name=$1 seed=$2 + + CLKNETSIM_RANDOM_SEED=$seed ./$name + result=$? + + if [ $result -ne 0 -a $result -ne 9 ]; then + if [ $abort_on_fail -ne 0 ]; then + echo 1>&2 + echo Failed with random seed $seed 1>&2 + exit 1 + fi + failed_seeds=(${failed_seeds[@]} $seed) + fi + + return $result +} + +abort_on_fail=0 +iterations=1 +max_fails=0 +random_seed=${CLKNETSIM_RANDOM_SEED:-$RANDOM} + +while getopts ":ai:m:s:" opt; do + case $opt in + a) abort_on_fail=1;; + i) iterations=$OPTARG;; + m) max_fails=$OPTARG;; + s) random_seed=$OPTARG;; + *) print_help "$0"; exit 3;; + esac +done + +shift $[$OPTIND - 1] + +passed=() failed=() skipped=() failed_seeds=() + +[ $# -gt 0 ] && tests=($@) || tests=([0-9]*-*[^_]) + +for test in "${tests[@]}"; do + if [ $iterations -gt 1 ]; then + printf "%-30s" "$test" + fails=0 + for i in $(seq 1 $iterations); do + run_test $test $[$random_seed + $i - 1] > /dev/null + case $? in + 0) echo -n ".";; + 9) break;; + *) echo -n "x"; fails=$[$fails + 1];; + esac + done + if [ $i -lt $iterations ]; then + printf "%${iterations}s" "" + echo " SKIP" + result=9 + elif [ $fails -gt $max_fails ]; then + echo " FAIL" + result=1 + else + echo " PASS" + result=0 + fi + else + printf "%s " "$test" + run_test $test $random_seed + result=$? + echo + fi + + case $result in + 0) passed=(${passed[@]} $test);; + 9) skipped=(${skipped[@]} $test);; + *) failed=(${failed[@]} $test);; + esac +done + +echo +echo "SUMMARY:" +echo " TOTAL $[${#passed[@]} + ${#failed[@]} + ${#skipped[@]}]" +echo " PASSED ${#passed[@]}" +echo " FAILED ${#failed[@]} (${failed[@]}) (${failed_seeds[@]})" +echo " SKIPPED ${#skipped[@]} (${skipped[@]})" + +[ ${#failed[@]} -eq 0 ] diff --git a/test/simulation/test.common b/test/simulation/test.common new file mode 100644 index 0000000..70bbde1 --- /dev/null +++ b/test/simulation/test.common @@ -0,0 +1,528 @@ +# Copyright (C) 2013-2014 Miroslav Lichvar <mlichvar@redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# 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, see <http://www.gnu.org/licenses/>. + +export LC_ALL=C +export PATH=../../:$PATH +export CLKNETSIM_PATH=${CLKNETSIM_PATH:-clknetsim} + +if [ ! -x $CLKNETSIM_PATH/clknetsim ]; then + echo "SKIP (clknetsim not found)" + exit 9 +fi + +. $CLKNETSIM_PATH/clknetsim.bash + +# Default test testings + +default_limit=10000 +default_primary_time_offset=0.0 +default_time_offset=1e-1 +default_freq_offset=1e-4 +default_base_delay=1e-4 +default_jitter=1e-4 +default_jitter_asymmetry=0.0 +default_wander=1e-9 +default_refclock_jitter="" +default_refclock_offset=0.0 + +default_update_interval=0 +default_shift_pll=2 + +default_server_strata=1 +default_servers=1 +default_clients=1 +default_peers=0 +default_falsetickers=0 +default_server_start=0.0 +default_client_start=0.0 +default_chronyc_start=1000.0 +default_server_step="" +default_client_step="" + +default_client_server_conf="" +default_server_server_options="" +default_client_server_options="" +default_server_peer_options="" +default_server_lpeer_options="" +default_server_rpeer_options="" +default_client_peer_options="" +default_client_lpeer_options="" +default_client_rpeer_options="" +default_server_conf="" +default_client_conf="" +default_chronyc_conf="" +default_server_chronyd_options="" +default_client_chronyd_options="" +default_chronyc_options="" + +default_time_max_limit=1e-3 +default_freq_max_limit=5e-4 +default_time_rms_limit=3e-4 +default_freq_rms_limit=1e-5 +default_min_sync_time=120 +default_max_sync_time=210 + +default_client_min_mean_out_interval=0.0 +default_client_max_min_out_interval=inf + +default_cmdmon_unix=1 +default_dns=0 + +# Initialize test settings from their defaults +for defoptname in ${!default_*}; do + optname=${defoptname#default_} + [ -z "${!optname}" ] && declare "$optname"="${!defoptname}" +done + +test_start() { + rm -rf tmp/* + echo "Testing $@:" + + check_config_h 'FEAT_NTP 1' || test_skip +} + +test_pass() { + echo "PASS" + exit 0 +} + +test_fail() { + echo "FAIL" + exit 1 +} + +test_skip() { + echo "SKIP" + exit 9 +} + +test_ok() { + pad_line + echo -e "\tOK" + return 0 +} + +test_bad() { + pad_line + echo -e "\tBAD" + return 1 +} + +test_error() { + pad_line + echo -e "\tERROR" + return 1 +} + +msg_length=0 +pad_line() { + local line_length=56 + [ $msg_length -lt $line_length ] && \ + printf "%$[$line_length - $msg_length]s" "" + msg_length=0 +} + +# Print aligned message +test_message() { + local level=$1 eol=$2 + shift 2 + local msg="$*" + + while [ $level -gt 0 ]; do + echo -n " " + level=$[$level - 1] + msg_length=$[$msg_length + 2] + done + echo -n "$msg" + + msg_length=$[$msg_length + ${#msg}] + if [ $eol -ne 0 ]; then + echo + msg_length=0 + fi +} + +get_wander_expr() { + local scaled_wander + + scaled_wander=$(awk "BEGIN {print $wander / \ + sqrt($update_interval < 0 ? 2^-($update_interval) : 1)}") + + echo "(+ $freq_offset (sum (* $scaled_wander (normal))))" +} + + +get_delay_expr() { + local direction=$1 asym + + if [ $jitter_asymmetry == "0.0" ]; then + asym="" + elif [ $direction = "up" ]; then + asym=$(awk "BEGIN {print 1 - 2 * $jitter_asymmetry}") + elif [ $direction = "down" ]; then + asym=$(awk "BEGIN {print 1 + 2 * $jitter_asymmetry}") + fi + echo "(+ $base_delay (* $asym $jitter (exponential)))" +} + +get_refclock_expr() { + echo "(+ $refclock_offset (* $refclock_jitter (normal)))" +} + +get_chronyd_nodes() { + echo $[$servers * $server_strata + $clients] +} + +get_node_name() { + local index=$1 + + if [ $dns -ne 0 ]; then + echo "node$index.net1.clk" + else + echo "192.168.123.$index" + fi +} + +get_chronyd_conf() { + local i stratum=$1 peer=$2 + + if [ $stratum -eq 1 ]; then + echo "local stratum 1" + echo "$server_conf" + elif [ $stratum -le $server_strata ]; then + for i in $(seq 1 $servers); do + echo "server $(get_node_name $[$servers * ($stratum - 2) + $i]) $server_server_options" + done + for i in $(seq 1 $peers); do + [ $i -eq $peer -o $i -gt $servers ] && continue + echo -n "peer $(get_node_name $[$servers * ($stratum - 1) + $i]) $server_peer_options " + [ $i -lt $peer ] && echo "$server_lpeer_options" || echo "$server_rpeer_options" + done + echo "$server_conf" + else + echo "deny" + if [ -n "$client_server_conf" ]; then + echo "$client_server_conf" + else + for i in $(seq 1 $servers); do + echo "server $(get_node_name $[$servers * ($stratum - 2) + $i]) $client_server_options" + done + fi + for i in $(seq 1 $peers); do + [ $i -eq $peer -o $i -gt $clients ] && continue + echo -n "peer $(get_node_name $[$servers * ($stratum - 1) + $i]) $client_peer_options " + [ $i -lt $peer ] && echo "$client_lpeer_options" || echo "$client_rpeer_options" + done + echo "$client_conf" + fi +} + +# Check if chrony was built with specified option in config.h +check_config_h() { + local pattern=$1 + grep -q "^#define $pattern" ../../config.h +} + +# Check if the clock was well synchronized +check_sync() { + local i sync_time max_time_error max_freq_error ret=0 + local rms_time_error rms_freq_error + + test_message 2 1 "checking clock sync time, max/rms time/freq error:" + + for i in $(seq 1 $(get_chronyd_nodes)); do + [ $i -gt $[$servers * $server_strata] ] || continue + + sync_time=$(find_sync tmp/log.offset tmp/log.freq $i \ + $time_max_limit $freq_max_limit 1.0) + max_time_error=$(get_stat 'Maximum absolute offset' $i) + max_freq_error=$(get_stat 'Maximum absolute frequency' $i) + rms_time_error=$(get_stat 'RMS offset' $i) + rms_freq_error=$(get_stat 'RMS frequency' $i) + + test_message 3 0 "node $i: $sync_time $(printf '%.2e %.2e %.2e %.2e' \ + $max_time_error $max_freq_error $rms_time_error $rms_freq_error)" + + check_stat $sync_time $min_sync_time $max_sync_time && \ + check_stat $max_time_error 0.0 $time_max_limit && \ + check_stat $max_freq_error 0.0 $freq_max_limit && \ + check_stat $rms_time_error 0.0 $time_rms_limit && \ + check_stat $rms_freq_error 0.0 $freq_rms_limit && \ + test_ok || test_bad + + [ $? -eq 0 ] || ret=1 + done + + return $ret +} + +# Check if chronyd exited properly +check_chronyd_exit() { + local i ret=0 + + test_message 2 1 "checking chronyd exit:" + + for i in $(seq 1 $(get_chronyd_nodes)); do + test_message 3 0 "node $i:" + + grep -q 'chronyd exiting' tmp/log.$i && \ + ! grep -q 'Adjustment.*exceeds.*exiting' tmp/log.$i && \ + ! grep -q 'Assertion.*failed' tmp/log.$i && \ + test_ok || test_bad + [ $? -eq 0 ] || ret=1 + done + + return $ret +} + +# Check for problems in source selection +check_source_selection() { + local i ret=0 + + test_message 2 1 "checking source selection:" + + for i in $(seq $[$servers * $server_strata + 1] $(get_chronyd_nodes)); do + test_message 3 0 "node $i:" + + ! grep -q 'no majority\|no selectable sources' tmp/log.$i && \ + grep -q 'Selected source' tmp/log.$i && \ + test_ok || test_bad + [ $? -eq 0 ] || ret=1 + done + + return $ret +} + +# Check if incoming and outgoing packet intervals are sane +check_packet_interval() { + local i ret=0 mean_in_interval mean_out_interval min_in_interval min_out_interval + + test_message 2 1 "checking mean/min incoming/outgoing packet interval:" + + for i in $(seq 1 $(get_chronyd_nodes)); do + mean_in_interval=$(get_stat 'Mean incoming packet interval' $i) + mean_out_interval=$(get_stat 'Mean outgoing packet interval' $i) + min_in_interval=$(get_stat 'Minimum incoming packet interval' $i) + min_out_interval=$(get_stat 'Minimum outgoing packet interval' $i) + + test_message 3 0 "node $i: $(printf '%.2e %.2e %.2e %.2e' \ + $mean_in_interval $mean_out_interval $min_in_interval $min_out_interval)" + + # Check that the mean intervals are non-zero and shorter than + # limit, incoming is not longer than outgoing for stratum 1 + # servers, outgoing is not longer than incoming for clients, + # and the minimum outgoing interval is not shorter than the NTP + # sampling separation or iburst interval for clients + nodes=$[$servers * $server_strata + $clients] + check_stat $mean_in_interval 0.1 inf && \ + check_stat $mean_out_interval 0.1 inf && \ + ([ $i -gt $servers ] || \ + check_stat $mean_in_interval 0.0 $mean_out_interval 10*$jitter) && \ + ([ $i -le $[$servers * $server_strata] ] || \ + check_stat $mean_out_interval $client_min_mean_out_interval \ + $mean_in_interval 10*$jitter) && \ + ([ $i -le $[$servers * $server_strata] ] || \ + check_stat $min_out_interval \ + $([ $servers -gt 1 ] && echo 0.18 || echo 1.8) \ + $client_max_min_out_interval) && \ + test_ok || test_bad + + [ $? -eq 0 ] || ret=1 + done + + return $ret +} + +# Compare chronyc output with specified pattern +check_chronyc_output() { + local i ret=0 pattern=$1 + + test_message 2 1 "checking chronyc output:" + + for i in $(seq $[$(get_chronyd_nodes) + 1] $[$(get_chronyd_nodes) + $clients]); do + test_message 3 0 "node $i:" + + [[ "$(cat tmp/log.$i)" =~ $pattern ]] && \ + test_ok || test_bad + [ $? -eq 0 ] || ret=1 + done + + return $ret +} + +# Check the number of messages matching a pattern in the client logs +check_log_messages() { + local i count ret=0 pattern=$1 min=$2 max=$3 + + test_message 2 1 "checking number of messages \"$pattern\":" + + for i in $(seq $[$servers * $server_strata + 1] $(get_chronyd_nodes)); do + count=$(grep "$pattern" tmp/log.$i | wc -l) + test_message 3 0 "node $i: $count" + + [ "$min" -le "$count" ] && [ "$count" -le "$max" ] && \ + test_ok || test_bad + [ $? -eq 0 ] || ret=1 + done + + return $ret +} + +# Check the number of messages matching a pattern in a specified file +check_file_messages() { + local i count ret=0 pattern=$1 min=$2 max=$3 + shift 3 + + test_message 2 1 "checking number of messages \"$pattern\":" + + for i; do + count=$(grep "$pattern" tmp/$i | wc -l) + test_message 3 0 "$i: $count" + + [ "$min" -le "$count" ] && [ "$count" -le "$max" ] && \ + test_ok || test_bad + [ $? -eq 0 ] || ret=1 + done + + return $ret +} + +# Check if only NTP port (123) was used +check_packet_port() { + local i ret=0 port=123 + + test_message 2 1 "checking port numbers in packet log:" + + for i in $(seq 1 $(get_chronyd_nodes)); do + test_message 3 0 "node $i:" + + grep -E -q "^([0-9e.+-]+ ){5}$port " tmp/log.packets && \ + ! grep -E "^[0-9e.+-]+ $i " tmp/log.packets | \ + grep -E -q -v "^([0-9e.+-]+ ){5}$port " && \ + test_ok || test_bad + [ $? -eq 0 ] || ret=1 + done + + return $ret +} + +# Print test settings which differ from default value +print_nondefaults() { + local defoptname optname + + test_message 2 1 "non-default settings:" + for defoptname in ${!default_*}; do + optname=${defoptname#default_} + [ "${!defoptname}" = "${!optname}" ] || \ + test_message 3 1 $optname=${!optname} + done +} + +run_simulation() { + local nodes=$1 + + test_message 2 0 "running simulation:" + + start_server $nodes \ + -n 2 \ + -o tmp/log.offset -f tmp/log.freq -p tmp/log.packets \ + -R $(awk "BEGIN {print $update_interval < 0 ? 2^-($update_interval) : 1}") \ + -r $(awk "BEGIN {print $max_sync_time * 2^$update_interval}") \ + -l $(awk "BEGIN {print $limit * 2^$update_interval}") && test_ok || test_error +} + +run_test() { + local i j n stratum node nodes step start freq offset conf options + + test_message 1 1 "network with $servers*$server_strata servers and $clients clients:" + print_nondefaults + + nodes=$(get_chronyd_nodes) + [ -n "$chronyc_conf" ] && nodes=$[$nodes + $clients] + + export CLKNETSIM_UNIX_SUBNET=$[$cmdmon_unix != 0 ? 2 : 0] + + for i in $(seq 1 $nodes); do + echo "node${i}_shift_pll = $shift_pll" + for j in $(seq 1 $nodes); do + echo "node${i}_delay${j} = $(get_delay_expr up)" + echo "node${j}_delay${i} = $(get_delay_expr down)" + done + done > tmp/conf + + node=1 + + for stratum in $(seq 1 $[$server_strata + 1]); do + [ $stratum -le $server_strata ] && n=$servers || n=$clients + + for i in $(seq 1 $n); do + test_message 2 0 "starting node $node:" + if [ $stratum -eq 1 ]; then + step=$server_step + start=$server_start + freq="" + [ $i -le $falsetickers ] && + offset=$i.0 || offset=$primary_time_offset + options=$server_chronyd_options + elif [ $stratum -le $server_strata ]; then + step=$server_step + start=$server_start + freq=$(get_wander_expr) + offset=0.0 + options=$server_chronyd_options + else + step=$client_step + start=$client_start + freq=$(get_wander_expr) + offset=$time_offset + options=$client_chronyd_options + fi + + conf=$(get_chronyd_conf $stratum $i $n) + + [ -z "$freq" ] || echo "node${node}_freq = $freq" >> tmp/conf + [ -z "$step" ] || echo "node${node}_step = $step" >> tmp/conf + [ -z "$refclock_jitter" ] || \ + echo "node${node}_refclock = $(get_refclock_expr)" >> tmp/conf + echo "node${node}_offset = $offset" >> tmp/conf + echo "node${node}_start = $start" >> tmp/conf + start_client $node chronyd "$conf" "" "$options" && \ + test_ok || test_error + + [ $? -ne 0 ] && return 1 + node=$[$node + 1] + done + done + + for i in $(seq 1 $[$nodes - $node + 1]); do + test_message 2 0 "starting node $node:" + + options=$([ $dns -eq 0 ] && printf "%s" "-n") + if [ $cmdmon_unix -ne 0 ]; then + options+=" -h /clknetsim/unix/$[$node - $clients]:1" + else + options+=" -h $(get_node_name $[$node - $clients])" + fi + + echo "node${node}_start = $chronyc_start" >> tmp/conf + start_client $node chronyc "$chronyc_conf" "" "$options $chronyc_options" && \ + test_ok || test_error + + [ $? -ne 0 ] && return 1 + node=$[$node + 1] + done + + run_simulation $nodes +} |