/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set et sw=2 ts=2: */ /*************************************************************************** * testclient.cc * * Thu May 3 10:06:49 CEST 2012 * Copyright 2012 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of Munia. * * Munia 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. * * Munia 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 Munia; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "testclient.h" #ifdef TEST_TESTCLIENT //deps: //cflags: $(LIBWEBSOCKETS_CFLAGS) //libs: $(LIBWEBSOCKETS_LIBS) #include "test.h" #include #include #include #include #include #include struct test { const char *command; const char *result; bool success; }; enum demo_protocols { PROTOCOL_TASK, }; struct test *current_test = NULL; static int callback_task(struct libwebsocket_context *me, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING]; int l; switch (reason) { case LWS_CALLBACK_CLOSED: fprintf(stderr, "mirror: LWS_CALLBACK_CLOSED\n"); // wsi_mirror = NULL; break; case LWS_CALLBACK_CLIENT_ESTABLISHED: /* * start the ball rolling, * LWS_CALLBACK_CLIENT_WRITEABLE will come next service */ libwebsocket_callback_on_writable(me, wsi); break; case LWS_CALLBACK_CLIENT_RECEIVE: fprintf(stderr, "rx %d '", (int)len); fwrite(in, len, 1, stderr); fprintf(stderr, "'\n"); current_test->success = strncmp(current_test->result, (char*)in, len) == 0; current_test++; libwebsocket_callback_on_writable(me, wsi); break; case LWS_CALLBACK_CLIENT_WRITEABLE: l = sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING], "%s", current_test->command); fprintf(stderr, "sx '%s'\n", &buf[LWS_SEND_BUFFER_PRE_PADDING]); libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], l, LWS_WRITE_TEXT); if(current_test->result == NULL) { current_test->success = true; current_test++; libwebsocket_callback_on_writable(me, wsi); } /* * without at least this delay, we choke the browser * and the connection stalls, despite we now take care about * flow control */ // usleep(200); // sleep(1); break; default: break; } return 0; } static struct libwebsocket_protocols protocols[] = { { "lws-task-protocol", callback_task, 0, }, { NULL, NULL, 0 } }; int client(const char *address, int port, struct test tests[]) { current_test = &tests[0]; struct libwebsocket_context *context; struct libwebsocket *wsi_task = NULL; int ietf_version = -1; // latest context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, protocols, libwebsocket_internal_extensions, NULL, NULL, -1, -1, 0); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); return 1; } /* * sit there servicing the websocket context to handle incoming * packets, and drawing random circles on the mirror protocol websocket */ int n = 1; while(n >= 0 && current_test->command) { n = libwebsocket_service(context, 1000); if (wsi_task == NULL) { wsi_task = libwebsocket_client_connect(context, address, port, 0, "/", address, address, protocols[PROTOCOL_TASK].name, ietf_version); if (wsi_task == NULL) { fprintf(stderr, "libwebsocket task connect failed\n"); return -1; } } else { /* fprintf(stderr, "closing mirror session\n"); libwebsocket_close_and_free_session(context, wsi_mirror, LWS_CLOSE_STATUS_GOINGAWAY); */ } } fprintf(stderr, "Exiting\n"); libwebsocket_context_destroy(context); return 0; } TEST_BEGIN; #define BASE "0 create 0 -1; 0 update 0 \"root\"; 0 create 1 0; 0 update 1 \"Finished\"; 0 create 2 0; 0 update 2 \"Backlog\"; 0 create 3 0; 0 update 3 \"Lost+Found\"; 0 create 4 0; 0 update 4 \"Projects\";" #define RMBASE "0 remove 4; 0 remove 3; 0 remove 2; 0 remove 1; 0 remove 0;" static struct test tests[] = { { "observe 0", BASE, false }, { "unobserve 0", RMBASE, false }, { "create 0", NULL, false }, { "observe 0", BASE" 0 create 10 0; 0 update 10 \"\";", false }, { "update 10 \"My title\"", "0 update 10 \"My title\";", false }, { "unobserve 0", "0 remove 10; "RMBASE, false }, { "observe 0", BASE" 0 create 10 0; 0 update 10 \"My title\";", false }, { "move 10 1", "0 move 10 1;", false }, { "create 10", "0 create 11 10;", false }, { "remove 10", "0 remove 11; 0 remove 10;", false }, /* { "observe 0", BASE"0 add title description 5", false }, { "add title2 description 0", BASE"0 add title2 description 6", false }, { "unobserve 0", NULL, false }, { "observe 0", BASE"0 add title description 5; add title description 6", false }, { "unobserve 0", NULL, false }, */ { NULL, NULL, false } }; client("localhost", 10001, tests); struct test *t = &tests[0]; while(t->command) { TEST_TRUE(t->success, "%s", t->command); t++; } // TODO: Put some testcode here (see test.h for usable macros). //TEST_TRUE(false, "No tests yet!"); TEST_END; #endif/*TEST_TESTCLIENT*/