[OpenWrt-Devel] [PATCH 7/7] ubus: add count test to validate large message sizes

Alexandru Ardelean ardeleanalex at gmail.com
Fri Jun 27 12:11:45 EDT 2014


Client creates a string "1 2 3 ... 10000 ...", sends it to the server
along with the maximum number in the string.

Server creates another string like the client sent.

It validates it and, returns strcmp()'s result.

This is loop-ed every 2 seconds.

---
 examples/CMakeLists.txt |  4 +--
 examples/client.c       | 78 +++++++++++++++++++++++++++++++++++++++++++++++++
 examples/count.c        | 48 ++++++++++++++++++++++++++++++
 examples/count.h        | 19 ++++++++++++
 examples/server.c       | 40 +++++++++++++++++++++++++
 5 files changed, 187 insertions(+), 2 deletions(-)
 create mode 100644 examples/count.c
 create mode 100644 examples/count.h

diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 3d06161..0279f6e 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -4,9 +4,9 @@ ADD_DEFINITIONS(-I..)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/..)
 
 IF (BUILD_EXAMPLES)
-	ADD_EXECUTABLE(server server.c)
+	ADD_EXECUTABLE(server server.c count.c)
 	TARGET_LINK_LIBRARIES(server ubus ubox blobmsg_json)
 
-	ADD_EXECUTABLE(client client.c)
+	ADD_EXECUTABLE(client client.c count.c)
 	TARGET_LINK_LIBRARIES(client ubus ubox)
 ENDIF()
diff --git a/examples/client.c b/examples/client.c
index 4d6b6ec..b586eaf 100644
--- a/examples/client.c
+++ b/examples/client.c
@@ -17,6 +17,7 @@
 #include <libubox/ustream.h>
 
 #include "libubus.h"
+#include "count.h"
 
 static struct ubus_context *ctx;
 static struct blob_buf b;
@@ -55,10 +56,85 @@ static void test_client_notify_cb(struct uloop_timeout *timeout)
 	uloop_timeout_set(timeout, 1000);
 }
 
+enum {
+	RETURN_CODE,
+	__RETURN_MAX,
+};
+
+static const struct blobmsg_policy return_policy[__RETURN_MAX] = {
+	[RETURN_CODE] = { .name = "rc", .type = BLOBMSG_TYPE_INT32 },
+};
+
+static void test_count_data_cb(struct ubus_request *req,
+				    int type, struct blob_attr *msg)
+{
+	struct blob_attr *tb[__RETURN_MAX];
+	int rc;
+	uint32_t count_to = *(uint32_t *)req->priv;
+
+	blobmsg_parse(return_policy, __RETURN_MAX, tb, blob_data(msg), blob_len(msg));
+
+	if (!tb[RETURN_CODE]) {
+		fprintf(stderr, "No return code received from server\n");
+		return;
+	}
+	rc = blobmsg_get_u32(tb[RETURN_CODE]);
+	if (rc)
+		fprintf(stderr, "Corruption of data with count up to '%u'\n", count_to);
+	else
+		fprintf(stderr, "Server validated our count up to '%u'\n", count_to);
+}
+
+static void test_count(struct uloop_timeout *timeout)
+{
+	enum {
+		COUNT_TO_MIN = 10000,
+		COUNT_TO_MAX = 1000000,
+		PROGRESSION  = 100,
+	};
+
+	uint32_t id;
+	static uint32_t count_to = 100000;
+	static int count_progression = PROGRESSION;
+	char *s;
+
+	if (count_to <= COUNT_TO_MIN)
+		count_progression = PROGRESSION;
+	else if (count_to >= COUNT_TO_MAX)
+		count_progression = -PROGRESSION;
+
+	count_to += count_progression;
+
+	s = count_to_number(count_to);
+	if (!s)
+		fprintf(stderr, "Could not allocate memory to count up to '%u'\n", count_to);
+
+	fprintf(stderr, "Sending count up to '%u'; string has length '%u'\n",
+	        count_to, (uint32_t)strlen(s));
+	blob_buf_init(&b, 0);
+	blobmsg_add_u32(&b, "to", count_to);
+	blobmsg_add_string(&b, "string", s);
+
+	if (ubus_lookup_id(ctx, "test", &id)) {
+		fprintf(stderr, "Failed to look up test object\n");
+		return;
+	}
+
+	ubus_invoke(ctx, id, "count", b.head, test_count_data_cb, &count_to, 5000);
+
+	free(s);
+
+	uloop_timeout_set(timeout, 2000);
+}
+
 static struct uloop_timeout notify_timer = {
 	.cb = test_client_notify_cb,
 };
 
