Skip to content

Commit

Permalink
Add Channel bookmarks to loadtest (#828)
Browse files Browse the repository at this point in the history
* Add Channel bookmarks to loadtest

* update dependency to reflect changes in client4.go

* fixes after model.NewString, model.NewBool and others were removed?

* missing replacement of model.New...

* add parameter to cfg.Sanitize

* use model.NewPointer

* feedback review

* feedback review 2

* feedback review 3

* upload 4 files for posts and drafts
  • Loading branch information
enahum authored Nov 7, 2024
1 parent ce857d4 commit 4e7633c
Show file tree
Hide file tree
Showing 21 changed files with 468 additions and 48 deletions.
2 changes: 1 addition & 1 deletion api/agent_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func createFakeMMServer() *httptest.Server {
case "/api/v4/config":
mmCfg := model.Config{}
mmCfg.SetDefaults()
mmCfg.TeamSettings.MaxUsersPerTeam = model.NewInt(10000)
mmCfg.TeamSettings.MaxUsersPerTeam = model.NewPointer(10000)
json.NewEncoder(w).Encode(mmCfg)
case "/api/v4/emoji":
json.NewEncoder(w).Encode(&model.Emoji{})
Expand Down
2 changes: 1 addition & 1 deletion cmd/ltctl/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func collect(config deployment.Config, deploymentId string, outputName string) e
if err := json.Unmarshal(input, &cfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal MM configuration: %w", err)
}
cfg.Sanitize()
cfg.Sanitize(nil)
sanitizedCfg, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return nil, fmt.Errorf("failed to sanitize MM configuration: %w", err)
Expand Down
4 changes: 2 additions & 2 deletions deployment/terraform/cloudwatchlogs.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ func (t *Terraform) createCloudWatchLogsPolicy() error {
docJsonStr := string(docJsonBytes)

input := cloudwatchlogs.PutResourcePolicyInput{
PolicyName: model.NewString("lt-cloudwatch-log-policy"),
PolicyDocument: model.NewString(docJsonStr),
PolicyName: model.NewPointer("lt-cloudwatch-log-policy"),
PolicyDocument: model.NewPointer(docJsonStr),
}
if _, err := cwclient.PutResourcePolicy(context.Background(), &input); err != nil {
return fmt.Errorf("failed to create CloudWatchLogs policy; it can be manually created by running `aws logs put-resource-policy --policy-name lt-cloudwatch-log-policy --policy-document %q`; the next `deployment create` should work when such a policy is present in the AWS account; original error: %w", docJsonStr, err)
Expand Down
6 changes: 3 additions & 3 deletions deployment/terraform/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -1066,10 +1066,10 @@ func (t *Terraform) updateAppConfig(siteURL string, sshc *ssh.Client, jobServerE
}

if t.output.HasRedis() {
cfg.CacheSettings.CacheType = model.NewString(model.CacheTypeRedis)
cfg.CacheSettings.CacheType = model.NewPointer(model.CacheTypeRedis)
redisEndpoint := net.JoinHostPort(t.output.RedisServer.Address, strconv.Itoa(t.output.RedisServer.Port))
cfg.CacheSettings.RedisAddress = model.NewString(redisEndpoint)
cfg.CacheSettings.RedisDB = model.NewInt(0)
cfg.CacheSettings.RedisAddress = model.NewPointer(redisEndpoint)
cfg.CacheSettings.RedisDB = model.NewPointer(0)
}

if t.config.MattermostConfigPatchFile != "" {
Expand Down
1 change: 1 addition & 0 deletions deployment/terraform/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Group=ubuntu
LimitNOFILE=49152
Environment=MM_FEATUREFLAGS_POSTPRIORITY=true
Environment=MM_FEATUREFLAGS_WEBSOCKETEVENTSCOPE=true
Environment=MM_FEATUREFLAGS_CHANNELBOOKMARKS=true
Environment=MM_SERVICEENVIRONMENT=%s
[Install]
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/mattermost/mattermost-load-test-ng

go 1.22
go 1.22.0

toolchain go1.22.8

Expand Down Expand Up @@ -32,8 +32,8 @@ require (
github.com/gliderlabs/ssh v0.1.1
github.com/grafana/alloy/syntax v0.1.0
github.com/graph-gophers/graphql-go v1.5.1-0.20230110080634-edea822f558a
github.com/mattermost/mattermost/server/public v0.1.7-0.20240806035841-540febd866aa
github.com/mattermost/mattermost/server/v8 v8.0.0-20240726090344-5547504c1d68
github.com/mattermost/mattermost/server/public v0.1.8-0.20241015185928-63c97f5a6d8f
github.com/mattermost/mattermost/server/v8 v8.0.0-20241015185928-63c97f5a6d8f
github.com/opensearch-project/opensearch-go/v4 v4.1.0
github.com/pelletier/go-toml/v2 v2.2.2
github.com/vmihailenco/msgpack/v5 v5.4.1
Expand Down Expand Up @@ -141,7 +141,7 @@ require (
github.com/yudai/pp v2.0.1+incompatible // indirect
github.com/yuin/goldmark v1.7.4 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240725223205-93522f1f2a9f // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,10 @@ github.com/mattermost/ldap v3.0.4+incompatible h1:SOeNnz+JNR+foQ3yHkYqijb9MLPhXN
github.com/mattermost/ldap v3.0.4+incompatible/go.mod h1:b4reDCcGpBxJ4WX0f224KFY+OR0npin7or7EFpeIko4=
github.com/mattermost/logr/v2 v2.0.21 h1:CMHsP+nrbRlEC4g7BwOk1GAnMtHkniFhlSQPXy52be4=
github.com/mattermost/logr/v2 v2.0.21/go.mod h1:kZkB/zqKL9e+RY5gB3vGpsyenC+TpuiOenjMkvJJbzc=
github.com/mattermost/mattermost/server/public v0.1.7-0.20240806035841-540febd866aa h1:KB8BE35ITSzVaCBoMj3NP9WHiJi/PLJD0Hgw5N9QpNM=
github.com/mattermost/mattermost/server/public v0.1.7-0.20240806035841-540febd866aa/go.mod h1:Dm5uf3z8ckDOKYD1cbnb1Uqm/G9WYIaouSP/HnH+Rbs=
github.com/mattermost/mattermost/server/v8 v8.0.0-20240726090344-5547504c1d68 h1:5EoqvfOGhU+b0E2h4XdMxtCReyGZVBIWBiYYk6WTEoU=
github.com/mattermost/mattermost/server/v8 v8.0.0-20240726090344-5547504c1d68/go.mod h1:bCPUN2odATk4v9Gox88gBphLhnrJfEvqNQtaFVVVso4=
github.com/mattermost/mattermost/server/public v0.1.8-0.20241015185928-63c97f5a6d8f h1:NUAf56HZHFLayAyCqHxeVLmxJUN9xw3Qxc9m3ghy+Xw=
github.com/mattermost/mattermost/server/public v0.1.8-0.20241015185928-63c97f5a6d8f/go.mod h1:SkTKbMul91Rq0v2dIxe8mqzUOY+3KwlwwLmAlxDfGCk=
github.com/mattermost/mattermost/server/v8 v8.0.0-20241015185928-63c97f5a6d8f h1:h4T89Qkb3kddGnRN7xQAuB+fDaL3OgUgc5YPmssmzj8=
github.com/mattermost/mattermost/server/v8 v8.0.0-20241015185928-63c97f5a6d8f/go.mod h1:zwMZYGK4/xDy/kyepVBqXhM58YMTCRlanv/uKrZzJdw=
github.com/mattermost/morph v1.1.0 h1:Q9vrJbeM3s2jfweGheq12EFIzdNp9a/6IovcbvOQ6Cw=
github.com/mattermost/morph v1.1.0/go.mod h1:gD+EaqX2UMyyuzmF4PFh4r33XneQ8Nzi+0E8nXjMa3A=
github.com/mattermost/squirrel v0.4.0 h1:azf9LZ+8JUTAvwt/njB1utkPqWQ6e7Rje2ya5N0P2i4=
Expand Down Expand Up @@ -586,8 +586,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
Expand Down
16 changes: 11 additions & 5 deletions loadtest/control/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ func CreateAckPost(u user.User) UserActionResponse {
CreateAt: time.Now().UnixMilli(),
Metadata: &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(true),
Priority: model.NewPointer(model.PostPriorityUrgent),
RequestedAck: model.NewPointer(true),
},
},
})
Expand Down Expand Up @@ -346,9 +346,9 @@ func CreatePersistentNotificationPost(u user.User) UserActionResponse {
CreateAt: time.Now().UnixMilli(),
Metadata: &model.PostMetadata{
Priority: &model.PostPriority{
Priority: model.NewString(model.PostPriorityUrgent),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(true),
Priority: model.NewPointer(model.PostPriorityUrgent),
RequestedAck: model.NewPointer(false),
PersistentNotifications: model.NewPointer(true),
},
},
})
Expand Down Expand Up @@ -1032,6 +1032,12 @@ func DraftsEnabled(u user.User) (bool, UserActionResponse) {
return allow, UserActionResponse{}
}

func ChannelBookmarkEnabled(u user.User) (bool, UserActionResponse) {
allow := u.Store().FeatureFlags()["ChannelBookmarks"]

return allow, UserActionResponse{}
}

// MessageExport simulates the given user performing
// a compliance message export
func MessageExport(u user.User) UserActionResponse {
Expand Down
6 changes: 3 additions & 3 deletions loadtest/control/gencontroller/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ func (c *GenController) createPost(u user.User) (res control.UserActionResponse)
if isUrgent {
post.Metadata = &model.PostMetadata{}
post.Metadata.Priority = &model.PostPriority{
Priority: model.NewString("urgent"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(false),
Priority: model.NewPointer("urgent"),
RequestedAck: model.NewPointer(false),
PersistentNotifications: model.NewPointer(false),
}
}

Expand Down
12 changes: 9 additions & 3 deletions loadtest/control/simulcontroller/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,12 @@ func switchChannel(u user.User) control.UserActionResponse {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

if u.Store().FeatureFlags()["ChannelBookmarks"] {
if err := u.GetChannelBookmarks(channel.Id, 0); err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}
}

if u.Store().FeatureFlags()["WebSocketEventScope"] {
if err := u.UpdateActiveChannel(channel.Id); err != nil {
mlog.Warn("Failed to update active channel", mlog.String("channel_id", channel.Id))
Expand Down Expand Up @@ -796,9 +802,9 @@ func (c *SimulController) createPost(u user.User) control.UserActionResponse {
if isUrgent {
post.Metadata = &model.PostMetadata{}
post.Metadata.Priority = &model.PostPriority{
Priority: model.NewString("urgent"),
RequestedAck: model.NewBool(false),
PersistentNotifications: model.NewBool(false),
Priority: model.NewPointer("urgent"),
RequestedAck: model.NewPointer(false),
PersistentNotifications: model.NewPointer(false),
}
}

Expand Down
155 changes: 155 additions & 0 deletions loadtest/control/simulcontroller/bookmarks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright (c) 2019-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

package simulcontroller

import (
"fmt"
"math/rand"

"github.com/mattermost/mattermost-load-test-ng/loadtest/control"
"github.com/mattermost/mattermost-load-test-ng/loadtest/user"
"github.com/mattermost/mattermost/server/public/model"
)

var (
bookmarkNames = []string{"this is a file", "this is a link", "this is another file", "this is another link"}
bookmarkType = []model.ChannelBookmarkType{model.ChannelBookmarkLink, model.ChannelBookmarkFile}
)

func (c *SimulController) addChannelBookmark(u user.User) control.UserActionResponse {
if ok, resp := control.ChannelBookmarkEnabled(u); resp.Err != nil {
return resp
} else if !ok {
return control.UserActionResponse{Info: "channel bookmarks not enabled"}
}

channel, err := u.Store().CurrentChannel()
if err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

emoji := ""
// 10% of the times bookmarks will have an emoji assigned.
// https://mattermost.atlassian.net/browse/MM-61131
if rand.Float64() < 0.1 {
emoji = control.RandomEmoji()
}

bookmark := &model.ChannelBookmark{
ChannelId: channel.Id,
DisplayName: control.PickRandomString(bookmarkNames),
Emoji: emoji,
Type: bookmarkType[rand.Intn(len(bookmarkType))],
}

if bookmark.Type == model.ChannelBookmarkFile {
control.AttachFileToBookmark(u, bookmark)
} else {
bookmark.LinkUrl = control.RandomLink()
}

err = u.AddChannelBookmark(bookmark)
if err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

return control.UserActionResponse{Info: fmt.Sprintf("bookmark created in channel id %v", channel.Id)}
}

func (c *SimulController) updateBookmark(u user.User) control.UserActionResponse {
if ok, resp := control.ChannelBookmarkEnabled(u); resp.Err != nil {
return resp
} else if !ok {
return control.UserActionResponse{Info: "channel bookmarks not enabled"}
}

channel, err := u.Store().CurrentChannel()
if err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

currentBookmarks := u.Store().ChannelBookmarks(channel.Id)
if len(currentBookmarks) == 0 {
return control.UserActionResponse{Info: fmt.Sprintf("channel id %v does not have bookmarks to update", channel.Id)}
}

// here we update
bookmark := currentBookmarks[rand.Intn(len(currentBookmarks))]
bookmarkWithFileInfo := bookmark.Clone()
bookmarkWithFileInfo.DisplayName = control.PickRandomString(bookmarkNames)

// 10% of the times bookmarks will have an emoji assigned.
// https://mattermost.atlassian.net/browse/MM-61131
if bookmarkWithFileInfo.Emoji == "" && rand.Float64() < 0.1 {
bookmarkWithFileInfo.Emoji = control.RandomEmoji()
}

if bookmarkWithFileInfo.Type == model.ChannelBookmarkFile {
control.AttachFileToBookmark(u, bookmarkWithFileInfo.ChannelBookmark)
} else {
bookmarkWithFileInfo.LinkUrl = control.RandomLink()
}

err = u.UpdateChannelBookmark(bookmarkWithFileInfo)

if err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

return control.UserActionResponse{Info: fmt.Sprintf("bookmark %v updated in channel id %v", bookmarkWithFileInfo.Id, channel.Id)}
}

func (c *SimulController) deleteBookmark(u user.User) control.UserActionResponse {
if ok, resp := control.ChannelBookmarkEnabled(u); resp.Err != nil {
return resp
} else if !ok {
return control.UserActionResponse{Info: "channel bookmarks not enabled"}
}

channel, err := u.Store().CurrentChannel()
if err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

currentBookmarks := u.Store().ChannelBookmarks(channel.Id)
if len(currentBookmarks) == 0 {
return control.UserActionResponse{Info: "no channel bookmarks found"}
}

bookmark := currentBookmarks[rand.Intn(len(currentBookmarks))]
err = u.DeleteChannelBookmark(bookmark.ChannelId, bookmark.Id)
if err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

return control.UserActionResponse{Info: fmt.Sprintf("bookmark id %v deleted in channel id %v", bookmark.Id, channel.Id)}
}

func (c *SimulController) updateBookmarksSortOrder(u user.User) control.UserActionResponse {
if ok, resp := control.ChannelBookmarkEnabled(u); resp.Err != nil {
return resp
} else if !ok {
return control.UserActionResponse{Info: "channel bookmarks not enabled"}
}

channel, err := u.Store().CurrentChannel()
if err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

currentBookmarks := u.Store().ChannelBookmarks(channel.Id)
if len(currentBookmarks) <= 1 {
return control.UserActionResponse{Info: "not enough channel bookmarks to sort"}
}

bookmark := currentBookmarks[rand.Intn(len(currentBookmarks))]
newIndex := rand.Int63n(int64(len(currentBookmarks)))
err = u.UpdateChannelBookmarkSortOrder(channel.Id, bookmark.Id, newIndex)
if err != nil {
return control.UserActionResponse{Err: control.NewUserError(err)}
}

return control.UserActionResponse{Info: fmt.Sprintf("bookmark id %v in channel id %v sorted at index %d", bookmark.Id, channel.Id, newIndex)}

}
24 changes: 24 additions & 0 deletions loadtest/control/simulcontroller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,30 @@ func getActionList(c *SimulController) []userAction {
frequency: 1.41,
minServerVersion: control.MinSupportedVersion, // 7.7.0
},
{
name: "AddChannelBookmark",
run: c.addChannelBookmark,
frequency: 0.0003, // https://mattermost.atlassian.net/browse/MM-61131
minServerVersion: semver.MustParse("10.0.0"),
},
{
name: "UpdateOrAddChannelBookark",
run: c.updateBookmark,
frequency: 0.0002, // https://mattermost.atlassian.net/browse/MM-61131
minServerVersion: semver.MustParse("10.0.0"),
},
{
name: "UpdateChannelBookarkSortOrder",
run: c.updateBookmarksSortOrder,
frequency: 0.0002, // https://mattermost.atlassian.net/browse/MM-61131
minServerVersion: semver.MustParse("10.0.0"),
},
{
name: "DeleteChannelBookark",
run: c.deleteBookmark,
frequency: 0.0001, // https://mattermost.atlassian.net/browse/MM-61131
minServerVersion: semver.MustParse("10.0.0"),
},
// All actions are required to contain a valid minServerVersion:
// - If the action is present in server versions equal or older than
// control.MinSupportedVersion, use control.MinSupportedVersion.
Expand Down
Loading

0 comments on commit 4e7633c

Please sign in to comment.