github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/state/api/params/params_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package params_test 5 6 import ( 7 "encoding/json" 8 "testing" 9 10 "github.com/juju/charm" 11 gc "launchpad.net/gocheck" 12 13 "github.com/juju/juju/constraints" 14 "github.com/juju/juju/instance" 15 "github.com/juju/juju/network" 16 "github.com/juju/juju/state" 17 "github.com/juju/juju/state/api/params" 18 ) 19 20 // TestPackage integrates the tests into gotest. 21 func TestPackage(t *testing.T) { 22 gc.TestingT(t) 23 } 24 25 type MarshalSuite struct{} 26 27 var _ = gc.Suite(&MarshalSuite{}) 28 29 var marshalTestCases = []struct { 30 about string 31 // Value holds a real Go struct. 32 value params.Delta 33 // JSON document. 34 json string 35 }{{ 36 about: "MachineInfo Delta", 37 value: params.Delta{ 38 Entity: ¶ms.MachineInfo{ 39 Id: "Benji", 40 InstanceId: "Shazam", 41 Status: "error", 42 StatusInfo: "foo", 43 Life: params.Alive, 44 Series: "trusty", 45 SupportedContainers: []instance.ContainerType{instance.LXC}, 46 Jobs: []params.MachineJob{state.JobManageEnviron.ToParams()}, 47 Addresses: []network.Address{}, 48 HardwareCharacteristics: &instance.HardwareCharacteristics{}, 49 }, 50 }, 51 json: `["machine","change",{"Id":"Benji","InstanceId":"Shazam","Status":"error","StatusInfo":"foo","StatusData":null,"Life":"alive","Series":"trusty","SupportedContainers":["lxc"],"SupportedContainersKnown":false,"Jobs":["JobManageEnviron"],"Addresses":[],"HardwareCharacteristics":{}}]`, 52 }, { 53 about: "ServiceInfo Delta", 54 value: params.Delta{ 55 Entity: ¶ms.ServiceInfo{ 56 Name: "Benji", 57 Exposed: true, 58 CharmURL: "cs:quantal/name", 59 Life: params.Dying, 60 OwnerTag: "test-owner", 61 MinUnits: 42, 62 Constraints: constraints.MustParse("arch=armhf mem=1024M"), 63 Config: charm.Settings{ 64 "hello": "goodbye", 65 "foo": false, 66 }, 67 }, 68 }, 69 json: `["service","change",{"CharmURL": "cs:quantal/name","Name":"Benji","Exposed":true,"Life":"dying","OwnerTag":"test-owner","MinUnits":42,"Constraints":{"arch":"armhf", "mem": 1024},"Config": {"hello":"goodbye","foo":false}}]`, 70 }, { 71 about: "UnitInfo Delta", 72 value: params.Delta{ 73 Entity: ¶ms.UnitInfo{ 74 Name: "Benji", 75 Service: "Shazam", 76 Series: "precise", 77 CharmURL: "cs:~user/precise/wordpress-42", 78 Ports: []network.Port{ 79 { 80 Protocol: "http", 81 Number: 80}, 82 }, 83 PublicAddress: "testing.invalid", 84 PrivateAddress: "10.0.0.1", 85 MachineId: "1", 86 Status: "error", 87 StatusInfo: "foo", 88 }, 89 }, 90 json: `["unit", "change", {"CharmURL": "cs:~user/precise/wordpress-42", "MachineId": "1", "Series": "precise", "Name": "Benji", "PublicAddress": "testing.invalid", "Service": "Shazam", "PrivateAddress": "10.0.0.1", "Ports": [{"Protocol": "http", "Number": 80}], "Status": "error", "StatusInfo": "foo","StatusData":null}]`, 91 }, { 92 about: "RelationInfo Delta", 93 value: params.Delta{ 94 Entity: ¶ms.RelationInfo{ 95 Key: "Benji", 96 Id: 4711, 97 Endpoints: []params.Endpoint{ 98 {ServiceName: "logging", Relation: charm.Relation{Name: "logging-directory", Role: "requirer", Interface: "logging", Optional: false, Limit: 1, Scope: "container"}}, 99 {ServiceName: "wordpress", Relation: charm.Relation{Name: "logging-dir", Role: "provider", Interface: "logging", Optional: false, Limit: 0, Scope: "container"}}}, 100 }, 101 }, 102 json: `["relation","change",{"Key":"Benji", "Id": 4711, "Endpoints": [{"ServiceName":"logging", "Relation":{"Name":"logging-directory", "Role":"requirer", "Interface":"logging", "Optional":false, "Limit":1, "Scope":"container"}}, {"ServiceName":"wordpress", "Relation":{"Name":"logging-dir", "Role":"provider", "Interface":"logging", "Optional":false, "Limit":0, "Scope":"container"}}]}]`, 103 }, { 104 about: "AnnotationInfo Delta", 105 value: params.Delta{ 106 Entity: ¶ms.AnnotationInfo{ 107 Tag: "machine-0", 108 Annotations: map[string]string{ 109 "foo": "bar", 110 "arble": "2 4", 111 }, 112 }, 113 }, 114 json: `["annotation","change",{"Tag":"machine-0","Annotations":{"foo":"bar","arble":"2 4"}}]`, 115 }, { 116 about: "Delta Removed True", 117 value: params.Delta{ 118 Removed: true, 119 Entity: ¶ms.RelationInfo{ 120 Key: "Benji", 121 }, 122 }, 123 json: `["relation","remove",{"Key":"Benji", "Id": 0, "Endpoints": null}]`, 124 }} 125 126 func (s *MarshalSuite) TestDeltaMarshalJSON(c *gc.C) { 127 for _, t := range marshalTestCases { 128 c.Log(t.about) 129 output, err := t.value.MarshalJSON() 130 c.Check(err, gc.IsNil) 131 // We check unmarshalled output both to reduce the fragility of the 132 // tests (because ordering in the maps can change) and to verify that 133 // the output is well-formed. 134 var unmarshalledOutput interface{} 135 err = json.Unmarshal(output, &unmarshalledOutput) 136 c.Check(err, gc.IsNil) 137 var expected interface{} 138 err = json.Unmarshal([]byte(t.json), &expected) 139 c.Check(err, gc.IsNil) 140 c.Check(unmarshalledOutput, gc.DeepEquals, expected) 141 } 142 } 143 144 func (s *MarshalSuite) TestDeltaUnmarshalJSON(c *gc.C) { 145 for i, t := range marshalTestCases { 146 c.Logf("test %d. %s", i, t.about) 147 var unmarshalled params.Delta 148 err := json.Unmarshal([]byte(t.json), &unmarshalled) 149 c.Check(err, gc.IsNil) 150 c.Check(unmarshalled, gc.DeepEquals, t.value) 151 } 152 } 153 154 func (s *MarshalSuite) TestDeltaMarshalJSONCardinality(c *gc.C) { 155 err := json.Unmarshal([]byte(`[1,2]`), new(params.Delta)) 156 c.Check(err, gc.ErrorMatches, "Expected 3 elements in top-level of JSON but got 2") 157 } 158 159 func (s *MarshalSuite) TestDeltaMarshalJSONUnknownOperation(c *gc.C) { 160 err := json.Unmarshal([]byte(`["relation","masticate",{}]`), new(params.Delta)) 161 c.Check(err, gc.ErrorMatches, `Unexpected operation "masticate"`) 162 } 163 164 func (s *MarshalSuite) TestDeltaMarshalJSONUnknownEntity(c *gc.C) { 165 err := json.Unmarshal([]byte(`["qwan","change",{}]`), new(params.Delta)) 166 c.Check(err, gc.ErrorMatches, `Unexpected entity name "qwan"`) 167 }