Index: src/libbu/tests/bu_avs.c
===================================================================
--- src/libbu/tests/bu_avs.c	(revision 0)
+++ src/libbu/tests/bu_avs.c	(revision 0)
@@ -0,0 +1,427 @@
+/*                    T E S T _ A V S . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2011-2012 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+
+/**
+ * Test Case to test the behaviour of avs.c (Attribute/Value Set)
+ *
+ * Tests/uses the following functions:
+ *@li bu_avs_init           test
+ *@li bu_avs_init_empty     test
+ *@li bu_avs_new            test
+ *@li bu_avs_add            test
+ *@li bu_avs_add_vls        test
+ *@li bu_avs_add_nonunique  test
+ *@li bu_avs_remove         test
+ *@li bu_avs_merge          test
+ *@li bu_avs_get            test
+ *@li bu_avs_free           used (assumed to be working)
+ *@li bu_avs_print          test
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bu.h"
+
+int
+test_empty_avs()
+{
+    bu_avs_t avs;
+
+    bu_avs_init_empty(&avs);
+
+    if (!BU_AVS_IS_INITIALIZED(&avs)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int
+test_basic_avs()
+{
+    bu_avs_t *avs;
+    int result;
+
+    avs = bu_avs_new(3, "test_basic_avs");
+
+    result = BU_AVS_IS_INITIALIZED(avs);
+
+    bu_avs_free(avs);
+
+    return result;
+}
+
+int
+test_invalid_new_avs()
+{
+    bu_avs_t *avs;
+    int result;
+
+    avs = bu_avs_new(-3, "test_avs");
+
+    result = BU_AVS_IS_INITIALIZED(avs);
+
+    bu_avs_free(avs);
+
+    return result;
+}
+
+int
+test_basic_put()
+{
+    bu_avs_t *avs;
+    int result = 1;
+
+    avs = bu_avs_new(3, "test_avs");
+
+    if(bu_avs_add(avs, "key", "value") != 2) 
+        result = 0;
+
+    if(bu_avs_add(avs, "key", "value2") != 1)
+        result = 0;
+
+    if(bu_avs_add(avs, NULL, "value") != 0) 
+        result = 0;
+
+    if(bu_avs_add(avs, "", "value") != 0) 
+        result = 0;
+
+    bu_avs_free(avs);
+    return result;
+}
+
+int
+test_put_to_empty()
+{
+    bu_avs_t avs_data;
+    bu_avs_t *avs = &avs_data;
+    int result = 1;
+
+    bu_avs_init_empty(avs);
+
+    if(bu_avs_add(avs, "key", "value") != 2) 
+        result = 0;
+
+    return result;
+}
+
+int
+test_basic_get()
+{
+    bu_avs_t *avs;
+    int result = 1;
+
+    avs = bu_avs_new(3, "test_avs");
+
+    /* Ensure we get a NULL */
+    if(bu_avs_get(avs, "key"))
+        result = 0;
+
+    bu_avs_add(avs, "key", "value");
+
+    if(bu_strcmp("value", bu_avs_get(avs, "key")) != 0)
+        result = 0;
+
+    bu_avs_free(avs);
+    return result;
+}
+
+int
+test_basic_remove()
+{
+    bu_avs_t *avs;
+    int result = 1;
+
+    avs = bu_avs_new(3, "test_avs");
+
+    /*
+     * Test an existant attribute
+     */
+    bu_avs_add(avs, "key", "value");
+
+    /* Check that it's there */
+    if(bu_strcmp("value", bu_avs_get(avs, "key")) != 0)
+        result = 0;
+
+    if(bu_avs_remove(avs, "key") != 0)
+        result = 0;
+
+    /* Ensure we now get a NULL */
+    if(bu_avs_get(avs, "key"))
+        result = 0;
+
+    /*
+     * Test a nonexistant attribute
+     */
+    /* Check that it's not there */
+    if(bu_avs_get(avs, "key"))
+        result = 0;
+
+    if(bu_avs_remove(avs, "key") != -1)
+        result = 0;
+
+    /* Ensure we still get a NULL */
+    if(bu_avs_get(avs, "key"))
+        result = 0;
+
+    bu_avs_free(avs);
+    return result;
+}
+
+int
+test_merge()
+{
+    bu_avs_t *avs_src;
+    bu_avs_t *avs_dest;
+    int result = 1;
+
+    avs_src = bu_avs_new(3, "test_avs1");
+    avs_dest = bu_avs_new(3, "test_avs2");
+
+    bu_avs_add(avs_src, "static_key2", "its_value");
+    bu_avs_add(avs_src, "replaced_key", "replaced_value");
+    bu_avs_add(avs_dest, "static_key1", "its_value");
+    bu_avs_add(avs_dest, "replaced_key", "initial_value");
+
+
+    bu_avs_merge(avs_dest, avs_src);
+
+
+    if(bu_strcmp("its_value", bu_avs_get(avs_dest, "static_key1")) != 0)
+        result = 0;
+    if(bu_strcmp("its_value", bu_avs_get(avs_dest, "static_key2")) != 0)
+        result = 0;
+
+    if(bu_strcmp("replaced_value", bu_avs_get(avs_dest, "replaced_key")) != 0)
+        result = 0;
+
+    
+    bu_avs_free(avs_src);
+    bu_avs_free(avs_dest);
+    return result;
+}
+
+int
+test_add_nonunique()
+{
+    bu_avs_t *avs;
+    int result = 1;
+
+    avs = bu_avs_new(3, "test_avs");
+
+    bu_avs_add_nonunique(avs, "key", "value");
+    if(!bu_avs_get(avs, "key"))
+        result = 0;
+
+    /* Add it again */
+    bu_avs_add_nonunique(avs, "key", "value");
+
+    /* Ensure it's still there */
+    if(!bu_avs_get(avs, "key"))
+        result = 0;
+
+    /* Remove only deletes the first one it finds - the second entry
+     * should still be there
+     */
+    bu_avs_remove(avs, "key");
+    
+    if(!bu_avs_get(avs, "key"))
+        result = 0;
+
+    bu_avs_free(avs);
+    return result;
+}
+
+int
+test_add_vls()
+{
+    bu_vls_t *vls;
+    bu_avs_t *avs;
+    int result = 1;
+
+    avs = bu_avs_new(3, "test_avs");
+    vls = bu_vls_vlsinit();
+
+    bu_vls_strcat(vls, "the vls string");
+
+    bu_avs_add_vls(avs, "key", vls);
+
+    if(bu_strcmp("the vls string", bu_avs_get(avs, "key")) != 0)
+        result = 0;
+
+    bu_avs_free(avs);
+    bu_vls_free(vls);
+    return result;
+}
+
+
+
+int
+log_test_hook(genptr_t clientdata,
+	 genptr_t str)
+{
+    char *buf;
+    int len;
+    static int position = 0;
+
+    buf = (char *) clientdata;
+    
+    len = bu_strlcpy(buf+position, str, strlen(str));
+
+    position += len;
+
+    return len;
+}
+
+int
+test_print()
+{
+    bu_avs_t *avs;
+    char buf[400];
+    int result = 1;
+    char *expected = "A Title: 3 attributes:  key1 = value1  key2 = value2  key3 = value3";
+
+    bu_log_add_hook(log_test_hook, (genptr_t)buf);
+
+    avs = bu_avs_new(3, "test_avs");
+
+    bu_avs_add(avs, "key1", "value1");
+    bu_avs_add(avs, "key2", "value2");
+    bu_avs_add(avs, "key3", "value3");
+
+    bu_avs_print(avs, "A Title");
+
+    if (bu_strcmp(buf, expected) != 0)
+        result = 0;
+
+    bu_log_delete_hook(log_test_hook, (genptr_t)buf);
+
+    bu_avs_free(avs);
+    return result;
+}
+
+
+int
+test_reinitialize()
+{
+    bu_avs_t avs;
+    int result = 1;
+
+    bu_avs_init(&avs, 3, "test_avs");
+
+    bu_avs_add(&avs, "key", "value");
+
+    /* Ensure it exists */
+    if(!bu_avs_get(&avs, "key"))
+        result = 0;
+
+    bu_avs_init(&avs, 3, "test_avs2");
+
+    /* Ensure it doesn't exist */
+    if(bu_avs_get(&avs, "key"))
+        result = 0;
+
+    return result;
+}
+
+
+int
+main()
+{
+    int result = 1;
+
+    if (!test_empty_avs()) {
+        printf("test_empty_avs failed\n");
+        result = 0;
+    }
+
+    if (!test_basic_avs()) {
+        printf("test_basic_avs failed\n");
+        result = 0;
+    }
+
+    if (!test_invalid_new_avs()) {
+        printf("test_invalid_new_avs failed\n");
+        result = 0;
+    }
+
+    if (!test_basic_put()) {
+        printf("test_basic_put failed\n");
+        result = 0;
+    }
+
+    if (!test_put_to_empty()) {
+        printf("test_put_to_empty failed\n");
+        result = 0;
+    }
+
+    if (!test_basic_get()) {
+        printf("test_basic_get failed\n");
+        result = 0;
+    }
+
+    if (!test_basic_remove()) {
+        printf("test_basic_remove failed\n");
+        result = 0;
+    }
+
+    if (!test_merge()) {
+        printf("test_merge failed\n");
+        result = 0;
+    }
+
+    if (!test_add_nonunique()) {
+        printf("test_add_nonunique failed\n");
+        result = 0;
+    }
+
+    if (!test_add_vls()) {
+        printf("test_add_vls failed\n");
+        result = 0;
+    }
+
+    if (!test_print()) {
+        printf("test_print failed\n");
+        result = 0;
+    }
+
+    if (!test_reinitialize()) {
+        printf("test_print failed\n");
+        result = 0;
+    }
+
+    return !result;
+}
+
+
+/** @} */
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Index: src/libbu/tests/CMakeLists.txt
===================================================================
--- src/libbu/tests/CMakeLists.txt	(revision 53973)
+++ src/libbu/tests/CMakeLists.txt	(working copy)
@@ -293,6 +293,12 @@
 add_test(bu_gettime_test tester_bu_timer)
 
 #
+#  ************ avs.c tests *************
+#
+BRLCAD_ADDEXEC(tester_bu_avs bu_avs.c libbu NO_INSTALL LOCAL)
+add_test(bu_avs_test tester_bu_avs)
+
+#
 #  ************ vls_vprintf.c tests *************
 #
 BRLCAD_ADDEXEC(tester_bu_vls_vprintf bu_vls_vprintf.c libbu NO_INSTALL LOCAL)
