[PATCH 03/15] android/tester-ng: Add state machine handling mechanism and simple tester

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This adds simple test and state machine handling for test cases.
---
 android/android-tester-ng.c | 193 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 182 insertions(+), 11 deletions(-)

diff --git a/android/android-tester-ng.c b/android/android-tester-ng.c
index 272414d..f97da81 100644
--- a/android/android-tester-ng.c
+++ b/android/android-tester-ng.c
@@ -34,10 +34,33 @@
 #include "src/shared/tester.h"
 #include "src/shared/hciemu.h"
 #include "src/shared/mgmt.h"
+#include "src/shared/queue.h"
 
 #include <hardware/hardware.h>
 #include <hardware/bluetooth.h>
 
+/*
+ * Struct of data to check within step action.
+ */
+struct bt_action_data {
+	uint8_t status;
+};
+
+/*
+ * Step structure contains expected step data and step
+ * action, which should be performed before step check.
+ */
+struct step {
+	void (*action)(void);
+	struct bt_action_data action_result;
+
+};
+
+struct test_steps {
+	struct step *step;
+	uint16_t step_num;
+};
+
 struct test_data {
 	struct mgmt *mgmt;
 	struct hw_device_t *device;
@@ -47,6 +70,7 @@ struct test_data {
 	const bt_interface_t *if_bluetooth;
 
 	const void *test_data;
+	struct queue *steps;
 
 	guint signalfd;
 	uint16_t mgmt_index;
@@ -374,6 +398,85 @@ static void test_pre_setup(const void *test_data)
 				NULL, read_index_list_callback, NULL, NULL);
 }
 
+/*
+ * Check each test case step if test case expected
+ * data is set and match it with expected result.
+ */
+static bool match_data(struct step *step)
+{
+	struct test_data *data = tester_get_data();
+	const struct step *exp;
+
+	exp = queue_peek_head(data->steps);
+
+	if (!exp) {
+		/* Can occure while test passed already */
+		tester_debug("Cannot get step to match");
+		return false;
+	}
+
+	if (exp->action_result.status && (exp->action_result.status !=
+						step->action_result.status)) {
+		tester_debug("Action status don't match");
+		return false;
+	}
+	return true;
+}
+
+/*
+ * Steps are initialized before test case run.
+ */
+static void init_test_steps(struct test_data *data)
+{
+	const struct test_steps *test_steps = data->test_data;
+	int i = 0;
+
+	for (i = 0; i < test_steps->step_num; i++)
+		queue_push_tail(data->steps, &(test_steps->step[i]));
+
+	tester_print("tester: Number of test steps=%d",
+						queue_length(data->steps));
+}
+
+/*
+ * Each test case step should be verified, if match with
+ * expected result tester should go to next test step.
+ */
+static void verify_step(struct step *step, queue_destroy_func_t cleanup_cb)
+{
+	struct test_data *data = tester_get_data();
+	const struct test_steps *test_steps = data->test_data;
+	struct step *next_step;
+
+	tester_debug("tester: STEP[%d]",
+			test_steps->step_num-queue_length(data->steps) + 1);
+
+	if (step && !match_data(step)) {
+		if (cleanup_cb)
+			cleanup_cb(step);
+
+		return;
+	}
+
+	queue_pop_head(data->steps);
+
+	if (cleanup_cb)
+		cleanup_cb(step);
+
+	if (queue_isempty(data->steps)) {
+		tester_print("tester: All steps done, passing");
+		tester_test_passed();
+
+		return;
+	}
+
+	/* goto next step action if declared in step */
+	next_step = queue_peek_head(data->steps);
+
+	if (next_step->action)
+		next_step->action();
+}
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = NULL,
@@ -446,6 +549,10 @@ static bool setup_base(struct test_data *data)
 	if (!data->if_bluetooth)
 		return false;
 
+	if (!(data->steps = queue_new()))
+		return false;
+
+
 	return true;
 }
 
