summaryrefslogtreecommitdiffhomepage
path: root/tunnel
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2020-03-14 10:32:12 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2020-03-14 10:32:12 +0530
commit093139bc912018114f286edb269f1f8bc137c790 (patch)
tree57c78d16b97b625c9cfc35385062e7e5e5a37e02 /tunnel
parent6c8a4a6a283ceaa4450e6c971801fe40d453c31a (diff)
tunnel: Add an initial set of unit tests
Includes a control set of broken configuration files that we attempt to parse and verify that the parser fails in a predictable and consistent manner. Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Diffstat (limited to 'tunnel')
-rw-r--r--tunnel/build.gradle6
-rw-r--r--tunnel/src/test/java/com/wireguard/config/BadConfigExceptionTest.java172
-rw-r--r--tunnel/src/test/java/com/wireguard/config/ConfigTest.java45
-rw-r--r--tunnel/src/test/resources/broken.conf9
-rw-r--r--tunnel/src/test/resources/invalid-key.conf9
-rw-r--r--tunnel/src/test/resources/invalid-number.conf9
-rw-r--r--tunnel/src/test/resources/invalid-value.conf9
-rw-r--r--tunnel/src/test/resources/missing-attribute.conf8
-rw-r--r--tunnel/src/test/resources/missing-section.conf5
-rw-r--r--tunnel/src/test/resources/syntax-error.conf9
-rw-r--r--tunnel/src/test/resources/unknown-attribute.conf9
-rw-r--r--tunnel/src/test/resources/unknown-section.conf9
-rw-r--r--tunnel/src/test/resources/working.conf9
13 files changed, 308 insertions, 0 deletions
diff --git a/tunnel/build.gradle b/tunnel/build.gradle
index 6a2e1c0e..f306292c 100644
--- a/tunnel/build.gradle
+++ b/tunnel/build.gradle
@@ -21,6 +21,11 @@ android {
path 'tools/CMakeLists.txt'
}
}
+ testOptions.unitTests.all {
+ testLogging {
+ events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'
+ }
+ }
}
dependencies {
@@ -30,6 +35,7 @@ dependencies {
implementation "com.google.code.findbugs:jsr305:$jsr305Version"
implementation "com.jakewharton.threetenabp:threetenabp:$threetenabpVersion"
implementation "net.i2p.crypto:eddsa:$eddsaVersion"
+ testImplementation "junit:junit:$junitVersion"
}
apply from: "publish.gradle"
diff --git a/tunnel/src/test/java/com/wireguard/config/BadConfigExceptionTest.java b/tunnel/src/test/java/com/wireguard/config/BadConfigExceptionTest.java
new file mode 100644
index 00000000..54935510
--- /dev/null
+++ b/tunnel/src/test/java/com/wireguard/config/BadConfigExceptionTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2020 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.config;
+
+import com.wireguard.config.BadConfigException.Location;
+import com.wireguard.config.BadConfigException.Reason;
+import com.wireguard.config.BadConfigException.Section;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+public class BadConfigExceptionTest {
+ private static final String[] CONFIG_NAMES = {
+ "invalid-key",
+ "invalid-number",
+ "invalid-value",
+ "missing-attribute",
+ "missing-section",
+ "syntax-error",
+ "unknown-attribute",
+ "unknown-section"
+ };
+ private static final Map<String, InputStream> CONFIG_MAP = new HashMap<>();
+
+ @BeforeClass
+ public static void readConfigs() {
+ for (final String config: CONFIG_NAMES) {
+ CONFIG_MAP.put(config, BadConfigExceptionTest.class.getClassLoader().getResourceAsStream(config + ".conf"));
+ }
+ }
+
+ @AfterClass
+ public static void closeStreams() {
+ for (final InputStream inputStream : CONFIG_MAP.values()) {
+ try {
+ inputStream.close();
+ } catch (final IOException ignored) {
+ }
+ }
+ }
+
+ @Test
+ public void throws_correctly_with_INVALID_KEY_reason() {
+ try {
+ Config.parse(CONFIG_MAP.get("invalid-key"));
+ fail("Config parsing must fail in this test");
+ } catch (final BadConfigException e) {
+ assertEquals(e.getReason(), Reason.INVALID_KEY);
+ assertEquals(e.getLocation(), Location.PUBLIC_KEY);
+ assertEquals(e.getSection(), Section.PEER);
+ } catch (final IOException e) {
+ e.printStackTrace();
+ fail("IOException thrown during test");
+ }
+ }
+
+ @Test
+ public void throws_correctly_with_INVALID_NUMBER_reason() {
+ try {
+ Config.parse(CONFIG_MAP.get("invalid-number"));
+ fail("Config parsing must fail in this test");
+ } catch (final BadConfigException e) {
+ assertEquals(e.getReason(), Reason.INVALID_NUMBER);
+ assertEquals(e.getLocation(), Location.PERSISTENT_KEEPALIVE);
+ assertEquals(e.getSection(), Section.PEER);
+ } catch (final IOException e) {
+ e.printStackTrace();
+ fail("IOException thrown during test");
+ }
+ }
+
+ @Test
+ public void throws_correctly_with_INVALID_VALUE_reason() {
+ try {
+ Config.parse(CONFIG_MAP.get("invalid-value"));
+ fail("Config parsing must fail in this test");
+ } catch (final BadConfigException e) {
+ assertEquals(e.getReason(), Reason.INVALID_VALUE);
+ assertEquals(e.getLocation(), Location.DNS);
+ assertEquals(e.getSection(), Section.INTERFACE);
+ } catch (final IOException e) {
+ e.printStackTrace();
+ fail("IOException throwing during test");
+ }
+ }
+
+ @Test
+ public void throws_correctly_with_MISSING_ATTRIBUTE_reason() {
+ try {
+ Config.parse(CONFIG_MAP.get("missing-attribute"));
+ fail("Config parsing must fail in this test");
+ } catch (final BadConfigException e) {
+ assertEquals(e.getReason(), Reason.MISSING_ATTRIBUTE);
+ assertEquals(e.getLocation(), Location.PUBLIC_KEY);
+ assertEquals(e.getSection(), Section.PEER);
+ } catch (final IOException e) {
+ e.printStackTrace();
+ fail("IOException throwing during test");
+ }
+ }
+
+ @Test
+ public void throws_correctly_with_MISSING_SECTION_reason() {
+ try {
+ Config.parse(CONFIG_MAP.get("missing-section"));
+ fail("Config parsing must fail in this test");
+ } catch (final BadConfigException e) {
+ assertEquals(e.getReason(), Reason.MISSING_SECTION);
+ assertEquals(e.getLocation(), Location.TOP_LEVEL);
+ assertEquals(e.getSection(), Section.CONFIG);
+ } catch (final IOException e) {
+ e.printStackTrace();
+ fail("IOException throwing during test");
+ }
+ }
+
+ @Test
+ public void throws_correctly_with_SYNTAX_ERROR_reason() {
+ try {
+ Config.parse(CONFIG_MAP.get("syntax-error"));
+ fail("Config parsing must fail in this test");
+ } catch (final BadConfigException e) {
+ assertEquals(e.getReason(), Reason.SYNTAX_ERROR);
+ assertEquals(e.getLocation(), Location.TOP_LEVEL);
+ assertEquals(e.getSection(), Section.PEER);
+ } catch (final IOException e) {
+ e.printStackTrace();
+ fail("IOException throwing during test");
+ }
+ }
+
+ @Test
+ public void throws_correctly_with_UNKNOWN_ATTRIBUTE_reason() {
+ try {
+ Config.parse(CONFIG_MAP.get("unknown-attribute"));
+ fail("Config parsing must fail in this test");
+ } catch (final BadConfigException e) {
+ assertEquals(e.getReason(), Reason.UNKNOWN_ATTRIBUTE);
+ assertEquals(e.getLocation(), Location.TOP_LEVEL);
+ assertEquals(e.getSection(), Section.PEER);
+ } catch (final IOException e) {
+ e.printStackTrace();
+ fail("IOException throwing during test");
+ }
+ }
+
+ @Test
+ public void throws_correctly_with_UNKNOWN_SECTION_reason() {
+ try {
+ Config.parse(CONFIG_MAP.get("unknown-section"));
+ fail("Config parsing must fail in this test");
+ } catch (final BadConfigException e) {
+ assertEquals(e.getReason(), Reason.UNKNOWN_SECTION);
+ assertEquals(e.getLocation(), Location.TOP_LEVEL);
+ assertEquals(e.getSection(), Section.CONFIG);
+ } catch (final IOException e) {
+ e.printStackTrace();
+ fail("IOException throwing during test");
+ }
+ }
+}
diff --git a/tunnel/src/test/java/com/wireguard/config/ConfigTest.java b/tunnel/src/test/java/com/wireguard/config/ConfigTest.java
new file mode 100644
index 00000000..6d599217
--- /dev/null
+++ b/tunnel/src/test/java/com/wireguard/config/ConfigTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2020 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.config;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Objects;
+
+public class ConfigTest {
+
+ @Test
+ public void valid_config_parses_correctly() throws IOException, ParseException {
+ Config config = null;
+ final Collection<InetNetwork> expectedAllowedIps = new HashSet<>(Arrays.asList(InetNetwork.parse("0.0.0.0/0"), InetNetwork.parse("::0/0")));
+ try (final InputStream is = Objects.requireNonNull(getClass().getClassLoader()).getResourceAsStream("working.conf")) {
+ config = Config.parse(is);
+ } catch (final BadConfigException e) {
+ fail("'working.conf' should never fail to parse");
+ }
+ assertNotNull("config cannot be null after parsing", config);
+ assertTrue(
+ "No applications should be excluded by default",
+ config.getInterface().getExcludedApplications().isEmpty()
+ );
+ assertEquals("Test config has exactly one peer", 1, config.getPeers().size());
+ assertEquals("Test config's allowed IPs are 0.0.0.0/0 and ::0/0", config.getPeers().get(0).getAllowedIps(), expectedAllowedIps);
+ assertEquals("Test config has one DNS server", 1, config.getInterface().getDnsServers().size());
+ }
+
+ @Test(expected = BadConfigException.class)
+ public void invalid_config_throws() throws IOException, BadConfigException {
+ try (final InputStream is = Objects.requireNonNull(getClass().getClassLoader()).getResourceAsStream("broken.conf")) {
+ Config.parse(is);
+ }
+ }
+}
diff --git a/tunnel/src/test/resources/broken.conf b/tunnel/src/test/resources/broken.conf
new file mode 100644
index 00000000..753c9717
--- /dev/null
+++ b/tunnel/src/test/resources/broken.conf
@@ -0,0 +1,9 @@
+[Interface]
+PrivateKey = l0lth1s1sd3f1n1t3lybr0k3n=
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0
+
+[Peer]
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6O6Qg=
+AllowedIPs = 0.0.0.0/0,::0/0
+Endpoint = 192.0.2.1:51820
diff --git a/tunnel/src/test/resources/invalid-key.conf b/tunnel/src/test/resources/invalid-key.conf
new file mode 100644
index 00000000..215bec3b
--- /dev/null
+++ b/tunnel/src/test/resources/invalid-key.conf
@@ -0,0 +1,9 @@
+[Interface]
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0
+PrivateKey = TFlmmEUC7V7VtiDYLKsbP5rySTKLIZq1yn8lMqK83wo=
+[Peer]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint = 192.0.2.1:51820
+PersistentKeepalive = 0
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6Og=
diff --git a/tunnel/src/test/resources/invalid-number.conf b/tunnel/src/test/resources/invalid-number.conf
new file mode 100644
index 00000000..f05fe32b
--- /dev/null
+++ b/tunnel/src/test/resources/invalid-number.conf
@@ -0,0 +1,9 @@
+[Interface]
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0
+PrivateKey = TFlmmEUC7V7VtiDYLKsbP5rySTKLIZq1yn8lMqK83wo=
+[Peer]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint = 192.0.2.1:51820
+PersistentKeepalive = 0L
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6O6Qg=
diff --git a/tunnel/src/test/resources/invalid-value.conf b/tunnel/src/test/resources/invalid-value.conf
new file mode 100644
index 00000000..2889111e
--- /dev/null
+++ b/tunnel/src/test/resources/invalid-value.conf
@@ -0,0 +1,9 @@
+[Interface]
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0,yes
+PrivateKey = TFlmmEUC7V7VtiDYLKsbP5rySTKLIZq1yn8lMqK83wo=
+[Peer]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint = 192.0.2.1:51820
+PersistentKeepalive = 0
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6O6Qg=
diff --git a/tunnel/src/test/resources/missing-attribute.conf b/tunnel/src/test/resources/missing-attribute.conf
new file mode 100644
index 00000000..ddf8cbb5
--- /dev/null
+++ b/tunnel/src/test/resources/missing-attribute.conf
@@ -0,0 +1,8 @@
+[Interface]
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0
+PrivateKey = TFlmmEUC7V7VtiDYLKsbP5rySTKLIZq1yn8lMqK83wo=
+[Peer]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint = 192.0.2.1:51820
+PersistentKeepalive = 0
diff --git a/tunnel/src/test/resources/missing-section.conf b/tunnel/src/test/resources/missing-section.conf
new file mode 100644
index 00000000..676199ac
--- /dev/null
+++ b/tunnel/src/test/resources/missing-section.conf
@@ -0,0 +1,5 @@
+[Peer]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint = 192.0.2.1:51820
+PersistentKeepalive = 0
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6O6Qg=
diff --git a/tunnel/src/test/resources/syntax-error.conf b/tunnel/src/test/resources/syntax-error.conf
new file mode 100644
index 00000000..38b8ec95
--- /dev/null
+++ b/tunnel/src/test/resources/syntax-error.conf
@@ -0,0 +1,9 @@
+[Interface]
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0
+PrivateKey = TFlmmEUC7V7VtiDYLKsbP5rySTKLIZq1yn8lMqK83wo=
+[Peer]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint =
+PersistentKeepalive = 0
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6O6Qg=
diff --git a/tunnel/src/test/resources/unknown-attribute.conf b/tunnel/src/test/resources/unknown-attribute.conf
new file mode 100644
index 00000000..f311161d
--- /dev/null
+++ b/tunnel/src/test/resources/unknown-attribute.conf
@@ -0,0 +1,9 @@
+[Interface]
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0
+PrivateKey = TFlmmEUC7V7VtiDYLKsbP5rySTKLIZq1yn8lMqK83wo=
+[Peer]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint = 192.0.2.1:51820
+DontLetTheFeelingFade = 1
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6O6Qg=
diff --git a/tunnel/src/test/resources/unknown-section.conf b/tunnel/src/test/resources/unknown-section.conf
new file mode 100644
index 00000000..579d9717
--- /dev/null
+++ b/tunnel/src/test/resources/unknown-section.conf
@@ -0,0 +1,9 @@
+[Interface]
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0
+PrivateKey = TFlmmEUC7V7VtiDYLKsbP5rySTKLIZq1yn8lMqK83wo=
+[Peers]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint = 192.0.2.1:51820
+PersistentKeepalive = 0
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6O6Qg=
diff --git a/tunnel/src/test/resources/working.conf b/tunnel/src/test/resources/working.conf
new file mode 100644
index 00000000..3f9665c3
--- /dev/null
+++ b/tunnel/src/test/resources/working.conf
@@ -0,0 +1,9 @@
+[Interface]
+Address = 192.0.2.2/32,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128
+DNS = 192.0.2.0
+PrivateKey = TFlmmEUC7V7VtiDYLKsbP5rySTKLIZq1yn8lMqK83wo=
+[Peer]
+AllowedIPs = 0.0.0.0/0, ::0/0
+Endpoint = 192.0.2.1:51820
+PersistentKeepalive = 0
+PublicKey = vBN7qyUTb5lJtWYJ8LhbPio1Z4RcyBPGnqFBGn6O6Qg=