Replace total pid count waits with targeted waits

Wait for doc kits or spare kit counts specifically. This removes the chance of
race conditions between waiting for doc kits to shutdown and the spare kit to
start back up.

Signed-off-by: Neil Guertin <neil.guertin@collabora.com>
Change-Id: If28da4b786d3e2b429acb5840dfcdb7bb5a3f948
pull/8503/head
Neil Guertin 2024-03-07 15:55:34 -05:00 committed by Michael Meeks
parent f82915ebcb
commit 7e81b5ebbc
7 changed files with 202 additions and 243 deletions

View File

@ -14,13 +14,11 @@
#include <chrono>
#include <iostream>
#include <thread>
#include <string>
#include <wsd/COOLWSD.hpp>
#include <Common.hpp>
#include <Util.hpp>
#include <lokassert.hpp>
#include <test.hpp>
#include <testlog.hpp>
std::string getPidList(std::set<pid_t> pids);
@ -31,134 +29,12 @@ std::set<pid_t> helpers::getSpareKitPids() { return COOLWSD::getSpareKitPids();
std::set<pid_t> helpers::getDocKitPids() { return COOLWSD::getDocKitPids(); }
/// Get the PID of the forkit
std::set<pid_t> helpers::getForKitPids()
pid_t helpers::getForKitPid()
{
std::set<pid_t> pids;
if (COOLWSD::ForKitProcId >= 0)
pids.emplace(COOLWSD::ForKitProcId);
return pids;
}
/// How many live coolkit processes do we have ?
int helpers::getCoolKitProcessCount()
{
return getKitPids().size();
}
int helpers::countCoolKitProcesses(const int expected)
{
std::chrono::milliseconds timeoutMs = std::chrono::milliseconds(COMMAND_TIMEOUT_MS) * 8;
const auto testname = "countCoolKitProcesses ";
TST_LOG_BEGIN("Waiting until coolkit processes are exactly " << expected << ". Coolkits: ");
Util::Stopwatch stopwatch;
// This does not need to depend on any constant from Common.hpp.
// The shorter the better (the quicker the test runs).
constexpr int sleepMs = 10;
// This has to cause waiting for at least COMMAND_TIMEOUT_MS. Tolerate more for safety.
const std::size_t repeat = (timeoutMs.count() / sleepMs);
int count = getCoolKitProcessCount();
for (std::size_t i = 0; i < repeat; ++i)
{
TST_LOG_APPEND(count << ' ');
if (count == expected)
{
break;
}
// Give polls in the cool processes time to time out etc
std::this_thread::sleep_for(std::chrono::milliseconds(sleepMs));
const int newCount = getCoolKitProcessCount();
if (count != newCount)
{
// Allow more time until the number settles.
i = 0;
count = newCount;
}
}
TST_LOG_END;
LOK_ASSERT(expected == count);
if (expected != count)
{
TST_LOG_BEGIN("Found " << count << " LoKit processes but was expecting " << expected << ": [");
for (pid_t i : getKitPids())
{
TST_LOG_APPEND(i << ' ');
}
TST_LOG_APPEND(']');
TST_LOG_END;
}
std::set<pid_t> pids = getKitPids();
std::ostringstream oss;
oss << "Test kit pids are [";
for (pid_t i : pids)
oss << i << ' ';
oss << "] after waiting for " << stopwatch.elapsed();
TST_LOG(oss.str());
return count;
}
void helpers::testCountHowManyCoolkits()
{
const char testname[] = "countHowManyCoolkits ";
resetTestStartTime();
countCoolKitProcesses(InitialCoolKitCount);
TST_LOG("Initial coolkit count is " << InitialCoolKitCount);
LOK_ASSERT(InitialCoolKitCount > 0);
resetTestStartTime();
}
void helpers::testNoExtraCoolKitsLeft()
{
const char testname[] = "noExtraCoolKitsLeft ";
const int countNow = countCoolKitProcesses(InitialCoolKitCount);
LOK_ASSERT_EQUAL(InitialCoolKitCount, countNow);
const auto durationMs = timeSinceTestStartMs();
TST_LOG(" (" << durationMs << ')');
}
void helpers::waitForKitProcessToStop(
const pid_t pid,
const std::string& testname,
const std::chrono::milliseconds timeoutMs /* = COMMAND_TIMEOUT_MS * 8 */,
const std::chrono::milliseconds retryMs /* = 10ms */)
{
TST_LOG("Waiting for kit process " << pid << " to stop.");
std::set<pid_t> pids = getDocKitPids();
TST_LOG("Active kit pids are: " << getPidList(pids));
int tries = (timeoutMs / retryMs);
while(pids.contains(pid) && tries >= 0)
{
std::this_thread::sleep_for(retryMs);
pids = getDocKitPids();
tries--;
}
if (pids.contains(pid))
{
std::ostringstream oss;
oss << "Timed out waiting for kit process " << pid << " to stop. Active kit pids are: " << getPidList(pids);
LOK_ASSERT_FAIL(oss.str());
}
else
{
TST_LOG("Finished waiting for kit process " << pid << " to stop.");
TST_LOG("Active kit pids are: " << getPidList(pids));
}
std::string testname = "getForKitPid";
pid_t pid = COOLWSD::ForKitProcId;
LOK_ASSERT_MESSAGE("Expected forkit process id to be >= 0", pid > 0);
return pid;
}
std::string getPidList(std::set<pid_t> pids)
@ -172,3 +48,82 @@ std::string getPidList(std::set<pid_t> pids)
oss << "]";
return oss.str();
}
void helpers::logKitProcesses(const std::string& testname)
{
std::set<pid_t> docKitPids = getDocKitPids();
std::set<pid_t> spareKitPids = getSpareKitPids();
TST_LOG("Current kit processes: "
<< "Doc Kits: " << getPidList(docKitPids)
<< " Spare Kits: " << getPidList(spareKitPids));
}
void helpers::waitForKitProcessCount(
const std::string& testname,
int numDocKits,
int numSpareKits /* = -1 */,
const std::chrono::milliseconds timeoutMs /* = COMMAND_TIMEOUT_MS * 8 */,
const std::chrono::milliseconds retryMs /* = 10ms */)
{
TST_LOG("Waiting for kit process count: "
<< (numDocKits >= 0 ? "Doc Kits: " + std::to_string(numDocKits) + " " : "")
<< (numSpareKits >= 0 ? " Spare Kits: " + std::to_string(numSpareKits) + " " : ""));
std::set<pid_t> docKitPids = getDocKitPids();
std::set<pid_t> spareKitPids = getSpareKitPids();
bool pass = (numDocKits < 0 || docKitPids.size() == static_cast<size_t>(numDocKits)) &&
(numSpareKits < 0 || spareKitPids.size() == static_cast<size_t>(numSpareKits));
int tries = (timeoutMs / retryMs);
TST_LOG("Current kit processes: "
<< "Doc Kits: " << getPidList(docKitPids)
<< " Spare Kits: " << getPidList(spareKitPids));
while (tries >= 0 && !pass)
{
std::this_thread::sleep_for(retryMs);
docKitPids = getDocKitPids();
spareKitPids = getSpareKitPids();
pass = (numDocKits < 0 || docKitPids.size() == static_cast<size_t>(numDocKits)) &&
(numSpareKits < 0 || spareKitPids.size() == static_cast<size_t>(numSpareKits));
tries--;
TST_LOG("Current kit processes: "
<< "Doc Kits: " << getPidList(docKitPids)
<< " Spare Kits: " << getPidList(spareKitPids));
}
if (pass)
{
TST_LOG("Finished waiting for kit process count: "
<< (numDocKits >= 0 ? "Doc Kits: " + std::to_string(numDocKits) + " " : "")
<< (numSpareKits >= 0 ? " Spare Kits: " + std::to_string(numSpareKits) + " " : ""));
}
else
{
std::ostringstream oss;
oss << (numDocKits >= 0 ? "Doc Kits: " + std::to_string(numDocKits) + " " : "")
<< (numSpareKits >= 0 ? " Spare Kits: " + std::to_string(numSpareKits) + " " : "")
<< "Current kit processes: "
<< "Doc Kits: " << getPidList(docKitPids)
<< " Spare Kits: " << getPidList(spareKitPids);
LOK_ASSERT_FAIL("Timed out waiting for kit process count: " + oss.str());
}
}
void helpers::waitForKitPidsReady(
const std::string& testname,
const std::chrono::milliseconds timeoutMs /* = KIT_PID_TIMEOUT_MS */,
const std::chrono::milliseconds retryMs /* = KIT_PID_RETRY_MS */)
{
waitForKitProcessCount(testname, 0, 1, timeoutMs, retryMs);
}
void helpers::waitForKitPidsKilled(
const std::string& testname,
const std::chrono::milliseconds timeoutMs /* = KIT_PID_TIMEOUT_MS */,
const std::chrono::milliseconds retryMs /* = KIT_PID_RETRY_MS */)
{
waitForKitProcessCount(testname, 0, 0, timeoutMs, retryMs);
}

