github.com/ruphin/docker@v1.10.1/pkg/jsonmessage/jsonmessage_test.go (about)

     1  package jsonmessage
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/docker/docker/pkg/jsonlog"
    11  	"github.com/docker/docker/pkg/term"
    12  )
    13  
    14  func TestError(t *testing.T) {
    15  	je := JSONError{404, "Not found"}
    16  	if je.Error() != "Not found" {
    17  		t.Fatalf("Expected 'Not found' got '%s'", je.Error())
    18  	}
    19  }
    20  
    21  func TestProgress(t *testing.T) {
    22  	jp := JSONProgress{}
    23  	if jp.String() != "" {
    24  		t.Fatalf("Expected empty string, got '%s'", jp.String())
    25  	}
    26  
    27  	expected := "     1 B"
    28  	jp2 := JSONProgress{Current: 1}
    29  	if jp2.String() != expected {
    30  		t.Fatalf("Expected %q, got %q", expected, jp2.String())
    31  	}
    32  
    33  	expectedStart := "[==========>                                        ]     20 B/100 B"
    34  	jp3 := JSONProgress{Current: 20, Total: 100, Start: time.Now().Unix()}
    35  	// Just look at the start of the string
    36  	// (the remaining time is really hard to test -_-)
    37  	if jp3.String()[:len(expectedStart)] != expectedStart {
    38  		t.Fatalf("Expected to start with %q, got %q", expectedStart, jp3.String())
    39  	}
    40  
    41  	expected = "[=========================>                         ]     50 B/100 B"
    42  	jp4 := JSONProgress{Current: 50, Total: 100}
    43  	if jp4.String() != expected {
    44  		t.Fatalf("Expected %q, got %q", expected, jp4.String())
    45  	}
    46  
    47  	// this number can't be negative gh#7136
    48  	expected = "[==================================================>]     50 B"
    49  	jp5 := JSONProgress{Current: 50, Total: 40}
    50  	if jp5.String() != expected {
    51  		t.Fatalf("Expected %q, got %q", expected, jp5.String())
    52  	}
    53  }
    54  
    55  func TestJSONMessageDisplay(t *testing.T) {
    56  	now := time.Now()
    57  	messages := map[JSONMessage][]string{
    58  		// Empty
    59  		JSONMessage{}: {"\n", "\n"},
    60  		// Status
    61  		JSONMessage{
    62  			Status: "status",
    63  		}: {
    64  			"status\n",
    65  			"status\n",
    66  		},
    67  		// General
    68  		JSONMessage{
    69  			Time:   now.Unix(),
    70  			ID:     "ID",
    71  			From:   "From",
    72  			Status: "status",
    73  		}: {
    74  			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now.Unix(), 0).Format(jsonlog.RFC3339NanoFixed)),
    75  			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now.Unix(), 0).Format(jsonlog.RFC3339NanoFixed)),
    76  		},
    77  		// General, with nano precision time
    78  		JSONMessage{
    79  			TimeNano: now.UnixNano(),
    80  			ID:       "ID",
    81  			From:     "From",
    82  			Status:   "status",
    83  		}: {
    84  			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
    85  			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
    86  		},
    87  		// General, with both times Nano is preferred
    88  		JSONMessage{
    89  			Time:     now.Unix(),
    90  			TimeNano: now.UnixNano(),
    91  			ID:       "ID",
    92  			From:     "From",
    93  			Status:   "status",
    94  		}: {
    95  			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
    96  			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
    97  		},
    98  		// Stream over status
    99  		JSONMessage{
   100  			Status: "status",
   101  			Stream: "stream",
   102  		}: {
   103  			"stream",
   104  			"stream",
   105  		},
   106  		// With progress message
   107  		JSONMessage{
   108  			Status:          "status",
   109  			ProgressMessage: "progressMessage",
   110  		}: {
   111  			"status progressMessage",
   112  			"status progressMessage",
   113  		},
   114  		// With progress, stream empty
   115  		JSONMessage{
   116  			Status:   "status",
   117  			Stream:   "",
   118  			Progress: &JSONProgress{Current: 1},
   119  		}: {
   120  			"",
   121  			fmt.Sprintf("%c[2K\rstatus      1 B\r", 27),
   122  		},
   123  	}
   124  
   125  	// The tests :)
   126  	for jsonMessage, expectedMessages := range messages {
   127  		// Without terminal
   128  		data := bytes.NewBuffer([]byte{})
   129  		if err := jsonMessage.Display(data, false); err != nil {
   130  			t.Fatal(err)
   131  		}
   132  		if data.String() != expectedMessages[0] {
   133  			t.Fatalf("Expected [%v], got [%v]", expectedMessages[0], data.String())
   134  		}
   135  		// With terminal
   136  		data = bytes.NewBuffer([]byte{})
   137  		if err := jsonMessage.Display(data, true); err != nil {
   138  			t.Fatal(err)
   139  		}
   140  		if data.String() != expectedMessages[1] {
   141  			t.Fatalf("Expected [%v], got [%v]", expectedMessages[1], data.String())
   142  		}
   143  	}
   144  }
   145  
   146  // Test JSONMessage with an Error. It will return an error with the text as error, not the meaning of the HTTP code.
   147  func TestJSONMessageDisplayWithJSONError(t *testing.T) {
   148  	data := bytes.NewBuffer([]byte{})
   149  	jsonMessage := JSONMessage{Error: &JSONError{404, "Can't find it"}}
   150  
   151  	err := jsonMessage.Display(data, true)
   152  	if err == nil || err.Error() != "Can't find it" {
   153  		t.Fatalf("Expected a JSONError 404, got [%v]", err)
   154  	}
   155  
   156  	jsonMessage = JSONMessage{Error: &JSONError{401, "Anything"}}
   157  	err = jsonMessage.Display(data, true)
   158  	if err == nil || err.Error() != "Authentication is required." {
   159  		t.Fatalf("Expected an error [Authentication is required.], got [%v]", err)
   160  	}
   161  }
   162  
   163  func TestDisplayJSONMessagesStreamInvalidJSON(t *testing.T) {
   164  	var (
   165  		inFd uintptr
   166  	)
   167  	data := bytes.NewBuffer([]byte{})
   168  	reader := strings.NewReader("This is not a 'valid' JSON []")
   169  	inFd, _ = term.GetFdInfo(reader)
   170  
   171  	if err := DisplayJSONMessagesStream(reader, data, inFd, false, nil); err == nil && err.Error()[:17] != "invalid character" {
   172  		t.Fatalf("Should have thrown an error (invalid character in ..), got [%v]", err)
   173  	}
   174  }
   175  
   176  func TestDisplayJSONMessagesStream(t *testing.T) {
   177  	var (
   178  		inFd uintptr
   179  	)
   180  
   181  	messages := map[string][]string{
   182  		// empty string
   183  		"": {
   184  			"",
   185  			""},
   186  		// Without progress & ID
   187  		"{ \"status\": \"status\" }": {
   188  			"status\n",
   189  			"status\n",
   190  		},
   191  		// Without progress, with ID
   192  		"{ \"id\": \"ID\",\"status\": \"status\" }": {
   193  			"ID: status\n",
   194  			fmt.Sprintf("ID: status\n%c[%dB", 27, 0),
   195  		},
   196  		// With progress
   197  		"{ \"id\": \"ID\", \"status\": \"status\", \"progress\": \"ProgressMessage\" }": {
   198  			"ID: status ProgressMessage",
   199  			fmt.Sprintf("\n%c[%dAID: status ProgressMessage%c[%dB", 27, 0, 27, 0),
   200  		},
   201  		// With progressDetail
   202  		"{ \"id\": \"ID\", \"status\": \"status\", \"progressDetail\": { \"Current\": 1} }": {
   203  			"", // progressbar is disabled in non-terminal
   204  			fmt.Sprintf("\n%c[%dA%c[2K\rID: status      1 B\r%c[%dB", 27, 0, 27, 27, 0),
   205  		},
   206  	}
   207  	for jsonMessage, expectedMessages := range messages {
   208  		data := bytes.NewBuffer([]byte{})
   209  		reader := strings.NewReader(jsonMessage)
   210  		inFd, _ = term.GetFdInfo(reader)
   211  
   212  		// Without terminal
   213  		if err := DisplayJSONMessagesStream(reader, data, inFd, false, nil); err != nil {
   214  			t.Fatal(err)
   215  		}
   216  		if data.String() != expectedMessages[0] {
   217  			t.Fatalf("Expected an [%v], got [%v]", expectedMessages[0], data.String())
   218  		}
   219  
   220  		// With terminal
   221  		data = bytes.NewBuffer([]byte{})
   222  		reader = strings.NewReader(jsonMessage)
   223  		if err := DisplayJSONMessagesStream(reader, data, inFd, true, nil); err != nil {
   224  			t.Fatal(err)
   225  		}
   226  		if data.String() != expectedMessages[1] {
   227  			t.Fatalf("Expected an [%v], got [%v]", expectedMessages[1], data.String())
   228  		}
   229  	}
   230  
   231  }