Store message count, unread count and timestamp of latest message

in group metadata to be able to speed up group listings.

Closes #584, #586, #585
This commit is contained in:
Torsten Grote
2016-10-04 13:37:29 -03:00
parent 3fa84ec7a8
commit a727a0817e
25 changed files with 421 additions and 141 deletions

View File

@@ -8,6 +8,7 @@ import org.briarproject.api.blogs.BlogInvitationResponse;
import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogPostFactory;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
@@ -25,6 +26,7 @@ import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.sync.ValidationManager.State;
@@ -62,12 +64,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BlogSharingIntegrationTest extends BriarTestCase {
public class BlogSharingIntegrationTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1,
lifecycleManager2;
private SyncSessionFactory sync0, sync1, sync2;
private BlogManager blogManager0, blogManager1, blogManager2;
private SyncSessionFactory sync0, sync1;
private BlogManager blogManager0, blogManager1;
private ContactManager contactManager0, contactManager1, contactManager2;
private Contact contact1, contact2, contact01, contact02;
private ContactId contactId1, contactId2, contactId01, contactId02;
@@ -83,6 +85,8 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
@Inject
AuthorFactory authorFactory;
@Inject
ContactGroupFactory contactGroupFactory;
@Inject
BlogPostFactory blogPostFactory;
@Inject
CryptoComponent cryptoComponent;
@@ -138,13 +142,11 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
contactManager2 = t2.getContactManager();
blogManager0 = t0.getBlogManager();
blogManager1 = t1.getBlogManager();
blogManager2 = t2.getBlogManager();
blogSharingManager0 = t0.getBlogSharingManager();
blogSharingManager1 = t1.getBlogSharingManager();
blogSharingManager2 = t2.getBlogSharingManager();
sync0 = t0.getSyncSessionFactory();
sync1 = t1.getSyncSessionFactory();
sync2 = t2.getSyncSessionFactory();
// initialize waiters fresh for each test
eventWaiter = new Waiter();
@@ -187,15 +189,23 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
// invitee has own blog and that of the sharer
assertEquals(2, blogManager1.getBlogs().size());
// get sharing group and assert group message count
GroupId g = contactGroupFactory
.createContactGroup(blogSharingManager0.getClientId(),
contact1).getId();
assertGroupCount(blogSharingManager0, g, 1, 0);
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
assertGroupCount(blogSharingManager1, g, 2, 1);
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
assertGroupCount(blogSharingManager0, g, 2, 1);
// blog was added successfully
assertEquals(0, blogSharingManager0.getInvitations().size());
@@ -232,6 +242,10 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact1));
assertFalse(blogSharingManager1.canBeShared(blog2.getId(), contact01));
// group message count is still correct
assertGroupCount(blogSharingManager0, g, 2, 1);
assertGroupCount(blogSharingManager1, g, 2, 1);
stopLifecycles();
}
@@ -510,8 +524,7 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
private class SharerListener implements EventListener {
volatile boolean requestReceived = false;
volatile boolean responseReceived = false;
private volatile boolean responseReceived = false;
@Override
public void eventOccurred(Event e) {
@@ -534,7 +547,6 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
BlogInvitationReceivedEvent event =
(BlogInvitationReceivedEvent) e;
eventWaiter.assertEquals(contactId1, event.getContactId());
requestReceived = true;
Blog b = event.getBlog();
try {
Contact c = contactManager0.getContact(contactId1);
@@ -550,17 +562,16 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
private class InviteeListener implements EventListener {
volatile boolean requestReceived = false;
volatile boolean responseReceived = false;
private volatile boolean requestReceived = false;
private final boolean accept, answer;
InviteeListener(boolean accept, boolean answer) {
private InviteeListener(boolean accept, boolean answer) {
this.accept = accept;
this.answer = answer;
}
InviteeListener(boolean accept) {
private InviteeListener(boolean accept) {
this(accept, true);
}
@@ -596,7 +607,6 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
BlogInvitationResponseReceivedEvent event =
(BlogInvitationResponseReceivedEvent) e;
eventWaiter.assertEquals(contactId01, event.getContactId());
responseReceived = true;
eventWaiter.resume();
}
}

View File

@@ -0,0 +1,32 @@
package org.briarproject;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import static org.junit.Assert.assertEquals;
public abstract class BriarIntegrationTest extends BriarTestCase {
// TODO maybe we could add uncaught exception handlers for other threads here (#670)
protected void assertGroupCount(MessageTracker tracker, GroupId g,
long msgCount, long unreadCount, long latestMsg)
throws DbException {
GroupCount groupCount = tracker.getGroupCount(g);
assertEquals(msgCount, groupCount.getMsgCount());
assertEquals(unreadCount, groupCount.getUnreadCount());
assertEquals(latestMsg, groupCount.getLatestMsgTime());
}
protected void assertGroupCount(MessageTracker tracker, GroupId g,
long msgCount, long unreadCount) throws DbException {
GroupCount c1 = tracker.getGroupCount(g);
assertEquals(msgCount, c1.getMsgCount());
assertEquals(unreadCount, c1.getUnreadCount());
}
}

View File

@@ -59,7 +59,7 @@ import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
import static org.junit.Assert.assertTrue;
public class ForumManagerTest {
public class ForumManagerTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1;
private SyncSessionFactory sync0, sync1;
@@ -150,9 +150,19 @@ public class ForumManagerTest {
createForumPost(forum.getGroup().getId(), post1, body2, ms2);
assertEquals(ms2, post2.getMessage().getTimestamp());
forumManager0.addLocalPost(post1);
forumManager0.setReadFlag(post1.getMessage().getId(), true);
forumManager0.setReadFlag(forum.getGroup().getId(),
post1.getMessage().getId(), true);
assertGroupCount(forumManager0, forum.getGroup().getId(), 1, 0,
post1.getMessage().getTimestamp());
forumManager0.addLocalPost(post2);
forumManager0.setReadFlag(post2.getMessage().getId(), false);
forumManager0.setReadFlag(forum.getGroup().getId(),
post2.getMessage().getId(), false);
assertGroupCount(forumManager0, forum.getGroup().getId(), 2, 1,
post2.getMessage().getTimestamp());
forumManager0.setReadFlag(forum.getGroup().getId(),
post2.getMessage().getId(), false);
assertGroupCount(forumManager0, forum.getGroup().getId(), 2, 1,
post2.getMessage().getTimestamp());
Collection<ForumPostHeader> headers =
forumManager0.getPostHeaders(forum.getGroup().getId());
assertEquals(2, headers.size());
@@ -202,23 +212,29 @@ public class ForumManagerTest {
forumManager0.addLocalPost(post1);
assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(0, forumManager1.getPostHeaders(g).size());
assertGroupCount(forumManager0, g, 1, 0, time);
assertGroupCount(forumManager1, g, 0, 0, 0);
// send post to 1
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
assertEquals(1, forumManager1.getPostHeaders(g).size());
assertGroupCount(forumManager1, g, 1, 1, time);
// add another forum post
time = clock.currentTimeMillis();
ForumPost post2 = createForumPost(g, null, "b", time);
long time2 = clock.currentTimeMillis();
ForumPost post2 = createForumPost(g, null, "b", time2);
forumManager1.addLocalPost(post2);
assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(2, forumManager1.getPostHeaders(g).size());
assertGroupCount(forumManager0, g, 1, 0, time);
assertGroupCount(forumManager1, g, 2, 1, time2);
// send post to 0
sync1To0();
deliveryWaiter.await(TIMEOUT, 1);
assertEquals(2, forumManager1.getPostHeaders(g).size());
assertGroupCount(forumManager0, g, 2, 1, time2);
stopLifecycles();
}

View File

@@ -4,7 +4,7 @@ import android.support.annotation.Nullable;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.BriarTestCase;
import org.briarproject.BriarIntegrationTest;
import org.briarproject.TestDatabaseModule;
import org.briarproject.TestUtils;
import org.briarproject.api.FormatException;
@@ -99,7 +99,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class IntroductionIntegrationTest extends BriarTestCase {
public class IntroductionIntegrationTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1,
lifecycleManager2;
@@ -200,29 +200,43 @@ public class IntroductionIntegrationTest extends BriarTestCase {
introductionManager0
.makeIntroduction(introducee1, introducee2, "Hi!", time);
// check that messages are tracked properly
Group g1 = introductionGroupFactory
.createIntroductionGroup(introducee1);
Group g2 = introductionGroupFactory
.createIntroductionGroup(introducee2);
assertGroupCount(introductionManager0, g1.getId(), 1, 0, time);
assertGroupCount(introductionManager0, g2.getId(), 1, 0, time);
// sync first request message
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
assertGroupCount(introductionManager1, g1.getId(), 2, 1);
// sync second request message
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener2.requestReceived);
assertGroupCount(introductionManager2, g2.getId(), 2, 1);
// sync first response
deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.response1Received);
assertGroupCount(introductionManager0, g1.getId(), 2, 1);
// sync second response
deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.response2Received);
assertGroupCount(introductionManager0, g2.getId(), 2, 1);
// sync forwarded responses to introducees
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
assertGroupCount(introductionManager1, g1.getId(), 3, 2);
assertGroupCount(introductionManager2, g2.getId(), 3, 2);
// sync first ACK and its forward
deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0");
@@ -255,6 +269,10 @@ public class IntroductionIntegrationTest extends BriarTestCase {
}
assertDefaultUiMessages();
assertGroupCount(introductionManager0, g1.getId(), 2, 1);
assertGroupCount(introductionManager0, g2.getId(), 2, 1);
assertGroupCount(introductionManager1, g1.getId(), 3, 2);
assertGroupCount(introductionManager2, g2.getId(), 3, 2);
} finally {
stopLifecycles();
}