bgsave: improve unit tests.

Force background saving in the config for this test.

Use stamp files to force sequencing between Unit test and Kit.

Change-Id: Ia2c60c3dcfdad87c9c9754e8f20a3c36dbcf74d5
Signed-off-by: Michael Meeks <michael.meeks@collabora.com>
pull/8995/head
Michael Meeks 2024-05-03 16:34:57 +01:00 committed by Caolán McNamara
parent 80a6f97518
commit 7f6b59b180
4 changed files with 85 additions and 5 deletions

View File

@ -347,10 +347,18 @@ protected:
struct TileData;
/// Abstract helper methods from WSD for unit tests
class UnitWSDInterface {
public:
virtual ~UnitWSDInterface() {}
virtual std::string getJailRoot(int pid) = 0;
};
/// Derive your WSD unit test / hooks from me.
class UnitWSD : public UnitBase
{
bool _hasKitHooks;
UnitWSDInterface *_wsd;
public:
UnitWSD(const std::string& testname);
@ -410,6 +418,18 @@ public:
}
}
/// set the concrete wsd implementation
void setWSD(UnitWSDInterface *wsd)
{
_wsd = wsd;
}
/// Locate the path of a document jail by pid (or -1 for the first jail)
std::string getJailRoot(int pid = -1)
{
return _wsd ? _wsd->getJailRoot(pid) : std::string();
}
/// Process result message from kit
void processUnitResult(const StringVector &tokens);

View File

@ -14,9 +14,12 @@
#include <Unit.hpp>
#include <Util.hpp>
#include <JsonUtil.hpp>
#include <FileUtil.hpp>
#include <helpers.hpp>
#include <StringVector.hpp>
#include <WebSocketSession.hpp>
#include <wsd/COOLWSD.hpp>
#include <wsd/DocumentBroker.hpp>
#include <test/lokassert.hpp>
#include <Poco/Util/LayeredConfiguration.h>
@ -36,19 +39,35 @@ class UnitSaveTorture : public UnitWSD
{
UnitWSD::configure(config);
#if 0
// Force much faster auto-saving
config.setInt("per_document.idlesave_duration_secs", 1);
config.setInt("per_document.autosave_duration_secs", 2);
#endif
config.setBool("per_document.background_autosave", true);
}
// Force background autosave when saving the modified document
bool isAutosave() override
{
LOG_TST("isAutosave returns " << forceAutosave);
return forceAutosave;
}
std::string getJailRootPath(const std::string &name)
{
return getJailRoot() + "/tmp/" + name;
}
void createStamp(const std::string &name)
{
TST_LOG("create stamp " << name);
std::ofstream stamp(getJailRootPath(name));
stamp.close();
}
void removeStamp(const std::string &name)
{
FileUtil::removeFile(getJailRootPath(name));
TST_LOG("removed stamp " << name);
}
public:
UnitSaveTorture();
void invokeWSDTest() override;
@ -111,10 +130,14 @@ void UnitSaveTorture::saveTortureOne(
LOK_ASSERT_EQUAL(waitForModifiedStatus(name, wsSession), true);
createStamp("holdsave");
// Force a synchronous save-as-auto-save now
forceAutosave = true;
wsSession->sendMessage(std::string("save dontTerminateEdit=0 dontSaveIfUnmodified=0"));
removeStamp("holdsave");
// Check the save succeeded
message = wsSession->waitForMessage("unocommandresult:", timeout, name);
LOK_ASSERT(message.size() > 0);
@ -160,6 +183,22 @@ void UnitSaveTorture::invokeWSDTest()
// Inside the forkit & kit processes
class UnitKitSaveTorture : public UnitKit
{
void waitWhileStamp(const std::string &name)
{
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
while (FileUtil::Stat(std::string("/tmp/") + name).exists())
{
TST_LOG("wait for stamp " << name);
if (std::chrono::steady_clock::now() - start > std::chrono::seconds(10))
{
LOK_ASSERT_FAIL("Timed out while waiting for stamp file " + name + " to go");
return;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
TST_LOG("found stamp " << name);
}
public:
UnitKitSaveTorture() : UnitKit("savetorture")
{
@ -174,6 +213,9 @@ public:
virtual void postBackgroundSaveFork() override
{
std::cerr << "\n\npost background save process fork\n\n\n";
waitWhileStamp("holdsave");
// FIXME: create stamp files in file-system to avoid collision
// and to flag failure.
}

View File

@ -1076,6 +1076,7 @@ COOLWSD::COOLWSD()
COOLWSD::~COOLWSD()
{
UnitWSD::get().setWSD(nullptr);
}
#if !MOBILEAPP
@ -2257,6 +2258,7 @@ void COOLWSD::innerInitialize(Application& self)
{
throw std::runtime_error("Failed to load wsd unit test library.");
}
UnitWSD::get().setWSD(this);
// Allow UT to manipulate before using configuration values.
UnitWSD::get().configure(conf);
@ -4654,6 +4656,18 @@ int COOLWSD::getClientPortNumber()
return ClientPortNumber;
}
/// Only for unit testing ...
std::string COOLWSD::getJailRoot(int pid)
{
std::lock_guard<std::mutex> docBrokersLock(DocBrokersMutex);
for (auto &it : DocBrokers)
{
if (pid < 0 || it.second->getPid() == pid)
return it.second->getJailRoot();
}
return std::string();
}
#if !MOBILEAPP
std::vector<std::shared_ptr<DocumentBroker>> COOLWSD::getBrokersTestOnly()

View File

@ -236,7 +236,8 @@ public:
/// The Server class which is responsible for all
/// external interactions.
class COOLWSD final : public Poco::Util::ServerApplication
class COOLWSD final : public Poco::Util::ServerApplication,
public UnitWSDInterface
{
public:
COOLWSD();
@ -652,6 +653,9 @@ private:
static void appendAllowedAliasGroups(Poco::Util::LayeredConfiguration& conf, std::vector<std::string>& allowed);
private:
/// UnitWSDInterface
virtual std::string getJailRoot(int pid) override;
/// Settings passed from the command-line to override those in the config file.
std::map<std::string, std::string> _overrideSettings;