Unit tests for libimcv
[strongswan.git] / src / libimcv / suites / test_imcv_seg.c
1 /*
2 * Copyright (C) 2014 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include <imcv.h>
19 #include <pa_tnc/pa_tnc_attr.h>
20 #include <seg/seg_env.h>
21 #include <seg/seg_contract.h>
22 #include <ietf/ietf_attr_pa_tnc_error.h>
23 #include <ita/ita_attr.h>
24 #include <ita/ita_attr_command.h>
25 #include <ita/ita_attr_dummy.h>
26 #include <tcg/seg/tcg_seg_attr_seg_env.h>
27
28 #include <tncif_pa_subtypes.h>
29
30 static struct {
31 uint32_t max_seg_size, next_segs, last_seg_size;
32 } seg_env_tests[] = {
33 { 0, 0, 0 },
34 { 11, 0, 0 },
35 { 12, 3, 12 },
36 { 13, 3, 9 },
37 { 15, 3, 3 },
38 { 16, 2, 16 },
39 { 17, 2, 14 },
40 { 23, 2, 2 },
41 { 24, 1, 24 },
42 { 25, 1, 23 },
43 { 47, 1, 1 },
44 { 48, 0, 0 },
45 };
46
47 static char command[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
48 static uint32_t id = 0x123456;
49
50 START_TEST(test_imcv_seg_env)
51 {
52 pa_tnc_attr_t *attr, *attr1, *base_attr, *base_attr1, *error;
53 tcg_seg_attr_seg_env_t *seg_env_attr;
54 ita_attr_command_t *ita_attr;
55 seg_env_t *seg_env, *seg_env1;
56 pen_type_t type;
57 uint32_t base_attr_id, max_seg_size, last_seg_size, seg_size, offset;
58 uint8_t flags;
59 bool last, last_seg;
60 chunk_t value, segment, seg;
61 int n;
62
63 libimcv_init(FALSE);
64 max_seg_size = seg_env_tests[_i].max_seg_size;
65 last_seg_size = seg_env_tests[_i].last_seg_size;
66 base_attr = ita_attr_command_create(command);
67 base_attr->build(base_attr);
68
69 seg_env = seg_env_create(id, base_attr, max_seg_size);
70 if (seg_env_tests[_i].next_segs == 0)
71 {
72 ck_assert(seg_env == NULL);
73 }
74 else
75 {
76 ck_assert(seg_env->get_base_attr_id(seg_env) == id);
77 base_attr1 = seg_env->get_base_attr(seg_env, &error);
78 ck_assert(base_attr == base_attr1);
79 ck_assert(error == NULL);
80 base_attr1->destroy(base_attr1);
81
82 for (n = 0; n <= seg_env_tests[_i].next_segs; n++)
83 {
84 last_seg = (n == seg_env_tests[_i].next_segs);
85 seg_size = (last_seg) ? last_seg_size : max_seg_size;
86 if (n == 0)
87 {
88 /* create first segment */
89 attr = seg_env->first_segment(seg_env);
90
91 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
92 segment = seg_env_attr->get_segment(seg_env_attr, &flags);
93 if (max_seg_size > 12)
94 {
95 seg = chunk_create(command, seg_size - 12);
96 ck_assert(chunk_equals(seg, chunk_skip(segment, 12)));
97 }
98 ck_assert(flags == (SEG_ENV_FLAG_MORE | SEG_ENV_FLAG_START));
99 }
100 else
101 {
102 /* create next segments */
103 attr = seg_env->next_segment(seg_env, &last);
104 ck_assert(last == last_seg);
105
106 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
107 segment = seg_env_attr->get_segment(seg_env_attr, &flags);
108 seg = chunk_create(command + n * max_seg_size - 12, seg_size);
109 ck_assert(chunk_equals(seg, segment));
110 ck_assert(flags == last_seg ? SEG_ENV_FLAG_NONE :
111 SEG_ENV_FLAG_MORE);
112 }
113
114 /* check built segment envelope attribute */
115 value = attr->get_value(attr);
116 ck_assert(value.len == 4 + seg_size);
117 ck_assert(segment.len == seg_size);
118 ck_assert(seg_env_attr->get_base_attr_id(seg_env_attr) == id);
119
120 /* create parse segment envelope attribute from data */
121 attr1 = tcg_seg_attr_seg_env_create_from_data(value);
122 ck_assert(attr1->process(attr1, &offset) == SUCCESS);
123 attr->destroy(attr);
124
125 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr1;
126 segment = seg_env_attr->get_segment(seg_env_attr, &flags);
127 base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
128 ck_assert(base_attr_id == id);
129
130 /* create and update seg_env object on the receiving side */
131 if (n == 0)
132 {
133 ck_assert(flags == (SEG_ENV_FLAG_MORE | SEG_ENV_FLAG_START));
134 seg_env1 = seg_env_create_from_data(base_attr_id, segment,
135 max_seg_size);
136 }
137 else
138 {
139 ck_assert(flags == last_seg ? SEG_ENV_FLAG_NONE :
140 SEG_ENV_FLAG_MORE);
141 seg_env1->add_segment(seg_env1, segment);
142 }
143 attr1->destroy(attr1);
144 }
145
146 /* check reconstructed base attribute */
147 base_attr1 = seg_env1->get_base_attr(seg_env1, &error);
148 ck_assert(base_attr1);
149 ck_assert(error == NULL);
150 type = base_attr1->get_type(base_attr1);
151 ck_assert(type.vendor_id == PEN_ITA);
152 ck_assert(type.type == ITA_ATTR_COMMAND);
153 ita_attr = (ita_attr_command_t*)base_attr1;
154 ck_assert(streq(ita_attr->get_command(ita_attr), command));
155
156 seg_env->destroy(seg_env);
157 seg_env1->destroy(seg_env1);
158 base_attr1->destroy(base_attr1);
159 }
160 base_attr->destroy(base_attr);
161 libimcv_deinit();
162 }
163 END_TEST
164
165 START_TEST(test_imcv_seg_env_special)
166 {
167 pa_tnc_attr_t *attr, *attr1, *base_attr;
168 tcg_seg_attr_seg_env_t *seg_env_attr;
169 pen_type_t type;
170 seg_env_t *seg_env;
171 chunk_t segment;
172 uint32_t max_seg_size = 47;
173 uint32_t last_seg_size = 1;
174 uint32_t offset = 12;
175
176 base_attr = ita_attr_command_create(command);
177 base_attr->build(base_attr);
178
179 /* set noskip flag in base attribute */
180 base_attr->set_noskip_flag(base_attr, TRUE);
181
182 seg_env = seg_env_create(id, base_attr, max_seg_size);
183 attr = seg_env->first_segment(seg_env);
184 attr->destroy(attr);
185
186 /* don't return last segment indicator */
187 attr = seg_env->next_segment(seg_env, NULL);
188
189 /* build attribute */
190 attr->build(attr);
191
192 /* don't return flags */
193 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
194 segment = seg_env_attr->get_segment(seg_env_attr, NULL);
195 ck_assert(segment.len == last_seg_size);
196
197 /* get segment envelope attribute reference and destroy it */
198 attr1 = attr->get_ref(attr);
199 attr1->destroy(attr1);
200
201 /* check some standard methods */
202 type = attr->get_type(attr);
203 ck_assert(type.vendor_id == PEN_TCG);
204 ck_assert(type.type == TCG_SEG_ATTR_SEG_ENV);
205 ck_assert(attr->get_noskip_flag(attr) == FALSE);
206 attr->set_noskip_flag(attr, TRUE);
207 ck_assert(attr->get_noskip_flag(attr) == TRUE);
208
209 /* request next segment which does not exist */
210 ck_assert(seg_env->next_segment(seg_env, NULL) == NULL);
211
212 /* create and parse a too short segment envelope attribute */
213 attr1 = tcg_seg_attr_seg_env_create_from_data(chunk_empty);
214 ck_assert(attr1->process(attr1, &offset) == FAILED);
215 ck_assert(offset == 0);
216 attr1->destroy(attr1);
217
218 /* create and parse correct segment envelope attribute */
219 attr1 = tcg_seg_attr_seg_env_create_from_data(attr->get_value(attr));
220 ck_assert(attr1->process(attr1, &offset) == SUCCESS);
221 type = attr1->get_type(attr1);
222 ck_assert(type.vendor_id == PEN_TCG);
223 ck_assert(type.type == TCG_SEG_ATTR_SEG_ENV);
224 attr1->destroy(attr1);
225
226 /* cleanup */
227 attr->destroy(attr);
228 seg_env->destroy(seg_env);
229 base_attr->destroy(base_attr);
230 }
231 END_TEST
232
233 static struct {
234 pa_tnc_error_code_t error_code;
235 chunk_t segment;
236 } invalid_tests[] = {
237 { PA_ERROR_INVALID_PARAMETER, { NULL, 0 } },
238 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
239 0x00, 0xff, 0xff, 0xf0, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x0a)
240 },
241 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
242 0x00, 0x00, 0x90, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d)
243 },
244 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
245 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c)
246 },
247 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
248 0x00, 0x00, 0x90, 0x2a, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0c)
249 },
250 { PA_ERROR_ATTR_TYPE_NOT_SUPPORTED, chunk_from_chars(
251 0x80, 0x00, 0x90, 0x2a, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0c)
252 },
253 { PA_ERROR_RESERVED, chunk_from_chars(
254 0x00, 0x00, 0x90, 0x2a, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0c)
255 },
256 { PA_ERROR_RESERVED, chunk_from_chars(
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c)
258 },
259 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c)
261 }
262 };
263
264 START_TEST(test_imcv_seg_env_invalid)
265 {
266 seg_env_t *seg_env;
267 pen_type_t error_code;
268 pa_tnc_attr_t *base_attr, *error;
269 ietf_attr_pa_tnc_error_t *error_attr;
270
271 libimcv_init(FALSE);
272 seg_env = seg_env_create_from_data(id, invalid_tests[_i].segment, 20);
273 base_attr = seg_env->get_base_attr(seg_env, &error);
274 ck_assert(base_attr == NULL);
275 if (invalid_tests[_i].error_code == PA_ERROR_RESERVED)
276 {
277 ck_assert(error == NULL);
278 }
279 else
280 {
281 ck_assert(error);
282 error->build(error);
283 error_attr = (ietf_attr_pa_tnc_error_t*)error;
284 error_code = error_attr->get_error_code(error_attr);
285 ck_assert(error_code.vendor_id == PEN_IETF);
286 ck_assert(error_code.type == invalid_tests[_i].error_code);
287 error->destroy(error);
288 }
289 seg_env->destroy(seg_env);
290 libimcv_deinit();
291 }
292 END_TEST
293
294 START_TEST(test_imcv_seg_contract)
295 {
296 seg_contract_t *contract_i, *contract_r;
297 tcg_seg_attr_seg_env_t *seg_env_attr;
298 ita_attr_command_t *ita_attr;
299 pa_tnc_attr_t *attr, *base_attr_i, *base_attr_r, *error;
300 pen_type_t type, msg_type = { PEN_ITA, PA_SUBTYPE_ITA_TEST };
301 uint32_t max_seg_size, max_attr_size = 1000, issuer_id = 1;
302 uint32_t base_attr_id;
303 bool more;
304
305 libimcv_init(FALSE);
306 max_seg_size = seg_env_tests[_i].max_seg_size;
307 base_attr_r = ita_attr_command_create(command);
308 base_attr_r->build(base_attr_r);
309 contract_i = seg_contract_create(msg_type, max_attr_size, max_seg_size,
310 TRUE, issuer_id, FALSE);
311 contract_r = seg_contract_create(msg_type, max_attr_size, max_seg_size,
312 FALSE, issuer_id, TRUE);
313 attr = contract_r->first_segment(contract_r, base_attr_r);
314
315 if (seg_env_tests[_i].next_segs == 0)
316 {
317 ck_assert(attr == NULL);
318 }
319 else
320 {
321 ck_assert(attr);
322 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
323 base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
324 ck_assert(base_attr_id == 1);
325 base_attr_i = contract_i->add_segment(contract_i, attr, &error, &more);
326 ck_assert(base_attr_i == NULL);
327 attr->destroy(attr);
328 ck_assert(more);
329 while (more)
330 {
331 attr = contract_r->next_segment(contract_r, base_attr_id);
332 ck_assert(attr);
333 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
334 base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
335 ck_assert(base_attr_id == 1);
336 base_attr_i = contract_i->add_segment(contract_i, attr, &error,
337 &more);
338 attr->destroy(attr);
339 }
340 ck_assert(base_attr_i);
341 ck_assert(error == NULL);
342 type = base_attr_i->get_type(base_attr_i);
343 ck_assert(pen_type_equals(type, base_attr_r->get_type(base_attr_r)));
344 ita_attr = (ita_attr_command_t*)base_attr_i;
345 ck_assert(streq(ita_attr->get_command(ita_attr), command));
346 base_attr_i->destroy(base_attr_i);
347 }
348 contract_i->destroy(contract_i);
349 contract_r->destroy(contract_r);
350 base_attr_r->destroy(base_attr_r);
351 libimcv_deinit();
352 }
353 END_TEST
354
355 START_TEST(test_imcv_seg_contract_special)
356 {
357 seg_contract_t *contract_i, *contract_r;
358 tcg_seg_attr_seg_env_t *seg_env_attr1, *seg_env_attr2;
359 ita_attr_command_t *ita_attr;
360 pa_tnc_attr_t *base_attr1_i, *base_attr2_i, *base_attr1_r, *base_attr2_r;
361 pa_tnc_attr_t *attr1_f, *attr2_f, *attr1_n, *attr2_n, *attr3, *error;
362 pen_type_t type, msg_type = { PEN_ITA, PA_SUBTYPE_ITA_TEST };
363 uint32_t max_seg_size, max_attr_size, issuer_id = 1;
364 uint32_t base_attr1_id, base_attr2_id;
365 char info[512];
366 bool oversize, more;
367
368 libimcv_init(FALSE);
369
370 /* create two base attributes to be segmented */
371 base_attr1_r = ita_attr_command_create(command);
372 base_attr2_r = ita_attr_dummy_create(129);
373 base_attr1_r->build(base_attr1_r);
374 base_attr2_r->build(base_attr2_r);
375
376 /* create an issuer contract*/
377 contract_i = seg_contract_create(msg_type, 1000, 47,
378 TRUE, issuer_id, FALSE);
379 ck_assert(pen_type_equals(contract_i->get_msg_type(contract_i), msg_type));
380 ck_assert(contract_i->is_issuer(contract_i));
381 ck_assert(!contract_i->is_null(contract_i));
382
383 /* set null contract */
384 contract_i->set_max_size(contract_i, SEG_CONTRACT_MAX_SIZE_VALUE,
385 SEG_CONTRACT_MAX_SIZE_VALUE);
386 ck_assert(contract_i->is_null(contract_i));
387
388 /* set and get maximum attribute and segment sizes */
389 contract_i->set_max_size(contract_i, 1000, 47);
390 contract_i->get_max_size(contract_i, NULL, NULL);
391 contract_i->get_max_size(contract_i, &max_attr_size, &max_seg_size);
392 contract_i->get_info_string(contract_i, info, sizeof(info), TRUE);
393 ck_assert(max_attr_size == 1000 && max_seg_size == 47);
394 ck_assert(!contract_i->is_null(contract_i));
395
396 /* create a null responder contract*/
397 contract_r = seg_contract_create(msg_type, SEG_CONTRACT_MAX_SIZE_VALUE,
398 SEG_CONTRACT_MAX_SIZE_VALUE,
399 FALSE, issuer_id, TRUE);
400 ck_assert(!contract_r->is_issuer(contract_r));
401 ck_assert(!contract_r->check_size(contract_r, base_attr2_r, &oversize));
402 ck_assert(!oversize);
403
404 /* allow no fragmentation */
405 contract_r->set_max_size(contract_r, 1000, SEG_CONTRACT_MAX_SIZE_VALUE);
406 ck_assert(!contract_r->is_null(contract_r));
407 ck_assert(!contract_r->check_size(contract_r, base_attr2_r, &oversize));
408 ck_assert(!oversize);
409
410 /* no maximum size limit and no fragmentation needed */
411 contract_r->set_max_size(contract_r, SEG_CONTRACT_MAX_SIZE_VALUE, 141);
412 ck_assert(!contract_r->is_null(contract_r));
413 ck_assert(!contract_r->check_size(contract_r, base_attr2_r, &oversize));
414 ck_assert(!oversize);
415
416 /* oversize base attribute */
417 contract_r->set_max_size(contract_r, 140, 47);
418 ck_assert(!contract_r->is_null(contract_r));
419 ck_assert(!contract_r->check_size(contract_r, base_attr2_r, &oversize));
420 ck_assert(oversize);
421
422 /* set final maximum attribute and segment sizes */
423 contract_r->set_max_size(contract_r, 141, 47);
424 contract_r->get_info_string(contract_r, info, sizeof(info), TRUE);
425 ck_assert(contract_r->check_size(contract_r, base_attr2_r, &oversize));
426 ck_assert(!oversize);
427
428 /* get first segment of each base attribute */
429 attr1_f = contract_r->first_segment(contract_r, base_attr1_r);
430 attr2_f = contract_r->first_segment(contract_r, base_attr2_r);
431 ck_assert(attr1_f);
432 ck_assert(attr2_f);
433 seg_env_attr1 = (tcg_seg_attr_seg_env_t*)attr1_f;
434 seg_env_attr2 = (tcg_seg_attr_seg_env_t*)attr2_f;
435 base_attr1_id = seg_env_attr1->get_base_attr_id(seg_env_attr1);
436 base_attr2_id = seg_env_attr2->get_base_attr_id(seg_env_attr2);
437 ck_assert(base_attr1_id == 1);
438 ck_assert(base_attr2_id == 2);
439
440 /* get second segment of each base attribute */
441 attr1_n = contract_r->next_segment(contract_r, 1);
442 attr2_n = contract_r->next_segment(contract_r, 2);
443 ck_assert(attr1_n);
444 ck_assert(attr2_n);
445
446 /* process first segment of first base attribute */
447 base_attr1_i = contract_i->add_segment(contract_i, attr1_f, &error, &more);
448 ck_assert(base_attr1_i == NULL);
449 ck_assert(error == NULL);
450 ck_assert(more);
451
452 /* reapply first segment of first base attribute */
453 base_attr1_i = contract_i->add_segment(contract_i, attr1_f, &error, &more);
454 ck_assert(base_attr1_i == NULL);
455 ck_assert(error == NULL);
456 ck_assert(more);
457
458 /* process stray second segment of second attribute */
459 base_attr2_i = contract_i->add_segment(contract_i, attr2_n, &error, &more);
460 ck_assert(base_attr2_i == NULL);
461 ck_assert(error == NULL);
462 ck_assert(more);
463
464 /* process first segment of second base attribute */
465 base_attr2_i = contract_i->add_segment(contract_i, attr2_f, &error, &more);
466 ck_assert(base_attr2_i == NULL);
467 ck_assert(error == NULL);
468 ck_assert(more);
469
470 /* try to get a segment of a non-existing base-attribute */
471 attr3 = contract_r->next_segment(contract_r, 3);
472 ck_assert(attr3 == NULL);
473
474 /* process second segment of first base attribute */
475 base_attr1_i = contract_i->add_segment(contract_i, attr1_n, &error, &more);
476 ck_assert(base_attr1_i);
477 ck_assert(error == NULL);
478 ck_assert(!more);
479
480 /* process second segment of second base attribute */
481 base_attr2_i = contract_i->add_segment(contract_i, attr2_n, &error, &more);
482 ck_assert(base_attr2_i == NULL);
483 ck_assert(error == NULL);
484 ck_assert(more);
485
486 /* destroy first and second segments */
487 attr1_f->destroy(attr1_f);
488 attr2_f->destroy(attr2_f);
489 attr1_n->destroy(attr1_n);
490 attr2_n->destroy(attr2_n);
491
492 /* request surplus segment of first base attribute */
493 attr1_n = contract_r->next_segment(contract_r, 1);
494 ck_assert(attr1_n == NULL);
495
496 /* get last segment of second base attribute */
497 attr2_n = contract_r->next_segment(contract_r, 2);
498 ck_assert(attr2_n);
499
500 /* process last segment of second base attribute */
501 base_attr2_i = contract_i->add_segment(contract_i, attr2_n, &error, &more);
502 attr2_n->destroy(attr2_n);
503 ck_assert(base_attr2_i);
504 ck_assert(error == NULL);
505 ck_assert(!more);
506
507 /* request surplus segment of second base attribute */
508 attr2_n = contract_r->next_segment(contract_r, 2);
509 ck_assert(attr2_n == NULL);
510
511 /* compare original with reconstructed base attributes */
512 type = base_attr1_i->get_type(base_attr1_i);
513 ck_assert(pen_type_equals(type, base_attr1_r->get_type(base_attr1_r)));
514 ita_attr = (ita_attr_command_t*)base_attr1_i;
515 ck_assert(streq(ita_attr->get_command(ita_attr), command));
516
517 type = base_attr2_i->get_type(base_attr2_i);
518 ck_assert(pen_type_equals(type, base_attr2_r->get_type(base_attr2_r)));
519 ck_assert(chunk_equals(base_attr2_i->get_value(base_attr2_i),
520 base_attr2_r->get_value(base_attr2_r)));
521
522 /* cleanup */
523 base_attr1_r->destroy(base_attr1_r);
524 base_attr2_r->destroy(base_attr2_r);
525 base_attr1_i->destroy(base_attr1_i);
526 base_attr2_i->destroy(base_attr2_i);
527 contract_i->destroy(contract_i);
528 contract_r->destroy(contract_r);
529 libimcv_deinit();
530 }
531 END_TEST
532
533 Suite *imcv_seg_suite_create()
534 {
535 Suite *s;
536 TCase *tc;
537
538 s = suite_create("imcv_seg");
539
540 tc = tcase_create("env");
541 tcase_add_loop_test(tc, test_imcv_seg_env, 0, countof(seg_env_tests));
542 suite_add_tcase(s, tc);
543
544 tc = tcase_create("env_special");
545 tcase_add_test(tc, test_imcv_seg_env_special);
546 suite_add_tcase(s, tc);
547
548 tc = tcase_create("env_invalid");
549 tcase_add_loop_test(tc, test_imcv_seg_env_invalid, 0, countof(invalid_tests));
550 suite_add_tcase(s, tc);
551
552 tc = tcase_create("contract");
553 tcase_add_loop_test(tc, test_imcv_seg_contract, 0, countof(seg_env_tests));
554 suite_add_tcase(s, tc);
555
556 tc = tcase_create("contract_special");
557 tcase_add_test(tc, test_imcv_seg_contract_special);
558 suite_add_tcase(s, tc);
559
560 return s;
561 }