github.com/containers/podman/v4@v4.9.4/pkg/specgen/generate/ports_test.go (about)

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