github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/jujud/agent/caasoperator_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package agent 5 6 import ( 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "time" 11 12 "github.com/juju/cmd" 13 "github.com/juju/cmd/cmdtesting" 14 "github.com/juju/juju/agent" 15 jc "github.com/juju/testing/checkers" 16 "github.com/juju/utils/voyeur" 17 gc "gopkg.in/check.v1" 18 "gopkg.in/juju/names.v2" 19 "gopkg.in/juju/worker.v1" 20 "gopkg.in/juju/worker.v1/dependency" 21 "gopkg.in/natefinch/lumberjack.v2" 22 23 "github.com/juju/juju/cmd/jujud/agent/caasoperator" 24 coretesting "github.com/juju/juju/testing" 25 jujuworker "github.com/juju/juju/worker" 26 "github.com/juju/juju/worker/logsender" 27 ) 28 29 type CAASOperatorSuite struct { 30 coretesting.BaseSuite 31 32 rootDir string 33 } 34 35 var _ = gc.Suite(&CAASOperatorSuite{}) 36 37 func (s *CAASOperatorSuite) SetUpTest(c *gc.C) { 38 s.BaseSuite.SetUpTest(c) 39 s.rootDir = c.MkDir() 40 } 41 42 func (s *CAASOperatorSuite) dataDir() string { 43 return filepath.Join(s.rootDir, "/var/lib/juju") 44 } 45 46 func (s *CAASOperatorSuite) newBufferedLogWriter() *logsender.BufferedLogWriter { 47 logger := logsender.NewBufferedLogWriter(1024) 48 s.AddCleanup(func(*gc.C) { logger.Close() }) 49 return logger 50 } 51 52 func (s *CAASOperatorSuite) TestParseSuccess(c *gc.C) { 53 // Now init actually reads the agent configuration file. 54 a, err := NewCaasOperatorAgent(nil, s.newBufferedLogWriter()) 55 c.Assert(err, jc.ErrorIsNil) 56 err = cmdtesting.InitCommand(a, []string{ 57 "--data-dir", s.dataDir(), 58 "--application-name", "wordpress", 59 }) 60 c.Assert(err, jc.ErrorIsNil) 61 c.Check(a.AgentConf.DataDir(), gc.Equals, s.dataDir()) 62 c.Check(a.ApplicationName, gc.Equals, "wordpress") 63 } 64 65 func (s *CAASOperatorSuite) TestParseMissing(c *gc.C) { 66 uc, err := NewCaasOperatorAgent(nil, s.newBufferedLogWriter()) 67 c.Assert(err, jc.ErrorIsNil) 68 err = cmdtesting.InitCommand(uc, []string{ 69 "--data-dir", "jc", 70 }) 71 72 c.Assert(err, gc.ErrorMatches, "--application-name option must be set") 73 } 74 75 func (s *CAASOperatorSuite) TestParseNonsense(c *gc.C) { 76 for _, args := range [][]string{ 77 {"--application-name", "wordpress/0"}, 78 {"--application-name", "wordpress/seventeen"}, 79 {"--application-name", "wordpress/-32"}, 80 {"--application-name", "wordpress/wild/9"}, 81 {"--application-name", "20"}, 82 } { 83 a, err := NewCaasOperatorAgent(nil, s.newBufferedLogWriter()) 84 c.Assert(err, jc.ErrorIsNil) 85 86 err = cmdtesting.InitCommand(a, append(args, "--data-dir", "jc")) 87 c.Check(err, gc.ErrorMatches, `--application-name option expects "<application>" argument`) 88 } 89 } 90 91 func (s *CAASOperatorSuite) TestParseUnknown(c *gc.C) { 92 a, err := NewCaasOperatorAgent(nil, s.newBufferedLogWriter()) 93 c.Assert(err, jc.ErrorIsNil) 94 95 err = cmdtesting.InitCommand(a, []string{ 96 "--application-name", "wordpress", 97 "thundering typhoons", 98 }) 99 c.Check(err, gc.ErrorMatches, `unrecognized args: \["thundering typhoons"\]`) 100 } 101 102 func (s *CAASOperatorSuite) TestLogStderr(c *gc.C) { 103 ctx, err := cmd.DefaultContext() 104 c.Assert(err, gc.IsNil) 105 106 a := CaasOperatorAgent{ 107 AgentConf: FakeAgentConfig{}, 108 ctx: ctx, 109 ApplicationName: "mysql", 110 dead: make(chan struct{}), 111 } 112 113 err = a.Init(nil) 114 c.Assert(err, gc.IsNil) 115 116 _, ok := ctx.Stderr.(*lumberjack.Logger) 117 c.Assert(ok, jc.IsFalse) 118 } 119 120 var agentConfigContents = ` 121 # format 2.0 122 controller: controller-deadbeef-1bad-500d-9000-4b1d0d06f00d 123 model: model-deadbeef-0bad-400d-8000-4b1d0d06f00d 124 tag: machine-0 125 datadir: /home/user/.local/share/juju/local 126 logdir: /var/log/juju-user-local 127 upgradedToVersion: 1.2.3 128 apiaddresses: 129 - localhost:17070 130 apiport: 17070 131 `[1:] 132 133 func (s *CAASOperatorSuite) TestRunCopiesConfigTemplate(c *gc.C) { 134 ctx, err := cmd.DefaultContext() 135 c.Assert(err, gc.IsNil) 136 dataDir := c.MkDir() 137 agentDir := filepath.Join(dataDir, "agents", "application-mysql") 138 err = os.MkdirAll(agentDir, 0700) 139 c.Assert(err, gc.IsNil) 140 templateFile := filepath.Join(agentDir, "template-agent.conf") 141 142 err = ioutil.WriteFile(templateFile, []byte(agentConfigContents), 0600) 143 c.Assert(err, gc.IsNil) 144 145 a := &CaasOperatorAgent{ 146 AgentConf: NewAgentConf(dataDir), 147 ctx: ctx, 148 ApplicationName: "mysql", 149 bufferedLogger: s.newBufferedLogWriter(), 150 dead: make(chan struct{}), 151 } 152 153 dummy := jujuworker.NewSimpleWorker(func(stopCh <-chan struct{}) error { 154 return jujuworker.ErrTerminateAgent 155 }) 156 s.PatchValue(&CaasOperatorManifolds, func(config caasoperator.ManifoldsConfig) dependency.Manifolds { 157 return dependency.Manifolds{"test": dependency.Manifold{ 158 Start: func(context dependency.Context) (worker.Worker, error) { 159 return dummy, nil 160 }, 161 }} 162 }) 163 164 err = a.Init(nil) 165 c.Assert(err, jc.ErrorIsNil) 166 err = a.Run(ctx) 167 c.Assert(err, jc.ErrorIsNil) 168 defer func() { c.Check(a.Stop(), gc.IsNil) }() 169 170 agentConfig := a.CurrentConfig() 171 c.Assert(agentConfig.Controller(), gc.Equals, names.NewControllerTag("deadbeef-1bad-500d-9000-4b1d0d06f00d")) 172 addr, err := agentConfig.APIAddresses() 173 c.Assert(err, jc.ErrorIsNil) 174 c.Assert(addr, jc.SameContents, []string{"localhost:17070"}) 175 } 176 177 func (s *CAASOperatorSuite) TestChangeConfig(c *gc.C) { 178 config := FakeAgentConfig{} 179 configChanged := voyeur.NewValue(true) 180 a := UnitAgent{ 181 AgentConf: config, 182 configChangedVal: configChanged, 183 } 184 185 var mutateCalled bool 186 mutate := func(config agent.ConfigSetter) error { 187 mutateCalled = true 188 return nil 189 } 190 191 configChangedCh := make(chan bool) 192 watcher := configChanged.Watch() 193 watcher.Next() // consume initial event 194 go func() { 195 configChangedCh <- watcher.Next() 196 }() 197 198 err := a.ChangeConfig(mutate) 199 c.Assert(err, jc.ErrorIsNil) 200 201 c.Check(mutateCalled, jc.IsTrue) 202 select { 203 case result := <-configChangedCh: 204 c.Check(result, jc.IsTrue) 205 case <-time.After(coretesting.LongWait): 206 c.Fatal("timed out waiting for config changed signal") 207 } 208 }