github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/specgen/generate/ports_test.go (about)

     1  package generate
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/containers/common/libnetwork/types"
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  func TestParsePortMappingWithHostPort(t *testing.T) {
    11  	tests := []struct {
    12  		name string
    13  		arg  []types.PortMapping
    14  		arg2 map[uint16][]string
    15  		want []types.PortMapping
    16  	}{
    17  		{
    18  			name: "no ports",
    19  			arg:  nil,
    20  			want: nil,
    21  		},
    22  		{
    23  			name: "one tcp port",
    24  			arg: []types.PortMapping{
    25  				{
    26  					HostPort:      8080,
    27  					ContainerPort: 80,
    28  					Protocol:      "tcp",
    29  				},
    30  			},
    31  			want: []types.PortMapping{
    32  				{
    33  					HostPort:      8080,
    34  					ContainerPort: 80,
    35  					Protocol:      "tcp",
    36  					Range:         1,
    37  				},
    38  			},
    39  		},
    40  		{
    41  			name: "one tcp port no proto",
    42  			arg: []types.PortMapping{
    43  				{
    44  					HostPort:      8080,
    45  					ContainerPort: 80,
    46  				},
    47  			},
    48  			want: []types.PortMapping{
    49  				{
    50  					HostPort:      8080,
    51  					ContainerPort: 80,
    52  					Protocol:      "tcp",
    53  					Range:         1,
    54  				},
    55  			},
    56  		},
    57  		{
    58  			name: "one udp port",
    59  			arg: []types.PortMapping{
    60  				{
    61  					HostPort:      8080,
    62  					ContainerPort: 80,
    63  					Protocol:      "udp",
    64  				},
    65  			},
    66  			want: []types.PortMapping{
    67  				{
    68  					HostPort:      8080,
    69  					ContainerPort: 80,
    70  					Protocol:      "udp",
    71  					Range:         1,
    72  				},
    73  			},
    74  		},
    75  		{
    76  			name: "one sctp port",
    77  			arg: []types.PortMapping{
    78  				{
    79  					HostPort:      8080,
    80  					ContainerPort: 80,
    81  					Protocol:      "sctp",
    82  				},
    83  			},
    84  			want: []types.PortMapping{
    85  				{
    86  					HostPort:      8080,
    87  					ContainerPort: 80,
    88  					Protocol:      "sctp",
    89  					Range:         1,
    90  				},
    91  			},
    92  		},
    93  		{
    94  			name: "one port two protocols",
    95  			arg: []types.PortMapping{
    96  				{
    97  					HostPort:      8080,
    98  					ContainerPort: 80,
    99  					Protocol:      "tcp,udp",
   100  				},
   101  			},
   102  			want: []types.PortMapping{
   103  				{
   104  					HostPort:      8080,
   105  					ContainerPort: 80,
   106  					Protocol:      "tcp",
   107  					Range:         1,
   108  				},
   109  				{
   110  					HostPort:      8080,
   111  					ContainerPort: 80,
   112  					Protocol:      "udp",
   113  					Range:         1,
   114  				},
   115  			},
   116  		},
   117  		{
   118  			name: "one port three protocols",
   119  			arg: []types.PortMapping{
   120  				{
   121  					HostPort:      8080,
   122  					ContainerPort: 80,
   123  					Protocol:      "tcp,udp,sctp",
   124  				},
   125  			},
   126  			want: []types.PortMapping{
   127  				{
   128  					HostPort:      8080,
   129  					ContainerPort: 80,
   130  					Protocol:      "tcp",
   131  					Range:         1,
   132  				},
   133  				{
   134  					HostPort:      8080,
   135  					ContainerPort: 80,
   136  					Protocol:      "udp",
   137  					Range:         1,
   138  				},
   139  				{
   140  					HostPort:      8080,
   141  					ContainerPort: 80,
   142  					Protocol:      "sctp",
   143  					Range:         1,
   144  				},
   145  			},
   146  		},
   147  		{
   148  			name: "one port with range 1",
   149  			arg: []types.PortMapping{
   150  				{
   151  					HostPort:      8080,
   152  					ContainerPort: 80,
   153  					Protocol:      "tcp",
   154  					Range:         1,
   155  				},
   156  			},
   157  			want: []types.PortMapping{
   158  				{
   159  					HostPort:      8080,
   160  					ContainerPort: 80,
   161  					Protocol:      "tcp",
   162  					Range:         1,
   163  				},
   164  			},
   165  		},
   166  		{
   167  			name: "one port with range 5",
   168  			arg: []types.PortMapping{
   169  				{
   170  					HostPort:      8080,
   171  					ContainerPort: 80,
   172  					Protocol:      "tcp",
   173  					Range:         5,
   174  				},
   175  			},
   176  			want: []types.PortMapping{
   177  				{
   178  					HostPort:      8080,
   179  					ContainerPort: 80,
   180  					Protocol:      "tcp",
   181  					Range:         5,
   182  				},
   183  			},
   184  		},
   185  		{
   186  			name: "two ports joined",
   187  			arg: []types.PortMapping{
   188  				{
   189  					HostPort:      8080,
   190  					ContainerPort: 80,
   191  					Protocol:      "tcp",
   192  				},
   193  				{
   194  					HostPort:      8081,
   195  					ContainerPort: 81,
   196  					Protocol:      "tcp",
   197  				},
   198  			},
   199  			want: []types.PortMapping{
   200  				{
   201  					HostPort:      8080,
   202  					ContainerPort: 80,
   203  					Protocol:      "tcp",
   204  					Range:         2,
   205  				},
   206  			},
   207  		},
   208  		{
   209  			name: "two ports joined with range",
   210  			arg: []types.PortMapping{
   211  				{
   212  					HostPort:      8080,
   213  					ContainerPort: 80,
   214  					Protocol:      "tcp",
   215  					Range:         2,
   216  				},
   217  				{
   218  					HostPort:      8081,
   219  					ContainerPort: 81,
   220  					Protocol:      "tcp",
   221  				},
   222  			},
   223  			want: []types.PortMapping{
   224  				{
   225  					HostPort:      8080,
   226  					ContainerPort: 80,
   227  					Protocol:      "tcp",
   228  					Range:         2,
   229  				},
   230  			},
   231  		},
   232  		{
   233  			name: "two ports with no overlapping range",
   234  			arg: []types.PortMapping{
   235  				{
   236  					HostPort:      8080,
   237  					ContainerPort: 80,
   238  					Protocol:      "tcp",
   239  					Range:         10,
   240  				},
   241  				{
   242  					HostPort:      9090,
   243  					ContainerPort: 9090,
   244  					Protocol:      "tcp",
   245  				},
   246  			},
   247  			want: []types.PortMapping{
   248  				{
   249  					HostPort:      9090,
   250  					ContainerPort: 9090,
   251  					Protocol:      "tcp",
   252  					Range:         1,
   253  				},
   254  				{
   255  					HostPort:      8080,
   256  					ContainerPort: 80,
   257  					Protocol:      "tcp",
   258  					Range:         10,
   259  				},
   260  			},
   261  		},
   262  		{
   263  			name: "four ports with two overlapping ranges",
   264  			arg: []types.PortMapping{
   265  				{
   266  					HostPort:      8080,
   267  					ContainerPort: 80,
   268  					Protocol:      "tcp",
   269  					Range:         10,
   270  				},
   271  				{
   272  					HostPort:      8085,
   273  					ContainerPort: 85,
   274  					Protocol:      "tcp",
   275  					Range:         10,
   276  				},
   277  				{
   278  					HostPort:      100,
   279  					ContainerPort: 5,
   280  					Protocol:      "tcp",
   281  				},
   282  				{
   283  					HostPort:      101,
   284  					ContainerPort: 6,
   285  					Protocol:      "tcp",
   286  				},
   287  			},
   288  			want: []types.PortMapping{
   289  				{
   290  					HostPort:      8080,
   291  					ContainerPort: 80,
   292  					Protocol:      "tcp",
   293  					Range:         15,
   294  				},
   295  				{
   296  					HostPort:      100,
   297  					ContainerPort: 5,
   298  					Protocol:      "tcp",
   299  					Range:         2,
   300  				},
   301  			},
   302  		},
   303  		{
   304  			name: "two overlapping ranges",
   305  			arg: []types.PortMapping{
   306  				{
   307  					HostPort:      8080,
   308  					ContainerPort: 80,
   309  					Protocol:      "tcp",
   310  					Range:         10,
   311  				},
   312  				{
   313  					HostPort:      8085,
   314  					ContainerPort: 85,
   315  					Protocol:      "tcp",
   316  					Range:         2,
   317  				},
   318  			},
   319  			want: []types.PortMapping{
   320  				{
   321  					HostPort:      8080,
   322  					ContainerPort: 80,
   323  					Protocol:      "tcp",
   324  					Range:         10,
   325  				},
   326  			},
   327  		},
   328  		{
   329  			name: "four overlapping ranges",
   330  			arg: []types.PortMapping{
   331  				{
   332  					HostPort:      8080,
   333  					ContainerPort: 80,
   334  					Protocol:      "tcp",
   335  					Range:         10,
   336  				},
   337  				{
   338  					HostPort:      8085,
   339  					ContainerPort: 85,
   340  					Protocol:      "tcp",
   341  					Range:         2,
   342  				},
   343  				{
   344  					HostPort:      8090,
   345  					ContainerPort: 90,
   346  					Protocol:      "tcp",
   347  					Range:         7,
   348  				},
   349  				{
   350  					HostPort:      8095,
   351  					ContainerPort: 95,
   352  					Protocol:      "tcp",
   353  				},
   354  			},
   355  			want: []types.PortMapping{
   356  				{
   357  					HostPort:      8080,
   358  					ContainerPort: 80,
   359  					Protocol:      "tcp",
   360  					Range:         17,
   361  				},
   362  			},
   363  		},
   364  		{
   365  			name: "one port range overlaps 5 ports",
   366  			arg: []types.PortMapping{
   367  				{
   368  					HostPort:      8080,
   369  					ContainerPort: 80,
   370  					Range:         20,
   371  				},
   372  				{
   373  					HostPort:      8085,
   374  					ContainerPort: 85,
   375  					Range:         2,
   376  				},
   377  				{
   378  					HostPort:      8090,
   379  					ContainerPort: 90,
   380  				},
   381  				{
   382  					HostPort:      8095,
   383  					ContainerPort: 95,
   384  				},
   385  				{
   386  					HostPort:      8096,
   387  					ContainerPort: 96,
   388  				},
   389  			},
   390  			want: []types.PortMapping{
   391  				{
   392  					HostPort:      8080,
   393  					ContainerPort: 80,
   394  					Protocol:      "tcp",
   395  					Range:         20,
   396  				},
   397  			},
   398  		},
   399  		{
   400  			name: "different host ip same port",
   401  			arg: []types.PortMapping{
   402  				{
   403  					HostPort:      8080,
   404  					ContainerPort: 80,
   405  					Protocol:      "tcp",
   406  					HostIP:        "192.168.1.1",
   407  				},
   408  				{
   409  					HostPort:      8080,
   410  					ContainerPort: 80,
   411  					Protocol:      "tcp",
   412  					HostIP:        "192.168.2.1",
   413  				},
   414  			},
   415  			want: []types.PortMapping{
   416  				{
   417  					HostPort:      8080,
   418  					ContainerPort: 80,
   419  					Protocol:      "tcp",
   420  					HostIP:        "192.168.1.1",
   421  					Range:         1,
   422  				},
   423  				{
   424  					HostPort:      8080,
   425  					ContainerPort: 80,
   426  					Protocol:      "tcp",
   427  					HostIP:        "192.168.2.1",
   428  					Range:         1,
   429  				},
   430  			},
   431  		},
   432  	}
   433  	for _, tt := range tests {
   434  		tt := tt
   435  		t.Run(tt.name, func(t *testing.T) {
   436  			got, err := ParsePortMapping(tt.arg, tt.arg2)
   437  			assert.NoError(t, err, "error is not nil")
   438  			// use ElementsMatch instead of Equal because the order is not consistent
   439  			assert.ElementsMatch(t, tt.want, got, "got unexpected port mapping")
   440  		})
   441  	}
   442  }
   443  
   444  func TestParsePortMappingWithoutHostPort(t *testing.T) {
   445  	tests := []struct {
   446  		name string
   447  		arg  []types.PortMapping
   448  		arg2 map[uint16][]string
   449  		want []types.PortMapping
   450  	}{
   451  		{
   452  			name: "one tcp port",
   453  			arg: []types.PortMapping{
   454  				{
   455  					HostPort:      0,
   456  					ContainerPort: 80,
   457  					Protocol:      "tcp",
   458  				},
   459  			},
   460  			want: []types.PortMapping{
   461  				{
   462  					HostPort:      0,
   463  					ContainerPort: 80,
   464  					Protocol:      "tcp",
   465  					Range:         1,
   466  				},
   467  			},
   468  		},
   469  		{
   470  			name: "one port with two protocols",
   471  			arg: []types.PortMapping{
   472  				{
   473  					HostPort:      0,
   474  					ContainerPort: 80,
   475  					Protocol:      "tcp,udp",
   476  				},
   477  			},
   478  			want: []types.PortMapping{
   479  				{
   480  					HostPort:      0,
   481  					ContainerPort: 80,
   482  					Protocol:      "tcp",
   483  					Range:         1,
   484  				},
   485  				{
   486  					HostPort:      0,
   487  					ContainerPort: 80,
   488  					Protocol:      "udp",
   489  					Range:         1,
   490  				},
   491  			},
   492  		},
   493  		{
   494  			name: "same port twice",
   495  			arg: []types.PortMapping{
   496  				{
   497  					HostPort:      0,
   498  					ContainerPort: 80,
   499  					Protocol:      "tcp",
   500  				},
   501  				{
   502  					HostPort:      0,
   503  					ContainerPort: 80,
   504  					Protocol:      "tcp",
   505  				},
   506  			},
   507  			want: []types.PortMapping{
   508  				{
   509  					HostPort:      0,
   510  					ContainerPort: 80,
   511  					Protocol:      "tcp",
   512  					Range:         1,
   513  				},
   514  			},
   515  		},
   516  		{
   517  			name: "neighbor ports are not joined",
   518  			arg: []types.PortMapping{
   519  				{
   520  					HostPort:      0,
   521  					ContainerPort: 80,
   522  					Protocol:      "tcp",
   523  				},
   524  				{
   525  					HostPort:      0,
   526  					ContainerPort: 81,
   527  					Protocol:      "tcp",
   528  				},
   529  			},
   530  			want: []types.PortMapping{
   531  				{
   532  					HostPort:      0,
   533  					ContainerPort: 80,
   534  					Protocol:      "tcp",
   535  					Range:         1,
   536  				},
   537  				{
   538  					HostPort:      0,
   539  					ContainerPort: 81,
   540  					Protocol:      "tcp",
   541  					Range:         1,
   542  				},
   543  			},
   544  		},
   545  		{
   546  			name: "overlapping range ports are joined",
   547  			arg: []types.PortMapping{
   548  				{
   549  					HostPort:      0,
   550  					ContainerPort: 80,
   551  					Protocol:      "tcp",
   552  					Range:         2,
   553  				},
   554  				{
   555  					HostPort:      0,
   556  					ContainerPort: 81,
   557  					Protocol:      "tcp",
   558  				},
   559  			},
   560  			want: []types.PortMapping{
   561  				{
   562  					HostPort:      0,
   563  					ContainerPort: 80,
   564  					Protocol:      "tcp",
   565  					Range:         2,
   566  				},
   567  			},
   568  		},
   569  		{
   570  			name: "four overlapping range ports are joined",
   571  			arg: []types.PortMapping{
   572  				{
   573  					HostPort:      0,
   574  					ContainerPort: 80,
   575  					Protocol:      "tcp",
   576  					Range:         3,
   577  				},
   578  				{
   579  					HostPort:      0,
   580  					ContainerPort: 81,
   581  					Protocol:      "tcp",
   582  				},
   583  				{
   584  					HostPort:      0,
   585  					ContainerPort: 82,
   586  					Protocol:      "tcp",
   587  					Range:         10,
   588  				},
   589  				{
   590  					HostPort:      0,
   591  					ContainerPort: 90,
   592  					Protocol:      "tcp",
   593  					Range:         5,
   594  				},
   595  			},
   596  			want: []types.PortMapping{
   597  				{
   598  					HostPort:      0,
   599  					ContainerPort: 80,
   600  					Protocol:      "tcp",
   601  					Range:         15,
   602  				},
   603  			},
   604  		},
   605  		{
   606  			name: "expose one tcp port",
   607  			arg2: map[uint16][]string{
   608  				8080: {"tcp"},
   609  			},
   610  			want: []types.PortMapping{
   611  				{
   612  					HostPort:      0,
   613  					ContainerPort: 8080,
   614  					Protocol:      "tcp",
   615  					Range:         1,
   616  				},
   617  			},
   618  		},
   619  		{
   620  			name: "expose already defined port",
   621  			arg: []types.PortMapping{
   622  				{
   623  					HostPort:      0,
   624  					ContainerPort: 8080,
   625  					Protocol:      "tcp",
   626  				},
   627  			},
   628  			arg2: map[uint16][]string{
   629  				8080: {"tcp"},
   630  			},
   631  			want: []types.PortMapping{
   632  				{
   633  					HostPort:      0,
   634  					ContainerPort: 8080,
   635  					Protocol:      "tcp",
   636  					Range:         1,
   637  				},
   638  			},
   639  		},
   640  		{
   641  			name: "expose different proto",
   642  			arg: []types.PortMapping{
   643  				{
   644  					HostPort:      0,
   645  					ContainerPort: 8080,
   646  					Protocol:      "tcp",
   647  				},
   648  			},
   649  			arg2: map[uint16][]string{
   650  				8080: {"udp"},
   651  			},
   652  			want: []types.PortMapping{
   653  				{
   654  					HostPort:      0,
   655  					ContainerPort: 8080,
   656  					Protocol:      "tcp",
   657  					Range:         1,
   658  				},
   659  				{
   660  					HostPort:      0,
   661  					ContainerPort: 8080,
   662  					Protocol:      "udp",
   663  					Range:         1,
   664  				},
   665  			},
   666  		},
   667  	}
   668  	for _, tt := range tests {
   669  		tt := tt
   670  		t.Run(tt.name, func(t *testing.T) {
   671  			got, err := ParsePortMapping(tt.arg, tt.arg2)
   672  			assert.NoError(t, err, "error is not nil")
   673  
   674  			// because we always get random host ports when it is set to 0 we cannot check that exactly
   675  			// check if it is not 0 and set to to 0 afterwards
   676  			for i := range got {
   677  				assert.Greater(t, got[i].HostPort, uint16(0), "host port is zero")
   678  				got[i].HostPort = 0
   679  			}
   680  
   681  			// use ElementsMatch instead of Equal because the order is not consistent
   682  			assert.ElementsMatch(t, tt.want, got, "got unexpected port mapping")
   683  		})
   684  	}
   685  }
   686  
   687  func TestParsePortMappingMixedHostPort(t *testing.T) {
   688  	tests := []struct {
   689  		name           string
   690  		arg            []types.PortMapping
   691  		want           []types.PortMapping
   692  		resetHostPorts []int
   693  	}{
   694  		{
   695  			name: "two ports one without a hostport set",
   696  			arg: []types.PortMapping{
   697  				{
   698  					HostPort:      0,
   699  					ContainerPort: 80,
   700  				},
   701  				{
   702  					HostPort:      8080,
   703  					ContainerPort: 8080,
   704  				},
   705  			},
   706  			want: []types.PortMapping{
   707  				{
   708  					HostPort:      8080,
   709  					ContainerPort: 8080,
   710  					Protocol:      "tcp",
   711  					Range:         1,
   712  				},
   713  				{
   714  					HostPort:      0,
   715  					ContainerPort: 80,
   716  					Protocol:      "tcp",
   717  					Range:         1,
   718  				},
   719  			},
   720  			resetHostPorts: []int{1},
   721  		},
   722  		{
   723  			name: "two ports one without a hostport set, inverted order",
   724  			arg: []types.PortMapping{
   725  				{
   726  					HostPort:      8080,
   727  					ContainerPort: 8080,
   728  				},
   729  				{
   730  					HostPort:      0,
   731  					ContainerPort: 80,
   732  				},
   733  			},
   734  			want: []types.PortMapping{
   735  				{
   736  					HostPort:      8080,
   737  					ContainerPort: 8080,
   738  					Protocol:      "tcp",
   739  					Range:         1,
   740  				},
   741  				{
   742  					HostPort:      0,
   743  					ContainerPort: 80,
   744  					Protocol:      "tcp",
   745  					Range:         1,
   746  				},
   747  			},
   748  			resetHostPorts: []int{1},
   749  		},
   750  		{
   751  			name: "three ports without host ports, one with a hostport set, , inverted order",
   752  			arg: []types.PortMapping{
   753  				{
   754  					HostPort:      0,
   755  					ContainerPort: 80,
   756  				},
   757  				{
   758  					HostPort:      0,
   759  					ContainerPort: 85,
   760  				},
   761  				{
   762  					HostPort:      0,
   763  					ContainerPort: 90,
   764  				},
   765  				{
   766  					HostPort:      8080,
   767  					ContainerPort: 8080,
   768  				},
   769  			},
   770  			want: []types.PortMapping{
   771  				{
   772  					HostPort:      8080,
   773  					ContainerPort: 8080,
   774  					Protocol:      "tcp",
   775  					Range:         1,
   776  				},
   777  				{
   778  					HostPort:      0,
   779  					ContainerPort: 80,
   780  					Protocol:      "tcp",
   781  					Range:         1,
   782  				},
   783  				{
   784  					HostPort:      0,
   785  					ContainerPort: 85,
   786  					Protocol:      "tcp",
   787  					Range:         1,
   788  				},
   789  				{
   790  					HostPort:      0,
   791  					ContainerPort: 90,
   792  					Protocol:      "tcp",
   793  					Range:         1,
   794  				},
   795  			},
   796  			resetHostPorts: []int{1, 2, 3},
   797  		},
   798  		{
   799  			name: "three ports without host ports, one with a hostport set",
   800  			arg: []types.PortMapping{
   801  				{
   802  					HostPort:      8080,
   803  					ContainerPort: 8080,
   804  				},
   805  				{
   806  					HostPort:      0,
   807  					ContainerPort: 90,
   808  				},
   809  				{
   810  					HostPort:      0,
   811  					ContainerPort: 85,
   812  				},
   813  				{
   814  					HostPort:      0,
   815  					ContainerPort: 80,
   816  				},
   817  			},
   818  			want: []types.PortMapping{
   819  				{
   820  					HostPort:      8080,
   821  					ContainerPort: 8080,
   822  					Protocol:      "tcp",
   823  					Range:         1,
   824  				},
   825  				{
   826  					HostPort:      0,
   827  					ContainerPort: 80,
   828  					Protocol:      "tcp",
   829  					Range:         1,
   830  				},
   831  				{
   832  					HostPort:      0,
   833  					ContainerPort: 85,
   834  					Protocol:      "tcp",
   835  					Range:         1,
   836  				},
   837  				{
   838  					HostPort:      0,
   839  					ContainerPort: 90,
   840  					Protocol:      "tcp",
   841  					Range:         1,
   842  				},
   843  			},
   844  			resetHostPorts: []int{1, 2, 3},
   845  		},
   846  	}
   847  	for _, tt := range tests {
   848  		tt := tt
   849  		t.Run(tt.name, func(t *testing.T) {
   850  			got, err := ParsePortMapping(tt.arg, nil)
   851  			assert.NoError(t, err, "error is not nil")
   852  
   853  			// because we always get random host ports when it is set to 0 we cannot check that exactly
   854  			// use resetHostPorts to know which port element is 0
   855  			for _, num := range tt.resetHostPorts {
   856  				assert.Greater(t, got[num].HostPort, uint16(0), "host port is zero")
   857  				got[num].HostPort = 0
   858  			}
   859  
   860  			assert.Equal(t, tt.want, got, "got unexpected port mapping")
   861  		})
   862  	}
   863  }
   864  
   865  func TestParsePortMappingError(t *testing.T) {
   866  	tests := []struct {
   867  		name string
   868  		arg  []types.PortMapping
   869  		err  string
   870  	}{
   871  		{
   872  			name: "container port is 0",
   873  			arg: []types.PortMapping{
   874  				{
   875  					HostPort:      8080,
   876  					ContainerPort: 0,
   877  					Protocol:      "tcp",
   878  				},
   879  			},
   880  			err: "container port number must be non-0",
   881  		},
   882  		{
   883  			name: "container port range exceeds max",
   884  			arg: []types.PortMapping{
   885  				{
   886  					HostPort:      8080,
   887  					ContainerPort: 65000,
   888  					Protocol:      "tcp",
   889  					Range:         10000,
   890  				},
   891  			},
   892  			err: "container port range exceeds maximum allowable port number",
   893  		},
   894  		{
   895  			name: "host port range exceeds max",
   896  			arg: []types.PortMapping{
   897  				{
   898  					HostPort:      60000,
   899  					ContainerPort: 1,
   900  					Protocol:      "tcp",
   901  					Range:         10000,
   902  				},
   903  			},
   904  			err: "host port range exceeds maximum allowable port number",
   905  		},
   906  		{
   907  			name: "invalid protocol",
   908  			arg: []types.PortMapping{
   909  				{
   910  					HostPort:      8080,
   911  					ContainerPort: 80,
   912  					Protocol:      "1",
   913  				},
   914  			},
   915  			err: "unrecognized protocol \"1\" in port mapping",
   916  		},
   917  		{
   918  			name: "invalid protocol 2",
   919  			arg: []types.PortMapping{
   920  				{
   921  					HostPort:      8080,
   922  					ContainerPort: 80,
   923  					Protocol:      "udp,u",
   924  				},
   925  			},
   926  			err: "unrecognized protocol \"u\" in port mapping",
   927  		},
   928  		{
   929  			name: "invalid ip address",
   930  			arg: []types.PortMapping{
   931  				{
   932  					HostPort:      8080,
   933  					ContainerPort: 80,
   934  					HostIP:        "blah",
   935  				},
   936  			},
   937  			err: "invalid IP address \"blah\" in port mapping",
   938  		},
   939  		{
   940  			name: "invalid overalpping range",
   941  			arg: []types.PortMapping{
   942  				{
   943  					HostPort:      8080,
   944  					ContainerPort: 80,
   945  					Range:         5,
   946  				},
   947  				{
   948  					HostPort:      8081,
   949  					ContainerPort: 60,
   950  				},
   951  			},
   952  			err: "conflicting port mappings for host port 8081 (protocol tcp)",
   953  		},
   954  		{
   955  			name: "big port range with host port zero does not fit",
   956  			arg: []types.PortMapping{
   957  				{
   958  					HostPort:      0,
   959  					ContainerPort: 1,
   960  					Range:         65535,
   961  				},
   962  			},
   963  			err: "failed to find an open port to expose container port 1 with range 65535 on the host",
   964  		},
   965  		{
   966  			name: "big port range with host port zero does not fit",
   967  			arg: []types.PortMapping{
   968  				{
   969  					HostPort:      0,
   970  					ContainerPort: 80,
   971  					Range:         1,
   972  				},
   973  				{
   974  					HostPort:      0,
   975  					ContainerPort: 1000,
   976  					Range:         64535,
   977  				},
   978  			},
   979  			err: "failed to find an open port to expose container port 1000 with range 64535 on the host",
   980  		},
   981  	}
   982  	for _, tt := range tests {
   983  		tt := tt
   984  		t.Run(tt.name, func(t *testing.T) {
   985  			_, err := ParsePortMapping(tt.arg, nil)
   986  			assert.EqualError(t, err, tt.err, "error does not match")
   987  		})
   988  	}
   989  }