github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/cmd/juju/debuglog_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "fmt" 8 "io" 9 "io/ioutil" 10 "strings" 11 12 "github.com/juju/errors" 13 "github.com/juju/loggo" 14 jc "github.com/juju/testing/checkers" 15 gc "launchpad.net/gocheck" 16 17 "github.com/juju/juju/cmd" 18 "github.com/juju/juju/cmd/envcmd" 19 "github.com/juju/juju/state/api" 20 "github.com/juju/juju/testing" 21 ) 22 23 type DebugLogSuite struct { 24 testing.FakeJujuHomeSuite 25 } 26 27 var _ = gc.Suite(&DebugLogSuite{}) 28 29 func (s *DebugLogSuite) TestArgParsing(c *gc.C) { 30 for i, test := range []struct { 31 args []string 32 expected api.DebugLogParams 33 errMatch string 34 }{ 35 { 36 expected: api.DebugLogParams{ 37 Backlog: 10, 38 }, 39 }, { 40 args: []string{"-n0"}, 41 }, { 42 args: []string{"--lines=50"}, 43 expected: api.DebugLogParams{ 44 Backlog: 50, 45 }, 46 }, { 47 args: []string{"-l", "foo"}, 48 errMatch: `level value "foo" is not one of "TRACE", "DEBUG", "INFO", "WARNING", "ERROR"`, 49 }, { 50 args: []string{"--level=INFO"}, 51 expected: api.DebugLogParams{ 52 Backlog: 10, 53 Level: loggo.INFO, 54 }, 55 }, { 56 args: []string{"--include", "machine-1", "-i", "machine-2"}, 57 expected: api.DebugLogParams{ 58 IncludeEntity: []string{"machine-1", "machine-2"}, 59 Backlog: 10, 60 }, 61 }, { 62 args: []string{"--exclude", "machine-1", "-x", "machine-2"}, 63 expected: api.DebugLogParams{ 64 ExcludeEntity: []string{"machine-1", "machine-2"}, 65 Backlog: 10, 66 }, 67 }, { 68 args: []string{"--include-module", "juju.foo", "--include-module", "unit"}, 69 expected: api.DebugLogParams{ 70 IncludeModule: []string{"juju.foo", "unit"}, 71 Backlog: 10, 72 }, 73 }, { 74 args: []string{"--exclude-module", "juju.foo", "--exclude-module", "unit"}, 75 expected: api.DebugLogParams{ 76 ExcludeModule: []string{"juju.foo", "unit"}, 77 Backlog: 10, 78 }, 79 }, { 80 args: []string{"--replay"}, 81 expected: api.DebugLogParams{ 82 Backlog: 10, 83 Replay: true, 84 }, 85 }, { 86 args: []string{"--limit", "100"}, 87 expected: api.DebugLogParams{ 88 Backlog: 10, 89 Limit: 100, 90 }, 91 }, 92 } { 93 c.Logf("test %v", i) 94 command := &DebugLogCommand{} 95 err := testing.InitCommand(envcmd.Wrap(command), test.args) 96 if test.errMatch == "" { 97 c.Check(err, gc.IsNil) 98 c.Check(command.params, jc.DeepEquals, test.expected) 99 } else { 100 c.Check(err, gc.ErrorMatches, test.errMatch) 101 } 102 } 103 } 104 105 func (s *DebugLogSuite) TestParamsPassed(c *gc.C) { 106 fake := &fakeDebugLogAPI{} 107 s.PatchValue(&getDebugLogAPI, func(envName string) (DebugLogAPI, error) { 108 return fake, nil 109 }) 110 _, err := testing.RunCommand(c, envcmd.Wrap(&DebugLogCommand{}), 111 "-i", "machine-1*", "-x", "machine-1-lxc-1", 112 "--include-module=juju.provisioner", 113 "--lines=500", 114 "--level=WARNING", 115 ) 116 c.Assert(err, gc.IsNil) 117 c.Assert(fake.params, gc.DeepEquals, api.DebugLogParams{ 118 IncludeEntity: []string{"machine-1*"}, 119 IncludeModule: []string{"juju.provisioner"}, 120 ExcludeEntity: []string{"machine-1-lxc-1"}, 121 Backlog: 500, 122 Level: loggo.WARNING, 123 }) 124 } 125 126 func (s *DebugLogSuite) TestLogOutput(c *gc.C) { 127 s.PatchValue(&getDebugLogAPI, func(envName string) (DebugLogAPI, error) { 128 return &fakeDebugLogAPI{log: "this is the log output"}, nil 129 }) 130 ctx, err := testing.RunCommand(c, envcmd.Wrap(&DebugLogCommand{})) 131 c.Assert(err, gc.IsNil) 132 c.Assert(testing.Stdout(ctx), gc.Equals, "this is the log output") 133 } 134 135 func (s *DebugLogSuite) TestTailFallback(c *gc.C) { 136 s.PatchValue(&runSSHCommand, func(sshCmd *SSHCommand, ctx *cmd.Context) error { 137 fmt.Fprintf(ctx.Stdout, "%s", sshCmd.Args) 138 return nil 139 }) 140 s.PatchValue(&getDebugLogAPI, func(envName string) (DebugLogAPI, error) { 141 return &fakeDebugLogAPI{err: errors.NotSupportedf("testing")}, nil 142 }) 143 ctx, err := testing.RunCommand(c, envcmd.Wrap(&DebugLogCommand{}), "-n", "100") 144 c.Assert(err, gc.IsNil) 145 c.Check(testing.Stderr(ctx), gc.Equals, "Server does not support new stream log, falling back to tail\n") 146 c.Check(testing.Stdout(ctx), gc.Equals, "[tail -n -100 -f /var/log/juju/all-machines.log]") 147 } 148 149 func newFakeDebugLogAPI(log string) DebugLogAPI { 150 return &fakeDebugLogAPI{log: log} 151 } 152 153 type fakeDebugLogAPI struct { 154 log string 155 params api.DebugLogParams 156 err error 157 } 158 159 func (fake *fakeDebugLogAPI) WatchDebugLog(params api.DebugLogParams) (io.ReadCloser, error) { 160 if fake.err != nil { 161 return nil, fake.err 162 } 163 fake.params = params 164 return ioutil.NopCloser(strings.NewReader(fake.log)), nil 165 } 166 167 func (fake *fakeDebugLogAPI) Close() error { 168 return nil 169 }