github.com/docker/docker-ce@v17.12.1-ce-rc2+incompatible/components/cli/opts/port_test.go (about)

     1  package opts
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/docker/cli/internal/test/testutil"
     7  	"github.com/docker/docker/api/types/swarm"
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  func TestPortOptValidSimpleSyntax(t *testing.T) {
    12  	testCases := []struct {
    13  		value    string
    14  		expected []swarm.PortConfig
    15  	}{
    16  		{
    17  			value: "80",
    18  			expected: []swarm.PortConfig{
    19  				{
    20  					Protocol:    "tcp",
    21  					TargetPort:  80,
    22  					PublishMode: swarm.PortConfigPublishModeIngress,
    23  				},
    24  			},
    25  		},
    26  		{
    27  			value: "80:8080",
    28  			expected: []swarm.PortConfig{
    29  				{
    30  					Protocol:      "tcp",
    31  					TargetPort:    8080,
    32  					PublishedPort: 80,
    33  					PublishMode:   swarm.PortConfigPublishModeIngress,
    34  				},
    35  			},
    36  		},
    37  		{
    38  			value: "8080:80/tcp",
    39  			expected: []swarm.PortConfig{
    40  				{
    41  					Protocol:      "tcp",
    42  					TargetPort:    80,
    43  					PublishedPort: 8080,
    44  					PublishMode:   swarm.PortConfigPublishModeIngress,
    45  				},
    46  			},
    47  		},
    48  		{
    49  			value: "80:8080/udp",
    50  			expected: []swarm.PortConfig{
    51  				{
    52  					Protocol:      "udp",
    53  					TargetPort:    8080,
    54  					PublishedPort: 80,
    55  					PublishMode:   swarm.PortConfigPublishModeIngress,
    56  				},
    57  			},
    58  		},
    59  		{
    60  			value: "80-81:8080-8081/tcp",
    61  			expected: []swarm.PortConfig{
    62  				{
    63  					Protocol:      "tcp",
    64  					TargetPort:    8080,
    65  					PublishedPort: 80,
    66  					PublishMode:   swarm.PortConfigPublishModeIngress,
    67  				},
    68  				{
    69  					Protocol:      "tcp",
    70  					TargetPort:    8081,
    71  					PublishedPort: 81,
    72  					PublishMode:   swarm.PortConfigPublishModeIngress,
    73  				},
    74  			},
    75  		},
    76  		{
    77  			value: "80-82:8080-8082/udp",
    78  			expected: []swarm.PortConfig{
    79  				{
    80  					Protocol:      "udp",
    81  					TargetPort:    8080,
    82  					PublishedPort: 80,
    83  					PublishMode:   swarm.PortConfigPublishModeIngress,
    84  				},
    85  				{
    86  					Protocol:      "udp",
    87  					TargetPort:    8081,
    88  					PublishedPort: 81,
    89  					PublishMode:   swarm.PortConfigPublishModeIngress,
    90  				},
    91  				{
    92  					Protocol:      "udp",
    93  					TargetPort:    8082,
    94  					PublishedPort: 82,
    95  					PublishMode:   swarm.PortConfigPublishModeIngress,
    96  				},
    97  			},
    98  		},
    99  	}
   100  	for _, tc := range testCases {
   101  		var port PortOpt
   102  		assert.NoError(t, port.Set(tc.value))
   103  		assert.Len(t, port.Value(), len(tc.expected))
   104  		for _, expectedPortConfig := range tc.expected {
   105  			assertContains(t, port.Value(), expectedPortConfig)
   106  		}
   107  	}
   108  }
   109  
   110  func TestPortOptValidComplexSyntax(t *testing.T) {
   111  	testCases := []struct {
   112  		value    string
   113  		expected []swarm.PortConfig
   114  	}{
   115  		{
   116  			value: "target=80",
   117  			expected: []swarm.PortConfig{
   118  				{
   119  					TargetPort:  80,
   120  					Protocol:    "tcp",
   121  					PublishMode: swarm.PortConfigPublishModeIngress,
   122  				},
   123  			},
   124  		},
   125  		{
   126  			value: "target=80,protocol=tcp",
   127  			expected: []swarm.PortConfig{
   128  				{
   129  					Protocol:    "tcp",
   130  					TargetPort:  80,
   131  					PublishMode: swarm.PortConfigPublishModeIngress,
   132  				},
   133  			},
   134  		},
   135  		{
   136  			value: "target=80,published=8080,protocol=tcp",
   137  			expected: []swarm.PortConfig{
   138  				{
   139  					Protocol:      "tcp",
   140  					TargetPort:    80,
   141  					PublishedPort: 8080,
   142  					PublishMode:   swarm.PortConfigPublishModeIngress,
   143  				},
   144  			},
   145  		},
   146  		{
   147  			value: "published=80,target=8080,protocol=tcp",
   148  			expected: []swarm.PortConfig{
   149  				{
   150  					Protocol:      "tcp",
   151  					TargetPort:    8080,
   152  					PublishedPort: 80,
   153  					PublishMode:   swarm.PortConfigPublishModeIngress,
   154  				},
   155  			},
   156  		},
   157  		{
   158  			value: "target=80,published=8080,protocol=tcp,mode=host",
   159  			expected: []swarm.PortConfig{
   160  				{
   161  					Protocol:      "tcp",
   162  					TargetPort:    80,
   163  					PublishedPort: 8080,
   164  					PublishMode:   "host",
   165  				},
   166  			},
   167  		},
   168  		{
   169  			value: "target=80,published=8080,mode=host",
   170  			expected: []swarm.PortConfig{
   171  				{
   172  					TargetPort:    80,
   173  					PublishedPort: 8080,
   174  					PublishMode:   "host",
   175  					Protocol:      "tcp",
   176  				},
   177  			},
   178  		},
   179  		{
   180  			value: "target=80,published=8080,mode=ingress",
   181  			expected: []swarm.PortConfig{
   182  				{
   183  					TargetPort:    80,
   184  					PublishedPort: 8080,
   185  					PublishMode:   "ingress",
   186  					Protocol:      "tcp",
   187  				},
   188  			},
   189  		},
   190  	}
   191  	for _, tc := range testCases {
   192  		var port PortOpt
   193  		assert.NoError(t, port.Set(tc.value))
   194  		assert.Len(t, port.Value(), len(tc.expected))
   195  		for _, expectedPortConfig := range tc.expected {
   196  			assertContains(t, port.Value(), expectedPortConfig)
   197  		}
   198  	}
   199  }
   200  
   201  func TestPortOptInvalidComplexSyntax(t *testing.T) {
   202  	testCases := []struct {
   203  		value         string
   204  		expectedError string
   205  	}{
   206  		{
   207  			value:         "invalid,target=80",
   208  			expectedError: "invalid field",
   209  		},
   210  		{
   211  			value:         "invalid=field",
   212  			expectedError: "invalid field",
   213  		},
   214  		{
   215  			value:         "protocol=invalid",
   216  			expectedError: "invalid protocol value",
   217  		},
   218  		{
   219  			value:         "target=invalid",
   220  			expectedError: "invalid syntax",
   221  		},
   222  		{
   223  			value:         "published=invalid",
   224  			expectedError: "invalid syntax",
   225  		},
   226  		{
   227  			value:         "mode=invalid",
   228  			expectedError: "invalid publish mode value",
   229  		},
   230  		{
   231  			value:         "published=8080,protocol=tcp,mode=ingress",
   232  			expectedError: "missing mandatory field",
   233  		},
   234  		{
   235  			value:         `target=80,protocol="tcp,mode=ingress"`,
   236  			expectedError: "non-quoted-field",
   237  		},
   238  		{
   239  			value:         `target=80,"protocol=tcp,mode=ingress"`,
   240  			expectedError: "invalid protocol value",
   241  		},
   242  	}
   243  	for _, tc := range testCases {
   244  		var port PortOpt
   245  		testutil.ErrorContains(t, port.Set(tc.value), tc.expectedError)
   246  	}
   247  }
   248  
   249  func TestPortOptInvalidSimpleSyntax(t *testing.T) {
   250  	testCases := []struct {
   251  		value         string
   252  		expectedError string
   253  	}{
   254  		{
   255  			value:         "9999999",
   256  			expectedError: "Invalid containerPort: 9999999",
   257  		},
   258  		{
   259  			value:         "80/xyz",
   260  			expectedError: "Invalid proto: xyz",
   261  		},
   262  		{
   263  			value:         "tcp",
   264  			expectedError: "Invalid containerPort: tcp",
   265  		},
   266  		{
   267  			value:         "udp",
   268  			expectedError: "Invalid containerPort: udp",
   269  		},
   270  		{
   271  			value:         "",
   272  			expectedError: "No port specified: <empty>",
   273  		},
   274  		{
   275  			value:         "1.1.1.1:80:80",
   276  			expectedError: "hostip is not supported",
   277  		},
   278  	}
   279  	for _, tc := range testCases {
   280  		var port PortOpt
   281  		assert.EqualError(t, port.Set(tc.value), tc.expectedError)
   282  	}
   283  }
   284  
   285  func assertContains(t *testing.T, portConfigs []swarm.PortConfig, expected swarm.PortConfig) {
   286  	var contains = false
   287  	for _, portConfig := range portConfigs {
   288  		if portConfig == expected {
   289  			contains = true
   290  			break
   291  		}
   292  	}
   293  	if !contains {
   294  		t.Errorf("expected %v to contain %v, did not", portConfigs, expected)
   295  	}
   296  }