2013-12-11 10:46:31

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH v4 1/7] android/tester: Add android-tester

This commit add android-tester.c to tree and Makefile.am.
This will contain set of unit tests for testing android daemon.
---
.gitignore | 1 +
android/Makefile.am | 4 ++++
android/android-tester.c | 21 +++++++++++++++++++++
3 files changed, 26 insertions(+)
create mode 100644 android/android-tester.c

diff --git a/.gitignore b/.gitignore
index 2d3435a..c570728 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,3 +107,4 @@ unit/test-*.trs
android/system-emulator
android/bluetoothd
android/haltest
+android/android-tester
diff --git a/android/Makefile.am b/android/Makefile.am
index df04762..0768985 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -83,6 +83,10 @@ android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \

android_haltest_LDFLAGS = -pthread

+noinst_PROGRAMS += android/android-tester
+
+android_android_tester_SOURCES = android/android-tester.c
+
endif

EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
diff --git a/android/android-tester.c b/android/android-tester.c
new file mode 100644
index 0000000..f5c42b0
--- /dev/null
+++ b/android/android-tester.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed 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.
+ *
+ */
+
+int main(int argc, char *argv[])
+{
+ return 0;
+}
--
1.8.3.1



2013-12-11 11:15:39

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH v4 1/7] android/tester: Add android-tester

Hi Marcin,

On Wed, Dec 11, 2013 at 12:46 PM, Marcin Kraglak
<[email protected]> wrote:
> This commit add android-tester.c to tree and Makefile.am.
> This will contain set of unit tests for testing android daemon.
> ---
> .gitignore | 1 +
> android/Makefile.am | 4 ++++
> android/android-tester.c | 21 +++++++++++++++++++++
> 3 files changed, 26 insertions(+)
> create mode 100644 android/android-tester.c
>
> diff --git a/.gitignore b/.gitignore
> index 2d3435a..c570728 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -107,3 +107,4 @@ unit/test-*.trs
> android/system-emulator
> android/bluetoothd
> android/haltest
> +android/android-tester
> diff --git a/android/Makefile.am b/android/Makefile.am
> index df04762..0768985 100644
> --- a/android/Makefile.am
> +++ b/android/Makefile.am
> @@ -83,6 +83,10 @@ android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
>
> android_haltest_LDFLAGS = -pthread
>
> +noinst_PROGRAMS += android/android-tester
> +
> +android_android_tester_SOURCES = android/android-tester.c
> +
> endif
>
> EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
> diff --git a/android/android-tester.c b/android/android-tester.c
> new file mode 100644
> index 0000000..f5c42b0
> --- /dev/null
> +++ b/android/android-tester.c
> @@ -0,0 +1,21 @@
> +/*
> + * Copyright (C) 2013 Intel Corporation
> + *
> + * Licensed 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.
> + *
> + */
> +
> +int main(int argc, char *argv[])
> +{
> + return 0;
> +}
> --
> 1.8.3.1

Applied, thanks.


--
Luiz Augusto von Dentz

2013-12-11 11:10:38

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCH v4 3/7] android/tester: Start emulator in new process

Hi Marcin,

