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: &params.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: &params.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: &params.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: &params.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: &params.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: &params.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  }