Re: [PATCHv2 1/6] unit/avrcp: First unit test for AVRCP profile

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

 



Hi Andrei,

On Mon, Feb 24, 2014 at 9:09 AM, Andrei Emeltchenko
<andrei.emeltchenko@xxxxxxxxx> wrote:
> On Fri, Feb 21, 2014 at 05:23:45PM +0200, Andrei Emeltchenko wrote:
>> From: Andrei Emeltchenko <andrei.emeltchenko@xxxxxxxxx>
>>
>> The tests verifies connection establishment for control.
>
> ping
>
>
>> ---
>>  Makefile.am       |   9 ++
>>  unit/test-avrcp.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 274 insertions(+)
>>  create mode 100644 unit/test-avrcp.c
>>
>> diff --git a/Makefile.am b/Makefile.am
>> index 11f2aa1..5fe58eb 100644
>> --- a/Makefile.am
>> +++ b/Makefile.am
>> @@ -282,6 +282,15 @@ unit_test_avctp_SOURCES = unit/test-avctp.c \
>>                               android/avctp.c android/avctp.h
>>  unit_test_avctp_LDADD = @GLIB_LIBS@
>>
>> +unit_tests += unit/test-avrcp
>> +
>> +unit_test_avrcp_SOURCES = unit/test-avrcp.c \
>> +                             src/shared/util.h src/shared/util.c \
>> +                             src/log.h src/log.c \
>> +                             android/avctp.c android/avctp.h \
>> +                             android/avrcp-lib.c android/avrcp-lib.h
>> +unit_test_avrcp_LDADD = @GLIB_LIBS@ lib/libbluetooth-internal.la
>> +
>>  unit_tests += unit/test-gdbus-client
>>
>>  unit_test_gdbus_client_SOURCES = unit/test-gdbus-client.c
>> diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
>> new file mode 100644
>> index 0000000..f1c0f46
>> --- /dev/null
>> +++ b/unit/test-avrcp.c
>> @@ -0,0 +1,265 @@
>> +/*
>> + *
>> + *  BlueZ - Bluetooth protocol stack for Linux
>> + *
>> + *  Copyright (C) 2014  Intel Corporation. All rights reserved.
>> + *
>> + *
>> + *  This program is free software; you can redistribute it and/or modify
>> + *  it under the terms of the GNU General Public License as published by
>> + *  the Free Software Foundation; either version 2 of the License, or
>> + *  (at your option) any later version.
>> + *
>> + *  This program 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 General Public License for more details.
>> + *
>> + *  You should have received a copy of the GNU General Public License
>> + *  along with this program; if not, write to the Free Software
>> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
>> + *
>> + */
>> +
>> +#ifdef HAVE_CONFIG_H
>> +#include <config.h>
>> +#endif
>> +
>> +#include <unistd.h>
>> +#include <stdlib.h>
>> +#include <stdbool.h>
>> +#include <inttypes.h>
>> +#include <string.h>
>> +#include <fcntl.h>
>> +#include <sys/socket.h>
>> +
>> +#include <glib.h>
>> +
>> +#include "src/shared/util.h"
>> +#include "src/log.h"
>> +#include "lib/bluetooth.h"
>> +
>> +#include "android/avctp.h"
>> +#include "android/avrcp-lib.h"
>> +
>> +struct test_pdu {
>> +     bool valid;
>> +     bool fragmented;
>> +     const uint8_t *data;
>> +     size_t size;
>> +};
>> +
>> +struct test_data {
>> +     char *test_name;
>> +     struct test_pdu *pdu_list;
>> +};
>> +
>> +struct context {
>> +     GMainLoop *main_loop;
>> +     struct avrcp *session;
>> +     guint source;
>> +     guint process;
>> +     int fd;
>> +     unsigned int pdu_offset;
>> +     const struct test_data *data;
>> +};
>> +
>> +#define data(args...) ((const unsigned char[]) { args })
>> +
>> +#define raw_pdu(args...)                                     \
>> +     {                                                       \
>> +             .valid = true,                                  \
>> +             .data = data(args),                             \
>> +             .size = sizeof(data(args)),                     \
>> +     }
>> +
>> +#define frg_pdu(args...)                                     \
>> +     {                                                       \
>> +             .valid = true,                                  \
>> +             .fragmented = true,                             \
>> +             .data = data(args),                             \
>> +             .size = sizeof(data(args)),                     \
>> +     }
>> +
>> +#define define_test(name, function, args...)                         \
>> +     do {                                                            \
>> +             const struct test_pdu pdus[] = {                        \
>> +                     args, { }                                       \
>> +             };                                                      \
>> +             static struct test_data data;                           \
>> +             data.test_name = g_strdup(name);                        \
>> +             data.pdu_list = g_malloc(sizeof(pdus));                 \
>> +             memcpy(data.pdu_list, pdus, sizeof(pdus));              \
>> +             g_test_add_data_func(name, &data, function);            \
>> +     } while (0)
>> +
>> +static void test_debug(const char *str, void *user_data)
>> +{
>> +     const char *prefix = user_data;
>> +
>> +     g_print("%s%s\n", prefix, str);
>> +}
>> +
>> +static void test_free(gconstpointer user_data)
>> +{
>> +     const struct test_data *data = user_data;
>> +
>> +     g_free(data->test_name);
>> +     g_free(data->pdu_list);
>> +}
>> +
>> +static gboolean context_quit(gpointer user_data)
>> +{
>> +     struct context *context = user_data;
>> +
>> +     if (context->process > 0)
>> +             g_source_remove(context->process);
>> +
>> +     g_main_loop_quit(context->main_loop);
>> +
>> +     return FALSE;
>> +}
>> +
>> +static gboolean send_pdu(gpointer user_data)
>> +{
>> +     struct context *context = user_data;
>> +     const struct test_pdu *pdu;
>> +     ssize_t len;
>> +
>> +     pdu = &context->data->pdu_list[context->pdu_offset++];
>> +
>> +     len = write(context->fd, pdu->data, pdu->size);
>> +
>> +     if (g_test_verbose())
>> +             util_hexdump('<', pdu->data, len, test_debug, "AVRCP: ");
>> +
>> +     g_assert_cmpint(len, ==, pdu->size);
>> +
>> +     if (pdu->fragmented)
>> +             return send_pdu(user_data);
>> +
>> +     context->process = 0;
>> +     return FALSE;
>> +}
>> +
>> +static void context_process(struct context *context)
>> +{
>> +     if (!context->data->pdu_list[context->pdu_offset].valid) {
>> +             context_quit(context);
>> +             return;
>> +     }
>> +
>> +     context->process = g_idle_add(send_pdu, context);
>> +}
>> +
>> +static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
>> +                                                     gpointer user_data)
>> +{
>> +     struct context *context = user_data;
>> +     const struct test_pdu *pdu;
>> +     unsigned char buf[512];
>> +     ssize_t len;
>> +     int fd;
>> +
>> +     pdu = &context->data->pdu_list[context->pdu_offset++];
>> +
>> +     if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
>> +             context->source = 0;
>> +             g_print("%s: cond %x\n", __func__, cond);
>> +             return FALSE;
>> +     }
>> +
>> +     fd = g_io_channel_unix_get_fd(channel);
>> +
>> +     len = read(fd, buf, sizeof(buf));
>> +
>> +     g_assert(len > 0);
>> +
>> +     if (g_test_verbose())
>> +             util_hexdump('>', buf, len, test_debug, "AVRCP: ");
>> +
>> +     g_assert_cmpint(len, ==, pdu->size);
>> +
>> +     g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
>> +
>> +     if (!pdu->fragmented)
>> +             context_process(context);
>> +
>> +     return TRUE;
>> +}
>> +
>> +static struct context *create_context(uint16_t version, gconstpointer data)
>> +{
>> +     struct context *context = g_new0(struct context, 1);
>> +     GIOChannel *channel;
>> +     int err, sv[2];
>> +
>> +     context->main_loop = g_main_loop_new(NULL, FALSE);
>> +     g_assert(context->main_loop);
>> +
>> +     err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
>> +     g_assert(err == 0);
>> +
>> +     context->session = avrcp_new(sv[0], 672, 672, version);
>> +     g_assert(context->session != NULL);
>> +
>> +     channel = g_io_channel_unix_new(sv[1]);
>> +
>> +     g_io_channel_set_close_on_unref(channel, TRUE);
>> +     g_io_channel_set_encoding(channel, NULL, NULL);
>> +     g_io_channel_set_buffered(channel, FALSE);
>> +
>> +     context->source = g_io_add_watch(channel,
>> +                             G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
>> +                             test_handler, context);
>> +     g_assert(context->source > 0);
>> +
>> +     g_io_channel_unref(channel);
>> +
>> +     context->fd = sv[1];
>> +     context->data = data;
>> +
>> +     return context;
>> +}
>> +
>> +static void destroy_context(struct context *context)
>> +{
>> +     if (context->source > 0)
>> +             g_source_remove(context->source);
>> +
>> +     avrcp_shutdown(context->session);
>> +
>> +     g_main_loop_unref(context->main_loop);
>> +
>> +     test_free(context->data);
>> +     g_free(context);
>> +}
>> +
>> +static void test_dummy(gconstpointer data)
>> +{
>> +     struct context *context =  create_context(0x0100, data);
>> +
>> +     destroy_context(context);
>> +}
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +     g_test_init(&argc, &argv, NULL);
>> +
>> +     if (g_test_verbose())
>> +             __btd_log_init("*", 0);
>> +
>> +     /* Connection Establishment for Control tests */
>> +
>> +     /*
>> +      * Tests are checking connection establishement and release
>> +      * for control channel. Since we are connected through socketpair
>> +      * the tests are dummy
>> +      */
>> +     define_test("/TP/CEC/BV-01-I", test_dummy, raw_pdu(0x00));
>> +     define_test("/TP/CEC/BV-02-I", test_dummy, raw_pdu(0x00));
>> +     define_test("/TP/CRC/BV-01-I", test_dummy, raw_pdu(0x00));
>> +     define_test("/TP/CRC/BV-02-I", test_dummy, raw_pdu(0x00));
>> +
>> +     return g_test_run();
>> +}
>> --
>> 1.8.3.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

Applied, thanks.


-- 
Luiz Augusto von Dentz
--
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