Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SecureRandom for avoiding the port conflicts #219

Merged
merged 2 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,16 @@ public boolean disableIntegrationTests() {
return disableIntegrationTests.get();
}

@VisibleForTesting
Supplier<String> createParam(String key, String defaultValue) {
private Supplier<String> createParam(String key, String defaultValue) {
return Suppliers.memoize(() -> readParam(key, defaultValue));
}

@VisibleForTesting
Supplier<Boolean> createParam(String key, boolean defaultValue) {
private Supplier<Boolean> createParam(String key, boolean defaultValue) {
return Suppliers.memoize(() -> readParam(key, defaultValue));
}

@VisibleForTesting
String readParam(String key, String defaultValue) {
static String readParam(String key, String defaultValue) {
String env = System.getenv(key);
if (env != null && !env.isEmpty()) {
return env;
Expand All @@ -89,7 +87,7 @@ String readParam(String key, String defaultValue) {
}

@VisibleForTesting
Boolean readParam(String key, boolean defaultValue) {
static Boolean readParam(String key, boolean defaultValue) {
String env = System.getenv(key);
if (env != null && !env.isEmpty()) {
return Boolean.valueOf(env);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.security.SecureRandom;
import java.util.Random;

import javax.net.ServerSocketFactory;
Expand All @@ -14,7 +15,7 @@
public class PortsGenerator {
private static final int PORT_RANGE_MIN = 51000;
private static final int PORT_RANGE_MAX = 59000;
private static final Random RANDOM = new Random(System.nanoTime());
private static final Random RANDOM = new SecureRandom();

private int nextPort;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,79 @@
package tech.ydb.test.integration;

import java.util.HashMap;
import java.util.Map;

/**
*
* @author Aleksandr Gorshenin
*/
public class YdbEnvironmentMock extends YdbEnvironment {
private final Map<String, String> params = new HashMap<>();
private String database = null;
private String endpoint = null;
private String pemCert = null;
private String token = null;
private boolean useTLS = false;
private boolean dockerReuse = false;

public YdbEnvironmentMock withDatabase(String value) {
this.database = value;
return this;
}

public YdbEnvironmentMock with(String key, String value) {
params.put(key, value);
public YdbEnvironmentMock withEndpoint(String value) {
this.endpoint = value;
return this;
}

public YdbEnvironmentMock withPemCert(String value) {
this.pemCert = value;
return this;
}

public YdbEnvironmentMock withToken(String value) {
this.token = value;
return this;
}

public YdbEnvironmentMock withUseTLS(boolean value) {
this.useTLS = value;
return this;
}

public YdbEnvironmentMock withDockerReuse(boolean value) {
this.dockerReuse = value;
return this;
}

@Override
public String ydbDatabase() {
return database;
}

@Override
public String ydbEndpoint() {
return endpoint;
}

@Override
String readParam(String key, String defaultValue) {
return params.getOrDefault(key, defaultValue);
public String ydbPemCert() {
return pemCert;
}

@Override
Boolean readParam(String key, boolean defaultValue) {
if (params.containsKey(key)) {
return Boolean.valueOf(params.get(key));
}
return defaultValue;
public String ydbAuthToken() {
return token;
}

public static YdbEnvironmentMock create() {
return new YdbEnvironmentMock();
@Override
public boolean ydbUseTls() {
return useTLS;
}

@Override
public boolean dockerReuse() {
return dockerReuse;
}

@Override
public boolean disableIntegrationTests() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,71 +12,67 @@
*/
public class YdbEnvironmentTest {
private final static String ENV_PARAM = "TEST_VAR1";
private final static String NOT_EXIST_ENV_PARAM = "TEST_VAR2";
private final static String MISSED_ENV = "TEST_VAR2";
private final static String EMPTY_ENV_PARAM = "TEST_VAR3";
private final static String BOOLEAN_ENV_PARAM = "TEST_VAR4";
private final static String WRONG_BOOLEAN_ENV_PARAM = "TEST_VAR5";
private final static String WRONG_BOOLEAN_SYSTEM_PARAM = "TEST_VAR6";

@Test
public void envDefaultsTests() {
YdbEnvironment env = new YdbEnvironment();

// Correct string value from ENV
Assert.assertEquals("Check exist env param", "var1", env.readParam(ENV_PARAM, "default1"));
Assert.assertEquals("Check exist env param", "var1", YdbEnvironment.readParam(ENV_PARAM, "default1"));

// Incorrect string value from ENV
Assert.assertEquals("Check not exist env param", "default2", env.readParam(NOT_EXIST_ENV_PARAM, "default2"));
Assert.assertNull("Check not exist env param" ,env.readParam(NOT_EXIST_ENV_PARAM, null));
Assert.assertEquals("Check not exist env param", "default2",YdbEnvironment.readParam(MISSED_ENV, "default2"));
Assert.assertNull("Check not exist env param", YdbEnvironment.readParam(MISSED_ENV, null));

// Empty string value from ENV
Assert.assertEquals("Check empty env param", "default3", env.readParam(EMPTY_ENV_PARAM, "default3"));
Assert.assertNull("Check empty env param", env.readParam(EMPTY_ENV_PARAM, null));
Assert.assertEquals("Check empty env param", "default3", YdbEnvironment.readParam(EMPTY_ENV_PARAM, "default3"));
Assert.assertNull("Check empty env param", YdbEnvironment.readParam(EMPTY_ENV_PARAM, null));

// Correct boolean value from ENV
Assert.assertTrue("Check exist env param", env.readParam(BOOLEAN_ENV_PARAM, true));
Assert.assertTrue("Check exist env param", env.readParam(BOOLEAN_ENV_PARAM, false));
Assert.assertTrue("Check exist env param", YdbEnvironment.readParam(BOOLEAN_ENV_PARAM, true));
Assert.assertTrue("Check exist env param", YdbEnvironment.readParam(BOOLEAN_ENV_PARAM, false));

// Incorrect boolean value from ENV
Assert.assertFalse("Check exist env param", env.readParam(WRONG_BOOLEAN_ENV_PARAM, false));
Assert.assertFalse("Check exist env param", env.readParam(WRONG_BOOLEAN_ENV_PARAM, true));
Assert.assertFalse("Check exist env param", YdbEnvironment.readParam(WRONG_BOOLEAN_ENV_PARAM, false));
Assert.assertFalse("Check exist env param", YdbEnvironment.readParam(WRONG_BOOLEAN_ENV_PARAM, true));

// Empty boolean value from ENV
Assert.assertFalse("Check exist env param", env.readParam(EMPTY_ENV_PARAM, false));
Assert.assertTrue("Check exist env param", env.readParam(EMPTY_ENV_PARAM, true));
Assert.assertFalse("Check exist env param", YdbEnvironment.readParam(EMPTY_ENV_PARAM, false));
Assert.assertTrue("Check exist env param", YdbEnvironment.readParam(EMPTY_ENV_PARAM, true));
}

@Test
public void propertiesReadTests() {
try {
System.setProperty(ENV_PARAM, "prop1");
System.setProperty(NOT_EXIST_ENV_PARAM, "prop2");
System.setProperty(MISSED_ENV, "prop2");
System.setProperty(EMPTY_ENV_PARAM, "true");
System.setProperty(BOOLEAN_ENV_PARAM, "false");
System.setProperty(WRONG_BOOLEAN_SYSTEM_PARAM, "");

YdbEnvironment env = new YdbEnvironment();

// Correct string value - env has higher priority
Assert.assertEquals("Check exist env param", "var1", env.readParam(ENV_PARAM, "default1"));
Assert.assertEquals("Check exist env param", "var1", YdbEnvironment.readParam(ENV_PARAM, "default1"));

// Incorrect string value - use properites
Assert.assertEquals("Check not exist env param", "prop2", env.readParam(NOT_EXIST_ENV_PARAM, "default2"));
Assert.assertEquals("Check not exist env param", "prop2" ,env.readParam(NOT_EXIST_ENV_PARAM, null));
Assert.assertEquals("Check not exist env param", "prop2", YdbEnvironment.readParam(MISSED_ENV, "default2"));
Assert.assertEquals("Check not exist env param", "prop2" ,YdbEnvironment.readParam(MISSED_ENV, null));

// Empty string value from ENV
Assert.assertEquals("Check empty env param", "true", env.readParam(EMPTY_ENV_PARAM, "default3"));
Assert.assertEquals("Check empty env param", "true", env.readParam(EMPTY_ENV_PARAM, null));
Assert.assertEquals("Check empty env param", "true", YdbEnvironment.readParam(EMPTY_ENV_PARAM, "default3"));
Assert.assertEquals("Check empty env param", "true", YdbEnvironment.readParam(EMPTY_ENV_PARAM, null));

// Correct boolean value - env has hight priority
Assert.assertTrue("Check exist env param", env.readParam(BOOLEAN_ENV_PARAM, false));
Assert.assertTrue("Check exist env param", YdbEnvironment.readParam(BOOLEAN_ENV_PARAM, false));

// Incorrect boolean value - use properites
Assert.assertTrue("Check exist env param", env.readParam(EMPTY_ENV_PARAM, false));
Assert.assertFalse("Check exist env param", env.readParam(WRONG_BOOLEAN_SYSTEM_PARAM, false));
Assert.assertTrue("Check exist env param", YdbEnvironment.readParam(EMPTY_ENV_PARAM, false));
Assert.assertFalse("Check exist env param", YdbEnvironment.readParam(WRONG_BOOLEAN_SYSTEM_PARAM, false));
} finally {
System.getProperties().remove(ENV_PARAM);
System.getProperties().remove(NOT_EXIST_ENV_PARAM);
System.getProperties().remove(MISSED_ENV);
System.getProperties().remove(EMPTY_ENV_PARAM);
System.getProperties().remove(BOOLEAN_ENV_PARAM);
System.getProperties().remove(WRONG_BOOLEAN_SYSTEM_PARAM);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public void defaultInstanceTest() {
public void externalNonTlsInstanceTest() {
transportMock.setup("/database");

YdbEnvironmentMock env = YdbEnvironmentMock.create()
.with("YDB_ENDPOINT", "localhost:1234")
.with("YDB_DATABASE", "/database");
YdbEnvironmentMock env = new YdbEnvironmentMock()
.withEndpoint("localhost:1234")
.withDatabase("/database");

YdbHelperFactory factory = YdbHelperFactory.createYdbHelper(env);

Expand Down Expand Up @@ -79,11 +79,11 @@ public void externalTlsInstanceTest() throws IOException {
os.flush();
}

YdbEnvironmentMock env = YdbEnvironmentMock.create()
.with("YDB_ENDPOINT", "localhost:1234")
.with("YDB_DATABASE", "/tls")
.with("YDB_USE_TLS", "true")
.with("YDB_PEM_CERT", pem.getAbsolutePath());
YdbEnvironmentMock env = new YdbEnvironmentMock()
.withEndpoint("localhost:1234")
.withDatabase("/tls")
.withUseTLS(true)
.withPemCert(pem.getAbsolutePath());

YdbHelperFactory factory = YdbHelperFactory.createYdbHelper(env);

Expand All @@ -110,12 +110,12 @@ public void externalTlsInstanceTest() throws IOException {
public void externalAuthInstanceTest() throws IOException {
transportMock.setup("/token");

YdbEnvironmentMock env = YdbEnvironmentMock.create()
.with("YDB_ENDPOINT", "localhost:4321")
.with("YDB_DATABASE", "/token")
.with("YDB_USE_TLS", "true")
.with("YDB_TOKEN", "TOKEN1234")
.with("YDB_PEM_CERT", "/not_exists_file.pem");
YdbEnvironmentMock env = new YdbEnvironmentMock()
.withEndpoint("localhost:4321")
.withDatabase("/token")
.withUseTLS(true)
.withToken("TOKEN1234")
.withPemCert("/not_exists_file.pem");

YdbHelperFactory factory = YdbHelperFactory.createYdbHelper(env);

Expand Down Expand Up @@ -143,7 +143,7 @@ public void dockerUnavailableInstanceTest() {
try (DockerMock docker = new DockerMock()) {
docker.setup(Boolean.FALSE);

YdbHelperFactory factory = YdbHelperFactory.createYdbHelper(YdbEnvironmentMock.create());
YdbHelperFactory factory = YdbHelperFactory.createYdbHelper(new YdbEnvironmentMock());

Assert.assertNotNull("check disabled factory instance", factory);
Assert.assertFalse("check disabled factory instance", factory.isEnabled());
Expand All @@ -156,7 +156,7 @@ public void dockerInstanceTest() {
try (DockerMock docker = new DockerMock()) {
docker.setup(Boolean.TRUE);

YdbHelperFactory factory = YdbHelperFactory.createYdbHelper(YdbEnvironmentMock.create());
YdbHelperFactory factory = YdbHelperFactory.createYdbHelper(new YdbEnvironmentMock());

Assert.assertNotNull("check docker factory instance", factory);
Assert.assertTrue("check docker factory instance", factory.isEnabled());
Expand All @@ -168,26 +168,26 @@ public void wrongEnvTest() {
try (DockerMock docker = new DockerMock()) {
docker.setup(Boolean.FALSE);

YdbHelperFactory factory1 = YdbHelperFactory.createYdbHelper(YdbEnvironmentMock.create()
.with("YDB_ENDPOINT", "localhost:1234")
.with("YDB_DATABASE", "")
YdbHelperFactory factory1 = YdbHelperFactory.createYdbHelper(new YdbEnvironmentMock()
.withEndpoint("localhost:1234")
.withDatabase("")
);

Assert.assertNotNull("check disabled factory instance", factory1);
Assert.assertFalse("check disabled factory instance", factory1.isEnabled());
Assert.assertNull("empty helper for disabled factory instance", factory1.createHelper());

YdbHelperFactory factory2 = YdbHelperFactory.createYdbHelper(YdbEnvironmentMock.create()
.with("YDB_ENDPOINT", "")
.with("YDB_DATABASE", "/local")
YdbHelperFactory factory2 = YdbHelperFactory.createYdbHelper(new YdbEnvironmentMock()
.withEndpoint("")
.withDatabase("/local")
);

Assert.assertNotNull("check disabled factory instance", factory2);
Assert.assertFalse("check disabled factory instance", factory2.isEnabled());
Assert.assertNull("empty helper for disabled factory instance", factory2.createHelper());

YdbHelperFactory factory3 = YdbHelperFactory.createYdbHelper(YdbEnvironmentMock.create()
.with("YDB_ENDPOINT", "localhost:1234")
YdbHelperFactory factory3 = YdbHelperFactory.createYdbHelper(new YdbEnvironmentMock()
.withEndpoint("localhost:1234")
);

Assert.assertNotNull("check disabled factory instance", factory3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public void defaultDockerContainerTests() {
PortsGenerator ports = Mockito.mock(PortsGenerator.class);
Mockito.when(ports.findAvailablePort()).thenReturn(/* Secure */ 10, /* Insecure */ 11);

YdbEnvironmentMock env = YdbEnvironmentMock.create();
YdbEnvironmentMock env = new YdbEnvironmentMock();
YdbMockContainer container = new YdbMockContainer(env, ports);
DockerHelperFactory factory = new DockerHelperFactory(env, container);

Expand Down Expand Up @@ -156,10 +156,10 @@ public void tlsDockerContainerTests() {
PortsGenerator ports = Mockito.mock(PortsGenerator.class);
Mockito.when(ports.findAvailablePort()).thenReturn(/* Secure */ 22, /* Insecure */ 33);

YdbEnvironmentMock env = YdbEnvironmentMock.create()
.with("YDB_USE_TLS", "True")
.with("YDB_TOKEN", "SIMPLE_TOKEN")
.with("YDB_DOCKER_REUSE", "false");
YdbEnvironmentMock env = new YdbEnvironmentMock()
.withUseTLS(true)
.withToken("SIMPLE_TOKEN")
.withDockerReuse(false);

YdbMockContainer container = new YdbMockContainer(env, ports);
DockerHelperFactory factory = new DockerHelperFactory(env, container);
Expand Down Expand Up @@ -218,9 +218,9 @@ public void reuseDockerContainerTests() {
PortsGenerator ports = Mockito.mock(PortsGenerator.class);
Mockito.when(ports.findAvailablePort()).thenReturn(/* Secure */ 41, /* Insecure */ 44);

YdbEnvironmentMock env = YdbEnvironmentMock.create()
.with("YDB_USE_TLS", "True")
.with("YDB_DOCKER_REUSE", "true");
YdbEnvironmentMock env = new YdbEnvironmentMock()
.withUseTLS(true)
.withDockerReuse(true);

YdbMockContainer container = new YdbMockContainer(env, ports);
DockerHelperFactory factory = new DockerHelperFactory(env, container);
Expand Down