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  }