github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/network/formatter_test.go (about)

     1  // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
     2  //go:build go1.19
     3  
     4  package network
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"fmt"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/docker/cli/cli/command/formatter"
    15  	"github.com/docker/cli/internal/test"
    16  	"github.com/docker/docker/api/types"
    17  	"github.com/docker/docker/pkg/stringid"
    18  	"gotest.tools/v3/assert"
    19  	is "gotest.tools/v3/assert/cmp"
    20  )
    21  
    22  func TestNetworkContext(t *testing.T) {
    23  	networkID := stringid.GenerateRandomID()
    24  
    25  	var ctx networkContext
    26  	cases := []struct {
    27  		networkCtx networkContext
    28  		expValue   string
    29  		call       func() string
    30  	}{
    31  		{networkContext{
    32  			n:     types.NetworkResource{ID: networkID},
    33  			trunc: false,
    34  		}, networkID, ctx.ID},
    35  		{networkContext{
    36  			n:     types.NetworkResource{ID: networkID},
    37  			trunc: true,
    38  		}, stringid.TruncateID(networkID), ctx.ID},
    39  		{networkContext{
    40  			n: types.NetworkResource{Name: "network_name"},
    41  		}, "network_name", ctx.Name},
    42  		{networkContext{
    43  			n: types.NetworkResource{Driver: "driver_name"},
    44  		}, "driver_name", ctx.Driver},
    45  		{networkContext{
    46  			n: types.NetworkResource{EnableIPv6: true},
    47  		}, "true", ctx.IPv6},
    48  		{networkContext{
    49  			n: types.NetworkResource{EnableIPv6: false},
    50  		}, "false", ctx.IPv6},
    51  		{networkContext{
    52  			n: types.NetworkResource{Internal: true},
    53  		}, "true", ctx.Internal},
    54  		{networkContext{
    55  			n: types.NetworkResource{Internal: false},
    56  		}, "false", ctx.Internal},
    57  		{networkContext{
    58  			n: types.NetworkResource{},
    59  		}, "", ctx.Labels},
    60  		{networkContext{
    61  			n: types.NetworkResource{Labels: map[string]string{"label1": "value1", "label2": "value2"}},
    62  		}, "label1=value1,label2=value2", ctx.Labels},
    63  	}
    64  
    65  	for _, c := range cases {
    66  		ctx = c.networkCtx
    67  		v := c.call()
    68  		if strings.Contains(v, ",") {
    69  			test.CompareMultipleValues(t, v, c.expValue)
    70  		} else if v != c.expValue {
    71  			t.Fatalf("Expected %s, was %s\n", c.expValue, v)
    72  		}
    73  	}
    74  }
    75  
    76  func TestNetworkContextWrite(t *testing.T) {
    77  	cases := []struct {
    78  		context  formatter.Context
    79  		expected string
    80  	}{
    81  		// Errors
    82  		{
    83  			formatter.Context{Format: "{{InvalidFunction}}"},
    84  			`template parsing error: template: :1: function "InvalidFunction" not defined`,
    85  		},
    86  		{
    87  			formatter.Context{Format: "{{nil}}"},
    88  			`template parsing error: template: :1:2: executing "" at <nil>: nil is not a command`,
    89  		},
    90  		// Table format
    91  		{
    92  			formatter.Context{Format: NewFormat("table", false)},
    93  			`NETWORK ID   NAME         DRIVER    SCOPE
    94  networkID1   foobar_baz   foo       local
    95  networkID2   foobar_bar   bar       local
    96  `,
    97  		},
    98  		{
    99  			formatter.Context{Format: NewFormat("table", true)},
   100  			`networkID1
   101  networkID2
   102  `,
   103  		},
   104  		{
   105  			formatter.Context{Format: NewFormat("table {{.Name}}", false)},
   106  			`NAME
   107  foobar_baz
   108  foobar_bar
   109  `,
   110  		},
   111  		{
   112  			formatter.Context{Format: NewFormat("table {{.Name}}", true)},
   113  			`NAME
   114  foobar_baz
   115  foobar_bar
   116  `,
   117  		},
   118  		// Raw Format
   119  		{
   120  			formatter.Context{Format: NewFormat("raw", false)},
   121  			`network_id: networkID1
   122  name: foobar_baz
   123  driver: foo
   124  scope: local
   125  
   126  network_id: networkID2
   127  name: foobar_bar
   128  driver: bar
   129  scope: local
   130  
   131  `,
   132  		},
   133  		{
   134  			formatter.Context{Format: NewFormat("raw", true)},
   135  			`network_id: networkID1
   136  network_id: networkID2
   137  `,
   138  		},
   139  		// Custom Format
   140  		{
   141  			formatter.Context{Format: NewFormat("{{.Name}}", false)},
   142  			`foobar_baz
   143  foobar_bar
   144  `,
   145  		},
   146  		// Custom Format with CreatedAt
   147  		{
   148  			formatter.Context{Format: NewFormat("{{.Name}} {{.CreatedAt}}", false)},
   149  			`foobar_baz 2016-01-01 00:00:00 +0000 UTC
   150  foobar_bar 2017-01-01 00:00:00 +0000 UTC
   151  `,
   152  		},
   153  	}
   154  
   155  	timestamp1, _ := time.Parse("2006-01-02", "2016-01-01")
   156  	timestamp2, _ := time.Parse("2006-01-02", "2017-01-01")
   157  
   158  	networks := []types.NetworkResource{
   159  		{ID: "networkID1", Name: "foobar_baz", Driver: "foo", Scope: "local", Created: timestamp1},
   160  		{ID: "networkID2", Name: "foobar_bar", Driver: "bar", Scope: "local", Created: timestamp2},
   161  	}
   162  
   163  	for _, tc := range cases {
   164  		tc := tc
   165  		t.Run(string(tc.context.Format), func(t *testing.T) {
   166  			var out bytes.Buffer
   167  			tc.context.Output = &out
   168  			err := FormatWrite(tc.context, networks)
   169  			if err != nil {
   170  				assert.Error(t, err, tc.expected)
   171  			} else {
   172  				assert.Equal(t, out.String(), tc.expected)
   173  			}
   174  		})
   175  	}
   176  }
   177  
   178  func TestNetworkContextWriteJSON(t *testing.T) {
   179  	networks := []types.NetworkResource{
   180  		{ID: "networkID1", Name: "foobar_baz"},
   181  		{ID: "networkID2", Name: "foobar_bar"},
   182  	}
   183  	expectedJSONs := []map[string]any{
   184  		{"Driver": "", "ID": "networkID1", "IPv6": "false", "Internal": "false", "Labels": "", "Name": "foobar_baz", "Scope": "", "CreatedAt": "0001-01-01 00:00:00 +0000 UTC"},
   185  		{"Driver": "", "ID": "networkID2", "IPv6": "false", "Internal": "false", "Labels": "", "Name": "foobar_bar", "Scope": "", "CreatedAt": "0001-01-01 00:00:00 +0000 UTC"},
   186  	}
   187  
   188  	out := bytes.NewBufferString("")
   189  	err := FormatWrite(formatter.Context{Format: "{{json .}}", Output: out}, networks)
   190  	if err != nil {
   191  		t.Fatal(err)
   192  	}
   193  	for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") {
   194  		msg := fmt.Sprintf("Output: line %d: %s", i, line)
   195  		var m map[string]any
   196  		err := json.Unmarshal([]byte(line), &m)
   197  		assert.NilError(t, err, msg)
   198  		assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg)
   199  	}
   200  }
   201  
   202  func TestNetworkContextWriteJSONField(t *testing.T) {
   203  	networks := []types.NetworkResource{
   204  		{ID: "networkID1", Name: "foobar_baz"},
   205  		{ID: "networkID2", Name: "foobar_bar"},
   206  	}
   207  	out := bytes.NewBufferString("")
   208  	err := FormatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, networks)
   209  	if err != nil {
   210  		t.Fatal(err)
   211  	}
   212  	for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") {
   213  		msg := fmt.Sprintf("Output: line %d: %s", i, line)
   214  		var s string
   215  		err := json.Unmarshal([]byte(line), &s)
   216  		assert.NilError(t, err, msg)
   217  		assert.Check(t, is.Equal(networks[i].ID, s), msg)
   218  	}
   219  }