View File

@ -21,32 +21,59 @@
namespace helpers
{
const int InitialCoolKitCount = 1;
void testCountHowManyCoolkits();
void testNoExtraCoolKitsLeft();
constexpr int KIT_PID_TIMEOUT_MS = 4000 * TRACE_MULTIPLIER;
constexpr int KIT_PID_RETRY_MS = 20;
int countCoolKitProcesses(const int expected);/*,
std::chrono::milliseconds timeoutMs
= std::chrono::milliseconds(COMMAND_TIMEOUT_MS * 8));
*/
/// Get the list of all kit PIDs
/*
* Get the list of all kit pids
*/
std::set<pid_t> getKitPids();
/// Get the list of spare (unused) kit PIDs
/*
* Get the list of spare (unused) kit pids
*/
std::set<pid_t> getSpareKitPids();
/// Get the list of doc (loaded) kit PIDs
/*
* Get the list of doc (loaded) kit pids
*/
std::set<pid_t> getDocKitPids();
/// Get the PID of the forkit
std::set<pid_t> getForKitPids();
/*
* Get the pid of the coolforkit process
*/
pid_t getForKitPid();
/// How many live coolkit processes do we have ?
int getCoolKitProcessCount();
/*
* Log the current doc and spare kit pids
* Useful for debugging
*/
void logKitProcesses(const std::string& testname);
void waitForKitProcessToStop(
const pid_t pid,
/*
* Wait until the number of kit processes matches the desired count.
* Set numDocKits and numSpareKits to -1 to skip counting those processes
*/
void waitForKitProcessCount(const std::string& testname, int numDocKits, int numSpareKits,
const std::chrono::milliseconds timeoutMs,
const std::chrono::milliseconds retryMs);
/*
* Wait until ready with 0 doc kits and 1 spare kit
* Used to wait for spare kit to start up before use
* or to wait for doc kits to shut down after
*/
void waitForKitPidsReady(
const std::string& testname,
const std::chrono::milliseconds timeoutMs = std::chrono::milliseconds(COMMAND_TIMEOUT_MS * 8),
const std::chrono::milliseconds retryMs = std::chrono::milliseconds(10));
const std::chrono::milliseconds timeoutMs = std::chrono::milliseconds(KIT_PID_TIMEOUT_MS),
const std::chrono::milliseconds retryMs = std::chrono::milliseconds(KIT_PID_RETRY_MS));
}
/*
* Wait until all doc and spare kits are closed
*/
void waitForKitPidsKilled(
const std::string& testname,
const std::chrono::milliseconds timeoutMs = std::chrono::milliseconds(KIT_PID_TIMEOUT_MS),
const std::chrono::milliseconds retryMs = std::chrono::milliseconds(KIT_PID_RETRY_MS));
} // namespace helpers

