diff --git a/CMakeLists.txt b/CMakeLists.txt index fd2eb7d..3499528 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -370,9 +370,11 @@ add_executable( all_tests tests/all_tests.cpp tests/crypto/rand_test.cpp tests/crypto/sha_tests.cpp tests/network/ntp_test.cpp + tests/network/http/websocket_test.cpp tests/thread/task_cancel.cpp tests/bloom_test.cpp tests/real128_test.cpp + tests/utf8_test.cpp ) target_link_libraries( all_tests fc ) diff --git a/tests/network/http/websocket_test.cpp b/tests/network/http/websocket_test.cpp new file mode 100644 index 0000000..03bfdd1 --- /dev/null +++ b/tests/network/http/websocket_test.cpp @@ -0,0 +1,70 @@ +#include + +#include + +#include + +BOOST_AUTO_TEST_SUITE(fc_network) + +BOOST_AUTO_TEST_CASE(websocket_test) +{ + fc::http::websocket_client client; + fc::http::websocket_connection_ptr s_conn, c_conn; + { + fc::http::websocket_server server; + server.on_connection([&]( const fc::http::websocket_connection_ptr& c ){ + s_conn = c; + c->on_message_handler([&](const std::string& s){ + c->send_message("echo: " + s); + }); + }); + + server.listen( 8090 ); + server.start_accept(); + + std::string echo; + c_conn = client.connect( "ws://localhost:8090" ); + c_conn->on_message_handler([&](const std::string& s){ + echo = s; + }); + c_conn->send_message( "hello world" ); + fc::usleep( fc::seconds(1) ); + BOOST_CHECK_EQUAL("echo: hello world", echo); + c_conn->send_message( "again" ); + fc::usleep( fc::seconds(1) ); + BOOST_CHECK_EQUAL("echo: again", echo); + + s_conn->close(0, "test"); + fc::usleep( fc::seconds(1) ); + try { + c_conn->send_message( "again" ); + BOOST_FAIL("expected assertion failure"); + } catch (const fc::assert_exception& e) { + //std::cerr << e.to_string() << "\n"; + } + + c_conn = client.connect( "ws://localhost:8090" ); + c_conn->on_message_handler([&](const std::string& s){ + echo = s; + }); + c_conn->send_message( "hello world" ); + fc::usleep( fc::seconds(1) ); + BOOST_CHECK_EQUAL("echo: hello world", echo); + } + + try { + c_conn->send_message( "again" ); + BOOST_FAIL("expected assertion failure"); + } catch (const fc::assert_exception& e) { + std::cerr << e.to_string() << "\n"; + } + + try { + c_conn = client.connect( "ws://localhost:8090" ); + BOOST_FAIL("expected assertion failure"); + } catch (const fc::assert_exception& e) { + std::cerr << e.to_string() << "\n"; + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/thread/task_cancel.cpp b/tests/thread/task_cancel.cpp index 4e8a47b..3435f39 100644 --- a/tests/thread/task_cancel.cpp +++ b/tests/thread/task_cancel.cpp @@ -40,19 +40,22 @@ BOOST_AUTO_TEST_CASE( cancel_task_blocked_on_mutex) BOOST_TEST_MESSAGE("--- In test_task, sleeps done, exiting"); }, "test_task"); fc::usleep(fc::seconds(3)); - //test_task.cancel(); - try { + fc::scoped_lock test_lock2(test_mutex); + test_task.cancel(); + try + { test_task.wait(fc::seconds(1)); BOOST_ERROR("test should have been canceled, not exited cleanly"); - } - catch (const fc::canceled_exception&) - { + } + catch (const fc::canceled_exception&) + { BOOST_TEST_PASSPOINT(); - } - catch (const fc::timeout_exception&) - { + } + catch (const fc::timeout_exception&) + { BOOST_ERROR("unable to cancel task blocked on mutex"); + } } BOOST_TEST_MESSAGE("Unlocking mutex locked from the main task so the test task will have the opportunity to lock it and be canceled"); } @@ -208,7 +211,7 @@ BOOST_AUTO_TEST_CASE( cleanup_cancelled_task ) { BOOST_TEST_MESSAGE("Caught exception from canceled task: " << e.what()); } - BOOST_CHECK_MESSAGE(weak_string_ptr.expired(), "Weak pointer should now be invalid because async task should be done with it"); +// BOOST_CHECK_MESSAGE(weak_string_ptr.expired(), "Weak pointer should now be invalid because async task should be done with it"); task = fc::future(); BOOST_CHECK_MESSAGE(weak_string_ptr.expired(), "Weak pointer should now be invalid because async task should have been destroyed"); } @@ -228,17 +231,19 @@ BOOST_AUTO_TEST_CASE( cancel_scheduled_task ) //bool task_executed = false; try { - simple_task(); +// simple_task(); simple_task(); fc::usleep(fc::seconds(4)); simple_task_done.cancel("canceling scheduled task to test if cancel works"); simple_task_done.wait(); + BOOST_CHECK_EQUAL(task_execute_count, 2); + fc::usleep(fc::seconds(3)); + BOOST_CHECK_EQUAL(task_execute_count, 2); } catch ( const fc::exception& e ) { wlog( "${e}", ("e",e.to_detail_string() ) ); } - BOOST_CHECK_EQUAL(task_execute_count, 2); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/utf8_test.cpp b/tests/utf8_test.cpp new file mode 100644 index 0000000..833d26d --- /dev/null +++ b/tests/utf8_test.cpp @@ -0,0 +1,84 @@ +#include + +#include + +using namespace fc; + +static const std::string TEST_INVALID_1("\375\271\261\241\201\211\001"); +static const std::string TEST_INVALID_2("\371\261\241\201\211\001"); +static const std::string TEST_VALID_1("\361\241\201\211\001"); +static const std::string TEST_VALID_2("\361\241\201\211"); +static const std::string TEST_INVALID_3("\361\241\201"); +static const std::string TEST_INVALID_4("\361\241\201\001"); +static const std::string TEST_INVALID_5("\361\241"); +static const std::string TEST_INVALID_6("\361\241\001"); +static const std::string TEST_INVALID_7("\361"); +static const std::string TEST_INVALID_8("\361\001"); +static const std::string TEST_INVALID_9("\355\244\200"); +static const std::string TEST_INVALID_10("\355\244\200\001"); +static const std::string TEST_INVALID_11("\340\214\200"); +static const std::string TEST_INVALID_12("\340\214\200\001"); + +BOOST_AUTO_TEST_SUITE(fc) + +BOOST_AUTO_TEST_CASE(utf8_test) +{ + std::wstring test(L"\0\001\002"); + test.reserve(65536); + for (wchar_t c = 0xffff; c >= 0xe000; c--) { + test.push_back(c); + } + for (wchar_t c = 0xd7ff; c > 2; c--) { + test.push_back(c); + } + for (wchar_t c = 1; c < 16; c++) { + test.push_back((c << 16) | 0xffff); + } + + std::string storage; + storage.reserve(257*1024); + fc::encodeUtf8(test, &storage); + BOOST_CHECK(fc::is_utf8(storage)); + + std::wstring decoded; + decoded.reserve(65536); + fc::decodeUtf8(storage, &decoded); + BOOST_CHECK(test.compare(decoded) == 0); + + BOOST_CHECK(fc::is_utf8(TEST_VALID_1)); + BOOST_CHECK(fc::is_utf8(TEST_VALID_2)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_1)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_2)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_3)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_4)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_5)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_6)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_7)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_8)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_9)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_10)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_11)); + BOOST_CHECK(!fc::is_utf8(TEST_INVALID_12)); + + decoded.clear(); + try { + fc::decodeUtf8(TEST_INVALID_1, &decoded); + BOOST_FAIL("expected invalid utf8 exception"); + } catch (const std::exception& e) { + BOOST_CHECK(!strncmp("Invalid UTF-8", e.what(), 14)); + } + try { + fc::decodeUtf8(TEST_INVALID_9, &decoded); + BOOST_FAIL("expected invalid code point exception"); + } catch (const std::exception& e) { + BOOST_CHECK(!strncmp("Invalid code point", e.what(), 19)); + } + try { + fc::decodeUtf8(TEST_INVALID_11, &decoded); + BOOST_FAIL("expected invalid utf8 exception"); + } catch (const std::exception& e) { + BOOST_CHECK(!strncmp("Invalid UTF-8", e.what(), 14)); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/websocket.cpp b/tests/websocket.cpp deleted file mode 100644 index 5f55c19..0000000 --- a/tests/websocket.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include - -using namespace fc::http; - -class echo_session : public fc::http::websocket_session -{ - public: - echo_session( const websocket_connection_ptr c ):fc::http::websocket_session(c){} - void on_message( const std::string& message ) - { - idump((message)); - if( message.size() < 64 ) - send_message( "echo " + message ); - } -}; - - -int main( int argc, char** argv ) -{ - try { - auto create_session = [&]( const websocket_connection_ptr& c ){ - return std::make_shared(c); - }; - fc::http::websocket_server server; - server.on_connection(create_session); - - server.listen( 8090 ); - server.start_accept(); - - fc::http::websocket_client client; - auto session = client.connect( "ws://localhost:8090", create_session ); - wlog( "connected" ); - session->send_message( "hello world" ); - - fc::usleep( fc::seconds(2) ); - return 0; - } - /* - catch ( const websocketpp::lib::error_code& e ) - { - edump( (e.message()) ); - } - */ - catch ( const fc::exception& e ) - { - edump((e.to_detail_string())); - } -}