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