Skip to content

Commit

Permalink
Merge branch 'develop' into feat/parse-and-store-locationmessags
Browse files Browse the repository at this point in the history
  • Loading branch information
yamilmedina authored Dec 6, 2023
2 parents 5a9eb0e + 4e75095 commit 33dfbb3
Show file tree
Hide file tree
Showing 21 changed files with 578 additions and 477 deletions.
122 changes: 104 additions & 18 deletions monkeys/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,23 +145,56 @@
"description": "Should the application dump the users created into a file",
"type": "boolean"
},
"users": {
"description": "All users that are going to be used in the test. If set the parameters to create users will be ignored",
"type": "array",
"items": {
"type": "object",
"required": [
"email",
"id"
],
"properties": {
"email": {
"description": "Email of the user",
"type": "string"
},
"id": {
"description": "UUID of the user",
"type": "string"
"presetTeam": {
"description": "Team configuration and its users to use instead of creating them",
"type": "object",
"required": [
"id",
"owner",
"users"
],
"properties": {
"id": {
"description": "The team id",
"type": "string"
},
"owner": {
"description": "The creator of the group. It will be used to fetch the team's users, so it must have permission in the API to do so",
"type": "object",
"required": [
"email",
"id"
],
"properties": {
"email": {
"description": "Email of the user",
"type": "string"
},
"id": {
"description": "UUID of the user",
"type": "string"
}
}
},
"users": {
"description": "All users that are going to be used in the test. If set the parameters to create users will be ignored",
"type": "array",
"items": {
"type": "object",
"required": [
"email",
"id"
],
"properties": {
"email": {
"description": "Email of the user",
"type": "string"
},
"id": {
"description": "UUID of the user",
"type": "string"
}
}
}
}
}
Expand Down Expand Up @@ -225,7 +258,9 @@
"ADD_USERS_TO_CONVERSATION",
"LEAVE_CONVERSATION",
"DESTROY_CONVERSATION",
"SEND_REQUEST"
"SEND_REQUEST",
"HANDLE_EXTERNAL_REQUEST",
"SEND_EXTERNAL_REQUEST"
]
}
},
Expand Down Expand Up @@ -254,6 +289,12 @@
},
{
"$ref": "#/$defs/SendRequest"
},
{
"$ref": "#/$defs/SendExternalRequest"
},
{
"$ref": "#/$defs/HandleExternalRequest"
}
]
}
Expand Down Expand Up @@ -426,6 +467,51 @@
"type": "boolean"
}
}
},
"SendExternalRequest": {
"description": "Picks a random user and send a connection request to an user not on the scope of the monkeys",
"type": "object",
"required": [
"userCount",
"originTeam",
"targetTeam"
],
"properties": {
"userCount": {
"description": "How many users should send requests",
"$ref": "#/$defs/UserCount"
},
"originTeam": {
"description": "Users from which team should the requests originate",
"type": "string"
},
"targetTeam": {
"description": "Users from which team should be targeted",
"type": "string"
}
}
},
"HandleExternalRequest": {
"description": "Searches for a monkey with pending connection requests and accepts or rejects it. At this moment it considers also connection requests from other monkeys",
"type": "object",
"required": [
"userCount",
"shouldAccept"
],
"properties": {
"userCount": {
"description": "How many users should handle requests",
"$ref": "#/$defs/UserCount"
},
"shouldAccept": {
"description": "If the request should be accepted or not",
"type": "boolean"
},
"greetMessage": {
"description": "If accepted, this custom message will be sent to the other user. If not informed a random message will be sent.",
"type": "string"
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ object ActionScheduler {
suspend fun start(testCase: String, actions: List<ActionConfig>, coreLogic: CoreLogic, monkeyPool: MonkeyPool) {
actions.forEach { actionConfig ->
CoroutineScope(Dispatchers.Default).launch {
while (this.isActive) {
val actionName = actionConfig.type::class.serializer().descriptor.serialName
val actionName = actionConfig.type::class.serializer().descriptor.serialName
do {
val tags = listOf(Tag.of("testCase", testCase))
try {
logger.i("Running action $actionName: ${actionConfig.description} ${actionConfig.count} times")
Expand All @@ -58,7 +58,8 @@ object ActionScheduler {
MetricsCollector.count("c_errors", tags.plusElement(Tag.of("action", actionName)))
}
delay(actionConfig.repeatInterval.toLong())
}
} while (this.isActive && actionConfig.repeatInterval > 0u)
logger.i("Task for action $actionName finished")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class MonkeyApplication : CliktCommand(allowMultipleSubcommands = true) {
if (logOutputFile != null) {
CoreLogger.init(KaliumLogger.Config(logLevel, listOf(fileLogger)))
} else {
CoreLogger.init(KaliumLogger.Config(logLevel, emptyList()))
CoreLogger.init(KaliumLogger.Config(logLevel))
}
MonkeyLogger.init(KaliumLogger.Config(logLevel, listOf(monkeyFileLogger)))
logger.i("Initializing Metrics Endpoint")
Expand All @@ -81,22 +81,20 @@ class MonkeyApplication : CliktCommand(allowMultipleSubcommands = true) {

private suspend fun runMonkeys(
testData: TestData
) = with(testData) {
) {
val users = TestDataImporter.generateUserData(testData)
testData.testCases.forEachIndexed { index, testCase ->
val monkeyPool = MonkeyPool(users, testCase.name)
return testData.testCases.forEachIndexed { index, testCase ->
val coreLogic = coreLogic("$HOME_DIRECTORY/.kalium/${testCase.name.replace(' ', '_')}")
// the first one creates the preset groups
logger.i("Logging in and out all users to create key packages")
val monkeyPool = MonkeyPool(users, testCase.name)
// the first one creates the preset groups and logs everyone in so keypackages are created
if (index == 0) {
logger.i("Creating initial key packages for clients (logging everyone in and out). This can take a while...")
monkeyPool.warmUp(coreLogic)
logger.i("Creating prefixed groups")
testData.conversationDistribution.forEach { (prefix, config) ->
ConversationPool.createPrefixedConversations(
coreLogic,
prefix,
config.groupCount,
config.userCount,
config.protocol,
monkeyPool
coreLogic, prefix, config.groupCount, config.userCount, config.protocol, monkeyPool
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ abstract class Action {
is ActionType.Reconnect -> ReconnectAction(config.type)
is ActionType.SendMessage -> SendMessageAction(config.type)
is ActionType.SendRequest -> SendRequestAction(config.type)
is ActionType.HandleExternalRequest -> HandleExternalRequestAction(config.type)
is ActionType.SendExternalRequest -> SendExternalRequestAction(config.type)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.monkeys.actions

import com.wire.kalium.logic.CoreLogic
import com.wire.kalium.monkeys.conversation.Monkey
import com.wire.kalium.monkeys.importer.ActionType
import com.wire.kalium.monkeys.pool.MonkeyPool

private val DIRECT_MESSAGES = arrayOf(
"""
Hey there,
I hope you're doing well. I've got a bit of a craving for bananas, and I was wondering if you might be able to share a few with me?
It would mean a lot. 😊
Thanks a bunch,
A friendly monkey 🍌🐵
""".trimIndent(), """
Yo,
I'm in need of some bananas, my friend. Can you hook me up? I'd appreciate it big time.
Respect,
A neutral monkey 🍌
""".trimIndent(), """
Listen up,
I ain't messin' around. I want them bananas, and I want 'em now. You better deliver or there'll be consequences.
No games,
An evil monkey 🍌👿💀
""".trimIndent()
)

class HandleExternalRequestAction(val config: ActionType.HandleExternalRequest) : Action() {
override suspend fun execute(coreLogic: CoreLogic, monkeyPool: MonkeyPool) {
val monkeys = monkeyPool.randomMonkeysWithConnectionRequests(config.userCount)
monkeys.forEach { (monkey, pendingConnections) ->
if (config.shouldAccept) {
val otherUser =
Monkey.external(pendingConnections.random().otherUser?.id ?: error("Cannot get other user id from connection request"))
monkey.acceptRequest(otherUser)
monkey.sendDirectMessageTo(otherUser, config.greetMessage.ifBlank { DIRECT_MESSAGES.random() })
} else {
monkey.rejectRequest(Monkey.external(pendingConnections.random().connection.qualifiedToId))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class LeaveConversationAction(val config: ActionType.LeaveConversation) : Action
targets.forEach { conv ->
val leavers = conv.randomMonkeys(this.config.userCount)
// conversation admin should never leave the group
leavers.filter { it.user != conv.creator.user }.forEach {
leavers.filter { it.monkeyType.userData() != conv.creator.monkeyType.userData() }.forEach {
it.leaveConversation(conv.conversation.id)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.monkeys.actions

import com.wire.kalium.logic.CoreLogic
import com.wire.kalium.monkeys.importer.ActionType
import com.wire.kalium.monkeys.pool.MonkeyPool

class SendExternalRequestAction(val config: ActionType.SendExternalRequest) : Action() {
override suspend fun execute(coreLogic: CoreLogic, monkeyPool: MonkeyPool) {
val monkeys = monkeyPool.randomLoggedInMonkeysFromTeam(config.originTeam, config.userCount)
val usersFromTeam = monkeyPool.externalUsersFromTeam(config.targetTeam)
monkeys.forEach { monkey ->
monkey.sendRequest(usersFromTeam.random())
}
}
}
Loading

0 comments on commit 33dfbb3

Please sign in to comment.