2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-31 06:05:12 +00:00

Corrected unit tests

Settings were not save properly when certificate was null
Removed LanLinkProvider test, impossible with new design
This commit is contained in:
Vineet Garg
2015-06-21 17:30:29 +05:30
parent 7be045e7c4
commit 00557052ff
9 changed files with 155 additions and 378 deletions

View File

@@ -196,7 +196,6 @@ public class LanLink extends BaseLink {
InetSocketAddress address = (InetSocketAddress)channel.remoteAddress();
socket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
np.setPayload(socket.getInputStream(), np.getPayloadSize());
Log.e("KDE/LanLink", "Has payload ");
} catch (Exception e) {
try { socket.close(); } catch(Exception ignored) { }
e.printStackTrace();
@@ -208,8 +207,8 @@ public class LanLink extends BaseLink {
packageReceived(np);
}
static ServerSocket openTcpSocketOnFreePort(Context context, String deviceId, boolean onSsl) throws IOException {
if (onSsl) {
static ServerSocket openTcpSocketOnFreePort(Context context, String deviceId, boolean useSsl) throws IOException {
if (useSsl) {
return openSecureServerSocket(context, deviceId);
} else {
return openUnsecureSocketOnFreePort();

View File

@@ -85,17 +85,12 @@ public class LanLinkProvider extends BaseLinkProvider {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
// TODO : Add necessary action on ssl handshake failure
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Log.e("KDE/LanLinkProvider", "Channel Active : " + ctx.channel().hashCode());
// If certificate changed, getting SocketException, connection reset by peer
// Ssl engines closes by itself, so do channel and link is removed
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Log.e("KDE/LanLinkProvider", "Channel In active :" + ctx.channel().hashCode());
try {
long id = ctx.channel().hashCode();
final LanLink brokenLink = nioLinks.get(id);
@@ -131,9 +126,9 @@ public class LanLinkProvider extends BaseLinkProvider {
}).start();
}
} catch (Exception e) { //If we don't catch it here, Mina will swallow it :/
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/LanLinkProvider", "sessionClosed exception");
Log.e("KDE/LanLinkProvider", "channelInactive exception");
}
}
@@ -150,7 +145,6 @@ public class LanLinkProvider extends BaseLinkProvider {
}
final NetworkPackage np = NetworkPackage.unserialize(theMessage);
Log.e("KDE/LanLinkProvider", theMessage);
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
@@ -165,8 +159,7 @@ public class LanLinkProvider extends BaseLinkProvider {
nioLinks.put(ctx.channel().hashCode(), link);
//Log.i("KDE/LanLinkProvider","nioLinks.size(): " + nioLinks.size());
// Check if ssl supported, and add ssl handler
// Sslengine is returning null in some cases
// Check if ssl supported on other device and enabled on my device, and add ssl handler
try {
if (myIdentityPackage.getBoolean("sslSupported") && np.getBoolean("sslSupported", false)) {
Log.e("KDE/LanLinkProvider", "Remote device " + np.getString("deviceName") + " supports ssl");
@@ -190,7 +183,7 @@ public class LanLinkProvider extends BaseLinkProvider {
}
} catch (Exception e) {
e.printStackTrace();
addLink(np, link); // If error in ssl engine, which is returning null in some cases
addLink(np, link); // If exception getting ssl engine
}
} else {
@@ -211,7 +204,6 @@ public class LanLinkProvider extends BaseLinkProvider {
protected void channelRead0(final ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
try {
String theMessage = packet.content().toString(CharsetUtil.UTF_8);
Log.e("KDE/LanLinkProvider", "Udp message received : " + theMessage);
final NetworkPackage identityPackage = NetworkPackage.unserialize(theMessage);
@@ -221,7 +213,6 @@ public class LanLinkProvider extends BaseLinkProvider {
} else {
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
if (identityPackage.getString("deviceId").equals(myId)) {
Log.e("KDE/LanLinkProvider", "Oh, its my identity package");
return;
}
}

View File

@@ -28,7 +28,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
@@ -305,17 +304,19 @@ public class Device implements BaseLink.PackageReceiver {
preferences.edit().putBoolean(deviceId,true).apply();
//Store device information needed to create a Device object in a future
SharedPreferences.Editor editor = settings.edit();
try {
SharedPreferences.Editor editor = settings.edit();
editor.putString("deviceName", getName());
editor.putString("deviceType", deviceType.toString());
String encodedPublicKey = Base64.encodeToString(publicKey.getEncoded(), 0);
editor.putString("publicKey", encodedPublicKey);
String encodedCertificate = Base64.encodeToString(certificate.getEncoded(), 0);
editor.putString("certificate", encodedCertificate);
editor.apply();
} catch (Exception e){
Log.e("KDE/Device", "Exception pairing done");
e.printStackTrace();
} finally {
editor.apply();
}
reloadPluginsFromSettings();

View File

@@ -26,7 +26,6 @@ import android.preference.PreferenceManager;
import android.util.Base64;
import android.util.Log;
import org.apache.mina.filter.ssl.SslFilter;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.cert.X509CertificateHolder;
@@ -45,7 +44,6 @@ import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
@@ -53,9 +51,6 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import io.netty.handler.ssl.SslContext;
public class SslHelper {
public enum SslMode{
@@ -214,70 +209,4 @@ public class SslHelper {
}
return null;
}
// TODO : Remove this method, and use the above one, since it trusts all certificates
public static SslFilter getTrustAllCertsFilter(Context context, SslMode sslMode){
try{
// Get device private key
PrivateKey privateKey = RsaHelper.getPrivateKey(context);
// Get my certificate
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(context);
byte[] myCertificateBytes = Base64.decode(globalSettings.getString("certificate", ""), 0);
X509CertificateHolder myCertificateHolder = new X509CertificateHolder(myCertificateBytes);
X509Certificate myCertificate = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(myCertificateHolder);
// Setup keystore
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setKeyEntry("key", privateKey, "".toCharArray(), new java.security.cert.Certificate[]{myCertificate});;
// Setup key manager factory
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "".toCharArray());
// Setup default trust manager
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
// Setup custom trust manager if device not trusted
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// TODO : if device trusted, set need client auth
SSLContext tlsContext = SSLContext.getInstance("TLS");
tlsContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new SecureRandom());
SslFilter filter = new SslFilter(tlsContext,true);
if (sslMode == SslMode.Client){
filter.setUseClientMode(true);
}else{
filter.setUseClientMode(false);
filter.setWantClientAuth(true);
}
return filter;
}catch (Exception e){
e.printStackTrace();
Log.e("SslHelper", "Error creating ssl filter");
}
return null;
}
}

View File

@@ -25,11 +25,9 @@ import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.kde.kdeconnect.BackgroundService;
@@ -145,7 +143,6 @@ public class PairActivity extends ActionBarActivity {
public void onClick(View view) {
pairButton.setVisibility(View.GONE);
((TextView) findViewById(R.id.pair_message)).setText("");
findViewById(R.id.secret_keys).setVisibility(View.GONE);
findViewById(R.id.pair_progress).setVisibility(View.VISIBLE);
BackgroundService.RunCommand(PairActivity.this, new BackgroundService.InstanceCallback() {
@Override

View File

@@ -26,13 +26,24 @@ import android.test.AndroidTestCase;
import android.util.Base64;
import android.util.Log;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
import org.mockito.Mockito;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.cert.X509Certificate;
import java.util.Date;
public class DeviceTest extends AndroidTestCase {
@@ -140,6 +151,8 @@ public class DeviceTest extends AndroidTestCase {
assertEquals(device.getDeviceId(), "unpairedTestDevice");
assertEquals(device.getName(), "Unpaired Test Device");
assertEquals(device.getDeviceType(), Device.DeviceType.Phone);
assertNotNull(device.publicKey);
assertNull(device.certificate);
Method method;
try {
@@ -166,6 +179,90 @@ public class DeviceTest extends AndroidTestCase {
}
public void testPairingDoneWithCertificate() throws Exception{
KeyPair keyPair = null;
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
keyPair = keyGen.genKeyPair();
} catch(Exception e) {
e.printStackTrace();
Log.e("KDE/initializeRsaKeys", "Exception");
}
X509Certificate certificate = null;
try {
BouncyCastleProvider BC = new BouncyCastleProvider();
X500NameBuilder nameBuilder = new X500NameBuilder(BCStyle.INSTANCE);
nameBuilder.addRDN(BCStyle.CN, "testDevice");
nameBuilder.addRDN(BCStyle.OU, "KDE Connect");
nameBuilder.addRDN(BCStyle.O, "KDE");
Date notBefore = new Date(System.currentTimeMillis());
Date notAfter = new Date(System.currentTimeMillis() + System.currentTimeMillis());
X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(
nameBuilder.build(),
BigInteger.ONE,
notBefore,
notAfter,
nameBuilder.build(),
keyPair.getPublic()
);
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(keyPair.getPrivate());
certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateBuilder.build(contentSigner));
} catch(Exception e) {
e.printStackTrace();
Log.e("KDE/initialiseCertificate", "Exception");
}
NetworkPackage fakeNetworkPackage = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_IDENTITY);
fakeNetworkPackage.set("deviceId", "unpairedTestDevice");
fakeNetworkPackage.set("deviceName", "Unpaired Test Device");
fakeNetworkPackage.set("protocolVersion", NetworkPackage.ProtocolVersion);
fakeNetworkPackage.set("deviceType", Device.DeviceType.Phone.toString());
fakeNetworkPackage.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
LanLinkProvider linkProvider = Mockito.mock(LanLinkProvider.class);
Mockito.when(linkProvider.getName()).thenReturn("LanLinkProvider");
LanLink link = Mockito.mock(LanLink.class);
Mockito.when(link.getLinkProvider()).thenReturn(linkProvider);
Device device = new Device(getContext(), fakeNetworkPackage, link);
device.publicKey = keyPair.getPublic();
assertNotNull(device);
assertEquals(device.getDeviceId(), "unpairedTestDevice");
assertEquals(device.getName(), "Unpaired Test Device");
assertEquals(device.getDeviceType(), Device.DeviceType.Phone);
assertNotNull(device.publicKey);
assertNotNull(device.certificate);
Method method;
try {
method = Device.class.getDeclaredMethod("pairingDone");
method.setAccessible(true);
method.invoke(device);
}catch (Exception e){
e.printStackTrace();
}
assertEquals(device.isPaired(), true);
SharedPreferences preferences = getContext().getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
assertEquals(preferences.getBoolean(device.getDeviceId(), false), true);
SharedPreferences settings = getContext().getSharedPreferences(device.getDeviceId(),Context.MODE_PRIVATE);
assertEquals(settings.getString("deviceName", "Unknown device"), "Unpaired Test Device");
assertEquals(settings.getString("deviceType", "tablet"), "phone");
assertEquals(settings.getString("publicKey", ""), Base64.encodeToString(keyPair.getPublic().getEncoded(), 0));
assertEquals(settings.getString("certificate", ""), Base64.encodeToString(certificate.getEncoded(), 0));;
// Cleanup for unpaired test device
preferences.edit().remove(device.getDeviceId()).apply();
settings.edit().clear().apply();
}
public void testUnpair(){
Device device = new Device(getContext(), "testDevice");

View File

@@ -1,250 +0,0 @@
/*
* Copyright 2015 Vineet Garg <grg.vineet@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect;
import android.support.v4.util.LongSparseArray;
import android.test.AndroidTestCase;
import android.util.Log;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
public class LanLinkProviderTest extends AndroidTestCase {
private NioSocketAcceptor tcpAcceptor = null;
private NioDatagramAcceptor udpAcceptor = null;
private LanLinkProvider linkProvider;
@Override
protected void setUp() throws Exception {
super.setUp();
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().getPath());
linkProvider = new LanLinkProvider(getContext());
try {
Field field = LanLinkProvider.class.getDeclaredField("tcpAcceptor");
field.setAccessible(true);
tcpAcceptor = (NioSocketAcceptor)field.get(linkProvider);
assertNotNull(tcpAcceptor);
}catch (Exception e){
fail("Error getting tcpAcceptor from LanLinkProvider");
}
try{
Field field = LanLinkProvider.class.getDeclaredField("udpAcceptor");
field.setAccessible(true);
udpAcceptor = (NioDatagramAcceptor)field.get(linkProvider);
assertNotNull(udpAcceptor);
}catch (Exception e){
fail("Error getting udp acceptor from LanLinkProvider");
}
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
tcpAcceptor.dispose();
udpAcceptor.dispose();
}
public void testTcpAcceptor(){
assertNotNull(tcpAcceptor.getHandler());
assertEquals(tcpAcceptor.getSessionConfig().isKeepAlive(), true);
assertEquals(tcpAcceptor.getSessionConfig().isReuseAddress(), true);
assertNotNull(tcpAcceptor.getFilterChain().get("codec"));
}
public void testUdpAcceptor(){
assertNull(udpAcceptor.getHandler());
assertEquals(udpAcceptor.getSessionConfig().isReuseAddress(), true);
assertNotNull(udpAcceptor.getFilterChain().get("codec"));
}
public void testOnStart() throws Exception{
IoSession session = Mockito.mock(IoSession.class);
Mockito.when(session.getId()).thenReturn(12345l);
Mockito.when(session.getRemoteAddress()).thenReturn(new InetSocketAddress(5000));
linkProvider.onStart();
assertNotNull(udpAcceptor.getHandler());
assertEquals(udpAcceptor.getLocalAddress().getPort(), 1714);
}
public void testUdpPackageReceived() throws Exception {
final int port = 5000;
NetworkPackage networkPackage = Mockito.mock(NetworkPackage.class);
Mockito.when(networkPackage.getType()).thenReturn("kdeconnect.identity");
Mockito.when(networkPackage.getString("deviceId")).thenReturn("testDevice");
Mockito.when(networkPackage.getString("deviceName")).thenReturn("Test Device");
Mockito.when(networkPackage.getInt("protocolVersion")).thenReturn(NetworkPackage.ProtocolVersion);
Mockito.when(networkPackage.getString("deviceType")).thenReturn("phone");
Mockito.when(networkPackage.getInt("tcpPort")).thenReturn(port);
final String serialized = "{\"type\":\"kdeconnect.identity\",\"id\":12345,\"body\":{\"deviceName\":\"Test Device\",\"deviceType\":\"phone\",\"deviceId\":\"testDevice\",\"protocolVersion\":5,\"tcpPort\": "+ port +"}}";
Mockito.when(networkPackage.serialize()).thenReturn(serialized);
// Mocking udp session
IoSession session = Mockito.mock(IoSession.class);
Mockito.when(session.getId()).thenReturn(12345l);
Mockito.when(session.getRemoteAddress()).thenReturn(new InetSocketAddress(port));
// Making a server socket, so that original LanLinkProvider can connect to it when it receives our fake package
final ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(port));
final Thread thread = new Thread (new Runnable() {
@Override
public void run() {
try {
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
while (true) {
if (inputStream.available() != 0) {
// Data received from socket should be an identity package
byte[] inputData = new byte[inputStream.available()];
inputStream.read(inputData);
NetworkPackage receivedPackage = NetworkPackage.unserialize(new String(inputData));
NetworkPackage identityPackage = NetworkPackage.createIdentityPackage(getContext());
// If any assertion fails, its output will be in logcat, not on test case thread anymore
assertEquals(receivedPackage.getType(), identityPackage.getType());
assertEquals(receivedPackage.getString("deviceName"), identityPackage.getString("deviceName"));
assertEquals(receivedPackage.getString("deviceId"), identityPackage.getString("deviceId"));
assertEquals(receivedPackage.getInt("protocolVersion"), identityPackage.getInt("protocolVersion"));
serverSocket.close();
// Socket not closed to ensure visibleComputers contains entry for testDevice
break;
}
}
}catch (Exception e){
assertEquals("Exception in thread",1,5);
}
}
});
try {
thread.start();
linkProvider.onStart();
udpAcceptor.getHandler().messageReceived(session, networkPackage.serialize());
}catch (Exception e){
throw e;
}
// Wait 1 secs for our server, and then end test
thread.join(1 * 1000);
// visibleComputers should contain an entry for testDevice
HashMap<String, LanLink> visibleComputers;
try {
Field field = LanLinkProvider.class.getDeclaredField("visibleComputers");
field.setAccessible(true);
visibleComputers = (HashMap<String, LanLink>)field.get(linkProvider);
}catch (Exception e){
throw e;
}
assertNotNull(visibleComputers.get("testDevice"));
}
public void testTcpIdentityPackageReceived() throws Exception{
IoSession session = Mockito.mock(IoSession.class);
Mockito.when(session.getId()).thenReturn(12345l);
NetworkPackage networkPackage = Mockito.mock(NetworkPackage.class);
Mockito.when(networkPackage.getType()).thenReturn("kdeconnect.identity");
Mockito.when(networkPackage.getString("deviceId")).thenReturn("testDevice");
Mockito.when(networkPackage.getString("deviceName")).thenReturn("Test Device");
Mockito.when(networkPackage.getInt("protocolVersion")).thenReturn(NetworkPackage.ProtocolVersion);
Mockito.when(networkPackage.getString("deviceType")).thenReturn("phone");
String serialized = "{\"type\":\"kdeconnect.identity\",\"id\":12345,\"body\":{\"deviceName\":\"Test Device\",\"deviceType\":\"phone\",\"deviceId\":\"testDevice\",\"protocolVersion\":5}}";
Mockito.when(networkPackage.serialize()).thenReturn(serialized);
try {
tcpAcceptor.getHandler().messageReceived(session, networkPackage.serialize());
}catch (Exception e){
throw e;
}
LongSparseArray<LanLink> nioSessions;
try {
Field field = LanLinkProvider.class.getDeclaredField("nioSessions");
field.setAccessible(true);
nioSessions = (LongSparseArray<LanLink>)field.get(linkProvider);
}catch (Exception e){
throw e;
}
assertNotNull(nioSessions.get(12345l));
HashMap<String, LanLink> visibleComputers;
try {
Field field = LanLinkProvider.class.getDeclaredField("visibleComputers");
field.setAccessible(true);
visibleComputers = (HashMap<String, LanLink>)field.get(linkProvider);
}catch (Exception e){
throw e;
}
assertNotNull(visibleComputers.get("testDevice"));
// Testing session closed
try {
tcpAcceptor.getHandler().sessionClosed(session);
}catch (Exception e){
throw e;
}
assertNull(nioSessions.get(12345l));
assertNull(visibleComputers.get("testDevice"));
}
}

View File

@@ -23,8 +23,6 @@ package org.kde.kdeconnect;
import android.test.AndroidTestCase;
import android.util.Log;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IoSession;
import org.json.JSONObject;
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
@@ -34,17 +32,21 @@ import org.mockito.stubbing.Answer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
public class LanLinkTest extends AndroidTestCase {
LanLink lanLink;
IoSession session;
Channel channel;
Device.SendPackageStatusCallback callback;
WriteFuture writeFutureSuccess, writeFutureFailure;
ChannelFuture channelFutureSuccess, channelFutureFailure;
@Override
protected void setUp() throws Exception {
@@ -55,9 +57,10 @@ public class LanLinkTest extends AndroidTestCase {
LanLinkProvider linkProvider = Mockito.mock(LanLinkProvider.class);
Mockito.when(linkProvider.getName()).thenReturn("LanLinkProvider");
session = Mockito.mock(IoSession.class);
Mockito.when(session.getId()).thenReturn(12345l);
Mockito.when(session.getRemoteAddress()).thenReturn(new InetSocketAddress(5000));
channel = Mockito.mock(Channel.class);
// Mockito.when(channel.hashCode()).thenReturn(12345);
Mockito.when(channel.remoteAddress()).thenReturn(new InetSocketAddress(5000));
// Mockito.doReturn(new InetSocketAddress(5000)).when(channel).remoteAddress();
callback = Mockito.mock(Device.SendPackageStatusCallback.class);
Mockito.doNothing().when(callback).sendSuccess();
@@ -69,18 +72,20 @@ public class LanLinkTest extends AndroidTestCase {
}
}).when(callback).sendFailure(Mockito.any(Throwable.class));
writeFutureSuccess = Mockito.mock(WriteFuture.class);
Mockito.when(writeFutureSuccess.isWritten()).thenReturn(true);
Mockito.when(writeFutureSuccess.getSession()).thenReturn(session);
Mockito.when(writeFutureSuccess.isDone()).thenReturn(true);
channelFutureSuccess = Mockito.mock(ChannelFuture.class);
Mockito.when(channelFutureSuccess.isDone()).thenReturn(true);
Mockito.when(channelFutureSuccess.isSuccess()).thenReturn(true);
Mockito.when(channelFutureSuccess.channel()).thenReturn(channel);
Mockito.when(channelFutureSuccess.sync()).thenReturn(channelFutureSuccess);
writeFutureFailure = Mockito.mock(WriteFuture.class);
Mockito.when(writeFutureFailure.isWritten()).thenReturn(false);
Mockito.when(writeFutureFailure.getSession()).thenReturn(session);
Mockito.when(writeFutureFailure.isDone()).thenReturn(true);
Mockito.when(writeFutureFailure.getException()).thenReturn(new RuntimeException());
channelFutureFailure = Mockito.mock(ChannelFuture.class);
Mockito.when(channelFutureFailure.isDone()).thenReturn(true);
Mockito.when(channelFutureFailure.isSuccess()).thenReturn(false);
Mockito.when(channelFutureFailure.cause()).thenReturn(new IOException("Cannot send package"));
Mockito.when(channelFutureFailure.channel()).thenReturn(channel);
Mockito.when(channelFutureFailure.sync()).thenReturn(channelFutureFailure);
lanLink = new LanLink(session, "testDevice", linkProvider);
lanLink = new LanLink(getContext(), channel, "testDevice", linkProvider);
}
@Override
@@ -96,8 +101,15 @@ public class LanLinkTest extends AndroidTestCase {
Mockito.when(testPackage.getString("testName")).thenReturn("testSendPackageSuccess");
Mockito.when(testPackage.serialize()).thenReturn("{\"id\":123,\"type\":\"kdeconnect.test\",\"body\":{\"isTesting\":true,\"testName\":\"testSendPackageSuccess\"}}");
Mockito.when(session.write(testPackage.serialize())).thenReturn(writeFutureSuccess);
lanLink.sendPackage(testPackage, callback);
try {
Mockito.when(channel.writeAndFlush(testPackage.serialize())).thenReturn(channelFutureSuccess);
lanLink.sendPackage(testPackage, callback);
} catch (Exception e) {
e.printStackTrace();
}
assertEquals(channelFutureSuccess.isDone(), true);
assertEquals(channelFutureSuccess.isSuccess(), true);
}
public void testSendPackageFail(){
@@ -108,17 +120,16 @@ public class LanLinkTest extends AndroidTestCase {
Mockito.when(testPackage.getString("testName")).thenReturn("testSendPackageFail");
Mockito.when(testPackage.serialize()).thenReturn("{\"id\":123,\"type\":\"kdeconnect.test\",\"body\":{\"isTesting\":true,\"testName\":\"testSendPackageFail\"}}");
Mockito.when(session.write(testPackage.serialize())).thenReturn(writeFutureFailure);
try {
Mockito.when(channel.writeAndFlush(testPackage.serialize())).thenReturn(channelFutureFailure);
lanLink.sendPackage(testPackage, callback);
}catch (RuntimeException r){
// Do nothing, test is fine, callback should throw this exception
}catch (Exception e){
// This should not happen
throw e;
} catch (Exception e) {
e.printStackTrace();
}
assertEquals(channelFutureFailure.isDone(), true);
assertEquals(channelFutureFailure.isSuccess(), false);
assertEquals(channelFutureFailure.cause() instanceof IOException, true );
}
@@ -145,7 +156,7 @@ public class LanLinkTest extends AndroidTestCase {
try {
socket = new Socket();
int tcpPort = np.getPayloadTransferInfo().getInt("port");
InetSocketAddress address = (InetSocketAddress)session.getRemoteAddress();
InetSocketAddress address = (InetSocketAddress)channel.remoteAddress();
socket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
np.setPayload(socket.getInputStream(), np.getPayloadSize());
} catch (Exception e) {
@@ -246,9 +257,9 @@ public class LanLinkTest extends AndroidTestCase {
downloader.setNetworkPackage(np);
downloader.start();
return writeFutureSuccess;
return channelFutureSuccess;
}
}).when(session).write(Mockito.anyString());
}).when(channel).writeAndFlush(Mockito.anyString());
lanLink.sendPackage(sharePackage, callback);

View File

@@ -23,6 +23,8 @@ package org.kde.kdeconnect;
import android.test.AndroidTestCase;
import android.util.Log;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
@@ -106,10 +108,10 @@ public class NetworkPackageTest extends AndroidTestCase{
// Encrypt and decrypt np
assertEquals(original.getType(), "com.test");
try {
NetworkPackage encrypted = original.encrypt(publicKey);
NetworkPackage encrypted = RsaHelper.encrypt(original,publicKey);
assertEquals(encrypted.getType(), NetworkPackage.PACKAGE_TYPE_ENCRYPTED);
decrypted = encrypted.decrypt(privateKey);
decrypted = RsaHelper.decrypt(encrypted, privateKey);
assertEquals(decrypted.getType(), "com.test");
}catch (Exception e){
@@ -124,8 +126,8 @@ public class NetworkPackageTest extends AndroidTestCase{
String json = "{\"body\":{\"nowPlaying\":\"A really long song name - A really long artist name\",\"player\":\"A really long player name\",\"the_meaning_of_life_the_universe_and_everything\":\"42\"},\"id\":\"A really long package id\",\"payloadSize\":0,\"payloadTransferInfo\":{},\"type\":\"kdeconnect.a_really_really_long_package_type\"}\n";
NetworkPackage longJsonNp = NetworkPackage.unserialize(json);
try {
NetworkPackage encrypted = longJsonNp.encrypt(publicKey);
decrypted = encrypted.decrypt(privateKey);
NetworkPackage encrypted = RsaHelper.encrypt(longJsonNp, publicKey);
decrypted = RsaHelper.decrypt(encrypted, privateKey);
String decryptedJson = decrypted.serialize();
assertEquals(json, decryptedJson);