From 8a735902c044c2781bf7f0ea6718e669b5773304 Mon Sep 17 00:00:00 2001 From: Olof Kallander <31624827+olofkallander@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:01:49 +0100 Subject: [PATCH] Test framework update (#391) * UT framework improvement * doc update --- doc/api/READMEapi.md | 15 +++ logger/PacketLogger.cpp | 5 +- logger/PacketLogger.h | 2 + test/bwe/FakeAudioSource.cpp | 2 +- test/bwe/FakeVideoSource.cpp | 30 ++++- test/bwe/FakeVideoSource.h | 2 +- test/concurrency/LockFreeListTest.cpp | 9 ++ test/concurrency/MpmcMapTest.cpp | 3 + test/gtest_main.cpp | 6 +- test/gtest_main2.cpp | 6 +- test/include/mocks/TimeSourceMock.h | 2 +- test/integration/BarbellTest.cpp | 23 ++-- test/integration/ConfIntegrationTest.cpp | 3 + test/integration/FFTanalysis.cpp | 3 +- test/integration/IntegrationAudioTest.cpp | 3 + test/integration/IntegrationTest.cpp | 14 +- test/integration/emulator/FakeTcpEndpoint.cpp | 11 +- test/integration/emulator/FakeTcpEndpoint.h | 8 +- .../emulator/FakeTcpServerEndpoint.cpp | 17 ++- .../emulator/FakeTcpServerEndpoint.h | 28 ++-- test/integration/emulator/FakeUdpEndpoint.cpp | 33 +++-- test/integration/emulator/FakeUdpEndpoint.h | 4 +- test/integration/emulator/TimeTurner.cpp | 9 +- test/integration/emulator/TimeTurner.h | 5 +- test/jobmanager/JobManagerTest.cpp | 8 ++ test/load_test_main.cpp | 6 +- test/transport/AdaptiveJitterTest.cpp | 2 +- test/transport/FakeNetwork.cpp | 122 ++++++++---------- test/transport/FakeNetwork.h | 44 +++---- test/transport/IceTest.cpp | 33 +++-- test/transport/JitterTest.cpp | 8 +- utils/Time.cpp | 24 +++- utils/Time.h | 5 +- utils/Trackers.h | 9 +- 34 files changed, 311 insertions(+), 193 deletions(-) diff --git a/doc/api/READMEapi.md b/doc/api/READMEapi.md index 78342e381..6a27410ae 100644 --- a/doc/api/READMEapi.md +++ b/doc/api/READMEapi.md @@ -1048,3 +1048,18 @@ GET /ice-candidates "ufrag": "y2uBVS3RATC4Sd" } ``` + +## Data Channel notifications +SMB send messages over the data channel to all participants. The messages carrry information about which endpoint is dominant speaker at the moment. It also sends messages listing all the last-N active users in order. +This means that the dominant speaker can be derived from that list, but also that the enpoints that are in the list at the moment and which main video ssrc they are sending. This can be used by client to associate view port with the user being shown in that port. + +User media map contains the list of forwarded user streams +``` + {"type":"UserMediaMap","endpoints":[{"endpoint":"28885389-571f-4a43-8c20-d5fb225884bb", "ssrcs":[2035838989]}]} +``` + + +Dominant speaker message looks like this: +``` +{"type":"DominantSpeaker", "endpoint":"28885389-571f-4a43-8c20-d5fb225884bb"} +``` \ No newline at end of file diff --git a/logger/PacketLogger.cpp b/logger/PacketLogger.cpp index 6a50471c3..cb936744e 100644 --- a/logger/PacketLogger.cpp +++ b/logger/PacketLogger.cpp @@ -109,7 +109,10 @@ PacketLogReader::PacketLogReader(FILE* logFile) : _logFile(logFile) {} PacketLogReader::~PacketLogReader() { - ::fclose(_logFile); + if (_logFile) + { + ::fclose(_logFile); + } } bool PacketLogReader::getNext(PacketLogItem& item) diff --git a/logger/PacketLogger.h b/logger/PacketLogger.h index a87b6bde5..b28f89ef2 100644 --- a/logger/PacketLogger.h +++ b/logger/PacketLogger.h @@ -49,6 +49,8 @@ class PacketLogReader void rewind(); + bool isOpen() const { return _logFile != nullptr; } + private: FILE* _logFile; }; diff --git a/test/bwe/FakeAudioSource.cpp b/test/bwe/FakeAudioSource.cpp index b8b2cff94..b1f40948a 100644 --- a/test/bwe/FakeAudioSource.cpp +++ b/test/bwe/FakeAudioSource.cpp @@ -74,6 +74,6 @@ size_t FakeAudioSource::randomPacketSize() } } ++_counter; - return _talkSprint + randomSize(_talkSprint, 0.1); + return _talkSprint + randomSize(_talkSprint / 4, 0.75); } } // namespace fakenet diff --git a/test/bwe/FakeVideoSource.cpp b/test/bwe/FakeVideoSource.cpp index 8f1826371..ce41486ae 100644 --- a/test/bwe/FakeVideoSource.cpp +++ b/test/bwe/FakeVideoSource.cpp @@ -19,7 +19,7 @@ FakeVideoSource::FakeVideoSource(memory::PacketPoolAllocator& allocator, _frameSize(0), _fps(30), _pacing(0), - _mtu(1400), + _mtu(1250), _ssrc(ssrc), _sequenceCounter(0), _avgRate(0.0005), @@ -110,11 +110,11 @@ memory::UniquePacket FakeVideoSource::getPacket(uint64_t timestamp) bool lastInFrame = false; if (_frameSize > 0) { - _releaseTime += _counter % 2 == 0 ? 0 : _pacing; + _releaseTime += _packetsInFrame < 3 ? 0 : _pacing; } else { - _releaseTime = _frameReleaseTime; + _releaseTime += utils::Time::us * 100; lastInFrame = true; } _avgRate.update(packet->getLength() * 8, timestamp); @@ -140,8 +140,8 @@ memory::UniquePacket FakeVideoSource::getPacket(uint64_t timestamp) { setNextFrameSize(); _rtpTimestamp += 90000 / _fps; - _releaseTime = timestamp; _frameReleaseTime += utils::Time::sec / _fps; + _releaseTime = _frameReleaseTime; return getPacket(timestamp); } @@ -150,10 +150,16 @@ memory::UniquePacket FakeVideoSource::getPacket(uint64_t timestamp) void FakeVideoSource::setNextFrameSize() { + if (_bandwidthKbps < 100) + { + _frameSize = 0; + return; + } auto meanSize = _bandwidthKbps * 125 / _fps; + // key frame every 15s if (_counter % (_fps * 15) == 0) { - meanSize *= 4; + meanSize *= std::max(1u, 4 * _fps / 30); _keyFrame = true; } ++_counter; @@ -161,4 +167,18 @@ void FakeVideoSource::setNextFrameSize() _frameSize = randomSize(meanSize, 0.2); _pacing = (utils::Time::sec / _fps) * _mtu / (2 * (_frameSize + _mtu)); } + +void FakeVideoSource::setBandwidth(uint32_t kbps) +{ + _bandwidthKbps = kbps; + _fps = 30; + if (_bandwidthKbps < 400) + { + _fps = 15; + } + if (_bandwidthKbps < 200) + { + _fps = 7; + } +} } // namespace fakenet diff --git a/test/bwe/FakeVideoSource.h b/test/bwe/FakeVideoSource.h index 510094bde..b630886ca 100644 --- a/test/bwe/FakeVideoSource.h +++ b/test/bwe/FakeVideoSource.h @@ -37,7 +37,7 @@ class FakeVideoSource : public MediaSource return std::max(int64_t(0), static_cast(_releaseTime - timestamp)); } - void setBandwidth(uint32_t kbps) override { _bandwidthKbps = kbps; } + void setBandwidth(uint32_t kbps) override; uint32_t getBandwidth() const override { return _bandwidthKbps; } double getBitRate() const { return _avgRate.get() / 1000; } diff --git a/test/concurrency/LockFreeListTest.cpp b/test/concurrency/LockFreeListTest.cpp index 7dd0dbdf6..b8cc46515 100644 --- a/test/concurrency/LockFreeListTest.cpp +++ b/test/concurrency/LockFreeListTest.cpp @@ -139,15 +139,24 @@ class QueueWrapper TEST(LFList, consistencyPlenty) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif consistencyTest(8, 7 * BATCH_SIZE); } TEST(LFList, consistencyFew) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif consistencyTest(8, 128); } TEST(LFList, plainConsistencyPlenty) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif consistencyTest(8, 7 * BATCH_SIZE); } diff --git a/test/concurrency/MpmcMapTest.cpp b/test/concurrency/MpmcMapTest.cpp index 47dad6db8..8049c731a 100644 --- a/test/concurrency/MpmcMapTest.cpp +++ b/test/concurrency/MpmcMapTest.cpp @@ -253,6 +253,9 @@ TEST(MpmcMap, concurrency) TEST(MpmcMap, performance) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif using HMap = concurrency::MpmcHashmap32>; HMap hmap(4096); bool running = true; diff --git a/test/gtest_main.cpp b/test/gtest_main.cpp index 2a88eb420..53bee0cbc 100644 --- a/test/gtest_main.cpp +++ b/test/gtest_main.cpp @@ -34,7 +34,11 @@ class TestEventSink : public ::testing::TestEventListener virtual void OnTestEnd(const TestInfo& test_info) override { utils::Time::initialize(); // the time source may be deleted by now - logger::info("Test Ended %s.%s <<<", "gtest", test_info.test_case_name(), test_info.name()); + logger::info("Test Ended %s.%s (%" PRIi64 " ms) <<<", + "gtest", + test_info.test_case_name(), + test_info.name(), + test_info.result()->elapsed_time()); logger::awaitLogDrained(); } virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override {} diff --git a/test/gtest_main2.cpp b/test/gtest_main2.cpp index 8af6a4644..0764da0b6 100644 --- a/test/gtest_main2.cpp +++ b/test/gtest_main2.cpp @@ -34,7 +34,11 @@ class TestEventSink : public ::testing::TestEventListener virtual void OnTestEnd(const TestInfo& test_info) override { utils::Time::initialize(); // the time source may be deleted by now - logger::info("Test Ended %s.%s <<<", "gtest", test_info.test_case_name(), test_info.name()); + logger::info("Test Ended %s.%s (%" PRIi64 " ms) <<<", + "gtest", + test_info.test_case_name(), + test_info.name(), + test_info.result()->elapsed_time()); logger::awaitLogDrained(); } virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override {} diff --git a/test/include/mocks/TimeSourceMock.h b/test/include/mocks/TimeSourceMock.h index 4c1f70044..cbba7bcbd 100644 --- a/test/include/mocks/TimeSourceMock.h +++ b/test/include/mocks/TimeSourceMock.h @@ -8,7 +8,7 @@ namespace test struct TimeSourceMock : public utils::TimeSource { - MOCK_METHOD(uint64_t, getAbsoluteTime, (), (override)); + MOCK_METHOD(uint64_t, getAbsoluteTime, (), (const, override)); MOCK_METHOD(void, nanoSleep, (uint64_t nanoSeconds), (override)); MOCK_METHOD(std::chrono::system_clock::time_point, wallClock, (), (const, override)); MOCK_METHOD(void, advance, (uint64_t ns), (override)); diff --git a/test/integration/BarbellTest.cpp b/test/integration/BarbellTest.cpp index 682a69c7f..2f765f04b 100644 --- a/test/integration/BarbellTest.cpp +++ b/test/integration/BarbellTest.cpp @@ -86,6 +86,9 @@ Test setup: */ TEST_F(BarbellTest, packetLossViaBarbell) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif runTestInThread(expectedTestThreadCount(2), [this]() { constexpr auto PACKET_LOSS_RATE = 0.03; @@ -235,12 +238,12 @@ TEST_F(BarbellTest, packetLossViaBarbell) if (id == 0) { EXPECT_NEAR(fps, 30.0, 5.0); - EXPECT_NEAR(videoStats.numDecodedFrames, 146, 11); + EXPECT_NEAR(videoStats.numDecodedFrames, 146, 20); } else { EXPECT_NEAR(fps, 30.0, 2.0); - EXPECT_NEAR(videoStats.numDecodedFrames, 150, 11); + EXPECT_NEAR(videoStats.numDecodedFrames, 150, 20); } } } @@ -799,18 +802,18 @@ TEST_F(BarbellTest, barbellStats) EXPECT_EQ(s2["video"]["inbound"]["activeStreamCount"], 3); // Packates per second for audio (expectations for values per second we can hardcode): - EXPECT_NEAR(s1["video"]["inbound"]["packetsPerSecond"], 660, 30.0); - EXPECT_NEAR(s2["video"]["outbound"]["packetsPerSecond"], 660, 30.0); + EXPECT_NEAR(s1["video"]["inbound"]["packetsPerSecond"], 500, 30.0); + EXPECT_NEAR(s2["video"]["outbound"]["packetsPerSecond"], 500, 30.0); - EXPECT_NEAR(s1["video"]["outbound"]["packetsPerSecond"], 330, 15.0); - EXPECT_NEAR(s2["video"]["inbound"]["packetsPerSecond"], 330, 15.0); + EXPECT_NEAR(s1["video"]["outbound"]["packetsPerSecond"], 250, 15.0); + EXPECT_NEAR(s2["video"]["inbound"]["packetsPerSecond"], 250, 15.0); // Audio bitrate symmetry (expectations for values per second we can hardcode): - EXPECT_NEAR(s1["video"]["inbound"]["bitrateKbps"], 6222, 200.0); - EXPECT_NEAR(s2["video"]["outbound"]["bitrateKbps"], 6220, 200.0); + EXPECT_NEAR(s1["video"]["inbound"]["bitrateKbps"], 4500, 200.0); + EXPECT_NEAR(s2["video"]["outbound"]["bitrateKbps"], 4500, 200.0); - EXPECT_NEAR(s1["video"]["outbound"]["bitrateKbps"], 3100, 100.0); - EXPECT_NEAR(s2["video"]["inbound"]["bitrateKbps"], 3100, 100.0); + EXPECT_NEAR(s1["video"]["outbound"]["bitrateKbps"], 2235, 100.0); + EXPECT_NEAR(s2["video"]["inbound"]["bitrateKbps"], 2235, 100.0); // Packets sent / received symmetry (exact value could vary, but s1.inbound ~=~ s2.outbount): EXPECT_NE(s1["video"]["inbound"]["packets"], 0); diff --git a/test/integration/ConfIntegrationTest.cpp b/test/integration/ConfIntegrationTest.cpp index d720ab941..e58efba00 100644 --- a/test/integration/ConfIntegrationTest.cpp +++ b/test/integration/ConfIntegrationTest.cpp @@ -728,6 +728,9 @@ TEST_F(IntegrationTest, neighbours) TEST_F(IntegrationTest, dynamicNeighbours_removeNeighbours) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif runTestInThread(expectedTestThreadCount(1), [this]() { _config.readFromString(_defaultSmbConfig); diff --git a/test/integration/FFTanalysis.cpp b/test/integration/FFTanalysis.cpp index 31f0aa2b7..706d581ea 100644 --- a/test/integration/FFTanalysis.cpp +++ b/test/integration/FFTanalysis.cpp @@ -121,7 +121,8 @@ void fftProducer(const std::vector& recording, const size_t threadId, CmplxArray& spectrum) { - for (size_t cursor = fftWindowSize * threadId; cursor < size - fftWindowSize; cursor += fftWindowSize * numThreads) + for (size_t cursor = fftWindowSize * threadId; cursor + fftWindowSize < std::min(recording.size(), size); + cursor += fftWindowSize * numThreads) { CmplxArray testVector(fftWindowSize); for (size_t x = 0; x < fftWindowSize; ++x) diff --git a/test/integration/IntegrationAudioTest.cpp b/test/integration/IntegrationAudioTest.cpp index d3d4a34b3..e7f244f40 100644 --- a/test/integration/IntegrationAudioTest.cpp +++ b/test/integration/IntegrationAudioTest.cpp @@ -48,6 +48,9 @@ class IntegrationAudioTest : public IntegrationTest TEST_F(IntegrationAudioTest, longMute) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif runTestInThread( expectedTestThreadCount(1), [this]() { diff --git a/test/integration/IntegrationTest.cpp b/test/integration/IntegrationTest.cpp index a4f9463b9..74e77a4c8 100644 --- a/test/integration/IntegrationTest.cpp +++ b/test/integration/IntegrationTest.cpp @@ -54,9 +54,6 @@ IntegrationTest::~IntegrationTest() // Fake internet thread, JobManager timer thread, worker threads. void IntegrationTest::SetUp() { -#ifdef NOPERF_TEST - // GTEST_SKIP(); -#endif #if !ENABLE_LEGACY_API GTEST_SKIP(); #endif @@ -90,13 +87,18 @@ void IntegrationTest::SetUp() void IntegrationTest::TearDown() { -#ifdef NOPERF_TEST - // GTEST_SKIP(); -#endif #if !ENABLE_LEGACY_API GTEST_SKIP(); #endif + // if test ran, it will have re initialized, otherwise it is only threads started in Setup that runs. + if (!utils::Time::isDefaultTimeSource()) + { + _timeSource.waitForThreadsToSleep(_workerThreads.size() + 2, 3 * utils::Time::sec); + utils::Time::initialize(); + } + _timeSource.shutdown(); + _bridge.reset(); _clientTransportFactory.reset(); _publicTransportFactory.reset(); diff --git a/test/integration/emulator/FakeTcpEndpoint.cpp b/test/integration/emulator/FakeTcpEndpoint.cpp index 487cb4a04..7615180cf 100644 --- a/test/integration/emulator/FakeTcpEndpoint.cpp +++ b/test/integration/emulator/FakeTcpEndpoint.cpp @@ -27,7 +27,7 @@ FakeTcpEndpoint::FakeTcpEndpoint(jobmanager::JobManager& jobManager, _sendJobs(jobManager, 256 * 1024), _fakeFd(++_fdGenerator) { - while (!_network->isLocalPortFree(_localPort.setPort(_portCounter++))) + while (!_network->isLocalPortFree(_localPort.setPort(_portCounter++), fakenet::Protocol::TCPDATA)) { } } @@ -95,7 +95,11 @@ void FakeTcpEndpoint::sendStunTo(const transport::SocketAddress& target, void FakeTcpEndpoint::connect(const transport::SocketAddress& target) { - _network->addLocal(this); + if (!_network->addLocal(this)) + { + logger::error("Cannot open tcp port. IP clash", _name.c_str()); + return; + } _state = State::CONNECTING; _peerPort = target; @@ -148,8 +152,9 @@ void FakeTcpEndpoint::onReceive(fakenet::Protocol protocol, size_t length, uint64_t timestamp) { - assert(hasIp(target)); + assert(hasIp(target, protocol)); assert(protocol != fakenet::Protocol::UDP); + assert(source == _peerPort); auto packet = memory::makeUniquePacket(_networkLinkAllocator, data, length); assert(!isWeirdPacket(*packet)); _networkLink->push(serializeInbound(_networkLinkAllocator, protocol, source, data, length), timestamp); diff --git a/test/integration/emulator/FakeTcpEndpoint.h b/test/integration/emulator/FakeTcpEndpoint.h index c5f098e84..906d5aedc 100644 --- a/test/integration/emulator/FakeTcpEndpoint.h +++ b/test/integration/emulator/FakeTcpEndpoint.h @@ -73,8 +73,12 @@ class FakeTcpEndpoint : public transport::TcpEndpoint, public FakeEndpointImpl const void* data, size_t length, uint64_t timestamp) override; - bool hasIp(const transport::SocketAddress& target) override { return target == _localPort; } - + bool hasIp(const transport::SocketAddress& target, fakenet::Protocol protocol) const override + { + return target == _localPort && protocol > fakenet::Protocol::SYN_ACK; + } + bool hasIpClash(const NetworkNode& node) const override { return false; } + fakenet::Protocol getProtocol() const override { return fakenet::Protocol::TCPDATA; } void process(uint64_t timestamp) override; std::shared_ptr getDownlink() override { return _networkLink; } diff --git a/test/integration/emulator/FakeTcpServerEndpoint.cpp b/test/integration/emulator/FakeTcpServerEndpoint.cpp index 8633718b4..cc55c6f1b 100644 --- a/test/integration/emulator/FakeTcpServerEndpoint.cpp +++ b/test/integration/emulator/FakeTcpServerEndpoint.cpp @@ -29,14 +29,10 @@ FakeTcpServerEndpoint::FakeTcpServerEndpoint(jobmanager::JobManager& jobManager, _transportFactory(transportFactory), _endpointFactory(endpointFactory) { - if (!_network->isLocalPortFree(_localPort)) + if (!_network->addLocal(this)) { logger::error("TCP port already in use", _name.c_str()); } - else - { - _network->addLocal(this); - } } void FakeTcpServerEndpoint::onReceive(fakenet::Protocol protocol, @@ -46,7 +42,7 @@ void FakeTcpServerEndpoint::onReceive(fakenet::Protocol protocol, size_t length, uint64_t timestamp) { - assert(hasIp(target)); + assert(hasIp(target, protocol)); // assert(protocol != fakenet::Protocol::UDP); auto packet = memory::makeUniquePacket(_networkLinkAllocator, data, length); @@ -61,9 +57,9 @@ void FakeTcpServerEndpoint::onReceive(fakenet::Protocol protocol, } } -bool FakeTcpServerEndpoint::hasIp(const transport::SocketAddress& target) +bool FakeTcpServerEndpoint::hasIp(const transport::SocketAddress& target, const fakenet::Protocol protocol) const { - return (target == _localPort); + return (target == _localPort && protocol >= fakenet::Protocol::SYN && protocol <= fakenet::Protocol::SYN_ACK); } void FakeTcpServerEndpoint::process(uint64_t timestamp) @@ -118,7 +114,10 @@ void FakeTcpServerEndpoint::internalReceive() transport::SocketAddress(), transport::SocketAddress()); - _network->addLocal(tcpEndpoint); + if (!_network->addLocal(tcpEndpoint)) + { + logger::error("failed to accept tcp endpoint!", "FakeTcpServerEndpoint"); + } tcpEndpoint->sendSynAck(packetInfo.source); _endpoints.emplace(packetInfo.source, TcpEndpointItem{shareEndpoint, std::weak_ptr(shareEndpoint), tcpEndpoint}); diff --git a/test/integration/emulator/FakeTcpServerEndpoint.h b/test/integration/emulator/FakeTcpServerEndpoint.h index a51b2877c..285fc6aa5 100644 --- a/test/integration/emulator/FakeTcpServerEndpoint.h +++ b/test/integration/emulator/FakeTcpServerEndpoint.h @@ -26,28 +26,30 @@ class FakeTcpServerEndpoint : public transport::ServerEndpoint, public FakeEndpo FakeEndpointFactory& endpointFactory, transport::RtcePoll& epoll); - virtual const transport::SocketAddress getLocalPort() const override { return _localPort; }; - virtual void registerListener(const std::string& stunUserName, IEvents* listener) override; - virtual void unregisterListener(const std::string& stunUserName, IEvents* listener) override; - virtual bool isGood() const override { return true; } - virtual void start() override { _state = transport::Endpoint::State::CONNECTED; }; - virtual void stop(transport::ServerEndpoint::IStopEvents* event) override; - virtual const char* getName() const override { return _name.c_str(); } - virtual transport::Endpoint::State getState() const override { return _state; } - virtual void maintenance(uint64_t timestamp) override; + const transport::SocketAddress getLocalPort() const override { return _localPort; }; + void registerListener(const std::string& stunUserName, IEvents* listener) override; + void unregisterListener(const std::string& stunUserName, IEvents* listener) override; + bool isGood() const override { return true; } + void start() override { _state = transport::Endpoint::State::CONNECTED; }; + void stop(transport::ServerEndpoint::IStopEvents* event) override; + const char* getName() const override { return _name.c_str(); } + transport::Endpoint::State getState() const override { return _state; } + void maintenance(uint64_t timestamp) override; - virtual std::shared_ptr getDownlink() override { return nullptr; } + std::shared_ptr getDownlink() override { return nullptr; } private: // networkNode - virtual void onReceive(fakenet::Protocol protocol, + void onReceive(fakenet::Protocol protocol, const transport::SocketAddress& source, const transport::SocketAddress& target, const void* data, size_t length, uint64_t timestamp) override; - virtual bool hasIp(const transport::SocketAddress& target) override; - virtual void process(uint64_t timestamp) override; + bool hasIp(const transport::SocketAddress& target, fakenet::Protocol protocol) const override; + bool hasIpClash(const NetworkNode& node) const override { return node.hasIp(_localPort, fakenet::Protocol::SYN); } + fakenet::Protocol getProtocol() const override { return fakenet::Protocol::SYN; } + void process(uint64_t timestamp) override; void internalReceive(); diff --git a/test/integration/emulator/FakeUdpEndpoint.cpp b/test/integration/emulator/FakeUdpEndpoint.cpp index f801650c2..d6aa0d878 100644 --- a/test/integration/emulator/FakeUdpEndpoint.cpp +++ b/test/integration/emulator/FakeUdpEndpoint.cpp @@ -250,17 +250,21 @@ bool FakeUdpEndpoint::openPort(uint16_t port) { auto wantedAddress = _localPort; wantedAddress.setPort(port); - if (!_network->isLocalPortFree(wantedAddress)) - { - logger::error("UDP port already in use", _name.c_str()); - return false; - } + _localPort = wantedAddress; _localPort.setPort(port); - logger::info("adding %s to network", "FakeUdpEndpoint", _localPort.toString().c_str()); - _network->addLocal(this); - _state = Endpoint::State::CREATED; - return true; + + if (_network->addLocal(this)) + { + logger::info("adding %s to network", "FakeUdpEndpoint", _localPort.toString().c_str()); + _state = Endpoint::State::CREATED; + return true; + } + else + { + logger::error("UDP port already in use %s", _name.c_str(), wantedAddress.toString().c_str()); + } + return false; } bool FakeUdpEndpoint::isGood() const @@ -334,15 +338,20 @@ void FakeUdpEndpoint::onReceive(fakenet::Protocol protocol, size_t length, uint64_t timestamp) { - assert(hasIp(target)); + assert(hasIp(target, protocol)); assert(protocol == fakenet::Protocol::UDP); _networkLink->push(serializeInbound(_networkLinkAllocator, protocol, source, data, length), timestamp); } -bool FakeUdpEndpoint::hasIp(const transport::SocketAddress& target) +bool FakeUdpEndpoint::hasIp(const transport::SocketAddress& target, fakenet::Protocol protocol) const +{ + return target == _localPort && protocol == fakenet::Protocol::UDP; +} + +bool FakeUdpEndpoint::hasIpClash(const fakenet::NetworkNode& node) const { - return target == _localPort; + return node.hasIp(_localPort, fakenet::Protocol::UDP); } void FakeUdpEndpoint::process(uint64_t timestamp) diff --git a/test/integration/emulator/FakeUdpEndpoint.h b/test/integration/emulator/FakeUdpEndpoint.h index fd63a4378..6f2398557 100644 --- a/test/integration/emulator/FakeUdpEndpoint.h +++ b/test/integration/emulator/FakeUdpEndpoint.h @@ -56,7 +56,9 @@ class FakeUdpEndpoint : public transport::UdpEndpoint, public FakeEndpointImpl const void* data, size_t length, uint64_t timestamp) override; - bool hasIp(const transport::SocketAddress& target) override; + bool hasIp(const transport::SocketAddress& target, fakenet::Protocol protocol) const override; + bool hasIpClash(const fakenet::NetworkNode& node) const override; + fakenet::Protocol getProtocol() const override { return fakenet::Protocol::UDP; } void process(uint64_t timestamp) override; std::shared_ptr getDownlink() override { return _networkLink; } diff --git a/test/integration/emulator/TimeTurner.cpp b/test/integration/emulator/TimeTurner.cpp index 448c3d26c..9dfe4ad1d 100644 --- a/test/integration/emulator/TimeTurner.cpp +++ b/test/integration/emulator/TimeTurner.cpp @@ -6,7 +6,12 @@ namespace emulator { -TimeTurner::TimeTurner() : _timestamp(100), _startTime(std::chrono::system_clock::now()), _running(true), _abort(false) +TimeTurner::TimeTurner(uint64_t granularity) + : _timestamp(100), + _startTime(std::chrono::system_clock::now()), + _running(true), + _abort(false), + _granularity(granularity) { } @@ -160,7 +165,7 @@ void TimeTurner::advance() void TimeTurner::advance(uint64_t nanoSeconds) { - nanoSeconds = std::max(nanoSeconds, 2 * utils::Time::ms); + nanoSeconds = std::max(nanoSeconds, _granularity); _timestamp += nanoSeconds; for (auto& slot : _sleepers) diff --git a/test/integration/emulator/TimeTurner.h b/test/integration/emulator/TimeTurner.h index 06695896e..0473e6d4a 100644 --- a/test/integration/emulator/TimeTurner.h +++ b/test/integration/emulator/TimeTurner.h @@ -14,9 +14,9 @@ class TimeTurner : public utils::TimeSource public: static const size_t MAX_THREAD_COUNT = 60; - TimeTurner(); + explicit TimeTurner(uint64_t granularity = 2 * utils::Time::ms); - virtual uint64_t getAbsoluteTime() override { return _timestamp; } + virtual uint64_t getAbsoluteTime() const override { return _timestamp; } virtual void nanoSleep(uint64_t nanoSeconds) override; virtual std::chrono::system_clock::time_point wallClock() const override; @@ -66,5 +66,6 @@ class TimeTurner : public utils::TimeSource concurrency::CountdownEvent _sleeperCountdown; concurrency::EventSemaphore _abortSemaphore; std::atomic_bool _abort; + uint64_t _granularity; }; } // namespace emulator diff --git a/test/jobmanager/JobManagerTest.cpp b/test/jobmanager/JobManagerTest.cpp index 07e33c2db..f47c4425c 100644 --- a/test/jobmanager/JobManagerTest.cpp +++ b/test/jobmanager/JobManagerTest.cpp @@ -128,6 +128,10 @@ struct JobManagerTest : public ::testing::Test TEST_F(JobManagerTest, concurrentJobs) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif + thread writerThread1(writer, ref(context), 0, n / 2, ref(jobManager), nullptr); thread writerThread2(writer, ref(context), n / 2, n, ref(jobManager), nullptr); writerThread1.join(); @@ -149,6 +153,10 @@ TEST_F(JobManagerTest, concurrentJobs) TEST_F(JobManagerTest, serialJobs) { +#ifdef NOPERF_TEST + GTEST_SKIP(); +#endif + atomic_int32_t serialConcurrency1(0); atomic_int32_t serialConcurrency2(0); diff --git a/test/load_test_main.cpp b/test/load_test_main.cpp index 6dc4eb525..882a4c453 100644 --- a/test/load_test_main.cpp +++ b/test/load_test_main.cpp @@ -36,7 +36,11 @@ class TestEventSink : public ::testing::TestEventListener virtual void OnTestEnd(const TestInfo& test_info) override { utils::Time::initialize(); // the time source may be deleted by now - logger::info("Test Ended %s.%s <<<", "gtest", test_info.test_case_name(), test_info.name()); + logger::info("Test Ended %s.%s (%" PRIi64 " ms) <<<", + "gtest", + test_info.test_case_name(), + test_info.name(), + test_info.result()->elapsed_time()); logger::awaitLogDrained(); } virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override {} diff --git a/test/transport/AdaptiveJitterTest.cpp b/test/transport/AdaptiveJitterTest.cpp index 69160c6df..ce0b6f6ce 100644 --- a/test/transport/AdaptiveJitterTest.cpp +++ b/test/transport/AdaptiveJitterTest.cpp @@ -28,7 +28,7 @@ class TimeTicker : public utils::TimeSource public: TimeTicker() : _startTime(std::chrono::system_clock::now()), _time(utils::Time::getAbsoluteTime()) {} - uint64_t getAbsoluteTime() override { return _time; }; + uint64_t getAbsoluteTime() const override { return _time; }; void nanoSleep(uint64_t nanoSeconds) override { _time += nanoSeconds; }; diff --git a/test/transport/FakeNetwork.cpp b/test/transport/FakeNetwork.cpp index 95be6f6bd..c9986803b 100644 --- a/test/transport/FakeNetwork.cpp +++ b/test/transport/FakeNetwork.cpp @@ -44,6 +44,8 @@ const char* toString(Protocol p) return "FIN"; case Protocol::ACK: return "ACK"; + case Protocol::ANY: + return "ANY"; } return "any"; @@ -65,7 +67,7 @@ void Gateway::onReceive(Protocol protocol, const bool pushed = _packets.push(std::make_unique(protocol, data, len, source, target)); if (!pushed) { - logger::warn("gateway queue full", "Fakenetwork"); + logger::warn("gateway queue full", "FakeNetwork"); } } @@ -77,15 +79,19 @@ Internet::~Internet() } } -void Internet::addLocal(NetworkNode* node) +bool Internet::addLocal(NetworkNode* newNode) { std::lock_guard lock(_nodesMutex); - _nodes.push_back(node); -} - -void Internet::addPublic(NetworkNode* node) -{ - return addLocal(node); + for (auto& node : _nodes) + { + if (node->hasIpClash(*newNode)) + { + logger::error("IP clash adding public node", "Internet"); + return false; + } + } + _nodes.push_back(newNode); + return true; } void Internet::removeNode(NetworkNode* node) @@ -101,12 +107,25 @@ void Internet::removeNode(NetworkNode* node) } } -bool Internet::isPublicPortFree(const transport::SocketAddress& ipPort) const +bool Internet::isLocalPortFree(const transport::SocketAddress& ipPort, fakenet::Protocol protocol) const +{ + std::lock_guard lock(_nodesMutex); + for (auto& node : _nodes) + { + if (node->hasIp(ipPort, protocol)) + { + return false; + } + } + return true; +} + +bool Internet::hasIpClash(const NetworkNode& newNode) const { std::lock_guard lock(_nodesMutex); for (auto& node : _nodes) { - if (node->hasIp(ipPort)) + if (node->hasIpClash(newNode)) { return false; } @@ -128,7 +147,7 @@ void Internet::process(const uint64_t timestamp) std::lock_guard lock(_nodesMutex); for (auto node : _nodes) { - if (node->hasIp(packet->target)) + if (node->hasIp(packet->target, packet->protocol)) { NETWORK_LOG("forward %s %s -> %s bytes: %lu ", "Internet", @@ -169,7 +188,8 @@ void Internet::process(const uint64_t timestamp) Firewall::Firewall(const transport::SocketAddress& publicIp, Gateway& internet) : _portMappingsUdp(512), _portMappingsTcp(512), - _internet(internet) + _internet(internet), + _blackList(1024) { addPublicIp(publicIp); internet.addLocal(this); @@ -180,7 +200,8 @@ Firewall::Firewall(const transport::SocketAddress& publicIpv4, Gateway& internet) : _portMappingsUdp(512), _portMappingsTcp(512), - _internet(internet) + _internet(internet), + _blackList(1024) { addPublicIp(publicIpv4); addPublicIp(publicIpv6); @@ -199,16 +220,18 @@ Firewall::~Firewall() } } -void Firewall::addLocal(NetworkNode* endpoint) +bool Firewall::addLocal(NetworkNode* endpoint) { std::lock_guard lock(_nodesMutex); + for (auto& node : _endpoints) + { + if (node->hasIpClash(*endpoint)) + { + return false; + } + } _endpoints.push_back(endpoint); -} - -void Firewall::addPublic(NetworkNode* endpoint) -{ - std::lock_guard lock(_nodesMutex); - _publicEndpoints.push_back(endpoint); + return true; } void Firewall::removeNode(NetworkNode* node) @@ -222,35 +245,20 @@ void Firewall::removeNode(NetworkNode* node) return; } } - for (auto it = _publicEndpoints.begin(); it != _publicEndpoints.end(); ++it) - { - if (*it == node) - { - _publicEndpoints.erase(it); - return; - } - } } -bool Firewall::isLocalPortFree(const transport::SocketAddress& ipPort) const +bool Firewall::hasIpClash(const NetworkNode& newNode) const { std::lock_guard lock(_nodesMutex); - for (auto& node : _endpoints) - { - if (node->hasIp(ipPort)) - { - return false; - } - } - return true; + return newNode.hasIp(_publicIpv4, fakenet::Protocol::UDP) || newNode.hasIp(_publicIpv6, fakenet::Protocol::UDP); } -bool Firewall::isPublicPortFree(const transport::SocketAddress& ipPort) const +bool Firewall::isLocalPortFree(const transport::SocketAddress& ipPort, fakenet::Protocol protocol) const { std::lock_guard lock(_nodesMutex); - for (auto& node : _publicEndpoints) + for (auto& node : _endpoints) { - if (node->hasIp(ipPort)) + if (node->hasIp(ipPort, protocol)) { return false; } @@ -264,10 +272,6 @@ void Firewall::processEndpoints(const uint64_t timestamp) { node->process(timestamp); } - for (auto* node : _publicEndpoints) - { - node->process(timestamp); - } } void Firewall::dispatchNAT(const Packet& packet, const uint64_t timestamp) @@ -278,7 +282,7 @@ void Firewall::dispatchNAT(const Packet& packet, const uint64_t timestamp) { for (auto endpoint : _endpoints) { - if (endpoint->hasIp(portPair->lanPort)) + if (endpoint->hasIp(portPair->lanPort, packet.protocol)) { NETWORK_LOG("NAT %s, %s -> %s -> %s", "Firewall", @@ -302,7 +306,7 @@ bool Firewall::dispatchLocally(const Packet& packet, const uint64_t timestamp) { for (auto ep : _endpoints) { - if (ep->hasIp(packet.target)) + if (ep->hasIp(packet.target, packet.protocol)) { NETWORK_LOG("local %s -> %s", "Firewall", @@ -330,7 +334,7 @@ void Firewall::process(const uint64_t timestamp) continue; } - if (hasIp(packet->target)) + if (hasIp(packet->target, packet->protocol)) { dispatchNAT(*packet, timestamp); continue; @@ -352,26 +356,10 @@ void Firewall::process(const uint64_t timestamp) } packet->source = acquirePortMapping(packet->protocol, packet->source); - dispatchPublicly(*packet, timestamp); + _internet.onReceive(packet->protocol, packet->source, packet->target, packet->data, packet->length, timestamp); } } -void Firewall::dispatchPublicly(const Packet& packet, const uint64_t timestamp) -{ - assert(packet.source.getFamily() == packet.target.getFamily()); - for (auto publicEp : _publicEndpoints) - { - if (publicEp->hasIp(packet.target)) - { - NETWORK_LOG("dmz %s -> %s", "firewall", packet.source.toString().c_str(), packet.target.toString().c_str()); - publicEp->onReceive(packet.protocol, packet.source, packet.target, packet.data, packet.length, timestamp); - return; - } - } - - _internet.onReceive(packet.protocol, packet.source, packet.target, packet.data, packet.length, timestamp); -} - transport::SocketAddress Firewall::acquirePortMapping(const Protocol protocol, const transport::SocketAddress& source) { auto& portMap = (protocol == Protocol::UDP ? _portMappingsUdp : _portMappingsTcp); @@ -563,11 +551,7 @@ std::map> getMapOfInternet(std::shared const auto downlink = node->getDownlink(); internetMap.emplace(downlink->getName(), downlink); } - for (const auto& node : internet->getPublicNodes()) - { - const auto downlink = node->getDownlink(); - internetMap.emplace(downlink->getName(), downlink); - } + return internetMap; } } // namespace fakenet diff --git a/test/transport/FakeNetwork.h b/test/transport/FakeNetwork.h index dbab10b1b..de2911382 100644 --- a/test/transport/FakeNetwork.h +++ b/test/transport/FakeNetwork.h @@ -22,7 +22,8 @@ enum Protocol : uint8_t SYN_ACK, FIN, ACK, - TCPDATA + TCPDATA, + ANY }; const char* toString(Protocol p); @@ -38,8 +39,10 @@ class NetworkNode const void* data, size_t length, uint64_t timestamp) = 0; - virtual bool hasIp(const transport::SocketAddress& target) = 0; + virtual bool hasIp(const transport::SocketAddress& target, fakenet::Protocol) const = 0; + virtual bool hasIpClash(const NetworkNode& node) const = 0; virtual void process(uint64_t timestamp){}; + virtual fakenet::Protocol getProtocol() const = 0; virtual std::shared_ptr getDownlink() { return nullptr; } }; @@ -72,15 +75,12 @@ class Gateway : public NetworkNode Gateway(); ~Gateway(); - virtual void addLocal(NetworkNode* node) = 0; - virtual void addPublic(NetworkNode* endpoint) = 0; + virtual bool addLocal(NetworkNode* node) = 0; virtual std::vector& getLocalNodes() = 0; - virtual std::vector& getPublicNodes() = 0; virtual void removeNode(NetworkNode* node) = 0; - virtual bool isLocalPortFree(const transport::SocketAddress&) const = 0; - virtual bool isPublicPortFree(const transport::SocketAddress&) const = 0; + virtual bool isLocalPortFree(const transport::SocketAddress&, fakenet::Protocol) const = 0; void onReceive(Protocol protocol, const transport::SocketAddress& source, @@ -97,25 +97,24 @@ class Internet : public Gateway { public: ~Internet(); - bool hasIp(const transport::SocketAddress& target) override { return true; } + bool hasIp(const transport::SocketAddress& target, fakenet::Protocol protocol) const override { return true; } + bool hasIpClash(const NetworkNode& node) const override; + fakenet::Protocol getProtocol() const override { return fakenet::Protocol::ANY; } - void addLocal(NetworkNode* node) override; - void addPublic(NetworkNode* node) override; + bool addLocal(NetworkNode* node) override; void removeNode(NetworkNode* node) override; - bool isLocalPortFree(const transport::SocketAddress& ipPort) const override { return isPublicPortFree(ipPort); } - bool isPublicPortFree(const transport::SocketAddress& ipPort) const override; + bool isLocalPortFree(const transport::SocketAddress& ipPort, fakenet::Protocol protocol) const override; void process(uint64_t timestamp) override; std::vector& getLocalNodes() override { return _nodes; }; - std::vector& getPublicNodes() override { return _nodes; }; private: mutable std::mutex _nodesMutex; std::vector _nodes; }; -// private nextwork is 172.x.x.x and fe80:.... +// private network is 172.x.x.x and fe80:.... class Firewall : public Gateway { public: @@ -123,20 +122,21 @@ class Firewall : public Gateway Firewall(const transport::SocketAddress& publicIpv4, const transport::SocketAddress& publicIpv6, Gateway& internet); virtual ~Firewall(); - void addLocal(NetworkNode* endpoint) override; - void addPublic(NetworkNode* endpoint) override; + bool addLocal(NetworkNode* endpoint) override; void removeNode(NetworkNode* node) override; void addPublicIp(const transport::SocketAddress& addr); - bool isLocalPortFree(const transport::SocketAddress& ipPort) const override; - bool isPublicPortFree(const transport::SocketAddress& ipPort) const override; + bool isLocalPortFree(const transport::SocketAddress& ipPort, fakenet::Protocol protocol) const override; - bool hasIp(const transport::SocketAddress& port) override + fakenet::Protocol getProtocol() const override { return fakenet::Protocol::ANY; } + bool hasIp(const transport::SocketAddress& port, fakenet::Protocol) const override { return _publicIpv4.equalsIp(port) || _publicIpv6.equalsIp(port); } + bool hasIpClash(const NetworkNode& node) const override; + transport::SocketAddress getPublicIp() const { return _publicIpv4; } transport::SocketAddress getPublicIpv6() const { return _publicIpv6; } void process(uint64_t timestamp) override; @@ -145,13 +145,11 @@ class Firewall : public Gateway void removePortMapping(Protocol protocol, transport::SocketAddress& lanAddress); std::vector& getLocalNodes() override { return _endpoints; }; - std::vector& getPublicNodes() override { return _publicEndpoints; }; void block(const transport::SocketAddress& source, const transport::SocketAddress& destination); void unblock(const transport::SocketAddress& source, const transport::SocketAddress& destination); private: - void dispatchPublicly(const Packet& packet, uint64_t timestamp); void processEndpoints(const uint64_t timestamp); void dispatchNAT(const Packet& packet, const uint64_t timestamp); bool dispatchLocally(const Packet& packet, const uint64_t timestamp); @@ -172,11 +170,11 @@ class Firewall : public Gateway PortMap _portMappingsUdp; PortMap _portMappingsTcp; std::vector _endpoints; - std::vector _publicEndpoints; + Gateway& _internet; int _portCount = 1000; mutable std::mutex _nodesMutex; - memory::Map, bool, 1024> _blackList; + concurrency::MpmcHashmap32, bool> _blackList; }; class InternetRunner diff --git a/test/transport/IceTest.cpp b/test/transport/IceTest.cpp index 40c52f1e9..58f1bf31c 100644 --- a/test/transport/IceTest.cpp +++ b/test/transport/IceTest.cpp @@ -581,7 +581,12 @@ class FakeEndpoint : public ice::IceEndpoint, fakenet::NetworkNode void cancelStunTransaction(ice::Int96 transactionId) override {} transport::SocketAddress getLocalPort() const override { return _address; } - bool hasIp(const transport::SocketAddress& target) override { return target == _address; } + bool hasIp(const transport::SocketAddress& target, fakenet::Protocol protocol) const override + { + return target == _address && protocol == fakenet::Protocol::UDP; + } + bool hasIpClash(const NetworkNode& node) const override { return node.hasIp(_address, fakenet::Protocol::UDP); } + fakenet::Protocol getProtocol() const override { return fakenet::Protocol::UDP; } void attach(std::unique_ptr& session) { @@ -639,7 +644,6 @@ void FakeEndpoint::onReceive(fakenet::Protocol protocol, if (_address.equalsIp(target)) { - logger::debug("received from %s -> %s", "FakeEndpoint", source.toString().c_str(), target.toString().c_str()); _session->onStunPacketReceived(this, source, data, length, timestamp); } else if (_gateway) @@ -678,7 +682,7 @@ class FakeStunServer : public fakenet::NetworkNode _internet(internet) { assert(!port.empty()); - internet.addPublic(this); + internet.addLocal(this); } void onReceive(fakenet::Protocol protocol, const transport::SocketAddress& source, @@ -703,7 +707,12 @@ class FakeStunServer : public fakenet::NetworkNode } } } - bool hasIp(const transport::SocketAddress& target) override { return target == _address; } + bool hasIp(const transport::SocketAddress& target, fakenet::Protocol protocol) const override + { + return target == _address && protocol == fakenet::Protocol::UDP; + } + bool hasIpClash(const NetworkNode& node) const override { return node.hasIp(_address, fakenet::Protocol::UDP); } + fakenet::Protocol getProtocol() const override { return fakenet::Protocol::UDP; } transport::SocketAddress getIp() const { return _address; } @@ -959,13 +968,13 @@ TEST_F(IceTest, iceprobes2) auto pair1 = sessions[0]->getSelectedPair(); auto pair2 = sessions[1]->getSelectedPair(); - EXPECT_TRUE(firewall1.hasIp(pair1.first.address)); + EXPECT_TRUE(firewall1.hasIp(pair1.first.address, fakenet::Protocol::UDP)); EXPECT_TRUE(pair1.first.baseAddress == endpoint1b._address); EXPECT_TRUE(pair2.first.address == pair1.second.address); EXPECT_TRUE(pair1.first.address == pair2.second.address); EXPECT_TRUE(pair2.first.baseAddress == endpoint2._address); - EXPECT_TRUE(firewall2.hasIp(pair2.first.address)); + EXPECT_TRUE(firewall2.hasIp(pair2.first.address, fakenet::Protocol::UDP)); } TEST_F(IceTest, timerNoCandidates) @@ -1143,7 +1152,7 @@ TEST_F(IceTest, fixedportmap) auto pair1 = sessions[0]->getSelectedPair(); auto pair2 = sessions[1]->getSelectedPair(); - EXPECT_TRUE(firewall1.hasIp(pair1.first.address)); + EXPECT_TRUE(firewall1.hasIp(pair1.first.address, fakenet::Protocol::UDP)); EXPECT_TRUE(pair2.first.address == pair1.second.address); EXPECT_TRUE(pair1.first.address == pair2.second.address); @@ -1219,7 +1228,7 @@ TEST_F(IceTest, fixedportmapNogathering) auto pair1 = sessions[0]->getSelectedPair(); auto pair2 = sessions[1]->getSelectedPair(); - EXPECT_TRUE(firewall1.hasIp(pair1.first.address)); + EXPECT_TRUE(firewall1.hasIp(pair1.first.address, fakenet::Protocol::UDP)); EXPECT_TRUE(pair2.first.address == pair1.second.address); EXPECT_TRUE(pair1.first.address == pair2.second.address); @@ -1256,7 +1265,7 @@ TEST_F(IceTest, icev6) auto pair1 = sessions[0]->getSelectedPair(); auto pair2 = sessions[1]->getSelectedPair(); - EXPECT_TRUE(firewall1.hasIp(pair1.first.address)); + EXPECT_TRUE(firewall1.hasIp(pair1.first.address, fakenet::Protocol::UDP)); EXPECT_TRUE(pair2.first.address == pair1.second.address); EXPECT_TRUE(pair1.first.address == pair2.second.address); @@ -1292,8 +1301,8 @@ TEST_F(IceTest, icev6sameFw) auto pair1 = sessions[0]->getSelectedPair(); auto pair2 = sessions[1]->getSelectedPair(); - EXPECT_TRUE(endpoint1.hasIp(pair1.first.address)); - EXPECT_TRUE(endpoint2.hasIp(pair2.first.address)); + EXPECT_TRUE(endpoint1.hasIp(pair1.first.address, fakenet::Protocol::UDP)); + EXPECT_TRUE(endpoint2.hasIp(pair2.first.address, fakenet::Protocol::UDP)); EXPECT_TRUE(pair2.first.address == pair1.second.address); EXPECT_TRUE(pair1.first.address == pair2.second.address); } @@ -1336,7 +1345,7 @@ TEST_F(IceTest, icev6v4Mix) auto pair1 = sessions[0]->getSelectedPair(); auto pair2 = sessions[1]->getSelectedPair(); - EXPECT_TRUE(firewall1.hasIp(pair1.first.address)); + EXPECT_TRUE(firewall1.hasIp(pair1.first.address, fakenet::Protocol::UDP)); EXPECT_TRUE(pair2.first.address == pair1.second.address); EXPECT_TRUE(pair1.first.address == pair2.second.address); diff --git a/test/transport/JitterTest.cpp b/test/transport/JitterTest.cpp index 527262562..417e28348 100644 --- a/test/transport/JitterTest.cpp +++ b/test/transport/JitterTest.cpp @@ -400,8 +400,8 @@ TEST(JitterTest, clockSkewRxSlower) jitt.getMaxJitter()); logger::info("above %d, below %d, 95p %d", "", countAbove, countBelow, below95); - EXPECT_GE(countAbove, 700); - EXPECT_GE(countBelow, 700); + EXPECT_GE(countAbove, 690); + EXPECT_GE(countBelow, 690); EXPECT_GE(below95, 1440); EXPECT_NEAR(jitt.getJitter(), 5.5, 1.5); } @@ -745,8 +745,8 @@ TEST(JitterTest, adaptUp30) jitt.getMaxJitter()); logger::info("above %d, below %d, 95p %d", "", countAbove, countBelow, below95); - EXPECT_GE(countAbove, 600); - EXPECT_GE(countBelow, 600); + EXPECT_GE(countAbove, 580); + EXPECT_GE(countBelow, 580); EXPECT_GE(below95, 1150); EXPECT_NEAR(jitt.getJitter(), 12, 2.5); } diff --git a/utils/Time.cpp b/utils/Time.cpp index 48afb4247..5420e3a6a 100644 --- a/utils/Time.cpp +++ b/utils/Time.cpp @@ -29,9 +29,9 @@ utils::TimeSource* _timeSource = nullptr; class TimeSourceImpl final : public utils::TimeSource { public: - uint64_t getAbsoluteTime() override { return rawAbsoluteTime(); } + uint64_t getAbsoluteTime() const override { return rawAbsoluteTime(); } - uint64_t getApproximateTime() override + uint64_t getApproximateTime() const override { #ifdef __APPLE__ assert(machTimeBase.denom); @@ -41,10 +41,19 @@ class TimeSourceImpl final : public utils::TimeSource #endif } - void nanoSleep(uint64_t ns) override { rawNanoSleep(ns); } - void advance(uint64_t ns) override { rawNanoSleep(ns); } + void nanoSleep(uint64_t ns) override + { + rawNanoSleep(ns); + } + void advance(uint64_t ns) override + { + rawNanoSleep(ns); + } - std::chrono::system_clock::time_point wallClock() const override { return std::chrono::system_clock::now(); } + std::chrono::system_clock::time_point wallClock() const override + { + return std::chrono::system_clock::now(); + } }; TimeSourceImpl _defaultTimeSource; @@ -53,6 +62,11 @@ void initialize() initialize(_defaultTimeSource); } +bool isDefaultTimeSource() +{ + return _timeSource == &_defaultTimeSource; +} + void formatTime(const TimeSource& timeSource, char out[32]) { const std::time_t currentTime = std::chrono::system_clock::to_time_t(timeSource.wallClock()); diff --git a/utils/Time.h b/utils/Time.h index ceeeb2357..8f55ad04d 100644 --- a/utils/Time.h +++ b/utils/Time.h @@ -13,8 +13,8 @@ class TimeSource public: virtual ~TimeSource() = default; - virtual uint64_t getAbsoluteTime() = 0; - virtual uint64_t getApproximateTime() { return getAbsoluteTime(); }; + virtual uint64_t getAbsoluteTime() const = 0; + virtual uint64_t getApproximateTime() const { return getAbsoluteTime(); }; virtual void nanoSleep(uint64_t nanoSeconds) = 0; @@ -27,6 +27,7 @@ namespace Time void initialize(); void initialize(TimeSource& timeSource); +bool isDefaultTimeSource(); /** * Returns absolute time since some machine specific point in time in nanoseconds. diff --git a/utils/Trackers.h b/utils/Trackers.h index 0ba10d8b6..e13baa718 100644 --- a/utils/Trackers.h +++ b/utils/Trackers.h @@ -123,10 +123,11 @@ class RateTracker } duration = newDuration; totalSize += bucket.size; - if (duration == 0) - { - continue; - } + } + + if (duration < interval / 4) + { + return 0; } return totalSize / static_cast(std::max(int64_t(1), duration));