Added: avro/trunk/lang/c/tests/test_avro_values.c
URL: 
http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/test_avro_values.c?rev=1146546&view=auto
==============================================================================
--- avro/trunk/lang/c/tests/test_avro_values.c (added)
+++ avro/trunk/lang/c/tests/test_avro_values.c Thu Jul 14 02:35:04 2011
@@ -0,0 +1,1338 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.  See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+/* Test cases for the new avro_value_t interface */
+
+#include <inttypes.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "avro.h"
+#include "avro/allocation.h"
+#include "avro/data.h"
+#include "avro/generic.h"
+#include "avro/value.h"
+#include "avro_private.h"
+
+typedef int (*avro_test) (void);
+
+#ifndef SHOW_ALLOCATIONS
+#define SHOW_ALLOCATIONS 0
+#endif
+
+/*
+ * Use a custom allocator that verifies that the size that we use to
+ * free an object matches the size that we use to allocate it.
+ */
+
+static void *
+test_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
+{
+       AVRO_UNUSED(ud);
+       AVRO_UNUSED(osize);
+
+#if SHOW_ALLOCATIONS
+       fprintf(stderr, "alloc(%p, %zu, %zu) => ", ptr, osize, nsize);
+#endif
+
+       if (nsize == 0) {
+               size_t  *size = ((size_t *) ptr) - 1;
+               if (osize != *size) {
+                       fprintf(stderr,
+#if SHOW_ALLOCATIONS
+                               "ERROR!\n"
+#endif
+                               "Error freeing %p:\n"
+                               "Size passed to avro_free (%zu) "
+                               "doesn't match size passed to "
+                               "avro_malloc (%zu)\n",
+                               ptr, osize, *size);
+                       exit(EXIT_FAILURE);
+               }
+               free(size);
+#if SHOW_ALLOCATIONS
+               fprintf(stderr, "NULL\n");
+#endif
+               return NULL;
+       } else {
+               size_t  real_size = nsize + sizeof(size_t);
+               size_t  *old_size = ptr? ((size_t *) ptr)-1: NULL;
+               size_t  *size = realloc(old_size, real_size);
+               *size = nsize;
+#if SHOW_ALLOCATIONS
+               fprintf(stderr, "%p\n", (size+1));
+#endif
+               return (size + 1);
+       }
+}
+
+void
+init_rand(void)
+{
+       srand(time(NULL));
+}
+
+double
+rand_number(double from, double to)
+{
+       double range = to - from;
+       return from + ((double)rand() / (RAND_MAX + 1.0)) * range;
+}
+
+int64_t
+rand_int64(void)
+{
+       return (int64_t) rand_number(LONG_MIN, LONG_MAX);
+}
+
+int32_t
+rand_int32(void)
+{
+       return (int32_t) rand_number(INT_MIN, INT_MAX);
+}
+
+size_t
+rand_count(void)
+{
+       return (size_t) rand_number(0, 100);
+}
+
+#define check_(call) \
+       do { \
+               int _rval = call; \
+               if (_rval) { return _rval; } \
+       } while (0)
+
+/*
+ * Verify that we can't call any of the getters and setters that don't
+ * apply to the given value.
+ */
+
+static int
+_check_invalid_methods(const char *name, avro_value_t *val)
+{
+       avro_type_t  type = avro_value_get_type(val);
+
+#define check_bad(method, ...) \
+       do { \
+               if (!avro_value_##method(__VA_ARGS__)) { \
+                       fprintf(stderr, \
+                               "Shouldn't be able to " #method " a %s\n", \
+                               name); \
+                       return EXIT_FAILURE; \
+               } \
+       } while (0)
+
+       if (type != AVRO_BOOLEAN) {
+               bool  dummy = 0;
+               check_bad(get_boolean, val, &dummy);
+               check_bad(set_boolean, val, dummy);
+       }
+
+       if (type != AVRO_BYTES) {
+               const void  *cbuf = NULL;
+               void  *buf = NULL;
+               size_t  size = 0;
+               check_bad(get_bytes, val, &cbuf, &size);
+               check_bad(set_bytes, val, buf, size);
+       }
+
+       if (type != AVRO_DOUBLE) {
+               double  dummy = 0;
+               check_bad(get_double, val, &dummy);
+               check_bad(set_double, val, dummy);
+       }
+
+       if (type != AVRO_FLOAT) {
+               float  dummy = 0;
+               check_bad(get_float, val, &dummy);
+               check_bad(set_float, val, dummy);
+       }
+
+       if (type != AVRO_INT32) {
+               int32_t  dummy = 0;
+               check_bad(get_int, val, &dummy);
+               check_bad(set_int, val, dummy);
+       }
+
+       if (type != AVRO_INT64) {
+               int64_t  dummy = 0;
+               check_bad(get_long, val, &dummy);
+               check_bad(set_long, val, dummy);
+       }
+
+       if (type != AVRO_NULL) {
+               check_bad(get_null, val);
+               check_bad(set_null, val);
+       }
+
+       if (type != AVRO_STRING) {
+               const char  *cstr = NULL;
+               char  *str = NULL;
+               size_t  size = 0;
+               check_bad(get_string, val, &cstr, &size);
+               check_bad(set_string, val, str);
+               check_bad(set_string_len, val, str, size);
+       }
+
+       if (type != AVRO_ENUM) {
+               int  dummy = 0;
+               check_bad(get_enum, val, &dummy);
+               check_bad(set_enum, val, dummy);
+       }
+
+       if (type != AVRO_FIXED) {
+               const void  *cbuf = NULL;
+               void  *buf = NULL;
+               size_t  size = 0;
+               check_bad(get_fixed, val, &cbuf, &size);
+               check_bad(set_fixed, val, buf, size);
+       }
+
+       if (type != AVRO_ARRAY && type != AVRO_MAP && type != AVRO_RECORD) {
+               size_t  size = 0;
+               check_bad(get_size, val, &size);
+
+               size_t  index = 0;
+               avro_value_t  child;
+               const char  *key = NULL;
+               check_bad(get_by_index, val, index, &child, &key);
+       }
+
+       if (type != AVRO_MAP && type != AVRO_RECORD) {
+               const char  *key = NULL;
+               avro_value_t  child;
+               size_t  index = 0;
+               check_bad(get_by_name, val, key, &child, &index);
+       }
+
+       if (type != AVRO_ARRAY) {
+               avro_value_t  child;
+               size_t  index;
+               check_bad(append, val, &child, &index);
+       }
+
+       if (type != AVRO_MAP) {
+               const char  *key = NULL;
+               avro_value_t  child;
+               size_t  index = 0;
+               bool  is_new = false;
+               check_bad(add, val, key, &child, &index, &is_new);
+       }
+
+       if (type != AVRO_UNION) {
+               int  discriminant = 0;
+               avro_value_t  branch;
+               check_bad(get_discriminant, val, &discriminant);
+               check_bad(get_current_branch, val, &branch);
+               check_bad(set_branch, val, discriminant, &branch);
+       }
+
+#undef check_bad
+
+       return EXIT_SUCCESS;
+}
+
+#define check_invalid_methods(name, val) \
+       check_(_check_invalid_methods(name, val))
+
+/*
+ * Verify that we get the expected type code and schema for a value.
+ */
+
+static int
+check_type_and_schema(const char *name,
+                     avro_value_t *val,
+                     avro_type_t expected_type,
+                     avro_schema_t expected_schema)
+{
+       if (avro_value_get_type(val) != expected_type) {
+               avro_schema_decref(expected_schema);
+               fprintf(stderr, "Unexpected type for %s\n", name);
+               return EXIT_FAILURE;
+       }
+
+       if (!avro_schema_equal(avro_value_get_schema(val),
+                              expected_schema)) {
+               avro_schema_decref(expected_schema);
+               fprintf(stderr, "Unexpected schema for %s\n", name);
+               return EXIT_FAILURE;
+       }
+
+       avro_schema_decref(expected_schema);
+       return EXIT_SUCCESS;
+}
+
+#define try(call, msg) \
+       do { \
+               if (call) { \
+                       fprintf(stderr, msg ":\n  %s\n", avro_strerror()); \
+                       return EXIT_FAILURE; \
+               } \
+       } while (0)
+
+static int
+_check_write_read(avro_value_t *val)
+{
+       static char  buf[4096];
+
+       avro_reader_t  reader = avro_reader_memory(buf, sizeof(buf));
+       avro_writer_t  writer = avro_writer_memory(buf, sizeof(buf));
+
+       if (avro_value_write(writer, val)) {
+               fprintf(stderr, "Unable to write value:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       avro_writer_dump(writer, stderr);
+
+       size_t size;
+       if (avro_value_sizeof(val, &size)) {
+               fprintf(stderr, "Unable to determine size of value:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       if (size != (size_t) avro_writer_tell(writer)) {
+               fprintf(stderr, "Unexpected size of encoded value\n");
+               return EXIT_FAILURE;
+       }
+
+       avro_value_t  val_in;
+       if (avro_value_new(val->iface, &val_in)) {
+               fprintf(stderr, "Cannot allocate new value instance:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       if (avro_value_read(reader, &val_in)) {
+               fprintf(stderr, "Unable to read value:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       if (!avro_value_equal(val, &val_in)) {
+               fprintf(stderr, "Round-trip values not equal\n");
+               exit(EXIT_FAILURE);
+       }
+
+       avro_value_free(&val_in);
+       avro_reader_free(reader);
+       avro_writer_free(writer);
+
+       return EXIT_SUCCESS;
+}
+
+#define check_write_read(val) \
+       check_(_check_write_read(val))
+
+static int
+_check_copy(avro_value_t *val)
+{
+       avro_value_t  copied_val;
+       if (avro_value_new(val->iface, &copied_val)) {
+               fprintf(stderr, "Cannot allocate new value instance:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       if (avro_value_copy_fast(&copied_val, val)) {
+               fprintf(stderr, "Cannot copy value:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       if (!avro_value_equal(val, &copied_val)) {
+               fprintf(stderr, "Copied values not equal\n");
+               exit(EXIT_FAILURE);
+       }
+
+       avro_value_free(&copied_val);
+       return EXIT_SUCCESS;
+}
+
+#define check_copy(val) \
+       check_(_check_copy(val))
+
+static int
+test_boolean(void)
+{
+       int  rval;
+
+       int  i;
+       for (i = 0; i <= 1; i++) {
+               avro_value_t  val;
+               try(avro_generic_boolean_new(&val, i),
+                   "Cannot create boolean");
+               check(rval, check_type_and_schema
+                           ("boolean", &val,
+                            AVRO_BOOLEAN, avro_schema_boolean()));
+               try(avro_value_reset(&val),
+                   "Cannot reset boolean");
+               try(avro_value_set_boolean(&val, i),
+                   "Cannot set boolean");
+
+               /* Start with the wrong value to make sure _get does
+                * something. */
+               bool  actual = (bool) 23;
+               try(avro_value_get_boolean(&val, &actual),
+                   "Cannot get boolean value");
+
+               if (actual != i) {
+                       fprintf(stderr, "Unexpected boolean value\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_invalid_methods("boolean", &val);
+               check_write_read(&val);
+               check_copy(&val);
+               avro_value_free(&val);
+       }
+       return 0;
+}
+
+static int
+test_bytes(void)
+{
+       int  rval;
+
+       char bytes[] = { 0xDE, 0xAD, 0xBE, 0xEF };
+
+       avro_value_t  val;
+       try(avro_generic_bytes_new(&val, bytes, sizeof(bytes)),
+           "Cannot create bytes");
+       check(rval, check_type_and_schema
+                   ("bytes", &val,
+                    AVRO_BYTES, avro_schema_bytes()));
+       try(avro_value_reset(&val),
+           "Cannot reset bytes");
+       try(avro_value_set_bytes(&val, bytes, sizeof(bytes)),
+           "Cannot set bytes");
+
+       const void  *actual_buf = NULL;
+       size_t  actual_size = 0;
+       try(avro_value_get_bytes(&val, &actual_buf, &actual_size),
+           "Cannot get bytes value");
+
+       if (actual_size != sizeof(bytes)) {
+               fprintf(stderr, "Unexpected bytes size\n");
+               return EXIT_FAILURE;
+       }
+
+       if (memcmp(actual_buf, bytes, sizeof(bytes)) != 0) {
+               fprintf(stderr, "Unexpected bytes contents\n");
+               return EXIT_FAILURE;
+       }
+
+       avro_wrapped_buffer_t  wbuf;
+       try(avro_value_grab_bytes(&val, &wbuf),
+           "Cannot grab bytes value");
+
+       if (wbuf.size != sizeof(bytes)) {
+               fprintf(stderr, "Unexpected grabbed bytes size\n");
+               return EXIT_FAILURE;
+       }
+
+       if (memcmp(wbuf.buf, bytes, sizeof(bytes)) != 0) {
+               fprintf(stderr, "Unexpected grabbed bytes contents\n");
+               return EXIT_FAILURE;
+       }
+
+       avro_wrapped_buffer_free(&wbuf);
+
+       check_invalid_methods("bytes", &val);
+       check_write_read(&val);
+       check_copy(&val);
+       avro_value_free(&val);
+       return 0;
+}
+
+static int
+test_double(void)
+{
+       int  rval;
+
+       int  i;
+       for (i = 0; i < 100; i++) {
+               double  expected = rand_number(-1e10, 1e10);
+               avro_value_t  val;
+               try(avro_generic_double_new(&val, expected),
+                   "Cannot create double");
+               check(rval, check_type_and_schema
+                           ("double", &val,
+                            AVRO_DOUBLE, avro_schema_double()));
+               try(avro_value_reset(&val),
+                   "Cannot reset double");
+               try(avro_value_set_double(&val, expected),
+                   "Cannot set double");
+
+               double  actual = 0.0;
+               try(avro_value_get_double(&val, &actual),
+                   "Cannot get double value");
+
+               if (actual != expected) {
+                       fprintf(stderr, "Unexpected double value\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_invalid_methods("double", &val);
+               check_write_read(&val);
+               check_copy(&val);
+               avro_value_free(&val);
+       }
+       return 0;
+}
+
+static int
+test_float(void)
+{
+       int  rval;
+
+       int  i;
+       for (i = 0; i < 100; i++) {
+               float  expected = rand_number(-1e10, 1e10);
+               avro_value_t  val;
+               try(avro_generic_float_new(&val, expected),
+                   "Cannot create float");
+               check(rval, check_type_and_schema
+                           ("float", &val,
+                            AVRO_FLOAT, avro_schema_float()));
+               try(avro_value_reset(&val),
+                   "Cannot reset float");
+               try(avro_value_set_float(&val, expected),
+                   "Cannot set float");
+
+               float  actual = 0.0f;
+               try(avro_value_get_float(&val, &actual),
+                   "Cannot get float value");
+
+               if (actual != expected) {
+                       fprintf(stderr, "Unexpected float value\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_invalid_methods("float", &val);
+               check_write_read(&val);
+               check_copy(&val);
+               avro_value_free(&val);
+       }
+       return 0;
+}
+
+static int
+test_int(void)
+{
+       int  rval;
+
+       int  i;
+       for (i = 0; i < 100; i++) {
+               int32_t  expected = rand_int32();
+               avro_value_t  val;
+               try(avro_generic_int_new(&val, expected),
+                   "Cannot create int");
+               check(rval, check_type_and_schema
+                           ("int", &val,
+                            AVRO_INT32, avro_schema_int()));
+               try(avro_value_reset(&val),
+                   "Cannot reset int");
+               try(avro_value_set_int(&val, expected),
+                   "Cannot set int");
+
+               int32_t  actual = 0;
+               try(avro_value_get_int(&val, &actual),
+                   "Cannot get int value");
+
+               if (actual != expected) {
+                       fprintf(stderr, "Unexpected int value\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_invalid_methods("int", &val);
+               check_write_read(&val);
+               check_copy(&val);
+               avro_value_free(&val);
+       }
+       return 0;
+}
+
+static int
+test_long(void)
+{
+       int  rval;
+
+       int  i;
+       for (i = 0; i < 100; i++) {
+               int64_t  expected = rand_int64();
+               avro_value_t  val;
+               try(avro_generic_long_new(&val, expected),
+                   "Cannot create long");
+               check(rval, check_type_and_schema
+                           ("long", &val,
+                            AVRO_INT64, avro_schema_long()));
+               try(avro_value_reset(&val),
+                   "Cannot reset long");
+               try(avro_value_set_long(&val, expected),
+                   "Cannot set long");
+
+               int64_t  actual = 0;
+               try(avro_value_get_long(&val, &actual),
+                   "Cannot get long value");
+
+               if (actual != expected) {
+                       fprintf(stderr, "Unexpected long value\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_invalid_methods("long", &val);
+               check_write_read(&val);
+               check_copy(&val);
+               avro_value_free(&val);
+       }
+       return 0;
+}
+
+static int
+test_null(void)
+{
+       int  rval;
+
+       avro_value_t  val;
+       try(avro_generic_null_new(&val),
+           "Cannot create null");
+       check(rval, check_type_and_schema
+                   ("null", &val,
+                    AVRO_NULL, avro_schema_null()));
+       try(avro_value_reset(&val),
+           "Cannot reset null");
+       try(avro_value_set_null(&val),
+           "Cannot set null");
+       try(avro_value_get_null(&val),
+           "Cannot get null");
+
+       check_invalid_methods("null", &val);
+       check_write_read(&val);
+       check_copy(&val);
+       avro_value_free(&val);
+       return 0;
+}
+
+static int
+test_string(void)
+{
+       int  rval;
+
+       char *strings[] = {
+               "Four score and seven years ago",
+               "our father brought forth on this continent",
+               "a new nation",
+               "conceived in Liberty",
+               "and dedicated to the proposition that all men "
+                       "are created equal."
+       };
+
+       unsigned int  i;
+       for (i = 0; i < sizeof(strings) / sizeof(strings[0]); i++) {
+               avro_value_t  val;
+               try(avro_generic_string_new(&val, strings[i]),
+                   "Cannot create string");
+               check(rval, check_type_and_schema
+                           ("string", &val,
+                            AVRO_STRING, avro_schema_string()));
+               try(avro_value_reset(&val),
+                   "Cannot reset string");
+               try(avro_value_set_string_len(&val, "", 0),
+                   "Cannot set_len dummy string");
+
+               /* First try a round-trip using set_string */
+
+               try(avro_value_set_string(&val, strings[i]),
+                   "Cannot set string");
+
+               const char  *actual_str = NULL;
+               size_t  actual_size = 0;
+               try(avro_value_get_string(&val, &actual_str, &actual_size),
+                   "Cannot get string value");
+
+               if (actual_size != strlen(strings[i])+1) {
+                       fprintf(stderr, "Unexpected string size\n");
+                       return EXIT_FAILURE;
+               }
+
+               if (strcmp(actual_str, strings[i]) != 0) {
+                       fprintf(stderr, "Unexpected string contents\n");
+                       return EXIT_FAILURE;
+               }
+
+               avro_wrapped_buffer_t  wbuf;
+               try(avro_value_grab_string(&val, &wbuf),
+                   "Cannot grab string value");
+
+               if (wbuf.size != strlen(strings[i])+1) {
+                       fprintf(stderr, "Unexpected grabbed string size\n");
+                       return EXIT_FAILURE;
+               }
+
+               if (strcmp(wbuf.buf, strings[i]) != 0) {
+                       fprintf(stderr, "Unexpected grabbed string contents\n");
+                       return EXIT_FAILURE;
+               }
+
+               avro_wrapped_buffer_free(&wbuf);
+
+               /* and then again using set_string_len */
+
+               size_t  str_length = strlen(strings[i])+1;
+               try(avro_value_set_string_len(&val, strings[i], str_length),
+                   "Cannot set_len string");
+
+               actual_str = NULL;
+               actual_size = 0;
+               try(avro_value_get_string(&val, &actual_str, &actual_size),
+                   "Cannot get string value");
+
+               if (actual_size != strlen(strings[i])+1) {
+                       fprintf(stderr, "Unexpected string size\n");
+                       return EXIT_FAILURE;
+               }
+
+               if (strcmp(actual_str, strings[i]) != 0) {
+                       fprintf(stderr, "Unexpected string contents\n");
+                       return EXIT_FAILURE;
+               }
+
+               try(avro_value_grab_string(&val, &wbuf),
+                   "Cannot grab string value");
+
+               if (wbuf.size != strlen(strings[i])+1) {
+                       fprintf(stderr, "Unexpected grabbed string size\n");
+                       return EXIT_FAILURE;
+               }
+
+               if (strcmp(wbuf.buf, strings[i]) != 0) {
+                       fprintf(stderr, "Unexpected grabbed string contents\n");
+                       return EXIT_FAILURE;
+               }
+
+               avro_wrapped_buffer_free(&wbuf);
+
+               check_invalid_methods("string", &val);
+               check_write_read(&val);
+               check_copy(&val);
+               avro_value_free(&val);
+       }
+
+       return 0;
+}
+
+static int
+test_array(void)
+{
+       avro_schema_t  double_schema = avro_schema_double();
+       avro_schema_t  array_schema = avro_schema_array(double_schema);
+
+       avro_value_iface_t  *array_class =
+           avro_generic_class_from_schema(array_schema);
+
+       int  rval;
+
+       int  i;
+       for (i = 0; i < 100; i++) {
+               size_t  count = rand_count();
+
+               avro_value_t  val;
+               try(avro_value_new(array_class, &val),
+                   "Cannot create array");
+               check(rval, check_type_and_schema
+                           ("array", &val, AVRO_ARRAY,
+                            avro_schema_incref(array_schema)));
+
+               size_t  j;
+               for (j = 0; j < count; j++) {
+                       avro_value_t  element;
+                       size_t  new_index;
+                       try(avro_value_append(&val, &element, &new_index),
+                           "Cannot append to array");
+                       if (new_index != j) {
+                               fprintf(stderr, "Unexpected index\n");
+                               return EXIT_FAILURE;
+                       }
+
+                       double  expected = rand_number(-1e10, 1e10);
+                       try(avro_value_set_double(&element, expected),
+                           "Cannot set double");
+                       try(avro_value_get_by_index(&val, j, &element, NULL),
+                           "Cannot get from array");
+
+                       double  actual = 0.0;
+                       try(avro_value_get_double(&element, &actual),
+                           "Cannot get double value");
+
+                       if (actual != expected) {
+                               fprintf(stderr, "Unexpected double value\n");
+                               return EXIT_FAILURE;
+                       }
+               }
+
+               size_t  actual_size = 0;
+               try(avro_value_get_size(&val, &actual_size),
+                   "Cannot get_size array");
+
+               if (actual_size != count) {
+                       fprintf(stderr, "Unexpected size\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_write_read(&val);
+               check_copy(&val);
+
+               try(avro_value_reset(&val),
+                   "Cannot reset array");
+               try(avro_value_get_size(&val, &actual_size),
+                   "Cannot get_size empty array");
+
+               if (actual_size != 0) {
+                       fprintf(stderr, "Unexpected empty size\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_invalid_methods("array", &val);
+               avro_value_free(&val);
+       }
+
+       avro_schema_decref(double_schema);
+       avro_schema_decref(array_schema);
+       avro_value_iface_decref(array_class);
+       return 0;
+}
+
+static int
+test_enum(void)
+{
+       static const char  *SCHEMA_JSON =
+       "{"
+       "  \"type\": \"enum\","
+       "  \"name\": \"suits\","
+       "  \"symbols\": [\"CLUBS\",\"DIAMONDS\",\"HEARTS\",\"SPADES\"]"
+       "}";
+
+       avro_schema_t  enum_schema = NULL;
+       avro_schema_error_t  err;
+       if (avro_schema_from_json(SCHEMA_JSON, sizeof(SCHEMA_JSON),
+                                 &enum_schema, &err)) {
+               fprintf(stderr, "Error parsing schema:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       avro_value_iface_t  *enum_class =
+           avro_generic_enum_class(enum_schema);
+
+       int  rval;
+
+       int  i;
+       for (i = 0; i < 4; i++) {
+               int  expected = i;
+               avro_value_t  val;
+               try(avro_value_new(enum_class, &val),
+                   "Cannot create enum");
+               check(rval, check_type_and_schema
+                           ("enum", &val, AVRO_ENUM,
+                            avro_schema_incref(enum_schema)));
+               try(avro_value_reset(&val),
+                   "Cannot reset enum");
+               try(avro_value_set_enum(&val, expected),
+                   "Cannot set enum");
+
+               int  actual = -1;
+               try(avro_value_get_enum(&val, &actual),
+                   "Cannot get enum value");
+
+               if (actual != expected) {
+                       fprintf(stderr, "Unexpected enum value\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_invalid_methods("enum", &val);
+               check_write_read(&val);
+               check_copy(&val);
+               avro_value_free(&val);
+       }
+
+       avro_schema_decref(enum_schema);
+       avro_value_iface_decref(enum_class);
+       return 0;
+}
+
+static int
+test_fixed(void)
+{
+       static const char  *SCHEMA_JSON =
+       "{"
+       "  \"type\": \"fixed\","
+       "  \"name\": \"ipv4\","
+       "  \"size\": 4"
+       "}";
+
+       avro_schema_t  fixed_schema = NULL;
+       avro_schema_error_t  err;
+       if (avro_schema_from_json(SCHEMA_JSON, sizeof(SCHEMA_JSON),
+                                 &fixed_schema, &err)) {
+               fprintf(stderr, "Error parsing schema:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       avro_value_iface_t  *fixed_class =
+           avro_generic_fixed_class(fixed_schema);
+
+       int  rval;
+
+       char fixed[] = { 0xDE, 0xAD, 0xBE, 0xEF };
+
+       avro_value_t  val;
+       try(avro_value_new(fixed_class, &val),
+           "Cannot create fixed");
+       check(rval, check_type_and_schema
+                   ("fixed", &val, AVRO_FIXED,
+                    avro_schema_incref(fixed_schema)));
+       try(avro_value_reset(&val),
+           "Cannot reset fixed");
+
+       /* verify an error on invalid size */
+       try(!avro_value_set_fixed(&val, fixed, 0),
+           "Expected error with invalid size");
+
+       try(avro_value_set_fixed(&val, fixed, sizeof(fixed)),
+           "Cannot set fixed");
+
+       const void  *actual_buf = NULL;
+       size_t  actual_size = 0;
+       try(avro_value_get_fixed(&val, &actual_buf, &actual_size),
+           "Cannot get fixed value");
+
+       if (actual_size != sizeof(fixed)) {
+               fprintf(stderr, "Unexpected fixed size\n");
+               return EXIT_FAILURE;
+       }
+
+       if (memcmp(actual_buf, fixed, sizeof(fixed)) != 0) {
+               fprintf(stderr, "Unexpected fixed contents\n");
+               return EXIT_FAILURE;
+       }
+
+       avro_wrapped_buffer_t  wbuf;
+       try(avro_value_grab_fixed(&val, &wbuf),
+           "Cannot grab fixed value");
+
+       if (wbuf.size != sizeof(fixed)) {
+               fprintf(stderr, "Unexpected grabbed fixed size\n");
+               return EXIT_FAILURE;
+       }
+
+       if (memcmp(wbuf.buf, fixed, sizeof(fixed)) != 0) {
+               fprintf(stderr, "Unexpected grabbed fixed contents\n");
+               return EXIT_FAILURE;
+       }
+
+       avro_wrapped_buffer_free(&wbuf);
+
+       check_invalid_methods("fixed", &val);
+       check_write_read(&val);
+       check_copy(&val);
+       avro_value_free(&val);
+       avro_schema_decref(fixed_schema);
+       avro_value_iface_decref(fixed_class);
+       return 0;
+}
+
+static int
+test_map(void)
+{
+       avro_schema_t  double_schema = avro_schema_double();
+       avro_schema_t  map_schema = avro_schema_map(double_schema);
+
+       avro_value_iface_t  *map_class =
+           avro_generic_class_from_schema(map_schema);
+
+       int  rval;
+
+       int  i;
+       for (i = 0; i < 100; i++) {
+               size_t  count = rand_count();
+
+               avro_value_t  val;
+               try(avro_value_new(map_class, &val),
+                   "Cannot create map");
+               check(rval, check_type_and_schema
+                           ("map", &val, AVRO_MAP,
+                            avro_schema_incref(map_schema)));
+
+               size_t  j;
+               for (j = 0; j < count; j++) {
+                       avro_value_t  element;
+                       size_t  new_index;
+                       bool  is_new = false;
+
+                       char  key[64];
+                       snprintf(key, 64, "%zu", j);
+
+                       try(avro_value_add(&val, key,
+                                          &element, &new_index, &is_new),
+                           "Cannot add to map");
+
+                       if (new_index != j) {
+                               fprintf(stderr, "Unexpected index\n");
+                               return EXIT_FAILURE;
+                       }
+
+                       if (!is_new) {
+                               fprintf(stderr, "Expected new element\n");
+                               return EXIT_FAILURE;
+                       }
+
+                       double  expected = rand_number(-1e10, 1e10);
+                       try(avro_value_set_double(&element, expected),
+                           "Cannot set double");
+                       try(avro_value_add(&val, key,
+                                          &element, &new_index, &is_new),
+                           "Cannot re-add to map");
+
+                       if (is_new) {
+                               fprintf(stderr, "Expected non-new element\n");
+                               return EXIT_FAILURE;
+                       }
+
+                       const char  *actual_key = NULL;
+                       try(avro_value_get_by_index(&val, j, &element,
+                                                   &actual_key),
+                           "Cannot get from map");
+
+                       if (strcmp(actual_key, key) != 0) {
+                               fprintf(stderr, "Unexpected key\n");
+                               return EXIT_FAILURE;
+                       }
+
+                       double  actual = 0.0;
+                       try(avro_value_get_double(&element, &actual),
+                           "Cannot get double value");
+
+                       if (actual != expected) {
+                               fprintf(stderr, "Unexpected double value\n");
+                               return EXIT_FAILURE;
+                       }
+               }
+
+               size_t  actual_size = 0;
+               try(avro_value_get_size(&val, &actual_size),
+                   "Cannot get_size map");
+
+               if (actual_size != count) {
+                       fprintf(stderr, "Unexpected size\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_write_read(&val);
+               check_copy(&val);
+
+               try(avro_value_reset(&val),
+                   "Cannot reset map");
+               try(avro_value_get_size(&val, &actual_size),
+                   "Cannot get_size empty map");
+
+               if (actual_size != 0) {
+                       fprintf(stderr, "Unexpected empty size\n");
+                       return EXIT_FAILURE;
+               }
+
+               check_invalid_methods("map", &val);
+               avro_value_free(&val);
+       }
+
+       avro_schema_decref(double_schema);
+       avro_schema_decref(map_schema);
+       avro_value_iface_decref(map_class);
+       return 0;
+}
+
+static int
+test_record(void)
+{
+       static const char  *SCHEMA_JSON =
+       "{"
+       "  \"type\": \"record\","
+       "  \"name\": \"test\","
+       "  \"fields\": ["
+       "    { \"name\": \"b\", \"type\": \"boolean\" },"
+       "    { \"name\": \"i\", \"type\": \"int\" },"
+       "    { \"name\": \"s\", \"type\": \"string\" },"
+       "    { \"name\": \"ds\", \"type\": "
+       "      { \"type\": \"array\", \"items\": \"double\" } },"
+       "    { \"name\": \"sub\", \"type\": "
+       "      {"
+       "        \"type\": \"record\","
+       "        \"name\": \"subtest\","
+       "        \"fields\": ["
+       "          { \"name\": \"f\", \"type\": \"float\" },"
+       "          { \"name\": \"l\", \"type\": \"long\" }"
+       "        ]"
+       "      }"
+       "    },"
+       "    { \"name\": \"nested\", \"type\": [\"null\", \"test\"] }"
+       "  ]"
+       "}";
+
+       avro_schema_t  record_schema = NULL;
+       avro_schema_error_t  err;
+       if (avro_schema_from_json(SCHEMA_JSON, sizeof(SCHEMA_JSON),
+                                 &record_schema, &err)) {
+               fprintf(stderr, "Error parsing schema:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       avro_value_iface_t  *record_class =
+           avro_generic_class_from_schema(record_schema);
+
+       int  rval;
+
+       avro_value_t  val;
+       try(avro_value_new(record_class, &val),
+           "Cannot create record");
+       check(rval, check_type_and_schema
+                   ("record", &val, AVRO_RECORD,
+                    avro_schema_incref(record_schema)));
+
+       size_t  field_count;
+       try(avro_value_get_size(&val, &field_count),
+           "Cannot get field count");
+       if (field_count != 6) {
+               fprintf(stderr, "Unexpected field count\n");
+               return EXIT_FAILURE;
+       }
+
+       /* Assign to each field */
+       avro_value_t  field;
+       avro_value_t  element;
+       avro_value_t  subfield;
+       avro_value_t  branch;
+       const char  *name;
+       size_t  index;
+
+       try(avro_value_get_by_index(&val, 0, &field, NULL),
+           "Cannot get field 0");
+       try(avro_value_set_boolean(&field, true),
+           "Cannot set field 0");
+
+       try(avro_value_get_by_index(&val, 1, &field, &name),
+           "Cannot get field 1");
+       try(avro_value_set_int(&field, 42),
+           "Cannot set field 1");
+       if (strcmp(name, "i") != 0) {
+               fprintf(stderr, "Unexpected name for field 1: %s\n", name);
+               return EXIT_FAILURE;
+       }
+
+       try(avro_value_get_by_index(&val, 2, &field, NULL),
+           "Cannot get field 2");
+       try(avro_value_set_string(&field, "Hello world!"),
+           "Cannot set field 2");
+
+       try(avro_value_get_by_name(&val, "i", &field, &index),
+           "Cannot get \"i\" field");
+       if (index != 1) {
+               fprintf(stderr, "Unexpected index for \"i\" field: %zu\n", 
index);
+               return EXIT_FAILURE;
+       }
+
+       try(avro_value_get_by_index(&val, 3, &field, NULL),
+           "Cannot get field 3");
+       try(avro_value_append(&field, &element, NULL),
+           "Cannot append to field 3");
+       try(avro_value_set_double(&element, 10.0),
+           "Cannot set field 3, element 0");
+
+       try(avro_value_get_by_index(&val, 4, &field, NULL),
+           "Cannot get field 4");
+
+       try(avro_value_get_by_index(&field, 0, &subfield, NULL),
+           "Cannot get field 4, subfield 0");
+       try(avro_value_set_float(&subfield, 5.0f),
+           "Cannot set field 4, subfield 0");
+
+       try(avro_value_get_by_index(&field, 1, &subfield, NULL),
+           "Cannot get field 4, subfield 1");
+       try(avro_value_set_long(&subfield, 10000),
+           "Cannot set field 4, subfield 1");
+
+       try(avro_value_get_by_index(&val, 5, &field, NULL),
+           "Cannot get field 5");
+       try(avro_value_set_branch(&field, 0, &branch),
+           "Cannot select null branch");
+
+       check_write_read(&val);
+       check_copy(&val);
+
+       /* Reset and verify that the fields are empty again */
+       try(avro_value_reset(&val),
+           "Cannot reset record");
+
+       bool  bval;
+       try(avro_value_get_by_index(&val, 0, &field, NULL),
+           "Cannot get field 0");
+       try(avro_value_get_boolean(&field, &bval),
+           "Cannot get field 0 value");
+       if (bval) {
+               fprintf(stderr, "Unexpected value for field 0\n");
+               return EXIT_FAILURE;
+       }
+
+       size_t  count;
+       try(avro_value_get_by_index(&val, 3, &field, NULL),
+           "Cannot get field 3");
+       try(avro_value_get_size(&field, &count),
+           "Cannot get field 3 size");
+       if (count != 0) {
+               fprintf(stderr, "Unexpected size for field 3\n");
+               return EXIT_FAILURE;
+       }
+
+       check_invalid_methods("record", &val);
+       avro_value_free(&val);
+       avro_value_iface_decref(record_class);
+       avro_schema_decref(record_schema);
+       return EXIT_SUCCESS;
+}
+
+static int
+test_union(void)
+{
+       static const char  *SCHEMA_JSON =
+       "["
+       "  \"null\","
+       "  \"int\","
+       "  \"double\","
+       "  \"bytes\""
+       "]";
+
+       avro_schema_t  union_schema = NULL;
+       avro_schema_error_t  err;
+       if (avro_schema_from_json(SCHEMA_JSON, sizeof(SCHEMA_JSON),
+                                 &union_schema, &err)) {
+               fprintf(stderr, "Error parsing schema:\n  %s\n",
+                       avro_strerror());
+               return EXIT_FAILURE;
+       }
+
+       avro_value_iface_t  *union_class =
+           avro_generic_class_from_schema(union_schema);
+
+       int  rval;
+
+       avro_value_t  val;
+       try(avro_value_new(union_class, &val),
+           "Cannot create union");
+       check(rval, check_type_and_schema
+                   ("union", &val, AVRO_UNION,
+                    avro_schema_incref(union_schema)));
+
+       int discriminant = 0;
+       try(avro_value_get_discriminant(&val, &discriminant),
+           "Cannot get union discriminant");
+
+       if (discriminant != -1) {
+               fprintf(stderr, "Unexpected union discriminant\n");
+               return EXIT_FAILURE;
+       }
+
+       avro_value_t  branch;
+       try(!avro_value_get_current_branch(&val, &branch),
+           "Expected error getting empty current branch");
+
+       try(avro_value_set_branch(&val, 0, &branch),
+           "Cannot select null branch");
+       try(avro_value_set_null(&branch),
+           "Cannot set null branch value");
+
+       try(avro_value_set_branch(&val, 1, &branch),
+           "Cannot select int branch");
+       try(avro_value_set_int(&branch, 42),
+           "Cannot set int branch value");
+
+       try(avro_value_set_branch(&val, 1, &branch),
+           "Cannot select int branch");
+       try(avro_value_set_int(&branch, 10),
+           "Cannot set int branch value");
+
+       try(avro_value_set_branch(&val, 2, &branch),
+           "Cannot select double branch");
+       try(avro_value_set_double(&branch, 10.0),
+           "Cannot set double branch value");
+
+       char bytes[] = { 0xDE, 0xAD, 0xBE, 0xEF };
+       try(avro_value_set_branch(&val, 3, &branch),
+           "Cannot select bytes branch");
+       try(avro_value_set_bytes(&branch, bytes, sizeof(bytes)),
+           "Cannot set bytes branch value");
+
+       check_invalid_methods("union", &val);
+       check_write_read(&val);
+       check_copy(&val);
+       avro_value_free(&val);
+
+       avro_schema_decref(union_schema);
+       avro_value_iface_decref(union_class);
+       return 0;
+}
+
+int main(void)
+{
+       avro_set_allocator(test_allocator, NULL);
+
+       unsigned int i;
+       struct avro_tests {
+               char *name;
+               avro_test func;
+       } tests[] = {
+               { "boolean", test_boolean },
+               { "bytes", test_bytes },
+               { "double", test_double },
+               { "float", test_float },
+               { "int", test_int },
+               { "long", test_long },
+               { "null", test_null },
+               { "string", test_string },
+               { "array", test_array },
+               { "enum", test_enum },
+               { "fixed", test_fixed },
+               { "map", test_map },
+               { "record", test_record },
+               { "union", test_union }
+       };
+
+       init_rand();
+       for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+               struct avro_tests *test = tests + i;
+               fprintf(stderr, "**** Running %s tests ****\n", test->name);
+               if (test->func() != 0) {
+                       return EXIT_FAILURE;
+               }
+       }
+       return EXIT_SUCCESS;
+}

Added: avro/trunk/lang/c/tests/test_data_structures.c
URL: 
http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/test_data_structures.c?rev=1146546&view=auto
==============================================================================
--- avro/trunk/lang/c/tests/test_data_structures.c (added)
+++ avro/trunk/lang/c/tests/test_data_structures.c Thu Jul 14 02:35:04 2011
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.  See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "avro_private.h"
+#include "avro/data.h"
+
+static int  result = EXIT_SUCCESS;
+
+typedef int (*avro_test) (void);
+
+
+static int
+test_array(void)
+{
+       avro_raw_array_t  array;
+       long  *element;
+
+       /* Test once on a fresh array */
+
+       avro_raw_array_init(&array, sizeof(long));
+       element = avro_raw_array_append(&array);
+       *element = 1;
+       element = avro_raw_array_append(&array);
+       *element = 3;
+
+       if (avro_raw_array_size(&array) != 2) {
+               fprintf(stderr, "Incorrect array size: got %zu, expected 
%zu.\n",
+                       (size_t) avro_raw_array_size(&array),
+                       (size_t) 2);
+               return EXIT_FAILURE;
+       }
+
+       if (avro_raw_array_get(&array, long, 0) != 1) {
+               fprintf(stderr, "Unexpected array element %u: got %ld, expected 
%ld.\n",
+                       (unsigned int) 0, avro_raw_array_get(&array, long, 0),
+                       (long) 1);
+               return EXIT_FAILURE;
+       }
+
+       /* And test again after clearing the array */
+
+       avro_raw_array_clear(&array);
+       element = avro_raw_array_append(&array);
+       *element = 1;
+       element = avro_raw_array_append(&array);
+       *element = 3;
+
+       if (avro_raw_array_size(&array) != 2) {
+               fprintf(stderr, "Incorrect array size: got %zu, expected 
%zu.\n",
+                       (size_t) avro_raw_array_size(&array),
+                       (size_t) 2);
+               return EXIT_FAILURE;
+       }
+
+       if (avro_raw_array_get(&array, long, 0) != 1) {
+               fprintf(stderr, "Unexpected array element %u: got %ld, expected 
%ld.\n",
+                       (unsigned int) 0, avro_raw_array_get(&array, long, 0),
+                       (long) 1);
+               return EXIT_FAILURE;
+       }
+
+       avro_raw_array_done(&array);
+       return EXIT_SUCCESS;
+}
+
+
+static int
+test_map(void)
+{
+       avro_raw_map_t  map;
+       long  *element;
+       size_t  index;
+
+       /* Test once on a fresh map */
+
+       avro_raw_map_init(&map, sizeof(long));
+       avro_raw_map_get_or_create(&map, "x", (void **) &element, NULL);
+       *element = 1;
+       avro_raw_map_get_or_create(&map, "y", (void **) &element, NULL);
+       *element = 3;
+
+       if (avro_raw_map_size(&map) != 2) {
+               fprintf(stderr, "Incorrect map size: got %zu, expected %zu.\n",
+                       (size_t) avro_raw_map_size(&map),
+                       (size_t) 2);
+               return EXIT_FAILURE;
+       }
+
+       if (avro_raw_map_get_by_index(&map, long, 0) != 1) {
+               fprintf(stderr, "Unexpected map element %u: got %ld, expected 
%ld.\n",
+                       (unsigned int) 0,
+                       avro_raw_map_get_by_index(&map, long, 0),
+                       (long) 1);
+               return EXIT_FAILURE;
+       }
+
+       if (strcmp(avro_raw_map_get_key(&map, 0), "x") != 0) {
+               fprintf(stderr, "Unexpected key for map element 0: "
+                       "got \"%s\", expected \"%s\".\n",
+                       avro_raw_map_get_key(&map, 0), "x");
+               return EXIT_FAILURE;
+       }
+
+       element = avro_raw_map_get(&map, "y", &index);
+       if (index != 1) {
+               fprintf(stderr, "Unexpected index for map element \"%s\": "
+                       "got %zu, expected %u.\n",
+                       "y", index, 1);
+               return EXIT_FAILURE;
+       }
+
+       if (*element != 3) {
+               fprintf(stderr, "Unexpected map element %s: got %ld, expected 
%ld.\n",
+                       "y",
+                       *element, (long) 3);
+               return EXIT_FAILURE;
+       }
+
+       /* And test again after clearing the map */
+
+       avro_raw_map_clear(&map);
+       avro_raw_map_get_or_create(&map, "x", (void **) &element, NULL);
+       *element = 1;
+       avro_raw_map_get_or_create(&map, "y", (void **) &element, NULL);
+       *element = 3;
+
+       if (avro_raw_map_size(&map) != 2) {
+               fprintf(stderr, "Incorrect map size: got %zu, expected %zu.\n",
+                       (size_t) avro_raw_map_size(&map),
+                       (size_t) 2);
+               return EXIT_FAILURE;
+       }
+
+       if (avro_raw_map_get_by_index(&map, long, 0) != 1) {
+               fprintf(stderr, "Unexpected map element %u: got %ld, expected 
%ld.\n",
+                       (unsigned int) 0,
+                       avro_raw_map_get_by_index(&map, long, 0),
+                       (long) 1);
+               return EXIT_FAILURE;
+       }
+
+       element = avro_raw_map_get(&map, "y", &index);
+       if (index != 1) {
+               fprintf(stderr, "Unexpected index for map element \"%s\": "
+                       "got %zu, expected %u.\n",
+                       "y", index, 1);
+               return EXIT_FAILURE;
+       }
+
+       if (*element != 3) {
+               fprintf(stderr, "Unexpected map element %s: got %ld, expected 
%ld.\n",
+                       "y",
+                       *element, (long) 3);
+               return EXIT_FAILURE;
+       }
+
+       avro_raw_map_done(&map);
+       return EXIT_SUCCESS;
+}
+
+
+static int
+test_string(void)
+{
+       avro_raw_string_t  str;
+
+       avro_raw_string_init(&str);
+
+       avro_raw_string_set(&str, "a");
+       avro_raw_string_set(&str, "abcdefgh");
+       avro_raw_string_set(&str, "abcd");
+
+       if (avro_raw_string_length(&str) != 5) {
+               fprintf(stderr, "Incorrect string size: got %zu, expected 
%zu.\n",
+                       (size_t) avro_raw_string_length(&str),
+                       (size_t) 5);
+               return EXIT_FAILURE;
+       }
+
+       if (strcmp(str.wrapped.buf, "abcd") != 0) {
+               fprintf(stderr, "Incorrect string contents: "
+                               "got \"%s\", expected \"%s\".\n",
+                       (char *) avro_raw_string_get(&str),
+                       "abcd");
+               return EXIT_FAILURE;
+       }
+
+       avro_wrapped_buffer_t  wbuf;
+       avro_wrapped_buffer_new_string(&wbuf, "abcd");
+       avro_raw_string_give(&str, &wbuf);
+
+       if (avro_raw_string_length(&str) != 5) {
+               fprintf(stderr, "Incorrect string size: got %zu, expected 
%zu.\n",
+                       (size_t) avro_raw_string_length(&str),
+                       (size_t) 5);
+               return EXIT_FAILURE;
+       }
+
+       if (strcmp(str.wrapped.buf, "abcd") != 0) {
+               fprintf(stderr, "Incorrect string contents: "
+                               "got \"%s\", expected \"%s\".\n",
+                       (char *) avro_raw_string_get(&str),
+                       "abcd");
+               return EXIT_FAILURE;
+       }
+
+       avro_raw_string_t  str2;
+       avro_raw_string_init(&str2);
+       avro_raw_string_set(&str2, "abcd");
+
+       if (!avro_raw_string_equals(&str, &str2)) {
+               fprintf(stderr, "Strings should be equal.\n");
+               return EXIT_FAILURE;
+       }
+
+       avro_raw_string_done(&str);
+       avro_raw_string_done(&str2);
+       return EXIT_SUCCESS;
+}
+
+
+int main(int argc, char *argv[])
+{
+       AVRO_UNUSED(argc);
+       AVRO_UNUSED(argv);
+
+       unsigned int i;
+       struct avro_tests {
+               char *name;
+               avro_test func;
+       } tests[] = {
+               { "array", test_array },
+               { "map", test_map },
+               { "string", test_string }
+       };
+
+       for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+               struct avro_tests *test = tests + i;
+               fprintf(stderr, "**** Running %s tests ****\n", test->name);
+               if (test->func() != 0) {
+                       result = EXIT_FAILURE;
+               }
+       }
+       return result;
+}


Reply via email to