Create cros-specific unit tests.

Create infrastructure to allow cros-specific unit tests to be
created and executed.  Example .c unit tests are provided.
.c:  testcases/cros/unittests/cros_unittest_sample/cros_unittest_sample.c

Also create a cros test 'suite': runtest/cros_kernel_unittests.

Dependent CL creates a control.kernel_unittests that invokes
this suite wrapper.

To create a new test, create a new .c file within an existing
folder under cros/unittests or create a new folder with a
Makefile to contain new .c tests.  Each .c unittest simply
executes code and returns 0 for success and nonzero for failure.

To test:
-emerge-xxx autotest-tests-ltp
 (autotest-tests-ltp builds autotest-deps-ltp which builds the tests)
-run_remote_tests.sh ...  client/site_tests/kernel_LTP/control.kernel_unittests

BUG=chromium-os:36962
TEST=./run_remote_tests.sh --remote=... --use_emerged client/site_tests/kernel_LTP/control.sample
TEST=./run_remote_tests.sh --remote=... --use_emerged client/site_tests/kernel_LTP/control.kernel_unittests
TEST=./run_remote_tests.sh --remote=... --use_emerged client/site_tests/kernel_LTP/control.kernel_tests

CQ-DEPEND=I9d1c915edaac5abd82a29eef56906384f5b55345

Change-Id: I71fde5e6a90318b644b5b214477eb05f69f28cbb
Reviewed-on: https://gerrit.chromium.org/gerrit/45086
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: Olof Johansson <olofj@chromium.org>
Tested-by: Mike Truty <truty@chromium.org>
Commit-Queue: Mike Truty <truty@chromium.org>
diff --git a/README.chromium b/README.chromium
index 7fe55ca..4944d1f 100644
--- a/README.chromium
+++ b/README.chromium
@@ -6,3 +6,22 @@
 LICENSE="GNU GENERAL PUBLIC LICENSE Version 2"
 LICENSE_FILE="COPYING"
 