@@ -473,6 +580,9 @@ static void teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 
+	queue_destroy(data->steps, NULL);
+	data->steps = NULL;
+
 	if (data->if_bluetooth) {
 		data->if_bluetooth->cleanup();
 		data->if_bluetooth = NULL;
@@ -484,35 +594,92 @@ static void teardown(const void *test_data)
 		tester_teardown_complete();
 }
 
-static void test_dummy(const void *test_data)
+static void dummy_action(void)
+{
+	struct step step;
+
+	memset(&step, 0, sizeof(step));
+	step.action = dummy_action;
+
+	verify_step(&step, NULL);
+}
+
+static void bluetooth_enable_action(void)
 {
-	tester_test_passed();
+	struct test_data *data = tester_get_data();
+	struct step step;
+
+	memset(&step, 0, sizeof(step));
+	step.action_result.status = data->if_bluetooth->enable();
+
+	verify_step(&step, NULL);
+}
+
+static void generic_test_function(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct step *first_step;
+
+	init_test_steps(data);
+
+	/* first step action */
+	first_step = queue_peek_head(data->steps);
+	if (!first_step->action) {
+		tester_print("tester: No initial action declared");
+		tester_test_failed();
+		return;
+	}
+
+	first_step->action();
 }
 
+static struct step dummy_steps[] = {
+	{
+	.action = dummy_action,
+	},
+};
+
+static struct step bluetooth_enable_steps[] = {
+	{
+	.action_result.status = BT_STATUS_SUCCESS,
+	.action = bluetooth_enable_action,
+	},
+};
+
+#define TEST_DATA_CREATE(step_data) \
+	static struct test_steps step_data##_data = { \
+		.step_num = sizeof(step_data) / sizeof(struct step), \
+		.step = step_data, \
+	}
+
+#define TEST_DATA_GET(step_data) step_data##_data
+
 #define test_bredr(name, data, test_setup, test, test_teardown) \
 	do { \
+		TEST_DATA_CREATE(data); \
 		struct test_data *user; \
 		user = g_malloc0(sizeof(struct test_data)); \
 		if (!user) \
 			break; \
 		user->hciemu_type = HCIEMU_TYPE_BREDR; \
-		user->test_data = data; \
-		tester_add_full(name, data, test_pre_setup, test_setup, \
-				test, test_teardown, test_post_teardown, \
-							3, user, g_free); \
+		user->test_data = &TEST_DATA_GET(data); \
+		tester_add_full(name, &TEST_DATA_GET(data), test_pre_setup, \
+					test_setup, test, test_teardown, \
+					test_post_teardown, 3, user, g_free); \
 	} while (0)
 
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
 	do { \
+		TEST_DATA_CREATE(data); \
 		struct test_data *user; \
 		user = g_malloc0(sizeof(struct test_data)); \
 		if (!user) \
 			break; \
 		user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
-		user->test_data = data; \
-		tester_add_full(name, data, test_pre_setup, test_setup, \
-				test, test_teardown, test_post_teardown, \
-							3, user, g_free); \
+		user->test_data = &TEST_DATA_GET(data); \
+		tester_add_full(name, &TEST_DATA_GET(data), test_pre_setup, \
+					test_setup, test, test_teardown, \
+					test_post_teardown, 3, user, g_free); \
 	} while (0)
 
 int main(int argc, char *argv[])
@@ -521,7 +688,11 @@ int main(int argc, char *argv[])
 
 	tester_init(&argc, &argv);
 
-	test_bredrle("Bluetooth Init", NULL, setup, test_dummy, teardown);
+	test_bredr("Bluetooth Init", dummy_steps, setup, generic_test_function,
+								teardown);
+
+	test_bredrle("Bluetooth Enable", bluetooth_enable_steps, setup,
+					generic_test_function, teardown);
 
 	return tester_run();
 }
-- 
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux