Merge branch 'privategroup-testdata' into 'master'

TestDataCreator with support for private groups

See merge request briar/briar!1788
This commit is contained in:
Torsten Grote
2023-04-26 12:38:53 +00:00
4 changed files with 221 additions and 43 deletions

View File

@@ -24,9 +24,10 @@ public class TestDataActivity extends BriarActivity {
@Inject @Inject
TestDataCreator testDataCreator; TestDataCreator testDataCreator;
private TextView contactsTextView, forumsTextView; private TextView contactsTextView, forumsTextView, privateGroupsTextView;
private SeekBar contactsSeekBar, messagesSeekBar, avatarsSeekBar, private SeekBar contactsSeekBar, messagesSeekBar, avatarsSeekBar,
blogPostsSeekBar, forumsSeekBar, forumPostsSeekBar; blogPostsSeekBar, forumsSeekBar, forumPostsSeekBar,
privateGroupsSeekBar, privateGroupPostsSeekBar;
@Override @Override
public void onCreate(Bundle bundle) { public void onCreate(Bundle bundle) {
@@ -46,28 +47,26 @@ public class TestDataActivity extends BriarActivity {
forumsTextView = findViewById(R.id.TextViewForumsSb); forumsTextView = findViewById(R.id.TextViewForumsSb);
TextView forumPostsTextView = TextView forumPostsTextView =
findViewById(R.id.TextViewForumMessagesSb); findViewById(R.id.TextViewForumMessagesSb);
privateGroupsTextView = findViewById(R.id.TextViewPrivateGroupsSb);
TextView privateGroupPostsTextView =
findViewById(R.id.TextViewPrivateGroupMessagesSb);
contactsSeekBar = findViewById(R.id.seekBarContacts); contactsSeekBar = findViewById(R.id.seekBarContacts);
messagesSeekBar = findViewById(R.id.seekBarMessages); messagesSeekBar = findViewById(R.id.seekBarMessages);
avatarsSeekBar = findViewById(R.id.seekBarAvatars); avatarsSeekBar = findViewById(R.id.seekBarAvatars);
blogPostsSeekBar = findViewById(R.id.seekBarBlogPosts); blogPostsSeekBar = findViewById(R.id.seekBarBlogPosts);
forumsSeekBar = findViewById(R.id.seekBarForums); forumsSeekBar = findViewById(R.id.seekBarForums);
forumPostsSeekBar = findViewById(R.id.seekBarForumMessages); forumPostsSeekBar = findViewById(R.id.seekBarForumMessages);
privateGroupsSeekBar = findViewById(R.id.seekBarPrivateGroups);
privateGroupPostsSeekBar =
findViewById(R.id.seekBarPrivateGroupMessages);
contactsSeekBar contactsSeekBar.setOnSeekBarChangeListener(
.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { new AbstractOnSeekBarChangeListener() {
@Override @Override
public void onProgressChanged(SeekBar seekBar, public void onProgressChanged(SeekBar seekBar, int progress,
int progress, boolean fromUser) { boolean fromUser) {
contactsTextView.setText(String.valueOf(progress + 1)); contactsTextView.setText(String.valueOf(progress + 1));
} }
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}); });
messagesSeekBar.setOnSeekBarChangeListener( messagesSeekBar.setOnSeekBarChangeListener(
@@ -76,35 +75,39 @@ public class TestDataActivity extends BriarActivity {
new OnSeekBarChangeUpdateProgress(avatarsTextView)); new OnSeekBarChangeUpdateProgress(avatarsTextView));
blogPostsSeekBar.setOnSeekBarChangeListener( blogPostsSeekBar.setOnSeekBarChangeListener(
new OnSeekBarChangeUpdateProgress(blogPostsTextView)); new OnSeekBarChangeUpdateProgress(blogPostsTextView));
forumsSeekBar forumsSeekBar.setOnSeekBarChangeListener(
.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { new AbstractOnSeekBarChangeListener() {
@Override @Override
public void onProgressChanged(SeekBar seekBar, public void onProgressChanged(SeekBar seekBar, int progress,
int progress, boolean fromUser) { boolean fromUser) {
forumsTextView.setText(String.valueOf(progress)); forumsTextView.setText(String.valueOf(progress));
forumPostsSeekBar.setEnabled(progress > 0); forumPostsSeekBar.setEnabled(progress > 0);
} }
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}); });
forumPostsSeekBar.setOnSeekBarChangeListener( forumPostsSeekBar.setOnSeekBarChangeListener(
new OnSeekBarChangeUpdateProgress(forumPostsTextView)); new OnSeekBarChangeUpdateProgress(forumPostsTextView));
privateGroupsSeekBar.setOnSeekBarChangeListener(
findViewById(R.id.buttonZeroValues).setOnClickListener( new AbstractOnSeekBarChangeListener() {
v -> { @Override
contactsSeekBar.setProgress(0); public void onProgressChanged(SeekBar seekBar, int progress,
messagesSeekBar.setProgress(0); boolean fromUser) {
avatarsSeekBar.setProgress(0); privateGroupsTextView.setText(String.valueOf(progress));
blogPostsSeekBar.setProgress(0); privateGroupPostsSeekBar.setEnabled(progress > 0);
forumsSeekBar.setProgress(0); }
forumPostsSeekBar.setProgress(0);
}); });
privateGroupPostsSeekBar.setOnSeekBarChangeListener(
new OnSeekBarChangeUpdateProgress(privateGroupPostsTextView));
findViewById(R.id.buttonZeroValues).setOnClickListener(v -> {
contactsSeekBar.setProgress(0);
messagesSeekBar.setProgress(0);
avatarsSeekBar.setProgress(0);
blogPostsSeekBar.setProgress(0);
forumsSeekBar.setProgress(0);
forumPostsSeekBar.setProgress(0);
privateGroupsSeekBar.setProgress(0);
privateGroupPostsSeekBar.setProgress(0);
});
findViewById(R.id.buttonCreateTestData).setOnClickListener( findViewById(R.id.buttonCreateTestData).setOnClickListener(
v -> createTestData()); v -> createTestData());
@@ -114,7 +117,9 @@ public class TestDataActivity extends BriarActivity {
testDataCreator.createTestData(contactsSeekBar.getProgress() + 1, testDataCreator.createTestData(contactsSeekBar.getProgress() + 1,
messagesSeekBar.getProgress(), avatarsSeekBar.getProgress(), messagesSeekBar.getProgress(), avatarsSeekBar.getProgress(),
blogPostsSeekBar.getProgress(), forumsSeekBar.getProgress(), blogPostsSeekBar.getProgress(), forumsSeekBar.getProgress(),
forumPostsSeekBar.getProgress()); forumPostsSeekBar.getProgress(),
privateGroupsSeekBar.getProgress(),
privateGroupPostsSeekBar.getProgress());
Intent intent = new Intent(this, ENTRY_ACTIVITY); Intent intent = new Intent(this, ENTRY_ACTIVITY);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent); startActivity(intent);
@@ -136,7 +141,7 @@ public class TestDataActivity extends BriarActivity {
} }
private static class OnSeekBarChangeUpdateProgress private static class OnSeekBarChangeUpdateProgress
implements OnSeekBarChangeListener { extends AbstractOnSeekBarChangeListener {
private final TextView textView; private final TextView textView;
private OnSeekBarChangeUpdateProgress(TextView textView) { private OnSeekBarChangeUpdateProgress(TextView textView) {
@@ -148,7 +153,10 @@ public class TestDataActivity extends BriarActivity {
boolean fromUser) { boolean fromUser) {
textView.setText(String.valueOf(progress)); textView.setText(String.valueOf(progress));
} }
}
private abstract static class AbstractOnSeekBarChangeListener
implements OnSeekBarChangeListener {
@Override @Override
public void onStartTrackingTouch(SeekBar seekBar) { public void onStartTrackingTouch(SeekBar seekBar) {
} }
@@ -157,5 +165,4 @@ public class TestDataActivity extends BriarActivity {
public void onStopTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) {
} }
} }
} }

