/*** * ==++== * * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ==--== * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * * receive_msg_tests.cpp * * Test cases covering receiving messages from websocket server. * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #include "stdafx.h" #if defined(__cplusplus_winrt) || !defined(_M_ARM) using namespace concurrency; using namespace concurrency::streams; using namespace web::websockets; using namespace web::websockets::client; using namespace tests::functional::websocket::utilities; namespace tests { namespace functional { namespace websocket { namespace client { SUITE(receive_msg_tests) { pplx::task receive_text_msg_helper(websocket_client& client, test_websocket_server& server, web::uri uri, const std::string& body_str, bool connect_client = true) { std::vector body(body_str.begin(), body_str.end()); if (connect_client) client.connect(uri).wait(); auto t = client.receive().then([body_str](websocket_incoming_message ret_msg) { VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length()); auto ret_str = ret_msg.extract_string().get(); VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); }); test_websocket_msg msg; msg.set_data(std::move(body)); msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); server.send_msg(msg); return t; } pplx::task receive_msg_stream_helper(websocket_client& client, test_websocket_server& server, web::uri uri, const std::vector& body, test_websocket_message_type type, bool connect_client = true) { if (connect_client) client.connect(uri).wait(); auto t = client.receive().then([body, type](websocket_incoming_message ret_msg) { auto is = ret_msg.body(); streams::container_buffer> ret_data; is.read_to_end(ret_data).wait(); VERIFY_ARE_EQUAL(ret_msg.length(), body.size()); VERIFY_ARE_EQUAL(body, ret_data.collection()); if (type == test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE) VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::binary_message); else if (type == test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE) VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); }); test_websocket_msg msg; msg.set_data(std::move(body)); msg.set_msg_type(type); server.send_msg(msg); return t; } // Receive text message (no fragmentation) TEST_FIXTURE(uri_address, receive_text_msg) { test_websocket_server server; websocket_client client; receive_text_msg_helper(client, server, m_uri, "hello").wait(); client.close().wait(); } // Receive text message (no fragmentation) // Test the stream interface to read data TEST_FIXTURE(uri_address, receive_text_msg_stream) { std::string body_str("hello"); std::vector body(body_str.begin(), body_str.end()); test_websocket_server server; websocket_client client; receive_msg_stream_helper(client, server, m_uri, body, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE).wait(); client.close().wait(); } // Receive binary message (no fragmentation) TEST_FIXTURE(uri_address, receive_binary_msg) { std::vector body; body.resize(6); memcpy(&body[0], "a\0b\0c\0", 6); test_websocket_server server; websocket_client client; receive_msg_stream_helper(client, server, m_uri, body, test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE).wait(); client.close().wait(); } // Server sends text message fragmented in 2 fragments TEST_FIXTURE(uri_address, receive_text_msg_fragments, "Ignore", "898451") { std::string body_str("hello"); std::vector body(body_str.begin(), body_str.end()); test_websocket_server server; websocket_client client; client.connect(m_uri).wait(); auto t = client.receive().then([&](websocket_incoming_message ret_msg) { auto ret_str = ret_msg.extract_string().get(); VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); }); test_websocket_msg msg1; msg1.set_data(std::move(body)); msg1.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_FRAGMENT_TYPE); server.send_msg(msg1); test_websocket_msg msg2; msg2.set_data(std::move(body)); msg2.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_FRAGMENT_TYPE); server.send_msg(msg2); t.wait(); client.close().wait(); } // Server sends message of length 0 TEST_FIXTURE(uri_address, receive_zero_length_msg) { test_websocket_server server; websocket_client client; receive_text_msg_helper(client, server, m_uri, "").wait(); client.close().wait(); } // Receive UTF-8 string with special characters TEST_FIXTURE(uri_address, receive_multi_byte_utf8_msg) { std::string body_str = "\xC3\xA0\xC3\xB8"; test_websocket_server server; websocket_client client; receive_text_msg_helper(client, server, m_uri, body_str).wait(); client.close().wait(); } // Receive multiple messages TEST_FIXTURE(uri_address, receive_multiple_msges) { test_websocket_server server; websocket_client client; auto t1 = receive_text_msg_helper(client, server, m_uri, "hello1"); auto t2 = receive_text_msg_helper(client, server, m_uri, "hello2", false); t1.wait(); t2.wait(); client.close().wait(); } // Start the receive task after the server has sent a message TEST_FIXTURE(uri_address, receive_after_server_send) { std::string body_str("hello"); std::vector body(body_str.begin(), body_str.end()); test_websocket_server server; websocket_client client; client.connect(m_uri).wait(); test_websocket_msg msg; msg.set_data(std::move(body)); msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); server.send_msg(msg); // We dont have a way of knowing if the message has been received by our client. // Hence Sleep for 100 msecs and then initiate the receive std::chrono::milliseconds dura(100); std::this_thread::sleep_for(dura); client.receive().then([&](websocket_incoming_message ret_msg) { auto ret_str = ret_msg.extract_string().get(); VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); }).wait(); client.close().wait(); } // Start task to receive text message before connecting. TEST_FIXTURE(uri_address, receive_before_connect) { test_websocket_server server; websocket_client client; std::string body_str("hello"); std::vector body(body_str.begin(), body_str.end()); auto t = client.receive().then([body_str](websocket_incoming_message ret_msg) { VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length()); auto ret_str = ret_msg.extract_string().get(); VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); }); // Connect after the client is waiting on a receive task. client.connect(m_uri).wait(); // Now send the message from the server test_websocket_msg msg; msg.set_data(std::move(body)); msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); server.send_msg(msg); t.wait(); client.close().wait(); } // Receive message using callback APIs TEST_FIXTURE(uri_address, receive_text_msg_callback_client) { test_websocket_server server; websocket_callback_client client; client.connect(m_uri).wait(); std::string body_str("hello"); std::vector body(body_str.begin(), body_str.end()); pplx::task_completion_event receiveEvent; // make sure client works fine without setting receive handler test_websocket_msg msg; msg.set_data(std::move(body)); msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); server.send_msg(msg); // set receive handler client.set_message_handler([body_str, &receiveEvent](websocket_incoming_message ret_msg) { VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length()); auto ret_str = ret_msg.extract_string().get(); VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); receiveEvent.set(); }); server.send_msg(msg); pplx::create_task(receiveEvent).wait(); client.close().wait(); } } // SUITE(receive_msg_tests) }}}} #endif