blob: 4767c648820a43db2ba4d823ede0970e6537025b [file] [log] [blame]
/*
* Copyright (C) 2024 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <asio/executor_work_guard.hpp>
#include <asio/io_context.hpp>
#include <opendht/log.h>
#include "multiplexed_socket.h"
#include "test_runner.h"
#include "turn_cache.h"
namespace dhtnet {
namespace test {
class TurnCacheTest : public CppUnit::TestFixture
{
public:
TurnCacheTest()
{
testDir_ = std::filesystem::current_path() / "tmp_tests_turnCache";
}
~TurnCacheTest() {}
static std::string name() { return "TurnCache"; }
void setUp();
void tearDown();
std::shared_ptr<asio::io_context> ioContext;
std::shared_ptr<std::thread> ioContextRunner;
std::shared_ptr<Logger> logger = dht::log::getStdLogger();
private:
std::filesystem::path testDir_;
void testTurnResolution();
void testRefreshMultipleTimes();
CPPUNIT_TEST_SUITE(TurnCacheTest);
CPPUNIT_TEST(testTurnResolution);
CPPUNIT_TEST(testRefreshMultipleTimes);
CPPUNIT_TEST_SUITE_END();
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TurnCacheTest, TurnCacheTest::name());
void
TurnCacheTest::setUp()
{
if (!ioContext) {
ioContext = std::make_shared<asio::io_context>();
ioContextRunner = std::make_shared<std::thread>([&] {
auto work = asio::make_work_guard(*ioContext);
ioContext->run();
});
}
}
void
TurnCacheTest::tearDown()
{
ioContext->stop();
if (ioContextRunner && ioContextRunner->joinable()) {
ioContextRunner->join();
}
std::filesystem::remove_all(testDir_);
}
void
TurnCacheTest::testTurnResolution()
{
auto cachePath = testDir_ / "cache";
TurnTransportParams turnParams;
turnParams.domain = "turn.jami.net";
turnParams.realm = "ring";
turnParams.username = "ring";
turnParams.password = "ring";
auto turnCache = std::make_shared<TurnCache>("dummyAccount",
cachePath.string(),
ioContext,
logger,
turnParams,
true);
turnCache->refresh();
// Wait up to 30 seconds for the resolution of the TURN server
int timeout = 30 * 1000;
int waitTime = 0;
int delay = 25;
while (waitTime < timeout) {
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
waitTime += delay;
if (turnCache->getResolvedTurn(AF_INET) ||
turnCache->getResolvedTurn(AF_INET6)) {
logger->debug("Waited {} ms for TURN resolution", waitTime);
break;
}
}
CPPUNIT_ASSERT(turnCache->getResolvedTurn(AF_INET) ||
turnCache->getResolvedTurn(AF_INET6));
}
void
TurnCacheTest::testRefreshMultipleTimes()
{
auto cachePath = testDir_ / "cache";
bool enabled = true;
TurnTransportParams turnParams;
turnParams.domain = "turn.jami.net";
turnParams.realm = "ring";
turnParams.username = "ring";
turnParams.password = "ring";
auto turnCache = std::make_shared<TurnCache>("dummyAccount",
cachePath.string(),
ioContext,
logger,
turnParams,
enabled);
// This test is meant to be a regression test for the following issue:
// https://git.jami.net/savoirfairelinux/dhtnet/-/issues/27
// Calling refresh twice causes the TurnTransport created by the first call to
// be destroyed shortly thereafter, which seems to be enough to reliably
// trigger the bug described in the GitLab issue linked above.
turnCache->refresh();
turnCache->refresh();
}
} // namespace test
}
JAMI_TEST_RUNNER(dhtnet::test::TurnCacheTest::name())