View File

@@ -191,6 +191,66 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewForumMessages" /> app:layout_constraintTop_toBottomOf="@+id/textViewForumMessages" />
<TextView
android:id="@+id/textViewPrivateGroups"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_medium"
android:text="Number of private groups"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/seekBarForumMessages" />
<SeekBar
android:id="@+id/seekBarPrivateGroups"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:max="50"
android:paddingTop="5dp"
android:progress="5"
app:layout_constraintEnd_toStartOf="@+id/TextViewPrivateGroupsSb"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewPrivateGroups" />
<TextView
android:id="@+id/TextViewPrivateGroupsSb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="2"
android:text="5"
app:layout_constraintBottom_toBottomOf="@+id/seekBarPrivateGroups"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewPrivateGroups" />
<TextView
android:id="@+id/textViewPrivateGroupMessages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_medium"
android:text="Number of private group messages"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/seekBarPrivateGroups" />
<SeekBar
android:id="@+id/seekBarPrivateGroupMessages"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:max="50"
android:paddingTop="5dp"
android:progress="20"
app:layout_constraintEnd_toStartOf="@+id/TextViewPrivateGroupMessagesSb"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewPrivateGroupMessages" />
<TextView
android:id="@+id/TextViewPrivateGroupMessagesSb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="2"
android:text="20"
app:layout_constraintBottom_toBottomOf="@+id/seekBarPrivateGroupMessages"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewPrivateGroupMessages" />
<Button <Button
android:id="@+id/buttonZeroValues" android:id="@+id/buttonZeroValues"
style="@style/BriarButton" style="@style/BriarButton"
@@ -201,7 +261,7 @@
android:text="Zero values" android:text="Zero values"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/seekBarForumMessages" app:layout_constraintTop_toBottomOf="@+id/seekBarPrivateGroupMessages"
app:layout_constraintVertical_bias="1.0" /> app:layout_constraintVertical_bias="1.0" />
<Button <Button

