aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/testing
diff options
context:
space:
mode:
authoralexv-smirnov <alex@ydb.tech>2023-03-10 15:37:02 +0300
committeralexv-smirnov <alex@ydb.tech>2023-03-10 15:37:02 +0300
commit394219e982f65dd1ab4e4511051f4c97011c8712 (patch)
treed6a9c3984d7bac6e9564fa451bd28d6edcc063e3 /library/cpp/testing
parent7d576663c816bfaa02dcce5b6dfb8cfc3c7dec67 (diff)
downloadydb-394219e982f65dd1ab4e4511051f4c97011c8712.tar.gz
Add GetPort(port) support to maintain compatibility with unittest TPortManager
Singleton did not allow reinitialisation, so in existing tests this line https://a.yandex-team.ru/arcadia/library/cpp/testing/common/ut/network_ut.cpp?rev=rXXXXXX#L45 did not have any effect. The tests worked just because in both tests the env var PORT_SYNC_PATH was the same and its changes did not affect the tests anyway. As we need to change the env var NO_RANDOM_PORTS to run GetPort( port ) test, I had to make a reinitialisation method, which is now being called from inside the constructor, causing its double invocation during the tests. I could not find a better solution for Singleton(
Diffstat (limited to 'library/cpp/testing')
-rw-r--r--library/cpp/testing/common/network.cpp36
-rw-r--r--library/cpp/testing/common/network.h7
-rw-r--r--library/cpp/testing/common/ut/network_ut.cpp54
3 files changed, 89 insertions, 8 deletions
diff --git a/library/cpp/testing/common/network.cpp b/library/cpp/testing/common/network.cpp
index 230c50ee6d..7a7ff2544c 100644
--- a/library/cpp/testing/common/network.cpp
+++ b/library/cpp/testing/common/network.cpp
@@ -96,27 +96,32 @@ namespace {
static constexpr size_t Retries = 20;
public:
TPortManager()
- : SyncDir_(GetEnv("PORT_SYNC_PATH"))
- , Ranges_(GetPortRanges())
- , TotalCount_(0)
{
+ InitFromEnv();
+ }
+
+ void InitFromEnv() {
+ SyncDir_ = TFsPath(GetEnv("PORT_SYNC_PATH"));
if (!SyncDir_.IsDefined()) {
- SyncDir_ = TFsPath(GetSystemTempDir()) / "yandex_port_locks";
+ SyncDir_ = TFsPath(GetSystemTempDir()) / "testing_port_locks";
}
Y_VERIFY(SyncDir_.IsDefined());
NFs::MakeDirectoryRecursive(SyncDir_);
+ Ranges_ = GetPortRanges();
+ TotalCount_ = 0;
for (auto [left, right] : Ranges_) {
TotalCount_ += right - left;
}
Y_VERIFY(0 != TotalCount_);
+
+ DisableRandomPorts_ = !GetEnv("NO_RANDOM_PORTS").empty();
}
NTesting::TPortHolder GetFreePort() const {
ui16 salt = RandomNumber<ui16>();
for (ui16 attempt = 0; attempt < TotalCount_; ++attempt) {
ui16 probe = (salt + attempt) % TotalCount_;
-
for (auto [left, right] : Ranges_) {
if (probe >= right - left)
probe -= right - left;
@@ -165,6 +170,17 @@ namespace {
Y_FAIL("Cannot get range of %zu ports!", count);
}
+ NTesting::TPortHolder GetPort(ui16 port) const {
+ if (port && DisableRandomPorts_) {
+ auto ackport = TryAcquirePort(port);
+ if (ackport) {
+ return NTesting::TPortHolder{std::move(ackport)};
+ }
+ Y_FAIL("Cannot acquire port %hu!", port);
+ }
+ return GetFreePort();
+ }
+
private:
THolder<NTesting::IPort> TryAcquirePort(ui16 port) const {
auto lock = MakeHolder<TFileLock>(TString(SyncDir_ / ::ToString(port)));
@@ -178,7 +194,7 @@ namespace {
TSockAddrInet6 addr("::", port);
if (sock.Bind(&addr) != 0) {
lock->Release();
- Y_VERIFY(EADDRINUSE == LastSystemError(), "unexpected error: %d", LastSystemError());
+ Y_VERIFY(EADDRINUSE == LastSystemError(), "unexpected error: %d, port: %d", LastSystemError(), port);
return nullptr;
}
return MakeHolder<TPortGuard>(port, std::move(lock));
@@ -188,15 +204,23 @@ namespace {
TFsPath SyncDir_;
TVector<std::pair<ui16, ui16>> Ranges_;
size_t TotalCount_;
+ bool DisableRandomPorts_;
};
}
namespace NTesting {
+ void InitPortManagerFromEnv() {
+ Singleton<TPortManager>()->InitFromEnv();
+ }
+
TPortHolder GetFreePort() {
return Singleton<TPortManager>()->GetFreePort();
}
namespace NLegacy {
+ TPortHolder GetPort( ui16 port ) {
+ return Singleton<TPortManager>()->GetPort(port);
+ }
TVector<TPortHolder> GetFreePortsRange(size_t count) {
return Singleton<TPortManager>()->GetFreePortsRange(count);
}
diff --git a/library/cpp/testing/common/network.h b/library/cpp/testing/common/network.h
index eb4d32f3a1..4107145a7c 100644
--- a/library/cpp/testing/common/network.h
+++ b/library/cpp/testing/common/network.h
@@ -33,11 +33,16 @@ namespace NTesting {
[[nodiscard]] TPortHolder GetFreePort();
namespace NLegacy {
- // Do not use this method, it needs only for TPortManager from unittests.
+ // Do not use these methods made for Unittest TPortManager backward compatibility.
// Returns continuous sequence of the specified number of ports.
[[nodiscard]] TVector<TPortHolder> GetFreePortsRange(size_t count);
+ //@brief Returns port from parameter if NO_RANDOM_PORTS env var is set, otherwise first free port
+ [[nodiscard]] TPortHolder GetPort(ui16 port);
}
+ //@brief Reinitialize singleton from environment vars for tests
+ void InitPortManagerFromEnv();
+
//@brief helper class for inheritance
struct TFreePortOwner {
TFreePortOwner() : Port_(GetFreePort()) {}
diff --git a/library/cpp/testing/common/ut/network_ut.cpp b/library/cpp/testing/common/ut/network_ut.cpp
index 6a40775fd9..2016e26b09 100644
--- a/library/cpp/testing/common/ut/network_ut.cpp
+++ b/library/cpp/testing/common/ut/network_ut.cpp
@@ -15,7 +15,7 @@ static TTempDir TmpDir;
TEST(NetworkTest, FreePort) {
NTesting::TScopedEnvironment envGuard("PORT_SYNC_PATH", TmpDir.Name());
-
+ NTesting::InitPortManagerFromEnv();
TVector<NTesting::TPortHolder> ports(Reserve(100));
for (size_t i = 0; i < 100; ++i) {
@@ -40,9 +40,61 @@ TEST(NetworkTest, FreePort) {
}
}
+TEST(NetworkTest, FreePortWithinRanges) {
+ NTesting::TScopedEnvironment envGuard{{
+ {"PORT_SYNC_PATH", TmpDir.Name()},
+ {"VALID_PORT_RANGE", "3456:7654"},
+ }};
+ NTesting::InitPortManagerFromEnv();
+
+ for (size_t i = 0; i < 100; ++i) {
+ auto holder = NTesting::GetFreePort();
+ ui16 port = holder;
+ ASSERT_GE(port, 3456u);
+ ASSERT_LE(port, 7654u);
+ }
+}
+
+TEST(NetworkTest, GetPortRandom) {
+ NTesting::TScopedEnvironment envGuard{{
+ {"PORT_SYNC_PATH", TmpDir.Name()},
+ {"NO_RANDOM_PORTS", ""},
+ }};
+ NTesting::InitPortManagerFromEnv();
+
+ ui16 testPort = 80; // value just must be outside the assignable range
+ for (size_t i = 0; i < 10; ++i) {
+ NTesting::TPortHolder assigned = NTesting::NLegacy::GetPort(testPort);
+ ui16 assignedInt = assigned;
+ ASSERT_NE(testPort, assignedInt);
+ }
+}
+
+TEST(NetworkTest, GetPortNonRandom) {
+ NTesting::TScopedEnvironment envGuard{{
+ {"PORT_SYNC_PATH", TmpDir.Name()},
+ {"NO_RANDOM_PORTS", "1"},
+ }};
+ NTesting::InitPortManagerFromEnv();
+
+ TVector<ui16> ports(Reserve(100)); // keep integers, we don't need the ports to remain allocated
+
+ for (size_t i = 0; i < 10; ++i) {
+ auto portHolder = NTesting::GetFreePort();
+ ports.push_back(portHolder);
+ }
+
+ for (auto& testPort : ports) {
+ NTesting::TPortHolder assigned = NTesting::NLegacy::GetPort(testPort);
+ ui16 assignedInt = assigned;
+ ASSERT_EQ(testPort, assignedInt);
+ }
+}
+
TEST(FreePortTest, FreePortsRange) {
NTesting::TScopedEnvironment envGuard("PORT_SYNC_PATH", TmpDir.Name());
+ NTesting::InitPortManagerFromEnv();
for (ui16 i = 2; i < 10; ++i) {
TVector<NTesting::TPortHolder> ports = NTesting::NLegacy::GetFreePortsRange(i);