github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/metrics/sender/manifold_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package sender_test 5 6 import ( 7 "net/http" 8 "net/url" 9 "os" 10 "path/filepath" 11 12 "github.com/juju/errors" 13 "github.com/juju/httprequest" 14 "github.com/juju/testing" 15 jc "github.com/juju/testing/checkers" 16 gc "gopkg.in/check.v1" 17 "gopkg.in/juju/names.v2" 18 "gopkg.in/juju/worker.v1" 19 "gopkg.in/juju/worker.v1/dependency" 20 dt "gopkg.in/juju/worker.v1/dependency/testing" 21 "gopkg.in/macaroon-bakery.v2-unstable/httpbakery" 22 23 "github.com/juju/juju/agent" 24 "github.com/juju/juju/api/base" 25 "github.com/juju/juju/api/metricsadder" 26 "github.com/juju/juju/worker/metrics/sender" 27 "github.com/juju/juju/worker/metrics/spool" 28 ) 29 30 type ManifoldSuite struct { 31 testing.IsolationSuite 32 factory spool.MetricFactory 33 client metricsadder.MetricsAdderClient 34 apiCaller *stubAPICaller 35 manifold dependency.Manifold 36 resources dt.StubResources 37 } 38 39 var _ = gc.Suite(&ManifoldSuite{}) 40 41 func (s *ManifoldSuite) SetUpTest(c *gc.C) { 42 spoolDir := c.MkDir() 43 s.IsolationSuite.SetUpTest(c) 44 s.factory = &stubMetricFactory{ 45 &testing.Stub{}, 46 spoolDir, 47 } 48 49 testAPIClient := func(apiCaller base.APICaller) metricsadder.MetricsAdderClient { 50 return newTestAPIMetricSender() 51 } 52 s.PatchValue(&sender.NewMetricAdderClient, testAPIClient) 53 54 s.manifold = sender.Manifold(sender.ManifoldConfig{ 55 AgentName: "agent", 56 APICallerName: "api-caller", 57 MetricSpoolName: "metric-spool", 58 }) 59 60 dataDir := c.MkDir() 61 // create unit agent base dir so that hooks can run. 62 err := os.MkdirAll(filepath.Join(dataDir, "agents", "unit-u-0"), 0777) 63 c.Assert(err, jc.ErrorIsNil) 64 65 s.apiCaller = &stubAPICaller{&testing.Stub{}} 66 s.resources = dt.StubResources{ 67 "agent": dt.NewStubResource(&dummyAgent{dataDir: dataDir}), 68 "api-caller": dt.NewStubResource(s.apiCaller), 69 "metric-spool": dt.NewStubResource(s.factory), 70 } 71 } 72 73 func (s *ManifoldSuite) TestInputs(c *gc.C) { 74 c.Check(s.manifold.Inputs, jc.DeepEquals, []string{"agent", "api-caller", "metric-spool"}) 75 } 76 77 func (s *ManifoldSuite) TestStartMissingAPICaller(c *gc.C) { 78 context := dt.StubContext(nil, map[string]interface{}{ 79 "api-caller": dependency.ErrMissing, 80 "metric-spool": s.factory, 81 }) 82 worker, err := s.manifold.Start(context) 83 c.Check(worker, gc.IsNil) 84 c.Check(err, gc.ErrorMatches, dependency.ErrMissing.Error()) 85 } 86 87 func (s *ManifoldSuite) TestStartMissingAgent(c *gc.C) { 88 context := dt.StubContext(nil, map[string]interface{}{ 89 "agent": dependency.ErrMissing, 90 "api-caller": &stubAPICaller{&testing.Stub{}}, 91 "metric-spool": s.factory, 92 }) 93 worker, err := s.manifold.Start(context) 94 c.Check(worker, gc.IsNil) 95 c.Check(err, gc.ErrorMatches, dependency.ErrMissing.Error()) 96 } 97 98 func (s *ManifoldSuite) TestStartSuccess(c *gc.C) { 99 s.setupWorkerTest(c) 100 } 101 102 func (s *ManifoldSuite) setupWorkerTest(c *gc.C) worker.Worker { 103 worker, err := s.manifold.Start(s.resources.Context()) 104 c.Check(err, jc.ErrorIsNil) 105 s.AddCleanup(func(c *gc.C) { 106 worker.Kill() 107 err := worker.Wait() 108 c.Check(err, jc.ErrorIsNil) 109 }) 110 return worker 111 } 112 113 type mockListener struct { 114 testing.Stub 115 spool.ConnectionHandler 116 } 117 118 // Stop implements the stopper interface. 119 func (l *mockListener) Stop() error { 120 l.AddCall("Stop") 121 return nil 122 } 123 124 func (s *ManifoldSuite) TestWorkerErrorStopsSender(c *gc.C) { 125 listener := &mockListener{} 126 s.PatchValue(sender.NewListener, sender.NewListenerFunc(listener)) 127 128 s.apiCaller.SetErrors(errors.New("blah")) 129 130 worker, err := s.manifold.Start(s.resources.Context()) 131 c.Assert(err, jc.ErrorIsNil) 132 c.Assert(worker, gc.NotNil) 133 err = worker.Wait() 134 c.Assert(err, gc.ErrorMatches, ".*blah") 135 listener.CheckCallNames(c, "Stop") 136 } 137 138 var _ base.APICaller = (*stubAPICaller)(nil) 139 140 type stubAPICaller struct { 141 *testing.Stub 142 } 143 144 func (s *stubAPICaller) APICall(objType string, version int, id, request string, params, response interface{}) error { 145 s.MethodCall(s, "APICall", objType, version, id, request, params, response) 146 return s.NextErr() 147 } 148 149 func (s *stubAPICaller) BestFacadeVersion(facade string) int { 150 s.MethodCall(s, "BestFacadeVersion", facade) 151 return 42 152 } 153 154 func (s *stubAPICaller) ModelTag() (names.ModelTag, bool) { 155 s.MethodCall(s, "ModelTag") 156 return names.NewModelTag("foobar"), true 157 } 158 159 func (s *stubAPICaller) ConnectStream(string, url.Values) (base.Stream, error) { 160 panic("should not be called") 161 } 162 163 func (s *stubAPICaller) ConnectControllerStream(string, url.Values, http.Header) (base.Stream, error) { 164 panic("should not be called") 165 } 166 167 func (s *stubAPICaller) HTTPClient() (*httprequest.Client, error) { 168 panic("should not be called") 169 } 170 171 func (s *stubAPICaller) BakeryClient() *httpbakery.Client { 172 panic("should not be called") 173 } 174 175 type dummyAgent struct { 176 agent.Agent 177 dataDir string 178 } 179 180 func (a dummyAgent) CurrentConfig() agent.Config { 181 return &dummyAgentConfig{dataDir: a.dataDir} 182 } 183 184 type dummyAgentConfig struct { 185 agent.Config 186 dataDir string 187 } 188 189 // Tag implements agent.AgentConfig. 190 func (ac dummyAgentConfig) Tag() names.Tag { 191 return names.NewUnitTag("u/0") 192 } 193 194 // DataDir implements agent.AgentConfig. 195 func (ac dummyAgentConfig) DataDir() string { 196 return ac.dataDir 197 }