View File

@@ -19,9 +19,12 @@ public interface TestDataCreator {
* @param numBlogPosts Number of blog posts to create. * @param numBlogPosts Number of blog posts to create.
* @param numForums Number of forums to create. * @param numForums Number of forums to create.
* @param numForumPosts Number of forum posts to create per forum. * @param numForumPosts Number of forum posts to create per forum.
* @param numPrivateGroups Number of private groups to create.
* @param numPrivateGroupMessages Number of messages to create per private group.
*/ */
void createTestData(int numContacts, int numPrivateMsgs, int avatarPercent, void createTestData(int numContacts, int numPrivateMsgs, int avatarPercent,
int numBlogPosts, int numForums, int numForumPosts); int numBlogPosts, int numForums, int numForumPosts,
int numPrivateGroups, int numPrivateGroupMessages);
@IoExecutor @IoExecutor
Contact addContact(String name, boolean alias, boolean avatar) Contact addContact(String name, boolean alias, boolean avatar)

View File

@@ -6,6 +6,7 @@ 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.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
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;
@@ -38,6 +39,12 @@ import org.briarproject.briar.api.forum.ForumPost;
import org.briarproject.briar.api.messaging.MessagingManager; import org.briarproject.briar.api.messaging.MessagingManager;
import org.briarproject.briar.api.messaging.PrivateMessage; import org.briarproject.briar.api.messaging.PrivateMessage;
import org.briarproject.briar.api.messaging.PrivateMessageFactory; import org.briarproject.briar.api.messaging.PrivateMessageFactory;
import org.briarproject.briar.api.privategroup.GroupMessage;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationFactory;
import org.briarproject.briar.api.test.TestAvatarCreator; import org.briarproject.briar.api.test.TestAvatarCreator;
import org.briarproject.briar.api.test.TestDataCreator; import org.briarproject.briar.api.test.TestDataCreator;
import org.briarproject.nullsafety.NotNullByDefault; import org.briarproject.nullsafety.NotNullByDefault;
@@ -89,6 +96,10 @@ public class TestDataCreatorImpl implements TestDataCreator {
private final MessagingManager messagingManager; private final MessagingManager messagingManager;
private final BlogManager blogManager; private final BlogManager blogManager;
private final ForumManager forumManager; private final ForumManager forumManager;
private final PrivateGroupManager privateGroupManager;
private final PrivateGroupFactory privateGroupFactory;
private final GroupMessageFactory groupMessageFactory;
private final GroupInvitationFactory groupInvitationFactory;
private final TestAvatarCreator testAvatarCreator; private final TestAvatarCreator testAvatarCreator;
private final AvatarMessageEncoder avatarMessageEncoder; private final AvatarMessageEncoder avatarMessageEncoder;
@@ -111,6 +122,10 @@ public class TestDataCreatorImpl implements TestDataCreator {
TransportPropertyManager transportPropertyManager, TransportPropertyManager transportPropertyManager,
MessagingManager messagingManager, BlogManager blogManager, MessagingManager messagingManager, BlogManager blogManager,
ForumManager forumManager, ForumManager forumManager,
PrivateGroupManager privateGroupManager,
PrivateGroupFactory privateGroupFactory,
GroupMessageFactory groupMessageFactory,
GroupInvitationFactory groupInvitationFactory,
TestAvatarCreator testAvatarCreator, TestAvatarCreator testAvatarCreator,
AvatarMessageEncoder avatarMessageEncoder, AvatarMessageEncoder avatarMessageEncoder,
FeatureFlags featureFlags, FeatureFlags featureFlags,
@@ -128,6 +143,10 @@ public class TestDataCreatorImpl implements TestDataCreator {
this.messagingManager = messagingManager; this.messagingManager = messagingManager;
this.blogManager = blogManager; this.blogManager = blogManager;
this.forumManager = forumManager; this.forumManager = forumManager;
this.privateGroupManager = privateGroupManager;
this.privateGroupFactory = privateGroupFactory;
this.groupMessageFactory = groupMessageFactory;
this.groupInvitationFactory = groupInvitationFactory;
this.testAvatarCreator = testAvatarCreator; this.testAvatarCreator = testAvatarCreator;
this.avatarMessageEncoder = avatarMessageEncoder; this.avatarMessageEncoder = avatarMessageEncoder;
this.featureFlags = featureFlags; this.featureFlags = featureFlags;
@@ -137,14 +156,16 @@ public class TestDataCreatorImpl implements TestDataCreator {
@Override @Override
public void createTestData(int numContacts, int numPrivateMsgs, public void createTestData(int numContacts, int numPrivateMsgs,
int avatarPercent, int numBlogPosts, int numForums, int avatarPercent, int numBlogPosts, int numForums,
int numForumPosts) { int numForumPosts, int numPrivateGroups,
int numPrivateGroupMessages) {
if (numContacts == 0) throw new IllegalArgumentException(); if (numContacts == 0) throw new IllegalArgumentException();
if (avatarPercent < 0 || avatarPercent > 100) if (avatarPercent < 0 || avatarPercent > 100)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
ioExecutor.execute(() -> { ioExecutor.execute(() -> {
try { try {
createTestDataOnIoExecutor(numContacts, numPrivateMsgs, createTestDataOnIoExecutor(numContacts, numPrivateMsgs,
avatarPercent, numBlogPosts, numForums, numForumPosts); avatarPercent, numBlogPosts, numForums, numForumPosts,
numPrivateGroups, numPrivateGroupMessages);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);
} }
@@ -154,7 +175,8 @@ public class TestDataCreatorImpl implements TestDataCreator {
@IoExecutor @IoExecutor
private void createTestDataOnIoExecutor(int numContacts, int numPrivateMsgs, private void createTestDataOnIoExecutor(int numContacts, int numPrivateMsgs,
int avatarPercent, int numBlogPosts, int numForums, int avatarPercent, int numBlogPosts, int numForums,
int numForumPosts) throws DbException { int numForumPosts, int numPrivateGroups,
int numPrivateGroupMessages) throws DbException {
List<Contact> contacts = createContacts(numContacts, avatarPercent); List<Contact> contacts = createContacts(numContacts, avatarPercent);
createPrivateMessages(contacts, numPrivateMsgs); createPrivateMessages(contacts, numPrivateMsgs);
createBlogPosts(contacts, numBlogPosts); createBlogPosts(contacts, numBlogPosts);
@@ -162,6 +184,12 @@ public class TestDataCreatorImpl implements TestDataCreator {
for (Forum forum : forums) { for (Forum forum : forums) {
createRandomForumPosts(forum, contacts, numForumPosts); createRandomForumPosts(forum, contacts, numForumPosts);
} }
List<PrivateGroup> groups =
createPrivateGroups(contacts, numPrivateGroups);
for (PrivateGroup group : groups) {
createRandomPrivateGroupMessages(group, contacts,
numPrivateGroupMessages);
}
} }
private List<Contact> createContacts(int numContacts, int avatarPercent) private List<Contact> createContacts(int numContacts, int avatarPercent)
@@ -464,6 +492,86 @@ public class TestDataCreatorImpl implements TestDataCreator {
} }
} }
private List<PrivateGroup> createPrivateGroups(List<Contact> contacts,
int numPrivateGroups) throws DbException {
if (!featureFlags.shouldEnablePrivateGroupsInCore()) return emptyList();
List<PrivateGroup> groups = new ArrayList<>(numPrivateGroups);
for (int i = 0; i < numPrivateGroups; i++) {
// create private group
String name = GROUP_NAMES[random.nextInt(GROUP_NAMES.length)];
LocalAuthor creator = identityManager.getLocalAuthor();
PrivateGroup group =
privateGroupFactory.createPrivateGroup(name, creator);
GroupMessage joinMsg = groupMessageFactory.createJoinMessage(
group.getId(),
clock.currentTimeMillis() - (long) (100 - i) * 60 * 1000,
creator
);
privateGroupManager.addPrivateGroup(group, joinMsg, true);
groups.add(group);
}
if (LOG.isLoggable(INFO)) {
LOG.info("Created " + numPrivateGroups + " private groups.");
}
return groups;
}
private void createRandomPrivateGroupMessages(PrivateGroup group,
List<Contact> contacts, int amount) throws DbException {
List<GroupMessage> messages = new ArrayList<>();
PrivateKey creatorPrivateKey =
identityManager.getLocalAuthor().getPrivateKey();
int numMembers = random.nextInt(contacts.size());
if (numMembers == 0) numMembers++;
Map<Contact, MessageId> membersLastMessage = new HashMap<>();
List<Contact> members = new ArrayList<>(numMembers);
for (int i = 0; i < numMembers; i++) {
Contact contact = contacts.get(i);
members.add(contact);
}
for (int i = 0; i < amount; i++) {
Contact contact = members.get(random.nextInt(numMembers));
LocalAuthor author = localAuthors.get(contact);
long timestamp =
clock.currentTimeMillis() -
(long) (amount - i) * 60 * 1000;
GroupMessage msg;
if (!membersLastMessage.containsKey(contact)) {
// join message as first message of member
shareGroup(contact.getId(), group.getId());
long inviteTimestamp = timestamp - 1;
byte[] creatorSignature =
groupInvitationFactory.signInvitation(contact,
group.getId(), inviteTimestamp,
creatorPrivateKey);
msg = groupMessageFactory.createJoinMessage(group.getId(),
timestamp, author, inviteTimestamp,
creatorSignature);
} else {
// random text after first message
String text = getRandomText();
MessageId parent = null;
if (random.nextBoolean() && messages.size() > 0) {
GroupMessage parentMessage =
messages.get(random.nextInt(messages.size()));
parent = parentMessage.getMessage().getId();
}
MessageId lastMsg = membersLastMessage.get(contact);
msg = groupMessageFactory.createGroupMessage(
group.getId(), timestamp, parent, author, text,
lastMsg);
messages.add(msg);
}
membersLastMessage.put(contact, msg.getMessage().getId());
db.transaction(false, txn ->
db.receiveMessage(txn, contact.getId(), msg.getMessage()));
}
if (LOG.isLoggable(INFO)) {
LOG.info("Created " + amount + " private group messages.");
}
}
private String getRandomText() { private String getRandomText() {
int minLength = 3 + random.nextInt(500); int minLength = 3 + random.nextInt(500);
int maxWordLength = 15; int maxWordLength = 15;