@@ -13,6 +13,7 @@ import (
13
13
"github.com/coder/coder/v2/coderd/database"
14
14
"github.com/coder/coder/v2/coderd/database/dbfake"
15
15
"github.com/coder/coder/v2/coderd/database/dbtime"
16
+ "github.com/coder/coder/v2/coderd/rbac"
16
17
"github.com/coder/coder/v2/codersdk/agentsdk"
17
18
"github.com/coder/coder/v2/provisionersdk/proto"
18
19
"github.com/coder/coder/v2/testutil"
@@ -22,89 +23,150 @@ import (
22
23
func TestWorkspaceAgentReportStats (t * testing.T ) {
23
24
t .Parallel ()
24
25
25
- tickCh := make (chan time.Time )
26
- flushCh := make (chan int ,1 )
27
- client ,db := coderdtest .NewWithDatabase (t ,& coderdtest.Options {
28
- WorkspaceUsageTrackerFlush :flushCh ,
29
- WorkspaceUsageTrackerTick :tickCh ,
30
- })
31
- user := coderdtest .CreateFirstUser (t ,client )
32
- r := dbfake .WorkspaceBuild (t ,db , database.WorkspaceTable {
33
- OrganizationID :user .OrganizationID ,
34
- OwnerID :user .UserID ,
35
- LastUsedAt :dbtime .Now ().Add (- time .Minute ),
36
- }).WithAgent ().Do ()
26
+ for _ ,tc := range []struct {
27
+ name string
28
+ apiKeyScope rbac.ScopeName
29
+ }{
30
+ {
31
+ name :"empty (backwards compat)" ,
32
+ apiKeyScope :"" ,
33
+ },
34
+ {
35
+ name :"all" ,
36
+ apiKeyScope :rbac .ScopeAll ,
37
+ },
38
+ {
39
+ name :"no_user_data" ,
40
+ apiKeyScope :rbac .ScopeNoUserData ,
41
+ },
42
+ {
43
+ name :"application_connect" ,
44
+ apiKeyScope :rbac .ScopeApplicationConnect ,
45
+ },
46
+ } {
47
+ t .Run (tc .name ,func (t * testing.T ) {
48
+ t .Parallel ()
37
49
38
- ac := agentsdk .New (client .URL )
39
- ac .SetSessionToken (r .AgentToken )
40
- conn ,err := ac .ConnectRPC (context .Background ())
41
- require .NoError (t ,err )
42
- defer func () {
43
- _ = conn .Close ()
44
- }()
45
- agentAPI := agentproto .NewDRPCAgentClient (conn )
50
+ tickCh := make (chan time.Time )
51
+ flushCh := make (chan int ,1 )
52
+ client ,db := coderdtest .NewWithDatabase (t ,& coderdtest.Options {
53
+ WorkspaceUsageTrackerFlush :flushCh ,
54
+ WorkspaceUsageTrackerTick :tickCh ,
55
+ })
56
+ user := coderdtest .CreateFirstUser (t ,client )
57
+ r := dbfake .WorkspaceBuild (t ,db , database.WorkspaceTable {
58
+ OrganizationID :user .OrganizationID ,
59
+ OwnerID :user .UserID ,
60
+ LastUsedAt :dbtime .Now ().Add (- time .Minute ),
61
+ }).WithAgent (
62
+ func (agent []* proto.Agent ) []* proto.Agent {
63
+ for _ ,a := range agent {
64
+ a .ApiKeyScope = string (tc .apiKeyScope )
65
+ }
46
66
47
- _ ,err = agentAPI .UpdateStats (context .Background (),& agentproto.UpdateStatsRequest {
48
- Stats :& agentproto.Stats {
49
- ConnectionsByProto :map [string ]int64 {"TCP" :1 },
50
- ConnectionCount :1 ,
51
- RxPackets :1 ,
52
- RxBytes :1 ,
53
- TxPackets :1 ,
54
- TxBytes :1 ,
55
- SessionCountVscode :1 ,
56
- SessionCountJetbrains :0 ,
57
- SessionCountReconnectingPty :0 ,
58
- SessionCountSsh :0 ,
59
- ConnectionMedianLatencyMs :10 ,
60
- },
61
- })
62
- require .NoError (t ,err )
67
+ return agent
68
+ },
69
+ ).Do ()
70
+
71
+ ac := agentsdk .New (client .URL )
72
+ ac .SetSessionToken (r .AgentToken )
73
+ conn ,err := ac .ConnectRPC (context .Background ())
74
+ require .NoError (t ,err )
75
+ defer func () {
76
+ _ = conn .Close ()
77
+ }()
78
+ agentAPI := agentproto .NewDRPCAgentClient (conn )
79
+
80
+ _ ,err = agentAPI .UpdateStats (context .Background (),& agentproto.UpdateStatsRequest {
81
+ Stats :& agentproto.Stats {
82
+ ConnectionsByProto :map [string ]int64 {"TCP" :1 },
83
+ ConnectionCount :1 ,
84
+ RxPackets :1 ,
85
+ RxBytes :1 ,
86
+ TxPackets :1 ,
87
+ TxBytes :1 ,
88
+ SessionCountVscode :1 ,
89
+ SessionCountJetbrains :0 ,
90
+ SessionCountReconnectingPty :0 ,
91
+ SessionCountSsh :0 ,
92
+ ConnectionMedianLatencyMs :10 ,
93
+ },
94
+ })
95
+ require .NoError (t ,err )
63
96
64
- tickCh <- dbtime .Now ()
65
- count := <- flushCh
66
- require .Equal (t ,1 ,count ,"expected one flush with one id" )
97
+ tickCh <- dbtime .Now ()
98
+ count := <- flushCh
99
+ require .Equal (t ,1 ,count ,"expected one flush with one id" )
67
100
68
- newWorkspace ,err := client .Workspace (context .Background (),r .Workspace .ID )
69
- require .NoError (t ,err )
101
+ newWorkspace ,err := client .Workspace (context .Background (),r .Workspace .ID )
102
+ require .NoError (t ,err )
70
103
71
- assert .True (t ,
72
- newWorkspace .LastUsedAt .After (r .Workspace .LastUsedAt ),
73
- "%s is not after %s" ,newWorkspace .LastUsedAt ,r .Workspace .LastUsedAt ,
74
- )
104
+ assert .True (t ,
105
+ newWorkspace .LastUsedAt .After (r .Workspace .LastUsedAt ),
106
+ "%s is not after %s" ,newWorkspace .LastUsedAt ,r .Workspace .LastUsedAt ,
107
+ )
108
+ })
109
+ }
75
110
}
76
111
77
112
func TestAgentAPI_LargeManifest (t * testing.T ) {
78
113
t .Parallel ()
79
- ctx := testutil .Context (t ,testutil .WaitLong )
80
- client ,store := coderdtest .NewWithDatabase (t ,nil )
81
- adminUser := coderdtest .CreateFirstUser (t ,client )
82
- n := 512000
83
- longScript := make ([]byte ,n )
84
- for i := range longScript {
85
- longScript [i ]= 'q'
114
+
115
+ for _ ,tc := range []struct {
116
+ name string
117
+ apiKeyScope rbac.ScopeName
118
+ }{
119
+ {
120
+ name :"empty (backwards compat)" ,
121
+ apiKeyScope :"" ,
122
+ },
123
+ {
124
+ name :"all" ,
125
+ apiKeyScope :rbac .ScopeAll ,
126
+ },
127
+ {
128
+ name :"no_user_data" ,
129
+ apiKeyScope :rbac .ScopeNoUserData ,
130
+ },
131
+ {
132
+ name :"application_connect" ,
133
+ apiKeyScope :rbac .ScopeApplicationConnect ,
134
+ },
135
+ } {
136
+ t .Run (tc .name ,func (t * testing.T ) {
137
+ t .Parallel ()
138
+ ctx := testutil .Context (t ,testutil .WaitLong )
139
+ client ,store := coderdtest .NewWithDatabase (t ,nil )
140
+ adminUser := coderdtest .CreateFirstUser (t ,client )
141
+ n := 512000
142
+ longScript := make ([]byte ,n )
143
+ for i := range longScript {
144
+ longScript [i ]= 'q'
145
+ }
146
+ r := dbfake .WorkspaceBuild (t ,store , database.WorkspaceTable {
147
+ OrganizationID :adminUser .OrganizationID ,
148
+ OwnerID :adminUser .UserID ,
149
+ }).WithAgent (func (agents []* proto.Agent ) []* proto.Agent {
150
+ agents [0 ].Scripts = []* proto.Script {
151
+ {
152
+ Script :string (longScript ),
153
+ },
154
+ }
155
+ agents [0 ].ApiKeyScope = string (tc .apiKeyScope )
156
+ return agents
157
+ }).Do ()
158
+ ac := agentsdk .New (client .URL )
159
+ ac .SetSessionToken (r .AgentToken )
160
+ conn ,err := ac .ConnectRPC (ctx )
161
+ defer func () {
162
+ _ = conn .Close ()
163
+ }()
164
+ require .NoError (t ,err )
165
+ agentAPI := agentproto .NewDRPCAgentClient (conn )
166
+ manifest ,err := agentAPI .GetManifest (ctx ,& agentproto.GetManifestRequest {})
167
+ require .NoError (t ,err )
168
+ require .Len (t ,manifest .Scripts ,1 )
169
+ require .Len (t ,manifest .Scripts [0 ].Script ,n )
170
+ })
86
171
}
87
- r := dbfake .WorkspaceBuild (t ,store , database.WorkspaceTable {
88
- OrganizationID :adminUser .OrganizationID ,
89
- OwnerID :adminUser .UserID ,
90
- }).WithAgent (func (agents []* proto.Agent ) []* proto.Agent {
91
- agents [0 ].Scripts = []* proto.Script {
92
- {
93
- Script :string (longScript ),
94
- },
95
- }
96
- return agents
97
- }).Do ()
98
- ac := agentsdk .New (client .URL )
99
- ac .SetSessionToken (r .AgentToken )
100
- conn ,err := ac .ConnectRPC (ctx )
101
- defer func () {
102
- _ = conn .Close ()
103
- }()
104
- require .NoError (t ,err )
105
- agentAPI := agentproto .NewDRPCAgentClient (conn )
106
- manifest ,err := agentAPI .GetManifest (ctx ,& agentproto.GetManifestRequest {})
107
- require .NoError (t ,err )
108
- require .Len (t ,manifest .Scripts ,1 )
109
- require .Len (t ,manifest .Scripts [0 ].Script ,n )
110
172
}