]> sigrok.org Git - pulseview.git/blob - test/logicdatasnapshot.cpp
66232cd6975be057bb6f9fa3d1cf7b4e027da037
[pulseview.git] / test / logicdatasnapshot.cpp
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #define __STDC_LIMIT_MACROS
22 #include <stdint.h>
23
24 #include <boost/test/unit_test.hpp>
25
26 #include "../logicdatasnapshot.h"
27
28 using namespace std;
29
30 BOOST_AUTO_TEST_SUITE(LogicDataSnapshotTest)
31
32 void push_logic(LogicDataSnapshot &s, unsigned int length, uint8_t value)
33 {
34         sr_datafeed_logic logic;
35         logic.unitsize = 1;
36         logic.length = length;
37         logic.data = new uint8_t[length];
38         memset(logic.data, value, length * logic.unitsize);
39         s.append_payload(logic);
40         delete[] (uint8_t*)logic.data;
41 }
42
43 BOOST_AUTO_TEST_CASE(Pow2)
44 {
45         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(-2, 0), -2);
46         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(-1, 0), -1);
47         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(0, 0), 0);
48         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(1, 0), 1);
49         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(2, 0), 2);
50
51         BOOST_CHECK_EQUAL(
52                 LogicDataSnapshot::pow2_ceil(INT64_MIN, 0), INT64_MIN);
53         BOOST_CHECK_EQUAL(
54                 LogicDataSnapshot::pow2_ceil(INT64_MAX, 0), INT64_MAX);
55
56         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(-3, 1), -2);
57         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(-2, 1), -2);
58         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(-1, 1), 0);
59         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(0, 1), 0);
60         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(1, 1), 2);
61         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(2, 1), 2);
62         BOOST_CHECK_EQUAL(LogicDataSnapshot::pow2_ceil(3, 1), 4);
63 }
64
65 BOOST_AUTO_TEST_CASE(Basic)
66 {
67         // Create an empty LogicDataSnapshot object
68         sr_datafeed_logic logic;
69         logic.length = 0;
70         logic.unitsize = 1;
71         logic.data = NULL;
72
73         LogicDataSnapshot s(logic);
74
75         //----- Test LogicDataSnapshot::push_logic -----//
76
77         BOOST_CHECK(s.get_sample_count() == 0);
78         for(int i = 0; i < LogicDataSnapshot::ScaleStepCount; i++)
79         {
80                 const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
81                 BOOST_CHECK_EQUAL(m.length, 0);
82                 BOOST_CHECK_EQUAL(m.data_length, 0);
83                 BOOST_CHECK(m.data == NULL);
84         }
85
86         // Push 8 samples of all zeros
87         push_logic(s, 8, 0);
88
89         BOOST_CHECK(s.get_sample_count() == 8);
90
91         // There should not be enough samples to have a single mip map sample
92         for(int i = 0; i < LogicDataSnapshot::ScaleStepCount; i++)
93         {
94                 const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
95                 BOOST_CHECK_EQUAL(m.length, 0);
96                 BOOST_CHECK_EQUAL(m.data_length, 0);
97                 BOOST_CHECK(m.data == NULL);
98         }
99
100         // Push 8 samples of 0x11s to bring the total up to 16
101         push_logic(s, 8, 0x11);
102
103         // There should now be enough data for exactly one sample
104         // in mip map level 0, and that sample should be 0
105         const LogicDataSnapshot::MipMapLevel &m0 = s._mip_map[0];
106         BOOST_CHECK_EQUAL(m0.length, 1);
107         BOOST_CHECK_EQUAL(m0.data_length, LogicDataSnapshot::MipMapDataUnit);
108         BOOST_REQUIRE(m0.data != NULL);
109         BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[0], 0x11);
110
111         // The higher levels should still be empty
112         for(int i = 1; i < LogicDataSnapshot::ScaleStepCount; i++)
113         {
114                 const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
115                 BOOST_CHECK_EQUAL(m.length, 0);
116                 BOOST_CHECK_EQUAL(m.data_length, 0);
117                 BOOST_CHECK(m.data == NULL);
118         }
119
120         // Push 240 samples of all zeros to bring the total up to 256
121         push_logic(s, 240, 0);
122
123         BOOST_CHECK_EQUAL(m0.length, 16);
124         BOOST_CHECK_EQUAL(m0.data_length, LogicDataSnapshot::MipMapDataUnit);
125
126         BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[1], 0x11);
127         for(int i = 2; i < m0.length; i++)
128                 BOOST_CHECK_EQUAL(((uint8_t*)m0.data)[i], 0);
129
130         const LogicDataSnapshot::MipMapLevel &m1 = s._mip_map[1];
131         BOOST_CHECK_EQUAL(m1.length, 1);
132         BOOST_CHECK_EQUAL(m1.data_length, LogicDataSnapshot::MipMapDataUnit);
133         BOOST_REQUIRE(m1.data != NULL);
134         BOOST_CHECK_EQUAL(((uint8_t*)m1.data)[0], 0x11);
135
136         //----- Test LogicDataSnapshot::get_subsampled_edges -----//
137
138         // Test a full view at full zoom.
139         vector<LogicDataSnapshot::EdgePair> edges;
140         s.get_subsampled_edges(edges, 0, 255, 1, 0);
141         BOOST_REQUIRE_EQUAL(edges.size(), 4);
142
143         BOOST_CHECK_EQUAL(edges[0].first, 0);
144         BOOST_CHECK_EQUAL(edges[1].first, 8);
145         BOOST_CHECK_EQUAL(edges[2].first, 16);
146         BOOST_CHECK_EQUAL(edges[3].first, 255);
147
148         // Test a subset at high zoom
149         edges.clear();
150         s.get_subsampled_edges(edges, 6, 17, 0.05f, 0);
151         BOOST_REQUIRE_EQUAL(edges.size(), 4);
152
153         BOOST_CHECK_EQUAL(edges[0].first, 6);
154         BOOST_CHECK_EQUAL(edges[1].first, 8);
155         BOOST_CHECK_EQUAL(edges[2].first, 16);
156         BOOST_CHECK_EQUAL(edges[3].first, 17);
157 }
158
159 BOOST_AUTO_TEST_CASE(LargeData)
160 {
161         uint8_t prev_sample;
162         const int Length = 1000000;
163
164         sr_datafeed_logic logic;
165         logic.unitsize = 1;
166         logic.length = Length;
167         logic.data = new uint8_t[Length];
168         uint8_t *data = (uint8_t*)logic.data;
169
170         for(int i = 0; i < Length; i++)
171                 *data++ = (uint8_t)(i >> 8);
172
173         LogicDataSnapshot s(logic);
174         delete[] (uint8_t*)logic.data;
175
176         BOOST_CHECK(s.get_sample_count() == Length);
177
178         // Check mip map level 0
179         BOOST_CHECK_EQUAL(s._mip_map[0].length, 62500);
180         BOOST_CHECK_EQUAL(s._mip_map[0].data_length,
181                 LogicDataSnapshot::MipMapDataUnit);
182         BOOST_REQUIRE(s._mip_map[0].data != NULL);
183
184         prev_sample = 0;
185         for(int i = 0; i < s._mip_map[0].length;)
186         {
187                 BOOST_TEST_MESSAGE("Testing mip_map[0].data[" << i << "]");
188
189                 const uint8_t sample = (uint8_t)((i*16) >> 8);
190                 BOOST_CHECK_EQUAL(*((uint8_t*)s._mip_map[0].data + i++),
191                         prev_sample ^ sample);
192                 prev_sample = sample;
193
194                 for(int j = 1; i < s._mip_map[0].length && j < 16; j++)
195                 {
196                         BOOST_TEST_MESSAGE("Testing mip_map[0].data[" << i << "]");
197                         BOOST_CHECK_EQUAL(*((uint8_t*)s._mip_map[0].data + i++), 0);
198                 }
199         }
200
201         // Check mip map level 1
202         BOOST_CHECK_EQUAL(s._mip_map[1].length, 3906);
203         BOOST_CHECK_EQUAL(s._mip_map[1].data_length,
204                 LogicDataSnapshot::MipMapDataUnit);
205         BOOST_REQUIRE(s._mip_map[1].data != NULL);
206
207         prev_sample = 0;
208         for(int i = 0; i < s._mip_map[1].length; i++)
209         {
210                 BOOST_TEST_MESSAGE("Testing mip_map[1].data[" << i << "]");
211
212                 const uint8_t sample = i;
213                 const uint8_t expected = sample ^ prev_sample;
214                 prev_sample = i;
215
216                 BOOST_CHECK_EQUAL(*((uint8_t*)s._mip_map[1].data + i),
217                         expected);
218         }
219
220         // Check mip map level 2
221         BOOST_CHECK_EQUAL(s._mip_map[2].length, 244);
222         BOOST_CHECK_EQUAL(s._mip_map[2].data_length,
223                 LogicDataSnapshot::MipMapDataUnit);
224         BOOST_REQUIRE(s._mip_map[2].data != NULL);
225
226         prev_sample = 0;
227         for(int i = 0; i < s._mip_map[2].length; i++)
228         {
229                 BOOST_TEST_MESSAGE("Testing mip_map[2].data[" << i << "]");
230
231                 const uint8_t sample = i << 4;
232                 const uint8_t expected = (sample ^ prev_sample) | 0x0F;
233                 prev_sample = sample;
234
235                 BOOST_CHECK_EQUAL(*((uint8_t*)s._mip_map[2].data + i),
236                         expected);
237         }
238
239         // Check mip map level 3
240         BOOST_CHECK_EQUAL(s._mip_map[3].length, 15);
241         BOOST_CHECK_EQUAL(s._mip_map[3].data_length,
242                 LogicDataSnapshot::MipMapDataUnit);
243         BOOST_REQUIRE(s._mip_map[3].data != NULL);
244
245         for(int i = 0; i < s._mip_map[3].length; i++)
246                 BOOST_CHECK_EQUAL(*((uint8_t*)s._mip_map[3].data + i),
247                         0xFF);
248
249         // Check the higher levels
250         for(int i = 4; i < LogicDataSnapshot::ScaleStepCount; i++)
251         {
252                 const LogicDataSnapshot::MipMapLevel &m = s._mip_map[i];
253                 BOOST_CHECK_EQUAL(m.length, 0);
254                 BOOST_CHECK_EQUAL(m.data_length, 0);
255                 BOOST_CHECK(m.data == NULL);
256         }
257
258         //----- Test LogicDataSnapshot::get_subsampled_edges -----//
259         vector<LogicDataSnapshot::EdgePair> edges;
260
261         s.get_subsampled_edges(edges, 0, Length-1, 1, 7);
262         BOOST_REQUIRE_EQUAL(edges.size(), 32);
263
264         for(int i = 0; i < 31; i++)
265         {
266                 BOOST_REQUIRE_EQUAL(edges[i].first, i * 32768);
267                 BOOST_REQUIRE_EQUAL(edges[i].second, i & 1);
268         }
269
270         BOOST_REQUIRE_EQUAL(edges[31].first, 999999);
271 }
272
273 BOOST_AUTO_TEST_SUITE_END()