diff --git a/test/validation/Makefile.am b/test/validation/Makefile.am
index 2e1b991..5992f72 100644
--- a/test/validation/Makefile.am
+++ b/test/validation/Makefile.am
@@ -6,11 +6,12 @@ AM_LDFLAGS += -L$(CUNIT_PATH)/lib -static -lcunit
 if ODP_CUNIT_ENABLED
 TESTS = ${bin_PROGRAMS}
 check_PROGRAMS = ${bin_PROGRAMS}
-bin_PROGRAMS = odp_init odp_queue odp_crypto
+bin_PROGRAMS = odp_init odp_queue odp_crypto odp_shm
 odp_init_LDFLAGS = $(AM_LDFLAGS)
 odp_queue_LDFLAGS = $(AM_LDFLAGS)
 odp_crypto_CFLAGS = $(AM_CFLAGS) -I./crypto
 odp_crypto_LDFLAGS = $(AM_LDFLAGS)
+odp_shm_LDFLAGS = $(AM_LDFLAGS)
 endif

 dist_odp_init_SOURCES = odp_init.c
@@ -18,3 +19,4 @@ dist_odp_queue_SOURCES = odp_queue.c
 dist_odp_crypto_SOURCES = crypto/odp_crypto_test_async_inp.c \
                          crypto/odp_crypto_test_sync_inp.c \
                          odp_crypto.c