+CrOS-specific suites include:
+./runtest/cros_kernel_tests : 'heavy' tests with LTP test lib invocations.
+./runtest/cros_kernel_unittests : 'light' tests without LTP test lib calls.
+
+CrOS-specific tests (.sh and .c) reside under:
+./testcases/cros
+
+CrOS-specific 'lightweight' unittests (.c) reside under:
+./testcases/cros/unittests : tests are expected to be a single .c file
+                             that returns 0 on success and nonzero on fail.
+                             The tests may reside in their own folder
+                             or be grouped in a folder.
+
+Sample tests are:
+.sh: ./testcases/cros/commands/crossystem
+.c:  ./testcases/cros/kernel/syscalls/cros_getcwd
+
+Sample unittests are:
+.c: ./testcases/cros/unittests/cros_unittest_sample
diff --git a/runtest/cros_kernel_tests b/runtest/cros_kernel_tests
new file mode 100644
index 0000000..1bbb056
--- /dev/null
+++ b/runtest/cros_kernel_tests
@@ -0,0 +1,19 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# DESCRIPTION:ChromeOS kernel testing with LTP test lib calls in tests.
+#
+# For sh scripts, export TCdat so the cmd line tools will work.
+# For executables, simply supply the command.
+#
+# During the build process all scripts and executables are placed
+# into $LTPROOT/testcases/bin and the harness looks there explicitly.
+#
+# tag              test case cmdline
+
+# sample .sh test with LTP test lib calls.
+cros_sample_cmd_cs export TCdat=$LTPROOT/testcases/bin; cros_sample_crossystem_tests.sh
+
+# sample .c test with LTP test lib calls.
+cros_sample_getcwd02 cros_sample_getcwd02
diff --git a/runtest/cros_kernel_unittests b/runtest/cros_kernel_unittests
new file mode 100644
index 0000000..a63a9b9
--- /dev/null
+++ b/runtest/cros_kernel_unittests
@@ -0,0 +1,16 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# DESCRIPTION:ChromeOS kernel unit testing without LTP test lib calls in tests.
+#
+# This is designed for simple .c based tests.  No LTP test lib calls are
+# required to set status.  The wrapper makes these calls for each test.
+#
+# During the build process all scripts and executables are placed
+# into $LTPROOT/testcases/bin and the harness looks there explicitly.
+#
+# tag              test case cmdline
+
+# Cros unittest wrapper (these .c tests do not include LTP test lib calls).
+cros_unittests export TCdat=$LTPROOT/testcases/bin; cros_unittests_wrapper.sh
diff --git a/testcases/cros/Makefile b/testcases/cros/Makefile
new file mode 100644
index 0000000..957f3fb
--- /dev/null
+++ b/testcases/cros/Makefile
@@ -0,0 +1,10 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros test suite Makefile
+
+top_srcdir		?= ../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/cros/commands/Makefile b/testcases/cros/commands/Makefile
new file mode 100644
index 0000000..6074b80
--- /dev/null
+++ b/testcases/cros/commands/Makefile
@@ -0,0 +1,10 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros test suite Makefile
+
+top_srcdir		?= ../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/cros/commands/crossystem/00_Descriptions.txt b/testcases/cros/commands/crossystem/00_Descriptions.txt
new file mode 100644
index 0000000..03f09f5
--- /dev/null
+++ b/testcases/cros/commands/crossystem/00_Descriptions.txt
@@ -0,0 +1,8 @@
+cros_sample_cmd_cs01
+  crossystem command succeeds
+
+cros_sample_cmd_cs02
+  crossystem invalidcommand fails
+
+cros_sample_cmd_cs03
+  crossystem mainfw_act returns A or B
diff --git a/testcases/cros/commands/crossystem/Makefile b/testcases/cros/commands/crossystem/Makefile
new file mode 100644
index 0000000..aa28de3
--- /dev/null
+++ b/testcases/cros/commands/crossystem/Makefile
@@ -0,0 +1,15 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros/commands/cros_sample_crossystem test Makefile
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+INSTALL_TARGETS		:= cros_sample_crossystem_tests.sh
+
+MAKE_TARGETS		:=
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/cros/commands/crossystem/cros_sample_crossystem_tests.sh b/testcases/cros/commands/crossystem/cros_sample_crossystem_tests.sh
new file mode 100755
index 0000000..1d83f5d
--- /dev/null
+++ b/testcases/cros/commands/crossystem/cros_sample_crossystem_tests.sh
@@ -0,0 +1,147 @@
+#!/bin/sh
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# FILE:				cros_sample_crossystem_test.sh
+#
+# DESCRIPTION: Tests crossystem command. Basic tests to demonstrate a cros
+#							 test implemented as a bash script.
+#
+# AUTHOR:			 truty@chromium.org
+#
+# FULL REFERENCE:
+#		http://ltp.sourceforge.net/documentation/how-to/ltp.php
+#		Contents and organization of LTP.
+#		Instructions for creating tests including:
+#		-.c test template
+#		-Bash test template
+#
+# QUICK REFERENCE FOR TEST WRITING:
+# 1. Create a new test subdirectory with Makefile based on this one.
+# 2. Exporting TST_TOTAL, TCID and TST_COUNT are required. Copy this setup().
+# 3. Use $LTPTMP/... for storing files produced.
+# 4. Clean the files up in cleanup() if possible.
+# 5. Return 0 for success and nonzero for fail.
+# 6. Use these command line api's to indicate test status:
+#
+#		 Informational messages:
+#			 tst_resm TINFO "Informational message..."
+#
+#		 PASSED test:
+#			 tst_resm TPASS "Test succeeded message..."
+#
+#		 FAILED test:
+#			 tst_resm TFAIL "Test failed message"
+#
+#		 Unexpected infrastructure problem:
+#			 tst_brkm TBROK <cleanup_fn or NULL> "Unexpected ... message"
+#
+#		 Flavors of these commands exist that can also emit a file to include
+#		 detailed status as follows:
+#			 tst_res <status> <fname> "tmessage..."
+#			 tst_brk TBROK <fname> <cleanup_fn> "tmessage..."
+#
+#			 <tstatus> is one of:
+#				 TINFO - informational message
+#				 TPASS - test passed
+#				 TFAIL - test failed
+#				 TWARN - warning during the test
+# 7. Add your test to $LTPROOT/runtest/cros_kernel_unittests
+# 8. Modify INSTALL_TARGETS in the Makefile to match the new script.
+
+
+setup()
+{
+	# Required by LTP command line harness APIs:
+	export TST_TOTAL=3	# Total number of test cases in this file.
+	export TCID="setup" # Test case identifier
+	export TST_COUNT=0	# Set up is initialized as test 0
+	LTPTMP=${TMP}				# Temporary directory to create files, etc.
+
+	#trap "cleanup" 0
+
+	return 0
+}
+
+
+#cleanup()
+#{
+#  # Possible cleanup under $LTPTMP/... using rm -rf ...
+#}
+
+
+cros_cmd_cs01()
+{
+	# Test if crossystem command succeeds on this system.
+	TCID="cros_sample_cmd_cs01"
+	TST_COUNT=1
+	RC=0
+
+	tst_resm TINFO "Test #1: check if crossystem is available"
+	crossystem >/dev/null || RC=$?
+	if [ $RC -ne 0 ]; then
+		tst_resm TFAIL "Unable to execute crossystem"
+	else
+		tst_resm TPASS "crossystem succeeded"
+	fi
+	return $RC
+}
+
+
+cros_cmd_cs02()
+{
+	# Test if crossystem command handles invalid commands properly.
+	TCID="cros_sample_cmd_cs02"
+	TST_COUNT=2
+	RC=0
+
+	tst_resm TINFO "Test #2: check if crossystem fails on invalid commands"
+	crossystem invalidcommand >/dev/null 2>&1 || RC=$?
+	if [ $RC -ne 1 ]; then
+		tst_resm TFAIL "crossystem should have failed"
+		RC=1
+	else
+		tst_resm TPASS "crossystem handled invalid command properly"
+		RC=0
+	fi
+	return $RC
+}
+
+
+cros_cmd_cs03()
+{
+	# Test if one crossystem command returns valid values.
+	TCID="cros_sample_cmd_cs03"
+	TST_COUNT=3
+	RC=0
+
+	tst_resm TINFO "Test #3: check if crossystem returns valid data"
+	SLOT=$(crossystem mainfw_act) || RC=$?
+	if [ $RC -ne 0 ]; then
+		tst_resm TFAIL "crossystem mainfw_act failed unexpectedly"
+	else
+		if [ $SLOT != 'A' ] && [ $SLOT != 'B' ]; then
+			tst_resm TFAIL "crossystem mainfw_act failed unexpectedly"
+		else
+			tst_resm TPASS "crossystem mainfw"
+		fi
+	fi
+	return $RC
+}
+
+
+# Function:			main
+#
+# Description:	- Execute all tests, exit with test status.
+#
+# Exit:					- zero on success
+#								- non-zero on failure.
+#
+RC=0		# Return value from setup, and test functions.
+
+setup || exit $RC
+
+cros_cmd_cs01 || exit $RC
+cros_cmd_cs02 || exit $RC
+cros_cmd_cs03 || exit $RC
diff --git a/testcases/cros/kernel/Makefile b/testcases/cros/kernel/Makefile
new file mode 100644
index 0000000..f443316
--- /dev/null
+++ b/testcases/cros/kernel/Makefile
@@ -0,0 +1,10 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros/kernel test suite Makefile
+
+top_srcdir		?= ../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/cros/kernel/syscalls/Makefile b/testcases/cros/kernel/syscalls/Makefile
new file mode 100644
index 0000000..0065266
--- /dev/null
+++ b/testcases/cros/kernel/syscalls/Makefile
@@ -0,0 +1,10 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros/kernel/syscalls test suite Makefile
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/cros/kernel/syscalls/cros_sample_getcwd/Makefile b/testcases/cros/kernel/syscalls/cros_sample_getcwd/Makefile
new file mode 100644
index 0000000..797a536
--- /dev/null
+++ b/testcases/cros/kernel/syscalls/cros_sample_getcwd/Makefile
@@ -0,0 +1,10 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros/kernel/syscalls/cros_sample_getcwd test Makefile
+
+top_srcdir		?= ../../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/cros/kernel/syscalls/cros_sample_getcwd/cros_sample_getcwd02.c b/testcases/cros/kernel/syscalls/cros_sample_getcwd/cros_sample_getcwd02.c
new file mode 100644
index 0000000..c23a20b
--- /dev/null
+++ b/testcases/cros/kernel/syscalls/cros_sample_getcwd/cros_sample_getcwd02.c
@@ -0,0 +1,185 @@
+/*
+ *	Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ *	Use of this source code is governed by a BSD-style license that can be
+ *	found in the LICENSE file.
+ */
+
+/*
+ * NAME
+ *	cros_sample_getcwd02
+ *
+ * DESCRIPTION
+ *	Testcase to check the basic functionality of the getcwd(2) system call.
+ *
+ *	This was copied from the vanilla LTP getcwd test that resides under
+ *	testcases/kernel/syscalls/getcwd. It has been simplified to serve the
+ *	purpose of being a sample .c test within the cros tree.
+ *
+ * ALGORITHM
+ *	Get the path name of the current working directory from the current
+ *	shell through a pipe, and compare it with what is returned by
+ *	getcwd(2) system call.
+ *
+ *	Block 1: Call getcwd(2) with valid cwd[]:
+ *							Should work fine
+ *
+ *	Block 5: Call getcwd(2) with *buffer = NULL, size = 0:
+ *		 Should allocate buffer, and work fine
+ *
+ *	FULL REFERENCE:
+ *		http://ltp.sourceforge.net/documentation/how-to/ltp.php
+ *		Contents and organization of LTP.
+ *		Instructions for creating tests including:
+ *		-.c test template
+ *		-Bash test template
+ *
+ *	QUICK REFERENCE FOR TEST WRITING:
+ *	1. TCID, TST_TOTAL and Tst_count must be defined for the harness.
+ *	2. The test is run in a tmpdir, use setup() and cleanup() for this.
+ *	3. tst_resm() returns 0 for success and nonzero for fail.
+ *	4. Use these command line api's to indicate test status:
+ *
+ *		 Informational messages:
+ *			 tst_resm(TINFO, "Informational message...")
+ *
+ *		 PASSED test:
+ *			 tst_resm(TPASS, "Test succeeded message...");
+ *
+ *		 FAILED test:
+ *			 tst_resm(TFAIL, "Test failed message...");
+ *
+ *		 Unexpected infrastructure problem:
+ *			 tst_brkm(TBROK, <cleanup_fn or NULL>, "Unexpected ... message");
+ *
+ *		 Flavors of these commands exist that can also emit a file to include
+ *		 detailed status as follows:
+ *			 tst_res(<status>, <fname>, "tmessage...")
+ *			 tst_brk(TBROK, <fname>, <cleanup_fn>, "tmessage...")
+ *
+ *			 <tstatus> is one of:
+ *				 TINFO - informational message
+ *				 TPASS - test passed
+ *				 TFAIL - test failed
+ *				 TWARN - warning during the test
+ *	6. Add your test to $LTPROOT/runtest/cros_kernel_unittests
+ */
+#include <stdio.h>
+#include <string.h>
+#include "test.h"
+#include "usctest.h"
+#define FAILED 1
+
+char *pwd = "/bin/pwd";
+int flag;
+char *TCID = "cros_sample_getcwd02";
+int TST_TOTAL = 2;
+
+void cleanup(void);
+void setup(void);
+void do_block1(void);
+void do_block5(void);
+
+char pwd_buf[BUFSIZ];  //holds results of pwd pipe
+char cwd[BUFSIZ];			 //used as our valid buffer
+char *buffer = NULL;	//catches the return value from getcwd when passing NULL
+char *cwd_ptr = NULL;  //catches the return value from getcwd when passing cwd[]
+
+int main(int ac, char **av)
+{
+	FILE *fin;
+	char *cp;
+	int lc;			 /* loop counter */
+	char *msg;		/* parse_opts() return message */
+
+	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+	}
+	setup();
+
+	/*
+	 * The following loop checks looping state if -i option given
+	 */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		Tst_count = 0;
+
+		if ((fin = popen(pwd, "r")) == NULL) {
+			tst_resm(TINFO, "%s: can't run %s", TCID, pwd);
+			tst_brkm(TBROK, cleanup, "%s FAILED", TCID);
+		}
+		while (fgets(pwd_buf, sizeof(pwd_buf), fin) != NULL) {
+			if ((cp = strchr(pwd_buf, '\n')) == NULL) {
+				tst_brkm(TBROK, cleanup, "pwd output too long");
+			}
+			*cp = 0;
+		}
+		pclose(fin);
+
+		do_block1();
+		do_block5();
+	}
+	cleanup();
+	tst_exit();
+}
+
+void do_block1(void)		//valid cwd[]: -> Should work fine
+{
+	int flag = 0;
+	tst_resm(TINFO, "Enter Block 1");
+
+	if ((cwd_ptr = getcwd(cwd, sizeof(cwd))) == NULL) {
+		tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly.\n");
+		flag = FAILED;
+	}
+	if ((flag != FAILED) && (strcmp(pwd_buf, cwd) != 0)) {
+		tst_resm(TFAIL, "getcwd() returned unexpected working "
+			 "directory: expected: %s, got: %s\n", pwd_buf, cwd);
+		flag = FAILED;
+	}
+	tst_resm(TINFO, "Exit Block 1");
+	if (flag == FAILED) {
+		tst_resm(TFAIL, "Block 1 FAILED");
+	} else {
+		tst_resm(TPASS, "Block 1 PASSED");
+	}
+}
+
+void do_block5(void)		//buffer = NULL, and size = 0, should succeed
+{
+	int flag = 0;
+	tst_resm(TINFO, "Enter Block 5");
+
+	if ((buffer = getcwd(NULL, 0)) == NULL) {
+		tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly.\n");
+		flag = FAILED;
+	}
+	if ((flag != FAILED) && (strcmp(pwd_buf, buffer) != 0)) {
+		tst_resm(TFAIL, "getcwd() returned unexpected working "
+			 "directory: expected: %s, got: %s\n", pwd_buf, buffer);
+		flag = FAILED;
+	}
+	tst_resm(TINFO, "Exit Block 5");
+	if (flag == FAILED) {
+		tst_resm(TFAIL, "Block 5 FAILED");
+	} else {
+		tst_resm(TPASS, "Block 5 PASSED");
+	}
+	free(buffer);
+	buffer = NULL;
+}
+
+void setup(void)
+{
+	/* FORK is set here because of the popen() call above */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	TEST_PAUSE;
+
+	/* create a test directory and cd into it */
+	tst_tmpdir();
+}
+
+void cleanup(void)
+{
+	/* remove the test directory */
+	tst_rmdir();
+}
diff --git a/testcases/cros/unittests/Makefile b/testcases/cros/unittests/Makefile
new file mode 100644
index 0000000..f443316
--- /dev/null
+++ b/testcases/cros/unittests/Makefile
@@ -0,0 +1,10 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros/kernel test suite Makefile
+
+top_srcdir		?= ../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/cros/unittests/cros_unittest_sample/Makefile b/testcases/cros/unittests/cros_unittest_sample/Makefile
new file mode 100644
index 0000000..d9f9b7a
--- /dev/null
+++ b/testcases/cros/unittests/cros_unittest_sample/Makefile
@@ -0,0 +1,11 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Makefile for cros/unittests/cros_unittest_sample test
+#
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/cros/unittests/cros_unittest_sample/cros_unittest_sample.c b/testcases/cros/unittests/cros_unittest_sample/cros_unittest_sample.c
new file mode 100644
index 0000000..3a9a187
--- /dev/null
+++ b/testcases/cros/unittests/cros_unittest_sample/cros_unittest_sample.c
@@ -0,0 +1,64 @@
+/*
+ *	Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ *	Use of this source code is governed by a BSD-style license that can be
+ *	found in the LICENSE file.
+ */
+
+/*
+ * NAME
+ *  cros_unittest_sample
+ *
+ * DESCRIPTION
+ *  Testcase to demonstrate simple kernel unittests for ChromeOS.
+ *  While cros_sample_getcwd02 is a sample ChromeOS test, it uses the LTP
+ *  test template.  This test shows a method of writing a simpler test
+ *  that does not use the LTP template pattern. Instead, this test is
+ *  simply expected to run and return 0 (success) or nonzero (failure).
+ *
+ *  A ChromeOS .sh wrapper will be automatically generated with any
+ *  needed LTP library calls to allow the test to run under the LTP harness.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+char *pwd = "/bin/pwd";
+
+char pwd_buf[BUFSIZ];  //holds results of pwd pipe
+char cwd[BUFSIZ];			 //used as our valid buffer
+char *buffer = NULL;	//catches the return value from getcwd when passing NULL
+char *cwd_ptr = NULL;  //catches the return value from getcwd when passing cwd[]
+
+int main()
+{
+	FILE *fin;
+	char *cp;
+
+	/*
+	 * valid cwd[]: -> Should work fine
+	 */
+	if ((fin = popen(pwd, "r")) == NULL) {
+		fprintf(stderr, "Cannot run %s\n", pwd);
+		exit(1);
+	}
+	while (fgets(pwd_buf, sizeof(pwd_buf), fin) != NULL) {
+		if ((cp = strchr(pwd_buf, '\n')) == NULL) {
+			pclose(fin);
+			fprintf(stderr, "No newline\n");
+			exit(1);
+		}
+		*cp = 0;
+	}
+	pclose(fin);
+
+	if ((cwd_ptr = getcwd(cwd, sizeof(cwd))) == NULL) {
+		fprintf(stderr, "getcwd() returned NULL\n");
+		exit(1);
+	}
+	if (strcmp(pwd_buf, cwd) != 0) {
+		fprintf(stderr, "No match (%s, %s)\n", pwd_buf, cwd);
+		exit(1);
+	}
+	exit(0);
+}
diff --git a/testcases/cros/unittests/regen_manifest/Makefile b/testcases/cros/unittests/regen_manifest/Makefile
new file mode 100644
index 0000000..cf6a9be
--- /dev/null
+++ b/testcases/cros/unittests/regen_manifest/Makefile
@@ -0,0 +1,16 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros/commands/cros_sample_crossystem test Makefile
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+MAKE_TARGETS		:= cros_kernel_unittests.manifest
+
+cros_kernel_unittests.manifest: $(wildcard $(srcdir)/*.sh)
+	$(SHELL) "$(abs_srcdir)/regen_manifest.sh"
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/cros/unittests/regen_manifest/regen_manifest.sh b/testcases/cros/unittests/regen_manifest/regen_manifest.sh
new file mode 100644
index 0000000..96d3490
--- /dev/null
+++ b/testcases/cros/unittests/regen_manifest/regen_manifest.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# FILE:				regen_manifest.sh
+#
+# DESCRIPTION: Generate cros unittests test manifest file.
+#
+# AUTHOR:			 truty@chromium.org
+#
+
+MANIFEST=./cros_kernel_unittests.manifest
+
+find ../../unittests/ -type f -name '*.c' -printf '%f\n' | \
+	sed 's:[.]c$::' \
+	> "${MANIFEST}"
diff --git a/testcases/cros/unittests/wrapper/00_Descriptions.txt b/testcases/cros/unittests/wrapper/00_Descriptions.txt
new file mode 100644
index 0000000..4943f7e
--- /dev/null
+++ b/testcases/cros/unittests/wrapper/00_Descriptions.txt
@@ -0,0 +1,2 @@
+cros_unittests
+  Wrapper to run all cros unittests
diff --git a/testcases/cros/unittests/wrapper/Makefile b/testcases/cros/unittests/wrapper/Makefile
new file mode 100644
index 0000000..31a7f74
--- /dev/null
+++ b/testcases/cros/unittests/wrapper/Makefile
@@ -0,0 +1,15 @@
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# cros/commands/cros_sample_crossystem test Makefile
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+INSTALL_TARGETS		:= cros_unittests_wrapper.sh
+
+MAKE_TARGETS		:=
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/cros/unittests/wrapper/cros_unittests_wrapper.sh b/testcases/cros/unittests/wrapper/cros_unittests_wrapper.sh
new file mode 100755
index 0000000..e02ce5c
--- /dev/null
+++ b/testcases/cros/unittests/wrapper/cros_unittests_wrapper.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# FILE:				cros_unittests_wrapper.sh
+#
+# DESCRIPTION: Runs cros unittests programs.
+#
+# AUTHOR:			 truty@chromium.org
+#
+
+MANIFEST=./cros_kernel_unittests.manifest
+
+
+setup()
+{
+	# Required by LTP command line harness APIs:
+	export TST_TOTAL=$(wc -l < "${MANIFEST}")
+	export TCID="setup" # Test case identifier
+	export TST_COUNT=0	# Set up is initialized as test 0
+}
+
+
+run_unittest()
+{
+	# Run unittest with name supplied by $1
+	local test_name=$1
+	TCID="${test_name}"
+	TST_COUNT=$(( TST_COUNT += 1 ))
+
+	tst_resm TINFO "Test #${TST_COUNT}: ${test_name}"
+	./${test_name}
+	if [ $? -ne 0 ]; then
+		tst_resm TFAIL "Test ${test_name} failed."
+		return 1
+	fi
+	tst_resm TPASS "Test ${test_name} succeeded"
+	return 0
+}
+
+
+# Function:			main
+#
+# Description:	- Execute all tests, exit with test status.
+#
+# Exit:					- zero on success
+#								- non-zero on failure.
+#
+setup || exit $?
+
+RC=0
+while read test; do
+	run_unittest "${test}"
+	: $(( RC |= $? ))
+done < "${MANIFEST}"
+exit ${RC}