github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/charmrevisionupdater/testing/suite.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package testing
     5  
     6  import (
     7  	"fmt"
     8  	"net/http/httptest"
     9  	"net/url"
    10  
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/charm.v6-unstable"
    14  	"gopkg.in/juju/charmrepo.v2-unstable"
    15  	"gopkg.in/juju/charmrepo.v2-unstable/csclient"
    16  	"gopkg.in/juju/charmstore.v5-unstable"
    17  
    18  	"github.com/juju/juju/apiserver/charmrevisionupdater"
    19  	jujucharmstore "github.com/juju/juju/charmstore"
    20  	jujutesting "github.com/juju/juju/juju/testing"
    21  	"github.com/juju/juju/state"
    22  	"github.com/juju/juju/testcharms"
    23  )
    24  
    25  // CharmSuite provides infrastructure to set up and perform tests associated
    26  // with charm versioning. A testing charm store server is created and populated
    27  // with some known charms used for testing.
    28  type CharmSuite struct {
    29  	jcSuite *jujutesting.JujuConnSuite
    30  
    31  	Handler charmstore.HTTPCloseHandler
    32  	Server  *httptest.Server
    33  	Client  *csclient.Client
    34  	charms  map[string]*state.Charm
    35  }
    36  
    37  func (s *CharmSuite) SetUpSuite(c *gc.C, jcSuite *jujutesting.JujuConnSuite) {
    38  	s.jcSuite = jcSuite
    39  }
    40  
    41  func (s *CharmSuite) TearDownSuite(c *gc.C) {}
    42  
    43  func (s *CharmSuite) SetUpTest(c *gc.C) {
    44  	db := s.jcSuite.Session.DB("juju-testing")
    45  	params := charmstore.ServerParams{
    46  		AuthUsername: "test-user",
    47  		AuthPassword: "test-password",
    48  	}
    49  	handler, err := charmstore.NewServer(db, nil, "", params, charmstore.V5)
    50  	c.Assert(err, jc.ErrorIsNil)
    51  	s.Handler = handler
    52  	s.Server = httptest.NewServer(handler)
    53  	s.Client = csclient.New(csclient.Params{
    54  		URL:      s.Server.URL,
    55  		User:     params.AuthUsername,
    56  		Password: params.AuthPassword,
    57  	})
    58  	urls := map[string]string{
    59  		"mysql":     "quantal/mysql-23",
    60  		"dummy":     "quantal/dummy-24",
    61  		"riak":      "quantal/riak-25",
    62  		"wordpress": "quantal/wordpress-26",
    63  		"logging":   "quantal/logging-27",
    64  	}
    65  	for name, url := range urls {
    66  		testcharms.UploadCharm(c, s.Client, url, name)
    67  	}
    68  	s.jcSuite.PatchValue(&charmrepo.CacheDir, c.MkDir())
    69  	// Patch the charm repo initializer function: it is replaced with a charm
    70  	// store repo pointing to the testing server.
    71  	s.jcSuite.PatchValue(&charmrevisionupdater.NewCharmStoreClient, func(st *state.State) (jujucharmstore.Client, error) {
    72  		csURL, err := url.Parse(s.Server.URL)
    73  		c.Assert(err, jc.ErrorIsNil)
    74  		return jujucharmstore.NewCachingClient(state.MacaroonCache{st}, csURL)
    75  	})
    76  	s.charms = make(map[string]*state.Charm)
    77  }
    78  
    79  func (s *CharmSuite) TearDownTest(c *gc.C) {
    80  	s.Handler.Close()
    81  	s.Server.Close()
    82  }
    83  
    84  // AddMachine adds a new machine to state.
    85  func (s *CharmSuite) AddMachine(c *gc.C, machineId string, job state.MachineJob) {
    86  	m, err := s.jcSuite.State.AddOneMachine(state.MachineTemplate{
    87  		Series: "quantal",
    88  		Jobs:   []state.MachineJob{job},
    89  	})
    90  	c.Assert(err, jc.ErrorIsNil)
    91  	c.Assert(m.Id(), gc.Equals, machineId)
    92  	cons, err := m.Constraints()
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	inst, hc := jujutesting.AssertStartInstanceWithConstraints(c, s.jcSuite.Environ, m.Id(), cons)
    95  	err = m.SetProvisioned(inst.Id(), "fake_nonce", hc)
    96  	c.Assert(err, jc.ErrorIsNil)
    97  }
    98  
    99  // AddCharmWithRevision adds a charm with the specified revision to state.
   100  func (s *CharmSuite) AddCharmWithRevision(c *gc.C, charmName string, rev int) *state.Charm {
   101  	ch := testcharms.Repo.CharmDir(charmName)
   102  	name := ch.Meta().Name
   103  	curl := charm.MustParseURL(fmt.Sprintf("cs:quantal/%s-%d", name, rev))
   104  	info := state.CharmInfo{
   105  		Charm:       ch,
   106  		ID:          curl,
   107  		StoragePath: "dummy-path",
   108  		SHA256:      fmt.Sprintf("%s-%d-sha256", name, rev),
   109  	}
   110  	dummy, err := s.jcSuite.State.AddCharm(info)
   111  	c.Assert(err, jc.ErrorIsNil)
   112  	s.charms[name] = dummy
   113  	return dummy
   114  }
   115  
   116  // AddService adds a service for the specified charm to state.
   117  func (s *CharmSuite) AddService(c *gc.C, charmName, serviceName string) {
   118  	ch, ok := s.charms[charmName]
   119  	c.Assert(ok, jc.IsTrue)
   120  	owner := s.jcSuite.AdminUserTag(c)
   121  	_, err := s.jcSuite.State.AddService(state.AddServiceArgs{Name: serviceName, Owner: owner.String(), Charm: ch})
   122  	c.Assert(err, jc.ErrorIsNil)
   123  }
   124  
   125  // AddUnit adds a new unit for service to the specified machine.
   126  func (s *CharmSuite) AddUnit(c *gc.C, serviceName, machineId string) {
   127  	svc, err := s.jcSuite.State.Service(serviceName)
   128  	c.Assert(err, jc.ErrorIsNil)
   129  	u, err := svc.AddUnit()
   130  	c.Assert(err, jc.ErrorIsNil)
   131  	m, err := s.jcSuite.State.Machine(machineId)
   132  	c.Assert(err, jc.ErrorIsNil)
   133  	err = u.AssignToMachine(m)
   134  	c.Assert(err, jc.ErrorIsNil)
   135  }
   136  
   137  // SetUnitRevision sets the unit's charm to the specified revision.
   138  func (s *CharmSuite) SetUnitRevision(c *gc.C, unitName string, rev int) {
   139  	u, err := s.jcSuite.State.Unit(unitName)
   140  	c.Assert(err, jc.ErrorIsNil)
   141  	svc, err := u.Service()
   142  	c.Assert(err, jc.ErrorIsNil)
   143  	curl := charm.MustParseURL(fmt.Sprintf("cs:quantal/%s-%d", svc.Name(), rev))
   144  	err = u.SetCharmURL(curl)
   145  	c.Assert(err, jc.ErrorIsNil)
   146  }
   147  
   148  // SetupScenario adds some machines and services to state.
   149  // It assumes a controller machine has already been created.
   150  func (s *CharmSuite) SetupScenario(c *gc.C) {
   151  	s.AddMachine(c, "1", state.JobHostUnits)
   152  	s.AddMachine(c, "2", state.JobHostUnits)
   153  	s.AddMachine(c, "3", state.JobHostUnits)
   154  
   155  	// mysql is out of date
   156  	s.AddCharmWithRevision(c, "mysql", 22)
   157  	s.AddService(c, "mysql", "mysql")
   158  	s.AddUnit(c, "mysql", "1")
   159  
   160  	// wordpress is up to date
   161  	s.AddCharmWithRevision(c, "wordpress", 26)
   162  	s.AddService(c, "wordpress", "wordpress")
   163  	s.AddUnit(c, "wordpress", "2")
   164  	s.AddUnit(c, "wordpress", "2")
   165  	// wordpress/0 has a version, wordpress/1 is unknown
   166  	s.SetUnitRevision(c, "wordpress/0", 26)
   167  
   168  	// varnish is a charm that does not have a version in the mock store.
   169  	s.AddCharmWithRevision(c, "varnish", 5)
   170  	s.AddService(c, "varnish", "varnish")
   171  	s.AddUnit(c, "varnish", "3")
   172  }