2
2
mirror of https://github.com/octoleo/restic.git synced 2024-06-29 13:53:29 +00:00
restic/vendor/github.com/Azure/azure-sdk-for-go/storage/entity_test.go
2017-08-06 21:47:04 +02:00

551 lines
17 KiB
Go

package storage
import (
"encoding/json"
"fmt"
"strings"
"time"
"github.com/satori/uuid"
chk "gopkg.in/check.v1"
)
type StorageEntitySuite struct{}
var _ = chk.Suite(&StorageEntitySuite{})
func (s *StorageEntitySuite) TestGet(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "myrowkey")
props := map[string]interface{}{
"AmountDue": 200.23,
"CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"),
"CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC),
"IsActive": true,
"NumberOfOrders": int64(255),
}
entity.Properties = props
err = entity.Insert(EmptyPayload, nil)
c.Assert(err, chk.IsNil)
err = entity.Get(30, FullMetadata, &GetEntityOptions{
Select: []string{"IsActive"},
})
c.Assert(err, chk.IsNil)
c.Assert(entity.Properties, chk.HasLen, 1)
err = entity.Get(30, FullMetadata, &GetEntityOptions{
Select: []string{
"AmountDue",
"CustomerCode",
"CustomerSince",
"IsActive",
"NumberOfOrders",
}})
c.Assert(err, chk.IsNil)
c.Assert(entity.Properties, chk.HasLen, 5)
err = entity.Get(30, FullMetadata, nil)
c.Assert(err, chk.IsNil)
c.Assert(entity.Properties, chk.HasLen, 5)
}
const (
validEtag = "W/\"datetime''2017-04-01T01%3A07%3A23.8881885Z''\""
)
func (s *StorageEntitySuite) TestInsert(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "myrowkey")
props := map[string]interface{}{
"AmountDue": 200.23,
"CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"),
"CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC),
"IsActive": true,
"NumberOfOrders": int64(255),
}
entity.Properties = props
err = entity.Insert(EmptyPayload, nil)
c.Assert(err, chk.IsNil)
// Did not update
c.Assert(entity.TimeStamp, chk.Equals, time.Time{})
c.Assert(entity.OdataMetadata, chk.Equals, "")
c.Assert(entity.OdataType, chk.Equals, "")
c.Assert(entity.OdataID, chk.Equals, "")
c.Assert(entity.OdataEtag, chk.Equals, "")
c.Assert(entity.OdataEditLink, chk.Equals, "")
// Update
entity.PartitionKey = "mypartitionkey2"
entity.RowKey = "myrowkey2"
err = entity.Insert(FullMetadata, nil)
c.Assert(err, chk.IsNil)
// Check everything was updated...
c.Assert(entity.TimeStamp, chk.NotNil)
c.Assert(entity.OdataMetadata, chk.Not(chk.Equals), "")
c.Assert(entity.OdataType, chk.Not(chk.Equals), "")
c.Assert(entity.OdataID, chk.Not(chk.Equals), "")
c.Assert(entity.OdataEtag, chk.Not(chk.Equals), "")
c.Assert(entity.OdataEditLink, chk.Not(chk.Equals), "")
}
func (s *StorageEntitySuite) TestUpdate(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "myrowkey")
entity.Properties = map[string]interface{}{
"AmountDue": 200.23,
"CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"),
"CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC),
"IsActive": true,
"NumberOfOrders": int64(255),
}
// Force update
err = entity.Insert(FullMetadata, nil)
c.Assert(err, chk.IsNil)
etag := entity.OdataEtag
timestamp := entity.TimeStamp
props := map[string]interface{}{
"Name": "Anakin",
"FamilyName": "Skywalker",
"HasEpicTheme": true,
}
entity.Properties = props
// Update providing etag
err = entity.Update(false, nil)
c.Assert(err, chk.IsNil)
c.Assert(entity.Properties, chk.DeepEquals, props)
c.Assert(entity.OdataEtag, chk.Not(chk.Equals), etag)
c.Assert(entity.TimeStamp, chk.Not(chk.Equals), timestamp)
// Try to update with old etag
entity.OdataEtag = validEtag
err = entity.Update(false, nil)
c.Assert(err, chk.NotNil)
c.Assert(strings.Contains(err.Error(), "Etag didn't match"), chk.Equals, true)
// Force update
props = map[string]interface{}{
"Name": "Leia",
"FamilyName": "Organa",
"HasAwesomeDress": true,
}
entity.Properties = props
err = entity.Update(true, nil)
c.Assert(err, chk.IsNil)
c.Assert(entity.Properties, chk.DeepEquals, props)
}
func (s *StorageEntitySuite) TestMerge(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "myrowkey")
entity.Properties = map[string]interface{}{
"Country": "Mexico",
"MalePoet": "Nezahualcoyotl",
}
c.Assert(entity.Insert(FullMetadata, nil), chk.IsNil)
etag := entity.OdataEtag
timestamp := entity.TimeStamp
entity.Properties = map[string]interface{}{
"FemalePoet": "Sor Juana Ines de la Cruz",
}
// Merge providing etag
err = entity.Merge(false, nil)
c.Assert(err, chk.IsNil)
c.Assert(entity.OdataEtag, chk.Not(chk.Equals), etag)
c.Assert(entity.TimeStamp, chk.Not(chk.Equals), timestamp)
// Try to merge with incorrect etag
entity.OdataEtag = validEtag
err = entity.Merge(false, nil)
c.Assert(err, chk.NotNil)
c.Assert(strings.Contains(err.Error(), "Etag didn't match"), chk.Equals, true)
// Force merge
entity.Properties = map[string]interface{}{
"MalePainter": "Diego Rivera",
"FemalePainter": "Frida Kahlo",
}
err = entity.Merge(true, nil)
c.Assert(err, chk.IsNil)
}
func (s *StorageEntitySuite) TestDelete(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
// Delete providing etag
entity1 := table.GetEntityReference("pkey1", "rowkey1")
c.Assert(entity1.Insert(FullMetadata, nil), chk.IsNil)
err = entity1.Delete(false, nil)
c.Assert(err, chk.IsNil)
// Try to delete with incorrect etag
entity2 := table.GetEntityReference("pkey2", "rowkey2")
c.Assert(entity2.Insert(EmptyPayload, nil), chk.IsNil)
entity2.OdataEtag = "GolangRocksOnAzure"
err = entity2.Delete(false, nil)
c.Assert(err, chk.NotNil)
// Force delete
err = entity2.Delete(true, nil)
c.Assert(err, chk.IsNil)
}
func (s *StorageEntitySuite) TestInsertOrReplace(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "myrowkey")
entity.Properties = map[string]interface{}{
"Name": "Anakin",
"FamilyName": "Skywalker",
"HasEpicTheme": true,
}
err = entity.InsertOrReplace(nil)
c.Assert(err, chk.IsNil)
entity.Properties = map[string]interface{}{
"Name": "Leia",
"FamilyName": "Organa",
"HasAwesomeDress": true,
}
err = entity.InsertOrReplace(nil)
c.Assert(err, chk.IsNil)
}
func (s *StorageEntitySuite) TestInsertOrMerge(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "myrowkey")
entity.Properties = map[string]interface{}{
"Name": "Luke",
"FamilyName": "Skywalker",
}
err = entity.InsertOrMerge(nil)
c.Assert(err, chk.IsNil)
entity.Properties = map[string]interface{}{
"Father": "Anakin",
"Mentor": "Yoda",
}
err = entity.InsertOrMerge(nil)
c.Assert(err, chk.IsNil)
}
func (s *StorageEntitySuite) Test_InsertAndGetEntities(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "100")
entity.Properties = map[string]interface{}{
"Name": "Luke",
"FamilyName": "Skywalker",
"HasCoolWeapon": true,
}
c.Assert(entity.Insert(EmptyPayload, nil), chk.IsNil)
entity.RowKey = "200"
c.Assert(entity.Insert(FullMetadata, nil), chk.IsNil)
entities, err := table.QueryEntities(30, FullMetadata, nil)
c.Assert(err, chk.IsNil)
c.Assert(entities.Entities, chk.HasLen, 2)
c.Assert(entities.OdataMetadata+"/@Element", chk.Equals, entity.OdataMetadata)
compareEntities(entities.Entities[1], entity, c)
}
func (s *StorageEntitySuite) Test_InsertAndExecuteQuery(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "100")
entity.Properties = map[string]interface{}{
"Name": "Luke",
"FamilyName": "Skywalker",
"HasCoolWeapon": true,
}
c.Assert(entity.Insert(EmptyPayload, nil), chk.IsNil)
entity.RowKey = "200"
c.Assert(entity.Insert(EmptyPayload, nil), chk.IsNil)
queryOptions := QueryOptions{
Filter: "RowKey eq '200'",
}
entities, err := table.QueryEntities(30, FullMetadata, &queryOptions)
c.Assert(err, chk.IsNil)
c.Assert(entities.Entities, chk.HasLen, 1)
c.Assert(entities.Entities[0].RowKey, chk.Equals, entity.RowKey)
}
func (s *StorageEntitySuite) Test_InsertAndDeleteEntities(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
entity := table.GetEntityReference("mypartitionkey", "100")
entity.Properties = map[string]interface{}{
"FamilyName": "Skywalker",
"Name": "Luke",
"Number": 3,
}
c.Assert(entity.Insert(EmptyPayload, nil), chk.IsNil)
entity.Properties["Number"] = 1
entity.RowKey = "200"
c.Assert(entity.Insert(FullMetadata, nil), chk.IsNil)
options := QueryOptions{
Filter: "Number eq 1",
}
result, err := table.QueryEntities(30, FullMetadata, &options)
c.Assert(err, chk.IsNil)
c.Assert(result.Entities, chk.HasLen, 1)
compareEntities(result.Entities[0], entity, c)
err = result.Entities[0].Delete(true, nil)
c.Assert(err, chk.IsNil)
result, err = table.QueryEntities(30, FullMetadata, nil)
c.Assert(err, chk.IsNil)
// only 1 entry must be present
c.Assert(result.Entities, chk.HasLen, 1)
}
func (s *StorageEntitySuite) TestExecuteQueryNextResults(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
table := cli.GetTableReference(tableName(c))
err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)
var entityList []*Entity
for i := 0; i < 5; i++ {
entity := table.GetEntityReference("pkey", fmt.Sprintf("r%d", i))
err := entity.Insert(FullMetadata, nil)
c.Assert(err, chk.IsNil)
entityList = append(entityList, entity)
}
// retrieve using top = 2. Should return 2 entries, 2 entries and finally
// 1 entry
options := QueryOptions{
Top: 2,
}
results, err := table.QueryEntities(30, FullMetadata, &options)
c.Assert(err, chk.IsNil)
c.Assert(results.Entities, chk.HasLen, 2)
c.Assert(results.NextLink, chk.NotNil)
compareEntities(results.Entities[0], entityList[0], c)
compareEntities(results.Entities[1], entityList[1], c)
results, err = results.NextResults(nil)
c.Assert(err, chk.IsNil)
c.Assert(results.Entities, chk.HasLen, 2)
c.Assert(results.NextLink, chk.NotNil)
compareEntities(results.Entities[0], entityList[2], c)
compareEntities(results.Entities[1], entityList[3], c)
results, err = results.NextResults(nil)
c.Assert(err, chk.IsNil)
c.Assert(results.Entities, chk.HasLen, 1)
c.Assert(results.NextLink, chk.IsNil)
compareEntities(results.Entities[0], entityList[4], c)
}
func (s *StorageEntitySuite) Test_entityMarshalJSON(c *chk.C) {
expected := `{"Address":"Mountain View","Age":23,"AmountDue":200.23,"Binary":"abcd","Binary@odata.type":"Edm.Binary","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerCode@odata.type":"Edm.Guid","CustomerSince":"1992-12-20T21:55:00Z","CustomerSince@odata.type":"Edm.DateTime","IsActive":true,"NumberOfOrders":"255","NumberOfOrders@odata.type":"Edm.Int64","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}`
entity := Entity{
PartitionKey: "mypartitionkey",
RowKey: "myrowkey",
Properties: map[string]interface{}{
"Address": "Mountain View",
"Age": 23,
"AmountDue": 200.23,
"Binary": []byte("abcd"),
"CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"),
"CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC),
"IsActive": true,
"NumberOfOrders": int64(255),
},
}
got, err := json.Marshal(&entity)
c.Assert(err, chk.IsNil)
c.Assert(string(got), chk.Equals, expected)
entity.Properties["Contoso@odata.type"] = "Edm.Trololololol"
got, err = json.Marshal(&entity)
c.Assert(got, chk.IsNil)
c.Assert(err, chk.ErrorMatches, ".*Odata.type annotation Contoso@odata.type value is not valid")
entity.Properties["Contoso@odata.type"] = OdataGUID
got, err = json.Marshal(&entity)
c.Assert(got, chk.IsNil)
c.Assert(err, chk.ErrorMatches, ".*Odata.type annotation Contoso@odata.type defined without value defined")
}
func (s *StorageEntitySuite) Test_entityUnmarshalJSON(c *chk.C) {
input := `{
"odata.metadata":"https://azuregosdkstoragetests.table.core.windows.net/$metadata#SampleTable/@Element",
"odata.type":"azuregosdkstoragetests.SampleTable",
"odata.id":"https://azuregosdkstoragetests.table.core.windows.net/SampleTable(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')",
"odata.etag":"W/\"datetime''2017-01-27T01%3A01%3A44.151805Z''\"",
"odata.editLink":"SampleTable(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')",
"PartitionKey":"mypartitionkey",
"RowKey":"myrowkey",
"Timestamp":"2017-01-27T01:01:44.151805Z",
"Timestamp@odata.type":"Edm.DateTime",
"Address": "Mountain View",
"Age": 23,
"AmountDue":200.23,
"Binary@odata.type": "Edm.Binary",
"Binary": "abcd",
"CustomerCode@odata.type":"Edm.Guid",
"CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833",
"CustomerSince@odata.type":"Edm.DateTime",
"CustomerSince":"1992-12-20T21:55:00Z",
"IsActive":true,
"NumberOfOrders@odata.type":"Edm.Int64",
"NumberOfOrders":"255"}`
var entity Entity
data := []byte(input)
err := json.Unmarshal(data, &entity)
c.Assert(err, chk.IsNil)
expectedProperties := map[string]interface{}{
"Address": "Mountain View",
"Age": 23,
"AmountDue": 200.23,
"Binary": []byte("abcd"),
"CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"),
"CustomerSince": time.Date(1992, 12, 20, 21, 55, 0, 0, time.UTC),
"IsActive": true,
"NumberOfOrders": int64(255),
}
c.Assert(entity.OdataMetadata, chk.Equals, "https://azuregosdkstoragetests.table.core.windows.net/$metadata#SampleTable/@Element")
c.Assert(entity.OdataType, chk.Equals, "azuregosdkstoragetests.SampleTable")
c.Assert(entity.OdataID, chk.Equals, "https://azuregosdkstoragetests.table.core.windows.net/SampleTable(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')")
c.Assert(entity.OdataEtag, chk.Equals, "W/\"datetime''2017-01-27T01%3A01%3A44.151805Z''\"")
c.Assert(entity.OdataEditLink, chk.Equals, "SampleTable(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')")
c.Assert(entity.PartitionKey, chk.Equals, "mypartitionkey")
c.Assert(entity.RowKey, chk.Equals, "myrowkey")
c.Assert(entity.TimeStamp, chk.Equals, time.Date(2017, 1, 27, 1, 1, 44, 151805000, time.UTC))
c.Assert(entity.Properties, chk.HasLen, len(expectedProperties))
c.Assert(entity.Properties["Address"], chk.Equals, expectedProperties["Address"])
// Note on Age assertion... Looks like the json unmarshaller thinks all numbers are float64.
c.Assert(entity.Properties["Age"], chk.Equals, float64(expectedProperties["Age"].(int)))
c.Assert(entity.Properties["AmountDue"], chk.Equals, expectedProperties["AmountDue"])
c.Assert(entity.Properties["Binary"], chk.DeepEquals, expectedProperties["Binary"])
c.Assert(entity.Properties["CustomerSince"], chk.Equals, expectedProperties["CustomerSince"])
c.Assert(entity.Properties["IsActive"], chk.Equals, expectedProperties["IsActive"])
c.Assert(entity.Properties["NumberOfOrders"], chk.Equals, expectedProperties["NumberOfOrders"])
}
func compareEntities(got, expected *Entity, c *chk.C) {
c.Assert(got.PartitionKey, chk.Equals, expected.PartitionKey)
c.Assert(got.RowKey, chk.Equals, expected.RowKey)
c.Assert(got.TimeStamp, chk.Equals, expected.TimeStamp)
c.Assert(got.OdataEtag, chk.Equals, expected.OdataEtag)
c.Assert(got.OdataType, chk.Equals, expected.OdataType)
c.Assert(got.OdataID, chk.Equals, expected.OdataID)
c.Assert(got.OdataEditLink, chk.Equals, expected.OdataEditLink)
c.Assert(got.Properties, chk.DeepEquals, expected.Properties)
}