@@ -58,6 +58,120 @@ func TestTemplates(t *testing.T) {
58
58
require .NoError (t , err )
59
59
require .Equal (t , 2 * time .Hour , time .Duration (template .MaxTTLMillis )* time .Millisecond )
60
60
})
61
+
62
+ t .Run ("CreateUpdateWorkspaceMaxTTL" , func (t * testing.T ) {
63
+ t .Parallel ()
64
+ client := coderdenttest .New (t , & coderdenttest.Options {
65
+ Options : & coderdtest.Options {
66
+ IncludeProvisionerDaemon : true ,
67
+ },
68
+ })
69
+ user := coderdtest .CreateFirstUser (t , client )
70
+ _ = coderdenttest .AddLicense (t , client , coderdenttest.LicenseOptions {
71
+ Features : license.Features {
72
+ codersdk .FeatureAdvancedTemplateScheduling : 1 ,
73
+ },
74
+ })
75
+
76
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
77
+ exp := 24 * time .Hour .Milliseconds ()
78
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID , func (ctr * codersdk.CreateTemplateRequest ) {
79
+ ctr .DefaultTTLMillis = & exp
80
+ ctr .MaxTTLMillis = & exp
81
+ })
82
+ coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
83
+
84
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitLong )
85
+ defer cancel ()
86
+
87
+ // No TTL provided should use template default
88
+ req := codersdk.CreateWorkspaceRequest {
89
+ TemplateID : template .ID ,
90
+ Name : "testing" ,
91
+ }
92
+ ws , err := client .CreateWorkspace (ctx , template .OrganizationID , codersdk .Me , req )
93
+ require .NoError (t , err )
94
+ require .EqualValues (t , exp , * ws .TTLMillis )
95
+
96
+ // Editing a workspace to have a higher TTL than the template's max
97
+ // should error
98
+ exp = exp + time .Minute .Milliseconds ()
99
+ err = client .UpdateWorkspaceTTL (ctx , ws .ID , codersdk.UpdateWorkspaceTTLRequest {
100
+ TTLMillis : & exp ,
101
+ })
102
+ require .Error (t , err )
103
+ var apiErr * codersdk.Error
104
+ require .ErrorAs (t , err , & apiErr )
105
+ require .Equal (t , http .StatusBadRequest , apiErr .StatusCode ())
106
+ require .Len (t , apiErr .Validations , 1 )
107
+ require .Equal (t , apiErr .Validations [0 ].Field , "ttl_ms" )
108
+ require .Contains (t , apiErr .Validations [0 ].Detail , "time until shutdown must be less than or equal to the template's maximum TTL" )
109
+
110
+ // Creating workspace with TTL higher than max should error
111
+ req .Name = "testing2"
112
+ req .TTLMillis = & exp
113
+ ws , err = client .CreateWorkspace (ctx , template .OrganizationID , codersdk .Me , req )
114
+ require .Error (t , err )
115
+ apiErr = nil
116
+ require .ErrorAs (t , err , & apiErr )
117
+ require .Equal (t , http .StatusBadRequest , apiErr .StatusCode ())
118
+ require .Len (t , apiErr .Validations , 1 )
119
+ require .Equal (t , apiErr .Validations [0 ].Field , "ttl_ms" )
120
+ require .Contains (t , apiErr .Validations [0 ].Detail , "time until shutdown must be less than or equal to the template's maximum TTL" )
121
+ })
122
+
123
+ t .Run ("BlockDisablingAutoOffWithMaxTTL" , func (t * testing.T ) {
124
+ t .Parallel ()
125
+ client := coderdenttest .New (t , & coderdenttest.Options {
126
+ Options : & coderdtest.Options {
127
+ IncludeProvisionerDaemon : true ,
128
+ },
129
+ })
130
+ user := coderdtest .CreateFirstUser (t , client )
131
+ _ = coderdenttest .AddLicense (t , client , coderdenttest.LicenseOptions {
132
+ Features : license.Features {
133
+ codersdk .FeatureAdvancedTemplateScheduling : 1 ,
134
+ },
135
+ })
136
+
137
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
138
+ exp := 24 * time .Hour .Milliseconds ()
139
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID , func (ctr * codersdk.CreateTemplateRequest ) {
140
+ ctr .MaxTTLMillis = & exp
141
+ })
142
+ coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
143
+
144
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitLong )
145
+ defer cancel ()
146
+
147
+ // No TTL provided should use template default
148
+ req := codersdk.CreateWorkspaceRequest {
149
+ TemplateID : template .ID ,
150
+ Name : "testing" ,
151
+ }
152
+ ws , err := client .CreateWorkspace (ctx , template .OrganizationID , codersdk .Me , req )
153
+ require .NoError (t , err )
154
+ require .EqualValues (t , exp , * ws .TTLMillis )
155
+
156
+ // Editing a workspace to disable the TTL should do nothing
157
+ err = client .UpdateWorkspaceTTL (ctx , ws .ID , codersdk.UpdateWorkspaceTTLRequest {
158
+ TTLMillis : nil ,
159
+ })
160
+ require .NoError (t , err )
161
+ ws , err = client .Workspace (ctx , ws .ID )
162
+ require .NoError (t , err )
163
+ require .EqualValues (t , exp , * ws .TTLMillis )
164
+
165
+ // Editing a workspace to have a TTL of 0 should do nothing
166
+ zero := int64 (0 )
167
+ err = client .UpdateWorkspaceTTL (ctx , ws .ID , codersdk.UpdateWorkspaceTTLRequest {
168
+ TTLMillis : & zero ,
169
+ })
170
+ require .NoError (t , err )
171
+ ws , err = client .Workspace (ctx , ws .ID )
172
+ require .NoError (t , err )
173
+ require .EqualValues (t , exp , * ws .TTLMillis )
174
+ })
61
175
}
62
176
63
177
func TestTemplateACL (t * testing.T ) {
0 commit comments