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  }