github.com/nf/docker@v1.8.1/pkg/jsonmessage/jsonmessage_test.go (about)

     1  package jsonmessage
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/docker/docker/pkg/term"
    10  	"github.com/docker/docker/pkg/timeutils"
    11  	"strings"
    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/40 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().Unix()
    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,
    70  			ID:     "ID",
    71  			From:   "From",
    72  			Status: "status",
    73  		}: {
    74  			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now, 0).Format(timeutils.RFC3339NanoFixed)),
    75  			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now, 0).Format(timeutils.RFC3339NanoFixed)),
    76  		},
    77  		// Stream over status
    78  		JSONMessage{
    79  			Status: "status",
    80  			Stream: "stream",
    81  		}: {
    82  			"stream",
    83  			"stream",
    84  		},
    85  		// With progress message
    86  		JSONMessage{
    87  			Status:          "status",
    88  			ProgressMessage: "progressMessage",
    89  		}: {
    90  			"status progressMessage",
    91  			"status progressMessage",
    92  		},
    93  		// With progress, stream empty
    94  		JSONMessage{
    95  			Status:   "status",
    96  			Stream:   "",
    97  			Progress: &JSONProgress{Current: 1},
    98  		}: {
    99  			"",
   100  			fmt.Sprintf("%c[2K\rstatus      1 B\r", 27),
   101  		},
   102  	}
   103  
   104  	// The tests :)
   105  	for jsonMessage, expectedMessages := range messages {
   106  		// Without terminal
   107  		data := bytes.NewBuffer([]byte{})
   108  		if err := jsonMessage.Display(data, false); err != nil {
   109  			t.Fatal(err)
   110  		}
   111  		if data.String() != expectedMessages[0] {
   112  			t.Fatalf("Expected [%v], got [%v]", expectedMessages[0], data.String())
   113  		}
   114  		// With terminal
   115  		data = bytes.NewBuffer([]byte{})
   116  		if err := jsonMessage.Display(data, true); err != nil {
   117  			t.Fatal(err)
   118  		}
   119  		if data.String() != expectedMessages[1] {
   120  			t.Fatalf("Expected [%v], got [%v]", expectedMessages[1], data.String())
   121  		}
   122  	}
   123  }
   124  
   125  // Test JSONMessage with an Error. It will return an error with the text as error, not the meaning of the HTTP code.
   126  func TestJSONMessageDisplayWithJSONError(t *testing.T) {
   127  	data := bytes.NewBuffer([]byte{})
   128  	jsonMessage := JSONMessage{Error: &JSONError{404, "Can't find it"}}
   129  
   130  	err := jsonMessage.Display(data, true)
   131  	if err == nil || err.Error() != "Can't find it" {
   132  		t.Fatalf("Expected a JSONError 404, got [%v]", err)
   133  	}
   134  
   135  	jsonMessage = JSONMessage{Error: &JSONError{401, "Anything"}}
   136  	err = jsonMessage.Display(data, true)
   137  	if err == nil || err.Error() != "Authentication is required." {
   138  		t.Fatalf("Expected an error [Authentication is required.], got [%v]", err)
   139  	}
   140  }
   141  
   142  func TestDisplayJSONMessagesStreamInvalidJSON(t *testing.T) {
   143  	var (
   144  		inFd uintptr
   145  	)
   146  	data := bytes.NewBuffer([]byte{})
   147  	reader := strings.NewReader("This is not a 'valid' JSON []")
   148  	inFd, _ = term.GetFdInfo(reader)
   149  
   150  	if err := DisplayJSONMessagesStream(reader, data, inFd, false); err == nil && err.Error()[:17] != "invalid character" {
   151  		t.Fatalf("Should have thrown an error (invalid character in ..), got [%v]", err)
   152  	}
   153  }
   154  
   155  func TestDisplayJSONMessagesStream(t *testing.T) {
   156  	var (
   157  		inFd uintptr
   158  	)
   159  
   160  	messages := map[string][]string{
   161  		// empty string
   162  		"": {
   163  			"",
   164  			""},
   165  		// Without progress & ID
   166  		"{ \"status\": \"status\" }": {
   167  			"status\n",
   168  			"status\n",
   169  		},
   170  		// Without progress, with ID
   171  		"{ \"id\": \"ID\",\"status\": \"status\" }": {
   172  			"ID: status\n",
   173  			fmt.Sprintf("ID: status\n%c[%dB", 27, 0),
   174  		},
   175  		// With progress
   176  		"{ \"id\": \"ID\", \"status\": \"status\", \"progress\": \"ProgressMessage\" }": {
   177  			"ID: status ProgressMessage",
   178  			fmt.Sprintf("\n%c[%dAID: status ProgressMessage%c[%dB", 27, 0, 27, 0),
   179  		},
   180  		// With progressDetail
   181  		"{ \"id\": \"ID\", \"status\": \"status\", \"progressDetail\": { \"Current\": 1} }": {
   182  			"", // progressbar is disabled in non-terminal
   183  			fmt.Sprintf("\n%c[%dA%c[2K\rID: status      1 B\r%c[%dB", 27, 0, 27, 27, 0),
   184  		},
   185  	}
   186  	for jsonMessage, expectedMessages := range messages {
   187  		data := bytes.NewBuffer([]byte{})
   188  		reader := strings.NewReader(jsonMessage)
   189  		inFd, _ = term.GetFdInfo(reader)
   190  
   191  		// Without terminal
   192  		if err := DisplayJSONMessagesStream(reader, data, inFd, false); err != nil {
   193  			t.Fatal(err)
   194  		}
   195  		if data.String() != expectedMessages[0] {
   196  			t.Fatalf("Expected an [%v], got [%v]", expectedMessages[0], data.String())
   197  		}
   198  
   199  		// With terminal
   200  		data = bytes.NewBuffer([]byte{})
   201  		reader = strings.NewReader(jsonMessage)
   202  		if err := DisplayJSONMessagesStream(reader, data, inFd, true); err != nil {
   203  			t.Fatal(err)
   204  		}
   205  		if data.String() != expectedMessages[1] {
   206  			t.Fatalf("Expected an [%v], got [%v]", expectedMessages[1], data.String())
   207  		}
   208  	}
   209  
   210  }