github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/dblogpruner/worker_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package dblogpruner_test
     5  
     6  import (
     7  	stdtesting "testing"
     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"
    15  	"gopkg.in/mgo.v2/bson"
    16  
    17  	"github.com/juju/juju/state"
    18  	statetesting "github.com/juju/juju/state/testing"
    19  	"github.com/juju/juju/testing"
    20  	"github.com/juju/juju/worker"
    21  	"github.com/juju/juju/worker/dblogpruner"
    22  )
    23  
    24  func TestPackage(t *stdtesting.T) {
    25  	testing.MgoTestPackage(t)
    26  }
    27  
    28  var _ = gc.Suite(&suite{})
    29  
    30  type suite struct {
    31  	statetesting.StateSuite
    32  	pruner   worker.Worker
    33  	logsColl *mgo.Collection
    34  }
    35  
    36  func (s *suite) SetUpTest(c *gc.C) {
    37  	s.StateSuite.SetUpTest(c)
    38  	s.logsColl = s.State.MongoSession().DB("logs").C("logs")
    39  }
    40  
    41  func (s *suite) StartWorker(c *gc.C, maxLogAge time.Duration, maxCollectionMB int) {
    42  	params := &dblogpruner.LogPruneParams{
    43  		MaxLogAge:       maxLogAge,
    44  		MaxCollectionMB: maxCollectionMB,
    45  		PruneInterval:   time.Millisecond, // Speed up pruning interval for testing
    46  	}
    47  	s.pruner = dblogpruner.New(s.State, params)
    48  	s.AddCleanup(func(*gc.C) {
    49  		s.pruner.Kill()
    50  		c.Assert(s.pruner.Wait(), jc.ErrorIsNil)
    51  	})
    52  }
    53  
    54  func (s *suite) TestPrunesOldLogs(c *gc.C) {
    55  	maxLogAge := 24 * time.Hour
    56  	noPruneMB := int(1e9)
    57  	s.StartWorker(c, maxLogAge, noPruneMB)
    58  
    59  	now := time.Now()
    60  	addLogsToPrune := func(count int) {
    61  		// Add messages beyond the prune threshold.
    62  		tPrune := now.Add(-maxLogAge - 1)
    63  		s.addLogs(c, tPrune, "prune", count)
    64  	}
    65  	addLogsToKeep := func(count int) {
    66  		// Add messages within the prune threshold.
    67  		s.addLogs(c, now, "keep", count)
    68  	}
    69  	for i := 0; i < 10; i++ {
    70  		addLogsToKeep(5)
    71  		addLogsToPrune(5)
    72  	}
    73  
    74  	// Wait for all logs with the message "prune" to be removed.
    75  	for attempt := testing.LongAttempt.Start(); attempt.Next(); {
    76  		pruneRemaining, err := s.logsColl.Find(bson.M{"x": "prune"}).Count()
    77  		c.Assert(err, jc.ErrorIsNil)
    78  		if pruneRemaining == 0 {
    79  			// All the "keep" messages should still be there.
    80  			keepCount, err := s.logsColl.Find(bson.M{"x": "keep"}).Count()
    81  			c.Assert(err, jc.ErrorIsNil)
    82  			c.Assert(keepCount, gc.Equals, 50)
    83  			return
    84  		}
    85  	}
    86  	c.Fatal("pruning didn't happen as expected")
    87  }
    88  
    89  func (s *suite) TestPrunesLogsBySize(c *gc.C) {
    90  	startingLogCount := 25000
    91  	s.addLogs(c, time.Now(), "stuff", startingLogCount)
    92  
    93  	noPruneAge := 999 * time.Hour
    94  	s.StartWorker(c, noPruneAge, 2)
    95  
    96  	for attempt := testing.LongAttempt.Start(); attempt.Next(); {
    97  		count, err := s.logsColl.Count()
    98  		c.Assert(err, jc.ErrorIsNil)
    99  		// The space used by MongoDB by the collection isn't that
   100  		// predictable, so just treat any pruning due to size as
   101  		// success.
   102  		if count < startingLogCount {
   103  			return
   104  		}
   105  	}
   106  	c.Fatal("pruning didn't happen as expected")
   107  }
   108  
   109  func (s *suite) addLogs(c *gc.C, t0 time.Time, text string, count int) {
   110  	dbLogger := state.NewDbLogger(s.State, names.NewMachineTag("0"))
   111  	defer dbLogger.Close()
   112  
   113  	for offset := 0; offset < count; offset++ {
   114  		t := t0.Add(-time.Duration(offset) * time.Second)
   115  		dbLogger.Log(t, "some.module", "foo.go:42", loggo.INFO, text)
   116  	}
   117  }