On Wed, Dec 11, 2013 at 11:46:33AM +0100, Marcin Kraglak wrote:
> This is needed because bluetooth->init call is blocking,
> and we have to emulate normal behaviour of android environment.
> That process will exit if it won't receive any message in 2 sec
> or when bluetoothd will exit. Main tester thread will wait for
> this process in teardown method.
> ---
> android/android-tester.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 131 insertions(+), 1 deletion(-)
>
> diff --git a/android/android-tester.c b/android/android-tester.c
> index 498da22..ad7aa39 100644
> --- a/android/android-tester.c
> +++ b/android/android-tester.c
> @@ -15,9 +15,15 @@
> *
> */
>
> +#include <stdlib.h>
> #include <unistd.h>
>
> #include <glib.h>
> +#include <sys/socket.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <sys/un.h>
> +#include <libgen.h>
>
> #include "lib/bluetooth.h"
> #include "lib/mgmt.h"
> @@ -29,14 +35,20 @@
> struct generic_data {
> };
>
> +#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
> +#define EMULATOR_SIGNAL "emulator_started"
> +
> struct test_data {
> struct mgmt *mgmt;
> uint16_t mgmt_index;
> struct hciemu *hciemu;
> enum hciemu_type hciemu_type;
> const struct generic_data *test_data;
> + pid_t bluetoothd_pid;
> };
>
> +static char exec_dir[PATH_MAX + 1];
> +
> static void read_info_callback(uint8_t status, uint16_t length,
> const void *param, void *user_data)
> {
> @@ -165,13 +177,129 @@ static void test_post_teardown(const void *test_data)
> data->hciemu = NULL;
> }
>
> +static void bluetoothd_start(int hci_index)
> +{
> + char prg_name[PATH_MAX + 1];
> + char index[8];
> + char *prg_argv[4];
> +
> + snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
> + snprintf(index, sizeof(index), "%d", hci_index);
> +
> + prg_argv[0] = prg_name;
> + prg_argv[1] = "-i";
> + prg_argv[2] = index;
> + prg_argv[3] = NULL;
> +
> + if (!tester_use_debug())
> + fclose(stderr);
> +
> + execve(prg_argv[0], prg_argv, NULL);
> +}
> +
> +static void emulator(int pipe, int hci_index)
> +{
> + static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
> + char buf[1024];
> + struct sockaddr_un addr;
> + struct timeval tv;
> + int fd;
> + ssize_t len;
> +
> + fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
> + if (fd < 0)
> + goto failed;

return? otherwise you close invalid fd, or check fd in failed

> +
> + tv.tv_sec = WAIT_FOR_SIGNAL_TIME;
> + tv.tv_usec = 0;
> + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
> +
> + memset(&addr, 0, sizeof(addr));
> + addr.sun_family = AF_UNIX;
> + memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
> +
> + if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
> + perror("Failed to bind system socket");
> + goto failed;
> + }
> +
> + len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL));
> +

we do not need here empty space

Best regards
Andrei Emeltchenko
> + if (len != sizeof(EMULATOR_SIGNAL))
> + goto failed;
> +
> + memset(buf, 0, sizeof(buf));
> +
> + len = read(fd, buf, sizeof(buf));
> + if (len <= 0 || (strcmp(buf, "ctl.start=bluetoothd")))
> + goto failed;
> +
> + close(pipe);
> + close(fd);
> + bluetoothd_start(hci_index);
> +
> +failed:
> + close(pipe);
> + close(fd);
> +}
> +
> +static void setup(struct test_data *data)
> +{
> + int signal_fd[2];
> + char buf[1024];
> + pid_t pid;
> + int len;
> +
> + if (pipe(signal_fd)) {
> + tester_setup_failed();
> + return;
> + }
> +
> + pid = fork();
> +
> + if (pid < 0) {
> + close(signal_fd[0]);
> + close(signal_fd[1]);
> + tester_setup_failed();
> + return;
> + }
> +
> + if (pid == 0) {
> + if (!tester_use_debug())
> + fclose(stderr);
> +
> + close(signal_fd[0]);
> + emulator(signal_fd[1], data->mgmt_index);
> + exit(0);
> + }
> +
> + close(signal_fd[1]);
> + data->bluetoothd_pid = pid;
> +
> + len = read(signal_fd[0], buf, sizeof(buf));
> + if (len <= 0 || (strcmp(buf, EMULATOR_SIGNAL))) {
> + close(signal_fd[0]);
> + tester_setup_failed();
> + return;
> + }
> +}
> +
> static void setup_base(const void *test_data)
> {
> - tester_setup_failed();
> + struct test_data *data = tester_get_data();
> +
> + setup(data);
> +
> + tester_setup_complete();
> }
>
> static void teardown(const void *test_data)
> {
> + struct test_data *data = tester_get_data();
> +
> + if (data->bluetoothd_pid)
> + waitpid(data->bluetoothd_pid, NULL, 0);
> +
> tester_teardown_complete();
> }
>
> @@ -194,6 +322,8 @@ static void controller_setup(const void *test_data)
>
> int main(int argc, char *argv[])
> {
> + snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
> +
> tester_init(&argc, &argv);
>
> test_bredrle("Test Init", NULL, setup_base, controller_setup, teardown);
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2013-12-11 10:46:32

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH v4 2/7] android/tester: Add pre-setup and post-teardown routines

This will add hciemu initialization and cleanup. These functions
will be called to create hci emulator and cleanup it.
---
android/Makefile.am | 10 ++-
android/android-tester.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 191 insertions(+), 2 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 0768985..5364c2e 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -85,7 +85,15 @@ android_haltest_LDFLAGS = -pthread

