~stub/ubuntu/trusty/avro-c/trunk

« back to all changes in this revision

Viewing changes to tests/test_avro_values.c

  • Committer: Stuart Bishop
  • Date: 2015-05-14 11:53:53 UTC
  • Revision ID: stuart@stuartbishop.net-20150514115353-0cvnrcyohcq5l7yj
Tags: upstream-1.7.7
ImportĀ upstreamĀ versionĀ 1.7.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 * contributor license agreements.  See the NOTICE file distributed with
 
4
 * this work for additional information regarding copyright ownership.
 
5
 * The ASF licenses this file to you under the Apache License, Version 2.0
 
6
 * (the "License"); you may not use this file except in compliance with
 
7
 * the License.  You may obtain a copy of the License at
 
8
 *
 
9
 * http://www.apache.org/licenses/LICENSE-2.0
 
10
 *
 
11
 * Unless required by applicable law or agreed to in writing, software
 
12
 * distributed under the License is distributed on an "AS IS" BASIS,
 
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 
14
 * implied.  See the License for the specific language governing
 
15
 * permissions and limitations under the License.
 
16
 */
 
17
 
 
18
/* Test cases for the new avro_value_t interface */
 
19
 
 
20
#include <limits.h>
 
21
#include <stdlib.h>
 
22
#include <string.h>
 
23
#include <time.h>
 
24
 
 
25
#include "avro.h"
 
26
#include "avro_private.h"
 
27
 
 
28
typedef int (*avro_test) (void);
 
29
 
 
30
#ifndef SHOW_ALLOCATIONS
 
31
#define SHOW_ALLOCATIONS 0
 
32
#endif
 
33
 
 
34
/*
 
35
 * Use a custom allocator that verifies that the size that we use to
 
36
 * free an object matches the size that we use to allocate it.
 
37
 */
 
38
 
 
39
static void *
 
40
test_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
 
41
{
 
42
        AVRO_UNUSED(ud);
 
43
        AVRO_UNUSED(osize);
 
44
 
 
45
#if SHOW_ALLOCATIONS
 
46
        fprintf(stderr, "alloc(%p, %" PRIsz ", %" PRIsz ") => ", ptr, osize, nsize);
 
47
#endif
 
48
 
 
49
        if (nsize == 0) {
 
50
                size_t  *size = ((size_t *) ptr) - 1;
 
51
                if (osize != *size) {
 
52
                        fprintf(stderr,
 
53
#if SHOW_ALLOCATIONS
 
54
                                "ERROR!\n"
 
55
#endif
 
56
                                "Error freeing %p:\n"
 
57
                                "Size passed to avro_free (%" PRIsz ") "
 
58
                                "doesn't match size passed to "
 
59
                                "avro_malloc (%" PRIsz ")\n",
 
60
                                ptr, osize, *size);
 
61
                        exit(EXIT_FAILURE);
 
62
                }
 
63
                free(size);
 
64
#if SHOW_ALLOCATIONS
 
65
                fprintf(stderr, "NULL\n");
 
66
#endif
 
67
                return NULL;
 
68
        } else {
 
69
                size_t  real_size = nsize + sizeof(size_t);
 
70
                size_t  *old_size = ptr? ((size_t *) ptr)-1: NULL;
 
71
                size_t  *size = (size_t *) realloc(old_size, real_size);
 
72
                *size = nsize;
 
73
#if SHOW_ALLOCATIONS
 
74
                fprintf(stderr, "%p\n", (size+1));
 
75
#endif
 
76
                return (size + 1);
 
77
        }
 
78
}
 
79
 
 
80
void
 
81
init_rand(void)
 
82
{
 
83
        srand(time(NULL));
 
84
}
 
85
 
 
86
double
 
87
rand_number(double from, double to)
 
88
{
 
89
        double range = to - from;
 
90
        return from + ((double)rand() / (RAND_MAX + 1.0)) * range;
 
91
}
 
92
 
 
93
int64_t
 
94
rand_int64(void)
 
95
{
 
96
        return (int64_t) rand_number(LONG_MIN, LONG_MAX);
 
97
}
 
98
 
 
99
int32_t
 
100
rand_int32(void)
 
101
{
 
102
        return (int32_t) rand_number(INT_MIN, INT_MAX);
 
103
}
 
104
 
 
105
size_t
 
106
rand_count(void)
 
107
{
 
108
        return (size_t) rand_number(0, 100);
 
109
}
 
110
 
 
111
#define check_(call) \
 
112
        do { \
 
113
                int _rval = call; \
 
114
                if (_rval) { return _rval; } \
 
115
        } while (0)
 
116
 
 
117
/*
 
118
 * Verify that we can't call any of the getters and setters that don't
 
119
 * apply to the given value.
 
120
 */
 
121
 
 
122
static int
 
123
_check_invalid_methods(const char *name, avro_value_t *val)
 
