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