View File

@ -22,6 +22,9 @@
#include <cppunit/extensions/HelperMacros.h>
#include <sstream>
#include <random>
#include <Common.hpp>
#include <Protocol.hpp>
#include <MessageQueue.hpp>
@ -171,7 +174,7 @@ public:
void setUp()
{
resetTestStartTime();
testCountHowManyCoolkits();
waitForKitPidsReady("setUp");
resetTestStartTime();
_socketPoll->startThread();
}
@ -180,7 +183,7 @@ public:
{
_socketPoll->joinThread();
resetTestStartTime();
testNoExtraCoolKitsLeft();
waitForKitPidsReady("tearDown");
resetTestStartTime();
}
};
@ -451,13 +454,14 @@ void TileCacheTests::testDisconnectMultiView()
constexpr size_t repeat = 2;
for (size_t j = 1; j <= repeat; ++j)
{
std::string documentPath, documentURL;
getDocumentPathAndURL("setclientpart.ods", documentPath, documentURL, "disconnectMultiView ");
// Make sure previous sessions have closed
waitForKitPidsReady(testname);
TST_LOG("disconnectMultiView try #" << j);
// Wait to clear previous sessions.
countCoolKitProcesses(InitialCoolKitCount);
std::string documentPath, documentURL;
getDocumentPathAndURL("setclientpart.ods", documentPath, documentURL, "disconnectMultiView ");
// Request a huge tile, and cancel immediately.
std::shared_ptr<http::WebSocketSession> socket1

View File

@ -268,9 +268,6 @@ UnitBase::TestResult UnitCursor::testInsertAnnotationWriter()
LOK_ASSERT_MESSAGE("Expected successful disconnection of the WebSocket",
socket->waitForDisconnection(std::chrono::seconds(5)));
// Make sure the document is fully unloaded.
// testNoExtraCoolKitsLeft();
TST_LOG("Reloading ");
socket = helpers::loadDocAndGetSession(socketPoll, uri, documentURL, testname);
@ -340,8 +337,6 @@ UnitBase::TestResult UnitCursor::testEditAnnotationWriter()
LOK_ASSERT_EQUAL(
std::string("textselectioncontent: and now for something completely different"), res);
// const int kitcount = getCoolKitProcessCount();
// Close and reopen the same document and test again.
TST_LOG("Closing connection after pasting.");
socket->shutdownWS();
@ -351,9 +346,6 @@ UnitBase::TestResult UnitCursor::testEditAnnotationWriter()
TST_LOG("Reloading ");
socket = helpers::loadDocAndGetSession(socketPoll, uri, documentURL, testname);
// Should have no new instances.
// LOK_ASSERT_EQUAL(kitcount, countCoolKitProcesses(kitcount));
// Confirm that the text is in the comment and not doc body.
// Click in the body.
helpers::sendTextFrame(

View File

@ -55,7 +55,6 @@ class HTTPCrashTest : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(testBarren);
CPPUNIT_TEST(testCrashKit);
CPPUNIT_TEST(testRecoverAfterKitCrash);
CPPUNIT_TEST(testCrashForkit);
CPPUNIT_TEST_SUITE_END();
@ -65,9 +64,9 @@ class HTTPCrashTest : public CPPUNIT_NS::TestFixture
void testRecoverAfterKitCrash();
void testCrashForkit();
static
void killLoKitProcesses();
void killForkitProcess();
void killPid(const pid_t pid, const std::string& testname);
void killDocKitProcesses(const std::string& testname);
void killAllKitProcesses(const std::string& testname);
public:
HTTPCrashTest()
@ -94,7 +93,7 @@ public:
void setUp()
{
resetTestStartTime();
testCountHowManyCoolkits();
waitForKitPidsReady("setUp");
resetTestStartTime();
_socketPoll->startThread();
}
@ -103,23 +102,24 @@ public:
{
_socketPoll->joinThread();
resetTestStartTime();
testNoExtraCoolKitsLeft();
waitForKitPidsReady("tearDown");
resetTestStartTime();
}
};
void HTTPCrashTest::testBarren()
{
#if 0 // FIXME why does this fail?
// Kill all kit processes and try loading a document.
const char* testname = "barren ";
try
{
killLoKitProcesses();
countCoolKitProcesses(0);
TST_LOG("Killing all kits");
killAllKitProcesses(testname);
waitForKitPidsKilled(testname);
// Do not wait for spare kit to start up here
TST_LOG("Loading after kill.");
// Load a document and get its status.
std::shared_ptr<http::WebSocketSession> socket
= loadDocAndGetSession(_socketPoll, "hello.odt", _uri, testname);
@ -128,7 +128,6 @@ void HTTPCrashTest::testBarren()
assertResponseString(socket, "status:", testname);
socket->asyncShutdown();
LOK_ASSERT_MESSAGE("Expected successful disconnection of the WebSocket",
socket->waitForDisconnection(std::chrono::seconds(5)));
}
@ -136,7 +135,6 @@ void HTTPCrashTest::testBarren()
{
LOK_ASSERT_FAIL(exc.displayText());
}
#endif
}
void HTTPCrashTest::testCrashKit()
@ -144,18 +142,18 @@ void HTTPCrashTest::testCrashKit()
const char* testname = "crashKit ";
try
{
TST_LOG("Loading document");
std::shared_ptr<http::WebSocketSession> socket
= loadDocAndGetSession(_socketPoll, "empty.odt", _uri, testname);
TST_LOG("Allowing time for kits to spawn and connect to wsd to get cleanly killed");
TST_LOG("Allowing time for kit to connect to wsd to get cleanly killed");
std::this_thread::sleep_for(std::chrono::seconds(1));
TST_LOG("Killing coolkit instances.");
killAllKitProcesses(testname);
waitForKitPidsKilled(testname);
killLoKitProcesses();
countCoolKitProcesses(0);//, std::chrono::seconds(1));
TST_LOG("Reading the error code from the socket.");
// TST_LOG("Reading the error code from the socket.");
//FIXME: implement in WebSocketSession.
// std::string message;
// const int statusCode = getErrorCode(socket, message, testname);
@ -179,28 +177,20 @@ void HTTPCrashTest::testRecoverAfterKitCrash()
const char* testname = "recoverAfterKitCrash ";
try
{
TST_LOG("Loading document");
std::shared_ptr<http::WebSocketSession> socket1
= loadDocAndGetSession(_socketPoll, "empty.odt", _uri, testname);
TST_LOG("Allowing time for kits to spawn and connect to wsd to get cleanly killed");
TST_LOG("Allowing time for kit to connect to wsd to get cleanly killed");
std::this_thread::sleep_for(std::chrono::seconds(1));
TST_LOG("Killing coolkit instances.");
killDocKitProcesses(testname);
waitForKitPidsReady(testname);
killLoKitProcesses();
countCoolKitProcesses(0);//, std::chrono::seconds(1));
// We expect the client connection to close.
TST_LOG("Reconnect after kill.");
std::shared_ptr<http::WebSocketSession> socket2 = loadDocAndGetSession(
_socketPoll, "empty.odt", _uri, testname, /*isView=*/true, /*isAssert=*/false);
if (!socket2)
{
// In case still starting up.
sleep(2);
socket2 = loadDocAndGetSession(_socketPoll, "empty.odt", _uri, testname);
}
sendTextFrame(socket2, "status", testname);
assertResponseString(socket2, "status:", testname);
@ -224,13 +214,17 @@ void HTTPCrashTest::testCrashForkit()
const char* testname = "crashForkit ";
try
{
TST_LOG("Loading document");
std::shared_ptr<http::WebSocketSession> socket
= loadDocAndGetSession(_socketPoll, "empty.odt", _uri, testname);
TST_LOG("Killing forkit.");
killForkitProcess();
TST_LOG("Communicating after kill.");
TST_LOG("Allowing time for kit to connect to wsd to get cleanly killed");
std::this_thread::sleep_for(std::chrono::seconds(1));
TST_LOG("Killing forkit.");
killPid(getForKitPid(), testname);
TST_LOG("Communicating after kill.");
sendTextFrame(socket, "status", testname);
assertResponseString(socket, "status:", testname);
@ -240,13 +234,20 @@ void HTTPCrashTest::testCrashForkit()
socket->waitForDisconnection(std::chrono::seconds(5)));
TST_LOG("Killing coolkit.");
killLoKitProcesses();
countCoolKitProcesses(0);
killAllKitProcesses(testname);
waitForKitPidsKilled(testname);
// Forkit should restart
waitForKitPidsReady(testname);
TST_LOG("Communicating after kill.");
socket = loadDocAndGetSession(_socketPoll, "empty.odt", _uri, testname);
sendTextFrame(socket, "status", testname);
assertResponseString(socket, "status:", testname);
socket->asyncShutdown();
LOK_ASSERT_MESSAGE("Expected successful disconnection of the WebSocket",
socket->waitForDisconnection(std::chrono::seconds(5)));
socket->waitForDisconnection(std::chrono::seconds(5)));
}
catch (const Poco::Exception& exc)
{
@ -254,27 +255,29 @@ void HTTPCrashTest::testCrashForkit()
}
}
static void killPids(const std::set<pid_t> &pids, const std::string& testname)
void HTTPCrashTest::killPid(const pid_t pid, const std::string& testname)
{
TST_LOG("kill pids " << pids.size());
// Now kill them
for (pid_t pid : pids)
TST_LOG("Killing " << pid);
if (kill(pid, SIGKILL) == -1)
{
TST_LOG_BEGIN("Killing " << pid);
if (kill(pid, SIGKILL) == -1)
TST_LOG_APPEND("kill(" << pid << ", SIGKILL) failed: " << Util::symbolicErrno(errno) << ": " << std::strerror(errno));
TST_LOG_END;
TST_LOG("kill(" << pid << ", SIGKILL) failed: " << Util::symbolicErrno(errno) << ": " << std::strerror(errno));
}
}
void HTTPCrashTest::killLoKitProcesses()
void HTTPCrashTest::killDocKitProcesses(const std::string& testname)
{
killPids(getKitPids(), "killLoKitProcesses ");
for (pid_t pid : getDocKitPids())
{
killPid(pid, testname);
}
}
void HTTPCrashTest::killForkitProcess()
void HTTPCrashTest::killAllKitProcesses(const std::string& testname)
{
killPids(getForKitPids(), "killForkitProcess ");
for (pid_t pid : getKitPids())
{
killPid(pid, testname);
}
}
CPPUNIT_TEST_SUITE_REGISTRATION(HTTPCrashTest);