noinst_PROGRAMS += android/android-tester

-android_android_tester_SOURCES = android/android-tester.c
+android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
+ emulator/bthost.h emulator/bthost.c \
+ src/shared/util.h src/shared/util.c \
+ src/shared/mgmt.h src/shared/mgmt.c \
+ src/shared/hciemu.h src/shared/hciemu.c \
+ src/shared/tester.h src/shared/tester.c \
+ android/android-tester.c
+
+android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@

endif

diff --git a/android/android-tester.c b/android/android-tester.c
index f5c42b0..498da22 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -15,7 +15,188 @@
*
*/

+#include <unistd.h>
+
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+
+#include "src/shared/tester.h"
+#include "src/shared/mgmt.h"
+#include "src/shared/hciemu.h"
+
+struct generic_data {
+};
+
+struct test_data {
+ struct mgmt *mgmt;
+ uint16_t mgmt_index;
+ struct hciemu *hciemu;
+ enum hciemu_type hciemu_type;
+ const struct generic_data *test_data;
+};
+
+static void read_info_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct mgmt_rp_read_info *rp = param;
+ char addr[18];
+ uint16_t manufacturer;
+ uint32_t supported_settings, current_settings;
+
+ tester_print("Read Info callback");
+ tester_print(" Status: 0x%02x", status);
+
+ if (status || !param) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ ba2str(&rp->bdaddr, addr);
+ manufacturer = btohs(rp->manufacturer);
+ supported_settings = btohl(rp->supported_settings);
+ current_settings = btohl(rp->current_settings);
+
+ tester_print(" Address: %s", addr);
+ tester_print(" Version: 0x%02x", rp->version);
+ tester_print(" Manufacturer: 0x%04x", manufacturer);
+ tester_print(" Supported settings: 0x%08x", supported_settings);
+ tester_print(" Current settings: 0x%08x", current_settings);
+ tester_print(" Class: 0x%02x%02x%02x",
+ rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
+ tester_print(" Name: %s", rp->name);
+ tester_print(" Short name: %s", rp->short_name);
+
+ if (strcmp(hciemu_get_address(data->hciemu), addr)) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ tester_pre_setup_complete();
+}
+
+static void index_added_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Index Added callback");
+ tester_print(" Index: 0x%04x", index);
+
+ data->mgmt_index = index;
+
+ mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
+ read_info_callback, NULL, NULL);
+}
+
+static void index_removed_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Index Removed callback");
+ tester_print(" Index: 0x%04x", index);
+
+ if (index != data->mgmt_index)
+ return;
+
+ mgmt_unregister_index(data->mgmt, data->mgmt_index);
+
+ mgmt_unref(data->mgmt);
+ data->mgmt = NULL;
+
+ tester_post_teardown_complete();
+}
+
+static void read_index_list_callback(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+
+ tester_print("Read Index List callback");
+ tester_print(" Status: 0x%02x", status);
+
+ if (status || !param) {
+ tester_pre_setup_failed();
+ return;
+ }
+
+ mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+ index_added_callback, NULL, NULL);
+
+ mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+ index_removed_callback, NULL, NULL);
+
+ data->hciemu = hciemu_new(data->hciemu_type);
+ if (!data->hciemu) {
+ tester_warn("Failed to setup HCI emulation");
+ tester_pre_setup_failed();
+ return;
+ }
+
+ tester_print("New hciemu instance created");
+}
+
+static void test_pre_setup(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ if (!tester_use_debug())
+ fclose(stderr);
+
+ data->mgmt = mgmt_new_default();
+ if (!data->mgmt) {
+ tester_warn("Failed to setup management interface");
+ tester_pre_setup_failed();
+ return;
+ }
+
+ mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+ NULL, read_index_list_callback, NULL, NULL);
+}
+
+static void test_post_teardown(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ hciemu_unref(data->hciemu);
+ data->hciemu = NULL;
+}
+
+static void setup_base(const void *test_data)
+{
+ tester_setup_failed();
+}
+
+static void teardown(const void *test_data)
+{
+ tester_teardown_complete();
+}
+
+static void controller_setup(const void *test_data)
+{
+}
+
+#define test_bredrle(name, data, test_setup, test, test_teardown) \
+ do { \
+ 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); \
+ } while (0)
+
int main(int argc, char *argv[])
{
- return 0;
+ tester_init(&argc, &argv);
+
+ test_bredrle("Test Init", NULL, setup_base, controller_setup, teardown);
+
+ return tester_run();
}
--
1.8.3.1


2013-12-11 10:46:33

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH v4 3/7] android/tester: Start emulator in new process

This is needed because bluetooth->init call is blocking,
and we have to emulate normal behaviour of android environment.
That process will exit if it won't receive any message in 2 sec
or when bluetoothd will exit. Main tester thread will wait for
this process in teardown method.
---
android/android-tester.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 131 insertions(+), 1 deletion(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 498da22..ad7aa39 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -15,9 +15,15 @@
*
*/

+#include <stdlib.h>
#include <unistd.h>

#include <glib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <libgen.h>

#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -29,14 +35,20 @@
struct generic_data {
};

+#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
+#define EMULATOR_SIGNAL "emulator_started"
+
struct test_data {
struct mgmt *mgmt;
uint16_t mgmt_index;
struct hciemu *hciemu;
enum hciemu_type hciemu_type;
const struct generic_data *test_data;
+ pid_t bluetoothd_pid;
};

+static char exec_dir[PATH_MAX + 1];
+
static void read_info_callback(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -165,13 +177,129 @@ static void test_post_teardown(const void *test_data)
data->hciemu = NULL;
}

+static void bluetoothd_start(int hci_index)
+{
+ char prg_name[PATH_MAX + 1];
+ char index[8];
+ char *prg_argv[4];
+
+ snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
+ snprintf(index, sizeof(index), "%d", hci_index);
+
+ prg_argv[0] = prg_name;
+ prg_argv[1] = "-i";
+ prg_argv[2] = index;
+ prg_argv[3] = NULL;
+
+ if (!tester_use_debug())
+ fclose(stderr);
+
+ execve(prg_argv[0], prg_argv, NULL);
+}
+
+static void emulator(int pipe, int hci_index)
+{
+ static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
+ char buf[1024];
+ struct sockaddr_un addr;
+ struct timeval tv;
+ int fd;
+ ssize_t len;
+
+ fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ goto failed;
+
+ tv.tv_sec = WAIT_FOR_SIGNAL_TIME;
+ tv.tv_usec = 0;
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
+
+ if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ perror("Failed to bind system socket");
+ goto failed;
+ }
+
+ len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL));
+
+ if (len != sizeof(EMULATOR_SIGNAL))
+ goto failed;
+
+ memset(buf, 0, sizeof(buf));
+
+ len = read(fd, buf, sizeof(buf));
+ if (len <= 0 || (strcmp(buf, "ctl.start=bluetoothd")))
+ goto failed;
+
+ close(pipe);
+ close(fd);
+ bluetoothd_start(hci_index);
+
+failed:
+ close(pipe);
+ close(fd);
+}
+
+static void setup(struct test_data *data)
+{
+ int signal_fd[2];
+ char buf[1024];
+ pid_t pid;
+ int len;
+
+ if (pipe(signal_fd)) {
+ tester_setup_failed();
+ return;
+ }
+
+ pid = fork();
+
+ if (pid < 0) {
+ close(signal_fd[0]);
+ close(signal_fd[1]);
+ tester_setup_failed();
+ return;
+ }
+
+ if (pid == 0) {
+ if (!tester_use_debug())
+ fclose(stderr);
+
+ close(signal_fd[0]);
+ emulator(signal_fd[1], data->mgmt_index);
+ exit(0);
+ }
+
+ close(signal_fd[1]);
+ data->bluetoothd_pid = pid;
+
+ len = read(signal_fd[0], buf, sizeof(buf));
+ if (len <= 0 || (strcmp(buf, EMULATOR_SIGNAL))) {
+ close(signal_fd[0]);
+ tester_setup_failed();
+ return;
+ }
+}
+
static void setup_base(const void *test_data)
{
- tester_setup_failed();
+ struct test_data *data = tester_get_data();
+
+ setup(data);
+
+ tester_setup_complete();
}

static void teardown(const void *test_data)
{
+ struct test_data *data = tester_get_data();
+
+ if (data->bluetoothd_pid)
+ waitpid(data->bluetoothd_pid, NULL, 0);
+
tester_teardown_complete();
}

@@ -194,6 +322,8 @@ static void controller_setup(const void *test_data)

