blob: 4767c648820a43db2ba4d823ede0970e6537025b [file] [log] [blame]
François-Simon Fauteux-Chapleau25693412024-04-10 11:49:18 -04001/*
2 * Copyright (C) 2024 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include <cppunit/TestAssert.h>
19#include <cppunit/TestFixture.h>
20#include <cppunit/extensions/HelperMacros.h>
21
22#include <asio/executor_work_guard.hpp>
23#include <asio/io_context.hpp>
24#include <opendht/log.h>
25
26#include "multiplexed_socket.h"
27#include "test_runner.h"
28#include "turn_cache.h"
29
30
31namespace dhtnet {
32namespace test {
33
34class TurnCacheTest : public CppUnit::TestFixture
35{
36public:
37 TurnCacheTest()
38 {
39 testDir_ = std::filesystem::current_path() / "tmp_tests_turnCache";
40 }
41 ~TurnCacheTest() {}
42 static std::string name() { return "TurnCache"; }
43 void setUp();
44 void tearDown();
45
46 std::shared_ptr<asio::io_context> ioContext;
47 std::shared_ptr<std::thread> ioContextRunner;
48 std::shared_ptr<Logger> logger = dht::log::getStdLogger();
49
50private:
51 std::filesystem::path testDir_;
52
53 void testTurnResolution();
54 void testRefreshMultipleTimes();
55
56 CPPUNIT_TEST_SUITE(TurnCacheTest);
57 CPPUNIT_TEST(testTurnResolution);
58 CPPUNIT_TEST(testRefreshMultipleTimes);
59 CPPUNIT_TEST_SUITE_END();
60};
61
62CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TurnCacheTest, TurnCacheTest::name());
63
64void
65TurnCacheTest::setUp()
66{
67 if (!ioContext) {
68 ioContext = std::make_shared<asio::io_context>();
69 ioContextRunner = std::make_shared<std::thread>([&] {
70 auto work = asio::make_work_guard(*ioContext);
71 ioContext->run();
72 });
73 }
74}
75
76
77void
78TurnCacheTest::tearDown()
79{
80 ioContext->stop();
81 if (ioContextRunner && ioContextRunner->joinable()) {
82 ioContextRunner->join();
83 }
84 std::filesystem::remove_all(testDir_);
85}
86
87void
88TurnCacheTest::testTurnResolution()
89{
90 auto cachePath = testDir_ / "cache";
91
92 TurnTransportParams turnParams;
93 turnParams.domain = "turn.jami.net";
94 turnParams.realm = "ring";
95 turnParams.username = "ring";
96 turnParams.password = "ring";
97
98 auto turnCache = std::make_shared<TurnCache>("dummyAccount",
99 cachePath.string(),
100 ioContext,
101 logger,
102 turnParams,
103 true);
104 turnCache->refresh();
105
106 // Wait up to 30 seconds for the resolution of the TURN server
107 int timeout = 30 * 1000;
108 int waitTime = 0;
109 int delay = 25;
110 while (waitTime < timeout) {
111 std::this_thread::sleep_for(std::chrono::milliseconds(delay));
112 waitTime += delay;
113
114 if (turnCache->getResolvedTurn(AF_INET) ||
115 turnCache->getResolvedTurn(AF_INET6)) {
116 logger->debug("Waited {} ms for TURN resolution", waitTime);
117 break;
118 }
119 }
120
121 CPPUNIT_ASSERT(turnCache->getResolvedTurn(AF_INET) ||
122 turnCache->getResolvedTurn(AF_INET6));
123}
124
125void
126TurnCacheTest::testRefreshMultipleTimes()
127{
128 auto cachePath = testDir_ / "cache";
129 bool enabled = true;
130
131 TurnTransportParams turnParams;
132 turnParams.domain = "turn.jami.net";
133 turnParams.realm = "ring";
134 turnParams.username = "ring";
135 turnParams.password = "ring";
136
137 auto turnCache = std::make_shared<TurnCache>("dummyAccount",
138 cachePath.string(),
139 ioContext,
140 logger,
141 turnParams,
142 enabled);
143 // This test is meant to be a regression test for the following issue:
144 // https://git.jami.net/savoirfairelinux/dhtnet/-/issues/27
145 // Calling refresh twice causes the TurnTransport created by the first call to
146 // be destroyed shortly thereafter, which seems to be enough to reliably
147 // trigger the bug described in the GitLab issue linked above.
148 turnCache->refresh();
149 turnCache->refresh();
150}
151
152} // namespace test
153}
154
155JAMI_TEST_RUNNER(dhtnet::test::TurnCacheTest::name())