blob: c124ea29af8e875bd0908953876c8fbc0cace230 [file] [log] [blame]
Jan Tattermuschf6410f52015-07-22 16:21:57 -07001#region Copyright notice and license
2
3// Copyright 2015, Google Inc.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32#endregion
33
34using System;
35using System.Runtime.InteropServices;
36using Grpc.Core.Internal;
Jan Tattermusch452ca9b2015-10-29 10:38:03 -070037using Grpc.Core.Utils;
Jan Tattermuschf6410f52015-07-22 16:21:57 -070038using NUnit.Framework;
39
40namespace Grpc.Core.Internal.Tests
41{
42 public class TimespecTest
43 {
44 [Test]
Jan Tattermusch4113ba52015-07-22 18:37:35 -070045 public void Now_IsInUtc()
46 {
47 Assert.AreEqual(DateTimeKind.Utc, Timespec.Now.ToDateTime().Kind);
48 }
49
50 [Test]
51 public void Now_AgreesWithUtcNow()
Jan Tattermuschf6410f52015-07-22 16:21:57 -070052 {
53 var timespec = Timespec.Now;
Jan Tattermusch4113ba52015-07-22 18:37:35 -070054 var utcNow = DateTime.UtcNow;
55
56 TimeSpan difference = utcNow - timespec.ToDateTime();
57
58 // This test is inherently a race - but the two timestamps
59 // should really be way less that a minute apart.
60 Assert.IsTrue(difference.TotalSeconds < 60);
Jan Tattermuschf6410f52015-07-22 16:21:57 -070061 }
62
63 [Test]
Jan Tattermuscha7db28f2016-05-18 12:26:16 -070064 public void InfFutureMatchesNativeValue()
Jan Tattermuschf6410f52015-07-22 16:21:57 -070065 {
Jan Tattermuscha7db28f2016-05-18 12:26:16 -070066 Assert.AreEqual(Timespec.NativeInfFuture, Timespec.InfFuture);
Jan Tattermuschf6410f52015-07-22 16:21:57 -070067 }
68
69 [Test]
Jan Tattermuscha7db28f2016-05-18 12:26:16 -070070 public void InfPastMatchesNativeValue()
Jan Tattermuschf6410f52015-07-22 16:21:57 -070071 {
Jan Tattermuscha7db28f2016-05-18 12:26:16 -070072 Assert.AreEqual(Timespec.NativeInfPast, Timespec.InfPast);
Jan Tattermuschf6410f52015-07-22 16:21:57 -070073 }
74
75 [Test]
76 public void TimespecSizeIsNativeSize()
77 {
78 Assert.AreEqual(Timespec.NativeSize, Marshal.SizeOf(typeof(Timespec)));
79 }
80
81 [Test]
82 public void ToDateTime()
83 {
84 Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
Jan Tattermusch88086372015-12-10 10:54:12 -080085 new Timespec(0, 0).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -070086
87 Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50),
Jan Tattermusch88086372015-12-10 10:54:12 -080088 new Timespec(10, 5000).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -070089
90 Assert.AreEqual(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc),
Jan Tattermusch88086372015-12-10 10:54:12 -080091 new Timespec(1437452508, 0).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -070092
93 // before epoch
94 Assert.AreEqual(new DateTime(1969, 12, 31, 23, 59, 55, DateTimeKind.Utc).AddTicks(10),
Jan Tattermusch88086372015-12-10 10:54:12 -080095 new Timespec(-5, 1000).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -070096
Jan Tattermusch50b83652015-07-23 13:37:46 -070097 // infinity
98 Assert.AreEqual(DateTime.MaxValue, Timespec.InfFuture.ToDateTime());
99 Assert.AreEqual(DateTime.MinValue, Timespec.InfPast.ToDateTime());
100
101 // nanos are rounded to ticks are rounded up
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700102 Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(1),
Jan Tattermusch88086372015-12-10 10:54:12 -0800103 new Timespec(0, 99).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700104
Jan Tattermusch50b83652015-07-23 13:37:46 -0700105 // Illegal inputs
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700106 Assert.Throws(typeof(InvalidOperationException),
Jan Tattermusch88086372015-12-10 10:54:12 -0800107 () => new Timespec(0, -2).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700108 Assert.Throws(typeof(InvalidOperationException),
Jan Tattermusch88086372015-12-10 10:54:12 -0800109 () => new Timespec(0, 1000 * 1000 * 1000).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700110 Assert.Throws(typeof(InvalidOperationException),
Jan Tattermusche0af2862016-05-18 21:02:03 -0700111 () => new Timespec(0, 0, ClockType.Monotonic).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700112 }
113
114 [Test]
115 public void ToDateTime_ReturnsUtc()
116 {
Jan Tattermusch88086372015-12-10 10:54:12 -0800117 Assert.AreEqual(DateTimeKind.Utc, new Timespec(1437452508, 0).ToDateTime().Kind);
118 Assert.AreNotEqual(DateTimeKind.Unspecified, new Timespec(1437452508, 0).ToDateTime().Kind);
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700119 }
120
121 [Test]
Jan Tattermusch50b83652015-07-23 13:37:46 -0700122 public void ToDateTime_Overflow()
Jan Tattermusch88086372015-12-10 10:54:12 -0800123 {
124 var timespec = new Timespec(long.MaxValue - 100, 0);
125 Assert.AreNotEqual(Timespec.InfFuture, timespec);
126 Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700127
Jan Tattermusch88086372015-12-10 10:54:12 -0800128 Assert.AreEqual(DateTime.MinValue, new Timespec(long.MinValue + 100, 0).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700129 }
130
131 [Test]
Jan Tattermusch50b83652015-07-23 13:37:46 -0700132 public void ToDateTime_OutOfDateTimeRange()
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700133 {
Jan Tattermusch88086372015-12-10 10:54:12 -0800134 // DateTime range goes up to year 9999, 20000 years from now should
135 // be out of range.
136 long seconds = 20000L * 365L * 24L * 3600L;
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700137
Jan Tattermusch88086372015-12-10 10:54:12 -0800138 var timespec = new Timespec(seconds, 0);
139 Assert.AreNotEqual(Timespec.InfFuture, timespec);
140 Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700141
Jan Tattermusch88086372015-12-10 10:54:12 -0800142 Assert.AreEqual(DateTime.MinValue, new Timespec(-seconds, 0).ToDateTime());
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700143 }
Jan Tattermusch50b83652015-07-23 13:37:46 -0700144
145 [Test]
146 public void FromDateTime()
147 {
Jan Tattermusch88086372015-12-10 10:54:12 -0800148 Assert.AreEqual(new Timespec(0, 0),
Jan Tattermusch50b83652015-07-23 13:37:46 -0700149 Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
150
Jan Tattermusch88086372015-12-10 10:54:12 -0800151 Assert.AreEqual(new Timespec(10, 5000),
Jan Tattermusch50b83652015-07-23 13:37:46 -0700152 Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50)));
153
Jan Tattermusch88086372015-12-10 10:54:12 -0800154 Assert.AreEqual(new Timespec(1437452508, 0),
Jan Tattermusch50b83652015-07-23 13:37:46 -0700155 Timespec.FromDateTime(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc)));
156
157 // before epoch
Jan Tattermusch88086372015-12-10 10:54:12 -0800158 Assert.AreEqual(new Timespec(-5, 1000),
Jan Tattermusch50b83652015-07-23 13:37:46 -0700159 Timespec.FromDateTime(new DateTime(1969, 12, 31, 23, 59, 55, DateTimeKind.Utc).AddTicks(10)));
160
161 // infinity
162 Assert.AreEqual(Timespec.InfFuture, Timespec.FromDateTime(DateTime.MaxValue));
163 Assert.AreEqual(Timespec.InfPast, Timespec.FromDateTime(DateTime.MinValue));
164
165 // illegal inputs
166 Assert.Throws(typeof(ArgumentException),
167 () => Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified)));
168 }
Jan Tattermusch452ca9b2015-10-29 10:38:03 -0700169
Jan Tattermusch3ac274f2015-12-11 15:27:58 -0800170 [Test]
171 [Category("Performance")]
172 [Ignore("Prevent running on Jenkins")]
Jan Tattermusch452ca9b2015-10-29 10:38:03 -0700173 public void NowBenchmark()
174 {
175 // approx Timespec.Now latency <33ns
176 BenchmarkUtil.RunBenchmark(10000000, 1000000000, () => { var now = Timespec.Now; });
177 }
Jan Tattermusch3ac274f2015-12-11 15:27:58 -0800178
179 [Test]
180 [Category("Performance")]
181 [Ignore("Prevent running on Jenkins")]
Jan Tattermusch452ca9b2015-10-29 10:38:03 -0700182 public void PreciseNowBenchmark()
183 {
184 // approx Timespec.PreciseNow latency <18ns (when compiled with GRPC_TIMERS_RDTSC)
185 BenchmarkUtil.RunBenchmark(10000000, 1000000000, () => { var now = Timespec.PreciseNow; });
186 }
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700187 }
188}