int main(int argc, char *argv[])
{
+ snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
+
tester_init(&argc, &argv);

test_bredrle("Test Init", NULL, setup_base, controller_setup, teardown);
--
1.8.3.1


2013-12-11 10:46:34

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH v4 4/7] android/tester: Add stack initialization of stack in setup

This add stack initialization and cleanup in setup/teardown.
---
android/Makefile.am | 10 +++++++--
android/android-tester.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 5364c2e..f3e77c3 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -91,9 +91,15 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
src/shared/mgmt.h src/shared/mgmt.c \
src/shared/hciemu.h src/shared/hciemu.c \
src/shared/tester.h src/shared/tester.c \
- android/android-tester.c
+ android/hal-utils.h android/hal-utils.c \
+ android/client/hwmodule.c android/android-tester.c

-android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+android_android_tester_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
+
+android_android_tester_LDADD = lib/libbluetooth-internal.la \
+ android/libhal-internal.la @GLIB_LIBS@
+
+android_android_tester_LDFLAGS = -pthread

endif

diff --git a/android/android-tester.c b/android/android-tester.c
index ad7aa39..15f8c61 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -32,6 +32,9 @@
#include "src/shared/mgmt.h"
#include "src/shared/hciemu.h"

+#include <hardware/hardware.h>
+#include <hardware/bluetooth.h>
+
struct generic_data {
};

@@ -45,6 +48,7 @@ struct test_data {
enum hciemu_type hciemu_type;
const struct generic_data *test_data;
pid_t bluetoothd_pid;
+ const bt_interface_t *if_bluetooth;
};

static char exec_dir[PATH_MAX + 1];
@@ -243,12 +247,32 @@ failed:
close(fd);
}

+static bt_callbacks_t bt_callbacks = {
+ .size = sizeof(bt_callbacks),
+ .adapter_state_changed_cb = NULL,
+ .adapter_properties_cb = NULL,
+ .remote_device_properties_cb = NULL,
+ .device_found_cb = NULL,
+ .discovery_state_changed_cb = NULL,
+ .pin_request_cb = NULL,
+ .ssp_request_cb = NULL,
+ .bond_state_changed_cb = NULL,
+ .acl_state_changed_cb = NULL,
+ .thread_evt_cb = NULL,
+ .dut_mode_recv_cb = NULL,
+ .le_test_mode_cb = NULL
+};
+
static void setup(struct test_data *data)
{
+ const hw_module_t *module;
+ hw_device_t *device;
+ bt_status_t status;
int signal_fd[2];
char buf[1024];
pid_t pid;
int len;
+ int err;

if (pipe(signal_fd)) {
tester_setup_failed();
@@ -282,6 +306,33 @@ static void setup(struct test_data *data)
tester_setup_failed();
return;
}
+
+ close(signal_fd[0]);
+
+ err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
+ if (err) {
+ tester_setup_failed();
+ return;
+ }
+
+ err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
+ if (err) {
+ tester_setup_failed();
+ return;
+ }
+
+ data->if_bluetooth = ((bluetooth_device_t *)
+ device)->get_bluetooth_interface();
+ if (!data->if_bluetooth) {
+ tester_setup_failed();
+ return;
+ }
+
+ status = data->if_bluetooth->init(&bt_callbacks);
+ if (status != BT_STATUS_SUCCESS) {
+ data->if_bluetooth = NULL;
+ tester_setup_failed();
+ }
}

static void setup_base(const void *test_data)
@@ -297,6 +348,11 @@ static void teardown(const void *test_data)
{
struct test_data *data = tester_get_data();

+ if (data->if_bluetooth) {
+ data->if_bluetooth->cleanup();
+ data->if_bluetooth = NULL;
+ }
+
if (data->bluetoothd_pid)
waitpid(data->bluetoothd_pid, NULL, 0);

@@ -305,6 +361,7 @@ static void teardown(const void *test_data)

static void controller_setup(const void *test_data)
{
+ tester_test_passed();
}

#define test_bredrle(name, data, test_setup, test, test_teardown) \
--
1.8.3.1


2013-12-11 10:46:35

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH v4 5/7] android/tester: Make HAL logging wrapper print to stderr instead of stdout

From: Szymon Janc <[email protected]>

This is used for testing and for user it makes no difference. This
will allow to switch on/off verbose logging from automated android
tester.

