Add integration test for FeedManager

Attention: This factors out a DnsModule to be able to make actual
non-Tor DNS lookups for testing.
This commit is contained in:
Torsten Grote
2017-04-10 18:58:46 -03:00
parent d40a058ef5
commit b0b4a85d15
8 changed files with 281 additions and 16 deletions

View File

@@ -0,0 +1,16 @@
package org.briarproject.bramble.test;
import javax.net.SocketFactory;
import dagger.Module;
import dagger.Provides;
@Module
public class TestSocksModule {
@Provides
SocketFactory provideSocketFactory() {
return SocketFactory.getDefault();
}
}

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar;
import org.briarproject.briar.blog.BlogModule; import org.briarproject.briar.blog.BlogModule;
import org.briarproject.briar.client.BriarClientModule; import org.briarproject.briar.client.BriarClientModule;
import org.briarproject.briar.feed.DnsModule;
import org.briarproject.briar.feed.FeedModule; import org.briarproject.briar.feed.FeedModule;
import org.briarproject.briar.forum.ForumModule; import org.briarproject.briar.forum.ForumModule;
import org.briarproject.briar.introduction.IntroductionModule; import org.briarproject.briar.introduction.IntroductionModule;
@@ -16,6 +17,7 @@ import dagger.Module;
BlogModule.class, BlogModule.class,
BriarClientModule.class, BriarClientModule.class,
FeedModule.class, FeedModule.class,
DnsModule.class,
ForumModule.class, ForumModule.class,
GroupInvitationModule.class, GroupInvitationModule.class,
IntroductionModule.class, IntroductionModule.class,

View File

@@ -0,0 +1,18 @@
package org.briarproject.briar.feed;
import dagger.Module;
import dagger.Provides;
import okhttp3.Dns;
/**
* This is a dedicated module, so it can be replaced for testing.
*/
@Module
public class DnsModule {
@Provides
Dns provideDns(NoDns noDns) {
return noDns;
}
}

View File

