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