unit: Add SNEP test utilities
authorMarcin Malagowski <marcin.malagowski@mobica.com>
Sat, 23 Mar 2013 11:40:19 +0000 (12:40 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Mon, 25 Mar 2013 11:00:51 +0000 (12:00 +0100)
Makefile.am
unit/test-snep-read.c [new file with mode: 0644]
unit/test-utils.c [new file with mode: 0644]
unit/test-utils.h [new file with mode: 0644]

index 5ed2b6f..c4f1346 100644 (file)
@@ -111,7 +111,7 @@ tools_nfctool_nfctool_SOURCES = tools/nfctool/main.c \
 
 tools_nfctool_nfctool_LDADD = @GLIB_LIBS@ @NETLINK_LIBS@
 
-unit_tests = unit/test-ndef-parse unit/test-ndef-build
+unit_tests = unit/test-ndef-parse unit/test-ndef-build unit/test-snep-read
 
 unit_test_ndef_parse_SOURCES = $(gdbus_sources) src/log.c src/dbus.c \
                                        src/agent.c src/bluetooth.c \
@@ -123,6 +123,13 @@ unit_test_ndef_build_SOURCES = $(gdbus_sources) src/log.c src/dbus.c \
                                        src/ndef.c unit/test-ndef-build.c
 unit_test_ndef_build_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
 
+unit_test_snep_read_SOURCES = $(gdbus_sources) src/log.c src/dbus.c \
+                                       src/agent.c src/bluetooth.c \
+                                       src/ndef.c src/snep.c \
+                                       unit/test-snep-read.c unit/test-utils.c \
+                                       unit/test-utils.h
+unit_test_snep_read_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
+
 noinst_PROGRAMS += $(unit_tests)
 
 TESTS = $(unit_tests)
diff --git a/unit/test-snep-read.c b/unit/test-snep-read.c
new file mode 100644 (file)
index 0000000..0a2b77d
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *  neard - Near Field Communication manager
+ *
+ *  Copyright (C) 2013  Mobica Limited. 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 version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/socket.h>
+
+#include <near/types.h>
+
+#include "test-utils.h"
+
+#define TEST_SNEP_LOG(fmt, ...) do { \
+       if (g_test_verbose()) {\
+               g_printf("[SNEP unit] " fmt, ##__VA_ARGS__); \
+       } \
+       } while (0)
+
+#define TEST_SNEP_PTR_UNUSED(x) do { if ((void *)x != NULL) {} } while (0)
+
+static const char *short_text = "neard";
+
+/* sockets */
+static int sockfd[2];
+static int client;
+static int server;
+
+struct test_snep_context {
+       uint8_t snep_version;
+       uint32_t req_info_len;
+       uint32_t payload_len;
+       uint8_t *req_info;
+
+       uint32_t acc_len; /* req GET specific */
+
+       struct near_ndef_message *test_recd_msg;
+};
+
+/* variables used in dummy_req_{get|put} */
+static struct test_snep_context *gcontext;
+static struct near_ndef_record *stored_recd;
+static GSList *test_fragments;
+
+static void test_snep_init(gpointer context, gconstpointer data)
+{
+       struct test_snep_context *ctx = context;
+       struct timeval tv;
+       int ret;
+       const char *test_data = data;
+
+       g_assert(socketpair(PF_LOCAL, SOCK_STREAM, 0, sockfd) == 0);
+
+       client = 0;
+       server = 1;
+
+       tv.tv_sec = 1;
+       tv.tv_usec = 0;
+       ret = setsockopt(sockfd[client], SOL_SOCKET, SO_RCVTIMEO,
+                       (const void *) &tv, sizeof(tv));
+       if (ret != 0)
+               TEST_SNEP_LOG("set sock SO_RCVTIMEO failed");
+
+       __near_snep_core_init();
+
+       stored_recd = NULL;
+
+       ctx->test_recd_msg = test_ndef_create_test_record(test_data);
+
+       ctx->snep_version = NEAR_SNEP_VERSION;
+       ctx->req_info = ctx->test_recd_msg->data;
+       ctx->req_info_len = ctx->test_recd_msg->length;
+       ctx->payload_len = ctx->test_recd_msg->length;
+       ctx->acc_len = 64;
+
+       gcontext = ctx;
+}
+
+static void test_snep_cleanup(gpointer context, gconstpointer data)
+{
+       struct test_snep_context *ctx = context;
+
+       __near_snep_core_cleanup();
+
+       if (stored_recd)
+               test_ndef_free_record(stored_recd);
+
+       if (ctx->test_recd_msg) {
+               g_free(ctx->test_recd_msg->data);
+               g_free(ctx->test_recd_msg);
+       }
+
+       g_slist_free(test_fragments);
+
+       close(sockfd[client]);
+       close(sockfd[server]);
+
+       gcontext = NULL;
+}
+
+/*
+ * @brief Test: Confirm that server is able to send simple response
+ */
+static void test_snep_response_noinfo(gpointer context, gconstpointer gp)
+{
+       int bytes_recv;
+       struct p2p_snep_resp_frame resp;
+
+       near_snep_core_response_noinfo(sockfd[client], NEAR_SNEP_RESP_SUCCESS);
+
+       bytes_recv = recv(sockfd[server], &resp, sizeof(resp), 0);
+       g_assert(bytes_recv == NEAR_SNEP_RESP_HEADER_LENGTH);
+       g_assert(resp.version == NEAR_SNEP_VERSION);
+       g_assert(resp.response == NEAR_SNEP_RESP_SUCCESS);
+       g_assert(resp.length == 0);
+}
+
+int main(int argc, char **argv)
+{
+       GTestSuite *ts;
+       GTestFixtureFunc init = test_snep_init;
+       GTestFixtureFunc exit = test_snep_cleanup;
+       size_t fs = sizeof(struct test_snep_context);
+
+       g_test_init(&argc, &argv, NULL);
+
+       ts = g_test_create_suite("SNEP responses");
+       g_test_suite_add(ts,
+               g_test_create_case("noinfo", fs, short_text,
+                       init, test_snep_response_noinfo, exit));
+
+       g_test_suite_add_suite(g_test_get_root(), ts);
+
+       return g_test_run();
+}
diff --git a/unit/test-utils.c b/unit/test-utils.c
new file mode 100644 (file)
index 0000000..fe25656
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  neard - Near Field Communication manager
+ *
+ *  Copyright (C) 2013 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 version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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
+ *
+ */
+
+#include "test-utils.h"
+
+void test_ndef_free_record(struct near_ndef_record *record)
+{
+       g_free(record->header);
+       g_free(record->type);
+       g_free(record->data);
+       g_free(record);
+}
+
+struct near_ndef_message *test_ndef_create_test_record(const char *str)
+{
+       struct near_ndef_message *ndef;
+
+       ndef = near_ndef_prepare_text_record("UTF-8", "en-US", (char *) str);
+       g_assert(ndef);
+       g_assert(ndef->data);
+
+       return ndef;
+}
diff --git a/unit/test-utils.h b/unit/test-utils.h
new file mode 100644 (file)
index 0000000..c371d56
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ *  neard - Near Field Communication manager
+ *
+ *  Copyright (C) 2013 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 version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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
+ *
+ */
+
+#ifndef UNIT_TEST_UTILS_H
+#define UNIT_TEST_UTILS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <src/near.h>
+#include <near/nfc_copy.h>
+#include <near/types.h>
+#include <near/ndef.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+
+/* SNEP specific types */
+struct snep_fragment {
+       uint32_t len;
+       uint8_t *data;
+};
+
+struct p2p_snep_put_req_data {
+       uint8_t fd;
+       uint32_t adapter_idx;
+       uint32_t target_idx;
+       near_device_io_cb cb;
+       guint watch;
+
+       GSList *fragments;
+};
+
+struct p2p_snep_req_frame {
+       uint8_t version;
+       uint8_t request;
+       uint32_t length;
+       uint8_t ndef[];
+} __attribute__((packed));
+
+struct p2p_snep_resp_frame {
+       uint8_t version;
+       uint8_t response;
+       uint32_t length;
+       uint8_t info[];
+} __attribute__((packed));
+
+/* NDEF specific types */
+enum record_type {
+       RECORD_TYPE_WKT_SMART_POSTER          =   0x01,
+       RECORD_TYPE_WKT_URI                   =   0x02,
+       RECORD_TYPE_WKT_TEXT                  =   0x03,
+       RECORD_TYPE_WKT_SIZE                  =   0x04,
+       RECORD_TYPE_WKT_TYPE                  =   0x05,
+       RECORD_TYPE_WKT_ACTION                =   0x06,
+       RECORD_TYPE_WKT_HANDOVER_REQUEST      =   0x07,
+       RECORD_TYPE_WKT_HANDOVER_SELECT       =   0x08,
+       RECORD_TYPE_WKT_HANDOVER_CARRIER      =   0x09,
+       RECORD_TYPE_WKT_ALTERNATIVE_CARRIER   =   0x0a,
+       RECORD_TYPE_WKT_COLLISION_RESOLUTION  =   0x0b,
+       RECORD_TYPE_WKT_ERROR                 =   0x0c,
+       RECORD_TYPE_MIME_TYPE                 =   0x0d,
+       RECORD_TYPE_UNKNOWN                   =   0xfe,
+       RECORD_TYPE_ERROR                     =   0xff
+};
+
+struct near_ndef_record_header {
+       uint8_t mb;
+       uint8_t me;
+       uint8_t cf;
+       uint8_t sr;
+       uint8_t il;
+       uint8_t tnf;
+       uint8_t il_length;
+       uint8_t *il_field;
+       uint32_t payload_len;
+       uint32_t offset;
+       uint8_t type_len;
+       enum record_type rec_type;
+       char *type_name;
+       uint32_t header_len;
+};
+
+struct near_ndef_text_payload {
+       char *encoding;
+       char *language_code;
+       char *data;
+};
+
+struct near_ndef_uri_payload {
+       uint8_t identifier;
+
+       uint32_t  field_length;
+       uint8_t  *field;
+};
+
+struct near_ndef_sp_payload {
+       struct near_ndef_uri_payload *uri;
+
+       uint8_t number_of_title_records;
+       struct near_ndef_text_payload **title_records;
+
+       uint32_t size; /* from Size record*/
+       char *type;    /* from Type record*/
+       char *action;
+};
+
+struct near_ndef_record {
+       char *path;
+
+       struct near_ndef_record_header *header;
+
+       /* specific payloads */
+       struct near_ndef_text_payload *text;
+       struct near_ndef_uri_payload  *uri;
+       struct near_ndef_sp_payload   *sp;
+       struct near_ndef_mime_payload *mime;
+       struct near_ndef_ho_payload   *ho;      /* handover payload */
+
+       char *type;
+
+       uint8_t *data;
+       size_t data_len;
+};
+
+void test_ndef_free_record(struct near_ndef_record *record);
+
+struct near_ndef_message *test_ndef_create_test_record(const char *str);
+
+#endif