1 package storage
2
3
4
5
6 import (
7 "bytes"
8 "encoding/hex"
9 "encoding/xml"
10 "flag"
11 "fmt"
12 "io/ioutil"
13 "net/url"
14 "os"
15 "path/filepath"
16 "strings"
17 "testing"
18 "time"
19
20 chk "gopkg.in/check.v1"
21 )
22
23 var (
24 overwriteRec bool
25 pwd string
26 )
27
28 func TestMain(m *testing.M) {
29 var err error
30 flag.BoolVar(&overwriteRec, "ow", false, "Regenerate recordings for testing")
31 pwd, err = os.Getwd()
32 if err != nil {
33 fmt.Fprintf(os.Stderr, "Unable to get current working directory: %v\n", err)
34 os.Exit(1)
35 }
36 exitStatus := m.Run()
37 err = fixRecordings()
38 if err != nil {
39 fmt.Fprintf(os.Stderr, "After test run, fixing recordings failed with error: %v\n", err)
40 exitStatus = 1
41 }
42 os.Exit(exitStatus)
43 }
44
45 func fixRecordings() error {
46 err := filepath.Walk(recordingsFolder, func(path string, file os.FileInfo, err error) error {
47 if strings.ToLower(filepath.Ext(path)) == ".yaml" {
48 recording, err := ioutil.ReadFile(path)
49 if err != nil {
50 fmt.Fprintf(os.Stderr, "Error reading file '%s': %v", path, err)
51 }
52
53 fixedRecording := replaceStorageAccount(string(recording))
54
55 err = ioutil.WriteFile(path, []byte(fixedRecording), 0)
56 if err != nil {
57 fmt.Fprintf(os.Stderr, "Error writing file '%s': %v", path, err)
58 }
59 }
60 return err
61 })
62 return err
63 }
64
65 func replaceStorageAccount(recording string) string {
66 name := os.Getenv("ACCOUNT_NAME")
67 if name == "" {
68
69 return recording
70 }
71
72 nameHex := getHex(name)
73 dummyHex := getHex(dummyStorageAccount)
74
75 r := strings.NewReplacer(name, dummyStorageAccount,
76 nameHex, dummyHex)
77
78 return r.Replace(string(recording))
79 }
80
81 func getHex(input string) string {
82 encoded := strings.ToUpper(hex.EncodeToString([]byte(input)))
83 formatted := bytes.Buffer{}
84 for i := 0; i < len(encoded); i += 2 {
85 formatted.WriteString(`\x`)
86 formatted.WriteString(encoded[i : i+2])
87 }
88 return formatted.String()
89 }
90
91 const (
92 dummyStorageAccount = "golangrocksonazure"
93 dummyMiniStorageKey = "YmFy"
94 recordingsFolder = "recordings"
95 )
96
97 func (s *StorageClientSuite) Test_timeRfc1123Formatted(c *chk.C) {
98 now := time.Now().UTC()
99 expectedLayout := "Mon, 02 Jan 2006 15:04:05 GMT"
100 c.Assert(timeRfc1123Formatted(now), chk.Equals, now.Format(expectedLayout))
101 }
102
103 func (s *StorageClientSuite) Test_mergeParams(c *chk.C) {
104 v1 := url.Values{
105 "k1": {"v1"},
106 "k2": {"v2"}}
107 v2 := url.Values{
108 "k1": {"v11"},
109 "k3": {"v3"}}
110 out := mergeParams(v1, v2)
111 c.Assert(out.Get("k1"), chk.Equals, "v1")
112 c.Assert(out.Get("k2"), chk.Equals, "v2")
113 c.Assert(out.Get("k3"), chk.Equals, "v3")
114 c.Assert(out["k1"], chk.DeepEquals, []string{"v1", "v11"})
115 }
116
117 func (s *StorageClientSuite) Test_prepareBlockListRequest(c *chk.C) {
118 empty := []Block{}
119 expected := `<?xml version="1.0" encoding="utf-8"?><BlockList></BlockList>`
120 c.Assert(prepareBlockListRequest(empty), chk.DeepEquals, expected)
121
122 blocks := []Block{{"lol", BlockStatusLatest}, {"rofl", BlockStatusUncommitted}}
123 expected = `<?xml version="1.0" encoding="utf-8"?><BlockList><Latest>lol</Latest><Uncommitted>rofl</Uncommitted></BlockList>`
124 c.Assert(prepareBlockListRequest(blocks), chk.DeepEquals, expected)
125 }
126
127 func (s *StorageClientSuite) Test_xmlUnmarshal(c *chk.C) {
128 xml := `<?xml version="1.0" encoding="utf-8"?>
129 <Blob>
130 <Name>myblob</Name>
131 </Blob>`
132 var blob Blob
133 body := ioutil.NopCloser(strings.NewReader(xml))
134 c.Assert(xmlUnmarshal(body, &blob), chk.IsNil)
135 c.Assert(blob.Name, chk.Equals, "myblob")
136 }
137
138 func (s *StorageClientSuite) Test_xmlMarshal(c *chk.C) {
139 type t struct {
140 XMLName xml.Name `xml:"S"`
141 Name string `xml:"Name"`
142 }
143
144 b := t{Name: "myblob"}
145 expected := `<S><Name>myblob</Name></S>`
146 r, i, err := xmlMarshal(b)
147 c.Assert(err, chk.IsNil)
148 o, err := ioutil.ReadAll(r)
149 c.Assert(err, chk.IsNil)
150 out := string(o)
151 c.Assert(out, chk.Equals, expected)
152 c.Assert(i, chk.Equals, len(expected))
153 }
154
155 func (s *StorageClientSuite) Test_headersFromStruct(c *chk.C) {
156 type t struct {
157 Header1 string `header:"HEADER1"`
158 Header2 string `header:"HEADER2"`
159 TimePtr *time.Time `header:"ptr-time-header"`
160 TimeHeader time.Time `header:"time-header"`
161 UintPtr *uint `header:"ptr-uint-header"`
162 UintHeader uint `header:"uint-header"`
163 IntPtr *int `header:"ptr-int-header"`
164 IntHeader int `header:"int-header"`
165 StringAliasPtr *BlobType `header:"ptr-string-alias-header"`
166 StringAlias BlobType `header:"string-alias-header"`
167 NilPtr *time.Time `header:"nil-ptr"`
168 EmptyString string `header:"empty-string"`
169 }
170
171 timeHeader := time.Date(1985, time.February, 23, 10, 0, 0, 0, time.Local)
172 uintHeader := uint(15)
173 intHeader := 30
174 alias := BlobTypeAppend
175 h := t{
176 Header1: "value1",
177 Header2: "value2",
178 TimePtr: &timeHeader,
179 TimeHeader: timeHeader,
180 UintPtr: &uintHeader,
181 UintHeader: uintHeader,
182 IntPtr: &intHeader,
183 IntHeader: intHeader,
184 StringAliasPtr: &alias,
185 StringAlias: alias,
186 }
187 expected := map[string]string{
188 "HEADER1": "value1",
189 "HEADER2": "value2",
190 "ptr-time-header": "Sat, 23 Feb 1985 10:00:00 GMT",
191 "time-header": "Sat, 23 Feb 1985 10:00:00 GMT",
192 "ptr-uint-header": "15",
193 "uint-header": "15",
194 "ptr-int-header": "30",
195 "int-header": "30",
196 "ptr-string-alias-header": "AppendBlob",
197 "string-alias-header": "AppendBlob",
198 }
199
200 out := headersFromStruct(h)
201
202 c.Assert(out, chk.DeepEquals, expected)
203 }
204
View as plain text