github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/logfwd/syslog/client_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package syslog_test
     5  
     6  import (
     7  	"crypto/tls"
     8  	"crypto/x509"
     9  	"time"
    10  
    11  	"github.com/juju/loggo"
    12  	"github.com/juju/rfc/rfc5424"
    13  	"github.com/juju/rfc/rfc5424/sdelements"
    14  	"github.com/juju/testing"
    15  	jc "github.com/juju/testing/checkers"
    16  	"github.com/juju/version"
    17  	gc "gopkg.in/check.v1"
    18  	"gopkg.in/juju/names.v2"
    19  
    20  	"github.com/juju/juju/logfwd"
    21  	"github.com/juju/juju/logfwd/syslog"
    22  	coretesting "github.com/juju/juju/testing"
    23  )
    24  
    25  type ClientSuite struct {
    26  	testing.IsolationSuite
    27  
    28  	stub   *testing.Stub
    29  	sender *stubSender
    30  }
    31  
    32  var _ = gc.Suite(&ClientSuite{})
    33  
    34  func (s *ClientSuite) SetUpTest(c *gc.C) {
    35  	s.IsolationSuite.SetUpTest(c)
    36  
    37  	s.stub = &testing.Stub{}
    38  	s.sender = &stubSender{stub: s.stub}
    39  }
    40  
    41  func (s *ClientSuite) TestOpen(c *gc.C) {
    42  	cfg := syslog.RawConfig{
    43  		Enabled:    true,
    44  		Host:       "a.b.c:9876",
    45  		CACert:     coretesting.CACert,
    46  		ClientCert: coretesting.ServerCert,
    47  		ClientKey:  coretesting.ServerKey,
    48  	}
    49  	senderOpener := &stubSenderOpener{
    50  		stub:       s.stub,
    51  		ReturnOpen: s.sender,
    52  	}
    53  
    54  	client, err := syslog.OpenForSender(cfg, senderOpener)
    55  	c.Assert(err, jc.ErrorIsNil)
    56  
    57  	s.stub.CheckCallNames(c, "DialFunc", "Open")
    58  
    59  	clientCert, err := tls.X509KeyPair([]byte(coretesting.ServerCert), []byte(coretesting.ServerKey))
    60  	c.Assert(err, jc.ErrorIsNil)
    61  	rootCAs := x509.NewCertPool()
    62  	rootCAs.AddCert(coretesting.CACertX509)
    63  	tlsConfig := &tls.Config{
    64  		Certificates: []tls.Certificate{clientCert},
    65  		RootCAs:      rootCAs,
    66  	}
    67  
    68  	s.stub.CheckCall(c, 0, "DialFunc", tlsConfig, time.Duration(0))
    69  	c.Check(client.Sender, gc.Equals, s.sender)
    70  }
    71  
    72  func (s *ClientSuite) TestClose(c *gc.C) {
    73  	client := syslog.Client{Sender: s.sender}
    74  
    75  	err := client.Close()
    76  	c.Assert(err, jc.ErrorIsNil)
    77  
    78  	s.stub.CheckCallNames(c, "Close")
    79  }
    80  
    81  func (s *ClientSuite) TestSendLogFull(c *gc.C) {
    82  	tag := names.NewMachineTag("99")
    83  	cID := "9f484882-2f18-4fd2-967d-db9663db7bea"
    84  	mID := "deadbeef-2f18-4fd2-967d-db9663db7bea"
    85  	ver := version.MustParse("1.2.3")
    86  	ts := time.Unix(12345, 0)
    87  	rec := logfwd.Record{
    88  		Origin:    logfwd.OriginForMachineAgent(tag, cID, mID, ver),
    89  		Timestamp: time.Unix(12345, 0),
    90  		Level:     loggo.ERROR,
    91  		Location: logfwd.SourceLocation{
    92  			Module:   "juju.x.y",
    93  			Filename: "x/y/spam.go",
    94  			Line:     42,
    95  		},
    96  		Message: "(╯°□°)╯︵ ┻━┻",
    97  	}
    98  	client := syslog.Client{Sender: s.sender}
    99  
   100  	err := client.Send([]logfwd.Record{rec})
   101  	c.Assert(err, jc.ErrorIsNil)
   102  
   103  	s.stub.CheckCallNames(c, "Send")
   104  	s.stub.CheckCall(c, 0, "Send", rfc5424.Message{
   105  		Header: rfc5424.Header{
   106  			Priority: rfc5424.Priority{
   107  				Severity: rfc5424.SeverityError,
   108  				Facility: rfc5424.FacilityUser,
   109  			},
   110  			Timestamp: rfc5424.Timestamp{ts},
   111  			Hostname: rfc5424.Hostname{
   112  				FQDN: "machine-99.deadbeef-2f18-4fd2-967d-db9663db7bea",
   113  			},
   114  			AppName: "jujud-machine-agent-deadbeef-2f18-4fd2-967d-db96",
   115  		},
   116  		StructuredData: rfc5424.StructuredData{
   117  			&sdelements.Origin{
   118  				EnterpriseID: sdelements.OriginEnterpriseID{
   119  					Number: 28978,
   120  				},
   121  				SoftwareName:    "jujud-machine-agent",
   122  				SoftwareVersion: ver,
   123  			},
   124  			&sdelements.Private{
   125  				Name: "model",
   126  				PEN:  28978,
   127  				Data: []rfc5424.StructuredDataParam{{
   128  					Name:  "controller-uuid",
   129  					Value: "9f484882-2f18-4fd2-967d-db9663db7bea",
   130  				}, {
   131  					Name:  "model-uuid",
   132  					Value: "deadbeef-2f18-4fd2-967d-db9663db7bea",
   133  				}},
   134  			},
   135  			&sdelements.Private{
   136  				Name: "log",
   137  				PEN:  28978,
   138  				Data: []rfc5424.StructuredDataParam{{
   139  					Name:  "module",
   140  					Value: "juju.x.y",
   141  				}, {
   142  					Name:  "source",
   143  					Value: "x/y/spam.go:42",
   144  				}},
   145  			},
   146  		},
   147  		Msg: "(╯°□°)╯︵ ┻━┻",
   148  	})
   149  }
   150  
   151  func (s *ClientSuite) TestSendLogLevels(c *gc.C) {
   152  	tag := names.NewMachineTag("99")
   153  	cID := "9f484882-2f18-4fd2-967d-db9663db7bea"
   154  	mID := "deadbeef-2f18-4fd2-967d-db9663db7bea"
   155  	ver := version.MustParse("1.2.3")
   156  	rec := logfwd.Record{
   157  		Origin:    logfwd.OriginForMachineAgent(tag, cID, mID, ver),
   158  		Timestamp: time.Unix(12345, 0),
   159  		Level:     loggo.ERROR,
   160  		Location: logfwd.SourceLocation{
   161  			Module:   "juju.x.y",
   162  			Filename: "x/y/spam.go",
   163  			Line:     42,
   164  		},
   165  		Message: "(╯°□°)╯︵ ┻━┻",
   166  	}
   167  	client := syslog.Client{Sender: s.sender}
   168  
   169  	levels := map[loggo.Level]rfc5424.Severity{
   170  		loggo.ERROR:   rfc5424.SeverityError,
   171  		loggo.WARNING: rfc5424.SeverityWarning,
   172  		loggo.INFO:    rfc5424.SeverityInformational,
   173  		loggo.DEBUG:   rfc5424.SeverityDebug,
   174  		loggo.TRACE:   rfc5424.SeverityDebug,
   175  	}
   176  	for level, expected := range levels {
   177  		c.Logf("trying %s -> %s", level, expected)
   178  		s.stub.ResetCalls()
   179  		rec.Level = level
   180  
   181  		err := client.Send([]logfwd.Record{rec})
   182  		c.Assert(err, jc.ErrorIsNil)
   183  
   184  		msg := s.stub.Calls()[0].Args[0].(rfc5424.Message)
   185  		c.Check(msg.Severity, gc.Equals, expected)
   186  	}
   187  }
   188  
   189  type stubSenderOpener struct {
   190  	stub *testing.Stub
   191  
   192  	ReturnDialFunc rfc5424.DialFunc
   193  	ReturnOpen     syslog.Sender
   194  }
   195  
   196  func (s *stubSenderOpener) DialFunc(cfg *tls.Config, timeout time.Duration) (rfc5424.DialFunc, error) {
   197  	s.stub.AddCall("DialFunc", cfg, timeout)
   198  	if err := s.stub.NextErr(); err != nil {
   199  		return nil, err
   200  	}
   201  
   202  	dial := s.ReturnDialFunc
   203  	if dial == nil {
   204  		dial = func(network, address string) (rfc5424.Conn, error) {
   205  			s.stub.AddCall("dial", network, address)
   206  			if err := s.stub.NextErr(); err != nil {
   207  				return nil, err
   208  			}
   209  
   210  			return nil, nil
   211  		}
   212  	}
   213  	return dial, nil
   214  }
   215  
   216  func (s *stubSenderOpener) Open(host string, cfg rfc5424.ClientConfig, dial rfc5424.DialFunc) (syslog.Sender, error) {
   217  	s.stub.AddCall("Open", host, cfg, dial)
   218  	if err := s.stub.NextErr(); err != nil {
   219  		return nil, err
   220  	}
   221  
   222  	return s.ReturnOpen, nil
   223  }
   224  
   225  type stubSender struct {
   226  	stub *testing.Stub
   227  }
   228  
   229  func (s *stubSender) Send(msg rfc5424.Message) error {
   230  	s.stub.AddCall("Send", msg)
   231  	if err := s.stub.NextErr(); err != nil {
   232  		return err
   233  	}
   234  
   235  	return nil
   236  }
   237  
   238  func (s *stubSender) Close() error {
   239  	s.stub.AddCall("Close")
   240  	if err := s.stub.NextErr(); err != nil {
   241  		return err
   242  	}
   243  
   244  	return nil
   245  }