func (s *S) TestAppLog(c *check.C) { var stdout, stderr bytes.Buffer t := time.Now() logs := []log{ {Date: t, Message: "creating app lost", Source: "tsuru"}, {Date: t.Add(2 * time.Hour), Message: "app lost successfully created", Source: "app", Unit: "abcdef"}, } result, err := json.Marshal(logs) c.Assert(err, check.IsNil) t = t.In(time.Local) tfmt := "2006-01-02 15:04:05 -0700" expected := cmd.Colorfy(t.Format(tfmt)+" [tsuru]:", "blue", "", "") + " creating app lost\n" expected = expected + cmd.Colorfy(t.Add(2*time.Hour).Format(tfmt)+" [app][abcdef]:", "blue", "", "") + " app lost successfully created\n" context := cmd.Context{ Stdout: &stdout, Stderr: &stderr, } command := appLog{} transport := cmdtest.Transport{ Message: string(result), Status: http.StatusOK, } client := cmd.NewClient(&http.Client{Transport: &transport}, nil, manager) command.Flags().Parse(true, []string{"--app", "appName"}) err = command.Run(&context, client) c.Assert(err, check.IsNil) c.Assert(stdout.String(), check.Equals, expected) }
func (s *S) TestAppLogWithoutTheFlag(c *check.C) { var stdout, stderr bytes.Buffer t := time.Now() logs := []log{ {Date: t, Message: "creating app lost", Source: "tsuru"}, {Date: t.Add(2 * time.Hour), Message: "app lost successfully created", Source: "app"}, } result, err := json.Marshal(logs) c.Assert(err, check.IsNil) t = t.In(time.Local) tfmt := "2006-01-02 15:04:05 -0700" expected := cmd.Colorfy(t.Format(tfmt)+" [tsuru]:", "blue", "", "") + " creating app lost\n" expected = expected + cmd.Colorfy(t.Add(2*time.Hour).Format(tfmt)+" [app]:", "blue", "", "") + " app lost successfully created\n" context := cmd.Context{ Stdout: &stdout, Stderr: &stderr, } fake := &cmdtest.FakeGuesser{Name: "hitthelights"} command := appLog{GuessingCommand: cmd.GuessingCommand{G: fake}} command.Flags().Parse(true, nil) trans := &cmdtest.ConditionalTransport{ Transport: cmdtest.Transport{Message: string(result), Status: http.StatusOK}, CondFunc: func(req *http.Request) bool { return req.URL.Path == "/apps/hitthelights/log" && req.Method == "GET" && req.URL.Query().Get("lines") == "10" }, } client := cmd.NewClient(&http.Client{Transport: trans}, nil, manager) err = command.Run(&context, client) c.Assert(err, check.IsNil) c.Assert(stdout.String(), check.Equals, expected) }
func (s *S) TestJSONWriterChukedWrite(c *gocheck.C) { t := time.Now() logs := []log{ {Date: t, Message: "Something happened", Source: "tsuru"}, {Date: t.Add(2 * time.Hour), Message: "Something happened again", Source: "tsuru"}, } data, err := json.Marshal(logs) c.Assert(err, gocheck.IsNil) l := len(data) var buf bytes.Buffer w := jsonWriter{w: &buf} _, err = w.Write(data[:l/4]) c.Assert(err, gocheck.IsNil) c.Assert(buf.String(), gocheck.Equals, "") _, err = w.Write(data[l/4 : l/2]) c.Assert(err, gocheck.IsNil) c.Assert(buf.String(), gocheck.Equals, "") _, err = w.Write(data[l/2 : l/4*3]) c.Assert(err, gocheck.IsNil) c.Assert(buf.String(), gocheck.Equals, "") _, err = w.Write(data[l/4*3:]) c.Assert(err, gocheck.IsNil) tfmt := "2006-01-02 15:04:05 -0700" expected := cmd.Colorfy(t.Format(tfmt)+" [tsuru]:", "blue", "", "") + " Something happened\n" expected = expected + cmd.Colorfy(t.Add(2*time.Hour).Format(tfmt)+" [tsuru]:", "blue", "", "") + " Something happened again\n" c.Assert(buf.String(), gocheck.Equals, expected) }
func (s *S) TestAppLogWithNoSource(c *check.C) { var stdout, stderr bytes.Buffer t := time.Now() logs := []log{ {Date: t, Message: "GET /", Source: "web"}, {Date: t.Add(2 * time.Hour), Message: "POST /", Source: "web"}, } result, err := json.Marshal(logs) c.Assert(err, check.IsNil) t = t.In(time.Local) tfmt := "2006-01-02 15:04:05 -0700" expected := cmd.Colorfy(t.Format(tfmt)+":", "blue", "", "") + " GET /\n" expected = expected + cmd.Colorfy(t.Add(2*time.Hour).Format(tfmt)+":", "blue", "", "") + " POST /\n" context := cmd.Context{ Stdout: &stdout, Stderr: &stderr, } fake := &cmdtest.FakeGuesser{Name: "hitthelights"} command := appLog{GuessingCommand: cmd.GuessingCommand{G: fake}} command.Flags().Parse(true, []string{"--lines", "12", "-f", "--no-source"}) trans := &cmdtest.ConditionalTransport{ Transport: cmdtest.Transport{Message: string(result), Status: http.StatusOK}, CondFunc: func(req *http.Request) bool { return req.URL.Query().Get("lines") == "12" && req.URL.Query().Get("follow") == "1" }, } client := cmd.NewClient(&http.Client{Transport: trans}, nil, manager) err = command.Run(&context, client) c.Assert(err, check.IsNil) c.Assert(stdout.String(), check.Equals, expected) }
func (s *S) TestAppLogByUnit(c *gocheck.C) { var stdout, stderr bytes.Buffer t := time.Now() logs := []log{ {Date: t, Message: "creating app lost", Source: "tsuru", Unit: "api"}, {Date: t.Add(2 * time.Hour), Message: "app lost successfully created", Source: "tsuru", Unit: "api"}, } result, err := json.Marshal(logs) c.Assert(err, gocheck.IsNil) t = t.In(time.Local) tfmt := "2006-01-02 15:04:05 -0700" expected := cmd.Colorfy(t.Format(tfmt)+" [tsuru][api]:", "blue", "", "") + " creating app lost\n" expected = expected + cmd.Colorfy(t.Add(2*time.Hour).Format(tfmt)+" [tsuru][api]:", "blue", "", "") + " app lost successfully created\n" context := cmd.Context{ Stdout: &stdout, Stderr: &stderr, } fake := &FakeGuesser{name: "hitthelights"} command := AppLog{GuessingCommand: GuessingCommand{G: fake}} command.Flags().Parse(true, []string{"--unit", "api"}) trans := &testing.ConditionalTransport{ Transport: testing.Transport{Message: string(result), Status: http.StatusOK}, CondFunc: func(req *http.Request) bool { return req.URL.Query().Get("unit") == "api" }, } client := cmd.NewClient(&http.Client{Transport: trans}, nil, manager) err = command.Run(&context, client) c.Assert(err, gocheck.IsNil) c.Assert(stdout.String(), gocheck.Equals, expected) }
func (s *S) TestAppLogWithUnparsableData(c *gocheck.C) { var stdout, stderr bytes.Buffer t := time.Now() logs := []log{ {Date: t, Message: "creating app lost", Source: "tsuru"}, } result, err := json.Marshal(logs) c.Assert(err, gocheck.IsNil) t = t.In(time.Local) tfmt := "2006-01-02 15:04:05 -0700" context := cmd.Context{ Stdout: &stdout, Stderr: &stderr, } command := AppLog{} transport := testing.Transport{ Message: string(result) + "\nunparseable data", Status: http.StatusOK, } client := cmd.NewClient(&http.Client{Transport: &transport}, nil, manager) command.Flags().Parse(true, []string{"--app", "appName"}) err = command.Run(&context, client) c.Assert(err, gocheck.IsNil) expected := cmd.Colorfy(t.Format(tfmt)+" [tsuru]:", "blue", "", "") + " creating app lost\n" expected += "Error: unparseable data" c.Assert(stdout.String(), gocheck.Equals, expected) }
func (s *S) TestJSONWriter(c *gocheck.C) { t := time.Now() logs := []log{ {Date: t, Message: "Something happened", Source: "tsuru"}, {Date: t.Add(2 * time.Hour), Message: "Something happened again", Source: "tsuru"}, } b, err := json.Marshal(logs) c.Assert(err, gocheck.IsNil) var writer bytes.Buffer w := jsonWriter{w: &writer} n, err := w.Write(b) c.Assert(err, gocheck.IsNil) c.Assert(n, gocheck.Equals, len(b)) tfmt := "2006-01-02 15:04:05 -0700" expected := cmd.Colorfy(t.Format(tfmt)+" [tsuru]:", "blue", "", "") + " Something happened\n" expected = expected + cmd.Colorfy(t.Add(2*time.Hour).Format(tfmt)+" [tsuru]:", "blue", "", "") + " Something happened again\n" c.Assert(writer.String(), gocheck.Equals, expected) }
func (s *S) TestJSONWriterUsesCurrentTimeZone(c *gocheck.C) { t := time.Now() logs := []log{ {Date: t, Message: "Something happened", Source: "tsuru"}, {Date: t.Add(2 * time.Hour), Message: "Something happened again", Source: "tsuru"}, } data, err := json.Marshal(logs) c.Assert(err, gocheck.IsNil) var writer bytes.Buffer w := jsonWriter{w: &writer} old := time.Local time.Local = time.UTC defer func() { time.Local = old }() w.Write(data) tfmt := "2006-01-02 15:04:05 -0700" t = t.In(time.UTC) expected := cmd.Colorfy(t.Format(tfmt)+" [tsuru]:", "blue", "", "") + " Something happened\n" expected = expected + cmd.Colorfy(t.Add(2*time.Hour).Format(tfmt)+" [tsuru]:", "blue", "", "") + " Something happened again\n" c.Assert(writer.String(), gocheck.Equals, expected) }
func (w *jsonWriter) Write(b []byte) (int, error) { var logs []log w.b = append(w.b, b...) err := json.Unmarshal(w.b, &logs) if err != nil { return len(b), nil } for _, l := range logs { date := l.Date.In(time.Local).Format("2006-01-02 15:04:05 -0700") prefix := fmt.Sprintf("%s [%s]:", date, l.Source) fmt.Fprintf(w.w, "%s %s\n", cmd.Colorfy(prefix, "blue", "", ""), l.Message) } w.b = nil return len(b), nil }
func (f logFormatter) Format(out io.Writer, data []byte) error { var logs []log err := json.Unmarshal(data, &logs) if err != nil { return tsuruIo.ErrInvalidStreamChunk } for _, l := range logs { prefix := f.prefix(l) if prefix == "" { fmt.Fprintf(out, "%s\n", l.Message) } else { fmt.Fprintf(out, "%s %s\n", cmd.Colorfy(prefix, "blue", "", ""), l.Message) } } return nil }
func (logFormatter) Format(out io.Writer, data []byte) error { var logs []log err := json.Unmarshal(data, &logs) if err != nil { return tsuruIo.ErrInvalidStreamChunk } for _, l := range logs { date := l.Date.In(time.Local).Format("2006-01-02 15:04:05 -0700") var prefix string if l.Unit != "" { prefix = fmt.Sprintf("%s [%s][%s]:", date, l.Source, l.Unit) } else { prefix = fmt.Sprintf("%s [%s]:", date, l.Source) } fmt.Fprintf(out, "%s %s\n", cmd.Colorfy(prefix, "blue", "", ""), l.Message) } return nil }
func (c *appDeployList) Run(context *cmd.Context, client *cmd.Client) error { appName, err := c.Guess() if err != nil { return err } url, err := cmd.GetURL(fmt.Sprintf("/deploys?app=%s&limit=10", appName)) if err != nil { return err } request, err := http.NewRequest("GET", url, nil) if err != nil { return err } response, err := client.Do(request) if err != nil { return err } if response.StatusCode == http.StatusNoContent { fmt.Fprintf(context.Stdout, "App %s has no deploy.\n", appName) return nil } defer response.Body.Close() result, err := ioutil.ReadAll(response.Body) if err != nil { return err } var deploys []tsuruapp.DeployData err = json.Unmarshal(result, &deploys) if err != nil { return err } sort.Sort(sort.Reverse(deployList(deploys))) table := cmd.NewTable() table.Headers = cmd.Row([]string{"Image (Rollback)", "Origin", "User", "Date (Duration)", "Error"}) for _, deploy := range deploys { timestamp := deploy.Timestamp.Local().Format(time.Stamp) seconds := deploy.Duration / time.Second minutes := seconds / 60 seconds = seconds % 60 if deploy.Origin == "git" { if len(deploy.Commit) > 7 { deploy.Commit = deploy.Commit[:7] } deploy.Origin = fmt.Sprintf("git (%s)", deploy.Commit) } timestamp = fmt.Sprintf("%s (%02d:%02d)", timestamp, minutes, seconds) if deploy.CanRollback { deploy.Image += " (*)" } rowData := []string{deploy.Image, deploy.Origin, deploy.User, timestamp, deploy.Error} if deploy.Error != "" { for i, el := range rowData { if el != "" { rowData[i] = cmd.Colorfy(el, "red", "", "") } } } table.LineSeparator = true table.AddRow(cmd.Row(rowData)) } context.Stdout.Write(table.Bytes()) return nil }