wsd: test: refactor client connection management
The client connection management had nothing to do with the WopiTestServer and it was there for convenience. The issue was that it was not available to tests that do not need the custom WopiTestServer and depending on it would make them unnecessarily complicated. This adds a new intermediary class to manage client connections in tests. The reason this logic didn't move to UnitWSD or even UnitBase is simply because the client connection logic depends on the helpers namespace and other test-specific code that isn't available in COOLWSD. In short, UnitBase and UnitWSD are primarily an interface that COOLWSD and co depend on and cannot contain test-specific logic that isn't linked to coolwsd. We also move the UnitWebSocket helper class. Change-Id: I79567774164e137349dc162482529578f150353c Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>pull/5351/head
parent
c25e795bad
commit
5892bcba1e
|
@ -338,6 +338,7 @@ noinst_HEADERS = $(wsd_headers) $(shared_headers) $(kit_headers) \
|
|||
test/testlog.hpp \
|
||||
test/HttpTestServer.hpp \
|
||||
test/WOPIUploadConflictCommon.hpp \
|
||||
test/UnitWSDClient.hpp \
|
||||
test/helpers.hpp
|
||||
|
||||
GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
#include <Poco/Version.h>
|
||||
|
||||
#include "Common.hpp"
|
||||
#include <helpers.hpp>
|
||||
#include <net/WebSocketSession.hpp>
|
||||
|
||||
/// Unit test stub for a server response
|
||||
class UnitHTTPServerResponse : public Poco::Net::HTTPServerResponse
|
||||
|
@ -117,25 +115,4 @@ namespace UnitHTTP
|
|||
}
|
||||
}
|
||||
|
||||
class UnitWebSocket
|
||||
{
|
||||
std::shared_ptr<http::WebSocketSession> _httpSocket;
|
||||
|
||||
public:
|
||||
/// Get a websocket connected for a given URL
|
||||
UnitWebSocket(const std::shared_ptr<SocketPoll>& socketPoll, const std::string& documentURL)
|
||||
{
|
||||
Poco::URI uri(helpers::getTestServerURI());
|
||||
_httpSocket = helpers::connectLOKit(socketPoll, uri, documentURL, "UnitWebSocket ");
|
||||
}
|
||||
|
||||
/// Destroy the WS.
|
||||
/// Here, we can't do IO as we don't own the socket (SocketPoll does).
|
||||
/// In fact, we can't destroy it (it's referenced by SocketPoll).
|
||||
/// Instead, we can only flag for shutting down.
|
||||
~UnitWebSocket() { _httpSocket->asyncShutdown(); }
|
||||
|
||||
const std::shared_ptr<http::WebSocketSession>& getWebSocket() { return _httpSocket; }
|
||||
};
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* 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 "helpers.hpp"
|
||||
#include "testlog.hpp"
|
||||
#include "Unit.hpp"
|
||||
#include "Util.hpp"
|
||||
|
||||
#include <Poco/URI.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class UnitWebSocket final
|
||||
{
|
||||
std::shared_ptr<http::WebSocketSession> _httpSocket;
|
||||
|
||||
public:
|
||||
/// Get a websocket connected for a given URL
|
||||
UnitWebSocket(const std::shared_ptr<SocketPoll>& socketPoll, const std::string& documentURL)
|
||||
{
|
||||
Poco::URI uri(helpers::getTestServerURI());
|
||||
_httpSocket = helpers::connectLOKit(socketPoll, uri, documentURL, "UnitWebSocket ");
|
||||
}
|
||||
|
||||
/// Destroy the WS.
|
||||
/// Here, we can't do IO as we don't own the socket (SocketPoll does).
|
||||
/// In fact, we can't destroy it (it's referenced by SocketPoll).
|
||||
/// Instead, we can only flag for shutting down.
|
||||
~UnitWebSocket() { _httpSocket->asyncShutdown(); }
|
||||
|
||||
const std::shared_ptr<http::WebSocketSession>& getWebSocket() { return _httpSocket; }
|
||||
};
|
||||
|
||||
/// A WSD unit-test base class with support
|
||||
/// to manage client connections.
|
||||
class UnitWSDClient : public UnitWSD
|
||||
{
|
||||
public:
|
||||
UnitWSDClient(const std::string& name)
|
||||
: UnitWSD(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::string& getWopiSrc() const { return _wopiSrc; }
|
||||
|
||||
const std::unique_ptr<UnitWebSocket>& getWs() const { return _wsList.at(0); }
|
||||
|
||||
const std::unique_ptr<UnitWebSocket>& getWsAt(int index) { return _wsList.at(index); }
|
||||
|
||||
void deleteSocketAt(int index)
|
||||
{
|
||||
// Don't remove from the container, because the
|
||||
// indexes are how the test refers to them.
|
||||
std::unique_ptr<UnitWebSocket>& socket = _wsList.at(index);
|
||||
socket.reset();
|
||||
}
|
||||
|
||||
void initWebsocket(const std::string& wopiName)
|
||||
{
|
||||
Poco::URI wopiURL(helpers::getTestServerURI() + wopiName + "&testname=" + getTestname());
|
||||
|
||||
_wopiSrc.clear();
|
||||
Poco::URI::encode(wopiURL.toString(), ":/?", _wopiSrc);
|
||||
|
||||
// This is just a client connection that is used from the tests.
|
||||
LOG_TST("Connecting test client to COOL (#" << (_wsList.size() + 1)
|
||||
<< " connection): /cool/" << _wopiSrc << "/ws");
|
||||
|
||||
// Insert at the front.
|
||||
const auto& _ws = _wsList.emplace(
|
||||
_wsList.begin(),
|
||||
Util::make_unique<UnitWebSocket>(socketPoll(), "/cool/" + _wopiSrc + "/ws"));
|
||||
|
||||
assert((*_ws).get());
|
||||
}
|
||||
|
||||
void addWebSocket()
|
||||
{
|
||||
// This is just a client connection that is used from the tests.
|
||||
LOG_TST("Connecting test client to COOL (#" << (_wsList.size() + 1)
|
||||
<< " connection): /cool/" << _wopiSrc << "/ws");
|
||||
|
||||
// Insert at the back.
|
||||
const auto& _ws = _wsList.emplace(
|
||||
_wsList.end(),
|
||||
Util::make_unique<UnitWebSocket>(socketPoll(), "/cool/" + _wopiSrc + "/ws"));
|
||||
|
||||
assert((*_ws).get());
|
||||
}
|
||||
|
||||
private:
|
||||
/// The WOPISrc URL.
|
||||
std::string _wopiSrc;
|
||||
|
||||
/// Websockets to communicate.
|
||||
std::vector<std::unique_ptr<UnitWebSocket>> _wsList;
|
||||
};
|
||||
|
||||
/// Send a command message to WSD from a WopiTestServer on the given connection.
|
||||
#define WSD_CMD_BY_CONNECTION_INDEX(INDEX, MSG) \
|
||||
do \
|
||||
{ \
|
||||
LOG_TST("Sending from #" << INDEX << ": " << MSG); \
|
||||
helpers::sendTextFrame(getWsAt(INDEX)->getWebSocket(), MSG, getTestname()); \
|
||||
SocketPoll::wakeupWorld(); \
|
||||
} while (false)
|
||||
|
||||
/// Send a command message to WSD from a WopiTestServer on the primary connection.
|
||||
#define WSD_CMD(MSG) WSD_CMD_BY_CONNECTION_INDEX(0, MSG)
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
@ -11,8 +11,8 @@
|
|||
#include "helpers.hpp"
|
||||
#include "Log.hpp"
|
||||
#include "Unit.hpp"
|
||||
#include "UnitHTTP.hpp"
|
||||
#include "Util.hpp"
|
||||
#include "UnitWSDClient.hpp"
|
||||
|
||||
#include <Poco/JSON/Object.h>
|
||||
#include <Poco/URI.h>
|
||||
|
@ -35,7 +35,7 @@ class HTTPRequest;
|
|||
/// Furthermore, the file URI doesn't contain the
|
||||
/// real filename (in most tests), instead filenames
|
||||
/// 1 to 9 are considered special.
|
||||
class WopiTestServer : public UnitWSD
|
||||
class WopiTestServer : public UnitWSDClient
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -44,15 +44,6 @@ private:
|
|||
DocChanged = 1010
|
||||
};
|
||||
|
||||
/// The WOPISrc URL.
|
||||
std::string _wopiSrc;
|
||||
|
||||
/// The SocketPoll thread.
|
||||
std::shared_ptr<SocketPoll> _socketPoll;
|
||||
|
||||
/// Websockets to communicate.
|
||||
std::vector< std::unique_ptr<UnitWebSocket> > _wsList;
|
||||
|
||||
/// Content of the file.
|
||||
std::string _fileContent;
|
||||
|
||||
|
@ -76,18 +67,6 @@ private:
|
|||
|
||||
protected:
|
||||
|
||||
const std::string& getWopiSrc() const { return _wopiSrc; }
|
||||
|
||||
const std::unique_ptr<UnitWebSocket>& getWs() const { return _wsList.at(0); }
|
||||
|
||||
const std::unique_ptr<UnitWebSocket>& getWsAt(int index) { return _wsList.at(index); }
|
||||
|
||||
void deleteSocketAt(int index)
|
||||
{
|
||||
std::unique_ptr<UnitWebSocket>& socket = _wsList.at(index);
|
||||
socket.reset();
|
||||
}
|
||||
|
||||
const std::string& getFileContent() const { return _fileContent; }
|
||||
|
||||
/// Sets the file content to a given value and update the last file modified time
|
||||
|
@ -104,8 +83,7 @@ protected:
|
|||
}
|
||||
|
||||
WopiTestServer(const std::string& name, const std::string& filenameOrContents = "Hello, world")
|
||||
: UnitWSD(name)
|
||||
, _socketPoll(std::make_shared<SocketPoll>(name + "ServerPoll"))
|
||||
: UnitWSDClient(name)
|
||||
, _filename(DefaultFilename)
|
||||
, _countCheckFileInfo(0)
|
||||
, _countGetFile(0)
|
||||
|
@ -114,8 +92,6 @@ protected:
|
|||
{
|
||||
LOG_TST("WopiTestServer created for [" << getTestname() << ']');
|
||||
|
||||
_socketPoll->startThread();
|
||||
|
||||
// Read the document data and store as string in memory.
|
||||
const auto data = helpers::readDataFromFile(filenameOrContents);
|
||||
if (!data.empty())
|
||||
|
@ -144,45 +120,6 @@ protected:
|
|||
std::size_t getCountPutFile() const { return _countPutFile; }
|
||||
void resetCountPutFile() { _countPutFile = 0; }
|
||||
|
||||
void initWebsocket(const std::string& wopiName)
|
||||
{
|
||||
Poco::URI wopiURL(helpers::getTestServerURI() + wopiName + "&testname=" + getTestname());
|
||||
|
||||
_wopiSrc.clear();
|
||||
Poco::URI::encode(wopiURL.toString(), ":/?", _wopiSrc);
|
||||
|
||||
// This is just a client connection that is used from the tests.
|
||||
// It really has nothing to do with this fake WOPI server, exept
|
||||
// that it manages it since it is the base of WOPI tests, so
|
||||
// it's a common bit of housekeeping that all WOPI tests must do.
|
||||
LOG_TST("Connecting test client to COOL (#" << (_wsList.size() + 1)
|
||||
<< " connection): /cool/" << _wopiSrc << "/ws");
|
||||
|
||||
// Insert at the front.
|
||||
const auto& _ws = _wsList.emplace(
|
||||
_wsList.begin(),
|
||||
Util::make_unique<UnitWebSocket>(_socketPoll, "/cool/" + _wopiSrc + "/ws"));
|
||||
|
||||
assert((*_ws).get());
|
||||
}
|
||||
|
||||
void addWebSocket()
|
||||
{
|
||||
// This is just a client connection that is used from the tests.
|
||||
// It really has nothing to do with this fake WOPI server, exept
|
||||
// that it manages it since it is the base of WOPI tests, so
|
||||
// it's a common bit of housekeeping that all WOPI tests must do.
|
||||
LOG_TST("Connecting test client to COOL (#" << (_wsList.size() + 1)
|
||||
<< " connection): /cool/" << _wopiSrc << "/ws");
|
||||
|
||||
// Insert at the back.
|
||||
const auto& _ws = _wsList.emplace(
|
||||
_wsList.end(),
|
||||
Util::make_unique<UnitWebSocket>(_socketPoll, "/cool/" + _wopiSrc + "/ws"));
|
||||
|
||||
assert((*_ws).get());
|
||||
}
|
||||
|
||||
virtual void assertCheckFileInfoRequest(const Poco::Net::HTTPRequest& /*request*/)
|
||||
{
|
||||
}
|
||||
|
@ -511,16 +448,4 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
/// Send a command message to WSD from a WopiTestServer on the given connection.
|
||||
#define WSD_CMD_BY_CONNECTION_INDEX(INDEX, MSG) \
|
||||
do \
|
||||
{ \
|
||||
LOG_TST("Sending from #" << INDEX << ": " << MSG); \
|
||||
helpers::sendTextFrame(getWsAt(INDEX)->getWebSocket(), MSG, getTestname()); \
|
||||
SocketPoll::wakeupWorld(); \
|
||||
} while (false)
|
||||
|
||||
/// Send a command message to WSD from a WopiTestServer on the primary connection.
|
||||
#define WSD_CMD(MSG) WSD_CMD_BY_CONNECTION_INDEX(0, MSG)
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
Loading…
Reference in New Issue