github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/worker/certupdater/certupdater_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package certupdater_test
     5  
     6  import (
     7  	"crypto/x509"
     8  	stdtesting "testing"
     9  	"time"
    10  
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/apiserver/params"
    15  	"github.com/juju/juju/cert"
    16  	"github.com/juju/juju/environs/config"
    17  	"github.com/juju/juju/network"
    18  	"github.com/juju/juju/state"
    19  	coretesting "github.com/juju/juju/testing"
    20  	"github.com/juju/juju/worker/certupdater"
    21  )
    22  
    23  func TestPackage(t *stdtesting.T) {
    24  	gc.TestingT(t)
    25  }
    26  
    27  type CertUpdaterSuite struct {
    28  	coretesting.BaseSuite
    29  }
    30  
    31  var _ = gc.Suite(&CertUpdaterSuite{})
    32  
    33  type mockNotifyWatcher struct {
    34  	changes <-chan struct{}
    35  }
    36  
    37  func (w *mockNotifyWatcher) Changes() <-chan struct{} {
    38  	return w.changes
    39  }
    40  
    41  func (*mockNotifyWatcher) Stop() error {
    42  	return nil
    43  }
    44  
    45  func (*mockNotifyWatcher) Kill() {}
    46  
    47  func (*mockNotifyWatcher) Wait() error {
    48  	return nil
    49  }
    50  
    51  func (*mockNotifyWatcher) Err() error {
    52  	return nil
    53  }
    54  
    55  func newMockNotifyWatcher(changes <-chan struct{}) state.NotifyWatcher {
    56  	return &mockNotifyWatcher{changes}
    57  }
    58  
    59  type mockMachine struct {
    60  	changes chan struct{}
    61  }
    62  
    63  func (m *mockMachine) WatchAddresses() state.NotifyWatcher {
    64  	return newMockNotifyWatcher(m.changes)
    65  }
    66  
    67  func (m *mockMachine) Addresses() (addresses []network.Address) {
    68  	return []network.Address{{
    69  		Value: "0.1.2.3",
    70  	}}
    71  }
    72  
    73  type mockStateServingGetter struct{}
    74  
    75  func (g *mockStateServingGetter) StateServingInfo() (params.StateServingInfo, bool) {
    76  	return params.StateServingInfo{
    77  		Cert:         coretesting.ServerCert,
    78  		PrivateKey:   coretesting.ServerKey,
    79  		CAPrivateKey: coretesting.CAKey,
    80  		StatePort:    123,
    81  		APIPort:      456,
    82  	}, true
    83  }
    84  
    85  type mockConfigGetter struct{}
    86  
    87  func (g *mockConfigGetter) EnvironConfig() (*config.Config, error) {
    88  	return config.New(config.NoDefaults, coretesting.FakeConfig())
    89  
    90  }
    91  
    92  func (s *CertUpdaterSuite) TestStartStop(c *gc.C) {
    93  	setter := func(info params.StateServingInfo, dying <-chan struct{}) error {
    94  		return nil
    95  	}
    96  	changes := make(chan struct{})
    97  	certChangedChan := make(chan params.StateServingInfo)
    98  	worker := certupdater.NewCertificateUpdater(
    99  		&mockMachine{changes}, &mockStateServingGetter{}, &mockConfigGetter{}, setter, certChangedChan,
   100  	)
   101  	worker.Kill()
   102  	c.Assert(worker.Wait(), gc.IsNil)
   103  }
   104  
   105  func (s *CertUpdaterSuite) TestAddressChange(c *gc.C) {
   106  	var srvCert *x509.Certificate
   107  	updated := make(chan struct{})
   108  	setter := func(info params.StateServingInfo, dying <-chan struct{}) error {
   109  		var err error
   110  		srvCert, err = cert.ParseCert(info.Cert)
   111  		c.Assert(err, jc.ErrorIsNil)
   112  		sanIPs := make([]string, len(srvCert.IPAddresses))
   113  		for i, ip := range srvCert.IPAddresses {
   114  			sanIPs[i] = ip.String()
   115  		}
   116  		if len(sanIPs) == 1 && sanIPs[0] == "0.1.2.3" {
   117  			close(updated)
   118  		}
   119  		return nil
   120  	}
   121  	changes := make(chan struct{})
   122  	certChangedChan := make(chan params.StateServingInfo)
   123  	worker := certupdater.NewCertificateUpdater(
   124  		&mockMachine{changes}, &mockStateServingGetter{}, &mockConfigGetter{}, setter, certChangedChan,
   125  	)
   126  	defer func() { c.Assert(worker.Wait(), gc.IsNil) }()
   127  	defer worker.Kill()
   128  
   129  	changes <- struct{}{}
   130  	// Certificate should be updated with the address value.
   131  	select {
   132  	case <-updated:
   133  	case <-time.After(coretesting.LongWait):
   134  		c.Fatalf("timed out waiting for certificate to be updated")
   135  	}
   136  
   137  	// The server certificates must report "juju-apiserver" as a DNS
   138  	// name for backwards-compatibility with API clients. They must
   139  	// also report "juju-mongodb" because these certicates are also
   140  	// used for serving MongoDB connections.
   141  	c.Assert(srvCert.DNSNames, gc.DeepEquals,
   142  		[]string{"localhost", "juju-apiserver", "juju-mongodb", "anything"})
   143  }
   144  
   145  type mockStateServingGetterNoCAKey struct{}
   146  
   147  func (g *mockStateServingGetterNoCAKey) StateServingInfo() (params.StateServingInfo, bool) {
   148  	return params.StateServingInfo{
   149  		Cert:       coretesting.ServerCert,
   150  		PrivateKey: coretesting.ServerKey,
   151  		StatePort:  123,
   152  		APIPort:    456,
   153  	}, true
   154  
   155  }
   156  
   157  func (s *CertUpdaterSuite) TestAddressChangeNoCAKey(c *gc.C) {
   158  	updated := make(chan struct{})
   159  	setter := func(info params.StateServingInfo, dying <-chan struct{}) error {
   160  		close(updated)
   161  		return nil
   162  	}
   163  	changes := make(chan struct{})
   164  	certChangedChan := make(chan params.StateServingInfo)
   165  	worker := certupdater.NewCertificateUpdater(
   166  		&mockMachine{changes}, &mockStateServingGetterNoCAKey{}, &mockConfigGetter{}, setter, certChangedChan,
   167  	)
   168  	defer func() { c.Assert(worker.Wait(), gc.IsNil) }()
   169  	defer worker.Kill()
   170  
   171  	changes <- struct{}{}
   172  	// Certificate should not be updated with the address value.
   173  	select {
   174  	case <-time.After(coretesting.ShortWait):
   175  	case <-updated:
   176  		c.Fatalf("set state serving info unexpectedly called")
   177  	}
   178  }