Skip to content

Commit d393d55

Browse files
authored
Merge pull request #46 from thomasheller/backup-storages-created-and-origin
Support fields "created" and "origin" for backup storages
2 parents 8cbc8bc + 86ab503 commit d393d55

File tree

3 files changed

+131
-6
lines changed

3 files changed

+131
-6
lines changed

upcloud/service/service_test.go

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
package service
22

33
import (
4-
"github.com/UpCloudLtd/upcloud-go-api/upcloud"
5-
"github.com/UpCloudLtd/upcloud-go-api/upcloud/client"
6-
"github.com/UpCloudLtd/upcloud-go-api/upcloud/request"
74
"log"
85
"os"
96
"reflect"
107
"strings"
118
"testing"
129
"time"
10+
11+
"github.com/UpCloudLtd/upcloud-go-api/upcloud"
12+
"github.com/UpCloudLtd/upcloud-go-api/upcloud/client"
13+
"github.com/UpCloudLtd/upcloud-go-api/upcloud/request"
1314
)
1415

1516
// The service object used by the tests
@@ -18,7 +19,7 @@ var svc *Service
1819
// TestMain is the main test method
1920
func TestMain(m *testing.M) {
2021
setup()
21-
retCode := m.Run()
22+
retCode := m.Run()
2223

2324
// Optionally perform teardown
2425
deleteResources := os.Getenv("UPCLOUD_GO_SDK_TEST_DELETE_RESOURCES")
@@ -393,6 +394,7 @@ func TestLoadEjectCDROM(t *testing.T) {
393394
//
394395
// - creates a storage device
395396
// - creates a backup of the storage device
397+
// - gets backup storage details
396398
//
397399
// It's not feasible to test backup restoration due to time constraints
398400
func TestCreateBackup(t *testing.T) {
@@ -407,14 +409,42 @@ func TestCreateBackup(t *testing.T) {
407409

408410
// Create a backup
409411
t.Logf("Creating backup of storage with UUID %s ...", storageDetails.UUID)
412+
413+
timeBeforeBackup := utcTimeWithSecondPrecision()
414+
410415
backupDetails, err := svc.CreateBackup(&request.CreateBackupRequest{
411416
UUID: storageDetails.UUID,
412417
Title: "Backup",
413418
})
414419

415420
handleError(err)
416421
waitForStorageOnline(storageDetails.UUID)
422+
423+
timeAfterBackup := utcTimeWithSecondPrecision()
424+
417425
t.Logf("Created backup with UUID %s", backupDetails.UUID)
426+
427+
// Get backup storage details
428+
t.Logf("Getting details of backup storage with UUID %s ...", backupDetails.UUID)
429+
430+
backupStorageDetails, err := svc.GetStorageDetails(&request.GetStorageDetailsRequest{
431+
UUID: backupDetails.UUID,
432+
})
433+
handleError(err)
434+
435+
if backupStorageDetails.Origin != storageDetails.UUID {
436+
t.Errorf("The origin UUID %s of backup storage UUID %s does not match the actual origina UUID %s", backupStorageDetails.Origin, backupDetails.UUID, storageDetails.UUID)
437+
}
438+
439+
if backupStorageDetails.Created.Before(timeBeforeBackup) {
440+
t.Errorf("The creation timestamp of backup storage UUID %s is too early: %v (should be after %v)", backupDetails.UUID, backupStorageDetails.Created, timeBeforeBackup)
441+
}
442+
443+
if backupStorageDetails.Created.After(timeAfterBackup) {
444+
t.Errorf("The creation timestamp of backup storage UUID %s is too late: %v (should be before %v)", backupDetails.UUID, backupStorageDetails.Created, timeAfterBackup)
445+
}
446+
447+
t.Logf("Backup storage origin UUID OK")
418448
}
419449

420450
// TestAttachModifyReleaseIPAddress performs the following actions
@@ -740,6 +770,17 @@ func waitForStorageOnline(uuid string) {
740770
handleError(err)
741771
}
742772

773+
// Returns the current UTC time with second precision (milliseconds truncated).
774+
// This is the format we usually get from the UpCloud API.
775+
func utcTimeWithSecondPrecision() time.Time {
776+
utc, err := time.LoadLocation("UTC")
777+
handleError(err)
778+
779+
t := time.Now().In(utc).Truncate(time.Second)
780+
781+
return t
782+
}
783+
743784
// Handles the error by panicing, thus stopping the test execution
744785
func handleError(err error) {
745786
if err != nil {

upcloud/storage.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package upcloud
22

3-
import "encoding/xml"
3+
import (
4+
"encoding/xml"
5+
"time"
6+
)
47

58
// Constants
69
const (
@@ -54,6 +57,9 @@ type Storage struct {
5457
Type string `xml:"type"`
5558
UUID string `xml:"uuid"`
5659
Zone string `xml:"zone"`
60+
// Only for type "backup":
61+
Origin string `xml:"origin"`
62+
Created time.Time `xml:"created"`
5763
}
5864

5965
// StorageDetails represents detailed information about a piece of storage

upcloud/storage_test.go

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package upcloud
22

33
import (
44
"encoding/xml"
5-
"github.com/stretchr/testify/assert"
65
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/assert"
79
)
810

911
// TestUnmarshalStorage tests that Storages and Storage struct are unmarshaled correctly
@@ -54,6 +56,82 @@ func TestUnmarshalStorage(t *testing.T) {
5456
assert.Equal(t, "01000000-0000-4000-8000-000010010101", firstStorage.UUID)
5557
}
5658

59+
// TestUnmarshalStorage tests that Storages and Storage struct are unmarshaled correctly for private and backup storages
60+
func TestUnmarshalStoragesPrivateAndBackup(t *testing.T) {
61+
originalXML := `<?xml version="1.0" encoding="utf-8"?>
62+
<storages>
63+
<storage>
64+
<access>private</access>
65+
<license>0</license>
66+
<size>10</size>
67+
<state>online</state>
68+
<tier>hdd</tier>
69+
<title>Operating system disk</title>
70+
<type>normal</type>
71+
<uuid>01eff7ad-168e-413e-83b0-054f6a28fa23</uuid>
72+
<zone>uk-lon1</zone>
73+
</storage>
74+
<storage>
75+
<access>private</access>
76+
<created>2019-09-17T14:34:43Z</created>
77+
<license>0</license>
78+
<origin>01eff7ad-168e-413e-83b0-054f6a28fa23</origin>
79+
<size>10</size>
80+
<state>online</state>
81+
<title>On demand backup</title>
82+
<type>backup</type>
83+
<uuid>01287ad1-496c-4b5f-bb67-0fc2e3494740</uuid>
84+
<zone>uk-lon1</zone>
85+
</storage>
86+
<storage>
87+
<access>private</access>
88+
<license>0</license>
89+
<part_of_plan>yes</part_of_plan>
90+
<size>50</size>
91+
<state>online</state>
92+
<tier>maxiops</tier>
93+
<title>Databases</title>
94+
<type>normal</type>
95+
<uuid>01f3286c-a5ea-4670-8121-d0b9767d625b</uuid>
96+
<zone>fi-hel1</zone>
97+
</storage>
98+
</storages>`
99+
100+
storages := Storages{}
101+
err := xml.Unmarshal([]byte(originalXML), &storages)
102+
103+
assert.Nil(t, err)
104+
assert.Len(t, storages.Storages, 3)
105+
106+
firstStorage := storages.Storages[0]
107+
assert.Equal(t, "private", firstStorage.Access)
108+
assert.Equal(t, 0.0, firstStorage.License)
109+
assert.Equal(t, 10, firstStorage.Size)
110+
assert.Equal(t, "online", firstStorage.State)
111+
assert.Equal(t, "hdd", firstStorage.Tier)
112+
assert.Equal(t, "Operating system disk", firstStorage.Title)
113+
assert.Equal(t, "normal", firstStorage.Type)
114+
assert.Equal(t, "01eff7ad-168e-413e-83b0-054f6a28fa23", firstStorage.UUID)
115+
assert.Equal(t, "uk-lon1", firstStorage.Zone)
116+
assert.Equal(t, time.Time{}, firstStorage.Created)
117+
assert.Equal(t, "", firstStorage.Origin)
118+
119+
secondStorage := storages.Storages[1]
120+
assert.Equal(t, "private", secondStorage.Access)
121+
created, err := time.Parse(time.RFC3339, "2019-09-17T14:34:43Z")
122+
assert.Nil(t, err)
123+
assert.Equal(t, created, secondStorage.Created)
124+
assert.Equal(t, 0.0, secondStorage.License)
125+
assert.Equal(t, "01eff7ad-168e-413e-83b0-054f6a28fa23", secondStorage.Origin)
126+
assert.Equal(t, 10, secondStorage.Size)
127+
assert.Equal(t, "online", secondStorage.State)
128+
assert.Equal(t, "", secondStorage.Tier)
129+
assert.Equal(t, "On demand backup", secondStorage.Title)
130+
assert.Equal(t, "backup", secondStorage.Type)
131+
assert.Equal(t, "01287ad1-496c-4b5f-bb67-0fc2e3494740", secondStorage.UUID)
132+
assert.Equal(t, "uk-lon1", secondStorage.Zone)
133+
}
134+
57135
// TestUnmarshalStorageDetails tests that StorageDetails struct is unmarshaled correctly
58136
func TestUnmarshalStorageDetails(t *testing.T) {
59137
originalXML := `<?xml version="1.0" encoding="utf-8"?>

0 commit comments

Comments
 (0)