test/Makefile.am | 4 test/UnitLoadTorture.cpp | 217 +++++++++++++++++++++++++++++++++++++++++++++++ test/httpwstest.cpp | 170 ------------------------------------ 3 files changed, 221 insertions(+), 170 deletions(-)
New commits: commit 1bff9e7bf8f7cd5bfef962a8c7e799544ac54c79 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Oct 21 09:04:12 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Oct 21 09:04:12 2019 +0200 Convert load torture testcase to a new-style one So that they are in-process, which means it's easier to debug when they fail. Change-Id: I6b33887fbe8dd6071ee767f24d4776a694fb62f7 diff --git a/test/Makefile.am b/test/Makefile.am index a4f1eb96f..b2cf87b2d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -24,6 +24,7 @@ noinst_LTLIBRARIES = \ unit-tiff-load.la \ unit-large-paste.la \ unit-paste.la \ + unit-load-torture.la \ unit-wopi-loadencoded.la unit-wopi-temp.la MAGIC_TO_FORCE_SHLIB_CREATION = -rpath /dummy @@ -128,6 +129,8 @@ unit_large_paste_la_SOURCES = UnitLargePaste.cpp unit_large_paste_la_LIBADD = $(CPPUNIT_LIBS) unit_paste_la_SOURCES = UnitPaste.cpp unit_paste_la_LIBADD = $(CPPUNIT_LIBS) +unit_load_torture_la_SOURCES = UnitLoadTorture.cpp +unit_load_torture_la_LIBADD = $(CPPUNIT_LIBS) if HAVE_LO_PATH SYSTEM_STAMP = @SYSTEMPLATE_PATH@/system_stamp @@ -150,6 +153,7 @@ TESTS = unit-copy-paste.la unit-typing.la unit-convert.la unit-prefork.la unit-t unit-tiff-load.la \ unit-large-paste.la \ unit-paste.la \ + unit-load-torture.la \ unit-wopi-loadencoded.la unit-wopi-temp.la # TESTS = unit-client.la # TESTS += unit-admin.la diff --git a/test/UnitLoadTorture.cpp b/test/UnitLoadTorture.cpp new file mode 100644 index 000000000..01d2a385a --- /dev/null +++ b/test/UnitLoadTorture.cpp @@ -0,0 +1,217 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <memory> +#include <string> + +#include <Poco/URI.h> +#include <cppunit/TestAssert.h> + +#include <Unit.hpp> +#include <Util.hpp> +#include <helpers.hpp> + +class LOOLWebSocket; + +/// Load torture testcase. +class UnitLoadTorture : public UnitWSD +{ + int loadTorture(const std::string& testname, const std::string& docName, + const size_t thread_count, const size_t max_jitter_ms); + TestResult testLoadTortureODT(); + TestResult testLoadTortureODS(); + TestResult testLoadTortureODP(); + TestResult testLoadTorture(); + +public: + void invokeTest() override; +}; + +int UnitLoadTorture::loadTorture(const std::string& testname, const std::string& docName, + const size_t thread_count, const size_t max_jitter_ms) +{ + // Load same document from many threads together. + std::string documentPath, documentURL; + helpers::getDocumentPathAndURL(docName, documentPath, documentURL, testname); + + std::atomic<int> sum_view_ids; + sum_view_ids = 0; + std::atomic<int> num_of_views(0); + std::atomic<int> num_to_load(thread_count); + + std::vector<std::thread> threads; + for (size_t i = 0; i < thread_count; ++i) + { + threads.emplace_back([&] { + std::ostringstream oss; + oss << std::hex << std::this_thread::get_id(); + const std::string id = oss.str(); + + TST_LOG(": #" << id << ", views: " << num_of_views << ", to load: " << num_to_load); + try + { + // Load a document and wait for the status. + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); + Poco::Net::HTTPResponse response; + std::shared_ptr<LOOLWebSocket> socket = helpers::connectLOKit( + Poco::URI(helpers::getTestServerURI()), request, response, testname); + helpers::sendTextFrame(socket, "load url=" + documentURL, testname); + + const auto status = helpers::assertResponseString(socket, "status:", testname); + int viewid = -1; + LOOLProtocol::getTokenIntegerFromMessage(status, "viewid", viewid); + sum_view_ids += viewid; + ++num_of_views; + --num_to_load; + + TST_LOG(": #" << id << ", loaded views: " << num_of_views + << ", to load: " << num_to_load); + + while (true) + { + if (num_to_load == 0) + { + // Unload at once, nothing more left to do. + TST_LOG(": #" << id << ", no more to load, unloading."); + break; + } + + const auto ms + = (max_jitter_ms > 0 + ? std::chrono::milliseconds(Util::rng::getNext() % max_jitter_ms) + : std::chrono::milliseconds(0)); + std::this_thread::sleep_for(ms); + + // Unload only when we aren't the last/only. + if (--num_of_views > 0) + { + TST_LOG(": #" << id << ", views: " << num_of_views + << " not the last/only, unloading."); + break; + } + else + { + // Correct back, since we aren't unloading just yet. + ++num_of_views; + } + } + } + catch (const std::exception& exc) + { + TST_LOG(": #" << id << ", Exception: " << exc.what()); + --num_to_load; + } + }); + } + + for (auto& thread : threads) + { + try + { + thread.join(); + } + catch (const std::exception& exc) + { + TST_LOG(": Exception: " << exc.what()); + } + } + + return sum_view_ids; +} + +UnitBase::TestResult UnitLoadTorture::testLoadTortureODT() +{ + const int thread_count = 6; + const int max_jitter_ms = 100; + + const char* testname = "loadTortureODT "; + const int sum_view_ids = loadTorture(testname, "empty.odt", thread_count, max_jitter_ms); + + // This only works when the first view-ID is 0 and increments monotonously. + const int number_of_loads = thread_count; + const int exp_sum_view_ids = number_of_loads * (number_of_loads - 1) / 2; // 0-based view-ids. + CPPUNIT_ASSERT_EQUAL(exp_sum_view_ids, sum_view_ids); + return TestResult::Ok; +} + +UnitBase::TestResult UnitLoadTorture::testLoadTortureODS() +{ + const int thread_count = 6; + const int max_jitter_ms = 100; + + const char* testname = "loadTortureODS "; + const int sum_view_ids = loadTorture(testname, "empty.ods", thread_count, max_jitter_ms); + + // This only works when the first view-ID is 0 and increments monotonously. + const int number_of_loads = thread_count; + const int exp_sum_view_ids = number_of_loads * (number_of_loads - 1) / 2; // 0-based view-ids. + CPPUNIT_ASSERT_EQUAL(exp_sum_view_ids, sum_view_ids); + return TestResult::Ok; +} + +UnitBase::TestResult UnitLoadTorture::testLoadTortureODP() +{ + const int thread_count = 6; + const int max_jitter_ms = 100; + + const char* testname = "loadTortureODP "; + const int sum_view_ids = loadTorture(testname, "empty.odp", thread_count, max_jitter_ms); + + // For ODP the view-id is always odd, and we expect not to skip any ids. + const int number_of_loads = thread_count; + const int exp_sum_view_ids = number_of_loads * (number_of_loads - 1) / 2; // 0-based view-ids. + CPPUNIT_ASSERT_EQUAL(exp_sum_view_ids, sum_view_ids); + return TestResult::Ok; +} + +UnitBase::TestResult UnitLoadTorture::testLoadTorture() +{ + const int thread_count = 3; + const int max_jitter_ms = 75; + + std::vector<std::string> docNames = { "setclientpart.ods", "hello.odt", "viewcursor.odp" }; + + std::vector<std::thread> threads; + threads.reserve(docNames.size()); + for (const auto& docName : docNames) + { + threads.emplace_back([&] { + const auto testname = "loadTorture_" + docName + ' '; + loadTorture(testname, docName, thread_count, max_jitter_ms); + }); + } + + for (auto& thread : threads) + { + thread.join(); + } + return TestResult::Ok; +} + +void UnitLoadTorture::invokeTest() +{ + UnitBase::TestResult result = testLoadTortureODT(); + if (result != TestResult::Ok) + exitTest(result); + + result = testLoadTortureODS(); + if (result != TestResult::Ok) + exitTest(result); + + result = testLoadTortureODP(); + if (result != TestResult::Ok) + exitTest(result); + + result = testLoadTorture(); + exitTest(result); +} + +UnitBase* unit_create_wsd(void) { return new UnitLoadTorture(); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/test/httpwstest.cpp b/test/httpwstest.cpp index 64f211cb8..a934af15a 100644 --- a/test/httpwstest.cpp +++ b/test/httpwstest.cpp @@ -90,10 +90,6 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST(testCloseAfterClose); CPPUNIT_TEST(testConnectNoLoad); CPPUNIT_TEST(testLoadSimple); - CPPUNIT_TEST(testLoadTortureODT); - CPPUNIT_TEST(testLoadTortureODS); - CPPUNIT_TEST(testLoadTortureODP); - CPPUNIT_TEST(testLoadTorture); CPPUNIT_TEST(testBadLoad); CPPUNIT_TEST(testReload); CPPUNIT_TEST(testGetTextSelection); @@ -148,10 +144,6 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture void testCloseAfterClose(); void testConnectNoLoad(); void testLoadSimple(); - void testLoadTortureODT(); - void testLoadTortureODS(); - void testLoadTortureODP(); - void testLoadTorture(); void testBadLoad(); void testReload(); void testGetTextSelection(); @@ -201,11 +193,6 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture void loadDoc(const std::string& documentURL, const std::string& testname); - int loadTorture(const std::string& testname, - const std::string& docName, - const size_t thread_count, - const size_t max_jitter_ms); - void getPartHashCodes(const std::string& testname, const std::string& response, std::vector<std::string>& parts); @@ -471,163 +458,6 @@ void HTTPWSTest::testLoadSimple() loadDoc(documentURL, "load "); } -int HTTPWSTest::loadTorture(const std::string& testname, - const std::string& docName, - const size_t thread_count, - const size_t max_jitter_ms) -{ - // Load same document from many threads together. - std::string documentPath, documentURL; - getDocumentPathAndURL(docName, documentPath, documentURL, testname); - - std::atomic<int> sum_view_ids; - sum_view_ids = 0; - std::atomic<int> num_of_views(0); - std::atomic<int> num_to_load(thread_count); - - std::vector<std::thread> threads; - for (size_t i = 0; i < thread_count; ++i) - { - threads.emplace_back([&] - { - std::ostringstream oss; - oss << std::hex << std::this_thread::get_id(); - const std::string id = oss.str(); - - TST_LOG(": #" << id << ", views: " << num_of_views << ", to load: " << num_to_load); - try - { - // Load a document and wait for the status. - Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - Poco::Net::HTTPResponse response; - std::shared_ptr<LOOLWebSocket> socket = connectLOKit(_uri, request, response, testname); - sendTextFrame(socket, "load url=" + documentURL, testname); - - const auto status = assertResponseString(socket, "status:", testname); - int viewid = -1; - LOOLProtocol::getTokenIntegerFromMessage(status, "viewid", viewid); - sum_view_ids += viewid; - ++num_of_views; - --num_to_load; - - TST_LOG(": #" << id << ", loaded views: " << num_of_views << ", to load: " << num_to_load); - - while (true) - { - if (num_to_load == 0) - { - // Unload at once, nothing more left to do. - TST_LOG(": #" << id << ", no more to load, unloading."); - break; - } - - const auto ms = (max_jitter_ms > 0 - ? std::chrono::milliseconds(Util::rng::getNext() % max_jitter_ms) - : std::chrono::milliseconds(0)); - std::this_thread::sleep_for(ms); - - // Unload only when we aren't the last/only. - if (--num_of_views > 0) - { - TST_LOG(": #" << id << ", views: " << num_of_views << " not the last/only, unloading."); - break; - } - else - { - // Correct back, since we aren't unloading just yet. - ++num_of_views; - } - } - } - catch (const std::exception& exc) - { - TST_LOG(": #" << id << ", Exception: " << exc.what()); - --num_to_load; - } - }); - } - - for (auto& thread : threads) - { - try - { - thread.join(); - } - catch (const std::exception& exc) - { - TST_LOG(": Exception: " << exc.what()); - } - } - - return sum_view_ids; -} - -void HTTPWSTest::testLoadTortureODT() -{ - const int thread_count = 6; - const int max_jitter_ms = 100; - - const char* testname = "loadTortureODT "; - const int sum_view_ids = loadTorture(testname, "empty.odt", thread_count, max_jitter_ms); - - // This only works when the first view-ID is 0 and increments monotonously. - const int number_of_loads = thread_count; - const int exp_sum_view_ids = number_of_loads * (number_of_loads - 1) / 2; // 0-based view-ids. - CPPUNIT_ASSERT_EQUAL(exp_sum_view_ids, sum_view_ids); -} - -void HTTPWSTest::testLoadTortureODS() -{ - const int thread_count = 6; - const int max_jitter_ms = 100; - - const char* testname = "loadTortureODS "; - const int sum_view_ids = loadTorture(testname, "empty.ods", thread_count, max_jitter_ms); - - // This only works when the first view-ID is 0 and increments monotonously. - const int number_of_loads = thread_count; - const int exp_sum_view_ids = number_of_loads * (number_of_loads - 1) / 2; // 0-based view-ids. - CPPUNIT_ASSERT_EQUAL(exp_sum_view_ids, sum_view_ids); -} - -void HTTPWSTest::testLoadTortureODP() -{ - const int thread_count = 6; - const int max_jitter_ms = 100; - - const char* testname = "loadTortureODP "; - const int sum_view_ids = loadTorture(testname, "empty.odp", thread_count, max_jitter_ms); - - // For ODP the view-id is always odd, and we expect not to skip any ids. - const int number_of_loads = thread_count; - const int exp_sum_view_ids = number_of_loads * (number_of_loads - 1) / 2; // 0-based view-ids. - CPPUNIT_ASSERT_EQUAL(exp_sum_view_ids, sum_view_ids); -} - -void HTTPWSTest::testLoadTorture() -{ - const int thread_count = 3; - const int max_jitter_ms = 75; - - std::vector<std::string> docNames = { "setclientpart.ods", "hello.odt", "viewcursor.odp" }; - - std::vector<std::thread> threads; - threads.reserve(docNames.size()); - for (const auto& docName : docNames) - { - threads.emplace_back([&] - { - const auto testname = "loadTorture_" + docName + ' '; - loadTorture(testname, docName, thread_count, max_jitter_ms); - }); - } - - for (auto& thread : threads) - { - thread.join(); - } -} - void HTTPWSTest::testBadLoad() { const char* testname = "badLoad "; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits