summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2019-10-19 02:24:39 +0200
committercyBerta <cyberta@riseup.net>2019-10-19 02:24:39 +0200
commitb715aeba40bfb62de2f6a158609dfd81126da25a (patch)
treecd8483054f18b532c37cf60b22289b5cecf930e2
parent313627f7e8e174fab3df063905445af370deb26e (diff)
unit tests for gateway manager's gateway selection
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java5
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java32
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java189
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java20
-rw-r--r--app/src/test/resources/ptdemo_misconfigured_gateway.json38
5 files changed, 174 insertions, 110 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
index a62daca1..075aac71 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
@@ -16,6 +16,8 @@
*/
package se.leap.bitmaskclient.eip;
+import android.support.annotation.VisibleForTesting;
+
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -111,7 +113,8 @@ public class VpnConfigGenerator {
+ secretsConfiguration();
}
- private VpnProfile createProfile(Connection.TransportType transportType) throws IOException, ConfigParser.ConfigParseError, JSONException {
+ @VisibleForTesting
+ protected VpnProfile createProfile(Connection.TransportType transportType) throws IOException, ConfigParser.ConfigParseError, JSONException {
String configuration = getConfigurationString(transportType);
ConfigParser icsOpenvpnConfigParser = new ConfigParser();
icsOpenvpnConfigParser.parseConfig(new StringReader(configuration));
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java
index 5089de54..5d5a959b 100644
--- a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java
@@ -1,32 +1,5 @@
package se.leap.bitmaskclient.eip;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.database.DatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.view.Display;
-
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
@@ -41,12 +14,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.util.ArrayList;
import de.blinkt.openvpn.core.ConfigParser;
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
index 12e95a47..47db3e09 100644
--- a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
@@ -2,6 +2,7 @@ package se.leap.bitmaskclient.eip;
import android.content.Context;
import android.content.SharedPreferences;
+import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
@@ -10,95 +11,205 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
import java.io.IOException;
+import de.blinkt.openvpn.VpnProfile;
+import de.blinkt.openvpn.core.ConfigParser;
import de.blinkt.openvpn.core.connection.Connection;
-import se.leap.bitmaskclient.Constants;
import se.leap.bitmaskclient.Provider;
+import se.leap.bitmaskclient.ProviderObservable;
+import se.leap.bitmaskclient.testutils.MockHelper;
+import se.leap.bitmaskclient.testutils.MockSharedPreferences;
import se.leap.bitmaskclient.testutils.TestSetupHelper;
+import se.leap.bitmaskclient.utils.ConfigHelper;
+import se.leap.bitmaskclient.utils.PreferenceHelper;
+import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
+import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static se.leap.bitmaskclient.Constants.GATEWAYS;
+import static se.leap.bitmaskclient.Constants.PROVIDER_EIP_DEFINITION;
+import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY;
+import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.Provider.CA_CERT;
+import static se.leap.bitmaskclient.testutils.TestSetupHelper.getProvider;
/**
* Created by cyberta on 09.10.17.
*/
-@RunWith(MockitoJUnitRunner.class)
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ProviderObservable.class, Log.class, PreferenceHelper.class, ConfigHelper.class})
public class GatewaysManagerTest {
private GatewaysManager gatewaysManager;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mockContext;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+
private SharedPreferences sharedPreferences;
+ private JSONObject secrets;
+
@Before
public void setUp() throws IOException, JSONException {
+ mockStatic(Log.class);
+ mockStatic(ConfigHelper.class);
+ when(ConfigHelper.getCurrentTimezone()).thenReturn(-1);
+ when(ConfigHelper.stringEqual(anyString(), anyString())).thenCallRealMethod();
+ secrets = new JSONObject(getJsonStringFor("secrets.json"));
+ sharedPreferences = new MockSharedPreferences();
+ sharedPreferences.edit().
+ putString(PROVIDER_PRIVATE_KEY, secrets.getString(PROVIDER_PRIVATE_KEY)).
+ putString(CA_CERT, secrets.getString(CA_CERT)).
+ putString(PROVIDER_VPN_CERTIFICATE, secrets.getString(PROVIDER_VPN_CERTIFICATE))
+ .commit();
+ }
+ @Test
+ public void testFromEipServiceJson_emptyJson() throws Exception {
+ gatewaysManager = new GatewaysManager(mockContext, sharedPreferences);
+ assertEquals(0, gatewaysManager.size());
+ }
- JSONObject secrets = new JSONObject(getJsonStringFor("secrets.json"));
-
- when(sharedPreferences.getString(eq(Constants.PROVIDER_PRIVATE_KEY), anyString())).thenReturn(secrets.getString(Constants.PROVIDER_PRIVATE_KEY));
- when(sharedPreferences.getString(eq(Provider.CA_CERT), anyString())).thenReturn(secrets.getString(Provider.CA_CERT));
- when(sharedPreferences.getString(eq(Constants.PROVIDER_VPN_CERTIFICATE), anyString())).thenReturn(secrets.getString(Constants.PROVIDER_VPN_CERTIFICATE));
-
+ @Test
+ public void testFromEipServiceJson_ignoreGatewaysWithMisconfiguredTransportsWhileAddingValidOnes() throws Exception {
+ updateEipServiceJson("ptdemo_misconfigured_mixed_gateways.json");
+ gatewaysManager = new GatewaysManager(mockContext, sharedPreferences);
+ assertEquals(1, gatewaysManager.size());
+ assertNull(gatewaysManager.select(0).getProfile(OBFS4));
+ assertNotNull(gatewaysManager.select(0).getProfile(Connection.TransportType.OPENVPN));
+ }
+ @Test
+ public void testClearGatewaysAndProfiles_resetGateways() throws Exception {
+ updateEipServiceJson("eip-service-two-gateways.json");
gatewaysManager = new GatewaysManager(mockContext, sharedPreferences);
+ assertEquals(2, gatewaysManager.size());
+ gatewaysManager.clearGateways();
+ assertEquals(0, gatewaysManager.size());
}
@Test
- public void testFromEipServiceJson_emptyJson() throws Exception {
- gatewaysManager.fromEipServiceJson(new JSONObject());
- assertEquals(0, gatewaysManager.size());
+ public void testGatewayManagerFromCurrentProvider_noProvider_noGateways() {
+ gatewaysManager = new GatewaysManager(mockContext);
+ assertEquals(0, gatewaysManager.size());
}
@Test
- public void testFromEipServiceJson_ignoreDuplicateGateways_apiv3() throws Exception {
- String eipServiceJson = TestSetupHelper.getInputAsString(getClass().getClassLoader().getResourceAsStream("ptdemo_three_mixed_gateways.json"));
- gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson));
- assertEquals(3, gatewaysManager.size());
- eipServiceJson = TestSetupHelper.getInputAsString(getClass().getClassLoader().getResourceAsStream("ptdemo.bitmask.eip-service.json"));
- gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson));
+ public void testGatewayManagerFromCurrentProvider_misconfiguredProvider_noGateways() throws IOException, NullPointerException {
+ Provider provider = getProvider(null, null, null, "ptdemo_misconfigured_gateway.json");
+ MockHelper.mockProviderObserver(provider);
+ gatewaysManager = new GatewaysManager(mockContext);
+ assertEquals(0, gatewaysManager.size());
+ }
+
+ @Test
+ public void testGatewayManagerFromCurrentProvider_threeGateways() {
+ Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ MockHelper.mockProviderObserver(provider);
+ gatewaysManager = new GatewaysManager(mockContext);
assertEquals(3, gatewaysManager.size());
}
@Test
- public void testFromEipServiceJson_ignoreGatewaysWithMisconfiguredTransportsWhileAddingValidOnes() throws Exception {
- String eipServiceJson = TestSetupHelper.getInputAsString(getClass().getClassLoader().getResourceAsStream("ptdemo_misconfigured_mixed_gateways.json"));
- gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson));
- assertEquals(1, gatewaysManager.size());
- assertNull(gatewaysManager.select(0).getProfile(Connection.TransportType.OBFS4));
- assertNotNull(gatewaysManager.select(0).getProfile(Connection.TransportType.OPENVPN));
+ public void TestGetPosition_VpnProfileExtistingObfs4_returnPositionZero() throws JSONException, ConfigParser.ConfigParseError, IOException {
+ Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ JSONObject eipServiceJson = provider.getEipServiceJson();
+ JSONObject gateway1 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(0);
+ MockHelper.mockProviderObserver(provider);
+ mockStatic(PreferenceHelper.class);
+ when(PreferenceHelper.getUsePluggableTransports(any(Context.class))).thenReturn(true);
+ gatewaysManager = new GatewaysManager(mockContext);
+
+ VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, 3);
+ VpnProfile profile = configGenerator.createProfile(OBFS4);
+ profile.mGatewayIp = "37.218.247.60";
+
+ assertEquals(0, gatewaysManager.getPosition(profile));
}
@Test
- public void testFromEipServiceJson_ignoreDuplicateGateways() throws Exception {
- String eipServiceJson = TestSetupHelper.getInputAsString(getClass().getClassLoader().getResourceAsStream("eip-service-two-gateways.json"));
- gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson));
- assertEquals(2, gatewaysManager.size());
- eipServiceJson = TestSetupHelper.getInputAsString(getClass().getClassLoader().getResourceAsStream("eip-service-one-gateway.json"));
- gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson));
- assertEquals(2, gatewaysManager.size());
+ public void TestGetPosition_VpnProfileExtistingOpenvpn_returnPositionZero() throws JSONException, ConfigParser.ConfigParseError, IOException {
+ Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ JSONObject eipServiceJson = provider.getEipServiceJson();
+ JSONObject gateway1 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(0);
+ MockHelper.mockProviderObserver(provider);
+ mockStatic(PreferenceHelper.class);
+ when(PreferenceHelper.getUsePluggableTransports(any(Context.class))).thenReturn(false);
+ gatewaysManager = new GatewaysManager(mockContext);
+
+ VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, 3);
+ VpnProfile profile = configGenerator.createProfile(OPENVPN);
+ profile.mGatewayIp = "37.218.247.60";
+
+ assertEquals(0, gatewaysManager.getPosition(profile));
}
@Test
- public void testClearGatewaysAndProfiles_resetGateways() throws Exception {
- String eipServiceJson = TestSetupHelper.getInputAsString(getClass().getClassLoader().getResourceAsStream("eip-service-two-gateways.json"));
- gatewaysManager.fromEipServiceJson(new JSONObject(eipServiceJson));
- assertEquals(2, gatewaysManager.size());
- gatewaysManager.clearGateways();
- assertEquals(0, gatewaysManager.size());
+ public void TestGetPosition_VpnProfileDifferentIp_returnMinusOne() throws JSONException, ConfigParser.ConfigParseError, IOException {
+ Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ JSONObject eipServiceJson = provider.getEipServiceJson();
+ JSONObject gateway1 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(0);
+ MockHelper.mockProviderObserver(provider);
+ mockStatic(PreferenceHelper.class);
+ when(PreferenceHelper.getUsePluggableTransports(any(Context.class))).thenReturn(true);
+ gatewaysManager = new GatewaysManager(mockContext);
+
+ VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, 3);
+ VpnProfile profile = configGenerator.createProfile(OBFS4);
+ profile.mGatewayIp = "37.218.247.61";
+
+ assertEquals(-1, gatewaysManager.getPosition(profile));
+ }
+
+ @Test
+ public void TestGetPosition_VpnProfileMoscow_returnOne() throws JSONException, ConfigParser.ConfigParseError, IOException {
+ Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ JSONObject eipServiceJson = provider.getEipServiceJson();
+ JSONObject gateway1 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(1);
+ MockHelper.mockProviderObserver(provider);
+ mockStatic(PreferenceHelper.class);
+ when(PreferenceHelper.getUsePluggableTransports(any(Context.class))).thenReturn(true);
+ gatewaysManager = new GatewaysManager(mockContext);
+
+ VpnConfigGenerator configGenerator = new VpnConfigGenerator(provider.getDefinition(), secrets, gateway1, 3);
+ VpnProfile profile = configGenerator.createProfile(OBFS4);
+ profile.mGatewayIp = "3.21.247.89";
+
+ assertEquals(1, gatewaysManager.getPosition(profile));
+ }
+
+ @Test
+ public void TestSelectN_selectFirstObfs4Connection_returnThirdGateway() throws JSONException, ConfigParser.ConfigParseError, IOException {
+ Provider provider = getProvider(null, null, null, "ptdemo_two_openvpn_one_pt_gateways.json");
+ JSONObject eipServiceJson = provider.getEipServiceJson();
+ JSONObject gateway3 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(2);
+
+ MockHelper.mockProviderObserver(provider);
+ mockStatic(PreferenceHelper.class);
+ when(PreferenceHelper.getUsePluggableTransports(any(Context.class))).thenReturn(true);
+ gatewaysManager = new GatewaysManager(mockContext);
+
+ assertEquals("37.12.247.10", gatewaysManager.select(0).getRemoteIP());
}
private String getJsonStringFor(String filename) throws IOException {
return TestSetupHelper.getInputAsString(getClass().getClassLoader().getResourceAsStream(filename));
}
+ private void updateEipServiceJson(String filename) throws IOException {
+ String eipServiceJson = getJsonStringFor(filename);
+ sharedPreferences.edit().putString(PROVIDER_EIP_DEFINITION, eipServiceJson).commit();
+ }
} \ No newline at end of file
diff --git a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
index 24801b58..481c87cb 100644
--- a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
+++ b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
@@ -35,6 +35,7 @@ import java.util.Set;
import okhttp3.OkHttpClient;
import se.leap.bitmaskclient.OkHttpClientGenerator;
import se.leap.bitmaskclient.Provider;
+import se.leap.bitmaskclient.ProviderObservable;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.testutils.BackendMockResponses.BackendMockProvider;
import se.leap.bitmaskclient.testutils.matchers.BundleMatcher;
@@ -58,6 +59,7 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.utils.FileHelper.createFile;
+import static se.leap.bitmaskclient.utils.PreferenceHelper.getEipDefinitionFromPreferences;
import static se.leap.bitmaskclient.utils.PreferenceHelper.getFromPersistedProvider;
/**
@@ -402,6 +404,24 @@ public class MockHelper {
});
}
+ public static void mockPreferenceHelper(MockSharedPreferences preferences) {
+ mockStatic(PreferenceHelper.class);
+
+ when(getEipDefinitionFromPreferences(any(SharedPreferences.class))).thenAnswer(new Answer<JSONObject>() {
+ @Override
+ public JSONObject answer(InvocationOnMock invocation) throws Throwable {
+ return getEipDefinitionFromPreferences(preferences);
+ }
+ });
+ }
+
+ public static void mockProviderObserver(Provider provider) {
+ ProviderObservable observable = ProviderObservable.getInstance();
+ observable.updateProvider(provider);
+ mockStatic(ProviderObservable.class);
+ when(ProviderObservable.getInstance()).thenAnswer((Answer<ProviderObservable>) invocation -> observable);
+ }
+
public static void mockFingerprintForCertificate(String mockedFingerprint) throws CertificateEncodingException, NoSuchAlgorithmException {
mockStatic(ConfigHelper.class);
when(ConfigHelper.getFingerprintFromCertificate(any(X509Certificate.class), anyString())).thenReturn(mockedFingerprint);
diff --git a/app/src/test/resources/ptdemo_misconfigured_gateway.json b/app/src/test/resources/ptdemo_misconfigured_gateway.json
index 8308157d..38008880 100644
--- a/app/src/test/resources/ptdemo_misconfigured_gateway.json
+++ b/app/src/test/resources/ptdemo_misconfigured_gateway.json
@@ -18,15 +18,6 @@
"cert": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX2",
"iat-mode": "0"
}
- },
- {
- "type":"openvpn",
- "protocols":[
- "tcp"
- ],
- "ports":[
- "1195"
- ]
}
],
"user_ips":false
@@ -34,29 +25,6 @@
"host":"moscow.bitmask.net",
"ip_address":"3.21.247.89",
"location":"moscow"
- },
- {
- "capabilities":{
- "adblock":false,
- "filter_dns":false,
- "limited":false,
- "transport":[
- {
- "type":"openvpn",
- "protocols":[
- "tcp",
- "udp"
- ],
- "ports":[
- "1195"
- ]
- }
- ],
- "user_ips":false
- },
- "host":"manila.bitmask.net",
- "ip_address":"37.12.247.10",
- "location":"manila"
}
],
"locations":{
@@ -65,12 +33,6 @@
"hemisphere":"N",
"name":"Amsterdam",
"timezone":"-1"
- },
- "moscow": {
- "country_code": "RU",
- "hemisphere": "N",
- "name": "Moscow",
- "timezone": "+3"
}
},
"openvpn_configuration":{