/* -*- 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_NODE, }; struct test *current_test = nullptr; static int callback_node(struct lws_context *me, struct lws *wsi, enum lws_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 = nullptr; break; case LWS_CALLBACK_CLIENT_ESTABLISHED: // start the ball rolling, // LWS_CALLBACK_CLIENT_WRITEABLE will come next service lws_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++; lws_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]); lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], l, LWS_WRITE_TEXT); if(current_test->result == nullptr) { current_test->success = true; current_test++; lws_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 lws_protocols protocols[] = { { "lws-node-protocol", callback_node, 0, }, { nullptr, nullptr, 0 } }; int client(const char *address, int port, struct test tests[]) { current_test = &tests[0]; struct lws_context *context; struct lws *wsi_node = nullptr; int ietf_version = -1; // latest context = lws_create_context(CONTEXT_PORT_NO_LISTEN, nullptr, protocols, lws_internal_extensions, nullptr, nullptr, -1, -1, 0); if(context == nullptr) { fprintf(stderr, "Creating lws 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 = lws_service(context, 1000); if(wsi_node == nullptr) { wsi_node = lws_client_connect(context, address, port, 0, "/", address, address, protocols[PROTOCOL_NODE].name, ietf_version); if` (wsi_node == nullptr) { fprintf(stderr, "lws node connect failed\n"); return -1; } } else { //fprintf(stderr, "closing mirror session\n"); //lws_close_and_free_session(context, // wsi_mirror, LWS_CLOSE_STATUS_GOINGAWAY); } } fprintf(stderr, "Exiting\n"); lws_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[] = { { "subscribe 0", BASE, false }, { "unsubscribe 0", RMBASE, false }, { "create 0", nullptr, false }, { "subscribe 0", BASE" 0 create 10 0; 0 update 10 \"\";", false }, { "update 10 \"My title\"", "0 update 10 \"My title\";", false }, { "unsubscribe 0", "0 remove 10; "RMBASE, false }, { "subscribe 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 }, //{ "subscribe 0", BASE"0 add title description 5", false }, //{ "add title2 description 0", BASE"0 add title2 description 6", false }, //{ "unsubscribe 0", nullptr, false }, //{ "subscribe 0", BASE"0 add title description 5; add title description 6", false }, //{ "unsubscribe 0", nullptr, false }, { nullptr, nullptr, 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*/