You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CTimeTest.hpp 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. ///-------------------------------------------------------------------------------------------------
  2. ///
  3. /// \file CMatrixTest.hpp
  4. /// \brief Test Definitions for OpenViBE Matrix Class.
  5. /// \author Thibaut Monseigne (Inria).
  6. /// \version 1.0.
  7. /// \date 11/05/2020.
  8. /// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
  9. ///
  10. ///-------------------------------------------------------------------------------------------------
  11. #pragma once
  12. #include <gtest/gtest.h>
  13. #include <openvibe/CTime.hpp>
  14. #include <cmath>
  15. #include <vector>
  16. #include "utils.hpp"
  17. //---------------------------------------------------------------------------------------------------
  18. namespace Dataset {
  19. const double HOUR = 60 * 60;
  20. const double DAY = 24 * HOUR;
  21. const double WEEK = 7 * DAY;
  22. const double MONTH = 30 * DAY;
  23. const double YEAR = 365 * DAY;
  24. /// <summary> time values to test in seconds </summary>
  25. const std::vector<double> SECONDS =
  26. {
  27. 0, 0.001, 0.01, 0.1, 0.2, 0.25, 0.5, 1.0, 1.1, 1.5, 2,
  28. 1.000001, 1.999, 1.999999,
  29. 5, 10, 50, 100, 123.456789, 128.0, 500, 1000, 2500, 5000,
  30. DAY, DAY + 0.03, DAY + 0.999, DAY + 1,
  31. WEEK, WEEK + 0.03, WEEK + 0.999, WEEK + 1,
  32. MONTH, MONTH + 0.03, MONTH + 0.999, MONTH + 1,
  33. YEAR, YEAR + 0.03, YEAR + 0.999, YEAR + 1,
  34. };
  35. /// <summary> Time values to test in fixed point format. </summary>
  36. const std::vector<uint64_t> FIXED_POINT =
  37. {
  38. 1LL << 8, 1LL << 16, 1L << 19, 1LL << 22, 1LL << 27, 1L << 30, 1LL << 32, 10LL << 32, 100LL << 32, 123LL << 32, 500LL << 32, 512LL << 32, 1000LL << 32,
  39. 1024LL << 32, 2001LL << 32, 5000LL << 32
  40. };
  41. /// <summary> Sampling rates to test. </summary>
  42. const std::vector<size_t> SAMPLINGS = { 100, 128, 512, 1000, 1024, 16000, 44100 };
  43. /// <summary> Samples to test. </summary>
  44. const std::vector<uint64_t> SAMPLES = { 0, 1, 100, 128, 512, 1000, 1021, 1024, 5005, 12345, 59876, 100000, 717893, 1000001 };
  45. /// <summary> Epoch durations to test. </summary>
  46. const std::vector<double> DURATIONS = { 0.01, 0.1, 0.2, 0.25, 0.5, 1.0, 1.1, 1.5, 2, 5, 10, 50, 100 };
  47. /// <summary> We select 10-9 tolerance for seconds, being the best precision capacity of the CTime class. </summary>
  48. const double TOLERANCE = 10e-9;
  49. } // namespace Dataset
  50. //---------------------------------------------------------------------------------------------------
  51. //---------------------------------------------------------------------------------------------------
  52. TEST(CTime_Tests, constructor_time)
  53. {
  54. for (auto ref : Dataset::FIXED_POINT)
  55. {
  56. const OpenViBE::CTime res(ref);
  57. EXPECT_EQ(res.time(), ref) << ErrorMsg("Constructor with time", ref, res.time());
  58. }
  59. }
  60. //---------------------------------------------------------------------------------------------------
  61. //---------------------------------------------------------------------------------------------------
  62. TEST(CTime_Tests, constructor_seconds)
  63. {
  64. // test construction & conversion second -> fixed point -> second
  65. for (auto ref : Dataset::SECONDS)
  66. {
  67. const auto res = OpenViBE::CTime(ref).toSeconds();
  68. EXPECT_LT(std::abs(res - ref), Dataset::TOLERANCE) << ErrorMsg("Constructor with seconds and conversion to seconds", ref, res);
  69. }
  70. }
  71. //---------------------------------------------------------------------------------------------------
  72. //---------------------------------------------------------------------------------------------------
  73. TEST(CTime_Tests, constructor_sampling)
  74. {
  75. // test construction & conversion sample -> time -> sample
  76. for (auto sampling : Dataset::SAMPLINGS)
  77. {
  78. for (auto ref : Dataset::SAMPLES)
  79. {
  80. const auto res = OpenViBE::CTime(sampling, ref).toSampleCount(sampling);
  81. EXPECT_EQ(ref, res) << ErrorMsg("Constructor with sampling and sample count and conversion to sample count", ref, res);
  82. }
  83. }
  84. EXPECT_TRUE(OpenViBE::CTime(0, 1) == OpenViBE::CTime::max()) << ErrorMsg("Special Case if sampling = 0",
  85. OpenViBE::CTime::max(), OpenViBE::CTime(0, 1));
  86. }
  87. //---------------------------------------------------------------------------------------------------
  88. //---------------------------------------------------------------------------------------------------
  89. TEST(CTime_Tests, ceil)
  90. {
  91. // Ceil Test
  92. const OpenViBE::CTime t0 = OpenViBE::CTime().min().ceil();
  93. const OpenViBE::CTime t1 = OpenViBE::CTime().max().ceil();
  94. const OpenViBE::CTime t2 = OpenViBE::CTime(0xFEDCBA9876543210).ceil();
  95. const OpenViBE::CTime t3 = OpenViBE::CTime(0xFEDCBA9900000000);
  96. EXPECT_TRUE(t0 == t0) << ErrorMsg("ceil of Time Min (0)", t0, t0);
  97. EXPECT_TRUE(t1 == t0) << ErrorMsg("ceil of Time Max (0xFFFFFFFFFFFFFFFF)", t0, t1);
  98. EXPECT_TRUE(t2 == t3) << ErrorMsg("ceil of Time (0xFEDCBA9876543210)", t3, t2);
  99. }
  100. //---------------------------------------------------------------------------------------------------
  101. //---------------------------------------------------------------------------------------------------
  102. TEST(CTime_Tests, operators)
  103. {
  104. // Operators Tests
  105. const OpenViBE::CTime t0 = OpenViBE::CTime(1.0) + OpenViBE::CTime(1.0);
  106. const OpenViBE::CTime t1 = OpenViBE::CTime(4.0) - OpenViBE::CTime(1.0);
  107. const OpenViBE::CTime t2 = OpenViBE::CTime(1.0) - OpenViBE::CTime(4.0);
  108. const OpenViBE::CTime r0 = OpenViBE::CTime(2.0);
  109. const OpenViBE::CTime r1 = OpenViBE::CTime(3.0);
  110. // we remove 2 second from the max
  111. // - We have -3 as result, with uint max = -1 so result is max - 2
  112. // and max seconds = 2^32 - 1 (0xFFFFFFFF) so result is max - 2 : 0xFFFFFFFD so in Fixed Point 0xFFFFFFFD00000000)
  113. const OpenViBE::CTime r2 = OpenViBE::CTime(0xFFFFFFFD00000000);
  114. // Comparison
  115. EXPECT_TRUE(r0 == r0) << ErrorMsg("ref == calc", t0, t0);
  116. EXPECT_FALSE(r0 != r0) << ErrorMsg("!(ref != calc)", t1, t1);
  117. EXPECT_TRUE(r0 < r1) << ErrorMsg("(ref < calc)", r0, r1);
  118. EXPECT_TRUE(r0 <= r1) << ErrorMsg("(ref <= calc)", r0, r1);
  119. EXPECT_TRUE(r1 > r0) << ErrorMsg("(ref > calc)", r1, r0);
  120. EXPECT_TRUE(r1 >= r0) << ErrorMsg("(ref >= calc)", r1, r0);
  121. // Operation
  122. EXPECT_TRUE(t0 == r0) << ErrorMsg("Addition result", r0, t0);
  123. EXPECT_TRUE(t1 == r1) << ErrorMsg("Substract result", r1, t1);
  124. EXPECT_TRUE(t2 == r2) << ErrorMsg("substract with negative result", r2, t2);
  125. // Str
  126. EXPECT_EQ("1.000 sec (0x0000000100000000)", OpenViBE::CTime(1.0).str(true, true));
  127. EXPECT_EQ("1.000 sec", OpenViBE::CTime(1.0).str(true, false));
  128. EXPECT_EQ("4294967296 (0x0000000100000000)", OpenViBE::CTime(1.0).str(false, true));
  129. EXPECT_EQ("4294967296", OpenViBE::CTime(1.0).str(false, false));
  130. }
  131. //---------------------------------------------------------------------------------------------------
  132. //---------------------------------------------------------------------------------------------------
  133. TEST(CTime_Tests, conversion_chain)
  134. {
  135. // test conversion time -> sample -> time
  136. for (auto sampling : Dataset::SAMPLINGS)
  137. {
  138. for (auto seconds : Dataset::SECONDS)
  139. {
  140. auto tmp = OpenViBE::CTime(seconds).time();
  141. // If the sample count would overflow an uint64_t we skip the test
  142. if (std::log2(sampling) + std::log2(tmp) >= 64) { continue; }
  143. const uint64_t compute = OpenViBE::CTime(sampling, OpenViBE::CTime(tmp).toSampleCount(sampling)).time();
  144. const uint64_t difference = uint64_t(std::abs(int64_t(compute) - int64_t(tmp)));
  145. EXPECT_LT(OpenViBE::CTime(difference).toSeconds(), (1.0 / double(sampling)))
  146. << "Time difference too large between OV(" << seconds << ") and "
  147. << "SCtoOV(" << sampling << ", OVtoSC(" << sampling << "," << tmp << "))";
  148. }
  149. }
  150. }
  151. //---------------------------------------------------------------------------------------------------
  152. //---------------------------------------------------------------------------------------------------
  153. TEST(CTime_Tests, legacy_epoching)
  154. {
  155. // compare second -> time conversion to legacy method
  156. for (auto duration : Dataset::DURATIONS)
  157. {
  158. const auto legacy = uint64_t(duration * (1LL << 32)); // Legacy code from stimulationBasedEpoching
  159. const auto res = OpenViBE::CTime(duration).time();
  160. EXPECT_EQ(res, legacy) << ErrorMsg("Legacy Epoching for duration : " + std::to_string(duration), legacy, res);
  161. }
  162. }
  163. //---------------------------------------------------------------------------------------------------