+static struct uloop_timeout count_timer = {
+	.cb = test_count,
+};
+
 static void test_client_fd_data_cb(struct ustream *s, int bytes)
 {
 	char *data, *sep;
@@ -121,6 +197,8 @@ static void client_main(void)
 	req.complete_cb = test_client_complete_cb;
 	ubus_complete_request_async(ctx, &req);
 
+	uloop_timeout_set(&count_timer, 2000);
+
 	uloop_run();
 }
 
diff --git a/examples/count.c b/examples/count.c
new file mode 100644
index 0000000..e3e9c8a
--- /dev/null
+++ b/examples/count.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Felix Fietkau <nbd at openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "count.h"
+
+char *count_to_number(uint32_t num)
+{
+	uint32_t ptr = 0, size = 0;
+	uint32_t written = 0, i;
+	int new_line_every_n_numbers = 30;
+	char *s;
+
+	for (i=0; i < num; ++i) {
+		size += snprintf(NULL, 0, "%u ", i);
+		if (i > 0 && i % new_line_every_n_numbers == 0)
+			size++;
+	}
+	size++; /* one for null char */
+
+	s = calloc(size, sizeof(char));
+	if (!s)
+		goto out;
+
+	for (i=0; i < num; ++i) {
+		written = sprintf(&s[ptr], "%u ", i);
+		ptr  += written;
+		if (i > 0 && i % new_line_every_n_numbers == 0) {
+			sprintf(&s[ptr], "\n");
+			ptr++;
+		}
+	}
+
+out:
+	return s;
+}
diff --git a/examples/count.h b/examples/count.h
new file mode 100644
index 0000000..1f90f21
--- /dev/null
+++ b/examples/count.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 Felix Fietkau <nbd at openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * 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.
+ */
+
+#ifndef __COUNT_H
+#define __COUNT_H
+
+char *count_to_number(uint32_t num);
+
+#endif
diff --git a/examples/server.c b/examples/server.c
index 95eba5e..bbb3347 100644
--- a/examples/server.c
+++ b/examples/server.c
@@ -16,6 +16,7 @@
 
 #include <libubox/blobmsg_json.h>
 #include "libubus.h"
+#include "count.h"
 
 static struct ubus_context *ctx;
 static struct ubus_subscriber test_event;
@@ -149,9 +150,48 @@ static int test_watch(struct ubus_context *ctx, struct ubus_object *obj,
 	return ret;
 }
 
+enum {
+    COUNT_TO,
+    COUNT_STRING,
+    __COUNT_MAX
+};
+
+static const struct blobmsg_policy count_policy[__COUNT_MAX] = {
+    [COUNT_TO] = { .name = "to", .type = BLOBMSG_TYPE_INT32 },
+    [COUNT_STRING] = { .name = "string", .type = BLOBMSG_TYPE_STRING },
+};
+
+static int test_count(struct ubus_context *ctx, struct ubus_object *obj,
+		      struct ubus_request_data *req, const char *method,
+		      struct blob_attr *msg)
+{
+	struct blob_attr *tb[__COUNT_MAX];
+	char *s1, *s2;
+	uint32_t num;
+
+	blobmsg_parse(count_policy, __COUNT_MAX, tb, blob_data(msg), blob_len(msg));
+	if (!tb[COUNT_TO] || !tb[COUNT_STRING])
+		return UBUS_STATUS_INVALID_ARGUMENT;
+
+	num = blobmsg_get_u32(tb[COUNT_TO]);
+	s1 = blobmsg_get_string(tb[COUNT_STRING]);
+	s2 = count_to_number(num);
+	if (!s1 || !s2) {
+		free(s2);
+		return UBUS_STATUS_UNKNOWN_ERROR;
+	}
+	blob_buf_init(&b, 0);
+	blobmsg_add_u32(&b, "rc", strcmp(s1, s2));
+	ubus_send_reply(ctx, req, b.head);
+	free(s2);
+
+	return 0;
+}
+
 static const struct ubus_method test_methods[] = {
 	UBUS_METHOD("hello", test_hello, hello_policy),
 	UBUS_METHOD("watch", test_watch, watch_policy),
+	UBUS_METHOD("count", test_count, count_policy),
 };
 
 static struct ubus_object_type test_object_type =
-- 
1.8.4.5
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list