---
android/hal-log.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-log.h b/android/hal-log.h
index 9bd024d..63ff61b 100644
--- a/android/hal-log.h
+++ b/android/hal-log.h
@@ -25,7 +25,7 @@
#define LOG_WARN " W"
#define LOG_ERROR " E"
#define LOG_DEBUG " D"
-#define ALOG(pri, tag, fmt, arg...) printf(tag pri": " fmt"\n", ##arg)
+#define ALOG(pri, tag, fmt, arg...) fprintf(stderr, tag pri": " fmt"\n", ##arg)
#endif

#define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg)
--
1.8.3.1


2013-12-11 10:46:37

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH v4 7/7] android/tester: Add status check and adapter enable, disable test cases

From: Grzegorz Kolodziejczyk <[email protected]>

This adds handling of status check, enabled adapter setup method,
disable and enable fail test case.

---
android/android-tester.c | 108 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 103 insertions(+), 5 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 0dc1edf..09c76c9 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -46,6 +46,7 @@

enum hal_bluetooth_callbacks_id {
adapter_test_end,
+ adapter_test_setup_mode,
adapter_state_changed_on,
adapter_state_changed_off,
adapter_prop_bdaddr,
@@ -59,6 +60,7 @@ enum hal_bluetooth_callbacks_id {
};

struct generic_data {
+ uint8_t expected_adapter_status;
uint32_t expect_settings_set;
uint8_t expected_hal_callbacks[];
};
@@ -78,6 +80,7 @@ struct test_data {

bool mgmt_settings_set;
bool hal_cb_called;
+ bool status_checked;

GSList *expected_callbacks;
};
@@ -88,8 +91,13 @@ static void test_update_state(void)
{
struct test_data *data = tester_get_data();

- if (data->mgmt_settings_set && data->hal_cb_called)
- tester_test_passed();
+ if (!(data->mgmt_settings_set))
+ return;
+ if (!(data->hal_cb_called))
+ return;
+ if (!(data->status_checked))
+ return;
+ tester_test_passed();
}

static void test_mgmt_settings_set(struct test_data *data)
@@ -143,10 +151,38 @@ static void mgmt_cb_init(struct test_data *data)
command_generic_new_settings, NULL, NULL);
}

+static void expected_status_init(struct test_data *data)
+{
+ if (!(data->test_data->expected_adapter_status))
+ data->status_checked = true;
+}
+
+static void init_test_conditions(struct test_data *data)
+{
+ hal_cb_init(data);
+ mgmt_cb_init(data);
+ expected_status_init(data);
+}
+
+static void check_expected_status(uint8_t status)
+{
+ struct test_data *data = tester_get_data();
+
+ if (data->test_data->expected_adapter_status == status)
+ data->status_checked = true;
+ else
+ tester_test_failed();
+
+ test_update_state();
+}
+
static int get_expected_hal_cb(void)
{
struct test_data *data = tester_get_data();

+ if (!(g_slist_length(data->expected_callbacks)))
+ return adapter_test_setup_mode;
+
return GPOINTER_TO_INT(data->expected_callbacks->data);
}

@@ -359,13 +395,28 @@ failed:

