1package storage
2
3// Copyright 2017 Microsoft Corporation
4//
5//  Licensed under the Apache License, Version 2.0 (the "License");
6//  you may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at
8//
9//      http://www.apache.org/licenses/LICENSE-2.0
10//
11//  Unless required by applicable law or agreed to in writing, software
12//  distributed under the License is distributed on an "AS IS" BASIS,
13//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14//  See the License for the specific language governing permissions and
15//  limitations under the License.
16
17import (
18	"strconv"
19	"time"
20
21	chk "gopkg.in/check.v1"
22)
23
24type StorageTableSuite struct{}
25
26var _ = chk.Suite(&StorageTableSuite{})
27
28func getTableClient(c *chk.C) TableServiceClient {
29	return getBasicClient(c).GetTableService()
30}
31
32func (cli *TableServiceClient) deleteAllTables() {
33	if result, _ := cli.QueryTables(MinimalMetadata, nil); result != nil {
34		for _, t := range result.Tables {
35			t.Delete(30, nil)
36		}
37	}
38}
39
40func (s *StorageTableSuite) Test_CreateAndDeleteTable(c *chk.C) {
41	cli := getTableClient(c)
42	rec := cli.client.appendRecorder(c)
43	defer rec.Stop()
44
45	table1 := cli.GetTableReference(tableName(c, "1"))
46	err := table1.Create(30, EmptyPayload, nil)
47	c.Assert(err, chk.IsNil)
48
49	// update table metadata
50	table2 := cli.GetTableReference(tableName(c, "2"))
51	err = table2.Create(30, FullMetadata, nil)
52	defer table2.Delete(30, nil)
53	c.Assert(err, chk.IsNil)
54
55	// Check not empty values
56	c.Assert(table2.OdataEditLink, chk.Not(chk.Equals), "")
57	c.Assert(table2.OdataID, chk.Not(chk.Equals), "")
58	c.Assert(table2.OdataMetadata, chk.Not(chk.Equals), "")
59	c.Assert(table2.OdataType, chk.Not(chk.Equals), "")
60
61	err = table1.Delete(30, nil)
62	c.Assert(err, chk.IsNil)
63}
64
65func (s *StorageTableSuite) Test_CreateTableWithAllResponsePayloadLevels(c *chk.C) {
66	cli := getTableClient(c)
67	rec := cli.client.appendRecorder(c)
68	defer rec.Stop()
69
70	createAndDeleteTable(cli, EmptyPayload, c, "empty")
71	createAndDeleteTable(cli, NoMetadata, c, "nm")
72	createAndDeleteTable(cli, MinimalMetadata, c, "minimal")
73	createAndDeleteTable(cli, FullMetadata, c, "full")
74}
75
76func (s *StorageTableSuite) TestGet(c *chk.C) {
77	cli := getTableClient(c)
78	rec := cli.client.appendRecorder(c)
79	defer rec.Stop()
80
81	tn := tableName(c)
82	table := cli.GetTableReference(tn)
83	err := table.Create(30, EmptyPayload, nil)
84	c.Assert(err, chk.IsNil)
85	defer table.Delete(30, nil)
86
87	err = table.Get(30, FullMetadata)
88	c.Assert(err, chk.IsNil)
89	c.Assert(table.Name, chk.Equals, tn)
90	c.Assert(table.OdataEditLink, chk.Not(chk.Equals), "")
91	c.Assert(table.OdataID, chk.Not(chk.Equals), "")
92	c.Assert(table.OdataMetadata, chk.Not(chk.Equals), "")
93	c.Assert(table.OdataType, chk.Not(chk.Equals), "")
94}
95
96func createAndDeleteTable(cli TableServiceClient, ml MetadataLevel, c *chk.C, extra string) {
97	table := cli.GetTableReference(tableName(c, extra))
98	c.Assert(table.Create(30, ml, nil), chk.IsNil)
99	c.Assert(table.Delete(30, nil), chk.IsNil)
100}
101
102func (s *StorageTableSuite) TestQueryTablesNextResults(c *chk.C) {
103	cli := getTableClient(c)
104	cli.deleteAllTables()
105	rec := cli.client.appendRecorder(c)
106	defer rec.Stop()
107
108	for i := 0; i < 3; i++ {
109		table := cli.GetTableReference(tableName(c, strconv.Itoa(i)))
110		err := table.Create(30, EmptyPayload, nil)
111		c.Assert(err, chk.IsNil)
112		defer table.Delete(30, nil)
113	}
114
115	options := QueryTablesOptions{
116		Top: 2,
117	}
118	result, err := cli.QueryTables(MinimalMetadata, &options)
119	c.Assert(err, chk.IsNil)
120	c.Assert(result.Tables, chk.HasLen, 2)
121	c.Assert(result.NextLink, chk.NotNil)
122
123	result, err = result.NextResults(nil)
124	c.Assert(err, chk.IsNil)
125	c.Assert(result.Tables, chk.HasLen, 1)
126	c.Assert(result.NextLink, chk.IsNil)
127
128	result, err = result.NextResults(nil)
129	c.Assert(result, chk.IsNil)
130	c.Assert(err, chk.NotNil)
131}
132
133func appendTablePermission(policies []TableAccessPolicy, ID string,
134	canRead bool, canAppend bool, canUpdate bool, canDelete bool,
135	startTime time.Time, expiryTime time.Time) []TableAccessPolicy {
136
137	tap := TableAccessPolicy{
138		ID:         ID,
139		StartTime:  startTime,
140		ExpiryTime: expiryTime,
141		CanRead:    canRead,
142		CanAppend:  canAppend,
143		CanUpdate:  canUpdate,
144		CanDelete:  canDelete,
145	}
146	policies = append(policies, tap)
147	return policies
148}
149
150func (s *StorageTableSuite) TestSetPermissionsSuccessfully(c *chk.C) {
151	cli := getTableClient(c)
152	rec := cli.client.appendRecorder(c)
153	defer rec.Stop()
154
155	table := cli.GetTableReference(tableName(c))
156	c.Assert(table.Create(30, EmptyPayload, nil), chk.IsNil)
157	defer table.Delete(30, nil)
158
159	policies := []TableAccessPolicy{}
160	policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, fixedTime, fixedTime.Add(10*time.Hour))
161
162	err := table.SetPermissions(policies, 30, nil)
163	c.Assert(err, chk.IsNil)
164}
165
166func (s *StorageTableSuite) TestSetPermissionsUnsuccessfully(c *chk.C) {
167	cli := getTableClient(c)
168	rec := cli.client.appendRecorder(c)
169	defer rec.Stop()
170
171	table := cli.GetTableReference("nonexistingtable")
172
173	policies := []TableAccessPolicy{}
174	policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, fixedTime, fixedTime.Add(10*time.Hour))
175
176	err := table.SetPermissions(policies, 30, nil)
177	c.Assert(err, chk.NotNil)
178}
179
180func (s *StorageTableSuite) TestSetThenGetPermissionsSuccessfully(c *chk.C) {
181	cli := getTableClient(c)
182	rec := cli.client.appendRecorder(c)
183	defer rec.Stop()
184
185	table := cli.GetTableReference(tableName(c))
186	c.Assert(table.Create(30, EmptyPayload, nil), chk.IsNil)
187	defer table.Delete(30, nil)
188
189	policies := []TableAccessPolicy{}
190	policies = appendTablePermission(policies, "GolangRocksOnAzure", true, true, true, true, fixedTime, fixedTime.Add(10*time.Hour))
191	policies = appendTablePermission(policies, "AutoRestIsSuperCool", true, true, false, true, fixedTime.Add(20*time.Hour), fixedTime.Add(30*time.Hour))
192
193	err := table.SetPermissions(policies, 30, nil)
194	c.Assert(err, chk.IsNil)
195
196	newPolicies, err := table.GetPermissions(30, nil)
197	c.Assert(err, chk.IsNil)
198
199	// fixedTime check policy set.
200	c.Assert(newPolicies, chk.HasLen, 2)
201
202	for i := range newPolicies {
203		c.Assert(newPolicies[i].ID, chk.Equals, policies[i].ID)
204
205		// test timestamps down the second
206		// rounding start/expiry time original perms since the returned perms would have been rounded.
207		// so need rounded vs rounded.
208		c.Assert(newPolicies[i].StartTime.UTC().Round(time.Second).Format(time.RFC1123),
209			chk.Equals, policies[i].StartTime.UTC().Round(time.Second).Format(time.RFC1123))
210		c.Assert(newPolicies[i].ExpiryTime.UTC().Round(time.Second).Format(time.RFC1123),
211			chk.Equals, policies[i].ExpiryTime.UTC().Round(time.Second).Format(time.RFC1123))
212
213		c.Assert(newPolicies[i].CanRead, chk.Equals, policies[i].CanRead)
214		c.Assert(newPolicies[i].CanAppend, chk.Equals, policies[i].CanAppend)
215		c.Assert(newPolicies[i].CanUpdate, chk.Equals, policies[i].CanUpdate)
216		c.Assert(newPolicies[i].CanDelete, chk.Equals, policies[i].CanDelete)
217	}
218}
219
220func tableName(c *chk.C, extras ...string) string {
221	// 32 is the max len for table names
222	return nameGenerator(32, "table", alpha, c, extras)
223}
224