@@ -33,14 +33,15 @@ import (
33
33
"github.com/coder/coder/v2/codersdk"
34
34
"github.com/coder/coder/v2/codersdk/workspacesdk"
35
35
"github.com/coder/coder/v2/scaletest/agentconn"
36
- "github.com/coder/coder/v2/scaletest/coderconnect "
36
+ "github.com/coder/coder/v2/scaletest/createusers "
37
37
"github.com/coder/coder/v2/scaletest/createworkspaces"
38
38
"github.com/coder/coder/v2/scaletest/dashboard"
39
39
"github.com/coder/coder/v2/scaletest/harness"
40
40
"github.com/coder/coder/v2/scaletest/loadtestutil"
41
41
"github.com/coder/coder/v2/scaletest/reconnectingpty"
42
42
"github.com/coder/coder/v2/scaletest/workspacebuild"
43
43
"github.com/coder/coder/v2/scaletest/workspacetraffic"
44
+ "github.com/coder/coder/v2/scaletest/workspaceupdates"
44
45
"github.com/coder/serpent"
45
46
)
46
47
@@ -57,7 +58,7 @@ func (r *RootCmd) scaletestCmd() *serpent.Command {
57
58
r .scaletestCleanup (),
58
59
r .scaletestDashboard (),
59
60
r .scaletestCreateWorkspaces (),
60
- r .scaletestCoderConnect (),
61
+ r .scaletestWorkspaceUpdates (),
61
62
r .scaletestWorkspaceTraffic (),
62
63
},
63
64
}
@@ -856,16 +857,15 @@ func (r *RootCmd) scaletestCreateWorkspaces() *serpent.Command {
856
857
return cmd
857
858
}
858
859
859
- func (r * RootCmd )scaletestCoderConnect ()* serpent.Command {
860
+ func (r * RootCmd )scaletestWorkspaceUpdates ()* serpent.Command {
860
861
var (
861
862
workspaceCount int64
862
863
powerUserWorkspaces int64
863
- powerUserProportion float64
864
+ powerUserPercentage float64
864
865
workspaceUpdatesTimeout time.Duration
865
866
dialTimeout time.Duration
866
867
template string
867
868
noCleanup bool
868
- noWaitForAgents bool
869
869
870
870
parameterFlags workspaceParameterFlags
871
871
tracingFlags = & scaletestTracingFlags {}
@@ -877,8 +877,8 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
877
877
)
878
878
879
879
cmd := & serpent.Command {
880
- Use :"coder-connect " ,
881
- Short :"Simulate the load of Coder Desktop clients" ,
880
+ Use :"workspace-updates " ,
881
+ Short :"Simulate the load of Coder Desktop clients receiving workspace updates " ,
882
882
Handler :func (inv * serpent.Invocation )error {
883
883
ctx := inv .Context ()
884
884
client ,err := r .TryInitClient (inv )
@@ -910,24 +910,27 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
910
910
if powerUserWorkspaces <= 1 {
911
911
return xerrors .Errorf ("--power-user-workspaces must be greater than 1" )
912
912
}
913
- if powerUserProportion < 0 || powerUserProportion > 100 {
913
+ if powerUserPercentage < 0 || powerUserPercentage > 100 {
914
914
return xerrors .Errorf ("--power-user-proportion must be between 0 and 100" )
915
915
}
916
916
917
- powerUserWorkspaceCount := int64 (float64 (workspaceCount )* powerUserProportion / 100 )
917
+ powerUserWorkspaceCount := int64 (float64 (workspaceCount )* powerUserPercentage / 100 )
918
918
remainder := powerUserWorkspaceCount % powerUserWorkspaces
919
+ // If the power user workspaces can't be evenly divided, round down
920
+ // to the nearest multiple so that we only have two groups of users.
919
921
workspaceCount -= remainder
920
922
powerUserWorkspaceCount -= remainder
921
923
powerUserCount := powerUserWorkspaceCount / powerUserWorkspaces
922
924
regularWorkspaceCount := workspaceCount - powerUserWorkspaceCount
923
925
regularUserCount := regularWorkspaceCount
926
+ regularUserWorkspaceCount := 1
924
927
925
928
_ ,_ = fmt .Fprintf (inv .Stderr ,"Distribution plan:\n " )
926
929
_ ,_ = fmt .Fprintf (inv .Stderr ," Total workspaces: %d\n " ,workspaceCount )
927
930
_ ,_ = fmt .Fprintf (inv .Stderr ," Power users: %d (each owning %d workspaces = %d total)\n " ,
928
931
powerUserCount ,powerUserWorkspaces ,powerUserWorkspaceCount )
929
- _ ,_ = fmt .Fprintf (inv .Stderr ," Regular users: %d (each owning1 workspace = %d total)\n " ,
930
- regularUserCount ,regularWorkspaceCount )
932
+ _ ,_ = fmt .Fprintf (inv .Stderr ," Regular users: %d (each owning%d workspace = %d total)\n " ,
933
+ regularUserCount ,regularUserWorkspaceCount , regularWorkspaceCount )
931
934
932
935
outputs ,err := output .parse ()
933
936
if err != nil {
@@ -951,7 +954,6 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
951
954
RichParameterFile :parameterFlags .richParameterFile ,
952
955
RichParameters :cliRichParameters ,
953
956
})
954
- _ = richParameters
955
957
if err != nil {
956
958
return xerrors .Errorf ("prepare build: %w" ,err )
957
959
}
@@ -963,7 +965,7 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
963
965
tracer := tracerProvider .Tracer (scaletestTracerName )
964
966
965
967
reg := prometheus .NewRegistry ()
966
- metrics := coderconnect .NewMetrics (reg )
968
+ metrics := workspaceupdates .NewMetrics (reg )
967
969
968
970
logger := inv .Logger
969
971
prometheusSrvClose := ServeHandler (ctx ,logger ,promhttp .HandlerFor (reg , promhttp.HandlerOpts {}),prometheusFlags .Address ,"prometheus" )
@@ -981,13 +983,14 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
981
983
982
984
_ ,_ = fmt .Fprintln (inv .Stderr ,"Creating users..." )
983
985
984
- dialBarrier := harness .NewBarrier (int (powerUserCount + regularUserCount ))
986
+ dialBarrier := new (sync.WaitGroup )
987
+ dialBarrier .Add (int (powerUserCount + regularUserCount ))
985
988
986
- configs := make ([]coderconnect .Config ,0 ,powerUserCount + regularUserCount )
989
+ configs := make ([]workspaceupdates .Config ,0 ,powerUserCount + regularUserCount )
987
990
988
- for i := int64 ( 0 ); i < powerUserCount ; i ++ {
989
- config := coderconnect .Config {
990
- User :coderconnect. UserConfig {
991
+ for range powerUserCount {
992
+ config := workspaceupdates .Config {
993
+ User :createusers. Config {
991
994
OrganizationID :me .OrganizationIDs [0 ],
992
995
},
993
996
Workspace : workspacebuild.Config {
@@ -996,13 +999,12 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
996
999
TemplateID :tpl .ID ,
997
1000
RichParameterValues :richParameters ,
998
1001
},
999
- NoWaitForAgents :noWaitForAgents ,
1002
+ NoWaitForAgents :true ,
1000
1003
},
1001
1004
WorkspaceCount :powerUserWorkspaces ,
1002
1005
WorkspaceUpdatesTimeout :workspaceUpdatesTimeout ,
1003
1006
DialTimeout :dialTimeout ,
1004
1007
Metrics :metrics ,
1005
- NoCleanup :noCleanup ,
1006
1008
DialBarrier :dialBarrier ,
1007
1009
}
1008
1010
if err := config .Validate ();err != nil {
@@ -1011,10 +1013,9 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1011
1013
configs = append (configs ,config )
1012
1014
}
1013
1015
1014
- for i := int64 (0 );i < regularUserCount ;i ++ {
1015
- workspaceCount := 1
1016
- config := coderconnect.Config {
1017
- User : coderconnect.UserConfig {
1016
+ for range regularUserCount {
1017
+ config := workspaceupdates.Config {
1018
+ User : createusers.Config {
1018
1019
OrganizationID :me .OrganizationIDs [0 ],
1019
1020
},
1020
1021
Workspace : workspacebuild.Config {
@@ -1023,13 +1024,12 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1023
1024
TemplateID :tpl .ID ,
1024
1025
RichParameterValues :richParameters ,
1025
1026
},
1026
- NoWaitForAgents :noWaitForAgents ,
1027
+ NoWaitForAgents :true ,
1027
1028
},
1028
- WorkspaceCount :int64 (workspaceCount ),
1029
+ WorkspaceCount :int64 (regularUserWorkspaceCount ),
1029
1030
WorkspaceUpdatesTimeout :workspaceUpdatesTimeout ,
1030
1031
DialTimeout :dialTimeout ,
1031
1032
Metrics :metrics ,
1032
- NoCleanup :noCleanup ,
1033
1033
DialBarrier :dialBarrier ,
1034
1034
}
1035
1035
if err := config .Validate ();err != nil {
@@ -1040,16 +1040,9 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1040
1040
1041
1041
th := harness .NewTestHarness (strategy .toStrategy (),cleanupStrategy .toStrategy ())
1042
1042
for i ,config := range configs {
1043
- name := fmt .Sprintf ("coderconnect -%dw" ,config .WorkspaceCount )
1043
+ name := fmt .Sprintf ("workspaceupdates -%dw" ,config .WorkspaceCount )
1044
1044
id := strconv .Itoa (i )
1045
- username ,email ,err := loadtestutil .GenerateUserIdentifier (id )
1046
- if err != nil {
1047
- return xerrors .Errorf ("generate user identifier: %w" ,err )
1048
- }
1049
- config .User .Username = username
1050
- config .User .Email = email
1051
-
1052
- var runner harness.Runnable = coderconnect .NewRunner (client ,config )
1045
+ var runner harness.Runnable = workspaceupdates .NewRunner (client ,config )
1053
1046
if tracingEnabled {
1054
1047
runner = & runnableTraceWrapper {
1055
1048
tracer :tracer ,
@@ -1061,7 +1054,7 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1061
1054
th .AddRun (name ,id ,runner )
1062
1055
}
1063
1056
1064
- _ ,_ = fmt .Fprintln (inv .Stderr ,"RunningCoder Connect scaletest..." )
1057
+ _ ,_ = fmt .Fprintln (inv .Stderr ,"Runningworkspace updates scaletest..." )
1065
1058
testCtx ,testCancel := strategy .toContext (ctx )
1066
1059
defer testCancel ()
1067
1060
err = th .Run (testCtx )
@@ -1082,12 +1075,14 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1082
1075
}
1083
1076
}
1084
1077
1085
- _ ,_ = fmt .Fprintln (inv .Stderr ,"\n Cleaning up..." )
1086
- cleanupCtx ,cleanupCancel := cleanupStrategy .toContext (ctx )
1087
- defer cleanupCancel ()
1088
- err = th .Cleanup (cleanupCtx )
1089
- if err != nil {
1090
- return xerrors .Errorf ("cleanup tests: %w" ,err )
1078
+ if ! noCleanup {
1079
+ _ ,_ = fmt .Fprintln (inv .Stderr ,"\n Cleaning up..." )
1080
+ cleanupCtx ,cleanupCancel := cleanupStrategy .toContext (ctx )
1081
+ defer cleanupCancel ()
1082
+ err = th .Cleanup (cleanupCtx )
1083
+ if err != nil {
1084
+ return xerrors .Errorf ("cleanup tests: %w" ,err )
1085
+ }
1091
1086
}
1092
1087
1093
1088
if res .TotalFail > 0 {
@@ -1105,6 +1100,7 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1105
1100
Env :"CODER_SCALETEST_WORKSPACE_COUNT" ,
1106
1101
Description :"Required: Total number of workspaces to create." ,
1107
1102
Value :serpent .Int64Of (& workspaceCount ),
1103
+ Required :true ,
1108
1104
},
1109
1105
{
1110
1106
Flag :"power-user-workspaces" ,
@@ -1114,11 +1110,11 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1114
1110
Required :true ,
1115
1111
},
1116
1112
{
1117
- Flag :"power-user-proportion " ,
1118
- Env :"CODER_SCALETEST_POWER_USER_PROPORTION " ,
1113
+ Flag :"power-user-percentage " ,
1114
+ Env :"CODER_SCALETEST_POWER_USER_PERCENTAGE " ,
1119
1115
Default :"50.0" ,
1120
1116
Description :"Percentage of total workspaces owned by power-users (0-100)." ,
1121
- Value :serpent .Float64Of (& powerUserProportion ),
1117
+ Value :serpent .Float64Of (& powerUserPercentage ),
1122
1118
},
1123
1119
{
1124
1120
Flag :"workspace-updates-timeout" ,
@@ -1131,7 +1127,7 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1131
1127
Flag :"dial-timeout" ,
1132
1128
Env :"CODER_SCALETEST_DIAL_TIMEOUT" ,
1133
1129
Default :"2m" ,
1134
- Description :"Timeout for dialing theCoder Connect endpoint." ,
1130
+ Description :"Timeout for dialing thetailnet endpoint." ,
1135
1131
Value :serpent .DurationOf (& dialTimeout ),
1136
1132
},
1137
1133
{
@@ -1142,12 +1138,6 @@ func (r *RootCmd) scaletestCoderConnect() *serpent.Command {
1142
1138
Value :serpent .StringOf (& template ),
1143
1139
Required :true ,
1144
1140
},
1145
- {
1146
- Flag :"no-wait-for-agents" ,
1147
- Env :"CODER_SCALETEST_NO_WAIT_FOR_AGENTS" ,
1148
- Description :`Do not wait for agents to start before marking the test as succeeded. This can be useful if you are running the test against a template that does not start the agent quickly.` ,
1149
- Value :serpent .BoolOf (& noWaitForAgents ),
1150
- },
1151
1141
{
1152
1142
Flag :"no-cleanup" ,
1153
1143
Env :"CODER_SCALETEST_NO_CLEANUP" ,