github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/certpool_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package api_test
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"path/filepath"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/juju/loggo"
    14  	jc "github.com/juju/testing/checkers"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/api"
    18  	"github.com/juju/juju/cert"
    19  	"github.com/juju/juju/testing"
    20  )
    21  
    22  type certPoolSuite struct {
    23  	testing.BaseSuite
    24  	logs *certLogs
    25  }
    26  
    27  var _ = gc.Suite(&certPoolSuite{})
    28  
    29  func (s *certPoolSuite) SetUpTest(c *gc.C) {
    30  	s.BaseSuite.SetUpTest(c)
    31  	s.logs = &certLogs{}
    32  	loggo.GetLogger("juju.api").SetLogLevel(loggo.TRACE)
    33  	loggo.RegisterWriter("api-certs", s.logs)
    34  }
    35  
    36  func (*certPoolSuite) TestCreateCertPoolNoCert(c *gc.C) {
    37  	pool, err := api.CreateCertPool("")
    38  	c.Assert(err, jc.ErrorIsNil)
    39  	c.Assert(pool.Subjects(), gc.HasLen, 0)
    40  }
    41  
    42  func (*certPoolSuite) TestCreateCertPoolTestCert(c *gc.C) {
    43  	pool, err := api.CreateCertPool(testing.CACert)
    44  	c.Assert(err, jc.ErrorIsNil)
    45  	c.Assert(pool.Subjects(), gc.HasLen, 1)
    46  }
    47  
    48  func (s *certPoolSuite) TestCreateCertPoolNoDir(c *gc.C) {
    49  	certDir := filepath.Join(c.MkDir(), "missing")
    50  	s.PatchValue(api.CertDir, certDir)
    51  
    52  	pool, err := api.CreateCertPool("")
    53  	c.Assert(err, jc.ErrorIsNil)
    54  	c.Assert(pool.Subjects(), gc.HasLen, 0)
    55  
    56  	c.Assert(s.logs.messages, gc.HasLen, 1)
    57  	// The directory not existing is likely to happen a lot, so it is only
    58  	// logged out at trace to help be explicit in the case where detailed
    59  	// debugging is needed.
    60  	c.Assert(s.logs.messages[0], gc.Matches, `TRACE cert dir ".*" does not exist`)
    61  }
    62  
    63  func (s *certPoolSuite) TestCreateCertPoolNotADir(c *gc.C) {
    64  	certDir := filepath.Join(c.MkDir(), "missing")
    65  	s.PatchValue(api.CertDir, certDir)
    66  	// Make the certDir a file instead...
    67  	c.Assert(ioutil.WriteFile(certDir, []byte("blah"), 0644), jc.ErrorIsNil)
    68  
    69  	pool, err := api.CreateCertPool("")
    70  	c.Assert(err, jc.ErrorIsNil)
    71  	c.Assert(pool.Subjects(), gc.HasLen, 0)
    72  
    73  	c.Assert(s.logs.messages, gc.HasLen, 1)
    74  	c.Assert(s.logs.messages[0], gc.Matches, `INFO cert dir ".*" is not a directory`)
    75  }
    76  
    77  func (s *certPoolSuite) TestCreateCertPoolEmptyDir(c *gc.C) {
    78  	certDir := c.MkDir()
    79  	s.PatchValue(api.CertDir, certDir)
    80  
    81  	pool, err := api.CreateCertPool("")
    82  	c.Assert(err, jc.ErrorIsNil)
    83  	c.Assert(pool.Subjects(), gc.HasLen, 0)
    84  	c.Assert(s.logs.messages, gc.HasLen, 1)
    85  	c.Assert(s.logs.messages[0], gc.Matches, `DEBUG added 0 certs to the pool from .*`)
    86  }
    87  
    88  func (s *certPoolSuite) TestCreateCertPoolLoadsPEMFiles(c *gc.C) {
    89  	certDir := c.MkDir()
    90  	s.PatchValue(api.CertDir, certDir)
    91  	s.addCert(c, filepath.Join(certDir, "first.pem"))
    92  	s.addCert(c, filepath.Join(certDir, "second.pem"))
    93  	s.addCert(c, filepath.Join(certDir, "third.pem"))
    94  
    95  	pool, err := api.CreateCertPool("")
    96  	c.Assert(err, jc.ErrorIsNil)
    97  	c.Assert(pool.Subjects(), gc.HasLen, 3)
    98  	c.Assert(s.logs.messages, gc.HasLen, 1)
    99  	c.Assert(s.logs.messages[0], gc.Matches, `DEBUG added 3 certs to the pool from .*`)
   100  }
   101  
   102  func (s *certPoolSuite) TestCreateCertPoolLoadsOnlyPEMFiles(c *gc.C) {
   103  	certDir := c.MkDir()
   104  	s.PatchValue(api.CertDir, certDir)
   105  	s.addCert(c, filepath.Join(certDir, "first.pem"))
   106  	c.Assert(ioutil.WriteFile(filepath.Join(certDir, "second.cert"), []byte("blah"), 0644), jc.ErrorIsNil)
   107  
   108  	pool, err := api.CreateCertPool("")
   109  	c.Assert(err, jc.ErrorIsNil)
   110  	c.Assert(pool.Subjects(), gc.HasLen, 1)
   111  	c.Assert(s.logs.messages, gc.HasLen, 1)
   112  	c.Assert(s.logs.messages[0], gc.Matches, `DEBUG added 1 certs to the pool from .*`)
   113  }
   114  
   115  func (s *certPoolSuite) TestCreateCertPoolLogsBadCerts(c *gc.C) {
   116  	certDir := c.MkDir()
   117  	s.PatchValue(api.CertDir, certDir)
   118  	c.Assert(ioutil.WriteFile(filepath.Join(certDir, "broken.pem"), []byte("blah"), 0644), jc.ErrorIsNil)
   119  
   120  	pool, err := api.CreateCertPool("")
   121  	c.Assert(err, jc.ErrorIsNil)
   122  	c.Assert(pool.Subjects(), gc.HasLen, 0)
   123  	c.Assert(s.logs.messages, gc.HasLen, 2)
   124  	c.Assert(s.logs.messages[0], gc.Matches, `INFO error parsing cert ".*broken.pem": .*`)
   125  	c.Assert(s.logs.messages[1], gc.Matches, `DEBUG added 0 certs to the pool from .*`)
   126  }
   127  
   128  func (s *certPoolSuite) addCert(c *gc.C, filename string) {
   129  	expiry := time.Now().UTC().AddDate(10, 0, 0)
   130  	pem, _, err := cert.NewCA("random env name", "1", expiry)
   131  	c.Assert(err, jc.ErrorIsNil)
   132  	err = ioutil.WriteFile(filename, []byte(pem), 0644)
   133  	c.Assert(err, jc.ErrorIsNil)
   134  }
   135  
   136  type certLogs struct {
   137  	messages []string
   138  }
   139  
   140  func (c *certLogs) Write(entry loggo.Entry) {
   141  	if strings.HasSuffix(entry.Filename, "certpool.go") {
   142  		c.messages = append(c.messages, fmt.Sprintf("%s %s", entry.Level, entry.Message))
   143  	}
   144  }