|
@@ -1,7 +1,14 @@
|
|
|
package jsonmessage
|
|
|
|
|
|
import (
|
|
|
+ "bytes"
|
|
|
+ "fmt"
|
|
|
"testing"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/docker/docker/pkg/term"
|
|
|
+ "github.com/docker/docker/pkg/timeutils"
|
|
|
+ "strings"
|
|
|
)
|
|
|
|
|
|
func TestError(t *testing.T) {
|
|
@@ -23,16 +30,181 @@ func TestProgress(t *testing.T) {
|
|
|
t.Fatalf("Expected %q, got %q", expected, jp2.String())
|
|
|
}
|
|
|
|
|
|
- expected = "[=========================> ] 50 B/100 B"
|
|
|
- jp3 := JSONProgress{Current: 50, Total: 100}
|
|
|
- if jp3.String() != expected {
|
|
|
- t.Fatalf("Expected %q, got %q", expected, jp3.String())
|
|
|
+ expectedStart := "[==========> ] 20 B/100 B"
|
|
|
+ jp3 := JSONProgress{Current: 20, Total: 100, Start: time.Now().Unix()}
|
|
|
+ // Just look at the start of the string
|
|
|
+ // (the remaining time is really hard to test -_-)
|
|
|
+ if jp3.String()[:len(expectedStart)] != expectedStart {
|
|
|
+ t.Fatalf("Expected to start with %q, got %q", expectedStart, jp3.String())
|
|
|
}
|
|
|
|
|
|
- // this number can't be negetive gh#7136
|
|
|
- expected = "[==================================================>] 50 B/40 B"
|
|
|
- jp4 := JSONProgress{Current: 50, Total: 40}
|
|
|
+ expected = "[=========================> ] 50 B/100 B"
|
|
|
+ jp4 := JSONProgress{Current: 50, Total: 100}
|
|
|
if jp4.String() != expected {
|
|
|
t.Fatalf("Expected %q, got %q", expected, jp4.String())
|
|
|
}
|
|
|
+
|
|
|
+ // this number can't be negative gh#7136
|
|
|
+ expected = "[==================================================>] 50 B/40 B"
|
|
|
+ jp5 := JSONProgress{Current: 50, Total: 40}
|
|
|
+ if jp5.String() != expected {
|
|
|
+ t.Fatalf("Expected %q, got %q", expected, jp5.String())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestJSONMessageDisplay(t *testing.T) {
|
|
|
+ now := time.Now().Unix()
|
|
|
+ messages := map[JSONMessage][]string{
|
|
|
+ // Empty
|
|
|
+ JSONMessage{}: {"\n", "\n"},
|
|
|
+ // Status
|
|
|
+ JSONMessage{
|
|
|
+ Status: "status",
|
|
|
+ }: {
|
|
|
+ "status\n",
|
|
|
+ "status\n",
|
|
|
+ },
|
|
|
+ // General
|
|
|
+ JSONMessage{
|
|
|
+ Time: now,
|
|
|
+ ID: "ID",
|
|
|
+ From: "From",
|
|
|
+ Status: "status",
|
|
|
+ }: {
|
|
|
+ fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now, 0).Format(timeutils.RFC3339NanoFixed)),
|
|
|
+ fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now, 0).Format(timeutils.RFC3339NanoFixed)),
|
|
|
+ },
|
|
|
+ // Stream over status
|
|
|
+ JSONMessage{
|
|
|
+ Status: "status",
|
|
|
+ Stream: "stream",
|
|
|
+ }: {
|
|
|
+ "stream",
|
|
|
+ "stream",
|
|
|
+ },
|
|
|
+ // With progress message
|
|
|
+ JSONMessage{
|
|
|
+ Status: "status",
|
|
|
+ ProgressMessage: "progressMessage",
|
|
|
+ }: {
|
|
|
+ "status progressMessage",
|
|
|
+ "status progressMessage",
|
|
|
+ },
|
|
|
+ // With progress, stream empty
|
|
|
+ JSONMessage{
|
|
|
+ Status: "status",
|
|
|
+ Stream: "",
|
|
|
+ Progress: &JSONProgress{Current: 1},
|
|
|
+ }: {
|
|
|
+ "",
|
|
|
+ fmt.Sprintf("%c[2K\rstatus 1 B\r", 27),
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ // The tests :)
|
|
|
+ for jsonMessage, expectedMessages := range messages {
|
|
|
+ // Without terminal
|
|
|
+ data := bytes.NewBuffer([]byte{})
|
|
|
+ if err := jsonMessage.Display(data, false); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ if data.String() != expectedMessages[0] {
|
|
|
+ t.Fatalf("Expected [%v], got [%v]", expectedMessages[0], data.String())
|
|
|
+ }
|
|
|
+ // With terminal
|
|
|
+ data = bytes.NewBuffer([]byte{})
|
|
|
+ if err := jsonMessage.Display(data, true); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ if data.String() != expectedMessages[1] {
|
|
|
+ t.Fatalf("Expected [%v], got [%v]", expectedMessages[1], data.String())
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Test JSONMessage with an Error. It will return an error with the text as error, not the meaning of the HTTP code.
|
|
|
+func TestJSONMessageDisplayWithJSONError(t *testing.T) {
|
|
|
+ data := bytes.NewBuffer([]byte{})
|
|
|
+ jsonMessage := JSONMessage{Error: &JSONError{404, "Can't find it"}}
|
|
|
+
|
|
|
+ err := jsonMessage.Display(data, true)
|
|
|
+ if err == nil || err.Error() != "Can't find it" {
|
|
|
+ t.Fatalf("Expected a JSONError 404, got [%v]", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ jsonMessage = JSONMessage{Error: &JSONError{401, "Anything"}}
|
|
|
+ err = jsonMessage.Display(data, true)
|
|
|
+ if err == nil || err.Error() != "Authentication is required." {
|
|
|
+ t.Fatalf("Expected an error [Authentication is required.], got [%v]", err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestDisplayJSONMessagesStreamInvalidJSON(t *testing.T) {
|
|
|
+ var (
|
|
|
+ inFd uintptr
|
|
|
+ )
|
|
|
+ data := bytes.NewBuffer([]byte{})
|
|
|
+ reader := strings.NewReader("This is not a 'valid' JSON []")
|
|
|
+ inFd, _ = term.GetFdInfo(reader)
|
|
|
+
|
|
|
+ if err := DisplayJSONMessagesStream(reader, data, inFd, false); err == nil && err.Error()[:17] != "invalid character" {
|
|
|
+ t.Fatalf("Should have thrown an error (invalid character in ..), got [%v]", err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestDisplayJSONMessagesStream(t *testing.T) {
|
|
|
+ var (
|
|
|
+ inFd uintptr
|
|
|
+ )
|
|
|
+
|
|
|
+ messages := map[string][]string{
|
|
|
+ // empty string
|
|
|
+ "": {
|
|
|
+ "",
|
|
|
+ ""},
|
|
|
+ // Without progress & ID
|
|
|
+ "{ \"status\": \"status\" }": {
|
|
|
+ "status\n",
|
|
|
+ "status\n",
|
|
|
+ },
|
|
|
+ // Without progress, with ID
|
|
|
+ "{ \"id\": \"ID\",\"status\": \"status\" }": {
|
|
|
+ "ID: status\n",
|
|
|
+ fmt.Sprintf("ID: status\n%c[%dB", 27, 0),
|
|
|
+ },
|
|
|
+ // With progress
|
|
|
+ "{ \"id\": \"ID\", \"status\": \"status\", \"progress\": \"ProgressMessage\" }": {
|
|
|
+ "ID: status ProgressMessage",
|
|
|
+ fmt.Sprintf("\n%c[%dAID: status ProgressMessage%c[%dB", 27, 0, 27, 0),
|
|
|
+ },
|
|
|
+ // With progressDetail
|
|
|
+ "{ \"id\": \"ID\", \"status\": \"status\", \"progressDetail\": { \"Current\": 1} }": {
|
|
|
+ "", // progressbar is disabled in non-terminal
|
|
|
+ fmt.Sprintf("\n%c[%dA%c[2K\rID: status 1 B\r%c[%dB", 27, 0, 27, 27, 0),
|
|
|
+ },
|
|
|
+ }
|
|
|
+ for jsonMessage, expectedMessages := range messages {
|
|
|
+ data := bytes.NewBuffer([]byte{})
|
|
|
+ reader := strings.NewReader(jsonMessage)
|
|
|
+ inFd, _ = term.GetFdInfo(reader)
|
|
|
+
|
|
|
+ // Without terminal
|
|
|
+ if err := DisplayJSONMessagesStream(reader, data, inFd, false); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ if data.String() != expectedMessages[0] {
|
|
|
+ t.Fatalf("Expected an [%v], got [%v]", expectedMessages[0], data.String())
|
|
|
+ }
|
|
|
+
|
|
|
+ // With terminal
|
|
|
+ data = bytes.NewBuffer([]byte{})
|
|
|
+ reader = strings.NewReader(jsonMessage)
|
|
|
+ if err := DisplayJSONMessagesStream(reader, data, inFd, true); err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+ if data.String() != expectedMessages[1] {
|
|
|
+ t.Fatalf("Expected an [%v], got [%v]", expectedMessages[1], data.String())
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|