DockerCLI/opts/port_test.go

298 lines
6.3 KiB
Go

package opts
import (
"testing"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestPortOptValidSimpleSyntax(t *testing.T) {
testCases := []struct {
value string
expected []swarm.PortConfig
}{
{
value: "80",
expected: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 80,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "80:8080",
expected: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 8080,
PublishedPort: 80,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "8080:80/tcp",
expected: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 80,
PublishedPort: 8080,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "80:8080/udp",
expected: []swarm.PortConfig{
{
Protocol: "udp",
TargetPort: 8080,
PublishedPort: 80,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "80-81:8080-8081/tcp",
expected: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 8080,
PublishedPort: 80,
PublishMode: swarm.PortConfigPublishModeIngress,
},
{
Protocol: "tcp",
TargetPort: 8081,
PublishedPort: 81,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "80-82:8080-8082/udp",
expected: []swarm.PortConfig{
{
Protocol: "udp",
TargetPort: 8080,
PublishedPort: 80,
PublishMode: swarm.PortConfigPublishModeIngress,
},
{
Protocol: "udp",
TargetPort: 8081,
PublishedPort: 81,
PublishMode: swarm.PortConfigPublishModeIngress,
},
{
Protocol: "udp",
TargetPort: 8082,
PublishedPort: 82,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
}
for _, tc := range testCases {
var port PortOpt
assert.Check(t, port.Set(tc.value))
assert.Check(t, is.Len(port.Value(), len(tc.expected)))
for _, expectedPortConfig := range tc.expected {
assertContains(t, port.Value(), expectedPortConfig)
}
}
}
func TestPortOptValidComplexSyntax(t *testing.T) {
testCases := []struct {
value string
expected []swarm.PortConfig
}{
{
value: "target=80",
expected: []swarm.PortConfig{
{
TargetPort: 80,
Protocol: "tcp",
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "target=80,protocol=tcp",
expected: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 80,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "target=80,published=8080,protocol=tcp",
expected: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 80,
PublishedPort: 8080,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "published=80,target=8080,protocol=tcp",
expected: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 8080,
PublishedPort: 80,
PublishMode: swarm.PortConfigPublishModeIngress,
},
},
},
{
value: "target=80,published=8080,protocol=tcp,mode=host",
expected: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 80,
PublishedPort: 8080,
PublishMode: "host",
},
},
},
{
value: "target=80,published=8080,mode=host",
expected: []swarm.PortConfig{
{
TargetPort: 80,
PublishedPort: 8080,
PublishMode: "host",
Protocol: "tcp",
},
},
},
{
value: "target=80,published=8080,mode=ingress",
expected: []swarm.PortConfig{
{
TargetPort: 80,
PublishedPort: 8080,
PublishMode: "ingress",
Protocol: "tcp",
},
},
},
}
for _, tc := range testCases {
var port PortOpt
assert.Check(t, port.Set(tc.value))
assert.Check(t, is.Len(port.Value(), len(tc.expected)))
for _, expectedPortConfig := range tc.expected {
assertContains(t, port.Value(), expectedPortConfig)
}
}
}
func TestPortOptInvalidComplexSyntax(t *testing.T) {
testCases := []struct {
value string
expectedError string
}{
{
value: "invalid,target=80",
expectedError: "invalid field",
},
{
value: "invalid=field",
expectedError: "invalid field",
},
{
value: "protocol=invalid",
expectedError: "invalid protocol value",
},
{
value: "target=invalid",
expectedError: "invalid syntax",
},
{
value: "published=invalid",
expectedError: "invalid syntax",
},
{
value: "mode=invalid",
expectedError: "invalid publish mode value",
},
{
value: "published=8080,protocol=tcp,mode=ingress",
expectedError: "missing mandatory field",
},
{
value: `target=80,protocol="tcp,mode=ingress"`,
expectedError: "non-quoted-field",
},
{
value: `target=80,"protocol=tcp,mode=ingress"`,
expectedError: "invalid protocol value",
},
}
for _, tc := range testCases {
var port PortOpt
testutil.ErrorContains(t, port.Set(tc.value), tc.expectedError)
}
}
func TestPortOptInvalidSimpleSyntax(t *testing.T) {
testCases := []struct {
value string
expectedError string
}{
{
value: "9999999",
expectedError: "Invalid containerPort: 9999999",
},
{
value: "80/xyz",
expectedError: "Invalid proto: xyz",
},
{
value: "tcp",
expectedError: "Invalid containerPort: tcp",
},
{
value: "udp",
expectedError: "Invalid containerPort: udp",
},
{
value: "",
expectedError: "No port specified: <empty>",
},
{
value: "1.1.1.1:80:80",
expectedError: "hostip is not supported",
},
}
for _, tc := range testCases {
var port PortOpt
assert.Check(t, is.Error(port.Set(tc.value), tc.expectedError))
}
}
func assertContains(t *testing.T, portConfigs []swarm.PortConfig, expected swarm.PortConfig) {
var contains = false
for _, portConfig := range portConfigs {
if portConfig == expected {
contains = true
break
}
}
if !contains {
t.Errorf("expected %v to contain %v, did not", portConfigs, expected)
}
}