github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/observer/recorder_test.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package observer_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/clock/testclock"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/apiserver/observer"
    15  	"github.com/juju/juju/apiserver/observer/fakeobserver"
    16  	"github.com/juju/juju/apiserver/params"
    17  	apitesting "github.com/juju/juju/apiserver/testing"
    18  	"github.com/juju/juju/core/auditlog"
    19  	"github.com/juju/juju/rpc"
    20  )
    21  
    22  type recorderSuite struct {
    23  	testing.IsolationSuite
    24  }
    25  
    26  var _ = gc.Suite(&recorderSuite{})
    27  
    28  func (s *recorderSuite) TestServerRequest(c *gc.C) {
    29  	fake := &fakeobserver.Instance{}
    30  	log := &apitesting.FakeAuditLog{}
    31  	clock := testclock.NewClock(time.Now())
    32  	auditRecorder, err := auditlog.NewRecorder(log, clock, auditlog.ConversationArgs{
    33  		ConnectionID: 4567,
    34  	})
    35  	c.Assert(err, jc.ErrorIsNil)
    36  	factory := observer.NewRecorderFactory(fake, auditRecorder, observer.CaptureArgs)
    37  	recorder := factory()
    38  	hdr := &rpc.Header{
    39  		RequestId: 123,
    40  		Request:   rpc.Request{"Type", 5, "", "Action"},
    41  	}
    42  	err = recorder.HandleRequest(hdr, "the args")
    43  	c.Assert(err, jc.ErrorIsNil)
    44  
    45  	fake.CheckCallNames(c, "RPCObserver")
    46  	fakeOb := fake.Calls()[0].Args[0].(*fakeobserver.RPCInstance)
    47  	fakeOb.CheckCallNames(c, "ServerRequest")
    48  	fakeOb.CheckCall(c, 0, "ServerRequest", hdr, "the args")
    49  
    50  	log.CheckCallNames(c, "AddConversation", "AddRequest")
    51  
    52  	request := log.Calls()[1].Args[0].(auditlog.Request)
    53  	c.Assert(request.ConversationID, gc.HasLen, 16)
    54  	request.ConversationID = "abcdef0123456789"
    55  	c.Assert(request, gc.Equals, auditlog.Request{
    56  		ConversationID: "abcdef0123456789",
    57  		ConnectionID:   "11D7",
    58  		RequestID:      123,
    59  		When:           clock.Now().Format(time.RFC3339),
    60  		Facade:         "Type",
    61  		Method:         "Action",
    62  		Version:        5,
    63  		Args:           `"the args"`,
    64  	})
    65  }
    66  
    67  func (s *recorderSuite) TestServerRequestNoArgs(c *gc.C) {
    68  	fake := &fakeobserver.Instance{}
    69  	log := &apitesting.FakeAuditLog{}
    70  	clock := testclock.NewClock(time.Now())
    71  	auditRecorder, err := auditlog.NewRecorder(log, clock, auditlog.ConversationArgs{
    72  		ConnectionID: 4567,
    73  	})
    74  	c.Assert(err, jc.ErrorIsNil)
    75  	factory := observer.NewRecorderFactory(fake, auditRecorder, observer.NoCaptureArgs)
    76  	recorder := factory()
    77  	hdr := &rpc.Header{
    78  		RequestId: 123,
    79  		Request:   rpc.Request{"Type", 5, "", "Action"},
    80  	}
    81  	err = recorder.HandleRequest(hdr, "the args")
    82  	c.Assert(err, jc.ErrorIsNil)
    83  
    84  	log.CheckCallNames(c, "AddConversation", "AddRequest")
    85  
    86  	request := log.Calls()[1].Args[0].(auditlog.Request)
    87  	c.Assert(request.ConversationID, gc.HasLen, 16)
    88  	request.ConversationID = "abcdef0123456789"
    89  	c.Assert(request, gc.Equals, auditlog.Request{
    90  		ConversationID: "abcdef0123456789",
    91  		ConnectionID:   "11D7",
    92  		RequestID:      123,
    93  		When:           clock.Now().Format(time.RFC3339),
    94  		Facade:         "Type",
    95  		Method:         "Action",
    96  		Version:        5,
    97  	})
    98  }
    99  
   100  func (s *recorderSuite) TestServerReply(c *gc.C) {
   101  	fake := &fakeobserver.Instance{}
   102  	log := &apitesting.FakeAuditLog{}
   103  	clock := testclock.NewClock(time.Now())
   104  	auditRecorder, err := auditlog.NewRecorder(log, clock, auditlog.ConversationArgs{
   105  		ConnectionID: 4567,
   106  	})
   107  	c.Assert(err, jc.ErrorIsNil)
   108  	factory := observer.NewRecorderFactory(fake, auditRecorder, observer.CaptureArgs)
   109  	recorder := factory()
   110  
   111  	req := rpc.Request{"Type", 5, "", "Action"}
   112  	hdr := &rpc.Header{RequestId: 123}
   113  	err = recorder.HandleReply(req, hdr, "the response")
   114  	c.Assert(err, jc.ErrorIsNil)
   115  
   116  	fake.CheckCallNames(c, "RPCObserver")
   117  	fakeOb := fake.Calls()[0].Args[0].(*fakeobserver.RPCInstance)
   118  	fakeOb.CheckCallNames(c, "ServerReply")
   119  	fakeOb.CheckCall(c, 0, "ServerReply", req, hdr, "the response")
   120  
   121  	log.CheckCallNames(c, "AddConversation", "AddResponse")
   122  
   123  	respErrors := log.Calls()[1].Args[0].(auditlog.ResponseErrors)
   124  	c.Assert(respErrors.ConversationID, gc.HasLen, 16)
   125  	respErrors.ConversationID = "abcdef0123456789"
   126  	c.Assert(respErrors, gc.DeepEquals, auditlog.ResponseErrors{
   127  		ConversationID: "abcdef0123456789",
   128  		ConnectionID:   "11D7",
   129  		RequestID:      123,
   130  		When:           clock.Now().Format(time.RFC3339),
   131  		Errors:         nil,
   132  	})
   133  }
   134  
   135  func (s *recorderSuite) TestReplyResultNotAStruct(c *gc.C) {
   136  	s.checkServerReplyErrors(c, 12345, nil)
   137  }
   138  
   139  func (s *recorderSuite) TestReplyResultNoErrorAttrs(c *gc.C) {
   140  	s.checkServerReplyErrors(c,
   141  		params.ApplicationCharmRelationsResults{
   142  			CharmRelations: []string{"abc", "123"},
   143  		},
   144  		nil,
   145  	)
   146  }
   147  
   148  func (s *recorderSuite) TestReplyResultErrorSlice(c *gc.C) {
   149  	s.checkServerReplyErrors(c,
   150  		params.ErrorResults{
   151  			Results: []params.ErrorResult{{
   152  				Error: &params.Error{
   153  					Message: "antiphon",
   154  					Code:    "midlake",
   155  				},
   156  			}, {
   157  				Error: nil,
   158  			}},
   159  		},
   160  		[]*auditlog.Error{{
   161  			Message: "antiphon",
   162  			Code:    "midlake",
   163  		}, nil},
   164  	)
   165  }
   166  
   167  func (s *recorderSuite) TestReplyResultError(c *gc.C) {
   168  	s.checkServerReplyErrors(c,
   169  		params.ErrorResult{
   170  			Error: &params.Error{
   171  				Message: "antiphon",
   172  				Code:    "midlake",
   173  			},
   174  		},
   175  		[]*auditlog.Error{{
   176  			Message: "antiphon",
   177  			Code:    "midlake",
   178  		}},
   179  	)
   180  }
   181  
   182  func (s *recorderSuite) TestReplyResultSlice(c *gc.C) {
   183  	s.checkServerReplyErrors(c,
   184  		params.AddMachinesResults{
   185  			Machines: []params.AddMachinesResult{{
   186  				Machine: "some-machine",
   187  			}, {
   188  				Error: &params.Error{
   189  					Message: "something bad",
   190  					Code:    "fall-down-go-boom",
   191  					Info:    &params.ErrorInfo{MacaroonPath: "somewhere"},
   192  				},
   193  			}},
   194  		},
   195  		[]*auditlog.Error{nil, {
   196  			Message: "something bad",
   197  			Code:    "fall-down-go-boom",
   198  		}},
   199  	)
   200  }
   201  
   202  func (s *recorderSuite) checkServerReplyErrors(c *gc.C, result interface{}, expected []*auditlog.Error) {
   203  	fake := &fakeobserver.Instance{}
   204  	log := &apitesting.FakeAuditLog{}
   205  	clock := testclock.NewClock(time.Now())
   206  	auditRecorder, err := auditlog.NewRecorder(log, clock, auditlog.ConversationArgs{
   207  		ConnectionID: 4567,
   208  	})
   209  	c.Assert(err, jc.ErrorIsNil)
   210  	factory := observer.NewRecorderFactory(fake, auditRecorder, observer.CaptureArgs)
   211  	recorder := factory()
   212  
   213  	req := rpc.Request{"Type", 5, "", "Action"}
   214  	hdr := &rpc.Header{RequestId: 123}
   215  	err = recorder.HandleReply(req, hdr, result)
   216  	c.Assert(err, jc.ErrorIsNil)
   217  
   218  	log.CheckCallNames(c, "AddConversation", "AddResponse")
   219  
   220  	respErrors := log.Calls()[1].Args[0].(auditlog.ResponseErrors)
   221  	c.Assert(respErrors.ConversationID, gc.HasLen, 16)
   222  	respErrors.ConversationID = ""
   223  	c.Assert(respErrors, gc.DeepEquals, auditlog.ResponseErrors{
   224  		ConnectionID: "11D7",
   225  		RequestID:    123,
   226  		When:         clock.Now().Format(time.RFC3339),
   227  		Errors:       expected,
   228  	})
   229  }
   230  
   231  func (s *recorderSuite) TestNoAuditRequest(c *gc.C) {
   232  	fake := &fakeobserver.Instance{}
   233  	factory := observer.NewRecorderFactory(fake, nil, observer.NoCaptureArgs)
   234  	recorder := factory()
   235  	hdr := &rpc.Header{
   236  		RequestId: 123,
   237  		Request:   rpc.Request{"Type", 0, "", "Action"},
   238  	}
   239  	err := recorder.HandleRequest(hdr, "the body")
   240  	c.Assert(err, jc.ErrorIsNil)
   241  }
   242  
   243  func (s *recorderSuite) TestNoAuditReply(c *gc.C) {
   244  	fake := &fakeobserver.Instance{}
   245  	factory := observer.NewRecorderFactory(fake, nil, observer.NoCaptureArgs)
   246  	recorder := factory()
   247  	req := rpc.Request{"Type", 0, "", "Action"}
   248  	hdr := &rpc.Header{RequestId: 123}
   249  	err := recorder.HandleReply(req, hdr, "the body")
   250  	c.Assert(err, jc.ErrorIsNil)
   251  }