Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance testing groups #457

Merged
merged 19 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions example/src/TestScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useRoute } from '@react-navigation/native'
import React, { useEffect, useState } from 'react'
import { View, Text, Button, ScrollView } from 'react-native'

import { groupPerformanceTests } from './tests/groupPerformanceTests'
import { groupPermissionsTests } from './tests/groupPermissionsTests'
import { groupTests } from './tests/groupTests'
import { restartStreamTests } from './tests/restartStreamsTests'
Expand Down Expand Up @@ -108,6 +109,7 @@ export enum TestCategory {
group = 'group',
restartStreans = 'restartStreams',
groupPermissions = 'groupPermissions',
groupPerformance = 'groupPerformance',
}

export default function TestScreen(): JSX.Element {
Expand All @@ -121,6 +123,7 @@ export default function TestScreen(): JSX.Element {
...groupTests,
...restartStreamTests,
...groupPermissionsTests,
...groupPerformanceTests,
]
let activeTests, title
switch (params.testSelection) {
Expand All @@ -136,10 +139,6 @@ export default function TestScreen(): JSX.Element {
activeTests = groupTests
title = 'Group Unit Tests'
break
case TestCategory.createdAt:
activeTests = createdAtTests
title = 'Created At Unit Tests'
break
case TestCategory.restartStreans:
activeTests = restartStreamTests
title = 'Restart Streams Unit Tests'
Expand All @@ -148,6 +147,10 @@ export default function TestScreen(): JSX.Element {
activeTests = groupPermissionsTests
title = 'Group Permissions Unit Tests'
break
case TestCategory.groupPerformance:
activeTests = groupPerformanceTests
title = 'Group Performance Unit Tests'
break
}

return (
Expand Down
270 changes: 270 additions & 0 deletions example/src/tests/groupPerformanceTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
/* eslint-disable @typescript-eslint/no-extra-non-null-assertion */
import { Client, Group } from 'xmtp-react-native-sdk'

import { Test, assert, createClients } from './test-utils'

export const groupPerformanceTests: Test[] = []
let counter = 1
function test(name: string, perform: () => Promise<boolean>) {
groupPerformanceTests.push({
name: String(counter++) + '. ' + name,
run: perform,
})
}

async function createGroups(
client: Client,
peers: Client[],
numGroups: number,
numMessages: number
): Promise<Group[]> {
const groups = []
const addresses: string[] = peers.map((client) => client.address)
for (let i = 0; i < numGroups; i++) {
const group = await client.conversations.newGroup(addresses, {
name: `group ${i}`,
imageUrlSquare: `www.group${i}.com`,
description: `group ${i}`,
})
groups.push(group)
for (let i = 0; i < numMessages; i++) {
await group.send({ text: `Alix message ${i}` })
}
}
return groups
}

let alixClient: Client
let boClient: Client
let initialPeers: Client[]
let initialGroups: Group[]

async function beforeAll(
groupSize: number = 1,
groupMessages: number = 1,
peersSize: number = 1
) {
;[alixClient] = await createClients(1)

initialPeers = await createClients(peersSize)
boClient = initialPeers[0]

initialGroups = await createGroups(
alixClient,
initialPeers,
groupSize,
groupMessages
)
}

test('testing large group listings', async () => {
await beforeAll(1000)

let start = Date.now()
let groups = await alixClient.conversations.listGroups()
let end = Date.now()
console.log(`Alix loaded ${groups.length} groups in ${end - start}ms`)
assert(
end - start < 3000,
'listing 1000 groups should take less than a 3 second'
)

start = Date.now()
await alixClient.conversations.syncGroups()
end = Date.now()
console.log(`Alix synced ${groups.length} groups in ${end - start}ms`)
assert(
end - start < 100,
'syncing 1000 cached groups should take less than a .1 second'
)

start = Date.now()
await boClient.conversations.syncGroups()
end = Date.now()
console.log(`Bo synced ${groups.length} groups in ${end - start}ms`)
assert(
end - start < 6000,
'syncing 1000 groups should take less than a 6 second'
)

start = Date.now()
groups = await boClient.conversations.listGroups()
end = Date.now()
console.log(`Bo loaded ${groups.length} groups in ${end - start}ms`)
assert(
end - start < 3000,
'loading 1000 groups should take less than a 3 second'
)

return true
})

test('testing large message listings', async () => {
await beforeAll(1, 2000)

const alixGroup = initialGroups[0]
let start = Date.now()
let messages = await alixGroup.messages()
let end = Date.now()
console.log(`Alix loaded ${messages.length} messages in ${end - start}ms`)
assert(
end - start < 1000,
'listing 2000 self messages should take less than a 1 second'
)

start = Date.now()
await alixGroup.sync()
end = Date.now()
console.log(`Alix synced ${messages.length} messages in ${end - start}ms`)
assert(
end - start < 100,
'syncing 2000 self messages should take less than a .1 second'
)

await boClient.conversations.syncGroups()
const boGroup = await boClient.conversations.findGroup(alixGroup.id)
start = Date.now()
await boGroup!.sync()
end = Date.now()
console.log(`Bo synced ${messages.length} messages in ${end - start}ms`)
assert(
end - start < 3000,
'syncing 2000 messages should take less than a 3 second'
)

start = Date.now()
messages = await boGroup!.messages()
end = Date.now()
console.log(`Bo loaded ${messages.length} messages in ${end - start}ms`)
assert(
end - start < 1000,
'loading 2000 messages should take less than a 1 second'
)

return true
})

test('testing large member listings', async () => {
await beforeAll(1, 1, 50)

const alixGroup = initialGroups[0]
let start = Date.now()
let members = await alixGroup.members
let end = Date.now()
console.log(`Alix loaded ${members.length} members in ${end - start}ms`)
assert(
end - start < 100,
'listing 50 members should take less than a .1 second'
)

start = Date.now()
await alixGroup.sync()
end = Date.now()
console.log(`Alix synced ${members.length} members in ${end - start}ms`)
assert(
end - start < 100,
'syncing 50 members should take less than a .1 second'
)

await boClient.conversations.syncGroups()
const boGroup = await boClient.conversations.findGroup(alixGroup.id)
start = Date.now()
await boGroup!.sync()
end = Date.now()
console.log(`Bo synced ${members.length} members in ${end - start}ms`)
assert(
end - start < 100,
'syncing 50 members should take less than a .1 second'
)

start = Date.now()
members = await boGroup!.members
end = Date.now()
console.log(`Bo loaded ${members.length} members in ${end - start}ms`)
assert(
end - start < 100,
'loading 50 members should take less than a .1 second'
)

const [davonClient] = await createClients(1)

start = Date.now()
await alixGroup.addMembers([davonClient.address])
end = Date.now()
console.log(`Alix added 1 member in ${end - start}ms`)
assert(end - start < 100, 'adding 1 member should take less than a .1 second')

start = Date.now()
members = await alixGroup.members
end = Date.now()
console.log(`Alix loaded ${members.length} members in ${end - start}ms`)
assert(
end - start < 100,
'loading 50 member should take less than a .1 second'
)

start = Date.now()
await boGroup!.sync()
end = Date.now()
console.log(`Bo synced ${members.length} members in ${end - start}ms`)
assert(
end - start < 100,
'syncing 50 member should take less than a .1 second'
)

start = Date.now()
members = await boGroup!.members
end = Date.now()
console.log(`Bo loaded ${members.length} members in ${end - start}ms`)
assert(
end - start < 100,
'loading 50 member should take less than a .1 second'
)

return true
})

test('testing sending message in large group', async () => {
await beforeAll(1, 2000, 100)

const alixGroup = initialGroups[0]
let start = Date.now()
await alixGroup.send({ text: `Alix message` })
let end = Date.now()
console.log(`Alix sent a message in ${end - start}ms`)
assert(
end - start < 200,
'sending a message should take less than a .2 second'
)

await boClient.conversations.syncGroups()
const boGroup = await boClient.conversations.findGroup(alixGroup.id)
start = Date.now()
await boGroup!.prepareMessage({ text: `Bo message` })
end = Date.now()
console.log(`Bo sent a message in ${end - start}ms`)
assert(
end - start < 100,
'preparing a message should take less than a .1 second'
)

start = Date.now()
await boGroup!.sync()
end = Date.now()
console.log(`Bo synced messages in ${end - start}ms`)
assert(
end - start < 9000,
'syncing 2000 messages should take less than a 9 second'
)

start = Date.now()
await boGroup!.send({ text: `Bo message 2` })
end = Date.now()
console.log(`Bo sent a message in ${end - start}ms`)
assert(
end - start < 100,
'sending a message should take less than a .1 second'
)

return true
})
nplasterer marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 8 additions & 8 deletions example/src/tests/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Platform } from 'expo-modules-core'
import { Client } from 'xmtp-react-native-sdk'
import { Client, GroupUpdatedCodec } from 'xmtp-react-native-sdk'

export type Test = {
name: string
Expand Down Expand Up @@ -29,13 +29,13 @@ export async function createClients(numClients: number): Promise<Client[]> {
166, 83, 208, 224, 254, 44, 205, 227, 175, 49, 234, 129, 74, 252, 135,
145,
])
clients.push(
await Client.createRandom({
env: 'local',
enableV3: true,
dbEncryptionKey: keyBytes,
})
)
const client = await Client.createRandom({
env: 'local',
enableV3: true,
dbEncryptionKey: keyBytes,
})
client.register(new GroupUpdatedCodec())
clients.push(client)
}
return clients
}
1 change: 1 addition & 0 deletions example/src/types/react-native-config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ declare module 'react-native-config' {
export interface NativeConfig {
THIRD_WEB_CLIENT_ID?: string
TEST_PRIVATE_KEY?: string
TEST_V3_PRIVATE_KEY?: string
}

export const Config: NativeConfig
Expand Down
Loading