github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/formatter/volume_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 formatter 5 6 import ( 7 "bytes" 8 "encoding/json" 9 "fmt" 10 "strings" 11 "testing" 12 13 "github.com/docker/cli/internal/test" 14 "github.com/docker/docker/api/types/volume" 15 "github.com/docker/docker/pkg/stringid" 16 "gotest.tools/v3/assert" 17 is "gotest.tools/v3/assert/cmp" 18 ) 19 20 func TestVolumeContext(t *testing.T) { 21 volumeName := stringid.GenerateRandomID() 22 23 var ctx volumeContext 24 cases := []struct { 25 volumeCtx volumeContext 26 expValue string 27 call func() string 28 }{ 29 {volumeContext{ 30 v: volume.Volume{Name: volumeName}, 31 }, volumeName, ctx.Name}, 32 {volumeContext{ 33 v: volume.Volume{Driver: "driver_name"}, 34 }, "driver_name", ctx.Driver}, 35 {volumeContext{ 36 v: volume.Volume{Scope: "local"}, 37 }, "local", ctx.Scope}, 38 {volumeContext{ 39 v: volume.Volume{Mountpoint: "mountpoint"}, 40 }, "mountpoint", ctx.Mountpoint}, 41 {volumeContext{ 42 v: volume.Volume{}, 43 }, "", ctx.Labels}, 44 {volumeContext{ 45 v: volume.Volume{Labels: map[string]string{"label1": "value1", "label2": "value2"}}, 46 }, "label1=value1,label2=value2", ctx.Labels}, 47 } 48 49 for _, c := range cases { 50 ctx = c.volumeCtx 51 v := c.call() 52 if strings.Contains(v, ",") { 53 test.CompareMultipleValues(t, v, c.expValue) 54 } else if v != c.expValue { 55 t.Fatalf("Expected %s, was %s\n", c.expValue, v) 56 } 57 } 58 } 59 60 func TestVolumeContextWrite(t *testing.T) { 61 cases := []struct { 62 context Context 63 expected string 64 }{ 65 // Errors 66 { 67 Context{Format: "{{InvalidFunction}}"}, 68 `template parsing error: template: :1: function "InvalidFunction" not defined`, 69 }, 70 { 71 Context{Format: "{{nil}}"}, 72 `template parsing error: template: :1:2: executing "" at <nil>: nil is not a command`, 73 }, 74 // Table format 75 { 76 Context{Format: NewVolumeFormat("table", false)}, 77 `DRIVER VOLUME NAME 78 foo foobar_baz 79 bar foobar_bar 80 `, 81 }, 82 { 83 Context{Format: NewVolumeFormat("table", true)}, 84 `foobar_baz 85 foobar_bar 86 `, 87 }, 88 { 89 Context{Format: NewVolumeFormat("table {{.Name}}", false)}, 90 `VOLUME NAME 91 foobar_baz 92 foobar_bar 93 `, 94 }, 95 { 96 Context{Format: NewVolumeFormat("table {{.Name}}", true)}, 97 `VOLUME NAME 98 foobar_baz 99 foobar_bar 100 `, 101 }, 102 // Raw Format 103 { 104 Context{Format: NewVolumeFormat("raw", false)}, 105 `name: foobar_baz 106 driver: foo 107 108 name: foobar_bar 109 driver: bar 110 111 `, 112 }, 113 { 114 Context{Format: NewVolumeFormat("raw", true)}, 115 `name: foobar_baz 116 name: foobar_bar 117 `, 118 }, 119 // Custom Format 120 { 121 Context{Format: NewVolumeFormat("{{.Name}}", false)}, 122 `foobar_baz 123 foobar_bar 124 `, 125 }, 126 } 127 128 volumes := []*volume.Volume{ 129 {Name: "foobar_baz", Driver: "foo"}, 130 {Name: "foobar_bar", Driver: "bar"}, 131 } 132 133 for _, tc := range cases { 134 tc := tc 135 t.Run(string(tc.context.Format), func(t *testing.T) { 136 var out bytes.Buffer 137 tc.context.Output = &out 138 err := VolumeWrite(tc.context, volumes) 139 if err != nil { 140 assert.Error(t, err, tc.expected) 141 } else { 142 assert.Equal(t, out.String(), tc.expected) 143 } 144 }) 145 } 146 } 147 148 func TestVolumeContextWriteJSON(t *testing.T) { 149 volumes := []*volume.Volume{ 150 {Driver: "foo", Name: "foobar_baz"}, 151 {Driver: "bar", Name: "foobar_bar"}, 152 } 153 expectedJSONs := []map[string]any{ 154 {"Availability": "N/A", "Driver": "foo", "Group": "N/A", "Labels": "", "Links": "N/A", "Mountpoint": "", "Name": "foobar_baz", "Scope": "", "Size": "N/A", "Status": "N/A"}, 155 {"Availability": "N/A", "Driver": "bar", "Group": "N/A", "Labels": "", "Links": "N/A", "Mountpoint": "", "Name": "foobar_bar", "Scope": "", "Size": "N/A", "Status": "N/A"}, 156 } 157 out := bytes.NewBufferString("") 158 err := VolumeWrite(Context{Format: "{{json .}}", Output: out}, volumes) 159 if err != nil { 160 t.Fatal(err) 161 } 162 for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { 163 msg := fmt.Sprintf("Output: line %d: %s", i, line) 164 var m map[string]any 165 err := json.Unmarshal([]byte(line), &m) 166 assert.NilError(t, err, msg) 167 assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg) 168 } 169 } 170 171 func TestVolumeContextWriteJSONField(t *testing.T) { 172 volumes := []*volume.Volume{ 173 {Driver: "foo", Name: "foobar_baz"}, 174 {Driver: "bar", Name: "foobar_bar"}, 175 } 176 out := bytes.NewBufferString("") 177 err := VolumeWrite(Context{Format: "{{json .Name}}", Output: out}, volumes) 178 if err != nil { 179 t.Fatal(err) 180 } 181 for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { 182 msg := fmt.Sprintf("Output: line %d: %s", i, line) 183 var s string 184 err := json.Unmarshal([]byte(line), &s) 185 assert.NilError(t, err, msg) 186 assert.Check(t, is.Equal(volumes[i].Name, s), msg) 187 } 188 }