static void adapter_state_changed_cb(bt_state_t state)
{
- switch (get_expected_hal_cb()) {
+ enum hal_bluetooth_callbacks_id hal_cb;
+
+ hal_cb = get_expected_hal_cb();
+
+ switch (hal_cb) {
case adapter_state_changed_on:
if (state == BT_STATE_ON)
remove_expected_hal_cb();
else
tester_test_failed();
break;
+ case adapter_state_changed_off:
+ if (state == BT_STATE_OFF)
+ remove_expected_hal_cb();
+ else
+ tester_test_failed();
+ break;
+ case adapter_test_setup_mode:
+ if (state == BT_STATE_ON)
+ tester_setup_complete();
+ else
+ tester_setup_failed();
default:
break;
}
@@ -379,6 +430,10 @@ static void adapter_properties_cb(bt_status_t status, int num_properties,

for (i = 0; i < num_properties; i++) {
hal_cb = get_expected_hal_cb();
+
+ if (hal_cb == adapter_test_setup_mode)
+ break;
+
switch (properties[i].type) {
case BT_PROPERTY_BDADDR:
if (hal_cb != adapter_prop_bdaddr) {
@@ -454,6 +509,15 @@ static const struct generic_data bluetooth_enable_success_test = {
adapter_test_end}
};

+static const struct generic_data bluetooth_enable_done_test = {
+ .expected_hal_callbacks = {adapter_props, adapter_test_end},
+ .expected_adapter_status = BT_STATUS_DONE
+};
+
+static const struct generic_data bluetooth_disable_success_test = {
+ .expected_hal_callbacks = {adapter_state_changed_off, adapter_test_end}
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -551,6 +615,15 @@ static void setup_base(const void *test_data)
tester_setup_complete();
}

+static void setup_enabled_adapter(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ setup(data);
+
+ data->if_bluetooth->enable();
+}
+
static void teardown(const void *test_data)
{
struct test_data *data = tester_get_data();
@@ -573,12 +646,31 @@ static void test_enable(const void *test_data)
{
struct test_data *data = tester_get_data();

- hal_cb_init(data);
- mgmt_cb_init(data);
+ init_test_conditions(data);

data->if_bluetooth->enable();
}

+static void test_enable_done(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ bt_status_t adapter_status;
+
+ init_test_conditions(data);
+
+ adapter_status = data->if_bluetooth->enable();
+ check_expected_status(adapter_status);
+}
+
+static void test_disable(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->disable();
+}
+
static void controller_setup(const void *test_data)
{
tester_test_passed();
@@ -608,5 +700,11 @@ int main(int argc, char *argv[])
test_bredrle("Test Enable - Success", &bluetooth_enable_success_test,
setup_base, test_enable, teardown);

+ test_bredrle("Test Enable - Done", &bluetooth_enable_done_test,
+ setup_enabled_adapter, test_enable_done, teardown);
+
+ test_bredrle("Test Disable - Success", &bluetooth_disable_success_test,
+ setup_enabled_adapter, test_disable, teardown);
+
return tester_run();
}
--
1.8.3.1


2013-12-11 10:46:36

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCH v4 6/7] android/tester: Add basic enable test

From: Grzegorz Kolodziejczyk <[email protected]>

---
android/android-tester.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 225 insertions(+), 2 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 15f8c61..0dc1edf 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -35,7 +35,32 @@
#include <hardware/hardware.h>
#include <hardware/bluetooth.h>

+#define adapter_props adapter_prop_bdaddr, adapter_prop_bdname, \
+ adapter_prop_uuids, adapter_prop_cod, \
+ adapter_prop_scan_mode, adapter_prop_disc_timeout
+
+/*
+ * those are assigned to HAL methods and callbacks, we use ID later
+ * on mapped in switch-case due to different functions prototypes.
+ */
+
+enum hal_bluetooth_callbacks_id {
+ adapter_test_end,
+ adapter_state_changed_on,
+ adapter_state_changed_off,
+ adapter_prop_bdaddr,
+ adapter_prop_bdname,
+ adapter_prop_uuids,
+ adapter_prop_cod,
+ adapter_prop_scan_mode,
+ adapter_prop_disc_timeout,
+ adapter_prop_service_record,
+ adapter_prop_bonded_devices
+};
+
struct generic_data {
+ uint32_t expect_settings_set;
+ uint8_t expected_hal_callbacks[];
};

#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
@@ -44,15 +69,100 @@ struct generic_data {
struct test_data {
struct mgmt *mgmt;
uint16_t mgmt_index;
+ unsigned int mgmt_settings_id;
struct hciemu *hciemu;
enum hciemu_type hciemu_type;
const struct generic_data *test_data;
pid_t bluetoothd_pid;
const bt_interface_t *if_bluetooth;
+
+ bool mgmt_settings_set;
+ bool hal_cb_called;
+
+ GSList *expected_callbacks;
};

static char exec_dir[PATH_MAX + 1];

+static void test_update_state(void)
+{
+ struct test_data *data = tester_get_data();
+
+ if (data->mgmt_settings_set && data->hal_cb_called)
+ tester_test_passed();
+}
+
+static void test_mgmt_settings_set(struct test_data *data)
+{
+ data->mgmt_settings_set = true;
+
+ test_update_state();
+}
+
+static void command_generic_new_settings(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ uint32_t settings;
+
+ if (length != 4) {
+ tester_warn("Invalid parameter size for new settings event");
+ tester_test_failed();
+ return;
+ }
+
+ settings = bt_get_le32(param);
+
+ if ((settings & data->test_data->expect_settings_set) !=
+ data->test_data->expect_settings_set)
+ return;
+
+ test_mgmt_settings_set(data);
+ mgmt_unregister(data->mgmt, data->mgmt_settings_id);
+}
+
+static void hal_cb_init(struct test_data *data)
+{
+ unsigned int i = 0;
+
+ while (data->test_data->expected_hal_callbacks[i]) {
+ data->expected_callbacks =
+ g_slist_append(data->expected_callbacks,
+ GINT_TO_POINTER(data->test_data->expected_hal_callbacks[i]));
+ i++;
+ }
+}
+
+static void mgmt_cb_init(struct test_data *data)
+{
+ if (!data->test_data->expect_settings_set)
+ test_mgmt_settings_set(data);
+ else
+ data->mgmt_settings_id = mgmt_register(data->mgmt,
+ MGMT_EV_NEW_SETTINGS, data->mgmt_index,
+ command_generic_new_settings, NULL, NULL);
+}
+
+static int get_expected_hal_cb(void)
+{
+ struct test_data *data = tester_get_data();
+
+ return GPOINTER_TO_INT(data->expected_callbacks->data);
+}
+
+static void remove_expected_hal_cb(void)
+{
+ struct test_data *data = tester_get_data();
+
+ data->expected_callbacks = g_slist_remove(data->expected_callbacks,
+ data->expected_callbacks->data);
+
+ if (!data->expected_callbacks)
+ data->hal_cb_called = true;
+
+ test_update_state();
+}
+
static void read_info_callback(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -247,10 +357,107 @@ failed:
close(fd);
}

+static void adapter_state_changed_cb(bt_state_t state)
+{
+ switch (get_expected_hal_cb()) {
+ case adapter_state_changed_on:
+ if (state == BT_STATE_ON)
+ remove_expected_hal_cb();
+ else
+ tester_test_failed();
+ break;
+ default:
+ break;
+ }
+}
+
+static void adapter_properties_cb(bt_status_t status, int num_properties,
+ bt_property_t *properties)
+{
+ enum hal_bluetooth_callbacks_id hal_cb;
+ int i;
+
+ for (i = 0; i < num_properties; i++) {
+ hal_cb = get_expected_hal_cb();
+ switch (properties[i].type) {
+ case BT_PROPERTY_BDADDR:
+ if (hal_cb != adapter_prop_bdaddr) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ case BT_PROPERTY_BDNAME:
+ if (hal_cb != adapter_prop_bdname) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ case BT_PROPERTY_UUIDS:
+ if (hal_cb != adapter_prop_uuids) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ if (hal_cb != adapter_prop_cod) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ if (hal_cb != adapter_prop_bdaddr) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ case BT_PROPERTY_SERVICE_RECORD:
+ if (hal_cb != adapter_prop_service_record) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ if (hal_cb != adapter_prop_scan_mode) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+ if (hal_cb != adapter_prop_bonded_devices) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ if (hal_cb != adapter_prop_disc_timeout) {
+ tester_test_failed();
+ return;
+ }
+ remove_expected_hal_cb();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static const struct generic_data bluetooth_enable_success_test = {
+ .expected_hal_callbacks = {adapter_props, adapter_state_changed_on,
+ adapter_test_end}
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
- .adapter_state_changed_cb = NULL,
- .adapter_properties_cb = NULL,
+ .adapter_state_changed_cb = adapter_state_changed_cb,
+ .adapter_properties_cb = adapter_properties_cb,
.remote_device_properties_cb = NULL,
.device_found_cb = NULL,
.discovery_state_changed_cb = NULL,
@@ -356,9 +563,22 @@ static void teardown(const void *test_data)
if (data->bluetoothd_pid)
waitpid(data->bluetoothd_pid, NULL, 0);

+ if (data->expected_callbacks)
+ g_slist_free(data->expected_callbacks);
+
tester_teardown_complete();
}

+static void test_enable(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ hal_cb_init(data);
+ mgmt_cb_init(data);
+
+ data->if_bluetooth->enable();
+}
+
static void controller_setup(const void *test_data)
{
tester_test_passed();
@@ -385,5 +605,8 @@ int main(int argc, char *argv[])

test_bredrle("Test Init", NULL, setup_base, controller_setup, teardown);

+ test_bredrle("Test Enable - Success", &bluetooth_enable_success_test,
+ setup_base, test_enable, teardown);
+
return tester_run();
}
--
1.8.3.1