Forked from
briar / briar
6119 commits behind the upstream repository.
ModemPluginTest.java 10.17 KiB
package org.briarproject.plugins.modem;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.briarproject.BriarTestCase;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.hamcrest.Description;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.api.Action;
import org.jmock.api.Invocation;
import org.junit.Test;
public class ModemPluginTest extends BriarTestCase {
private static final String ISO_1336 = "GB";
private static final String NUMBER1 = "0123";
private static final String NUMBER2 = "0234";
private static final String NUMBER3 = "0345";
@Test
public void testModemCreation() throws Exception {
Mockery context = new Mockery();
final ModemFactory modemFactory = context.mock(ModemFactory.class);
final SerialPortList serialPortList =
context.mock(SerialPortList.class);
final ModemPlugin plugin = new ModemPlugin(null, modemFactory,
serialPortList, null, 0, 0, 0, true);
final Modem modem = context.mock(Modem.class);
context.checking(new Expectations() {{
oneOf(serialPortList).getPortNames();
will(returnValue(new String[] { "foo", "bar", "baz" }));
// First call to createModem() returns false
oneOf(modemFactory).createModem(plugin, "foo");
will(returnValue(modem));
oneOf(modem).start();
will(returnValue(false));
// Second call to createModem() throws an exception
oneOf(modemFactory).createModem(plugin, "bar");
will(returnValue(modem));
oneOf(modem).start();
will(throwException(new IOException()));
// Third call to createModem() returns true
oneOf(modemFactory).createModem(plugin, "baz");
will(returnValue(modem));
oneOf(modem).start();
will(returnValue(true));
}});
assertTrue(plugin.start());
context.assertIsSatisfied();
}
@Test
public void testCreateConnection() throws Exception {
Mockery context = new Mockery();
final ModemFactory modemFactory = context.mock(ModemFactory.class);
final SerialPortList serialPortList =
context.mock(SerialPortList.class);
final DuplexPluginCallback callback =
context.mock(DuplexPluginCallback.class);
final ModemPlugin plugin = new ModemPlugin(null, modemFactory,
serialPortList, callback, 0, 0, 0, true);
final Modem modem = context.mock(Modem.class);
final TransportProperties local = new TransportProperties();
local.put("iso3166", ISO_1336);
TransportProperties p = new TransportProperties();
p.put("iso3166", ISO_1336);
p.put("number", NUMBER1);
ContactId contactId = new ContactId(234);
final Map<ContactId, TransportProperties> remote =
Collections.singletonMap(contactId, p);
context.checking(new Expectations() {{
// start()
oneOf(serialPortList).getPortNames();
will(returnValue(new String[] { "foo" }));
oneOf(modemFactory).createModem(plugin, "foo");
will(returnValue(modem));
oneOf(modem).start();
will(returnValue(true));
// createConnection()
oneOf(callback).getLocalProperties();
will(returnValue(local));
oneOf(callback).getRemoteProperties();
will(returnValue(remote));
oneOf(modem).dial(NUMBER1);
will(returnValue(true));
}});
assertTrue(plugin.start());
// A connection should be returned
assertNotNull(plugin.createConnection(contactId));
context.assertIsSatisfied();
}
@Test
public void testCreateConnectionWhenDialReturnsFalse() throws Exception {
Mockery context = new Mockery();
final ModemFactory modemFactory = context.mock(ModemFactory.class);
final SerialPortList serialPortList =
context.mock(SerialPortList.class);
final DuplexPluginCallback callback =
context.mock(DuplexPluginCallback.class);
final ModemPlugin plugin = new ModemPlugin(null, modemFactory,
serialPortList, callback, 0, 0, 0, true);
final Modem modem = context.mock(Modem.class);
final TransportProperties local = new TransportProperties();
local.put("iso3166", ISO_1336);
TransportProperties p = new TransportProperties();
p.put("iso3166", ISO_1336);
p.put("number", NUMBER1);
ContactId contactId = new ContactId(234);
final Map<ContactId, TransportProperties> remote =
Collections.singletonMap(contactId, p);
context.checking(new Expectations() {{
// start()
oneOf(serialPortList).getPortNames();
will(returnValue(new String[] { "foo" }));
oneOf(modemFactory).createModem(plugin, "foo");
will(returnValue(modem));
oneOf(modem).start();
will(returnValue(true));
// createConnection()
oneOf(callback).getLocalProperties();
will(returnValue(local));
oneOf(callback).getRemoteProperties();
will(returnValue(remote));
oneOf(modem).dial(NUMBER1);
will(returnValue(false));
}});
assertTrue(plugin.start());
// No connection should be returned
assertNull(plugin.createConnection(contactId));
context.assertIsSatisfied();
}
@Test
public void testCreateConnectionWhenDialThrowsException() throws Exception {
Mockery context = new Mockery();
final ModemFactory modemFactory = context.mock(ModemFactory.class);
final SerialPortList serialPortList =
context.mock(SerialPortList.class);
final DuplexPluginCallback callback =
context.mock(DuplexPluginCallback.class);
final ModemPlugin plugin = new ModemPlugin(null, modemFactory,
serialPortList, callback, 0, 0, 0, true);
final Modem modem = context.mock(Modem.class);
final TransportProperties local = new TransportProperties();
local.put("iso3166", ISO_1336);
TransportProperties p = new TransportProperties();
p.put("iso3166", ISO_1336);
p.put("number", NUMBER1);
ContactId contactId = new ContactId(234);
final Map<ContactId, TransportProperties> remote =
Collections.singletonMap(contactId, p);
context.checking(new Expectations() {{
// start()
oneOf(serialPortList).getPortNames();
will(returnValue(new String[] { "foo" }));
oneOf(modemFactory).createModem(plugin, "foo");
will(returnValue(modem));
oneOf(modem).start();
will(returnValue(true));
// createConnection()
oneOf(callback).getLocalProperties();
will(returnValue(local));
oneOf(callback).getRemoteProperties();
will(returnValue(remote));
oneOf(modem).dial(NUMBER1);
will(throwException(new IOException()));
// resetModem()
oneOf(serialPortList).getPortNames();
will(returnValue(new String[] { "foo" }));
oneOf(modemFactory).createModem(plugin, "foo");
will(returnValue(modem));
oneOf(modem).start();
will(returnValue(true));
}});
assertTrue(plugin.start());
// No connection should be returned
assertNull(plugin.createConnection(contactId));
context.assertIsSatisfied();
}
@Test
public void testPolling() throws Exception {
final ExecutorService ioExecutor = Executors.newSingleThreadExecutor();
Mockery context = new Mockery();
final ModemFactory modemFactory = context.mock(ModemFactory.class);
final SerialPortList serialPortList =
context.mock(SerialPortList.class);
final DuplexPluginCallback callback =
context.mock(DuplexPluginCallback.class);
// Disable shuffling for this test, it confuses jMock
final ModemPlugin plugin = new ModemPlugin(ioExecutor, modemFactory,
serialPortList, callback, 0, 0, 0, false);
final Modem modem = context.mock(Modem.class);
final TransportProperties local = new TransportProperties();
local.put("iso3166", ISO_1336);
TransportProperties p1 = new TransportProperties();
p1.put("iso3166", ISO_1336);
p1.put("number", NUMBER1);
TransportProperties p2 = new TransportProperties();
p2.put("iso3166", ISO_1336);
p2.put("number", NUMBER2);
TransportProperties p3 = new TransportProperties();
p3.put("iso3166", ISO_1336);
p3.put("number", NUMBER3);
ContactId contactId1 = new ContactId(234);
ContactId contactId2 = new ContactId(345);
ContactId contactId3 = new ContactId(456);
final Map<ContactId, TransportProperties> remote =
new HashMap<ContactId, TransportProperties>();
remote.put(contactId1, p1);
remote.put(contactId2, p2);
remote.put(contactId3, p3);
final DisposeAction disposeAction = new DisposeAction();
context.checking(new Expectations() {{
// start()
oneOf(serialPortList).getPortNames();
will(returnValue(new String[] { "foo" }));
oneOf(modemFactory).createModem(plugin, "foo");
will(returnValue(modem));
oneOf(modem).start();
will(returnValue(true));
// poll()
oneOf(callback).getLocalProperties();
will(returnValue(local));
oneOf(callback).getRemoteProperties();
will(returnValue(remote));
// First call to dial() throws an exception
oneOf(modem).dial(NUMBER1);
will(throwException(new IOException()));
// resetModem()
oneOf(serialPortList).getPortNames();
will(returnValue(new String[] { "foo" }));
oneOf(modemFactory).createModem(plugin, "foo");
will(returnValue(modem));
oneOf(modem).start();
will(returnValue(true));
// Second call to dial() returns true
oneOf(modem).dial(NUMBER2);
will(returnValue(true));
// A connection is passed to the callback - dispose of it
oneOf(callback).outgoingConnectionCreated(
with(any(ContactId.class)),
with(any(DuplexTransportConnection.class)));
will(disposeAction);
oneOf(modem).hangUp();
// Third call to dial() returns false
oneOf(modem).dial(NUMBER3);
will(returnValue(false));
}});
assertTrue(plugin.start());
plugin.poll(Collections.<ContactId>emptyList());
assertTrue(disposeAction.invoked.await(5, SECONDS));
ioExecutor.shutdown();
context.assertIsSatisfied();
}
private static class DisposeAction implements Action {
private final CountDownLatch invoked = new CountDownLatch(1);
public void describeTo(Description description) {
description.appendText("Disposes of a transport connection");
}
public Object invoke(Invocation invocation) throws Throwable {
DuplexTransportConnection conn =
(DuplexTransportConnection) invocation.getParameter(1);
conn.getReader().dispose(false, true);
conn.getWriter().dispose(false);
invoked.countDown();
return null;
}
}
}