124
{
 
125
        avro_type_t  type = avro_value_get_type(val);
 
126
 
 
127
/* For a description on GCC vs Visual Studio 2008 usage of variadic
 
128
 * macros see:
 
129
 * http://stackoverflow.com/questions/2575864/the-problem-about-different
 
130
 * -treatment-to-va-args-when-using-vs-2008-and-gcc
 
131
 */
 
132
#define expand_args(...) __VA_ARGS__
 
133
#define check_bad(method, ...) \
 
134
        do { \
 
135
          if (!expand_args(avro_value_##method(__VA_ARGS__))) {  \
 
136
                        fprintf(stderr, \
 
137
                                "Shouldn't be able to " #method " a %s\n", \
 
138
                                name); \
 
139
                        return EXIT_FAILURE; \
 
140
                } \
 
141
        } while (0)
 
142
 
 
143
        if (type != AVRO_BOOLEAN) {
 
144
                int  dummy = 0;
 
145
                check_bad(get_boolean, val, &dummy);
 
146
                check_bad(set_boolean, val, dummy);
 
147
        }
 
148
 
 
149
        if (type != AVRO_BYTES) {
 
150
                const void  *cbuf = NULL;
 
151
                void  *buf = NULL;
 
152
                size_t  size = 0;
 
153
                check_bad(get_bytes, val, &cbuf, &size);
 
154
                check_bad(set_bytes, val, buf, size);
 
155
        }
 
156
 
 
157
        if (type != AVRO_DOUBLE) {
 
158
                double  dummy = 0;
 
159
                check_bad(get_double, val, &dummy);
 
160
                check_bad(set_double, val, dummy);
 
161
        }
 
162
 
 
163
        if (type != AVRO_FLOAT) {
 
164
                float  dummy = 0;
 
165
                check_bad(get_float, val, &dummy);
 
166
                check_bad(set_float, val, dummy);
 
167
        }
 
168
 
 
169
        if (type != AVRO_INT32) {
 
170
                int32_t  dummy = 0;
 
171
                check_bad(get_int, val, &dummy);
 
172
                check_bad(set_int, val, dummy);
 
173
        }
 
174
 
 
175
        if (type != AVRO_INT64) {
 
176
                int64_t  dummy = 0;
 
177
                check_bad(get_long, val, &dummy);
 
178
                check_bad(set_long, val, dummy);
 
179
        }
 
180
 
 
181
        if (type != AVRO_NULL) {
 
182
                check_bad(get_null, val);
 
183
                check_bad(set_null, val);
 
184
        }
 
185
 
 
186
        if (type != AVRO_STRING) {
 
187
                const char  *cstr = NULL;
 
188
                char  *str = NULL;
 
189
                size_t  size = 0;
 
190
                check_bad(get_string, val, &cstr, &size);
 
191
                check_bad(set_string, val, str);
 
192
                check_bad(set_string_len, val, str, size);
 
193
        }
 
194
 
 
195
        if (type != AVRO_ENUM) {
 
196
                int  dummy = 0;
 
197
                check_bad(get_enum, val, &dummy);
 
198
                check_bad(set_enum, val, dummy);
 
199
        }
 
200
 
 
201
        if (type != AVRO_FIXED) {
 
202
                const void  *cbuf = NULL;
 
203
                void  *buf = NULL;
 
204
                size_t  size = 0;
 
205
                check_bad(get_fixed, val, &cbuf, &size);
 
206
                check_bad(set_fixed, val, buf, size);
 
207
        }
 
208
 
 
209
        if (type != AVRO_ARRAY && type != AVRO_MAP && type != AVRO_RECORD) {
 
210
                size_t  size = 0;
 
211
                check_bad(get_size, val, &size);
 
212
 
 
213
                size_t  index = 0;
 
214
                avro_value_t  child;
 
215
                const char  *key = NULL;
 
216
                check_bad(get_by_index, val, index, &child, &key);
 
217
        }
 
218
 
 
219
        if (type != AVRO_MAP && type != AVRO_RECORD) {
 
220
                const char  *key = NULL;
 
221
                avro_value_t  child;
 
222
                size_t  index = 0;
 
223
                check_bad(get_by_name, val, key, &child, &index);
 
224
        }
 
225
 
 
226
        if (type != AVRO_ARRAY) {
 
227
                avro_value_t  child;
 
228
                size_t  index;
 
229
                check_bad(append, val, &child, &index);
 
230
        }
 
231
 
 
232
        if (type != AVRO_MAP) {
 
233
                const char  *key = NULL;
 
234
                avro_value_t  child;
 
235
                size_t  index = 0;
 
236
                int  is_new = 0;
 
237
                check_bad(add, val, key, &child, &index, &is_new);
 
238
        }
 
239
 
 
240
        if (type != AVRO_UNION) {
 
241
                int  discriminant = 0;
 
242
                avro_value_t  branch;
 
243
                check_bad(get_discriminant, val, &discriminant);
 
244
                check_bad(get_current_branch, val, &branch);
 
245
                check_bad(set_branch, val, discriminant, &branch);
 
246
        }
 
247
 
 
248
#undef check_bad
 
249
 
 
250
        return EXIT_SUCCESS;
 
251
}
 
252
 
 
253
#define check_invalid_methods(name, val) \
 
254
        check_(_check_invalid_methods(name, val))
 
255
 
 
256
/*
 
257
 * Verify that we get the expected type code and schema for a value.
 
258
 */
 
259
 
 
260
static int
 
261
check_type_and_schema(const char *name,
 
262
                      avro_value_t *val,
 
263
                      avro_type_t expected_type,
 
264
                      avro_schema_t expected_schema)
 
265
{
 
266
        if (avro_value_get_type(val) != expected_type) {
 
267
                avro_schema_decref(expected_schema);
 
268
                fprintf(stderr, "Unexpected type for %s\n", name);
 
269
                return EXIT_FAILURE;
 
270
        }
 
271
 
 
272
        if (!avro_schema_equal(avro_value_get_schema(val),
 
273
                               expected_schema)) {
 
274
                avro_schema_decref(expected_schema);
 
275
                fprintf(stderr, "Unexpected schema for %s\n", name);
 
276
                return EXIT_FAILURE;
 
277
        }
 
278
 
 
279
        avro_schema_decref(expected_schema);
 
280
        return EXIT_SUCCESS;
 
281
}
 
282
 
 
283
#define try(call, msg) \
 
284
        do { \
 
285
                if (call) { \
 
286
                        fprintf(stderr, msg ":\n  %s\n", avro_strerror()); \
 
287
                        return EXIT_FAILURE; \
 
288
                } \
 
289
        } while (0)
 
290
 
 
291
static int
 
292
_check_write_read(avro_value_t *val)
 
293
{
 
294
        static char  buf[4096];
 
295
 
 
296
        avro_reader_t  reader = avro_reader_memory(buf, sizeof(buf));
 
297
        avro_writer_t  writer = avro_writer_memory(buf, sizeof(buf));
 
298
 
 
299
        if (avro_value_write(writer, val)) {
 
300
                fprintf(stderr, "Unable to write value:\n  %s\n",
 
301
                        avro_strerror());
 
302
                return EXIT_FAILURE;
 
303
        }
 
304
 
 
305
        avro_writer_dump(writer, stderr);
 
306
 
 
307
        size_t size;
 
308
        if (avro_value_sizeof(val, &size)) {
 
309
                fprintf(stderr, "Unable to determine size of value:\n  %s\n",
 
310
                        avro_strerror());
 
311
                return EXIT_FAILURE;
 
312
        }
 
313
 
 
314
        if (size != (size_t) avro_writer_tell(writer)) {
 
315
                fprintf(stderr, "Unexpected size of encoded value\n");
 
316
                return EXIT_FAILURE;
 
317
        }
 
318
 
 
319
        avro_value_t  val_in;
 
320
        if (avro_generic_value_new(val->iface, &val_in)) {
 
321
                fprintf(stderr, "Cannot allocate new value instance:\n  %s\n",
 
322
                        avro_strerror());
 
323
                return EXIT_FAILURE;
 
324
        }
 
325
 
 
326
        if (avro_value_read(reader, &val_in)) {
 
327
                fprintf(stderr, "Unable to read value:\n  %s\n",
 
328
                        avro_strerror());
 
329
                return EXIT_FAILURE;
 
330
        }
 
331
 
 
332
        if (!avro_value_equal(val, &val_in)) {
 
333
                fprintf(stderr, "Round-trip values not equal\n");
 
334
                exit(EXIT_FAILURE);
 
335
        }
 
336
 
 
337
        avro_value_decref(&val_in);
 
338
        avro_reader_free(reader);
 
339
        avro_writer_free(writer);
 
340
 
 
341
        return EXIT_SUCCESS;
 
342
}
 
343
 
 
344
#define check_write_read(val) \
 
345
        check_(_check_write_read(val))
 
346
 
 
347
static int
 
348
_check_hash(avro_value_t *val1, avro_value_t *val2)
 
349
{
 
350
        uint32_t  hash1 = avro_value_hash(val1);
 
351
        uint32_t  hash2 = avro_value_hash(val2);
 
352
        if (hash1 != hash2) {
 
353
                fprintf(stderr, "Copied hashed not equal\n");
 
354
                return EXIT_FAILURE;
 
355
        }
 
356
        return EXIT_SUCCESS;
 
357
}
 
358
 
 
359
#define check_hash(val1, val2) \
 
360
        check_(_check_hash(val1, val2))
 
361
 
 
362
static int
 
363
_check_copy(avro_value_t *val)
 
364
{
 
365
        avro_value_t  copied_val;
 
366
        if (avro_generic_value_new(val->iface, &copied_val)) {
 
367
                fprintf(stderr, "Cannot allocate new value instance:\n  %s\n",
 
368
                        avro_strerror());
 
369
                return EXIT_FAILURE;
 
370
        }
 
371
 
 
372
        if (avro_value_copy_fast(&copied_val, val)) {
 
373
                fprintf(stderr, "Cannot copy value:\n  %s\n",
 
374
                        avro_strerror());
 
375
                return EXIT_FAILURE;
 
376
        }
 
377
 
 
378
        if (!avro_value_equal(val, &copied_val)) {
 
379
                fprintf(stderr, "Copied values not equal\n");
 
380
                return EXIT_FAILURE;
 
381
        }
 
382
 
 
383
        check_hash(val, &copied_val);
 
384
 
 
385
        avro_value_decref(&copied_val);
 
386
        return EXIT_SUCCESS;
 
387
}
 
388
 
 
389
#define check_copy(val) \
 
390
        check_(_check_copy(val))
 
391
 
 
392
static int
 
393
test_boolean(void)
 
394
{
 
395
        int  rval;
 
396
 
 
397
        int  i;
 
398
        for (i = 0; i <= 1; i++) {
 
399
                avro_value_t  val;
 
400
                try(avro_generic_boolean_new(&val, i),
 
401
                    "Cannot create boolean");
 
402
                check(rval, check_type_and_schema
 
403
                            ("boolean", &val,
 
404
                             AVRO_BOOLEAN, avro_schema_boolean()));
 
405
                try(avro_value_reset(&val),
 
406
                    "Cannot reset boolean");
 
407
                try(avro_value_set_boolean(&val, i),
 
408
                    "Cannot set boolean");
 
409
 
 
410
                /* Start with the wrong value to make sure _get does
 
411
                 * something. */
 
412
                int  actual = (int) 23;
 
413
                try(avro_value_get_boolean(&val, &actual),
 
414
                    "Cannot get boolean value");
 
415
 
 
416
                if (actual != i) {
 
417
                        fprintf(stderr, "Unexpected boolean value\n");
 
418
                        return EXIT_FAILURE;
 
419
                }
 
420
 
 
421
                check_invalid_methods("boolean", &val);
 
422
                check_write_read(&val);
 
423
                check_copy(&val);
 
424
                avro_value_decref(&val);
 
425
        }
 
426
 
 
427
        avro_value_t  val1;
 
428
        avro_value_t  val2;
 
429
        try(avro_generic_boolean_new(&val1, 0),
 
430
            "Cannot create boolean");
 
431
        try(avro_generic_boolean_new(&val2, 1),
 
432
            "Cannot create boolean");
 
433
        if (avro_value_cmp_fast(&val1, &val2) >= 0) {
 
434
                fprintf(stderr, "Incorrect sort order\n");
 
435
                return EXIT_FAILURE;
 
436
        }
 
437
        if (avro_value_cmp_fast(&val2, &val1) <= 0) {
 
438
                fprintf(stderr, "Incorrect sort order\n");
 
439
                return EXIT_FAILURE;
 
440
        }
 
441
        if (avro_value_cmp_fast(&val1, &val1) != 0) {
 
442
                fprintf(stderr, "Incorrect sort order\n");
 
443
                return EXIT_FAILURE;
 
444
        }
 
445
        avro_value_decref(&val1);
 
446
        avro_value_decref(&val2);
 
447
 
 
448
        return 0;
 
449
}
 
450
 
 
451
static int
 
452
test_bytes(void)
 
453
{
 
454
        int  rval;
 
455
 
 
456
        char bytes[] = { 0xDE, 0xAD, 0xBE, 0xEF };
 
457
 
 
458
        avro_value_t  val;
 
459
        try(avro_generic_bytes_new(&val, bytes, sizeof(bytes)),
 
460
            "Cannot create bytes");
 
461
        check(rval, check_type_and_schema
 
462
                    ("bytes", &val,
 
463
                     AVRO_BYTES, avro_schema_bytes()));
 
464
        try(avro_value_reset(&val),
 
465
            "Cannot reset bytes");
 
466
        try(avro_value_set_bytes(&val, bytes, sizeof(bytes)),
 
467
            "Cannot set bytes");
 
468
 
 
469
        const void  *actual_buf = NULL;
 
470
        size_t  actual_size = 0;
 
471
        try(avro_value_get_bytes(&val, &actual_buf, &actual_size),
 
472
            "Cannot get bytes value");
 
473
 
 
474
        if (actual_size != sizeof(bytes)) {
 
475
                fprintf(stderr, "Unexpected bytes size\n");
 
476
                return EXIT_FAILURE;
 
477
        }
 
478
 
 
479
        if (memcmp(actual_buf, bytes, sizeof(bytes)) != 0) {
 
480
                fprintf(stderr, "Unexpected bytes contents\n");
 
481
                return EXIT_FAILURE;
 
482
        }
 
483
 
 
484
        avro_wrapped_buffer_t  wbuf;
 
485
        try(avro_value_grab_bytes(&val, &wbuf),
 
486
            "Cannot grab bytes value");
 
487
 
 
488
        if (wbuf.size != sizeof(bytes)) {
 
489
                fprintf(stderr, "Unexpected grabbed bytes size\n");
 
490
                return EXIT_FAILURE;
 
491
        }
 
492
 
 
493
        if (memcmp(wbuf.buf, bytes, sizeof(bytes)) != 0) {
 
494
                fprintf(stderr, "Unexpected grabbed bytes contents\n");
 
495
                return EXIT_FAILURE;
 
496
        }
 
497
 
 
498
        avro_wrapped_buffer_free(&wbuf);
 
499
 
 
500
        check_invalid_methods("bytes", &val);
 
501
        check_write_read(&val);
 
502
        check_copy(&val);
 
503
        avro_value_decref(&val);
 
504
 
 
505
        avro_value_t  val1;
 
506
        avro_value_t  val2;
 
507
        avro_value_t  val3;
 
508
        try(avro_generic_bytes_new(&val1, "abcd", 4),
 
509
            "Cannot create bytes");
 
510
        try(avro_generic_bytes_new(&val2, "abcde", 5),
 
511
            "Cannot create bytes");
 
512
        try(avro_generic_bytes_new(&val3, "abce", 4),
 
513
            "Cannot create bytes");
 
514
        if (avro_value_cmp_fast(&val1, &val2) >= 0) {
 
515
                fprintf(stderr, "Incorrect sort order\n");
 
516
                return EXIT_FAILURE;
 
517
        }
 
518
        if (avro_value_cmp_fast(&val2, &val1) <= 0) {
 
519
                fprintf(stderr, "Incorrect sort order\n");
 
520
                return EXIT_FAILURE;
 
521
        }
 
522
        if (avro_value_cmp_fast(&val1, &val3) >= 0) {
 
523
                fprintf(stderr, "Incorrect sort order\n");
 
524
                return EXIT_FAILURE;
 
525
        }
 
526
        if (avro_value_cmp_fast(&val1, &val1) != 0) {
 
527
                fprintf(stderr, "Incorrect sort order\n");
 
528
                return EXIT_FAILURE;
 
529
        }
 
530
        avro_value_decref(&val1);
 
531
        avro_value_decref(&val2);
 
532
        avro_value_decref(&val3);
 
533
 
 
534
        return 0;
 
535
}
 
536
 
 
537
static int
 
538
test_double(void)
 
539
{
 
540
        int  rval;
 
541
 
 
542
        int  i;
 
543
        for (i = 0; i < 100; i++) {
 
544
                double  expected = rand_number(-1e10, 1e10);
 
545
                avro_value_t  val;
 
546
                try(avro_generic_double_new(&val, expected),
 
547
                    "Cannot create double");
 
548
                check(rval, check_type_and_schema
 
549
                            ("double", &val,
 
550
                             AVRO_DOUBLE, avro_schema_double()));
 
551
                try(avro_value_reset(&val),
 
552
                    "Cannot reset double");
 
553
                try(avro_value_set_double(&val, expected),
 
554
                    "Cannot set double");
 
555
 
 
556
                double  actual = 0.0;
 
557
                try(avro_value_get_double(&val, &actual),
 
558
                    "Cannot get double value");
 
559
 
 
560
                if (actual != expected) {
 
561
                        fprintf(stderr, "Unexpected double value\n");
 
562
                        return EXIT_FAILURE;
 
563
                }
 
564
 
 
565
                check_invalid_methods("double", &val);
 
566
                check_write_read(&val);
 
567
                check_copy(&val);
 
568
                avro_value_decref(&val);
 
569
        }
 
570
        return 0;
 
571
}
 
572
 
 
573
static int
 
574
test_float(void)
 
575
{
 
576
        int  rval;
 
577
 
 
578
        int  i;
 
579
        for (i = 0; i < 100; i++) {
 
580
                float  expected = rand_number(-1e10, 1e10);
 
581
                avro_value_t  val;
 
582
                try(avro_generic_float_new(&val, expected),
 
583
                    "Cannot create float");
 
584
                check(rval, check_type_and_schema
 
585
                            ("float", &val,
 
586
                             AVRO_FLOAT, avro_schema_float()));
 
587
                try(avro_value_reset(&val),
 
588
                    "Cannot reset float");
 
589
                try(avro_value_set_float(&val, expected),
 
590
                    "Cannot set float");
 
591
 
 
592
                float  actual = 0.0f;
 
593
                try(avro_value_get_float(&val, &actual),
 
594
                    "Cannot get float value");
 
595
 
 
596
                if (actual != expected) {
 
597
                        fprintf(stderr, "Unexpected float value\n");
 
598
                        return EXIT_FAILURE;
 
599
                }
 
600
 
 
601
                check_invalid_methods("float", &val);
 
602
                check_write_read(&val);
 
603
                check_copy(&val);
 
604
                avro_value_decref(&val);
 
605
        }
 
606
        return 0;
 
607
}
 
608
 
 
609
static int
 
610
test_int(void)
 
611
{
 
612
        int  rval;
 
613
 
 
614
        int  i;
 
615
        for (i = 0; i < 100; i++) {
 
616
                int32_t  expected = rand_int32();
 
617
                avro_value_t  val;
 
618
                try(avro_generic_int_new(&val, expected),
 
619
                    "Cannot create int");
 
620
                check(rval, check_type_and_schema
 
621
                            ("int", &val,
 
622
                             AVRO_INT32, avro_schema_int()));
 
623
                try(avro_value_reset(&val),
 
624
                    "Cannot reset int");
 
625
                try(avro_value_set_int(&val, expected),
 
626
                    "Cannot set int");
 
627
 
 
628
                int32_t  actual = 0;
 
629
                try(avro_value_get_int(&val, &actual),
 
630
                    "Cannot get int value");
 
631
 
 
632
                if (actual != expected) {
 
633
                        fprintf(stderr, "Unexpected int value\n");
 
634
                        return EXIT_FAILURE;
 
635
                }
 
636
 
 
637
                check_invalid_methods("int", &val);
 
638
                check_write_read(&val);
 
639
                check_copy(&val);
 
640
                avro_value_decref(&val);
 
641
        }
 
642
 
 
643
        avro_value_t  val1;
 
644
        avro_value_t  val2;
 
645
        try(avro_generic_int_new(&val1, -10),
 
646
            "Cannot create int");
 
647
        try(avro_generic_int_new(&val2, 42),
 
648
            "Cannot create int");
 
649
        if (avro_value_cmp_fast(&val1, &val2) >= 0) {
 
650
                fprintf(stderr, "Incorrect sort order\n");
 
651
                return EXIT_FAILURE;
 
652
        }
 
653
        if (avro_value_cmp_fast(&val2, &val1) <= 0) {
 
654
                fprintf(stderr, "Incorrect sort order\n");
 
655
                return EXIT_FAILURE;
 
656
        }
 
657
        if (avro_value_cmp_fast(&val1, &val1) != 0) {
 
658
                fprintf(stderr, "Incorrect sort order\n");
 
659
                return EXIT_FAILURE;
 
660
        }
 
661
        avro_value_decref(&val1);
 
662
        avro_value_decref(&val2);
 
663
 
 
664
        return 0;
 
665
}
 
666
 
 
667
static int
 
668
test_long(void)
 
669
{
 
670
        int  rval;
 
671
 
 
672
        int  i;
 
673
        for (i = 0; i < 100; i++) {
 
674
                int64_t  expected = rand_int64();
 
675
                avro_value_t  val;
 
676
                try(avro_generic_long_new(&val, expected),
 
677
                    "Cannot create long");
 
678
                check(rval, check_type_and_schema
 
679
                            ("long", &val,
 
680
                             AVRO_INT64, avro_schema_long()));
 
681
                try(avro_value_reset(&val),
 
682
                    "Cannot reset long");
 
683
                try(avro_value_set_long(&val, expected),
 
684
                    "Cannot set long");
 
685
 
 
686
                int64_t  actual = 0;
 
687
                try(avro_value_get_long(&val, &actual),
 
688
                    "Cannot get long value");
 
689
 
 
690
                if (actual != expected) {
 
691
                        fprintf(stderr, "Unexpected long value\n");
 
692
                        return EXIT_FAILURE;
 
693
                }
 
694
 
 
695
                check_invalid_methods("long", &val);
 
696
                check_write_read(&val);
 
697
                check_copy(&val);
 
698
                avro_value_decref(&val);
 
699
        }
 
700
        return 0;
 
701
}
 
702
 
 
703
static int
 
704
test_null(void)
 
705
{
 
706
        int  rval;
 
707
 
 
708
        avro_value_t  val;
 
709
        try(avro_generic_null_new(&val),
 
710
            "Cannot create null");
 
711
        check(rval, check_type_and_schema
 
712
                    ("null", &val,
 
713
                     AVRO_NULL, avro_schema_null()));
 
714
        try(avro_value_reset(&val),
 
715
            "Cannot reset null");
 
716
        try(avro_value_set_null(&val),
 
717
            "Cannot set null");
 
718
        try(avro_value_get_null(&val),
 
719
            "Cannot get null");
 
720
 
 
721
        check_invalid_methods("null", &val);
 
722
        check_write_read(&val);
 
723
        check_copy(&val);
 
724
        avro_value_decref(&val);
 
725
        return 0;
 
726
}
 
727
 
 
728
static int
 
729
test_string(void)
 
730
{
 
731
        int  rval;
 
732
 
 
733
        char *strings[] = {
 
734
                "Four score and seven years ago",
 
735
                "our father brought forth on this continent",
 
736
                "a new nation",
 
737
                "conceived in Liberty",
 
738
                "and dedicated to the proposition that all men "
 
739
                        "are created equal."
 
740
        };
 
741
 
 
742
        unsigned int  i;
 
743
        for (i = 0; i < sizeof(strings) / sizeof(strings[0]); i++) {
 
744
                avro_value_t  val;
 
745
                try(avro_generic_string_new(&val, strings[i]),
 
746
                    "Cannot create string");
 
747
                check(rval, check_type_and_schema
 
748
                            ("string", &val,
 
749
                             AVRO_STRING, avro_schema_string()));
 
750
                try(avro_value_reset(&val),
 
751
                    "Cannot reset string");
 
752
                try(avro_value_set_string_len(&val, "", 0),
 
753
                    "Cannot set_len dummy string");
 
754
 
 
755
                /* First try a round-trip using set_string */
 
756
 
 
757
                try(avro_value_set_string(&val, strings[i]),
 
758
                    "Cannot set string");
 
759
 
 
760
                const char  *actual_str = NULL;
 
761
                size_t  actual_size = 0;
 
762
                try(avro_value_get_string(&val, &actual_str, &actual_size),
 
763
                    "Cannot get string value");
 
764
 
 
765
                if (actual_size != strlen(strings[i])+1) {
 
766
                        fprintf(stderr, "Unexpected string size\n");
 
767
                        return EXIT_FAILURE;
 
768
                }
 
769
 
 
770
                if (strcmp(actual_str, strings[i]) != 0) {
 
771
                        fprintf(stderr, "Unexpected string contents\n");
 
772
                        return EXIT_FAILURE;
 
773
                }
 
774
 
 
775
                avro_wrapped_buffer_t  wbuf;
 
776
                try(avro_value_grab_string(&val, &wbuf),
 
777
                    "Cannot grab string value");
 
778
 
 
779
                if (wbuf.size != strlen(strings[i])+1) {
 
780
                        fprintf(stderr, "Unexpected grabbed string size\n");
 
781
                        return EXIT_FAILURE;
 
782
                }
 
783
 
 
784
                if (strcmp((const char *) wbuf.buf, strings[i]) != 0) {
 
785
                        fprintf(stderr, "Unexpected grabbed string contents\n");
 
786
                        return EXIT_FAILURE;
 
787
                }
 
788
 
 
789
                avro_wrapped_buffer_free(&wbuf);
 
790
 
 
791
                /* and then again using set_string_len */
 
792
 
 
793
                size_t  str_length = strlen(strings[i])+1;
 
794
                try(avro_value_set_string_len(&val, strings[i], str_length),
 
795
                    "Cannot set_len string");
 
796
 
 
797
                actual_str = NULL;
 
798
                actual_size = 0;
 
799
                try(avro_value_get_string(&val, &actual_str, &actual_size),
 
800
                    "Cannot get string value");
 
801
 
 
802
                if (actual_size != strlen(strings[i])+1) {
 
803
                        fprintf(stderr, "Unexpected string size\n");
 
804
                        return EXIT_FAILURE;
 
805
                }
 
806
 
 
807
                if (strcmp(actual_str, strings[i]) != 0) {
 
808
                        fprintf(stderr, "Unexpected string contents\n");
 
809
                        return EXIT_FAILURE;
 
810
                }
 
811
 
 
812
                try(avro_value_grab_string(&val, &wbuf),
 
813
                    "Cannot grab string value");
 
814
 
 
815
                if (wbuf.size != strlen(strings[i])+1) {
 
816
                        fprintf(stderr, "Unexpected grabbed string size\n");
 
817
                        return EXIT_FAILURE;
 
818
                }
 
819
 
 
820
                if (strcmp((const char *) wbuf.buf, strings[i]) != 0) {
 
821
                        fprintf(stderr, "Unexpected grabbed string contents\n");
 
822
                        return EXIT_FAILURE;
 
823
                }
 
824
 
 
825
                avro_wrapped_buffer_free(&wbuf);
 
826
 
 
827
                check_invalid_methods("string", &val);
 
828
                check_write_read(&val);
 
829
                check_copy(&val);
 
830
                avro_value_decref(&val);
 
831
        }
 
832
 
 
833
        return 0;
 
834
}
 
835
 
 
836
static int
 
837
test_array(void)
 
838
{
 
839
        avro_schema_t  double_schema = avro_schema_double();
 
840
        avro_schema_t  array_schema = avro_schema_array(double_schema);
 
841
 
 
842
        avro_value_iface_t  *array_class =
 
843
            avro_generic_class_from_schema(array_schema);
 
844
 
 
845
        int  rval;
 
846
 
 
847
        int  i;
 
848
        for (i = 0; i < 100; i++) {
 
849
                size_t  count = rand_count();
 
850
 
 
851
                avro_value_t  val;
 
852
                try(avro_generic_value_new(array_class, &val),
 
853
                    "Cannot create array");
 
854
                check(rval, check_type_and_schema
 
855
                            ("array", &val, AVRO_ARRAY,
 
856
                             avro_schema_incref(array_schema)));
 
857
 
 
858
                size_t  j;
 
859
                for (j = 0; j < count; j++) {
 
860
                        avro_value_t  element;
 
861
                        size_t  new_index;
 
862
                        try(avro_value_append(&val, &element, &new_index),
 
863
                            "Cannot append to array");
 
864
                        if (new_index != j) {
 
865
                                fprintf(stderr, "Unexpected index\n");
 
866
                                return EXIT_FAILURE;
 
867
                        }
 
868
 
 
869
                        double  expected = rand_number(-1e10, 1e10);
 
870
                        try(avro_value_set_double(&element, expected),
 
871
                            "Cannot set double");
 
872
                        try(avro_value_get_by_index(&val, j, &element, NULL),
 
873
                            "Cannot get from array");
 
874
 
 
875
                        double  actual = 0.0;
 
876
                        try(avro_value_get_double(&element, &actual),
 
877
                            "Cannot get double value");
 
878
 
 
879
                        if (actual != expected) {
 
880
                                fprintf(stderr, "Unexpected double value\n");
 
881
                                return EXIT_FAILURE;
 
882
                        }
 
883
                }
 
884
 
 
885
                size_t  actual_size = 0;
 
886
                try(avro_value_get_size(&val, &actual_size),
 
887
                    "Cannot get_size array");
 
888
 
 
889
                if (actual_size != count) {
 
890
                        fprintf(stderr, "Unexpected size\n");
 
891
                        return EXIT_FAILURE;
 
892
                }
 
893
 
 
894
                check_write_read(&val);
 
895
                check_copy(&val);
 
896
 
 
897
                try(avro_value_reset(&val),
 
898
                    "Cannot reset array");
 
899
                try(avro_value_get_size(&val, &actual_size),
 
900
                    "Cannot get_size empty array");
 
901
 
 
902
                if (actual_size != 0) {
 
903
                        fprintf(stderr, "Unexpected empty size\n");
 
904
                        return EXIT_FAILURE;
 
905
                }
 
906
 
 
907
                check_invalid_methods("array", &val);
 
908
                avro_value_decref(&val);
 
909
        }
 
910
 
 
911
        avro_schema_decref(double_schema);
 
912
        avro_schema_decref(array_schema);
 
913
        avro_value_iface_decref(array_class);
 
914
        return 0;
 
915
}
 
916
 
 
917
static int
 
918
test_enum(void)
 
919
{
 
920
        static const char  SCHEMA_JSON[] =
 
921
        "{"
 
922
        "  \"type\": \"enum\","
 
923
        "  \"name\": \"suits\","
 
924
        "  \"symbols\": [\"CLUBS\",\"DIAMONDS\",\"HEARTS\",\"SPADES\"]"
 
925
        "}";
 
926
 
 
927
        avro_schema_t  enum_schema = NULL;
 
928
        if (avro_schema_from_json_literal(SCHEMA_JSON, &enum_schema)) {
 
929
                fprintf(stderr, "Error parsing schema:\n  %s\n",
 
930
                        avro_strerror());
 
931
                return EXIT_FAILURE;
 
932
        }
 
933
 
 
934
        avro_value_iface_t  *enum_class =
 
935
            avro_generic_class_from_schema(enum_schema);
 
936
 
 
937
        int  rval;
 
938
 
 
939
        int  i;
 
940
        for (i = 0; i < 4; i++) {
 
941
                int  expected = i;
 
942
                avro_value_t  val;
 
943
                try(avro_generic_value_new(enum_class, &val),
 
944
                    "Cannot create enum");
 
945
                check(rval, check_type_and_schema
 
946
                            ("enum", &val, AVRO_ENUM,
 
947
                             avro_schema_incref(enum_schema)));
 
948
                try(avro_value_reset(&val),
 
949
                    "Cannot reset enum");
 
950
                try(avro_value_set_enum(&val, expected),
 
951
                    "Cannot set enum");
 
952
 
 
953
                int  actual = -1;
 
954
                try(avro_value_get_enum(&val, &actual),
 
955
                    "Cannot get enum value");
 
956
 
 
957
                if (actual != expected) {
 
958
                        fprintf(stderr, "Unexpected enum value\n");
 
959
                        return EXIT_FAILURE;
 
960
                }
 
961
 
 
962
                check_invalid_methods("enum", &val);
 
963
                check_write_read(&val);
 
964
                check_copy(&val);
 
965
                avro_value_decref(&val);
 
966
        }
 
967
 
 
968
        avro_schema_decref(enum_schema);
 
969
        avro_value_iface_decref(enum_class);
 
970
        return 0;
 
971
}
 
972
 
 
973
static int
 
974
test_fixed(void)
 
975
{
 
976
        static const char  SCHEMA_JSON[] =
 
977
        "{"
 
978
        "  \"type\": \"fixed\","
 
979
        "  \"name\": \"ipv4\","
 
980
        "  \"size\": 4"
 
981
        "}";
 
982
 
 
983
        avro_schema_t  fixed_schema = NULL;
 
984
        if (avro_schema_from_json_literal(SCHEMA_JSON, &fixed_schema)) {
 
985
                fprintf(stderr, "Error parsing schema:\n  %s\n",
 
986
                        avro_strerror());
 
987
                return EXIT_FAILURE;
 
988
        }
 
989
 
 
990
        avro_value_iface_t  *fixed_class =
 
991
            avro_generic_class_from_schema(fixed_schema);
 
992
 
 
993
        int  rval;
 
994
 
 
995
        char fixed[] = { 0xDE, 0xAD, 0xBE, 0xEF };
 
996
 
 
997
        avro_value_t  val;
 
998
        try(avro_generic_value_new(fixed_class, &val),
 
999
            "Cannot create fixed");
 
1000
        check(rval, check_type_and_schema
 
1001
                    ("fixed", &val, AVRO_FIXED,
 
1002
                     avro_schema_incref(fixed_schema)));
 
1003
        try(avro_value_reset(&val),
 
1004
            "Cannot reset fixed");
 
1005
 
 
1006
        /* verify an error on invalid size */
 
1007
        try(!avro_value_set_fixed(&val, fixed, 0),
 
1008
            "Expected error with invalid size");
 
1009
 
 
1010
        try(avro_value_set_fixed(&val, fixed, sizeof(fixed)),
 
1011
            "Cannot set fixed");
 
1012
 
 
1013
        const void  *actual_buf = NULL;
 
1014
        size_t  actual_size = 0;
 
1015
        try(avro_value_get_fixed(&val, &actual_buf, &actual_size),
 
1016
            "Cannot get fixed value");
 
1017
 
 
1018
        if (actual_size != sizeof(fixed)) {
 
1019
                fprintf(stderr, "Unexpected fixed size\n");
 
1020
                return EXIT_FAILURE;
 
1021
        }
 
1022
 
 
1023
        if (memcmp(actual_buf, fixed, sizeof(fixed)) != 0) {
 
1024
                fprintf(stderr, "Unexpected fixed contents\n");
 
1025
                return EXIT_FAILURE;
 
1026
        }
 
1027
 
 
1028
        avro_wrapped_buffer_t  wbuf;
 
1029
        try(avro_value_grab_fixed(&val, &wbuf),
 
1030
            "Cannot grab fixed value");
 
1031
 
 
1032
        if (wbuf.size != sizeof(fixed)) {
 
1033
                fprintf(stderr, "Unexpected grabbed fixed size\n");
 
1034
                return EXIT_FAILURE;
 
1035
        }
 
1036
 
 
1037
        if (memcmp(wbuf.buf, fixed, sizeof(fixed)) != 0) {
 
1038
                fprintf(stderr, "Unexpected grabbed fixed contents\n");
 
1039
                return EXIT_FAILURE;
 
1040
        }
 
1041
 
 
1042
        avro_wrapped_buffer_free(&wbuf);
 
1043
 
 
1044
        check_invalid_methods("fixed", &val);
 
1045
        check_write_read(&val);
 
1046
        check_copy(&val);
 
1047
        avro_value_decref(&val);
 
1048
        avro_schema_decref(fixed_schema);
 
1049
        avro_value_iface_decref(fixed_class);
 
1050
        return 0;
 
1051
}
 
1052
 
 
1053
static int
 
1054
test_map(void)
 
1055
{
 
1056
        avro_schema_t  double_schema = avro_schema_double();
 
1057
        avro_schema_t  map_schema = avro_schema_map(double_schema);
 
1058
 
 
1059
        avro_value_iface_t  *map_class =
 
1060
            avro_generic_class_from_schema(map_schema);
 
1061
 
 
1062
        int  rval;
 
1063
 
 
1064
        int  i;
 
1065
        for (i = 0; i < 100; i++) {
 
1066
                size_t  count = rand_count();
 
1067
 
 
1068
                avro_value_t  val;
 
1069
                try(avro_generic_value_new(map_class, &val),
 
1070
                    "Cannot create map");
 
1071
                check(rval, check_type_and_schema
 
1072
                            ("map", &val, AVRO_MAP,
 
1073
                             avro_schema_incref(map_schema)));
 
1074
 
 
1075
                size_t  j;
 
1076
                for (j = 0; j < count; j++) {
 
1077
                        avro_value_t  element;
 
1078
                        size_t  new_index;
 
1079
                        int  is_new = 0;
 
1080
 
 
1081
                        char  key[64];
 
1082
                        snprintf(key, 64, "%" PRIsz, j);
 
1083
 
 
1084
                        try(avro_value_add(&val, key,
 
1085
                                           &element, &new_index, &is_new),
 
1086
                            "Cannot add to map");
 
1087
 
 
1088
                        if (new_index != j) {
 
1089
                                fprintf(stderr, "Unexpected index\n");
 
1090
                                return EXIT_FAILURE;
 
1091
                        }
 
1092
 
 
1093
                        if (!is_new) {
 
1094
                                fprintf(stderr, "Expected new element\n");
 
1095
                                return EXIT_FAILURE;
 
1096
                        }
 
1097
 
 
1098
                        double  expected = rand_number(-1e10, 1e10);
 
1099
                        try(avro_value_set_double(&element, expected),
 
1100
                            "Cannot set double");
 
1101
                        try(avro_value_add(&val, key,
 
1102
                                           &element, &new_index, &is_new),
 
1103
                            "Cannot re-add to map");
 
1104
 
 
1105
                        if (is_new) {
 
1106
                                fprintf(stderr, "Expected non-new element\n");
 
1107
                                return EXIT_FAILURE;
 
1108
                        }
 
1109
 
 
1110
                        const char  *actual_key = NULL;
 
1111
                        try(avro_value_get_by_index(&val, j, &element,
 
1112
                                                    &actual_key),
 
1113
                            "Cannot get from map");
 
1114
 
 
1115
                        if (strcmp(actual_key, key) != 0) {
 
1116
                                fprintf(stderr, "Unexpected key\n");
 
1117
                                return EXIT_FAILURE;
 
1118
                        }
 
1119
 
 
1120
                        double  actual = 0.0;
 
1121
                        try(avro_value_get_double(&element, &actual),
 
1122
                            "Cannot get double value");
 
1123
 
 
1124
                        if (actual != expected) {
 
1125
                                fprintf(stderr, "Unexpected double value\n");
 
1126
                                return EXIT_FAILURE;
 
1127
                        }
 
1128
                }
 
1129
 
 
1130
                size_t  actual_size = 0;
 
1131
                try(avro_value_get_size(&val, &actual_size),
 
1132
                    "Cannot get_size map");
 
1133
 
 
1134
                if (actual_size != count) {
 
1135
                        fprintf(stderr, "Unexpected size\n");
 
1136
                        return EXIT_FAILURE;
 
1137
                }
 
1138
 
 
1139
                /*
 
1140
                 * Create a reversed copy of the map to ensure that the
 
1141
                 * element ordering doesn't affect the hash value.
 
1142
                 */
 
1143
 
 
1144
                avro_value_t  reversed;
 
1145
                try(avro_generic_value_new(map_class, &reversed),
 
1146
                    "Cannot create map");
 
1147
 
 
1148
                for (j = count; j-- > 0; ) {
 
1149
                        avro_value_t  element;
 
1150
                        const char  *key = NULL;
 
1151
                        double  element_value = 0.0;
 
1152
                        try(avro_value_get_by_index(&val, j, &element, &key),
 
1153
                            "Cannot get from map");
 
1154
                        try(avro_value_get_double(&element, &element_value),
 
1155
                            "Cannot get double value");
 
1156
 
 
1157
                        try(avro_value_add(&reversed, key, &element, NULL, NULL),
 
1158
                            "Cannot add to map");
 
1159
                        try(avro_value_set_double(&element, element_value),
 
1160
                            "Cannot set double");
 
1161
                }
 
1162
 
 
1163
                check_hash(&val, &reversed);
 
1164
                if (!avro_value_equal(&val, &reversed)) {
 
1165
                        fprintf(stderr, "Reversed values not equal\n");
 
1166
                        return EXIT_FAILURE;
 
1167
                }
 
1168
 
 
1169
                /* Final tests and cleanup */
 
1170
 
 
1171
                check_write_read(&val);
 
1172
                check_copy(&val);
 
1173
 
 
1174
                try(avro_value_reset(&val),
 
1175
                    "Cannot reset map");
 
1176
                try(avro_value_get_size(&val, &actual_size),
 
1177
                    "Cannot get_size empty map");
 
1178
 
 
1179
                if (actual_size != 0) {
 
1180
                        fprintf(stderr, "Unexpected empty size\n");
 
1181
                        return EXIT_FAILURE;
 
1182
                }
 
1183
 
 
1184
                check_invalid_methods("map", &val);
 
1185
                avro_value_decref(&val);
 
1186
                avro_value_decref(&reversed);
 
1187
        }
 
1188
 
 
1189
        avro_schema_decref(double_schema);
 
1190
        avro_schema_decref(map_schema);
 
1191
        avro_value_iface_decref(map_class);
 
1192
        return 0;
 
1193
}
 
1194
 
 
1195
static int
 
1196
test_record(void)
 
1197
{
 
1198
        static const char  SCHEMA_JSON[] =
 
1199
        "{"
 
1200
        "  \"type\": \"record\","
 
1201
        "  \"name\": \"test\","
 
1202
        "  \"fields\": ["
 
1203
        "    { \"name\": \"b\", \"type\": \"boolean\" },"
 
1204
        "    { \"name\": \"i\", \"type\": \"int\" },"
 
1205
        "    { \"name\": \"s\", \"type\": \"string\" },"
 
1206
        "    { \"name\": \"ds\", \"type\": "
 
1207
        "      { \"type\": \"array\", \"items\": \"double\" } },"
 
1208
        "    { \"name\": \"sub\", \"type\": "
 
1209
        "      {"
 
1210
        "        \"type\": \"record\","
 
1211
        "        \"name\": \"subtest\","
 
1212
        "        \"fields\": ["
 
1213
        "          { \"name\": \"f\", \"type\": \"float\" },"
 
1214
        "          { \"name\": \"l\", \"type\": \"long\" }"
 
1215
        "        ]"
 
1216
        "      }"
 
1217
        "    },"
 
1218
        "    { \"name\": \"nested\", \"type\": [\"null\", \"test\"] }"
 
1219
        "  ]"
 
1220
        "}";
 
1221
 
 
1222
        avro_schema_t  record_schema = NULL;
 
1223
        if (avro_schema_from_json_literal(SCHEMA_JSON, &record_schema)) {
 
1224
                fprintf(stderr, "Error parsing schema:\n  %s\n",
 
1225
                        avro_strerror());
 
1226
                return EXIT_FAILURE;
 
1227
        }
 
1228
 
 
1229
        avro_value_iface_t  *record_class =
 
1230
            avro_generic_class_from_schema(record_schema);
 
1231
 
 
1232
        int  rval;
 
1233
 
 
1234
        avro_value_t  val;
 
1235
        try(avro_generic_value_new(record_class, &val),
 
1236
            "Cannot create record");
 
1237
        check(rval, check_type_and_schema
 
1238
                    ("record", &val, AVRO_RECORD,
 
1239
                     avro_schema_incref(record_schema)));
 
1240
 
 
1241
        size_t  field_count;
 
1242
        try(avro_value_get_size(&val, &field_count),
 
1243
            "Cannot get field count");
 
1244
        if (field_count != 6) {
 
1245
                fprintf(stderr, "Unexpected field count\n");
 
1246
                return EXIT_FAILURE;
 
1247
        }
 
1248
 
 
1249
        /* Assign to each field */
 
1250
        avro_value_t  field;
 
1251
        avro_value_t  element;
 
1252
        avro_value_t  subfield;
 
1253
        avro_value_t  branch;
 
1254
        const char  *name;
 
1255
        size_t  index;
 
1256
 
 
1257
        try(avro_value_get_by_index(&val, 0, &field, NULL),
 
1258
            "Cannot get field 0");
 
1259
        try(avro_value_set_boolean(&field, 1),
 
1260
            "Cannot set field 0");
 
1261
 
 
1262
        try(avro_value_get_by_index(&val, 1, &field, &name),
 
1263
            "Cannot get field 1");
 
1264
        try(avro_value_set_int(&field, 42),
 
1265
            "Cannot set field 1");
 
1266
        if (strcmp(name, "i") != 0) {
 
1267
                fprintf(stderr, "Unexpected name for field 1: %s\n", name);
 
1268
                return EXIT_FAILURE;
 
1269
        }
 
1270
 
 
1271
        try(avro_value_get_by_index(&val, 2, &field, NULL),
 
1272
            "Cannot get field 2");
 
1273
        try(avro_value_set_string(&field, "Hello world!"),
 
1274
            "Cannot set field 2");
 
1275
 
 
1276
        try(avro_value_get_by_name(&val, "i", &field, &index),
 
1277
            "Cannot get \"i\" field");
 
1278
        if (index != 1) {
 
1279
                fprintf(stderr, "Unexpected index for \"i\" field: %" PRIsz "\n", index);
 
1280
                return EXIT_FAILURE;
 
1281
        }
 
1282
 
 
1283
        try(avro_value_get_by_index(&val, 3, &field, NULL),
 
1284
            "Cannot get field 3");
 
1285
        try(avro_value_append(&field, &element, NULL),
 
1286
            "Cannot append to field 3");
 
1287
        try(avro_value_set_double(&element, 10.0),
 
1288
            "Cannot set field 3, element 0");
 
1289
 
 
1290
        try(avro_value_get_by_index(&val, 4, &field, NULL),
 
1291
            "Cannot get field 4");
 
1292
 
 
1293
        try(avro_value_get_by_index(&field, 0, &subfield, NULL),
 
1294
            "Cannot get field 4, subfield 0");
 
1295
        try(avro_value_set_float(&subfield, 5.0f),
 
1296
            "Cannot set field 4, subfield 0");
 
1297
 
 
1298
        try(avro_value_get_by_index(&field, 1, &subfield, NULL),
 
1299
            "Cannot get field 4, subfield 1");
 
1300
        try(avro_value_set_long(&subfield, 10000),
 
1301
            "Cannot set field 4, subfield 1");
 
1302
 
 
1303
        try(avro_value_get_by_index(&val, 5, &field, NULL),
 
1304
            "Cannot get field 5");
 
1305
        try(avro_value_set_branch(&field, 0, &branch),
 
1306
            "Cannot select null branch");
 
1307
 
 
1308
        check_write_read(&val);
 
1309
        check_copy(&val);
 
1310
 
 
1311
        /* Reset and verify that the fields are empty again */
 
1312
        try(avro_value_reset(&val),
 
1313
            "Cannot reset record");
 
1314
 
 
1315
        int  bval;
 
1316
        try(avro_value_get_by_index(&val, 0, &field, NULL),
 
1317
            "Cannot get field 0");
 
1318
        try(avro_value_get_boolean(&field, &bval),
 
1319
            "Cannot get field 0 value");
 
1320
        if (bval) {
 
1321
                fprintf(stderr, "Unexpected value for field 0\n");
 
1322
                return EXIT_FAILURE;
 
1323
        }
 
1324
 
 
1325
        size_t  count;
 
1326
        try(avro_value_get_by_index(&val, 3, &field, NULL),
 
1327
            "Cannot get field 3");
 
1328
        try(avro_value_get_size(&field, &count),
 
1329
            "Cannot get field 3 size");
 
1330
        if (count != 0) {
 
1331
                fprintf(stderr, "Unexpected size for field 3\n");
 
1332
                return EXIT_FAILURE;
 
1333
        }
 
1334
 
 
1335
        check_invalid_methods("record", &val);
 
1336
        avro_value_decref(&val);
 
1337
        avro_value_iface_decref(record_class);
 
1338
        avro_schema_decref(record_schema);
 
1339
        return EXIT_SUCCESS;
 
1340
}
 
1341
 
 
1342
static int
 
1343
test_union(void)
 
1344
{
 
1345
        static const char  SCHEMA_JSON[] =
 
1346
        "["
 
1347
        "  \"null\","
 
1348
        "  \"int\","
 
1349
        "  \"double\","
 
1350
        "  \"bytes\""
 
1351
        "]";
 
1352
 
 
1353
        avro_schema_t  union_schema = NULL;
 
1354
        if (avro_schema_from_json_literal(SCHEMA_JSON, &union_schema)) {
 
1355
                fprintf(stderr, "Error parsing schema:\n  %s\n",
 
1356
                        avro_strerror());
 
1357
                return EXIT_FAILURE;
 
1358
        }
 
1359
 
 
1360
        avro_value_iface_t  *union_class =
 
1361
            avro_generic_class_from_schema(union_schema);
 
1362
 
 
1363
        int  rval;
 
1364
 
 
1365
        avro_value_t  val;
 
1366
        try(avro_generic_value_new(union_class, &val),
 
1367
            "Cannot create union");
 
1368
        check(rval, check_type_and_schema
 
1369
                    ("union", &val, AVRO_UNION,
 
1370
                     avro_schema_incref(union_schema)));
 
1371
 
 
1372
        int discriminant = 0;
 
1373
        try(avro_value_get_discriminant(&val, &discriminant),
 
1374
            "Cannot get union discriminant");
 
1375
 
 
1376
        if (discriminant != -1) {
 
1377
                fprintf(stderr, "Unexpected union discriminant\n");
 
1378
                return EXIT_FAILURE;
 
1379
        }
 
1380
 
 
1381
        avro_value_t  branch;
 
1382
        try(!avro_value_get_current_branch(&val, &branch),
 
1383
            "Expected error getting empty current branch");
 
1384
 
 
1385
        try(avro_value_set_branch(&val, 0, &branch),
 
1386
            "Cannot select null branch");
 
1387
        try(avro_value_set_null(&branch),
 
1388
            "Cannot set null branch value");
 
1389
 
 
1390
        try(avro_value_set_branch(&val, 1, &branch),
 
1391
            "Cannot select int branch");
 
1392
        try(avro_value_set_int(&branch, 42),
 
1393
            "Cannot set int branch value");
 
1394
 
 
1395
        try(avro_value_set_branch(&val, 1, &branch),
 
1396
            "Cannot select int branch");
 
1397
        try(avro_value_set_int(&branch, 10),
 
1398
            "Cannot set int branch value");
 
1399
 
 
1400
        try(avro_value_set_branch(&val, 2, &branch),
 
1401
            "Cannot select double branch");
 
1402
        try(avro_value_set_double(&branch, 10.0),
 
1403
            "Cannot set double branch value");
 
1404
 
 
1405
        char bytes[] = { 0xDE, 0xAD, 0xBE, 0xEF };
 
1406
        try(avro_value_set_branch(&val, 3, &branch),
 
1407
            "Cannot select bytes branch");
 
1408
        try(avro_value_set_bytes(&branch, bytes, sizeof(bytes)),
 
1409
            "Cannot set bytes branch value");
 
1410
 
 
1411
        check_invalid_methods("union", &val);
 
1412
        check_write_read(&val);
 
1413
        check_copy(&val);
 
1414
        avro_value_decref(&val);
 
1415
 
 
1416
        avro_schema_decref(union_schema);
 
1417
        avro_value_iface_decref(union_class);
 
1418
        return 0;
 
1419
}
 
1420
 
 
1421
int main(void)
 
1422
{
 
1423
        avro_set_allocator(test_allocator, NULL);
 
1424
 
 
1425
        unsigned int i;
 
1426
        struct avro_tests {
 
1427
                char *name;
 
1428
                avro_test func;
 
1429
        } tests[] = {
 
1430
                { "boolean", test_boolean },
 
1431
                { "bytes", test_bytes },
 
1432
                { "double", test_double },
 
1433
                { "float", test_float },
 
1434
                { "int", test_int },
 
1435
                { "long", test_long },
 
1436
                { "null", test_null },
 
1437
                { "string", test_string },
 
1438
                { "array", test_array },
 
1439
                { "enum", test_enum },
 
1440
                { "fixed", test_fixed },
 
1441
                { "map", test_map },
 
1442
                { "record", test_record },
 
1443
                { "union", test_union }
 
1444
        };
 
1445
 
 
1446
        init_rand();
 
1447
        for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
 
1448
                struct avro_tests *test = tests + i;
 
1449
                fprintf(stderr, "**** Running %s tests ****\n", test->name);
 
1450
                if (test->func() != 0) {
 
1451
                        return EXIT_FAILURE;
 
1452
                }
 
1453
        }
 
1454
        return EXIT_SUCCESS;
 
1455
}