+dist_odp_shm_SOURCES = odp_shm.c odp_cunit_common.c
diff --git a/test/validation/odp_cunit_common.c b/test/validation/odp_cunit_common.c
new file mode 100644
index 0000000..885b981
--- /dev/null
+++ b/test/validation/odp_cunit_common.c
@@ -0,0 +1,37 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP test application common
+ */
+
+#include <string.h>
+#include <odp.h>
+#include "odp_cunit_common.h"
+#include "odph_linux.h"
+/* Globals */
+static odph_linux_pthread_t thread_tbl[MAX_WORKERS];
+
+/** create test thread */
+int odp_cunit_thread_create(void *func_ptr(void *), pthrd_arg *arg)
+{
+       /* Create and init additional threads */
+       odph_linux_pthread_create(thread_tbl, arg->numthrds, 0, func_ptr,
+                                 (void *)arg);
+
+       return 0;
+}
+
+/** exit from test thread */
+int odp_cunit_thread_exit(pthrd_arg *arg)
+{
+       /* Wait for other threads to exit */
+       odph_linux_pthread_join(thread_tbl, arg->numthrds);
+
+       return 0;
+}
diff --git a/test/validation/odp_cunit_common.h b/test/validation/odp_cunit_common.h
new file mode 100644
index 0000000..f6eb332
--- /dev/null
+++ b/test/validation/odp_cunit_common.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP test application common headers
+ */
+
+#ifndef ODP_CUNICT_COMMON_H
+#define ODP_CUNICT_COMMON_H
+
+#define MAX_WORKERS 32 /**< Maximum number of work threads */
+
+typedef struct {
+       int foo;
+       int bar;
+} test_shared_data_t;
+
+/** types of tests */
+typedef enum {
+       ODP_SHM_TEST = 0,
+       ODP_MAX_TEST
+} odp_test_case_e;
+
+/**
+ * Thread argument
+ */
+typedef struct {
+       int testcase; /**< specifies which set of API's to exercise */
+       int numthrds; /**< no of pthreads to create */
+} pthrd_arg;
+
+/** create thread fro start_routine function */
+extern int odp_cunit_thread_create(void *func_ptr(void *), pthrd_arg *arg);
+extern int odp_cunit_thread_exit(pthrd_arg *);
+
+#endif /* ODP_COMMON_H */
diff --git a/test/validation/odp_shm.c b/test/validation/odp_shm.c
new file mode 100644
index 0000000..fea3620
--- /dev/null
+++ b/test/validation/odp_shm.c
@@ -0,0 +1,121 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include "odp.h"
+#include "CUnit/Basic.h"
+#include "odp_cunit_common.h"
+
+#define ALIGE_SIZE  (128)
+#define TESTNAME "cunit_test_shared_data"
+
+odp_shm_t shm;
+
+__thread test_shared_data_t *test_shared_data;
+static void *run_shm_thread(void *arg)
+{
+       pthrd_arg *parg = (pthrd_arg *)arg;
+       odp_shm_info_t  info;
+       int thr;
+
+       thr = odp_thread_id();
+
+       printf("Thread %i starts\n", thr);
+
+       switch (parg->testcase) {
+       case ODP_SHM_TEST:
+               shm = odp_shm_lookup(TESTNAME);
+               CU_ASSERT(ODP_SHM_INVALID != shm);
+               test_shared_data = odp_shm_addr(shm);
+               CU_ASSERT(0 == odp_shm_info(shm, &info));
+               CU_ASSERT(0 == strcmp(TESTNAME, info.name));
+               CU_ASSERT(0 == info.flags);
+               CU_ASSERT(test_shared_data == info.addr);
+               CU_ASSERT(sizeof(test_shared_data_t) == info.size);
+               CU_ASSERT(odp_sys_page_size() == info.page_size);
+               odp_shm_print_all();
+               break;
+       default:
+               printf("Invalid test case [%d]\n", parg->testcase);
+       }
+       fflush(stdout);
+       return parg;
+}
+
+static void test_odp_shm_sunnyday(void)
+{
+       pthrd_arg thrdarg;
+
+       shm = odp_shm_reserve(TESTNAME,
+                             sizeof(test_shared_data_t), ALIGE_SIZE, 0);
+       CU_ASSERT(ODP_SHM_INVALID != shm);
+
+       CU_ASSERT(0 == odp_shm_free(shm));
+       CU_ASSERT(ODP_SHM_INVALID == odp_shm_lookup(TESTNAME));
+
+       shm = odp_shm_reserve(TESTNAME,
+                             sizeof(test_shared_data_t), ALIGE_SIZE, 0);
+       CU_ASSERT(ODP_SHM_INVALID != shm);
+
+       test_shared_data = odp_shm_addr(shm);
+       CU_ASSERT(NULL != test_shared_data);
+       memset(test_shared_data, 0, sizeof(test_shared_data_t));
+
+       thrdarg.testcase = ODP_SHM_TEST;
+       thrdarg.numthrds = odp_sys_core_count();
+
+       if (thrdarg.numthrds > MAX_WORKERS)
+               thrdarg.numthrds = MAX_WORKERS;
+
+       odp_cunit_thread_create(run_shm_thread, &thrdarg);
+       odp_cunit_thread_exit(&thrdarg);
+}
+
+static int finalize(void)
+{
+       odp_term_local();
+       odp_term_global();
+       return 0;
+}
+
+static int init(void)
+{ +       if (0 != odp_init_global(NULL, NULL)) {
+               printf("odp_init_global fail.\n");
+               return -1;
+       }
+       if (0 != odp_init_local()) {
+               printf("odp_init_local fail.\n");
+               return -1;
+       }
+       return 0;
+}
+
+int main(void)
+{
+       CU_pSuite ptr_suite;
+
+       /* initialize the CUnit test registry */
+       if (CUE_SUCCESS != CU_initialize_registry())
+               return CU_get_error(); +
+       /* add the tests to the shm suite */
+       ptr_suite = CU_add_suite(__FILE__, init, finalize);
+       if (!ptr_suite) {
+               CU_cleanup_registry();
+               return CU_get_error();
+       }

This is a different style of test framework failure exit to the one that Stuarts patch provided which returned -1 and we should get all the tests working the same way, 

I wonder if we should use  void CU_set_error_action(CU_ErrorAction action) and set CUEA_ABORT which results in the application calling exit() when an error occurs in the framework
(but not in the asserts in the actual tests, they work as before).

This means we don't need to add checks to the return codes  in the tests for the CU_* calls, we also no longer have to add and prints to stderr to explain the situation making the test framework less intrusive in the test code.
To test this I added this call to set the exit behavior and then forced a framework error by passing null into AC_ADD_TEST and got the following in the two run scenarios, and it works well I think


$ make check
...
make[4]: Entering directory '/home/mike/git/odp/test/validation'
FAIL: odp_init
