test/helpers.hpp | 48 +++++++++++++++++++ test/httpwstest.cpp | 125 +++++++++++++++------------------------------------- 2 files changed, 83 insertions(+), 90 deletions(-)
New commits: commit 050403daf04d6b36ef850006ba4a15eab6be9afc Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Oct 12 13:47:38 2019 -0400 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sat Oct 19 20:57:51 2019 +0200 test: improve stability of a number of tests There are numerous race conditions between issuing action and getting the events. This causes a mismatch, such that the events from SelectAll is received when waiting for the events for a subsequent action (say, Delete). To make matters worse, sometimes Core issues an invalidation whilst sending the events for an action, and this completely messes our accounting of what events we expect. This latter could also be an issue with real clients, however it's less likely to be disruptive. Still, it is possible that the client doesn't get key events because Core had a hiccup, which breaks the tests. For the tests at least, the solution is to re-issue the last action, such that we make sure that we move forward only when the correct event is received, or we timeout waiting. The end results is that tests now don't fail nearly as often as they used to. Change-Id: Ib1a658846061990649987ca083915a49c1fb092a Reviewed-on: https://gerrit.libreoffice.org/80894 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/test/helpers.hpp b/test/helpers.hpp index 06dff21f8..480c5ca6e 100644 --- a/test/helpers.hpp +++ b/test/helpers.hpp @@ -52,6 +52,9 @@ static std::mutex MutexLog; #define TST_LOG_NAME(NAME, X) TST_LOG_NAME_BEGIN(NAME, X); TST_LOG_END #define TST_LOG(X) TST_LOG_NAME(testname, X) +// Sometimes we need to retry some commands as they can (due to timing or load) soft-fail. +constexpr int COMMAND_RETRY_COUNT = 5; + /// Common helper testing functions. /// Avoid the temptation to reuse from LOOL code! /// These are supposed to be testing the latter. @@ -654,8 +657,6 @@ inline void getServerVersion(std::shared_ptr<LOOLWebSocket>& socket, getServerVersion(*socket, major, minor, testname); } -} - inline bool svgMatch(const char *testname, const std::vector<char> &response, const char *templateFile) { const std::vector<char> expectedSVG = helpers::readDataFromFile(templateFile); @@ -681,6 +682,49 @@ inline bool svgMatch(const char *testname, const std::vector<char> &response, co return true; } +/// Select all and wait for the text selection update. +inline void selectAll(const std::shared_ptr<LOOLWebSocket>& socket, const std::string& testname, int repeat = COMMAND_RETRY_COUNT) +{ + for (int i = 0; i < repeat; ++i) + { + sendTextFrame(socket, "uno .uno:SelectAll", testname); + if (!getResponseString(socket, "textselection:", testname).empty()) + break; + } +} + + +/// Delete all and wait for the text selection update. +inline void deleteAll(const std::shared_ptr<LOOLWebSocket>& socket, const std::string& testname, int repeat = COMMAND_RETRY_COUNT) +{ + selectAll(socket, testname); + + for (int i = 0; i < repeat; ++i) + { + sendTextFrame(socket, "uno .uno:Delete", testname); + if (!getResponseString(socket, "textselection:", testname).empty()) + break; + } +} + +inline std::string getAllText(const std::shared_ptr<LOOLWebSocket>& socket, + const std::string& testname, int retry = COMMAND_RETRY_COUNT) +{ + std::string text; + for (int i = 0; i < retry; ++i) + { + selectAll(socket, testname); + + sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); + text = assertResponseString(socket, "textselectioncontent:", testname); + if (!text.empty()) + break; + } + + return text; +} + +} #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/test/httpwstest.cpp b/test/httpwstest.cpp index 90b71d704..012938f2a 100644 --- a/test/httpwstest.cpp +++ b/test/httpwstest.cpp @@ -680,9 +680,7 @@ void HTTPWSTest::testGetTextSelection() std::shared_ptr<LOOLWebSocket> socket = loadDocAndGetSocket(_uri, documentURL, testname); std::shared_ptr<LOOLWebSocket> socket2 = loadDocAndGetSocket(_uri, documentURL, testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), selection); } catch (const Poco::Exception& exc) @@ -709,16 +707,13 @@ void HTTPWSTest::testSaveOnDisconnect() std::shared_ptr<LOOLWebSocket> socket2 = loadDocAndGetSocket(_uri, documentURL, testname); sendTextFrame(socket2, "userinactive"); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "uno .uno:Delete", testname); + deleteAll(socket, testname); sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\n" + text, testname); TST_LOG("Validating what we sent before disconnecting."); // Check if the document contains the pasted text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL("textselectioncontent: " + text, selection); // Closing connection too fast might not flush buffers. @@ -750,9 +745,7 @@ void HTTPWSTest::testSaveOnDisconnect() CPPUNIT_ASSERT_EQUAL(kitcount, countLoolKitProcesses(kitcount)); // Check if the document contains the pasted text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL("textselectioncontent: " + text, selection); } catch (const Poco::Exception& exc) @@ -775,18 +768,18 @@ void HTTPWSTest::testSavePassiveOnDisconnect() try { std::shared_ptr<LOOLWebSocket> socket = loadDocAndGetSocket(_uri, documentURL, testname); + getResponseMessage(socket, "textselection", testname); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); std::shared_ptr<LOOLWebSocket> socket2 = connectLOKit(_uri, request, _response, testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "uno .uno:Delete", testname); + deleteAll(socket, testname); + sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\n" + text, testname); + getResponseMessage(socket, "textselection:", testname); // Check if the document contains the pasted text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL("textselectioncontent: " + text, selection); // Closing connection too fast might not flush buffers. @@ -813,14 +806,13 @@ void HTTPWSTest::testSavePassiveOnDisconnect() { // Load the same document and check that the last changes (pasted text) is saved. std::shared_ptr<LOOLWebSocket> socket = loadDocAndGetSocket(_uri, documentURL, testname); + getResponseMessage(socket, "textselection", testname); // Should have no new instances. CPPUNIT_ASSERT_EQUAL(kitcount, countLoolKitProcesses(kitcount)); // Check if the document contains the pasted text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL("textselectioncontent: " + text, selection); } catch (const Poco::Exception& exc) @@ -839,8 +831,7 @@ void HTTPWSTest::testReloadWhileDisconnecting() std::shared_ptr<LOOLWebSocket> socket = loadDocAndGetSocket(_uri, documentURL, testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "uno .uno:Delete", testname); + deleteAll(socket, testname); sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\naaa bbb ccc", testname); // Closing connection too fast might not flush buffers. @@ -862,9 +853,7 @@ void HTTPWSTest::testReloadWhileDisconnecting() CPPUNIT_ASSERT_EQUAL(kitcount, countLoolKitProcesses(kitcount)); // Check if the document contains the pasted text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: aaa bbb ccc"), selection); } catch (const Poco::Exception& exc) @@ -907,17 +896,14 @@ void HTTPWSTest::testPaste() TST_LOG("Pasting text #" << i + 1 << ": " << text); // Always delete everything to have an empty doc. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "uno .uno:Delete", testname); + deleteAll(socket, testname); // Paste some text into it. sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\n" + text, testname); const std::string expected = "textselectioncontent: " + text; // Check if the document contains the pasted text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(expected, selection); } } @@ -930,16 +916,13 @@ void HTTPWSTest::testPasteBlank() // Load a document and make it empty, then paste nothing into it. std::shared_ptr<LOOLWebSocket> socket = loadDocAndGetSocket("hello.odt", _uri, testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "uno .uno:Delete", testname); + deleteAll(socket, testname); // Paste nothing into it. - sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8", testname); + sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\n", testname); // Check if the document contains the pasted text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: "), selection); } catch (const Poco::Exception& exc) @@ -956,8 +939,7 @@ void HTTPWSTest::testLargePaste() // Load a document and make it empty, then paste some text into it. std::shared_ptr<LOOLWebSocket> socket = loadDocAndGetSocket("hello.odt", _uri, testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "uno .uno:Delete", testname); + deleteAll(socket, testname); // Paste some text into it. std::ostringstream oss; @@ -972,9 +954,7 @@ void HTTPWSTest::testLargePaste() // Check if the server is still alive. // This resulted first in a hang, as respose for the message never arrived, then a bit later in a Poco::TimeoutException. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - const auto selection = assertResponseString(socket, "textselectioncontent:", testname); + const std::string selection = getAllText(socket, testname); CPPUNIT_ASSERT_MESSAGE("Pasted text was either corrupted or couldn't be read back", "textselectioncontent: " + documentContents == selection); } @@ -1362,8 +1342,7 @@ void HTTPWSTest::testInactiveClient() sendTextFrame(socket2, "userinactive", "inactiveClient-2 "); // While second is inactive, make some changes. - sendTextFrame(socket1, "uno .uno:SelectAll", "inactiveClient-1 "); - sendTextFrame(socket1, "uno .uno:Delete", "inactiveClient-1 "); + deleteAll(socket1, "inactiveClient-1 "); // Activate second. sendTextFrame(socket2, "useractive", "inactiveClient-2 "); @@ -1619,15 +1598,11 @@ void HTTPWSTest::testInsertAnnotationWriter() sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nxxx yyy zzzz", testname); // Read it back. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - auto res = getResponseString(socket, "textselectioncontent:", testname); + std::string res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: xxx yyy zzzz"), res); // Can we edit the coment? sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\naaa bbb ccc", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: aaa bbb ccc"), res); // Confirm that the text is in the comment and not doc body. @@ -1635,24 +1610,18 @@ void HTTPWSTest::testInsertAnnotationWriter() sendTextFrame(socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0", testname); sendTextFrame(socket, "mouse type=buttonup x=1600 y=1600 count=1 buttons=1 modifier=0", testname); // Read body text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res); // Confirm that the comment is still intact. sendTextFrame(socket, "mouse type=buttondown x=13855 y=1893 count=1 buttons=1 modifier=0", testname); sendTextFrame(socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: aaa bbb ccc"), res); // Can we still edit the coment? sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nand now for something completely different", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: and now for something completely different"), res); // Close and reopen the same document and test again. @@ -1669,24 +1638,18 @@ void HTTPWSTest::testInsertAnnotationWriter() sendTextFrame(socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0", testname); sendTextFrame(socket, "mouse type=buttonup x=1600 y=1600 count=1 buttons=1 modifier=0", testname); // Read body text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res); // Confirm that the comment is still intact. sendTextFrame(socket, "mouse type=buttondown x=13855 y=1893 count=1 buttons=1 modifier=0", testname); sendTextFrame(socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: and now for something completely different"), res); // Can we still edit the coment? sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nblah blah xyz", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: blah blah xyz"), res); } @@ -1703,24 +1666,18 @@ void HTTPWSTest::testEditAnnotationWriter() sendTextFrame(socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0", testname); sendTextFrame(socket, "mouse type=buttonup x=1600 y=1600 count=1 buttons=1 modifier=0", testname); // Read body text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - auto res = getResponseString(socket, "textselectioncontent:", testname); + std::string res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res); // Confirm that the comment is intact. sendTextFrame(socket, "mouse type=buttondown x=13855 y=1893 count=1 buttons=1 modifier=0", testname); sendTextFrame(socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: blah blah xyz"), res); // Can we still edit the coment? sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nand now for something completely different", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: and now for something completely different"), res); const int kitcount = getLoolKitProcessCount(); @@ -1740,24 +1697,18 @@ void HTTPWSTest::testEditAnnotationWriter() sendTextFrame(socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0", testname); sendTextFrame(socket, "mouse type=buttonup x=1600 y=1600 count=1 buttons=1 modifier=0", testname); // Read body text. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res); // Confirm that the comment is still intact. sendTextFrame(socket, "mouse type=buttondown x=13855 y=1893 count=1 buttons=1 modifier=0", testname); sendTextFrame(socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: and now for something completely different"), res); // Can we still edit the coment? sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nnew text different", testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - res = getResponseString(socket, "textselectioncontent:", testname); + res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: new text different"), res); } @@ -1773,9 +1724,7 @@ void HTTPWSTest::testInsertAnnotationCalc() sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\naaa bbb ccc", testname); // Read it back. - sendTextFrame(socket, "uno .uno:SelectAll", testname); - sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); - auto res = getResponseString(socket, "textselectioncontent:", testname); + std::string res = getAllText(socket, testname); CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: aaa bbb ccc"), res); } @@ -2753,7 +2702,7 @@ void HTTPWSTest::testRenderShapeSelectionImpress() std::shared_ptr<LOOLWebSocket> socket = loadDocAndGetSocket(_uri, documentURL, testname); - sendTextFrame(socket, "uno .uno:SelectAll", testname); + selectAll(socket, testname); std::this_thread::sleep_for(std::chrono::milliseconds(250)); sendTextFrame(socket, "rendershapeselection mimetype=image/svg+xml", testname); std::vector<char> responseSVG = getResponseMessage(socket, "shapeselectioncontent:", testname); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits