| /* |
| ********************************************************************** |
| * Copyright (C) Miroslav Lichvar 2018 |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of version 2 of the GNU General Public License as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with this program; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| * |
| ********************************************************************** |
| */ |
| |
| #include <local.h> |
| #include "test.h" |
| |
| #define LCL_GetSysPrecisionAsQuantum() (1.0e-6) |
| |
| #include <samplefilt.c> |
| |
| void |
| test_unit(void) |
| { |
| NTP_Sample sample_in, sample_out; |
| SPF_Instance filter; |
| int i, j, k, sum_count, min_samples, max_samples; |
| double mean, combine_ratio, sum_err; |
| |
| LCL_Initialise(); |
| |
| memset(&sample_in, 0, sizeof (sample_in)); |
| memset(&sample_out, 0, sizeof (sample_out)); |
| |
| for (i = 0; i <= 100; i++) { |
| max_samples = random() % 20 + 1; |
| min_samples = random() % (max_samples) + 1; |
| combine_ratio = TST_GetRandomDouble(0.0, 1.0); |
| |
| filter = SPF_CreateInstance(min_samples, max_samples, 2.0, combine_ratio); |
| |
| for (j = 0, sum_count = 0, sum_err = 0.0; j < 100; j++) { |
| DEBUG_LOG("iteration %d/%d", i, j); |
| |
| mean = TST_GetRandomDouble(-1.0e3, 1.0e3); |
| UTI_ZeroTimespec(&sample_in.time); |
| |
| for (k = 0; k < 100; k++) { |
| UTI_AddDoubleToTimespec(&sample_in.time, TST_GetRandomDouble(1.0e-1, 1.0e2), |
| &sample_in.time); |
| sample_in.offset = mean + TST_GetRandomDouble(-1.0, 1.0); |
| sample_in.peer_dispersion = TST_GetRandomDouble(1.0e-4, 2.0e-4); |
| sample_in.root_dispersion = TST_GetRandomDouble(1.0e-3, 2.0e-3); |
| sample_in.peer_delay = TST_GetRandomDouble(1.0e-2, 2.0e-2); |
| sample_in.root_delay = TST_GetRandomDouble(1.0e-1, 2.0e-1); |
| |
| TEST_CHECK(SPF_AccumulateSample(filter, &sample_in)); |
| TEST_CHECK(!SPF_AccumulateSample(filter, &sample_in)); |
| |
| TEST_CHECK(SPF_GetNumberOfSamples(filter) == MIN(k + 1, max_samples)); |
| |
| SPF_GetLastSample(filter, &sample_out); |
| TEST_CHECK(!memcmp(&sample_in, &sample_out, sizeof (sample_in))); |
| |
| SPF_SlewSamples(filter, &sample_in.time, 0.0, 0.0); |
| SPF_AddDispersion(filter, 0.0); |
| |
| if (k + 1 < min_samples) |
| TEST_CHECK(!SPF_GetFilteredSample(filter, &sample_out)); |
| |
| TEST_CHECK(SPF_GetNumberOfSamples(filter) == MIN(k + 1, max_samples)); |
| } |
| |
| if (random() % 10) { |
| TEST_CHECK(SPF_GetFilteredSample(filter, &sample_out)); |
| |
| TEST_CHECK(SPF_GetAvgSampleDispersion(filter) <= 2.0); |
| |
| sum_err += sample_out.offset - mean; |
| sum_count++; |
| |
| TEST_CHECK(UTI_CompareTimespecs(&sample_out.time, &sample_in.time) <= 0 && |
| sample_out.time.tv_sec >= 0); |
| TEST_CHECK(fabs(sample_out.offset - mean) <= 1.0); |
| TEST_CHECK(sample_out.peer_dispersion >= 1.0e-4 && |
| (sample_out.peer_dispersion <= 2.0e-4 || filter->max_samples > 1)); |
| TEST_CHECK(sample_out.root_dispersion >= 1.0e-3 && |
| (sample_out.root_dispersion <= 2.0e-3 || filter->max_samples > 1)); |
| TEST_CHECK(sample_out.peer_delay >= 1.0e-2 && |
| sample_out.peer_delay <= 2.0e-2); |
| TEST_CHECK(sample_out.root_delay >= 1.0e-1 && |
| sample_out.root_delay <= 2.0e-1); |
| |
| if (max_samples == 1) |
| TEST_CHECK(!memcmp(&sample_in, &sample_out, sizeof (sample_in))); |
| |
| } else { |
| SPF_DropSamples(filter); |
| } |
| |
| TEST_CHECK(SPF_GetNumberOfSamples(filter) == 0); |
| } |
| |
| TEST_CHECK(fabs(sum_err / sum_count) < 0.3); |
| |
| SPF_DestroyInstance(filter); |
| } |
| |
| LCL_Finalise(); |
| } |