3abe9331 |
1 | /****************************************************************************** |
d44e3c4f |
2 | * Copyright (c) 2000-2016 Ericsson Telecom AB |
3abe9331 |
3 | * All rights reserved. This program and the accompanying materials |
4 | * are made available under the terms of the Eclipse Public License v1.0 |
5 | * which accompanies this distribution, and is available at |
6 | * http://www.eclipse.org/legal/epl-v10.html |
d44e3c4f |
7 | * |
8 | * Contributors: |
9 | * Balasko, Jeno |
10 | * Baranyi, Botond |
11 | * |
3abe9331 |
12 | ******************************************************************************/ |
13 | |
14 | // Tests for encoding and decoding integers as the ETSI Common Library type "IntX" |
15 | // (defined in ETSI TS 103 097) |
16 | module IntX { |
17 | |
18 | /************* Type definitions *************/ |
19 | type integer IntX_unsigned with { variant "IntX, COMP(nosign)"; } |
20 | |
21 | type integer IntX_signed with { variant "IntX, COMP(signbit)"; } |
22 | |
23 | type integer IntX_compl with { variant "IntX, COMP(2scompl)"; } |
24 | |
25 | type record of IntX_signed IntXList with { variant ""; } |
26 | |
27 | type record RecIntX { |
28 | integer i, |
29 | integer ix, |
30 | bitstring bs |
31 | } |
32 | with { |
33 | variant "FIELDORDER(msb)"; |
34 | variant(i) "FIELDLENGTH(16), COMP(2scompl), BITORDER(msb)"; |
35 | variant(i) "BYTEORDER(first), BITORDERINFIELD(msb)"; |
36 | variant(ix) "IntX, COMP(2scompl)"; |
37 | variant(bs) "FIELDLENGTH(8)"; |
38 | } |
39 | |
40 | type record RecIntXPartial { |
41 | integer i, |
42 | integer ix, |
43 | bitstring bs |
44 | } |
45 | with { |
46 | variant "FIELDORDER(msb)"; |
47 | variant(i) "FIELDLENGTH(12), BITORDER(msb)"; |
48 | variant(i) "BYTEORDER(first), BITORDERINFIELD(msb)"; |
49 | variant(ix) "IntX"; |
50 | variant(bs) "FIELDLENGTH(8)"; |
51 | } |
52 | |
53 | type record RecIntXPadded { |
54 | integer i, |
55 | integer ix, |
56 | bitstring bs, |
57 | integer ix2 |
58 | } |
59 | with { |
60 | variant "FIELDORDER(msb), PADDING(6), PADDALL"; |
61 | variant(i) "FIELDLENGTH(16), PADDING(5), BITORDER(msb)"; |
62 | variant(i) "BYTEORDER(first), BITORDERINFIELD(msb)"; |
63 | variant(ix) "IntX, PREPADDING(6)"; |
64 | variant(bs) "FIELDLENGTH(8)"; |
65 | variant(ix2) "IntX"; |
66 | } |
67 | |
68 | type component CT {} |
69 | |
70 | /************* Coding functions *************/ |
71 | external function f_enc_intx_u(in IntX_unsigned x) return octetstring |
72 | with { extension "prototype(convert) encode(RAW)" } |
73 | |
74 | external function f_dec_intx_u(in octetstring x) return IntX_unsigned |
75 | with { extension "prototype(convert) decode(RAW)" } |
76 | |
77 | external function f_enc_intx_s(in IntX_signed x) return octetstring |
78 | with { extension "prototype(convert) encode(RAW)" } |
79 | |
80 | external function f_dec_intx_s(in octetstring x) return IntX_signed |
81 | with { extension "prototype(convert) decode(RAW)" } |
82 | |
83 | external function f_enc_intx_c(in IntX_compl x) return octetstring |
84 | with { extension "prototype(convert) encode(RAW)" } |
85 | |
86 | external function f_dec_intx_c(in octetstring x) return IntX_compl |
87 | with { extension "prototype(convert) decode(RAW)" } |
88 | |
89 | external function f_enc_intx_list(in IntXList x) return octetstring |
90 | with { extension "prototype(convert) encode(RAW)" } |
91 | |
92 | external function f_dec_intx_list(in octetstring x) return IntXList |
93 | with { extension "prototype(convert) decode(RAW)" } |
94 | |
95 | external function f_enc_intx_rec(in RecIntX x) return octetstring |
96 | with { extension "prototype(convert) encode(RAW)" } |
97 | |
98 | external function f_dec_intx_rec(in octetstring x) return RecIntX |
99 | with { extension "prototype(convert) decode(RAW)" } |
100 | |
101 | external function f_enc_intx_rec_part(in RecIntXPartial x) return octetstring |
102 | with { extension "prototype(convert) encode(RAW)" } |
103 | |
104 | external function f_dec_intx_rec_part(in octetstring x) return RecIntXPartial |
105 | with { extension "prototype(convert) decode(RAW)" } |
106 | |
107 | external function f_enc_intx_rec_padd(in RecIntXPadded x) return octetstring |
108 | with { extension "prototype(convert) encode(RAW)" } |
109 | |
110 | external function f_dec_intx_rec_padd(in octetstring x) return RecIntXPadded |
111 | with { extension "prototype(convert) decode(RAW)" } |
112 | |
113 | /************* Test cases *************/ |
114 | testcase tc_intx_unsigned() runs on CT |
115 | { |
116 | // one octet |
117 | var IntX_unsigned val := 10; |
118 | var octetstring enc_val_exp := '0A'O; |
119 | var octetstring enc_val := f_enc_intx_u(val); |
120 | if (enc_val != enc_val_exp) { |
121 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
122 | } |
123 | var IntX_unsigned dec_val := f_dec_intx_u(enc_val_exp); |
124 | if (dec_val != val) { |
125 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
126 | } |
127 | |
128 | // two octets |
129 | val := 2184; |
130 | enc_val_exp := '8888'O; |
131 | enc_val := f_enc_intx_u(val); |
132 | if (enc_val != enc_val_exp) { |
133 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
134 | } |
135 | dec_val := f_dec_intx_u(enc_val_exp); |
136 | if (dec_val != val) { |
137 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
138 | } |
139 | |
140 | // ten octets |
141 | val := 2554246324530855315; |
142 | enc_val_exp := 'FF002372817FCA823D93'O; |
143 | enc_val := f_enc_intx_u(val); |
144 | if (enc_val != enc_val_exp) { |
145 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
146 | } |
147 | dec_val := f_dec_intx_u(enc_val_exp); |
148 | if (dec_val != val) { |
149 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
150 | } |
151 | |
152 | // twelve octets |
153 | val := 7165932342958243219318534; |
154 | enc_val_exp := 'FFC5ED71F8802FC9D0112706'O; |
155 | enc_val := f_enc_intx_u(val); |
156 | if (enc_val != enc_val_exp) { |
157 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
158 | } |
159 | dec_val := f_dec_intx_u(enc_val_exp); |
160 | if (dec_val != val) { |
161 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
162 | } |
163 | |
164 | setverdict(pass); |
165 | } |
166 | |
167 | testcase tc_intx_signed() runs on CT |
168 | { |
169 | // one octet |
170 | var IntX_signed val := -10; |
171 | var octetstring enc_val_exp := '4A'O; |
172 | var octetstring enc_val := f_enc_intx_s(val); |
173 | if (enc_val != enc_val_exp) { |
174 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
175 | } |
176 | var IntX_signed dec_val := f_dec_intx_s(enc_val_exp); |
177 | if (dec_val != val) { |
178 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
179 | } |
180 | |
181 | // two octets |
182 | val := -2184; |
183 | enc_val_exp := 'A888'O; |
184 | enc_val := f_enc_intx_s(val); |
185 | if (enc_val != enc_val_exp) { |
186 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
187 | } |
188 | dec_val := f_dec_intx_s(enc_val_exp); |
189 | if (dec_val != val) { |
190 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
191 | } |
192 | |
193 | // ten octets |
194 | val := -2554246324530855315; |
195 | enc_val_exp := 'FF402372817FCA823D93'O; |
196 | enc_val := f_enc_intx_s(val); |
197 | if (enc_val != enc_val_exp) { |
198 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
199 | } |
200 | dec_val := f_dec_intx_s(enc_val_exp); |
201 | if (dec_val != val) { |
202 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
203 | } |
204 | |
205 | // twelve octets |
206 | val := -7165932342958243219318534; |
207 | enc_val_exp := 'FFD5ED71F8802FC9D0112706'O; |
208 | enc_val := f_enc_intx_s(val); |
209 | if (enc_val != enc_val_exp) { |
210 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
211 | } |
212 | dec_val := f_dec_intx_s(enc_val_exp); |
213 | if (dec_val != val) { |
214 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
215 | } |
216 | |
217 | setverdict(pass); |
218 | } |
219 | |
220 | testcase tc_intx_2scompl() runs on CT |
221 | { |
222 | // one octet |
223 | var IntX_compl val := -10; |
224 | var octetstring enc_val_exp := '76'O; |
225 | var octetstring enc_val := f_enc_intx_c(val); |
226 | if (enc_val != enc_val_exp) { |
227 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
228 | } |
229 | var IntX_compl dec_val := f_dec_intx_c(enc_val_exp); |
230 | if (dec_val != val) { |
231 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
232 | } |
233 | |
234 | // two octets |
235 | val := -2184; |
236 | enc_val_exp := 'B778'O; |
237 | enc_val := f_enc_intx_c(val); |
238 | if (enc_val != enc_val_exp) { |
239 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
240 | } |
241 | dec_val := f_dec_intx_c(enc_val_exp); |
242 | if (dec_val != val) { |
243 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
244 | } |
245 | |
246 | // ten octets |
247 | val := -2554246324530855315; |
248 | enc_val_exp := 'FF7FDC8D7E80357DC26D'O; |
249 | enc_val := f_enc_intx_c(val); |
250 | if (enc_val != enc_val_exp) { |
251 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
252 | } |
253 | dec_val := f_dec_intx_c(enc_val_exp); |
254 | if (dec_val != val) { |
255 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
256 | } |
257 | |
258 | // twelve octets |
259 | val := -7165932342958243219318534; |
260 | enc_val_exp := 'FFDA128E077FD0362FEED8FA'O; |
261 | enc_val := f_enc_intx_c(val); |
262 | if (enc_val != enc_val_exp) { |
263 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
264 | } |
265 | dec_val := f_dec_intx_c(enc_val_exp); |
266 | if (dec_val != val) { |
267 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
268 | } |
269 | |
270 | setverdict(pass); |
271 | } |
272 | |
273 | testcase tc_intx_record_of() runs on CT |
274 | { |
275 | // record of IntX |
276 | var IntXList val := { 10, -2184, -2554246324530855315, 7165932342958243219318534 }; |
277 | var octetstring enc_val_exp := '0AA888FF402372817FCA823D93FFC5ED71F8802FC9D0112706'O; |
278 | var octetstring enc_val := f_enc_intx_list(val); |
279 | if (enc_val != enc_val_exp) { |
280 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
281 | } |
282 | var IntXList dec_val := f_dec_intx_list(enc_val_exp); |
283 | if (dec_val != val) { |
284 | setverdict(fail, "Expected: ", val, ", got: ", dec_val); |
285 | } |
286 | setverdict(pass); |
287 | } |
288 | |
289 | testcase tc_intx_record() runs on CT |
290 | { |
291 | // record with IntX starting at an octet boundary |
292 | var RecIntX val1 := { -10376, -10376, '11001100'B }; |
293 | var octetstring enc_val_exp := 'D778DFD778CC'O; |
294 | var octetstring enc_val := f_enc_intx_rec(val1); |
295 | if (enc_val != enc_val_exp) { |
296 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
297 | } |
298 | var RecIntX dec_val1 := f_dec_intx_rec(enc_val_exp); |
299 | if (dec_val1 != val1) { |
300 | setverdict(fail, "Expected: ", val1, ", got: ", dec_val1); |
301 | } |
302 | |
303 | // record with IntX starting in a partial octet |
304 | // (the previous field is encoded in 12 bits) |
305 | var RecIntXPartial val2 := { 716, 716, '10101010'B }; |
306 | enc_val_exp := '2CC82CCAA0'O; |
307 | enc_val := f_enc_intx_rec_part(val2); |
308 | if (enc_val != enc_val_exp) { |
309 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
310 | } |
311 | var RecIntXPartial dec_val2 := f_dec_intx_rec_part(enc_val_exp); |
312 | if (dec_val2 != val2) { |
313 | setverdict(fail, "Expected: ", val2, ", got: ", dec_val2); |
314 | } |
315 | |
316 | // record with two IntX fields and padding |
317 | // (the first IntX starts after 24 bits, the second one after 54 bits) |
318 | var RecIntXPadded val3 := { 716, 716, '10101010'B, 716 }; |
319 | enc_val_exp := '02CC0082CC2A820B30'O; |
320 | enc_val := f_enc_intx_rec_padd(val3); |
321 | if (enc_val != enc_val_exp) { |
322 | setverdict(fail, "Expected: ", enc_val_exp, ", got: ", enc_val); |
323 | } |
324 | var RecIntXPadded dec_val3 := f_dec_intx_rec_padd(enc_val_exp); |
325 | if (dec_val3 != val3) { |
326 | setverdict(fail, "Expected: ", val3, ", got: ", dec_val3); |
327 | } |
328 | |
329 | setverdict(pass); |
330 | } |
331 | |
332 | testcase tc_intx_decode_error() runs on CT |
333 | { |
334 | // negative tests for decoding |
335 | // test 1: the last 2 octets from one of the signed IntX tests was removed |
336 | var octetstring bad_enc_val := 'FF402372817FCA82'O; |
337 | var template charstring msg_template := pattern "*While RAW-decoding type *: There are not enough bits in the buffer to decode the value of IntX type * \(needed: 64, found: 48\)."; |
338 | @try { |
339 | var IntX_signed ret_val := f_dec_intx_s(bad_enc_val); |
340 | setverdict(fail, "Expected dynamic test case error when decoding ", bad_enc_val, |
341 | ", got decoded value: ", ret_val); |
342 | } |
343 | @catch (msg) { |
344 | if (not match(msg, msg_template)) { |
345 | setverdict(fail, "Expected error: ", msg_template, ", got: ", msg); |
346 | } |
347 | } |
348 | |
349 | // test 2: same value, but only the first octet is present (even the length data is incomplete) |
350 | bad_enc_val := 'FF'O; |
351 | msg_template := pattern "*While RAW-decoding type *: There are not enough bits in the buffer to decode the length of IntX type * \(needed: 16, found: 8\)."; |
352 | @try { |
353 | var IntX_signed ret_val := f_dec_intx_s(bad_enc_val); |
354 | setverdict(fail, "Expected dynamic test case error when decoding ", bad_enc_val, |
355 | ", got decoded value: ", ret_val); |
356 | } |
357 | @catch (msg) { |
358 | if (not match(msg, msg_template)) { |
359 | setverdict(fail, "Expected error: ", msg_template, ", got: ", msg); |
360 | } |
361 | } |
362 | setverdict(pass); |
363 | } |
364 | |
365 | control { |
366 | execute(tc_intx_unsigned()); |
367 | execute(tc_intx_signed()); |
368 | execute(tc_intx_2scompl()); |
369 | execute(tc_intx_record_of()); |
370 | execute(tc_intx_record()); |
371 | execute(tc_intx_decode_error()); |
372 | } |
373 | |
374 | } |
375 | with { |
376 | encode "RAW" |
377 | } |