github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/logsender/worker_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package logsender_test
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	"github.com/juju/loggo"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    14  	"gopkg.in/mgo.v2/bson"
    15  
    16  	"github.com/juju/juju/api"
    17  	apilogsender "github.com/juju/juju/api/logsender"
    18  	jujutesting "github.com/juju/juju/juju/testing"
    19  	"github.com/juju/juju/testing"
    20  	"github.com/juju/juju/testing/factory"
    21  	"github.com/juju/juju/version"
    22  	"github.com/juju/juju/worker/logsender"
    23  )
    24  
    25  type workerSuite struct {
    26  	jujutesting.JujuConnSuite
    27  
    28  	// machineTag holds the tag of a machine created
    29  	// for the test.
    30  	machineTag names.Tag
    31  
    32  	// APIState holds an API connection authenticated
    33  	// as the above machine.
    34  	APIState api.Connection
    35  }
    36  
    37  var _ = gc.Suite(&workerSuite{})
    38  
    39  func (s *workerSuite) SetUpTest(c *gc.C) {
    40  	s.JujuConnSuite.SetUpTest(c)
    41  
    42  	// Create a machine for the client to log in as.
    43  	nonce := "some-nonce"
    44  	machine, password := s.Factory.MakeMachineReturningPassword(c,
    45  		&factory.MachineParams{Nonce: nonce})
    46  	apiInfo := s.APIInfo(c)
    47  	apiInfo.Tag = machine.Tag()
    48  	apiInfo.Password = password
    49  	apiInfo.Nonce = nonce
    50  	st, err := api.Open(apiInfo, api.DefaultDialOpts())
    51  	c.Assert(err, gc.IsNil)
    52  	s.APIState = st
    53  	s.machineTag = machine.Tag()
    54  }
    55  
    56  func (s *workerSuite) TearDownTest(c *gc.C) {
    57  	s.APIState.Close()
    58  	s.JujuConnSuite.TearDownTest(c)
    59  }
    60  
    61  func (s *workerSuite) logSenderAPI() *apilogsender.API {
    62  	return apilogsender.NewAPI(s.APIState)
    63  }
    64  
    65  func (s *workerSuite) TestLogSending(c *gc.C) {
    66  	const logCount = 5
    67  	logsCh := make(chan *logsender.LogRecord, logCount)
    68  
    69  	// Start the logsender worker.
    70  	worker := logsender.New(logsCh, s.logSenderAPI())
    71  	defer func() {
    72  		worker.Kill()
    73  		c.Check(worker.Wait(), jc.ErrorIsNil)
    74  	}()
    75  
    76  	// Send some logs, also building up what should appear in the
    77  	// database.
    78  	var expectedDocs []bson.M
    79  	for i := 0; i < logCount; i++ {
    80  		ts := time.Now()
    81  		location := fmt.Sprintf("loc%d", i)
    82  		message := fmt.Sprintf("%d", i)
    83  
    84  		logsCh <- &logsender.LogRecord{
    85  			Time:     ts,
    86  			Module:   "logsender-test",
    87  			Location: location,
    88  			Level:    loggo.INFO,
    89  			Message:  message,
    90  		}
    91  
    92  		expectedDocs = append(expectedDocs, bson.M{
    93  			"t": ts.UnixNano(),
    94  			"e": s.State.ModelUUID(),
    95  			"r": version.Current.String(),
    96  			"n": s.machineTag.String(),
    97  			"m": "logsender-test",
    98  			"l": location,
    99  			"v": int(loggo.INFO),
   100  			"x": message,
   101  		})
   102  	}
   103  
   104  	// Wait for the logs to appear in the database.
   105  	var docs []bson.M
   106  	logsColl := s.State.MongoSession().DB("logs").C("logs")
   107  	for a := testing.LongAttempt.Start(); a.Next(); {
   108  		err := logsColl.Find(bson.M{"m": "logsender-test"}).All(&docs)
   109  		c.Assert(err, jc.ErrorIsNil)
   110  		if len(docs) == logCount {
   111  			break
   112  		}
   113  	}
   114  
   115  	// Check that the logs are correct.
   116  	c.Assert(docs, gc.HasLen, logCount)
   117  	for i := 0; i < logCount; i++ {
   118  		doc := docs[i]
   119  		delete(doc, "_id")
   120  		c.Assert(doc, gc.DeepEquals, expectedDocs[i])
   121  	}
   122  }
   123  
   124  func (s *workerSuite) TestDroppedLogs(c *gc.C) {
   125  	logsCh := make(logsender.LogRecordCh)
   126  
   127  	// Start the logsender worker.
   128  	worker := logsender.New(logsCh, s.logSenderAPI())
   129  	defer func() {
   130  		worker.Kill()
   131  		c.Check(worker.Wait(), jc.ErrorIsNil)
   132  	}()
   133  
   134  	// Send a log record which indicates some messages after it were
   135  	// dropped.
   136  	ts := time.Now()
   137  	logsCh <- &logsender.LogRecord{
   138  		Time:         ts,
   139  		Module:       "aaa",
   140  		Location:     "loc",
   141  		Level:        loggo.INFO,
   142  		Message:      "message0",
   143  		DroppedAfter: 42,
   144  	}
   145  
   146  	// Send another log record with no drops indicated.
   147  	logsCh <- &logsender.LogRecord{
   148  		Time:     time.Now(),
   149  		Module:   "zzz",
   150  		Location: "loc",
   151  		Level:    loggo.INFO,
   152  		Message:  "message1",
   153  	}
   154  
   155  	// Wait for the logs to appear in the database.
   156  	var docs []bson.M
   157  	logsColl := s.State.MongoSession().DB("logs").C("logs")
   158  	for a := testing.LongAttempt.Start(); a.Next(); {
   159  		if !a.HasNext() {
   160  			c.Fatal("timed out waiting for logs")
   161  		}
   162  		err := logsColl.Find(nil).Sort("m").All(&docs)
   163  		c.Assert(err, jc.ErrorIsNil)
   164  		// Expect the 2 messages sent along with a message about
   165  		// dropped messages.
   166  		if len(docs) == 3 {
   167  			break
   168  		}
   169  	}
   170  
   171  	// Check that the log records sent are present as well as an additional
   172  	// message in between indicating that some messages were dropped.
   173  	c.Assert(docs[0]["x"], gc.Equals, "message0")
   174  	delete(docs[1], "_id")
   175  	c.Assert(docs[1], gc.DeepEquals, bson.M{
   176  		"t": ts.UnixNano(), // Should share timestamp with previous message.
   177  		"e": s.State.ModelUUID(),
   178  		"r": version.Current.String(),
   179  		"n": s.machineTag.String(),
   180  		"m": "juju.worker.logsender",
   181  		"l": "",
   182  		"v": int(loggo.WARNING),
   183  		"x": "42 log messages dropped due to lack of API connectivity",
   184  	})
   185  	c.Assert(docs[2]["x"], gc.Equals, "message1")
   186  }