2022-11-07 19:27:12 -06:00
|
|
|
/* -*- 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"
|
2022-11-15 17:28:42 -06:00
|
|
|
#include "lokassert.hpp"
|
2022-11-07 19:27:12 -06:00
|
|
|
#include "testlog.hpp"
|
|
|
|
#include "Unit.hpp"
|
|
|
|
#include "Util.hpp"
|
|
|
|
|
|
|
|
#include <Poco/URI.h>
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2022-11-08 07:29:08 -06:00
|
|
|
/// Send a command message to WSD from a UnitWSDClient instance on the given connection.
|
|
|
|
#define WSD_CMD_BY_CONNECTION_INDEX(INDEX, MSG) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
LOG_TST("Sending from #" << INDEX << ": " << MSG); \
|
2022-11-15 17:28:42 -06:00
|
|
|
sendCommand(INDEX, MSG); \
|
2022-11-08 07:29:08 -06:00
|
|
|
} while (false)
|
|
|
|
|
|
|
|
/// Send a command message to WSD from a UnitWSDClient instance on the primary connection.
|
|
|
|
#define WSD_CMD(MSG) WSD_CMD_BY_CONNECTION_INDEX(0, MSG)
|
|
|
|
|
|
|
|
/// A WebSocketSession wrapper to help with testing.
|
2022-11-07 19:27:12 -06:00
|
|
|
class UnitWebSocket final
|
|
|
|
{
|
|
|
|
std::shared_ptr<http::WebSocketSession> _httpSocket;
|
|
|
|
|
|
|
|
public:
|
2022-11-08 07:29:08 -06:00
|
|
|
/// Get a websocket connected for a given URL.
|
|
|
|
UnitWebSocket(const std::shared_ptr<SocketPoll>& socketPoll, const std::string& documentURL,
|
|
|
|
const std::string& testname = "UnitWebSocket ")
|
2022-11-07 19:27:12 -06:00
|
|
|
{
|
|
|
|
Poco::URI uri(helpers::getTestServerURI());
|
2022-11-08 07:29:08 -06:00
|
|
|
_httpSocket = helpers::connectLOKit(socketPoll, uri, documentURL, testname);
|
2022-11-07 19:27:12 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2022-11-08 07:29:08 -06:00
|
|
|
/// This cannot be in UnitWSD or UnitBase because
|
|
|
|
/// we use test code that isn't availabe in COOLWSD.
|
2022-11-07 19:27:12 -06:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-05-31 05:42:40 -05:00
|
|
|
std::string initWebsocket(const std::string& wopiName)
|
2022-11-07 19:27:12 -06:00
|
|
|
{
|
2023-05-31 05:42:40 -05:00
|
|
|
const Poco::URI wopiURL(helpers::getTestServerURI() + wopiName +
|
|
|
|
"&testname=" + getTestname());
|
2022-11-07 19:27:12 -06:00
|
|
|
|
2023-05-31 05:42:40 -05:00
|
|
|
_wopiSrc = Util::encodeURIComponent(wopiURL.toString());
|
2022-11-07 19:27:12 -06:00
|
|
|
|
|
|
|
// 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(
|
2023-08-01 06:21:20 -05:00
|
|
|
_wsList.begin(), std::make_unique<UnitWebSocket>(
|
2022-11-08 07:29:08 -06:00
|
|
|
socketPoll(), "/cool/" + _wopiSrc + "/ws", getTestname()));
|
2022-11-07 19:27:12 -06:00
|
|
|
|
|
|
|
assert((*_ws).get());
|
2023-05-31 05:42:40 -05:00
|
|
|
|
|
|
|
return _wopiSrc;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string addWebSocket(const std::string& wopiName)
|
|
|
|
{
|
|
|
|
const Poco::URI wopiURL(helpers::getTestServerURI() + wopiName +
|
|
|
|
"&testname=" + getTestname());
|
|
|
|
|
|
|
|
std::string wopiSrc = Util::encodeURIComponent(wopiURL.toString());
|
|
|
|
|
|
|
|
// 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(
|
2023-08-01 06:21:20 -05:00
|
|
|
_wsList.end(), std::make_unique<UnitWebSocket>(socketPoll(), "/cool/" + wopiSrc + "/ws",
|
|
|
|
getTestname()));
|
2023-05-31 05:42:40 -05:00
|
|
|
assert((*_ws).get());
|
|
|
|
|
|
|
|
return wopiSrc;
|
2022-11-07 19:27:12 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
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(
|
2023-08-01 06:21:20 -05:00
|
|
|
_wsList.end(), std::make_unique<UnitWebSocket>(
|
2022-11-08 07:29:08 -06:00
|
|
|
socketPoll(), "/cool/" + _wopiSrc + "/ws", getTestname()));
|
2022-11-07 19:27:12 -06:00
|
|
|
|
|
|
|
assert((*_ws).get());
|
|
|
|
}
|
|
|
|
|
2022-11-26 07:27:07 -06:00
|
|
|
void endTest(const std::string& reason) override
|
|
|
|
{
|
|
|
|
LOG_TST("Ending test by disconnecting " << _wsList.size() << " connection(s): " << reason);
|
|
|
|
_wsList.clear();
|
|
|
|
UnitWSD::endTest(reason);
|
|
|
|
}
|
|
|
|
|
2022-11-15 17:28:42 -06:00
|
|
|
/// Send a command to WSD.
|
|
|
|
void sendCommand(int index, const std::string& msg)
|
|
|
|
{
|
2022-12-10 10:28:29 -06:00
|
|
|
LOK_ASSERT_SILENT(index >= 0 && static_cast<std::size_t>(index) < _wsList.size());
|
2022-11-15 17:28:42 -06:00
|
|
|
helpers::sendTextFrame(getWsAt(index)->getWebSocket(), msg, getTestname());
|
|
|
|
SocketPoll::wakeupWorld();
|
|
|
|
}
|
|
|
|
|
2022-11-12 17:33:19 -06:00
|
|
|
/// Connect to a local test document (not a fake wopi URL), without loading it.
|
|
|
|
/// Returns the document URL to use for loading.
|
|
|
|
std::string connectToLocalDocument(const std::string& docFilename)
|
|
|
|
{
|
|
|
|
std::string documentPath, documentURL;
|
|
|
|
helpers::getDocumentPathAndURL(docFilename, documentPath, documentURL, getTestname());
|
|
|
|
|
|
|
|
LOG_TST("Connecting to local document [" << docFilename << "] with URL: " << documentURL);
|
|
|
|
_wsList.emplace_back(
|
2023-08-01 06:21:20 -05:00
|
|
|
std::make_unique<UnitWebSocket>(socketPoll(), documentURL, getTestname()));
|
2022-11-12 17:33:19 -06:00
|
|
|
|
|
|
|
return documentURL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Connect and load a local test document (not a fake wopi document).
|
|
|
|
void connectAndLoadLocalDocument(const std::string& docFilename)
|
|
|
|
{
|
|
|
|
const std::string documentURL = connectToLocalDocument(docFilename);
|
|
|
|
|
|
|
|
LOG_TST("Loading local document [" << docFilename << "] with URL: " << documentURL);
|
|
|
|
WSD_CMD("load url=" + documentURL);
|
|
|
|
}
|
|
|
|
|
2022-11-07 19:27:12 -06:00
|
|
|
private:
|
|
|
|
/// The WOPISrc URL.
|
|
|
|
std::string _wopiSrc;
|
|
|
|
|
|
|
|
/// Websockets to communicate.
|
|
|
|
std::vector<std::unique_ptr<UnitWebSocket>> _wsList;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|