mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 14:49:53 +01:00
Start work on an integration test
This commit is contained in:
@@ -6,7 +6,6 @@ import android.net.wifi.WifiInfo;
|
|||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.Pair;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
@@ -16,16 +15,13 @@ import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
|||||||
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InterfaceAddress;
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
@@ -36,7 +32,8 @@ import static java.util.logging.Level.INFO;
|
|||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class OwnerReturnShardViewModel extends AndroidViewModel implements SecretOwnerTask.Observer {
|
class OwnerReturnShardViewModel extends AndroidViewModel
|
||||||
|
implements SecretOwnerTask.Observer {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(OwnerReturnShardViewModel.class.getName());
|
getLogger(OwnerReturnShardViewModel.class.getName());
|
||||||
@@ -123,6 +120,8 @@ class OwnerReturnShardViewModel extends AndroidViewModel implements SecretOwnerT
|
|||||||
@UiThread
|
@UiThread
|
||||||
private void startListening() {
|
private void startListening() {
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
|
task.cancel();
|
||||||
|
// wait until really cancelled
|
||||||
task.start(this, getWifiIpv4Address());
|
task.start(this, getWifiIpv4Address());
|
||||||
});
|
});
|
||||||
// KeyAgreementTask oldTask = task;
|
// KeyAgreementTask oldTask = task;
|
||||||
@@ -142,8 +141,6 @@ class OwnerReturnShardViewModel extends AndroidViewModel implements SecretOwnerT
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to true in onPostResume() and false in onPause(). This prevents the
|
* Set to true in onPostResume() and false in onPause(). This prevents the
|
||||||
* QR code fragment from being shown if onRequestPermissionsResult() is
|
* QR code fragment from being shown if onRequestPermissionsResult() is
|
||||||
@@ -175,9 +172,11 @@ class OwnerReturnShardViewModel extends AndroidViewModel implements SecretOwnerT
|
|||||||
public void onStateChanged(SecretOwnerTask.State state) {
|
public void onStateChanged(SecretOwnerTask.State state) {
|
||||||
this.state.postValue(state);
|
this.state.postValue(state);
|
||||||
if (state instanceof SecretOwnerTask.State.Listening) {
|
if (state instanceof SecretOwnerTask.State.Listening) {
|
||||||
DisplayMetrics dm = getApplication().getResources().getDisplayMetrics();
|
DisplayMetrics dm =
|
||||||
|
getApplication().getResources().getDisplayMetrics();
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
byte[] payloadBytes = ((SecretOwnerTask.State.Listening) state).getLocalPayload();
|
byte[] payloadBytes = ((SecretOwnerTask.State.Listening) state)
|
||||||
|
.getLocalPayload();
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Local payload is " + payloadBytes.length
|
LOG.info("Local payload is " + payloadBytes.length
|
||||||
+ " bytes");
|
+ " bytes");
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ public class CustodianTaskImpl extends ReturnShardTaskImpl
|
|||||||
private void connectAndSendShard() {
|
private void connectAndSendShard() {
|
||||||
observer.onStateChanged(new CustodianTask.State.SendingShard());
|
observer.onStateChanged(new CustodianTask.State.SendingShard());
|
||||||
try {
|
try {
|
||||||
|
LOG.info("Connecting to secret owner " + remoteSocketAddress);
|
||||||
socket.connect(remoteSocketAddress, TIMEOUT);
|
socket.connect(remoteSocketAddress, TIMEOUT);
|
||||||
LOG.info("Connected to secret owner " + remoteSocketAddress);
|
LOG.info("Connected to secret owner " + remoteSocketAddress);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|||||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
@@ -35,7 +36,8 @@ public class ReturnShardTaskImpl {
|
|||||||
return nonce;
|
return nonce;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deriveSharedSecret(AgreementPublicKey remotePublicKey, byte[] context) throws
|
void deriveSharedSecret(AgreementPublicKey remotePublicKey, byte[] context)
|
||||||
|
throws
|
||||||
GeneralSecurityException {
|
GeneralSecurityException {
|
||||||
sharedSecret =
|
sharedSecret =
|
||||||
crypto.deriveSharedSecret("ShardReturn", remotePublicKey,
|
crypto.deriveSharedSecret("ShardReturn", remotePublicKey,
|
||||||
@@ -60,9 +62,9 @@ public class ReturnShardTaskImpl {
|
|||||||
|
|
||||||
byte[] read(InputStream inputStream, int length)
|
byte[] read(InputStream inputStream, int length)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
DataInputStream dis = new DataInputStream(inputStream);
|
||||||
byte[] output = new byte[length];
|
byte[] output = new byte[length];
|
||||||
int bytesRead = inputStream.read(output);
|
dis.readFully(output);
|
||||||
if (bytesRead < 0) throw new IOException("Cannot read from socket");
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,13 @@ import org.briarproject.bramble.api.client.ClientHelper;
|
|||||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||||
import org.briarproject.bramble.api.crypto.AuthenticatedCipher;
|
import org.briarproject.bramble.api.crypto.AuthenticatedCipher;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
@@ -64,8 +63,10 @@ public class SecretOwnerTaskImpl extends ReturnShardTaskImpl
|
|||||||
|
|
||||||
// Start listening on socketAddress
|
// Start listening on socketAddress
|
||||||
try {
|
try {
|
||||||
|
LOG.info("Binding socket");
|
||||||
serverSocket = new ServerSocket();
|
serverSocket = new ServerSocket();
|
||||||
serverSocket.bind(socketAddress);
|
serverSocket.bind(socketAddress);
|
||||||
|
LOG.info("Binding socket done");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.warning(
|
LOG.warning(
|
||||||
"IO Error when listening on local socket" + e.getMessage());
|
"IO Error when listening on local socket" + e.getMessage());
|
||||||
@@ -80,18 +81,22 @@ public class SecretOwnerTaskImpl extends ReturnShardTaskImpl
|
|||||||
payloadList.add(localKeyPair.getPublic().getEncoded());
|
payloadList.add(localKeyPair.getPublic().getEncoded());
|
||||||
payloadList.add(socketAddress.getAddress().getAddress());
|
payloadList.add(socketAddress.getAddress().getAddress());
|
||||||
payloadList.add(socketAddress.getPort());
|
payloadList.add(socketAddress.getPort());
|
||||||
|
LOG.info("changing state to listening");
|
||||||
observer.onStateChanged(
|
observer.onStateChanged(
|
||||||
new State.Listening(clientHelper.toByteArray(payloadList)));
|
new State.Listening(clientHelper.toByteArray(payloadList)));
|
||||||
|
LOG.info("changing state to listening done");
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
LOG.warning("Error encoding QR code");
|
LOG.warning("Error encoding QR code");
|
||||||
observer.onStateChanged(new State.Failure());
|
observer.onStateChanged(new State.Failure());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
LOG.info("receiving payload");
|
||||||
receivePayload();
|
receivePayload();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void receivePayload() {
|
private void receivePayload() {
|
||||||
try {
|
try {
|
||||||
|
LOG.info("Accepting connections");
|
||||||
socket = serverSocket.accept();
|
socket = serverSocket.accept();
|
||||||
LOG.info("Client connected");
|
LOG.info("Client connected");
|
||||||
observer.onStateChanged(new State.ReceivingShard());
|
observer.onStateChanged(new State.ReceivingShard());
|
||||||
@@ -125,7 +130,8 @@ public class SecretOwnerTaskImpl extends ReturnShardTaskImpl
|
|||||||
// StreamWriter streamWriter = streamWriterFactory.createContactExchangeStreamWriter(socket.getOutputStream(), sharedSecret);
|
// StreamWriter streamWriter = streamWriterFactory.createContactExchangeStreamWriter(socket.getOutputStream(), sharedSecret);
|
||||||
// OutputStream outputStream = streamWriter.getOutputStream();
|
// OutputStream outputStream = streamWriter.getOutputStream();
|
||||||
|
|
||||||
OutputStream outputStream = socket.getOutputStream();
|
DataOutputStream outputStream =
|
||||||
|
new DataOutputStream(socket.getOutputStream());
|
||||||
byte[] ackNonce = generateNonce();
|
byte[] ackNonce = generateNonce();
|
||||||
outputStream.write(ackNonce);
|
outputStream.write(ackNonce);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
package org.briarproject.briar.socialbackup.recovery;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
|
import org.briarproject.bramble.test.TestDatabaseConfigModule;
|
||||||
|
import org.briarproject.briar.api.socialbackup.recovery.CustodianTask;
|
||||||
|
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.fail;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class ReturnShardIntegrationTest extends BrambleTestCase {
|
||||||
|
|
||||||
|
private final File testDir = getTestDirectory();
|
||||||
|
private final File ownerDir = new File(testDir, "owner");
|
||||||
|
private final File custodianDir = new File(testDir, "custodian");
|
||||||
|
|
||||||
|
private ReturnShardIntegrationTestComponent owner, custodian;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
assertTrue(testDir.mkdirs());
|
||||||
|
// Create the devices
|
||||||
|
owner = DaggerReturnShardIntegrationTestComponent.builder()
|
||||||
|
.testDatabaseConfigModule(
|
||||||
|
new TestDatabaseConfigModule(ownerDir)).build();
|
||||||
|
BrambleCoreIntegrationTestEagerSingletons.Helper
|
||||||
|
.injectEagerSingletons(owner);
|
||||||
|
custodian = DaggerReturnShardIntegrationTestComponent.builder()
|
||||||
|
.testDatabaseConfigModule(new TestDatabaseConfigModule(
|
||||||
|
custodianDir))
|
||||||
|
.build();
|
||||||
|
BrambleCoreIntegrationTestEagerSingletons.Helper
|
||||||
|
.injectEagerSingletons(custodian);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReturnShard() {
|
||||||
|
SecretOwnerTask secretOwnerTask = owner.getSecretOwnerTask();
|
||||||
|
CustodianTask custodianTask = custodian.getCustodianTask();
|
||||||
|
|
||||||
|
SecretOwnerTask.Observer ownerObserver =
|
||||||
|
state -> {
|
||||||
|
if (state instanceof SecretOwnerTask.State.Listening) {
|
||||||
|
SecretOwnerTask.State.Listening listening =
|
||||||
|
(SecretOwnerTask.State.Listening) state;
|
||||||
|
byte[] payload = listening.getLocalPayload();
|
||||||
|
System.out.println(payload.length);
|
||||||
|
tansferQrCode(custodianTask, payload);
|
||||||
|
} else if (state instanceof SecretOwnerTask.State.Failure) {
|
||||||
|
System.out.println("owner state: failure");
|
||||||
|
fail();
|
||||||
|
} else {
|
||||||
|
System.out.println(
|
||||||
|
"owner: " + state.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CustodianTask.Observer custodianObserver =
|
||||||
|
state -> System.out.println(
|
||||||
|
"custodian: " + state.getClass().getSimpleName());
|
||||||
|
|
||||||
|
owner.getIoExecutor().execute(() -> {
|
||||||
|
try {
|
||||||
|
secretOwnerTask
|
||||||
|
.start(ownerObserver, InetAddress.getLocalHost());
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
custodian.getIoExecutor().execute(() -> {
|
||||||
|
try {
|
||||||
|
custodianTask.start(custodianObserver);
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tansferQrCode(CustodianTask custodianTask, byte[] payload) {
|
||||||
|
System.out.println("Calling qrCodeDecoded in executor()");
|
||||||
|
custodian.getIoExecutor().execute(() -> {
|
||||||
|
try {
|
||||||
|
System.out.println("Calling qrCodeDecoded()");
|
||||||
|
Thread.sleep(500);
|
||||||
|
custodianTask.qrCodeDecoded(payload);
|
||||||
|
System.out.println("qrCodeDecoded() done");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tearDown(ReturnShardIntegrationTestComponent device)
|
||||||
|
throws Exception {
|
||||||
|
// Stop the lifecycle manager
|
||||||
|
LifecycleManager lifecycleManager = device.getLifecycleManager();
|
||||||
|
lifecycleManager.stopServices();
|
||||||
|
lifecycleManager.waitForShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
tearDown(owner);
|
||||||
|
tearDown(custodian);
|
||||||
|
deleteTestDirectory(testDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.briarproject.briar.socialbackup.recovery;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
|
||||||
|
import org.briarproject.bramble.BrambleCoreModule;
|
||||||
|
import org.briarproject.bramble.api.connection.ConnectionManager;
|
||||||
|
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
||||||
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule;
|
||||||
|
import org.briarproject.briar.api.socialbackup.recovery.CustodianTask;
|
||||||
|
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
||||||
|
import org.briarproject.briar.socialbackup.SocialBackupModule;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.Component;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Component(modules = {
|
||||||
|
BrambleCoreIntegrationTestModule.class,
|
||||||
|
BrambleCoreModule.class,
|
||||||
|
SocialBackupModule.class
|
||||||
|
})
|
||||||
|
interface ReturnShardIntegrationTestComponent
|
||||||
|
extends BrambleCoreIntegrationTestEagerSingletons {
|
||||||
|
|
||||||
|
ConnectionManager getConnectionManager();
|
||||||
|
|
||||||
|
ContactExchangeManager getContactExchangeManager();
|
||||||
|
|
||||||
|
ContactManager getContactManager();
|
||||||
|
|
||||||
|
EventBus getEventBus();
|
||||||
|
|
||||||
|
IdentityManager getIdentityManager();
|
||||||
|
|
||||||
|
@IoExecutor
|
||||||
|
Executor getIoExecutor();
|
||||||
|
|
||||||
|
LifecycleManager getLifecycleManager();
|
||||||
|
|
||||||
|
SecretOwnerTask getSecretOwnerTask();
|
||||||
|
|
||||||
|
CustodianTask getCustodianTask();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user