github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/commands/debuglog_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package commands 5 6 import ( 7 "time" 8 9 "github.com/juju/loggo" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/api" 14 "github.com/juju/juju/cmd/modelcmd" 15 "github.com/juju/juju/testing" 16 ) 17 18 type DebugLogSuite struct { 19 testing.FakeJujuXDGDataHomeSuite 20 } 21 22 var _ = gc.Suite(&DebugLogSuite{}) 23 24 func (s *DebugLogSuite) TestArgParsing(c *gc.C) { 25 for i, test := range []struct { 26 args []string 27 expected api.DebugLogParams 28 errMatch string 29 }{ 30 { 31 expected: api.DebugLogParams{ 32 Backlog: 10, 33 }, 34 }, { 35 args: []string{"-n0"}, 36 }, { 37 args: []string{"--lines=50"}, 38 expected: api.DebugLogParams{ 39 Backlog: 50, 40 }, 41 }, { 42 args: []string{"-l", "foo"}, 43 errMatch: `level value "foo" is not one of "TRACE", "DEBUG", "INFO", "WARNING", "ERROR"`, 44 }, { 45 args: []string{"--level=INFO"}, 46 expected: api.DebugLogParams{ 47 Backlog: 10, 48 Level: loggo.INFO, 49 }, 50 }, { 51 args: []string{"--include", "machine-1", "-i", "machine-2"}, 52 expected: api.DebugLogParams{ 53 IncludeEntity: []string{"machine-1", "machine-2"}, 54 Backlog: 10, 55 }, 56 }, { 57 args: []string{"--exclude", "machine-1", "-x", "machine-2"}, 58 expected: api.DebugLogParams{ 59 ExcludeEntity: []string{"machine-1", "machine-2"}, 60 Backlog: 10, 61 }, 62 }, { 63 args: []string{"--include-module", "juju.foo", "--include-module", "unit"}, 64 expected: api.DebugLogParams{ 65 IncludeModule: []string{"juju.foo", "unit"}, 66 Backlog: 10, 67 }, 68 }, { 69 args: []string{"--exclude-module", "juju.foo", "--exclude-module", "unit"}, 70 expected: api.DebugLogParams{ 71 ExcludeModule: []string{"juju.foo", "unit"}, 72 Backlog: 10, 73 }, 74 }, { 75 args: []string{"--replay"}, 76 expected: api.DebugLogParams{ 77 Backlog: 10, 78 Replay: true, 79 }, 80 }, { 81 args: []string{"--no-tail", "--tail"}, 82 errMatch: `setting --tail and --no-tail not valid`, 83 }, { 84 args: []string{"--limit", "100"}, 85 expected: api.DebugLogParams{ 86 Backlog: 10, 87 Limit: 100, 88 }, 89 }, 90 } { 91 c.Logf("test %v", i) 92 command := &debugLogCommand{} 93 err := testing.InitCommand(modelcmd.Wrap(command), test.args) 94 if test.errMatch == "" { 95 c.Check(err, jc.ErrorIsNil) 96 c.Check(command.params, jc.DeepEquals, test.expected) 97 } else { 98 c.Check(err, gc.ErrorMatches, test.errMatch) 99 } 100 } 101 } 102 103 func (s *DebugLogSuite) TestParamsPassed(c *gc.C) { 104 fake := &fakeDebugLogAPI{} 105 s.PatchValue(&getDebugLogAPI, func(_ *debugLogCommand) (DebugLogAPI, error) { 106 return fake, nil 107 }) 108 _, err := testing.RunCommand(c, newDebugLogCommand(), 109 "-i", "machine-1*", "-x", "machine-1-lxd-1", 110 "--include-module=juju.provisioner", 111 "--lines=500", 112 "--level=WARNING", 113 "--no-tail", 114 ) 115 c.Assert(err, jc.ErrorIsNil) 116 c.Assert(fake.params, gc.DeepEquals, api.DebugLogParams{ 117 IncludeEntity: []string{"machine-1*"}, 118 IncludeModule: []string{"juju.provisioner"}, 119 ExcludeEntity: []string{"machine-1-lxd-1"}, 120 Backlog: 500, 121 Level: loggo.WARNING, 122 NoTail: true, 123 }) 124 } 125 126 func (s *DebugLogSuite) TestLogOutput(c *gc.C) { 127 // test timezone is 6 hours east of UTC 128 tz := time.FixedZone("test", 6*60*60) 129 s.PatchValue(&getDebugLogAPI, func(_ *debugLogCommand) (DebugLogAPI, error) { 130 return &fakeDebugLogAPI{log: []api.LogMessage{ 131 { 132 Entity: "machine-0", 133 Timestamp: time.Date(2016, 10, 9, 8, 15, 23, 345000000, time.UTC), 134 Severity: "INFO", 135 Module: "test.module", 136 Location: "somefile.go:123", 137 Message: "this is the log output", 138 }, 139 }}, nil 140 }) 141 checkOutput := func(args ...string) { 142 count := len(args) 143 args, expected := args[:count-1], args[count-1] 144 ctx, err := testing.RunCommand(c, newDebugLogCommandTZ(tz), args...) 145 c.Check(err, jc.ErrorIsNil) 146 c.Check(testing.Stdout(ctx), gc.Equals, expected) 147 148 } 149 checkOutput( 150 "machine-0: 14:15:23 INFO test.module this is the log output\n") 151 checkOutput( 152 "--ms", 153 "machine-0: 14:15:23.345 INFO test.module this is the log output\n") 154 checkOutput( 155 "--utc", 156 "machine-0: 08:15:23 INFO test.module this is the log output\n") 157 checkOutput( 158 "--date", 159 "machine-0: 2016-10-09 14:15:23 INFO test.module this is the log output\n") 160 checkOutput( 161 "--utc", "--date", 162 "machine-0: 2016-10-09 08:15:23 INFO test.module this is the log output\n") 163 checkOutput( 164 "--location", 165 "machine-0: 14:15:23 INFO test.module somefile.go:123 this is the log output\n") 166 } 167 168 type fakeDebugLogAPI struct { 169 log []api.LogMessage 170 params api.DebugLogParams 171 err error 172 } 173 174 func (fake *fakeDebugLogAPI) WatchDebugLog(params api.DebugLogParams) (<-chan api.LogMessage, error) { 175 if fake.err != nil { 176 return nil, fake.err 177 } 178 fake.params = params 179 response := make(chan api.LogMessage) 180 go func() { 181 defer close(response) 182 for _, msg := range fake.log { 183 response <- msg 184 } 185 }() 186 return response, nil 187 } 188 189 func (fake *fakeDebugLogAPI) Close() error { 190 return nil 191 }