github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/featuretests/dblog_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package featuretests 5 6 import ( 7 "bufio" 8 "time" 9 10 "github.com/juju/loggo" 11 "github.com/juju/names" 12 jujutesting "github.com/juju/testing" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 "gopkg.in/mgo.v2/bson" 16 17 "github.com/juju/juju/agent" 18 "github.com/juju/juju/api" 19 agentcmd "github.com/juju/juju/cmd/jujud/agent" 20 agenttesting "github.com/juju/juju/cmd/jujud/agent/testing" 21 "github.com/juju/juju/state" 22 coretesting "github.com/juju/juju/testing" 23 "github.com/juju/juju/testing/factory" 24 "github.com/juju/juju/worker/logsender" 25 "github.com/juju/juju/worker/peergrouper" 26 ) 27 28 // dblogSuite tests that logs flow correctly from the machine and unit 29 // agents over the API into MongoDB. These are very much integration 30 // tests with more detailed testing of the individual components 31 // being done in unit tests. 32 type dblogSuite struct { 33 agenttesting.AgentSuite 34 } 35 36 func (s *dblogSuite) SetUpTest(c *gc.C) { 37 s.AgentSuite.SetUpTest(c) 38 } 39 40 func (s *dblogSuite) TestMachineAgentLogsGoToDB(c *gc.C) { 41 foundLogs := s.runMachineAgentTest(c) 42 c.Assert(foundLogs, jc.IsTrue) 43 } 44 45 func (s *dblogSuite) TestUnitAgentLogsGoToDB(c *gc.C) { 46 foundLogs := s.runUnitAgentTest(c) 47 c.Assert(foundLogs, jc.IsTrue) 48 } 49 50 func (s *dblogSuite) runMachineAgentTest(c *gc.C) bool { 51 // Create a machine and an agent for it. 52 m, password := s.Factory.MakeMachineReturningPassword(c, &factory.MachineParams{ 53 Nonce: agent.BootstrapNonce, 54 }) 55 56 s.PrimeAgent(c, m.Tag(), password) 57 agentConf := agentcmd.NewAgentConf(s.DataDir()) 58 agentConf.ReadConfig(m.Tag().String()) 59 logsCh, err := logsender.InstallBufferedLogWriter(1000) 60 c.Assert(err, jc.ErrorIsNil) 61 machineAgentFactory := agentcmd.MachineAgentFactoryFn(agentConf, logsCh, c.MkDir()) 62 a := machineAgentFactory(m.Id()) 63 64 // Ensure there's no logs to begin with. 65 c.Assert(s.getLogCount(c, m.Tag()), gc.Equals, 0) 66 67 // Start the agent. 68 go func() { c.Check(a.Run(nil), jc.ErrorIsNil) }() 69 defer a.Stop() 70 71 return s.waitForLogs(c, m.Tag()) 72 } 73 74 func (s *dblogSuite) runUnitAgentTest(c *gc.C) bool { 75 // Create a unit and an agent for it. 76 u, password := s.Factory.MakeUnitReturningPassword(c, nil) 77 s.PrimeAgent(c, u.Tag(), password) 78 logsCh, err := logsender.InstallBufferedLogWriter(1000) 79 c.Assert(err, jc.ErrorIsNil) 80 a := agentcmd.NewUnitAgent(nil, logsCh) 81 s.InitAgent(c, a, "--unit-name", u.Name(), "--log-to-stderr=true") 82 83 // Ensure there's no logs to begin with. 84 c.Assert(s.getLogCount(c, u.Tag()), gc.Equals, 0) 85 86 // Start the agent. 87 go func() { c.Assert(a.Run(nil), jc.ErrorIsNil) }() 88 defer a.Stop() 89 90 return s.waitForLogs(c, u.Tag()) 91 } 92 93 func (s *dblogSuite) getLogCount(c *gc.C, entity names.Tag) int { 94 // TODO(mjs) - replace this with State's functionality for reading 95 // logs from the DB, once it gets this. This will happen before 96 // the DB logging feature branch is merged. 97 logs := s.Session.DB("logs").C("logs") 98 count, err := logs.Find(bson.M{"n": entity.String()}).Count() 99 c.Assert(err, jc.ErrorIsNil) 100 return count 101 } 102 103 func (s *dblogSuite) waitForLogs(c *gc.C, entityTag names.Tag) bool { 104 for a := coretesting.LongAttempt.Start(); a.Next(); { 105 if s.getLogCount(c, entityTag) > 0 { 106 return true 107 } 108 } 109 return false 110 } 111 112 // debugLogDbSuite tests that the debuglog API works when logs are 113 // being read from the database. 114 type debugLogDbSuite struct { 115 agenttesting.AgentSuite 116 } 117 118 var _ = gc.Suite(&debugLogDbSuite{}) 119 120 func (s *debugLogDbSuite) SetUpSuite(c *gc.C) { 121 // Restart mongod with a the replicaset enabled. 122 mongod := jujutesting.MgoServer 123 mongod.Params = []string{"--replSet", "juju"} 124 mongod.Restart() 125 126 // Initiate the replicaset. 127 info := mongod.DialInfo() 128 args := peergrouper.InitiateMongoParams{ 129 DialInfo: info, 130 MemberHostPort: mongod.Addr(), 131 } 132 err := peergrouper.InitiateMongoServer(args) 133 c.Assert(err, jc.ErrorIsNil) 134 135 s.AgentSuite.SetUpSuite(c) 136 } 137 138 func (s *debugLogDbSuite) TearDownSuite(c *gc.C) { 139 // Restart mongod without the replicaset enabled so as not to 140 // affect other test that reply on this mongod instance in this 141 // package. 142 mongod := jujutesting.MgoServer 143 mongod.Params = []string{} 144 mongod.Restart() 145 146 s.AgentSuite.TearDownSuite(c) 147 } 148 149 func (s *debugLogDbSuite) TestLogsAPI(c *gc.C) { 150 dbLogger := state.NewDbLogger(s.State, names.NewMachineTag("99")) 151 defer dbLogger.Close() 152 153 t := time.Date(2015, 6, 23, 13, 8, 49, 0, time.UTC) 154 dbLogger.Log(t, "juju.foo", "code.go:42", loggo.INFO, "all is well") 155 dbLogger.Log(t.Add(time.Second), "juju.bar", "go.go:99", loggo.ERROR, "no it isn't") 156 157 lines := make(chan string) 158 go func(numLines int) { 159 client := s.APIState.Client() 160 reader, err := client.WatchDebugLog(api.DebugLogParams{}) 161 c.Assert(err, jc.ErrorIsNil) 162 defer reader.Close() 163 164 bufReader := bufio.NewReader(reader) 165 for n := 0; n < numLines; n++ { 166 line, err := bufReader.ReadString('\n') 167 c.Assert(err, jc.ErrorIsNil) 168 lines <- line 169 } 170 }(3) 171 172 assertLine := func(expected string) { 173 select { 174 case actual := <-lines: 175 c.Assert(actual, gc.Equals, expected) 176 case <-time.After(coretesting.LongWait): 177 c.Fatal("timed out waiting for log line") 178 } 179 } 180 181 // Read the 2 lines that are in the logs collection. 182 assertLine("machine-99: 2015-06-23 13:08:49 INFO juju.foo code.go:42 all is well\n") 183 assertLine("machine-99: 2015-06-23 13:08:50 ERROR juju.bar go.go:99 no it isn't\n") 184 185 // Now write and observe another log. This should be read from the oplog. 186 dbLogger.Log(t.Add(2*time.Second), "ju.jitsu", "no.go:3", loggo.WARNING, "beep beep") 187 assertLine("machine-99: 2015-06-23 13:08:51 WARNING ju.jitsu no.go:3 beep beep\n") 188 }