Compare commits

...

1 Commits

Author SHA1 Message Date
akwizgran
b0928089ec Deliver test messages as though they arrived from contacts. 2020-11-27 11:30:40 +00:00

View File

@@ -1,15 +1,12 @@
package org.briarproject.briar.test; package org.briarproject.briar.test;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
@@ -30,7 +27,6 @@ import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.blog.BlogPost; import org.briarproject.briar.api.blog.BlogPost;
import org.briarproject.briar.api.blog.BlogPostFactory; import org.briarproject.briar.api.blog.BlogPostFactory;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.forum.Forum; import org.briarproject.briar.api.forum.Forum;
import org.briarproject.briar.api.forum.ForumManager; import org.briarproject.briar.api.forum.ForumManager;
import org.briarproject.briar.api.forum.ForumPost; import org.briarproject.briar.api.forum.ForumPost;
@@ -54,8 +50,10 @@ import javax.inject.Inject;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES; import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.test.TestData.AUTHOR_NAMES; import static org.briarproject.briar.test.TestData.AUTHOR_NAMES;
import static org.briarproject.briar.test.TestData.GROUP_NAMES; import static org.briarproject.briar.test.TestData.GROUP_NAMES;
@@ -64,13 +62,11 @@ import static org.briarproject.briar.test.TestData.GROUP_NAMES;
public class TestDataCreatorImpl implements TestDataCreator { public class TestDataCreatorImpl implements TestDataCreator {
private final Logger LOG = private final Logger LOG =
Logger.getLogger(TestDataCreatorImpl.class.getName()); getLogger(TestDataCreatorImpl.class.getName());
private final AuthorFactory authorFactory; private final AuthorFactory authorFactory;
private final Clock clock; private final Clock clock;
private final PrivateMessageFactory privateMessageFactory; private final PrivateMessageFactory privateMessageFactory;
private final ClientHelper clientHelper;
private final MessageTracker messageTracker;
private final BlogPostFactory blogPostFactory; private final BlogPostFactory blogPostFactory;
private final DatabaseComponent db; private final DatabaseComponent db;
@@ -90,7 +86,6 @@ public class TestDataCreatorImpl implements TestDataCreator {
@Inject @Inject
TestDataCreatorImpl(AuthorFactory authorFactory, Clock clock, TestDataCreatorImpl(AuthorFactory authorFactory, Clock clock,
PrivateMessageFactory privateMessageFactory, PrivateMessageFactory privateMessageFactory,
ClientHelper clientHelper, MessageTracker messageTracker,
BlogPostFactory blogPostFactory, DatabaseComponent db, BlogPostFactory blogPostFactory, DatabaseComponent db,
IdentityManager identityManager, ContactManager contactManager, IdentityManager identityManager, ContactManager contactManager,
TransportPropertyManager transportPropertyManager, TransportPropertyManager transportPropertyManager,
@@ -99,8 +94,6 @@ public class TestDataCreatorImpl implements TestDataCreator {
this.authorFactory = authorFactory; this.authorFactory = authorFactory;
this.clock = clock; this.clock = clock;
this.privateMessageFactory = privateMessageFactory; this.privateMessageFactory = privateMessageFactory;
this.clientHelper = clientHelper;
this.messageTracker = messageTracker;
this.blogPostFactory = blogPostFactory; this.blogPostFactory = blogPostFactory;
this.db = db; this.db = db;
this.identityManager = identityManager; this.identityManager = identityManager;
@@ -115,14 +108,13 @@ public class TestDataCreatorImpl implements TestDataCreator {
@Override @Override
public void createTestData(int numContacts, int numPrivateMsgs, public void createTestData(int numContacts, int numPrivateMsgs,
int numBlogPosts, int numForums, int numForumPosts) { int numBlogPosts, int numForums, int numForumPosts) {
if (numContacts == 0) throw new IllegalArgumentException( if (numContacts == 0) throw new IllegalArgumentException();
"Number of contacts must be >= 1");
ioExecutor.execute(() -> { ioExecutor.execute(() -> {
try { try {
createTestDataOnIoExecutor(numContacts, numPrivateMsgs, createTestDataOnIoExecutor(numContacts, numPrivateMsgs,
numBlogPosts, numForums, numForumPosts); numBlogPosts, numForums, numForumPosts);
} catch (DbException e) { } catch (DbException e) {
LOG.log(WARNING, "Creating test data failed", e); logException(LOG, WARNING, e);
} }
}); });
} }
@@ -134,8 +126,7 @@ public class TestDataCreatorImpl implements TestDataCreator {
List<Contact> contacts = createContacts(numContacts); List<Contact> contacts = createContacts(numContacts);
createPrivateMessages(contacts, numPrivateMsgs); createPrivateMessages(contacts, numPrivateMsgs);
createBlogPosts(contacts, numBlogPosts); createBlogPosts(contacts, numBlogPosts);
List<Forum> forums = createForums(contacts, numForums, numForumPosts); List<Forum> forums = createForums(contacts, numForums);
for (Forum forum : forums) { for (Forum forum : forums) {
createRandomForumPosts(forum, contacts, numForumPosts); createRandomForumPosts(forum, contacts, numForumPosts);
} }
@@ -154,7 +145,6 @@ public class TestDataCreatorImpl implements TestDataCreator {
private Contact addContact(AuthorId localAuthorId, LocalAuthor remote) private Contact addContact(AuthorId localAuthorId, LocalAuthor remote)
throws DbException { throws DbException {
// prepare to add contact // prepare to add contact
SecretKey secretKey = getSecretKey(); SecretKey secretKey = getSecretKey();
long timestamp = clock.currentTimeMillis(); long timestamp = clock.currentTimeMillis();
@@ -164,26 +154,20 @@ public class TestDataCreatorImpl implements TestDataCreator {
Map<TransportId, TransportProperties> props = Map<TransportId, TransportProperties> props =
getRandomTransportProperties(); getRandomTransportProperties();
Contact contact; Contact contact = db.transactionWithResult(false, txn -> {
Transaction txn = db.startTransaction(false); ContactId contactId = contactManager.addContact(txn, remote,
try { localAuthorId, secretKey, timestamp, true, verified, true);
ContactId contactId = contactManager
.addContact(txn, remote, localAuthorId, secretKey,
timestamp, true, verified, true);
if (random.nextBoolean()) { if (random.nextBoolean()) {
contactManager contactManager.setContactAlias(txn, contactId,
.setContactAlias(txn, contactId, getRandomAuthorName()); getRandomAuthorName());
} }
transportPropertyManager.addRemoteProperties(txn, contactId, props); transportPropertyManager.addRemoteProperties(txn, contactId, props);
contact = db.getContact(txn, contactId); return db.getContact(txn, contactId);
db.commitTransaction(txn); });
} finally {
db.endTransaction(txn);
}
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Added contact " + remote.getName()); LOG.info("Added contact " + remote.getName() +
LOG.info("with transport properties: " + props.toString()); " with transport properties: " + props.toString());
} }
localAuthors.put(contact, remote); localAuthors.put(contact, remote);
return contact; return contact;
@@ -213,7 +197,6 @@ public class TestDataCreatorImpl implements TestDataCreator {
private Map<TransportId, TransportProperties> getRandomTransportProperties() { private Map<TransportId, TransportProperties> getRandomTransportProperties() {
Map<TransportId, TransportProperties> props = new HashMap<>(); Map<TransportId, TransportProperties> props = new HashMap<>();
// Bluetooth // Bluetooth
TransportProperties bt = new TransportProperties(); TransportProperties bt = new TransportProperties();
String btAddress = getRandomBluetoothAddress(); String btAddress = getRandomBluetoothAddress();
@@ -293,16 +276,20 @@ public class TestDataCreatorImpl implements TestDataCreator {
return sb.toString(); return sb.toString();
} }
// TODO: Do this properly via clients without breaking encapsulation
private void shareGroup(ContactId contactId, GroupId groupId)
throws DbException {
db.transaction(false, txn ->
db.setGroupVisibility(txn, contactId, groupId, SHARED));
}
private void createPrivateMessages(List<Contact> contacts, private void createPrivateMessages(List<Contact> contacts,
int numPrivateMsgs) throws DbException { int numPrivateMsgs) throws DbException {
for (Contact contact : contacts) { for (Contact contact : contacts) {
Group group = messagingManager.getContactGroup(contact); Group group = messagingManager.getContactGroup(contact);
shareGroup(contact.getId(), group.getId());
for (int i = 0; i < numPrivateMsgs; i++) { for (int i = 0; i < numPrivateMsgs; i++) {
try { createRandomPrivateMessage(contact.getId(), group.getId(), i);
createRandomPrivateMessage(group.getId(), i);
} catch (FormatException e) {
throw new RuntimeException(e);
}
} }
} }
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
@@ -311,62 +298,66 @@ public class TestDataCreatorImpl implements TestDataCreator {
} }
} }
private void createRandomPrivateMessage(GroupId groupId, int num) private void createRandomPrivateMessage(ContactId contactId,
throws DbException, FormatException { GroupId groupId, int num) throws DbException {
long timestamp = clock.currentTimeMillis() - num * 60 * 1000; long timestamp = clock.currentTimeMillis() - num * 60 * 1000;
String text = getRandomText(); String text = getRandomText();
boolean local = random.nextBoolean(); boolean local = random.nextBoolean();
createPrivateMessage(groupId, text, timestamp, local); createPrivateMessage(contactId, groupId, text, timestamp, local);
} }
private void createPrivateMessage(GroupId groupId, String text, private void createPrivateMessage(ContactId contactId, GroupId groupId,
long timestamp, boolean local) throws DbException, FormatException { String text, long timestamp, boolean local) throws DbException {
PrivateMessage m = privateMessageFactory
.createPrivateMessage(groupId, timestamp, text, emptyList());
BdfDictionary meta = new BdfDictionary();
meta.put("timestamp", timestamp);
meta.put("local", local);
meta.put("read", local); // all local messages are read
Transaction txn = db.startTransaction(false);
try { try {
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true, PrivateMessage m = privateMessageFactory.createPrivateMessage(
false); groupId, timestamp, text, emptyList());
if (local) messageTracker.trackOutgoingMessage(txn, m.getMessage()); if (local) {
else messageTracker.trackIncomingMessage(txn, m.getMessage()); messagingManager.addLocalMessage(m);
db.commitTransaction(txn); } else {
} finally { db.transaction(false, txn ->
db.endTransaction(txn); db.receiveMessage(txn, contactId, m.getMessage()));
}
} catch (FormatException e) {
throw new AssertionError(e);
} }
} }
private void createBlogPosts(List<Contact> contacts, int numBlogPosts) private void createBlogPosts(List<Contact> contacts, int numBlogPosts)
throws DbException { throws DbException {
LocalAuthor localAuthor = identityManager.getLocalAuthor();
Blog ours = blogManager.getPersonalBlog(localAuthor);
for (Contact contact : contacts) {
Blog theirs = blogManager.getPersonalBlog(contact.getAuthor());
shareGroup(contact.getId(), ours.getId());
shareGroup(contact.getId(), theirs.getId());
}
for (int i = 0; i < numBlogPosts; i++) { for (int i = 0; i < numBlogPosts; i++) {
Contact contact = contacts.get(random.nextInt(contacts.size())); Contact contact = contacts.get(random.nextInt(contacts.size()));
LocalAuthor author = localAuthors.get(contact); LocalAuthor author = localAuthors.get(contact);
addBlogPost(author, i); addBlogPost(contact.getId(), author, i);
} }
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Created " + numBlogPosts + " blog posts."); LOG.info("Created " + numBlogPosts + " blog posts.");
} }
} }
private void addBlogPost(LocalAuthor author, int num) throws DbException { private void addBlogPost(ContactId contactId, LocalAuthor author, int num)
throws DbException {
Blog blog = blogManager.getPersonalBlog(author); Blog blog = blogManager.getPersonalBlog(author);
long timestamp = clock.currentTimeMillis() - num * 60 * 1000; long timestamp = clock.currentTimeMillis() - num * 60 * 1000;
String text = getRandomText(); String text = getRandomText();
try { try {
BlogPost blogPost = blogPostFactory.createBlogPost(blog.getId(), BlogPost blogPost = blogPostFactory.createBlogPost(blog.getId(),
timestamp, null, author, text); timestamp, null, author, text);
blogManager.addLocalPost(blogPost); db.transaction(false, txn ->
db.receiveMessage(txn, contactId, blogPost.getMessage()));
} catch (FormatException | GeneralSecurityException e) { } catch (FormatException | GeneralSecurityException e) {
throw new RuntimeException(e); throw new AssertionError(e);
} }
} }
private List<Forum> createForums(List<Contact> contacts, int numForums, private List<Forum> createForums(List<Contact> contacts, int numForums)
int numForumPosts) throws DbException { throws DbException {
List<Forum> forums = new ArrayList<>(numForums); List<Forum> forums = new ArrayList<>(numForums);
for (int i = 0; i < numForums; i++) { for (int i = 0; i < numForums; i++) {
// create forum // create forum
@@ -374,21 +365,13 @@ public class TestDataCreatorImpl implements TestDataCreator {
Forum forum = forumManager.addForum(name); Forum forum = forumManager.addForum(name);
// share with all contacts // share with all contacts
Transaction txn = db.startTransaction(false); for (Contact contact : contacts) {
try { shareGroup(contact.getId(), forum.getId());
for (Contact c : contacts) {
db.setGroupVisibility(txn, c.getId(), forum.getId(),
SHARED);
}
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
} }
forums.add(forum); forums.add(forum);
} }
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Created " + numForums + " forums with " + LOG.info("Created " + numForums + " forums.");
numForumPosts + " posts each.");
} }
return forums; return forums;
} }
@@ -403,18 +386,17 @@ public class TestDataCreatorImpl implements TestDataCreator {
String text = getRandomText(); String text = getRandomText();
MessageId parent = null; MessageId parent = null;
if (random.nextBoolean() && posts.size() > 0) { if (random.nextBoolean() && posts.size() > 0) {
ForumPost parentPost = ForumPost parentPost = posts.get(random.nextInt(posts.size()));
posts.get(random.nextInt(posts.size()));
parent = parentPost.getMessage().getId(); parent = parentPost.getMessage().getId();
} }
ForumPost post = forumManager.createLocalPost(forum.getId(), text, ForumPost post = forumManager.createLocalPost(forum.getId(), text,
timestamp, parent, author); timestamp, parent, author);
posts.add(post); posts.add(post);
forumManager.addLocalPost(post); db.transaction(false, txn ->
if (random.nextBoolean()) { db.receiveMessage(txn, contact.getId(), post.getMessage()));
forumManager.setReadFlag(forum.getId(),
post.getMessage().getId(), false);
} }
if (LOG.isLoggable(INFO)) {
LOG.info("Created " + numForumPosts + " forum posts.");
} }
} }