@@ -39,8 +39,6 @@ import org.briarproject.briar.api.feed.FeedManager;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -81,7 +79,6 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(FeedManagerImpl.class.getName()); Logger.getLogger(FeedManagerImpl.class.getName());
private static final byte[] UNSPECIFIED_ADDRESS = new byte[4];
private static final int CONNECT_TIMEOUT = 60 * 1000; // Milliseconds private static final int CONNECT_TIMEOUT = 60 * 1000; // Milliseconds
private final ScheduledExecutorService scheduler; private final ScheduledExecutorService scheduler;
@@ -94,6 +91,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
private final FeedFactory feedFactory; private final FeedFactory feedFactory;
private final SocketFactory torSocketFactory; private final SocketFactory torSocketFactory;
private final Clock clock; private final Clock clock;
private final Dns noDnsLookups;
private final AtomicBoolean fetcherStarted = new AtomicBoolean(false); private final AtomicBoolean fetcherStarted = new AtomicBoolean(false);
@Inject @Inject
@@ -102,7 +100,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
ContactGroupFactory contactGroupFactory, ClientHelper clientHelper, ContactGroupFactory contactGroupFactory, ClientHelper clientHelper,
BlogManager blogManager, BlogPostFactory blogPostFactory, BlogManager blogManager, BlogPostFactory blogPostFactory,
FeedFactory feedFactory, SocketFactory torSocketFactory, FeedFactory feedFactory, SocketFactory torSocketFactory,
Clock clock) { Clock clock, Dns noDnsLookups) {
this.scheduler = scheduler; this.scheduler = scheduler;
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
@@ -114,6 +112,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
this.feedFactory = feedFactory; this.feedFactory = feedFactory;
this.torSocketFactory = torSocketFactory; this.torSocketFactory = torSocketFactory;
this.clock = clock; this.clock = clock;
this.noDnsLookups = noDnsLookups;
} }
@Override @Override
@@ -374,21 +373,10 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
} }
private InputStream getFeedInputStream(String url) throws IOException { private InputStream getFeedInputStream(String url) throws IOException {
// Don't make local DNS lookups
Dns noLookups = new Dns() {
@Override
public List<InetAddress> lookup(String hostname)
throws UnknownHostException {
InetAddress unspecified =
InetAddress.getByAddress(hostname, UNSPECIFIED_ADDRESS);
return Collections.singletonList(unspecified);
}
};
// Build HTTP Client // Build HTTP Client
OkHttpClient client = new OkHttpClient.Builder() OkHttpClient client = new OkHttpClient.Builder()
.socketFactory(torSocketFactory) .socketFactory(torSocketFactory)
.dns(noLookups) .dns(noDnsLookups) // Don't make local DNS lookups
.connectTimeout(CONNECT_TIMEOUT, MILLISECONDS) .connectTimeout(CONNECT_TIMEOUT, MILLISECONDS)
.build(); .build();

View File

@@ -0,0 +1,28 @@
package org.briarproject.briar.feed;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import okhttp3.Dns;
class NoDns implements Dns {
private static final byte[] UNSPECIFIED_ADDRESS = new byte[4];
@Inject
public NoDns() {
}
@Override
public List<InetAddress> lookup(String hostname)
throws UnknownHostException {
InetAddress unspecified =
InetAddress.getByAddress(hostname, UNSPECIFIED_ADDRESS);
return Collections.singletonList(unspecified);
}
}

View File

@@ -0,0 +1,119 @@
package org.briarproject.briar.feed;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.contact.ContactModule;
import org.briarproject.bramble.crypto.CryptoModule;
import org.briarproject.bramble.identity.IdentityModule;
import org.briarproject.bramble.lifecycle.LifecycleModule;
import org.briarproject.bramble.sync.SyncModule;
import org.briarproject.bramble.system.SystemModule;
import org.briarproject.bramble.test.TestDatabaseModule;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.transport.TransportModule;
import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.feed.Feed;
import org.briarproject.briar.api.feed.FeedManager;
import org.briarproject.briar.blog.BlogModule;
import org.briarproject.briar.test.BriarTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class FeedManagerIntegrationTest extends BriarTestCase {
private LifecycleManager lifecycleManager;
private FeedManager feedManager;
private BlogManager blogManager;
private final File testDir = TestUtils.getTestDirectory();
private final File testFile = new File(testDir, "feedTest");
@Before
public void setUp() throws Exception {
assertTrue(testDir.mkdirs());
FeedManagerIntegrationTestComponent component =
DaggerFeedManagerIntegrationTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(testFile))
.build();
component.inject(this);
injectEagerSingletons(component);
lifecycleManager = component.getLifecycleManager();
lifecycleManager.startServices("feedTest");
lifecycleManager.waitForStartup();
feedManager = component.getFeedManager();
blogManager = component.getBlogManager();
}
@Test
public void testFeedImportAndRemoval() throws Exception {
// initially, there's only the one personal blog
Collection<Blog> blogs = blogManager.getBlogs();
assertEquals(1, blogs.size());
Blog personalBlog = blogs.iterator().next();
// add feed into a dedicated blog
String url = "https://www.schneier.com/blog/atom.xml";
feedManager.addFeed(url);
// then there's the feed's blog now
blogs = blogManager.getBlogs();
assertEquals(2, blogs.size());
Blog feedBlog = null;
for (Blog blog : blogs) {
if (!blog.equals(personalBlog)) feedBlog = blog;
}
assertNotNull(feedBlog);
// check the feed got saved as expected
Collection<Feed> feeds = feedManager.getFeeds();
assertEquals(1, feeds.size());
Feed feed = feeds.iterator().next();
assertTrue(feed.getLastEntryTime() > 0);
assertTrue(feed.getAdded() > 0);
assertTrue(feed.getUpdated() > 0);
assertEquals(url, feed.getUrl());
assertEquals(feedBlog, feed.getBlog());
assertEquals("Schneier on Security", feed.getTitle());
assertEquals("A blog covering security and security technology.",
feed.getDescription());
assertEquals(feed.getTitle(), feed.getBlog().getName());
assertEquals(feed.getTitle(), feed.getLocalAuthor().getName());
// now let's remove the feed's blog again
blogManager.removeBlog(feedBlog);
blogs = blogManager.getBlogs();
assertEquals(1, blogs.size());
assertEquals(personalBlog, blogs.iterator().next());
assertEquals(0, feedManager.getFeeds().size());
}
@After
public void tearDown() throws Exception {
lifecycleManager.stopServices();
lifecycleManager.waitForShutdown();
TestUtils.deleteTestDirectory(testDir);
}
protected void injectEagerSingletons(
FeedManagerIntegrationTestComponent component) {
component.inject(new FeedModule.EagerSingletons());
component.inject(new BlogModule.EagerSingletons());
component.inject(new ContactModule.EagerSingletons());
component.inject(new CryptoModule.EagerSingletons());
component.inject(new IdentityModule.EagerSingletons());
component.inject(new LifecycleModule.EagerSingletons());
component.inject(new SyncModule.EagerSingletons());
component.inject(new SystemModule.EagerSingletons());
component.inject(new TransportModule.EagerSingletons());
}
}

View File

@@ -0,0 +1,79 @@
package org.briarproject.briar.feed;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.client.ClientModule;
import org.briarproject.bramble.contact.ContactModule;
import org.briarproject.bramble.crypto.CryptoModule;
import org.briarproject.bramble.data.DataModule;
import org.briarproject.bramble.db.DatabaseModule;
import org.briarproject.bramble.event.EventModule;
import org.briarproject.bramble.identity.IdentityModule;
import org.briarproject.bramble.lifecycle.LifecycleModule;
import org.briarproject.bramble.sync.SyncModule;
import org.briarproject.bramble.system.SystemModule;
import org.briarproject.bramble.test.TestDatabaseModule;
import org.briarproject.bramble.test.TestPluginConfigModule;
import org.briarproject.bramble.test.TestSeedProviderModule;
import org.briarproject.bramble.test.TestSocksModule;
import org.briarproject.bramble.transport.TransportModule;
import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.feed.FeedManager;
import org.briarproject.briar.blog.BlogModule;
import org.briarproject.briar.client.BriarClientModule;
import org.briarproject.briar.test.TestDnsModule;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {
TestDatabaseModule.class,
TestPluginConfigModule.class,
TestSeedProviderModule.class,
TestSocksModule.class,
TestDnsModule.class,
LifecycleModule.class,
BriarClientModule.class,
ClientModule.class,
ContactModule.class,
CryptoModule.class,
BlogModule.class,
FeedModule.class,
DataModule.class,
DatabaseModule.class,
EventModule.class,
IdentityModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class
})
interface FeedManagerIntegrationTestComponent {
void inject(FeedManagerIntegrationTest testCase);
void inject(FeedModule.EagerSingletons init);
void inject(BlogModule.EagerSingletons init);
void inject(ContactModule.EagerSingletons init);
void inject(CryptoModule.EagerSingletons init);
void inject(IdentityModule.EagerSingletons init);
void inject(LifecycleModule.EagerSingletons init);
void inject(SyncModule.EagerSingletons init);
void inject(SystemModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init);
LifecycleManager getLifecycleManager();
FeedManager getFeedManager();
BlogManager getBlogManager();
}

View File

@@ -0,0 +1,15 @@
package org.briarproject.briar.test;
import dagger.Module;
import dagger.Provides;
import okhttp3.Dns;
@Module
public class TestDnsModule {
@Provides
Dns provideDns() {
return Dns.SYSTEM;
}
}