1package vps 2 3import ( 4 "fmt" 5 "github.com/stretchr/testify/assert" 6 "github.com/stretchr/testify/require" 7 "github.com/transip/gotransip/v6" 8 "github.com/transip/gotransip/v6/ipaddress" 9 "github.com/transip/gotransip/v6/repository" 10 "io/ioutil" 11 "net" 12 "net/http" 13 "net/http/httptest" 14 "net/url" 15 "testing" 16 "time" 17) 18 19// mockServer struct is used to test the how the client sends a request 20// and responds to a servers response 21type mockServer struct { 22 t *testing.T 23 expectedURL string 24 expectedMethod string 25 statusCode int 26 expectedRequest string 27 response string 28 skipRequestBody bool 29} 30 31func (m *mockServer) getHTTPServer() *httptest.Server { 32 return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { 33 assert.Equal(m.t, m.expectedURL, req.URL.String()) // check if right expectedURL is called 34 35 if m.skipRequestBody == false && req.ContentLength != 0 { 36 // get the request body 37 // and check if the body matches the expected request body 38 body, err := ioutil.ReadAll(req.Body) 39 require.NoError(m.t, err) 40 assert.Equal(m.t, m.expectedRequest, string(body)) 41 } 42 43 assert.Equal(m.t, m.expectedMethod, req.Method) // check if the right expectedRequest expectedMethod is used 44 rw.WriteHeader(m.statusCode) // respond with given status code 45 46 if m.response != "" { 47 _, err := rw.Write([]byte(m.response)) 48 require.NoError(m.t, err, "error when writing mock response") 49 } 50 })) 51} 52 53func (m *mockServer) getClient() (*repository.Client, func()) { 54 httpServer := m.getHTTPServer() 55 config := gotransip.DemoClientConfiguration 56 config.URL = httpServer.URL 57 client, err := gotransip.NewClient(config) 58 require.NoError(m.t, err) 59 60 // return tearDown method with which will close the test server after the test 61 tearDown := func() { 62 httpServer.Close() 63 } 64 65 return &client, tearDown 66} 67 68func TestRepository_GetAll(t *testing.T) { 69 const apiResponse = `{ "vpss": [ { "name": "example-vps", "description": "example VPS", "productName": "vps-bladevps-x1", "operatingSystem": "ubuntu-18.04", "diskSize": 157286400, "memorySize": 4194304, "cpus": 2, "status": "running", "ipAddress": "37.97.254.6", "macAddress": "52:54:00:3b:52:65", "currentSnapshots": 1, "maxSnapshots": 10, "isLocked": false, "isBlocked": false, "isCustomerLocked": false, "availabilityZone": "ams0", "tags": [ "customTag", "anotherTag" ] } ] }` 70 71 server := mockServer{t: t, expectedURL: "/vps", expectedMethod: "GET", statusCode: 200, response: apiResponse} 72 client, tearDown := server.getClient() 73 defer tearDown() 74 repo := Repository{Client: *client} 75 76 all, err := repo.GetAll() 77 require.NoError(t, err) 78 require.Equal(t, 1, len(all)) 79 80 assert.Equal(t, "example-vps", all[0].Name) 81 assert.Equal(t, "example VPS", all[0].Description) 82 assert.Equal(t, "vps-bladevps-x1", all[0].ProductName) 83 assert.Equal(t, "ubuntu-18.04", all[0].OperatingSystem) 84 assert.EqualValues(t, 157286400, all[0].DiskSize) 85 assert.EqualValues(t, 4194304, all[0].MemorySize) 86 assert.EqualValues(t, 2, all[0].CPUs) 87 assert.EqualValues(t, "running", all[0].Status) 88 assert.Equal(t, "37.97.254.6", all[0].IPAddress) 89 assert.Equal(t, "52:54:00:3b:52:65", all[0].MacAddress) 90 assert.EqualValues(t, 1, all[0].CurrentSnapshots) 91 assert.EqualValues(t, 10, all[0].MaxSnapshots) 92 assert.Equal(t, false, all[0].IsLocked) 93 assert.Equal(t, false, all[0].IsBlocked) 94 assert.Equal(t, false, all[0].IsCustomerLocked) 95 assert.Equal(t, "ams0", all[0].AvailabilityZone) 96 assert.Equal(t, []string{"customTag", "anotherTag"}, all[0].Tags) 97} 98 99func TestRepository_GetAllByTags(t *testing.T) { 100 const apiResponse = `{ "vpss": [ { "name": "example-vps", "uuid": "bfa08ad9-6c12-4e03-95dd-a888b97ffe49", "description": "example VPS", "productName": "vps-bladevps-x1", "operatingSystem": "ubuntu-18.04", "diskSize": 157286400, "memorySize": 4194304, "cpus": 2, "status": "running", "ipAddress": "37.97.254.6", "macAddress": "52:54:00:3b:52:65", "currentSnapshots": 1, "maxSnapshots": 10, "isLocked": false, "isBlocked": false, "isCustomerLocked": false, "availabilityZone": "ams0", "tags": [ "customTag", "anotherTag" ] } ] }` 101 102 server := mockServer{t: t, expectedURL: "/vps?tags=customTag", expectedMethod: "GET", statusCode: 200, response: apiResponse} 103 client, tearDown := server.getClient() 104 defer tearDown() 105 repo := Repository{Client: *client} 106 107 all, err := repo.GetAllByTags([]string{"customTag"}) 108 require.NoError(t, err) 109 require.Equal(t, 1, len(all)) 110 111 assert.Equal(t, "example-vps", all[0].Name) 112 assert.Equal(t, "example VPS", all[0].Description) 113 assert.Equal(t, "bfa08ad9-6c12-4e03-95dd-a888b97ffe49", all[0].UUID) 114 assert.Equal(t, "vps-bladevps-x1", all[0].ProductName) 115 assert.Equal(t, "ubuntu-18.04", all[0].OperatingSystem) 116 assert.EqualValues(t, 157286400, all[0].DiskSize) 117 assert.EqualValues(t, 4194304, all[0].MemorySize) 118 assert.EqualValues(t, 2, all[0].CPUs) 119 assert.EqualValues(t, "running", all[0].Status) 120 assert.Equal(t, "37.97.254.6", all[0].IPAddress) 121 assert.Equal(t, "52:54:00:3b:52:65", all[0].MacAddress) 122 assert.EqualValues(t, 1, all[0].CurrentSnapshots) 123 assert.EqualValues(t, 10, all[0].MaxSnapshots) 124 assert.Equal(t, false, all[0].IsLocked) 125 assert.Equal(t, false, all[0].IsBlocked) 126 assert.Equal(t, false, all[0].IsCustomerLocked) 127 assert.Equal(t, "ams0", all[0].AvailabilityZone) 128 assert.Equal(t, []string{"customTag", "anotherTag"}, all[0].Tags) 129} 130 131func TestRepository_GetSelection(t *testing.T) { 132 const apiResponse = `{ "vpss": [ { "name": "example-vps", "uuid": "bfa08ad9-6c12-4e03-95dd-a888b97ffe49", "description": "example VPS", "productName": "vps-bladevps-x1", "operatingSystem": "ubuntu-18.04", "diskSize": 157286400, "memorySize": 4194304, "cpus": 2, "status": "running", "ipAddress": "37.97.254.6", "macAddress": "52:54:00:3b:52:65", "currentSnapshots": 1, "maxSnapshots": 10, "isLocked": false, "isBlocked": false, "isCustomerLocked": false, "availabilityZone": "ams0", "tags": [ "customTag", "anotherTag" ] } ] }` 133 134 server := mockServer{t: t, expectedURL: "/vps?page=1&pageSize=25", expectedMethod: "GET", statusCode: 200, response: apiResponse} 135 client, tearDown := server.getClient() 136 defer tearDown() 137 repo := Repository{Client: *client} 138 139 all, err := repo.GetSelection(1, 25) 140 require.NoError(t, err) 141 require.Equal(t, 1, len(all)) 142 143 assert.Equal(t, "example-vps", all[0].Name) 144 assert.Equal(t, "bfa08ad9-6c12-4e03-95dd-a888b97ffe49", all[0].UUID) 145 assert.Equal(t, "example VPS", all[0].Description) 146 assert.Equal(t, "vps-bladevps-x1", all[0].ProductName) 147 assert.Equal(t, "ubuntu-18.04", all[0].OperatingSystem) 148 assert.EqualValues(t, 157286400, all[0].DiskSize) 149 assert.EqualValues(t, 4194304, all[0].MemorySize) 150 assert.EqualValues(t, 2, all[0].CPUs) 151 assert.EqualValues(t, "running", all[0].Status) 152 assert.Equal(t, "37.97.254.6", all[0].IPAddress) 153 assert.Equal(t, "52:54:00:3b:52:65", all[0].MacAddress) 154 assert.EqualValues(t, 1, all[0].CurrentSnapshots) 155 assert.EqualValues(t, 10, all[0].MaxSnapshots) 156 assert.Equal(t, false, all[0].IsLocked) 157 assert.Equal(t, false, all[0].IsBlocked) 158 assert.Equal(t, false, all[0].IsCustomerLocked) 159 assert.Equal(t, "ams0", all[0].AvailabilityZone) 160 assert.Equal(t, []string{"customTag", "anotherTag"}, all[0].Tags) 161} 162 163func TestRepository_GetByName(t *testing.T) { 164 const apiResponse = `{ "vps": { "name": "example-vps", "uuid": "bfa08ad9-6c12-4e03-95dd-a888b97ffe49", "description": "example VPS", "productName": "vps-bladevps-x1", "operatingSystem": "ubuntu-18.04", "diskSize": 157286400, "memorySize": 4194304, "cpus": 2, "status": "running", "ipAddress": "37.97.254.6", "macAddress": "52:54:00:3b:52:65", "currentSnapshots": 1, "maxSnapshots": 10, "isLocked": false, "isBlocked": false, "isCustomerLocked": false, "availabilityZone": "ams0", "tags": [ "customTag", "anotherTag" ] } }` 165 server := mockServer{t: t, expectedURL: "/vps/example-vps", expectedMethod: "GET", statusCode: 200, response: apiResponse} 166 client, tearDown := server.getClient() 167 defer tearDown() 168 repo := Repository{Client: *client} 169 170 vps, err := repo.GetByName("example-vps") 171 require.NoError(t, err) 172 173 assert.Equal(t, "example-vps", vps.Name) 174 assert.Equal(t, "bfa08ad9-6c12-4e03-95dd-a888b97ffe49", vps.UUID) 175 assert.Equal(t, "example VPS", vps.Description) 176 assert.Equal(t, "vps-bladevps-x1", vps.ProductName) 177 assert.Equal(t, "ubuntu-18.04", vps.OperatingSystem) 178 assert.EqualValues(t, 157286400, vps.DiskSize) 179 assert.EqualValues(t, 4194304, vps.MemorySize) 180 assert.EqualValues(t, 2, vps.CPUs) 181 assert.EqualValues(t, "running", vps.Status) 182 assert.Equal(t, "37.97.254.6", vps.IPAddress) 183 assert.Equal(t, "52:54:00:3b:52:65", vps.MacAddress) 184 assert.EqualValues(t, 1, vps.CurrentSnapshots) 185 assert.EqualValues(t, 10, vps.MaxSnapshots) 186 assert.Equal(t, false, vps.IsLocked) 187 assert.Equal(t, false, vps.IsBlocked) 188 assert.Equal(t, false, vps.IsCustomerLocked) 189 assert.Equal(t, "ams0", vps.AvailabilityZone) 190 assert.Equal(t, []string{"customTag", "anotherTag"}, vps.Tags) 191} 192 193func TestRepository_Order(t *testing.T) { 194 const expectedRequestBody = `{"productName":"vps-bladevps-x8","operatingSystem":"ubuntu-18.04","availabilityZone":"ams0","description":"example vps description","addons":["vpsAddon-1-extra-cpu-core"],"installFlavour":"cloudinit","hostname":"server01.example.com","username":"bob","sshKeys":["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDf2pxWX/yhUBDyk2LPhvRtI0LnVO8PyR5Zt6AHrnhtLGqK+8YG9EMlWbCCWrASR+Q1hFQG example"],"base64InstallText":"testtext123"}` 195 server := mockServer{t: t, expectedURL: "/vps", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequestBody} 196 client, tearDown := server.getClient() 197 defer tearDown() 198 repo := Repository{Client: *client} 199 200 order := Order{ 201 ProductName: "vps-bladevps-x8", 202 OperatingSystem: "ubuntu-18.04", 203 AvailabilityZone: "ams0", 204 Addons: []string{"vpsAddon-1-extra-cpu-core"}, 205 InstallFlavour: InstallFlavourCloudInit, 206 Hostname: "server01.example.com", 207 Username: "bob", 208 SSHKeys: []string{"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDf2pxWX/yhUBDyk2LPhvRtI0LnVO8PyR5Zt6AHrnhtLGqK+8YG9EMlWbCCWrASR+Q1hFQG example"}, 209 Description: "example vps description", 210 Base64InstallText: "testtext123", 211 } 212 213 err := repo.Order(order) 214 require.NoError(t, err) 215} 216 217func TestRepository_OrderMultiple(t *testing.T) { 218 const expectedRequestBody = `{"vpss":[{"productName":"vps-bladevps-x8","operatingSystem":"ubuntu-18.04","availabilityZone":"ams0","description":"webserver01","addons":["vpsAddon-1-extra-cpu-core"],"hostname":"server01.example.com","base64InstallText":"testtext123"},{"productName":"vps-bladevps-x8","operatingSystem":"ubuntu-18.04","availabilityZone":"ams0","description":"backupserver01","hostname":"server01.example.com"}]}` 219 server := mockServer{t: t, expectedURL: "/vps", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequestBody} 220 client, tearDown := server.getClient() 221 defer tearDown() 222 repo := Repository{Client: *client} 223 224 orders := []Order{{ 225 ProductName: "vps-bladevps-x8", 226 OperatingSystem: "ubuntu-18.04", 227 AvailabilityZone: "ams0", 228 Addons: []string{"vpsAddon-1-extra-cpu-core"}, 229 Hostname: "server01.example.com", 230 Description: "webserver01", 231 Base64InstallText: "testtext123", 232 }, { 233 ProductName: "vps-bladevps-x8", 234 OperatingSystem: "ubuntu-18.04", 235 AvailabilityZone: "ams0", 236 Hostname: "server01.example.com", 237 Description: "backupserver01", 238 }} 239 240 err := repo.OrderMultiple(orders) 241 require.NoError(t, err) 242} 243 244func TestRepository_Clone(t *testing.T) { 245 const expectedRequest = `{"vpsName":"example-vps"}` 246 server := mockServer{t: t, expectedURL: "/vps", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 247 client, tearDown := server.getClient() 248 defer tearDown() 249 repo := Repository{Client: *client} 250 251 err := repo.Clone("example-vps") 252 require.NoError(t, err) 253} 254 255func TestRepository_CloneToAvailabilityZone(t *testing.T) { 256 const expectedRequest = `{"vpsName":"example-vps","availabilityZone":"ams0"}` 257 server := mockServer{t: t, expectedURL: "/vps", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 258 client, tearDown := server.getClient() 259 defer tearDown() 260 repo := Repository{Client: *client} 261 262 err := repo.CloneToAvailabilityZone("example-vps", "ams0") 263 require.NoError(t, err) 264} 265 266func TestRepository_Update(t *testing.T) { 267 const expectedRequest = `{"vps":{"name":"example-vps","uuid":"bfa08ad9-6c12-4e03-95dd-a888b97ffe49","description":"example VPS","productName":"vps-bladevps-x1","operatingSystem":"ubuntu-18.04","diskSize":157286400,"memorySize":4194304,"cpus":2,"status":"running","ipAddress":"37.97.254.6","macAddress":"52:54:00:3b:52:65","currentSnapshots":1,"maxSnapshots":10,"isCustomerLocked":false,"availabilityZone":"ams0","tags":["customTag","anotherTag"]}}` 268 server := mockServer{t: t, expectedURL: "/vps/example-vps", expectedMethod: "PUT", statusCode: 204, expectedRequest: expectedRequest} 269 client, tearDown := server.getClient() 270 defer tearDown() 271 repo := Repository{Client: *client} 272 273 vpsToUpdate := Vps{ 274 Name: "example-vps", 275 UUID: "bfa08ad9-6c12-4e03-95dd-a888b97ffe49", 276 Description: "example VPS", 277 ProductName: "vps-bladevps-x1", 278 OperatingSystem: "ubuntu-18.04", 279 DiskSize: 157286400, 280 MemorySize: 4194304, 281 CPUs: 2, 282 Status: "running", 283 IPAddress: "37.97.254.6", 284 MacAddress: "52:54:00:3b:52:65", 285 CurrentSnapshots: 1, 286 MaxSnapshots: 10, 287 IsLocked: false, 288 IsBlocked: false, 289 IsCustomerLocked: false, 290 AvailabilityZone: "ams0", 291 Tags: []string{"customTag", "anotherTag"}, 292 } 293 294 err := repo.Update(vpsToUpdate) 295 296 require.NoError(t, err) 297} 298 299func TestRepository_Start(t *testing.T) { 300 const expectedRequest = `{"action":"start"}` 301 server := mockServer{t: t, expectedURL: "/vps/example-vps", expectedMethod: "PATCH", statusCode: 204, expectedRequest: expectedRequest} 302 client, tearDown := server.getClient() 303 defer tearDown() 304 repo := Repository{Client: *client} 305 306 err := repo.Start("example-vps") 307 require.NoError(t, err) 308} 309 310func TestRepository_Stop(t *testing.T) { 311 const expectedRequest = `{"action":"stop"}` 312 server := mockServer{t: t, expectedURL: "/vps/example-vps", expectedMethod: "PATCH", statusCode: 204, expectedRequest: expectedRequest} 313 client, tearDown := server.getClient() 314 defer tearDown() 315 repo := Repository{Client: *client} 316 317 err := repo.Stop("example-vps") 318 require.NoError(t, err) 319} 320 321func TestRepository_Reset(t *testing.T) { 322 const expectedRequest = `{"action":"reset"}` 323 server := mockServer{t: t, expectedURL: "/vps/example-vps", expectedMethod: "PATCH", statusCode: 204, expectedRequest: expectedRequest} 324 client, tearDown := server.getClient() 325 defer tearDown() 326 repo := Repository{Client: *client} 327 328 err := repo.Reset("example-vps") 329 require.NoError(t, err) 330} 331 332func TestRepository_Handover(t *testing.T) { 333 const expectedRequest = `{"action":"handover","targetCustomerName":"bobexample"}` 334 server := mockServer{t: t, expectedURL: "/vps/example-vps", expectedMethod: "PATCH", statusCode: 204, expectedRequest: expectedRequest} 335 client, tearDown := server.getClient() 336 defer tearDown() 337 repo := Repository{Client: *client} 338 339 err := repo.Handover("example-vps", "bobexample") 340 require.NoError(t, err) 341} 342 343func TestRepository_Cancel(t *testing.T) { 344 const expectedRequest = `{"endTime":"end"}` 345 server := mockServer{t: t, expectedURL: "/vps/example-vps", expectedMethod: "DELETE", statusCode: 204, expectedRequest: expectedRequest} 346 client, tearDown := server.getClient() 347 defer tearDown() 348 repo := Repository{Client: *client} 349 350 err := repo.Cancel("example-vps", gotransip.CancellationTimeEnd) 351 require.NoError(t, err) 352} 353 354func TestRepository_GetUsageData(t *testing.T) { 355 const apiResponse = `{"usage":{"cpu":[{"percentage":3.11,"date":1574783109}]}} ` 356 357 values := url.Values{ 358 "dateTimeStart": []string{"1500538995"}, 359 "dateTimeEnd": []string{"1500542619"}, 360 "types": []string{"cpu"}, 361 } 362 363 expectedURL := "/vps/example-vps/usage?" + values.Encode() 364 server := mockServer{t: t, expectedURL: expectedURL, expectedMethod: "GET", statusCode: 200, response: apiResponse} 365 client, tearDown := server.getClient() 366 defer tearDown() 367 repo := Repository{Client: *client} 368 369 usageData, err := repo.GetUsage("example-vps", []UsageType{UsageTypeCPU}, UsagePeriod{TimeStart: 1500538995, TimeEnd: 1500542619}) 370 require.NoError(t, err) 371 372 require.Equal(t, 1, len(usageData.CPU)) 373 assert.EqualValues(t, 3.11, usageData.CPU[0].Percentage) 374 assert.EqualValues(t, 1574783109, usageData.CPU[0].Date) 375} 376 377func TestRepository_GetAllUsageDataByVps(t *testing.T) { 378 const apiResponse = `{ "usage": { "cpu": [ { "percentage": 3.11, "date": 1574783109 } ], "disk": [ { "iopsRead": 0.27, "iopsWrite": 0.13, "date": 1574783109 } ], "network": [ { "mbitOut": 100.2, "mbitIn": 249.93, "date": 1574783109 } ] } } ` 379 380 values := url.Values{ 381 "dateTimeStart": []string{"1500538995"}, 382 "dateTimeEnd": []string{"1500542619"}, 383 "types": []string{"cpu,disk,network"}, 384 } 385 386 expectedURL := "/vps/example-vps/usage?" + values.Encode() 387 server := mockServer{t: t, expectedURL: expectedURL, expectedMethod: "GET", statusCode: 200, response: apiResponse} 388 client, tearDown := server.getClient() 389 defer tearDown() 390 repo := Repository{Client: *client} 391 392 usageData, err := repo.GetAllUsage("example-vps", UsagePeriod{TimeStart: 1500538995, TimeEnd: 1500542619}) 393 require.NoError(t, err) 394 395 require.Equal(t, 1, len(usageData.CPU)) 396 require.Equal(t, 1, len(usageData.Disk)) 397 require.Equal(t, 1, len(usageData.Network)) 398 399 assert.EqualValues(t, 3.11, usageData.CPU[0].Percentage) 400 assert.EqualValues(t, 1574783109, usageData.CPU[0].Date) 401 402 assert.EqualValues(t, 0.27, usageData.Disk[0].IopsRead) 403 assert.EqualValues(t, 0.13, usageData.Disk[0].IopsWrite) 404 assert.EqualValues(t, 1574783109, usageData.Disk[0].Date) 405 406 assert.EqualValues(t, 100.2, usageData.Network[0].MbitOut) 407 assert.EqualValues(t, 249.93, usageData.Network[0].MbitIn) 408 assert.EqualValues(t, 1574783109, usageData.Network[0].Date) 409} 410 411func TestRepository_GetAllUsageDataByVps24Hours(t *testing.T) { 412 const apiResponse = `{ "usage": { "cpu": [ { "percentage": 3.11, "date": 1574783109 } ], "disk": [ { "iopsRead": 0.27, "iopsWrite": 0.13, "date": 1574783109 } ], "network": [ { "mbitOut": 100.2, "mbitIn": 249.93, "date": 1574783109 } ] } } ` 413 414 values := url.Values{ 415 "dateTimeStart": []string{fmt.Sprintf("%d", time.Now().Add(-24*time.Hour).Unix())}, 416 "dateTimeEnd": []string{fmt.Sprintf("%d", time.Now().Unix())}, 417 "types": []string{"cpu,disk,network"}, 418 } 419 420 expectedURL := "/vps/example-vps/usage?" + values.Encode() 421 server := mockServer{t: t, expectedURL: expectedURL, expectedMethod: "GET", statusCode: 200, response: apiResponse} 422 client, tearDown := server.getClient() 423 defer tearDown() 424 repo := Repository{Client: *client} 425 426 usageData, err := repo.GetAllUsage24Hours("example-vps") 427 require.NoError(t, err) 428 429 require.Equal(t, 1, len(usageData.CPU)) 430 require.Equal(t, 1, len(usageData.Disk)) 431 require.Equal(t, 1, len(usageData.Network)) 432 433 assert.EqualValues(t, 3.11, usageData.CPU[0].Percentage) 434 assert.EqualValues(t, 1574783109, usageData.CPU[0].Date) 435 436 assert.EqualValues(t, 0.27, usageData.Disk[0].IopsRead) 437 assert.EqualValues(t, 0.13, usageData.Disk[0].IopsWrite) 438 assert.EqualValues(t, 1574783109, usageData.Disk[0].Date) 439 440 assert.EqualValues(t, 100.2, usageData.Network[0].MbitOut) 441 assert.EqualValues(t, 249.93, usageData.Network[0].MbitIn) 442 assert.EqualValues(t, 1574783109, usageData.Network[0].Date) 443} 444 445func TestRepository_GetVNCData(t *testing.T) { 446 const apiResponse = `{ "vncData": { "host": "vncproxy.transip.nl", "path": "websockify?token=testtokentje", "url": "https://vncproxy.transip.nl/websockify?token=testtokentje", "token": "testtokentje", "password": "esisteinpassw0rd" } }` 447 server := mockServer{t: t, expectedURL: "/vps/example-vps/vnc-data", expectedMethod: "GET", statusCode: 200, response: apiResponse} 448 client, tearDown := server.getClient() 449 defer tearDown() 450 repo := Repository{Client: *client} 451 452 vncData, err := repo.GetVNCData("example-vps") 453 require.NoError(t, err) 454 assert.Equal(t, "vncproxy.transip.nl", vncData.Host) 455 assert.Equal(t, "websockify?token=testtokentje", vncData.Path) 456 assert.Equal(t, "https://vncproxy.transip.nl/websockify?token=testtokentje", vncData.URL) 457 assert.Equal(t, "esisteinpassw0rd", vncData.Password) 458 assert.Equal(t, "testtokentje", vncData.Token) 459 460} 461 462func TestRepository_RegenerateVNCToken(t *testing.T) { 463 server := mockServer{t: t, expectedURL: "/vps/example-vps/vnc-data", expectedMethod: "PATCH", statusCode: 204} 464 client, tearDown := server.getClient() 465 defer tearDown() 466 repo := Repository{Client: *client} 467 468 err := repo.RegenerateVNCToken("example-vps") 469 require.NoError(t, err) 470} 471 472func TestRepository_GetAddons(t *testing.T) { 473 const apiResponse = `{ "addons": { "active": [ { "name": "example-product-name", "description": "This is an example product", "price": 499, "recurringPrice": 799 } ], "cancellable": [ { "name": "example-product-name", "description": "This is an example product", "price": 499, "recurringPrice": 799 } ], "available": [ { "name": "example-product-name", "description": "This is an example product", "price": 499, "recurringPrice": 799 } ] } }` 474 server := mockServer{t: t, expectedURL: "/vps/example-vps/addons", expectedMethod: "GET", statusCode: 200, response: apiResponse} 475 client, tearDown := server.getClient() 476 defer tearDown() 477 repo := Repository{Client: *client} 478 479 allAddons, err := repo.GetAddons("example-vps") 480 require.NoError(t, err) 481 require.Equal(t, 1, len(allAddons.Active)) 482 require.Equal(t, 1, len(allAddons.Cancellable)) 483 require.Equal(t, 1, len(allAddons.Available)) 484 485 assert.Equal(t, "example-product-name", allAddons.Active[0].Name) 486 assert.Equal(t, "This is an example product", allAddons.Active[0].Description) 487 assert.Equal(t, 499, allAddons.Active[0].Price) 488 assert.Equal(t, 799, allAddons.Active[0].RecurringPrice) 489 490 assert.Equal(t, "example-product-name", allAddons.Cancellable[0].Name) 491 assert.Equal(t, "This is an example product", allAddons.Cancellable[0].Description) 492 assert.Equal(t, 499, allAddons.Cancellable[0].Price) 493 assert.Equal(t, 799, allAddons.Cancellable[0].RecurringPrice) 494 495 assert.Equal(t, "example-product-name", allAddons.Available[0].Name) 496 assert.Equal(t, "This is an example product", allAddons.Available[0].Description) 497 assert.Equal(t, 499, allAddons.Available[0].Price) 498 assert.Equal(t, 799, allAddons.Available[0].RecurringPrice) 499} 500 501func TestRepository_OrderAddons(t *testing.T) { 502 const expectedRequest = `{"addons":["vps-addon-1-extra-ip-address"]}` 503 server := mockServer{t: t, expectedURL: "/vps/example-vps/addons", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 504 client, tearDown := server.getClient() 505 defer tearDown() 506 repo := Repository{Client: *client} 507 508 err := repo.OrderAddons("example-vps", []string{"vps-addon-1-extra-ip-address"}) 509 require.NoError(t, err) 510} 511 512func TestRepository_CancelAddon(t *testing.T) { 513 server := mockServer{t: t, expectedURL: "/vps/example-vps/addons/einaddon", expectedMethod: "DELETE", statusCode: 204} 514 client, tearDown := server.getClient() 515 defer tearDown() 516 repo := Repository{Client: *client} 517 518 err := repo.CancelAddon("example-vps", "einaddon") 519 require.NoError(t, err) 520} 521 522func TestRepository_GetUpgrades(t *testing.T) { 523 const apiResponse = `{ "upgrades": [ { "name": "example-product-name", "description": "This is an example product", "price": 499, "recurringPrice": 799 } ] } ` 524 server := mockServer{t: t, expectedURL: "/vps/example-vps/upgrades", expectedMethod: "GET", statusCode: 200, response: apiResponse} 525 client, tearDown := server.getClient() 526 defer tearDown() 527 repo := Repository{Client: *client} 528 529 allUpgrades, err := repo.GetUpgrades("example-vps") 530 require.NoError(t, err) 531 require.Equal(t, 1, len(allUpgrades)) 532 533 assert.Equal(t, "example-product-name", allUpgrades[0].Name) 534 assert.Equal(t, "This is an example product", allUpgrades[0].Description) 535 assert.Equal(t, 499, allUpgrades[0].Price) 536 assert.Equal(t, 799, allUpgrades[0].RecurringPrice) 537} 538 539func TestRepository_Upgrade(t *testing.T) { 540 const expectedRequest = `{"productName":"vps-bladevps-pro-x16"}` 541 server := mockServer{t: t, expectedURL: "/vps/example-vps/upgrades", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 542 client, tearDown := server.getClient() 543 defer tearDown() 544 repo := Repository{Client: *client} 545 546 err := repo.Upgrade("example-vps", "vps-bladevps-pro-x16") 547 require.NoError(t, err) 548} 549 550func TestRepository_GetOperatingSystems(t *testing.T) { 551 const apiResponse = `{ 552 "operatingSystems": [ 553 { 554 "name": "ubuntu-18.04", 555 "description": "Ubuntu 18.04 LTS", 556 "version": "18.04 LTS", 557 "price": 1250, 558 "installFlavours": [ 559 "installer", 560 "preinstallable", 561 "cloudinit" 562 ] 563 } 564 ] 565}` 566 server := mockServer{t: t, expectedURL: "/vps/example-vps/operating-systems", expectedMethod: "GET", statusCode: 200, response: apiResponse} 567 client, tearDown := server.getClient() 568 defer tearDown() 569 repo := Repository{Client: *client} 570 571 oses, err := repo.GetOperatingSystems("example-vps") 572 require.NoError(t, err) 573 require.Equal(t, 1, len(oses)) 574 575 assert.Equal(t, "ubuntu-18.04", oses[0].Name) 576 assert.Equal(t, "Ubuntu 18.04 LTS", oses[0].Description) 577 assert.Equal(t, false, oses[0].IsPreinstallableImage) 578 assert.Contains(t, oses[0].InstallFlavours, InstallFlavourInstaller) 579 assert.Contains(t, oses[0].InstallFlavours, InstallFlavourPreinstallable) 580 assert.Contains(t, oses[0].InstallFlavours, InstallFlavourCloudInit) 581 assert.Equal(t, "18.04 LTS", oses[0].Version) 582 assert.Equal(t, 1250, oses[0].Price) 583} 584 585func TestRepository_InstallOperatingSystemOptionalFields(t *testing.T) { 586 const expectedRequest = `{"operatingSystemName":"ubuntu-18.04"}` 587 server := mockServer{t: t, expectedURL: "/vps/example-vps/operating-systems", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 588 client, tearDown := server.getClient() 589 defer tearDown() 590 repo := Repository{Client: *client} 591 592 err := repo.InstallOperatingSystem("example-vps", "ubuntu-18.04", "", "") 593 require.NoError(t, err) 594} 595 596func TestRepository_InstallOperatingSystem(t *testing.T) { 597 const expectedRequest = `{"operatingSystemName":"ubuntu-18.04","hostname":"test","base64InstallText":"ZGFzaXN0YmFzZTY0"}` 598 server := mockServer{t: t, expectedURL: "/vps/example-vps/operating-systems", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 599 client, tearDown := server.getClient() 600 defer tearDown() 601 repo := Repository{Client: *client} 602 603 err := repo.InstallOperatingSystem("example-vps", "ubuntu-18.04", "test", "ZGFzaXN0YmFzZTY0") 604 require.NoError(t, err) 605} 606 607func TestRepository_InstallOperatingSystemWithOptions(t *testing.T) { 608 const expectedRequest = `{"operatingSystemName":"ubuntu-20.04","installFlavour":"cloudinit","username":"bob","sshKeys":["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDf2pxWX/yhUBDyk2LPhvRtI0LnVO8PyR5Zt6AHrnhtLGqK+8YG9EMlWbCCWrASR+Q1hFQG example"]}` 609 server := mockServer{t: t, expectedURL: "/vps/example-vps/operating-systems", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 610 client, tearDown := server.getClient() 611 defer tearDown() 612 repo := Repository{Client: *client} 613 614 options := InstallOptions{ 615 OperatingSystemName: "ubuntu-20.04", 616 InstallFlavour: "cloudinit", 617 Hostname: "", 618 Username: "bob", 619 SSHKeys: []string{"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDf2pxWX/yhUBDyk2LPhvRtI0LnVO8PyR5Zt6AHrnhtLGqK+8YG9EMlWbCCWrASR+Q1hFQG example"}, 620 Base64InstallText: "", 621 } 622 623 err := repo.InstallOperatingSystemWithOptions("example-vps", options) 624 require.NoError(t, err) 625} 626 627func TestRepository_GetIPAddresses(t *testing.T) { 628 const apiResponse = `{ "ipAddresses" : [ { "dnsResolvers" : [ "195.8.195.8", "195.135.195.135" ], "subnetMask" : "255.255.255.0", "reverseDns" : "example.com", "address" : "149.210.192.184", "gateway" : "149.210.192.1" }, { "address" : "2a01:7c8:aab5:5d5::1", "gateway" : "2a01:7c8:aab5::1", "dnsResolvers" : [ "2a01:7c8:7000:195::8:195:8", "2a01:7c8:7000:195::135:195:135" ], "subnetMask" : "/48", "reverseDns" : "example.com" } ] }` 629 server := mockServer{t: t, expectedURL: "/vps/example-vps/ip-addresses", expectedMethod: "GET", statusCode: 200, response: apiResponse} 630 client, tearDown := server.getClient() 631 defer tearDown() 632 repo := Repository{Client: *client} 633 634 ips, err := repo.GetIPAddresses("example-vps") 635 require.NoError(t, err) 636 require.Equal(t, 2, len(ips)) 637 638 assert.EqualValues(t, "149.210.192.184", ips[0].Address.String()) 639 assert.EqualValues(t, "00000000000000000000ffffffffff00", ips[0].SubnetMask.String()) 640 assert.EqualValues(t, "149.210.192.1", ips[0].Gateway.String()) 641 assert.EqualValues(t, "195.8.195.8", ips[0].DNSResolvers[0].String()) 642 assert.EqualValues(t, "195.135.195.135", ips[0].DNSResolvers[1].String()) 643 assert.EqualValues(t, "example.com", ips[0].ReverseDNS) 644 645 assert.EqualValues(t, "2a01:7c8:aab5:5d5::1", ips[1].Address.String()) 646 assert.EqualValues(t, "ffffffffffff00000000000000000000", ips[1].SubnetMask.String()) 647 assert.EqualValues(t, "2a01:7c8:aab5::1", ips[1].Gateway.String()) 648 assert.EqualValues(t, "2a01:7c8:7000:195:0:8:195:8", ips[1].DNSResolvers[0].String()) 649 assert.EqualValues(t, "2a01:7c8:7000:195:0:135:195:135", ips[1].DNSResolvers[1].String()) 650 assert.EqualValues(t, "example.com", ips[1].ReverseDNS) 651} 652 653func TestRepository_GetIPAddressByAddress(t *testing.T) { 654 const apiResponse = `{ "ipAddress": { "address": "37.97.254.6", "subnetMask": "255.255.255.0", "gateway": "37.97.254.1", "dnsResolvers": [ "195.8.195.8", "195.135.195.135" ], "reverseDns": "example.com" } } ` 655 server := mockServer{t: t, expectedURL: "/vps/example-vps/ip-addresses/37.97.254.6", expectedMethod: "GET", statusCode: 200, response: apiResponse} 656 client, tearDown := server.getClient() 657 defer tearDown() 658 repo := Repository{Client: *client} 659 660 address := net.ParseIP("37.97.254.6") 661 ip, err := repo.GetIPAddressByAddress("example-vps", address) 662 require.NoError(t, err) 663 664 assert.EqualValues(t, "37.97.254.6", ip.Address.String()) 665 assert.EqualValues(t, "00000000000000000000ffffffffff00", ip.SubnetMask.String()) 666 assert.EqualValues(t, "37.97.254.1", ip.Gateway.String()) 667 assert.EqualValues(t, "195.8.195.8", ip.DNSResolvers[0].String()) 668 assert.EqualValues(t, "195.135.195.135", ip.DNSResolvers[1].String()) 669 assert.EqualValues(t, "example.com", ip.ReverseDNS) 670} 671 672func TestRepository_AddIPv6Address(t *testing.T) { 673 const expectedRequest = `{"ipAddress":"2a01:7c8:3:1337::6"}` 674 server := mockServer{t: t, expectedURL: "/vps/example-vps/ip-addresses", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 675 client, tearDown := server.getClient() 676 defer tearDown() 677 repo := Repository{Client: *client} 678 679 address := net.ParseIP("2a01:7c8:3:1337::6") 680 err := repo.AddIPv6Address("example-vps", address) 681 require.NoError(t, err) 682} 683 684func TestRepository_UpdateReverseDNS(t *testing.T) { 685 const expectedRequest = `{"ipAddress":{"address":"37.97.254.6","gateway":"37.97.254.1","reverseDns":"example.com","subnetMask":"255.0.0.0"}}` 686 server := mockServer{t: t, expectedURL: "/vps/example-vps/ip-addresses/37.97.254.6", expectedMethod: "PUT", statusCode: 204, expectedRequest: expectedRequest} 687 client, tearDown := server.getClient() 688 defer tearDown() 689 repo := Repository{Client: *client} 690 691 ip := net.ParseIP("37.97.254.6") 692 address := ipaddress.IPAddress{ 693 Address: ip, 694 Gateway: net.ParseIP("37.97.254.1"), 695 ReverseDNS: "example.com", 696 SubnetMask: ipaddress.SubnetMask{IPMask: ip.DefaultMask()}, 697 } 698 err := repo.UpdateReverseDNS("example-vps", address) 699 require.NoError(t, err) 700} 701 702func TestRepository_RemoveIPv6Address(t *testing.T) { 703 server := mockServer{t: t, expectedURL: "/vps/example-vps/ip-addresses/2a01::1", expectedMethod: "DELETE", statusCode: 204} 704 client, tearDown := server.getClient() 705 defer tearDown() 706 repo := Repository{Client: *client} 707 708 address := net.ParseIP("2a01::1") 709 err := repo.RemoveIPv6Address("example-vps", address) 710 require.NoError(t, err) 711} 712 713func TestRepository_GetSnapshots(t *testing.T) { 714 const apiResponse = `{ "snapshots": [ { "name": "1572607577", "description": "before upgrade", "diskSize": 314572800, "status": "creating", "dateTimeCreate": "2019-07-14 12:21:11", "operatingSystem": "ubuntu-18.04" } ] } ` 715 server := mockServer{t: t, expectedURL: "/vps/example-vps/snapshots", expectedMethod: "GET", statusCode: 200, response: apiResponse} 716 client, tearDown := server.getClient() 717 defer tearDown() 718 repo := Repository{Client: *client} 719 720 all, err := repo.GetSnapshots("example-vps") 721 require.NoError(t, err) 722 require.Equal(t, 1, len(all)) 723 724 assert.Equal(t, "1572607577", all[0].Name) 725 assert.Equal(t, "before upgrade", all[0].Description) 726 assert.EqualValues(t, 314572800, all[0].DiskSize) 727 assert.EqualValues(t, "creating", all[0].Status) 728 assert.Equal(t, "2019-07-14 12:21:11", all[0].DateTimeCreate) 729 assert.Equal(t, "ubuntu-18.04", all[0].OperatingSystem) 730 731} 732 733func TestRepository_GetSnapshotByName(t *testing.T) { 734 const apiResponse = `{ "snapshot": { "name": "1572607577", "description": "before upgrade", "diskSize": 314572800, "status": "creating", "dateTimeCreate": "2019-07-14 12:21:11", "operatingSystem": "ubuntu-18.04" } }` 735 server := mockServer{t: t, expectedURL: "/vps/example-vps/snapshots/1572607577", expectedMethod: "GET", statusCode: 200, response: apiResponse} 736 client, tearDown := server.getClient() 737 defer tearDown() 738 repo := Repository{Client: *client} 739 740 snap, err := repo.GetSnapshotByName("example-vps", "1572607577") 741 require.NoError(t, err) 742 743 assert.Equal(t, "1572607577", snap.Name) 744 assert.Equal(t, "before upgrade", snap.Description) 745 assert.EqualValues(t, 314572800, snap.DiskSize) 746 assert.EqualValues(t, "creating", snap.Status) 747 assert.Equal(t, "2019-07-14 12:21:11", snap.DateTimeCreate) 748 assert.Equal(t, "ubuntu-18.04", snap.OperatingSystem) 749} 750 751func TestRepository_CreateSnapshot(t *testing.T) { 752 const expectedRequest = `{"description":"BeforeItsAllBroken","shouldStartVps":true}` 753 server := mockServer{t: t, expectedURL: "/vps/example-vps/snapshots", expectedMethod: "POST", statusCode: 201, expectedRequest: expectedRequest} 754 client, tearDown := server.getClient() 755 defer tearDown() 756 repo := Repository{Client: *client} 757 758 err := repo.CreateSnapshot("example-vps", "BeforeItsAllBroken", true) 759 require.NoError(t, err) 760} 761 762func TestRepository_RevertSnapshot(t *testing.T) { 763 server := mockServer{t: t, expectedURL: "/vps/example-vps/snapshots/1337", expectedMethod: "PATCH", statusCode: 204} 764 client, tearDown := server.getClient() 765 defer tearDown() 766 repo := Repository{Client: *client} 767 768 err := repo.RevertSnapshot("example-vps", "1337") 769 require.NoError(t, err) 770} 771 772func TestRepository_RevertSnapshotToOtherVps(t *testing.T) { 773 const expectedRequest = `{"destinationVpsName":"example-vps2"}` 774 server := mockServer{t: t, expectedURL: "/vps/example-vps/snapshots/1337", expectedMethod: "PATCH", statusCode: 204, expectedRequest: expectedRequest} 775 client, tearDown := server.getClient() 776 defer tearDown() 777 repo := Repository{Client: *client} 778 779 err := repo.RevertSnapshotToOtherVps("example-vps", "1337", "example-vps2") 780 require.NoError(t, err) 781} 782 783func TestRepository_RemoveSnapshot(t *testing.T) { 784 server := mockServer{t: t, expectedURL: "/vps/example-vps/snapshots/1337", expectedMethod: "DELETE", statusCode: 204} 785 client, tearDown := server.getClient() 786 defer tearDown() 787 repo := Repository{Client: *client} 788 789 err := repo.RemoveSnapshot("example-vps", "1337") 790 require.NoError(t, err) 791} 792 793func TestRepository_GetBackups(t *testing.T) { 794 const apiResponse = `{ "backups": [ { "id": 712332, "status": "active", "dateTimeCreate": "2019-11-29 22:11:20", "diskSize": 157286400, "operatingSystem": "Ubuntu 19.10", "availabilityZone": "ams0" } ] }` 795 server := mockServer{t: t, expectedURL: "/vps/example-vps/backups", expectedMethod: "GET", statusCode: 200, response: apiResponse} 796 client, tearDown := server.getClient() 797 defer tearDown() 798 repo := Repository{Client: *client} 799 800 all, err := repo.GetBackups("example-vps") 801 require.NoError(t, err) 802 require.Equal(t, 1, len(all)) 803 804 assert.EqualValues(t, 712332, all[0].ID) 805 assert.EqualValues(t, "active", all[0].Status) 806 assert.Equal(t, "2019-11-29 22:11:20", all[0].DateTimeCreate.Format("2006-01-02 15:04:05")) 807 assert.EqualValues(t, 157286400, all[0].DiskSize) 808 assert.Equal(t, "Ubuntu 19.10", all[0].OperatingSystem) 809 assert.Equal(t, "ams0", all[0].AvailabilityZone) 810} 811 812func TestRepository_RevertBackup(t *testing.T) { 813 const expectedRequest = `{"action":"revert"}` 814 server := mockServer{t: t, expectedURL: "/vps/example-vps/backups/1337", expectedMethod: "PATCH", statusCode: 204, expectedRequest: expectedRequest} 815 client, tearDown := server.getClient() 816 defer tearDown() 817 repo := Repository{Client: *client} 818 819 err := repo.RevertBackup("example-vps", 1337) 820 require.NoError(t, err) 821} 822 823func TestRepository_ConvertBackupToSnapshot(t *testing.T) { 824 const expectedRequest = `{"action":"convert","description":"BeforeItsAllBroken"}` 825 server := mockServer{t: t, expectedURL: "/vps/example-vps/backups/1337", expectedMethod: "PATCH", statusCode: 204, expectedRequest: expectedRequest} 826 client, tearDown := server.getClient() 827 defer tearDown() 828 repo := Repository{Client: *client} 829 830 err := repo.ConvertBackupToSnapshot("example-vps", 1337, "BeforeItsAllBroken") 831 require.NoError(t, err) 832} 833