View File

@ -87,7 +87,7 @@ public:
void setUp()
{
resetTestStartTime();
testCountHowManyCoolkits();
waitForKitPidsReady("setUp");
resetTestStartTime();
_socketPoll->startThread();
}
@ -96,7 +96,7 @@ public:
{
_socketPoll->joinThread();
resetTestStartTime();
testNoExtraCoolKitsLeft();
waitForKitPidsReady("tearDown");
resetTestStartTime();
}
};
@ -135,7 +135,6 @@ void HTTPWSTest::testSaveOnDisconnect()
std::string documentPath, documentURL;
getDocumentPathAndURL("hello.odt", documentPath, documentURL, testname);
pid_t origPid;
try
{
std::shared_ptr<http::WebSocketSession> socket1
@ -149,11 +148,6 @@ void HTTPWSTest::testSaveOnDisconnect()
sendTextFrame(socket1, "paste mimetype=text/plain;charset=utf-8\n" + text, testname);
getResponseMessage(socket1, "pasteresult: success", testname);
std::set<pid_t> origPids = getDocKitPids();
LOK_ASSERT_EQUAL(static_cast<size_t>(1), origPids.size());
origPid = *(origPids.begin());
TST_LOG("Original pid: " << origPid);
// Shutdown abruptly.
TST_LOG("Closing connection after pasting.");
@ -164,29 +158,15 @@ void HTTPWSTest::testSaveOnDisconnect()
socket1->waitForDisconnection(std::chrono::seconds(5)));
LOK_ASSERT_MESSAGE("Expected successful disconnection of the WebSocket 2",
socket2->waitForDisconnection(std::chrono::seconds(5)));
}
catch (const Poco::Exception& exc)
{
LOK_ASSERT_FAIL(exc.displayText());
}
// Allow time to save and destroy before we connect again.
waitForKitProcessToStop(origPid,testname);
// Allow time to save and destroy before we connect again.
waitForKitPidsReady(testname);
TST_LOG("Loading again.");
try
{
TST_LOG("Loading again.");
// Load the same document and check that the last changes (pasted text) is saved.
std::shared_ptr<http::WebSocketSession> socket
= loadDocAndGetSession(_socketPoll, _uri, documentURL, testname + "3 ");
// Should have no new instances.
std::set<pid_t> newPids = getDocKitPids();
LOK_ASSERT_EQUAL(static_cast<size_t>(1), newPids.size());
pid_t newPid = *(newPids.begin());
TST_LOG("New pid: " << newPid);
LOK_ASSERT_MESSAGE("New pid ("<<newPid<<") should not match old pid ("<<origPid<<")", newPid != origPid);
// Check if the document contains the pasted text.
const std::string selection = getAllText(socket, testname, text);
LOK_ASSERT_EQUAL("textselectioncontent: " + text, selection);
@ -221,21 +201,19 @@ void HTTPWSTest::testReloadWhileDisconnecting()
// the socket is closed, when the doc is not even modified yet.
getResponseMessage(socket, "statechanged", testname);
const int kitcount = getCoolKitProcessCount();
// Shutdown abruptly.
TST_LOG("Closing connection after pasting.");
socket->asyncShutdown();
LOK_ASSERT_MESSAGE("Expected successful disconnection of the WebSocket",
socket->waitForDisconnection(std::chrono::seconds(5)));
// Do not wait here. Reconnect before disconnect finishes
// TODO: Test fails because it is unable to reconnect
// Load the same document and check that the last changes (pasted text) is saved.
TST_LOG("Loading again.");
socket = loadDocAndGetSession(_socketPoll, _uri, documentURL, testname);
// Should have no new instances.
LOK_ASSERT_EQUAL(kitcount, countCoolKitProcesses(kitcount));
// Check if the document contains the pasted text.
const std::string expected = "aaa bbb ccc";
const std::string selection = getAllText(socket, testname, expected);

View File

@ -100,14 +100,14 @@ public:
void setUp()
{
helpers::resetTestStartTime();
helpers::testCountHowManyCoolkits();
helpers::waitForKitPidsReady("setUp");
helpers::resetTestStartTime();
}
void tearDown()
{
helpers::resetTestStartTime();
helpers::testNoExtraCoolKitsLeft();
helpers::waitForKitPidsReady("tearDown");
helpers::resetTestStartTime();
}