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  }