github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/core/description/service_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package description 5 6 import ( 7 "github.com/juju/names" 8 jc "github.com/juju/testing/checkers" 9 gc "gopkg.in/check.v1" 10 "gopkg.in/yaml.v2" 11 ) 12 13 type ServiceSerializationSuite struct { 14 SliceSerializationSuite 15 StatusHistoryMixinSuite 16 } 17 18 var _ = gc.Suite(&ServiceSerializationSuite{}) 19 20 func (s *ServiceSerializationSuite) SetUpTest(c *gc.C) { 21 s.SliceSerializationSuite.SetUpTest(c) 22 s.importName = "services" 23 s.sliceName = "services" 24 s.importFunc = func(m map[string]interface{}) (interface{}, error) { 25 return importServices(m) 26 } 27 s.testFields = func(m map[string]interface{}) { 28 m["services"] = []interface{}{} 29 } 30 s.StatusHistoryMixinSuite.creator = func() HasStatusHistory { 31 return minimalService() 32 } 33 s.StatusHistoryMixinSuite.serializer = func(c *gc.C, initial interface{}) HasStatusHistory { 34 return s.exportImport(c, initial.(*service)) 35 } 36 } 37 38 func minimalServiceMap() map[interface{}]interface{} { 39 return map[interface{}]interface{}{ 40 "name": "ubuntu", 41 "series": "trusty", 42 "charm-url": "cs:trusty/ubuntu", 43 "cs-channel": "stable", 44 "charm-mod-version": 1, 45 "status": minimalStatusMap(), 46 "status-history": emptyStatusHistoryMap(), 47 "settings": map[interface{}]interface{}{ 48 "key": "value", 49 }, 50 "settings-refcount": 1, 51 "leader": "ubuntu/0", 52 "leadership-settings": map[interface{}]interface{}{ 53 "leader": true, 54 }, 55 "metrics-creds": "c2Vrcml0", // base64 encoded 56 "units": map[interface{}]interface{}{ 57 "version": 1, 58 "units": []interface{}{ 59 minimalUnitMap(), 60 }, 61 }, 62 } 63 } 64 65 func minimalService() *service { 66 s := newService(minimalServiceArgs()) 67 s.SetStatus(minimalStatusArgs()) 68 u := s.AddUnit(minimalUnitArgs()) 69 u.SetAgentStatus(minimalStatusArgs()) 70 u.SetWorkloadStatus(minimalStatusArgs()) 71 u.SetTools(minimalAgentToolsArgs()) 72 return s 73 } 74 75 func addMinimalService(model Model) { 76 s := model.AddService(minimalServiceArgs()) 77 s.SetStatus(minimalStatusArgs()) 78 u := s.AddUnit(minimalUnitArgs()) 79 u.SetAgentStatus(minimalStatusArgs()) 80 u.SetWorkloadStatus(minimalStatusArgs()) 81 u.SetTools(minimalAgentToolsArgs()) 82 } 83 84 func minimalServiceArgs() ServiceArgs { 85 return ServiceArgs{ 86 Tag: names.NewServiceTag("ubuntu"), 87 Series: "trusty", 88 CharmURL: "cs:trusty/ubuntu", 89 Channel: "stable", 90 CharmModifiedVersion: 1, 91 Settings: map[string]interface{}{ 92 "key": "value", 93 }, 94 SettingsRefCount: 1, 95 Leader: "ubuntu/0", 96 LeadershipSettings: map[string]interface{}{ 97 "leader": true, 98 }, 99 MetricsCredentials: []byte("sekrit"), 100 } 101 } 102 103 func (s *ServiceSerializationSuite) TestNewService(c *gc.C) { 104 args := ServiceArgs{ 105 Tag: names.NewServiceTag("magic"), 106 Series: "zesty", 107 Subordinate: true, 108 CharmURL: "cs:zesty/magic", 109 Channel: "stable", 110 CharmModifiedVersion: 1, 111 ForceCharm: true, 112 Exposed: true, 113 MinUnits: 42, // no judgement is made by the migration code 114 Settings: map[string]interface{}{ 115 "key": "value", 116 }, 117 SettingsRefCount: 1, 118 Leader: "magic/1", 119 LeadershipSettings: map[string]interface{}{ 120 "leader": true, 121 }, 122 MetricsCredentials: []byte("sekrit"), 123 } 124 service := newService(args) 125 126 c.Assert(service.Name(), gc.Equals, "magic") 127 c.Assert(service.Tag(), gc.Equals, names.NewServiceTag("magic")) 128 c.Assert(service.Series(), gc.Equals, "zesty") 129 c.Assert(service.Subordinate(), jc.IsTrue) 130 c.Assert(service.CharmURL(), gc.Equals, "cs:zesty/magic") 131 c.Assert(service.Channel(), gc.Equals, "stable") 132 c.Assert(service.CharmModifiedVersion(), gc.Equals, 1) 133 c.Assert(service.ForceCharm(), jc.IsTrue) 134 c.Assert(service.Exposed(), jc.IsTrue) 135 c.Assert(service.MinUnits(), gc.Equals, 42) 136 c.Assert(service.Settings(), jc.DeepEquals, args.Settings) 137 c.Assert(service.SettingsRefCount(), gc.Equals, 1) 138 c.Assert(service.Leader(), gc.Equals, "magic/1") 139 c.Assert(service.LeadershipSettings(), jc.DeepEquals, args.LeadershipSettings) 140 c.Assert(service.MetricsCredentials(), jc.DeepEquals, []byte("sekrit")) 141 } 142 143 func (s *ServiceSerializationSuite) TestMinimalServiceValid(c *gc.C) { 144 service := minimalService() 145 c.Assert(service.Validate(), jc.ErrorIsNil) 146 } 147 148 func (s *ServiceSerializationSuite) TestMinimalMatches(c *gc.C) { 149 bytes, err := yaml.Marshal(minimalService()) 150 c.Assert(err, jc.ErrorIsNil) 151 152 var source map[interface{}]interface{} 153 err = yaml.Unmarshal(bytes, &source) 154 c.Assert(err, jc.ErrorIsNil) 155 c.Assert(source, jc.DeepEquals, minimalServiceMap()) 156 } 157 158 func (s *ServiceSerializationSuite) exportImport(c *gc.C, service_ *service) *service { 159 initial := services{ 160 Version: 1, 161 Services_: []*service{service_}, 162 } 163 164 bytes, err := yaml.Marshal(initial) 165 c.Assert(err, jc.ErrorIsNil) 166 167 var source map[string]interface{} 168 err = yaml.Unmarshal(bytes, &source) 169 c.Assert(err, jc.ErrorIsNil) 170 171 services, err := importServices(source) 172 c.Assert(err, jc.ErrorIsNil) 173 c.Assert(services, gc.HasLen, 1) 174 return services[0] 175 } 176 177 func (s *ServiceSerializationSuite) TestParsingSerializedData(c *gc.C) { 178 svc := minimalService() 179 service := s.exportImport(c, svc) 180 c.Assert(service, jc.DeepEquals, svc) 181 } 182 183 func (s *ServiceSerializationSuite) TestAnnotations(c *gc.C) { 184 initial := minimalService() 185 annotations := map[string]string{ 186 "string": "value", 187 "another": "one", 188 } 189 initial.SetAnnotations(annotations) 190 191 service := s.exportImport(c, initial) 192 c.Assert(service.Annotations(), jc.DeepEquals, annotations) 193 } 194 195 func (s *ServiceSerializationSuite) TestConstraints(c *gc.C) { 196 initial := minimalService() 197 args := ConstraintsArgs{ 198 Architecture: "amd64", 199 Memory: 8 * gig, 200 RootDisk: 40 * gig, 201 } 202 initial.SetConstraints(args) 203 204 service := s.exportImport(c, initial) 205 c.Assert(service.Constraints(), jc.DeepEquals, newConstraints(args)) 206 } 207 208 func (s *ServiceSerializationSuite) TestLeaderValid(c *gc.C) { 209 args := minimalServiceArgs() 210 args.Leader = "ubuntu/1" 211 service := newService(args) 212 service.SetStatus(minimalStatusArgs()) 213 214 err := service.Validate() 215 c.Assert(err, gc.ErrorMatches, `missing unit for leader "ubuntu/1" not valid`) 216 }