• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright 2022 The Pigweed Authors
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may not
5# use this file except in compliance with the License. You may obtain a copy of
6# the License at
7#
8#     https://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations under
14# the License.
15"""Tests for the timestamp analyzer."""
16
17import unittest
18from pw_chrono.timestamp_analyzer import process_snapshot
19from pw_chrono_protos import chrono_pb2
20from pw_tokenizer import detokenize, tokens
21
22
23class TimestampTest(unittest.TestCase):
24    """Test for the timestamp analyzer."""
25
26    def test_no_timepoint(self):
27        snapshot = chrono_pb2.SnapshotTimestamps()
28        self.assertEqual(
29            '', str(process_snapshot(snapshot.SerializeToString()))
30        )
31
32    def test_timestamp_unknown_epoch_type(self):
33        snapshot = chrono_pb2.SnapshotTimestamps()
34
35        time_point = chrono_pb2.TimePoint(
36            timestamp=0,
37            clock_parameters=chrono_pb2.ClockParameters(
38                tick_period_seconds_numerator=1,
39                tick_period_seconds_denominator=1,
40                epoch_type=chrono_pb2.EpochType.Enum.UNKNOWN,
41            ),
42        )
43        snapshot.timestamps.append(time_point)
44
45        expected = '\n'.join(
46            (
47                'Snapshot capture timestamp',
48                '  Timestamp (epoch UNKNOWN): 0 s',
49                '',
50            )
51        )
52
53        self.assertEqual(
54            expected, str(process_snapshot(snapshot.SerializeToString()))
55        )
56
57    def test_timestamp_with_time_since_boot(self):
58        snapshot = chrono_pb2.SnapshotTimestamps()
59
60        time_point = chrono_pb2.TimePoint(
61            timestamp=8640015,
62            clock_parameters=chrono_pb2.ClockParameters(
63                tick_period_seconds_numerator=1,
64                tick_period_seconds_denominator=1000,
65                epoch_type=chrono_pb2.EpochType.Enum.TIME_SINCE_BOOT,
66            ),
67        )
68        snapshot.timestamps.append(time_point)
69
70        expected = '\n'.join(
71            (
72                'Snapshot capture timestamp',
73                '  Time since boot: 2:24:00.015000 (8640015 ms)',
74                '',
75            )
76        )
77
78        self.assertEqual(
79            expected, str(process_snapshot(snapshot.SerializeToString()))
80        )
81
82    def test_timestamp_with_utc_wall_clock(self):
83        snapshot = chrono_pb2.SnapshotTimestamps()
84
85        time_point = chrono_pb2.TimePoint(
86            timestamp=8640015,
87            clock_parameters=chrono_pb2.ClockParameters(
88                tick_period_seconds_numerator=1,
89                tick_period_seconds_denominator=1000,
90                epoch_type=chrono_pb2.EpochType.Enum.UTC_WALL_CLOCK,
91            ),
92        )
93        snapshot.timestamps.append(time_point)
94
95        expected = '\n'.join(
96            (
97                'Snapshot capture timestamp',
98                '  UTC time: 1970-01-01 02:24:00.015000+00:00 (8640015 ms)',
99                '',
100            )
101        )
102
103        self.assertEqual(
104            expected, str(process_snapshot(snapshot.SerializeToString()))
105        )
106
107    def test_timestamp_with_name(self):
108        snapshot = chrono_pb2.SnapshotTimestamps()
109
110        time_point = chrono_pb2.TimePoint(
111            timestamp=51140716,
112            clock_parameters=chrono_pb2.ClockParameters(
113                tick_period_seconds_numerator=1,
114                tick_period_seconds_denominator=1000000,
115                epoch_type=chrono_pb2.EpochType.Enum.UNKNOWN,
116                name='High resolution clock'.encode('utf-8'),
117            ),
118        )
119        snapshot.timestamps.append(time_point)
120
121        expected = '\n'.join(
122            (
123                'Snapshot capture timestamp',
124                '  High resolution clock (epoch UNKNOWN): 51140716 us',
125                '',
126            )
127        )
128
129        self.assertEqual(
130            expected, str(process_snapshot(snapshot.SerializeToString()))
131        )
132
133    def test_timestamp_with_tokenized_name(self):
134        token_db = tokens.Database(
135            [
136                tokens.TokenizedStringEntry(1, 'Peer device clock'),
137            ]
138        )
139        detokenizer = detokenize.Detokenizer(token_db)
140
141        snapshot = chrono_pb2.SnapshotTimestamps()
142
143        time_point = chrono_pb2.TimePoint(
144            timestamp=51140716,
145            clock_parameters=chrono_pb2.ClockParameters(
146                tick_period_seconds_numerator=1,
147                tick_period_seconds_denominator=1000000,
148                epoch_type=chrono_pb2.EpochType.Enum.UNKNOWN,
149                name=b'\x01\x00\x00\x00',
150            ),
151        )
152        snapshot.timestamps.append(time_point)
153
154        expected = '\n'.join(
155            (
156                'Snapshot capture timestamp',
157                '  Peer device clock (epoch UNKNOWN): 51140716 us',
158                '',
159            )
160        )
161
162        self.assertEqual(
163            expected,
164            str(process_snapshot(snapshot.SerializeToString(), detokenizer)),
165        )
166
167    def test_timestamp_with_tai_clock(self):
168        snapshot = chrono_pb2.SnapshotTimestamps()
169
170        time_point = chrono_pb2.TimePoint(
171            timestamp=1733882018,
172            clock_parameters=chrono_pb2.ClockParameters(
173                tick_period_seconds_numerator=1,
174                tick_period_seconds_denominator=1000,
175                epoch_type=chrono_pb2.EpochType.Enum.TAI_WALL_CLOCK,
176            ),
177        )
178        snapshot.timestamps.append(time_point)
179
180        expected = '\n'.join(
181            (
182                'Snapshot capture timestamp',
183                '  Timestamp (epoch TAI_WALL_CLOCK): 1733882018 ms',
184                '',
185            )
186        )
187
188        self.assertEqual(
189            expected, str(process_snapshot(snapshot.SerializeToString()))
190        )
191
192    def test_timestamp_with_unrecognized_epoch(self):
193        snapshot = chrono_pb2.SnapshotTimestamps()
194
195        time_point = chrono_pb2.TimePoint(
196            timestamp=3424,
197            clock_parameters=chrono_pb2.ClockParameters(
198                tick_period_seconds_numerator=1,
199                tick_period_seconds_denominator=1,
200                epoch_type=chrono_pb2.EpochType.Enum.ValueType(15),
201            ),
202        )
203        snapshot.timestamps.append(time_point)
204
205        expected = '\n'.join(
206            (
207                'Snapshot capture timestamp',
208                '  Timestamp (epoch 15): 3424 s',
209                '',
210            )
211        )
212
213        self.assertEqual(
214            expected, str(process_snapshot(snapshot.SerializeToString()))
215        )
216
217    def test_invalid_timestamp(self):
218        snapshot = chrono_pb2.SnapshotTimestamps()
219
220        time_point = chrono_pb2.TimePoint(
221            timestamp=1,
222            clock_parameters=chrono_pb2.ClockParameters(
223                tick_period_seconds_numerator=1,
224                tick_period_seconds_denominator=0,
225            ),
226        )
227        snapshot.timestamps.append(time_point)
228
229        expected = ''
230
231        self.assertEqual(
232            expected, str(process_snapshot(snapshot.SerializeToString()))
233        )
234
235    def test_no_timestamp(self):
236        snapshot = chrono_pb2.SnapshotTimestamps()
237
238        expected = ''
239
240        self.assertEqual(
241            expected, str(process_snapshot(snapshot.SerializeToString()))
242        )
243
244    def test_timestamp_with_time_since_boot_and_utc_wall_clock(self):
245        """Test multiple timestamps."""
246        snapshot = chrono_pb2.SnapshotTimestamps()
247
248        time_point = chrono_pb2.TimePoint(
249            timestamp=8640000,
250            clock_parameters=chrono_pb2.ClockParameters(
251                tick_period_seconds_numerator=1,
252                tick_period_seconds_denominator=1000,
253                epoch_type=chrono_pb2.EpochType.Enum.TIME_SINCE_BOOT,
254            ),
255        )
256        snapshot.timestamps.append(time_point)
257
258        time_point = chrono_pb2.TimePoint(
259            timestamp=8640000,
260            clock_parameters=chrono_pb2.ClockParameters(
261                tick_period_seconds_numerator=1,
262                tick_period_seconds_denominator=1000,
263                epoch_type=chrono_pb2.EpochType.Enum.UTC_WALL_CLOCK,
264            ),
265        )
266        snapshot.timestamps.append(time_point)
267
268        expected = '\n'.join(
269            (
270                'Snapshot capture timestamps',
271                '  Time since boot: 2:24:00 (8640000 ms)',
272                '  UTC time: 1970-01-01 02:24:00+00:00 (8640000 ms)',
273                '',
274            )
275        )
276
277        self.assertEqual(
278            expected, str(process_snapshot(snapshot.SerializeToString()))
279        )
280
281
282if __name__ == '__main__':
283    unittest.main()
284