Skip to content

Commit 4d584d7

Browse files
authored
Int test for all solvers (#564)
* release notes * [Gradle Release Plugin] - new version commit: '3.29.0-snapshot'. * Creating support for testing DPS really like a integration test, crating int test for solver remote happy pah * clean code * clean code * configuring templates * configuring templates * option to get answer ip * comptest task wont run int test * creating task to run all tests * adjusting ci steps * adjusting ci
1 parent f54f79c commit 4d584d7

File tree

13 files changed

+372
-6
lines changed

13 files changed

+372
-6
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ jobs:
1717
with:
1818
java-version: '21'
1919

20-
- name: Build and Tests
21-
run: ./gradlew build test compTest -i
20+
- name: Build and Unit Tests
21+
run: ./gradlew build test -i
22+
23+
- name: Comp Tests
24+
run: ./gradlew -x check compTest -i
2225

2326
- name: Native Image Integration Tests
2427
run: ./gradlew build -x check nativeIntTest -i

RELEASE-NOTES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 3.29.0
2+
* Implementing an IntTest which can validate the happy path of all DPS solvers,
3+
being able to detect bugs like the fixed at 3.25.14 (6db82f50d54bd3f3aed15d7120c1963c0386abf4).
4+
15
## 3.28.0
26
* Specify from which source the config is coming to facilitate troubleshooting. #533
37

build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ test {
104104

105105
def compTest = tasks.register("compTest", Test) {
106106
useJUnitPlatform()
107-
include "**/*CompTest.class", "**/*IntTest.class"
107+
include "**/*CompTest.class"
108108
failFast = true
109109
testLogging {
110110
events "passed", "skipped", "failed"
@@ -114,6 +114,10 @@ def compTest = tasks.register("compTest", Test) {
114114
}
115115
}
116116

117+
tasks.register("allTests", Test) {
118+
dependsOn test, compTest, nativeIntTest
119+
}
120+
117121
def intTest = tasks.register("intTest", Test) {
118122

119123
dependsOn shadowJar

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version=3.27.0-snapshot
1+
version=3.29.0-snapshot

src/main/java/com/mageddo/dns/utils/Messages.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,8 @@ public static HostnameQuery toHostnameQuery(Message query) {
301301
public static boolean isSuccess(Message res) {
302302
return res.getRcode() == Rcode.NOERROR;
303303
}
304+
305+
public static String findAnswerRawIP(Message res) {
306+
return findFirstAnswerRecord(res).rdataToString();
307+
}
304308
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.mageddo.dnsproxyserver.sandbox;
2+
3+
import com.mageddo.commons.exec.CommandLines;
4+
import com.mageddo.commons.exec.NopResultHandler;
5+
import com.mageddo.commons.exec.Request;
6+
import com.mageddo.dnsproxyserver.config.dataprovider.vo.ConfigEnv;
7+
import lombok.extern.slf4j.Slf4j;
8+
9+
import java.nio.file.Path;
10+
import java.util.Map;
11+
12+
@Slf4j
13+
public class BinaryFromGradleTestsSandbox {
14+
public Instance run(Path configFile) {
15+
final var commandLine = DpsBinaryExecutableFinder.buildCommandLine();
16+
final var request = Request.builder()
17+
.commandLine(commandLine)
18+
.handler(new NopResultHandler())
19+
.env(Map.of(ConfigEnv.MG_CONFIG_FILE_PATH, configFile.toString()))
20+
.build();
21+
22+
final var result = CommandLines.exec(request)
23+
.printOutToLogsInBackground();
24+
25+
return Instance.of(result);
26+
}
27+
28+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.mageddo.dnsproxyserver.sandbox;
2+
3+
import com.mageddo.utils.Runtime;
4+
import lombok.SneakyThrows;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.apache.commons.exec.CommandLine;
7+
import org.apache.commons.lang3.Validate;
8+
import org.graalvm.nativeimage.ImageInfo;
9+
10+
import java.nio.file.Files;
11+
import java.nio.file.Path;
12+
13+
@Slf4j
14+
public class DpsBinaryExecutableFinder {
15+
16+
public static CommandLine buildCommandLine() {
17+
return new DpsBinaryExecutableFinder().buildCommandLineForBestExecutable();
18+
}
19+
20+
private CommandLine buildCommandLineForBestExecutable() {
21+
final var executablePath = this.findBestExecutablePath();
22+
if (ImageInfo.inImageRuntimeCode()) {
23+
return new CommandLine(executablePath.toString());
24+
}
25+
final var javaCommandPath = this.findJavaCommand();
26+
return new CommandLine(javaCommandPath)
27+
.addArgument("-jar")
28+
.addArgument(executablePath.toFile().toString());
29+
}
30+
31+
private String findJavaCommand() {
32+
return ProcessHandle.current()
33+
.info()
34+
.command()
35+
.orElseThrow(() -> new IllegalStateException("Couldn't find current java process command"))
36+
;
37+
}
38+
39+
public static Path findPath() {
40+
return new DpsBinaryExecutableFinder().findBestExecutablePath();
41+
}
42+
43+
Path findBestExecutablePath() {
44+
if (ImageInfo.inImageRuntimeCode()) {
45+
return findBuiltNativeExecutablePath();
46+
}
47+
return findBuiltJarPath();
48+
}
49+
50+
Path findBuiltNativeExecutablePath() {
51+
final var buildPath = this.findBuildPath();
52+
final var path = buildPath.resolve("native/nativeIntTestCompile/dns-proxy-server-tests");
53+
Validate.isTrue(Files.exists(path), "Native executable not found at: " + path);
54+
return path;
55+
}
56+
57+
Path findBuiltJarPath() {
58+
final var buildPath = this.findBuildPath();
59+
final var libsPath = buildPath.resolve("libs");
60+
return findFirstMatchInPath(libsPath);
61+
}
62+
63+
@SneakyThrows
64+
private Path findFirstMatchInPath(Path libsPath) {
65+
try (var stream = Files.list(libsPath)) {
66+
return stream
67+
.filter(path -> path.toString().endsWith("-all.jar"))
68+
.findFirst()
69+
.orElseThrow(() -> new IllegalStateException("Unable to find fat jar at libs path"));
70+
}
71+
}
72+
73+
private Path findBuildPath() {
74+
var path = Runtime.getRunningDir();
75+
while (path != null) {
76+
if (path.endsWith("build")) {
77+
log.trace("buildPath={}", path);
78+
return path;
79+
}
80+
path = path.getParent();
81+
}
82+
return null;
83+
}
84+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.mageddo.dnsproxyserver.sandbox;
2+
3+
import com.mageddo.commons.exec.Result;
4+
import lombok.Builder;
5+
import lombok.NonNull;
6+
import lombok.Value;
7+
import lombok.extern.slf4j.Slf4j;
8+
9+
@Slf4j
10+
@Value
11+
@Builder
12+
public class Instance {
13+
14+
@NonNull
15+
Result result;
16+
17+
public static Instance of(Result result) {
18+
return Instance.builder()
19+
.result(result)
20+
.build()
21+
;
22+
}
23+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.mageddo.dnsproxyserver.sandbox;
2+
3+
import java.nio.file.Path;
4+
5+
public class Sandbox {
6+
public static Instance runFromGradleTests(Path configFile) {
7+
return new BinaryFromGradleTestsSandbox().run(configFile);
8+
}
9+
}

src/test/java/com/mageddo/dnsproxyserver/AppIntTest.java

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,34 @@
11
package com.mageddo.dnsproxyserver;
22

33
import com.mageddo.commons.concurrent.Threads;
4+
import com.mageddo.commons.exec.ProcessesWatchDog;
45
import com.mageddo.dns.utils.Messages;
56
import com.mageddo.dnsproxyserver.config.application.Configs;
7+
import com.mageddo.dnsproxyserver.config.dataprovider.JsonConfigs;
8+
import com.mageddo.dnsproxyserver.config.dataprovider.vo.ConfigJson;
9+
import com.mageddo.dnsproxyserver.sandbox.Instance;
10+
import com.mageddo.dnsproxyserver.sandbox.Sandbox;
611
import com.mageddo.dnsproxyserver.server.Starter;
712
import com.mageddo.dnsproxyserver.solver.SimpleResolver;
813
import com.mageddo.dnsproxyserver.utils.Ips;
14+
import com.mageddo.net.IpAddr;
915
import com.mageddo.utils.Executors;
1016
import lombok.SneakyThrows;
17+
import lombok.Value;
1118
import lombok.extern.slf4j.Slf4j;
1219
import org.junit.jupiter.api.AfterAll;
1320
import org.junit.jupiter.api.BeforeEach;
1421
import org.junit.jupiter.api.Test;
1522
import org.xbill.DNS.Message;
1623
import testing.templates.ConfigFlagArgsTemplates;
24+
import testing.templates.ConfigJsonFileTemplates;
1725

26+
import java.nio.file.Path;
1827
import java.time.Duration;
28+
import java.util.Arrays;
29+
import java.util.concurrent.ExecutorService;
1930

31+
import static org.junit.jupiter.api.Assertions.assertEquals;
2032
import static org.junit.jupiter.api.Assertions.assertTrue;
2133

2234
@Slf4j
@@ -29,12 +41,13 @@ void beforeEach() {
2941
}
3042

3143
@AfterAll
32-
static void afterAll(){
44+
static void afterAll() {
3345
Starter.setMustStartFlagActive(false);
46+
ProcessesWatchDog.instance().killAllProcesses();
3447
}
3548

3649
@Test
37-
void appMustStartAndQuerySampleWithSuccess() {
50+
void appMustStartAndQuerySampleWithSuccessFromLocalDbSolver() {
3851

3952
final var hostToQuery = "dps-sample.dev";
4053
final var args = ConfigFlagArgsTemplates.withRandomPortsAndNotAsDefaultDns();
@@ -51,13 +64,67 @@ void appMustStartAndQuerySampleWithSuccess() {
5164
assertTrue(Messages.isSuccess(res));
5265

5366
}
67+
}
68+
69+
@Test
70+
void mustQueryRemoteSolverPassingThroughAllModulesAndGetSuccess() {
71+
72+
final var hostToQuery = "dps-int-test.dev";
73+
74+
try (final var executor = Executors.newThreadExecutor()) {
75+
76+
final var serverAppConfig = buildAndStartServerApp(hostToQuery);
77+
final var clientApp = buildClientAppAndWait(executor, serverAppConfig.getDnsServerPort());
78+
79+
final var port = clientApp.getDnsServerPort();
80+
final var res = queryStartedServer(port, hostToQuery);
81+
82+
assertTrue(Messages.isSuccess(res));
83+
assertEquals("192.168.0.1", Messages.findAnswerRawIP(res));
84+
85+
}
5486

5587
}
5688

89+
private static App buildClientAppAndWait(ExecutorService executor, Integer serverPort) {
90+
final var remoteAddr = IpAddr.of("127.0.0.1", serverPort);
91+
return buildAppAndWait(executor, ConfigFlagArgsTemplates.withRandomPortsAndNotAsDefaultDnsUsingRemote(remoteAddr));
92+
}
93+
94+
private static Result buildAndStartServerApp(String hostToQuery) {
95+
final var configFile = ConfigJsonFileTemplates.withRandomPortsAndNotAsDefaultDnsAndCustomLocalDBEntry(hostToQuery);
96+
final var instance = Sandbox.runFromGradleTests(configFile);
97+
return Result.of(configFile, instance);
98+
}
99+
100+
private static App buildAppAndWait(ExecutorService executor, final String[] params) {
101+
log.debug("app={}", Arrays.toString(params));
102+
final var app = new App(params);
103+
executor.submit(app::start);
104+
Threads.sleep(Duration.ofSeconds(2));
105+
return app;
106+
}
107+
57108
@SneakyThrows
58109
static Message queryStartedServer(Integer port, String host) {
59110
final var dnsServerAddress = Ips.getAnyLocalAddress(port);
60111
final var dnsClient = new SimpleResolver(dnsServerAddress);
61112
return dnsClient.send(Messages.aQuestion(host));
62113
}
114+
115+
@Value
116+
static class Result {
117+
118+
private final ConfigJson config;
119+
private final Instance instance;
120+
121+
public static Result of(Path configFile, Instance instance) {
122+
return new Result(JsonConfigs.loadConfig(configFile), instance);
123+
}
124+
125+
public Integer getDnsServerPort() {
126+
return this.config.getDnsServerPort();
127+
}
128+
129+
}
63130
}

0 commit comments

Comments
 (0)