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  }