...

Source file src/github.com/redhat-developer/odo/pkg/port/port_test.go

Documentation: github.com/redhat-developer/odo/pkg/port

     1  package port
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/golang/mock/gomock"
    11  	"github.com/google/go-cmp/cmp"
    12  
    13  	"github.com/redhat-developer/odo/pkg/api"
    14  	"github.com/redhat-developer/odo/pkg/exec"
    15  	"github.com/redhat-developer/odo/pkg/remotecmd"
    16  )
    17  
    18  const (
    19  	podName       = "my-pod"
    20  	containerName = "my-container"
    21  )
    22  
    23  var cmd = []string{
    24  	remotecmd.ShellExecutable, "-c",
    25  	"cat /proc/net/tcp /proc/net/udp /proc/net/tcp6 /proc/net/udp6 || true",
    26  }
    27  
    28  const aggregatedContentFromProcNetFiles = `
    29  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
    30  0: 0100007F:4E21 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 2798686 1 0000000000000000 100 0 0 10 0
    31  1: 690A0A0A:192B 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 24399 1 0000000000000000 100 0 0 10 0
    32  2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 28227 1 0000000000000000 100 0 0 10 0
    33  6: 00000000:14EB 00000000:0000 0A 00000000:00000000 00:00000000 00000000   193        0 18937 1 0000000000000000 100 0 0 10 5
    34  10: 690A0A0A:A0B6 85B2FA8E:01BB 06 00000000:00000000 03:00000C93 00000000     0        0 0 3 0000000000000000
    35  11: 690A0A0A:DC86 6E882E34:01BB 01 00000000:00000000 02:00000418 00000000  1000        0 5992580 2 0000000000000000 29 4 30 10 -1
    36  invalid_state: 690A0A0A:DC86 6E882E34:01BB ZZZ 00000000:00000000 02:00000418 00000000  1000        0 5992580 2 0000000000000000 29 4 30 10 -1
    37  invalid_local_port: 690A0A0A:WXYZ 6E882E34:01BB 0A 00000000:00000000 02:00000418 00000000  1000        0 5992580 2 0000000000000000 29 4 30 10 -1
    38  
    39  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops
    40  299: 690A0A0A:87BE EE4BFA8E:01BB 01 00000000:00000000 00:00000000 00000000  1000        0 5879134 2 0000000000000000 0
    41  3670: FB0000E0:14E9 00000000:0000 07 00000000:00000000 00:00000000 00000000  1000        0 5422041 2 0000000000000000 0
    42  invalid_local_addr: 000ZZ000:14E9 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 5422041 2 0000000000000000 0
    43  
    44  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
    45  0: 00000000000000000000000001000000:0277 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 30021 1 0000000000000000 100 0 0 10 0
    46  1: 0000000000000000FFFF00000100007F:F76E 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 383053 1 0000000000000000 100 0 0 10 0
    47  3: 00000000000000000000000000000000:1388 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 29332 1 0000000000000000 100 0 0 10 0
    48  too_long_local_addr 00000000000000000000000001000000123456789010:0277 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 30021 1 0000000000000000 100 0 0 10 0
    49  
    50  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops
    51  623: 00000000000000000000000000000000:8902 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000  1000        0 5976457 2 0000000000000000 0
    52  32077: 00000000000000000000000000000000:83E0 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000  1000        0 5915479 2 0000000000000000 0
    53  invalid_local_addr_port 0000000000000000000000000100000:0277:123 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 30021 1 0000000000000000 100 0 0 10 0
    54  
    55  `
    56  
    57  func TestDetectRemotePortsBoundOnLoopback(t *testing.T) {
    58  	inputPorts := []api.ForwardedPort{
    59  		{ContainerPort: 20001},
    60  		{ContainerPort: 6443},
    61  		{ContainerPort: 22},
    62  		{ContainerPort: 5355},
    63  		{ContainerPort: 631},
    64  		{ContainerPort: 63342},
    65  		{ContainerPort: 5000},
    66  		{ContainerPort: 8080},
    67  		{ContainerPort: 5858},
    68  	}
    69  	type args struct {
    70  		execClientCustomizer func(client *exec.MockClient)
    71  		podName              string
    72  		containerName        string
    73  		ports                []api.ForwardedPort
    74  	}
    75  	tests := []struct {
    76  		name    string
    77  		args    args
    78  		want    []api.ForwardedPort
    79  		wantErr bool
    80  	}{
    81  		{
    82  			name: "error while executing command",
    83  			args: args{
    84  				execClientCustomizer: func(client *exec.MockClient) {
    85  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
    86  						Return(nil, nil, errors.New("some-err"))
    87  				},
    88  				podName:       podName,
    89  				containerName: containerName,
    90  				ports:         inputPorts,
    91  			},
    92  			wantErr: true,
    93  		},
    94  		{
    95  			name: "no active connections",
    96  			args: args{
    97  				execClientCustomizer: func(client *exec.MockClient) {
    98  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
    99  						Return(strings.Split(`
   100  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   101  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops
   102  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   103  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops
   104  `, "\n"), nil, nil)
   105  				},
   106  				podName:       podName,
   107  				containerName: containerName,
   108  				ports:         inputPorts,
   109  			},
   110  			wantErr: false,
   111  			want:    nil,
   112  		},
   113  		{
   114  			name: "no input ports",
   115  			args: args{
   116  				execClientCustomizer: func(client *exec.MockClient) {
   117  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   118  						Times(0)
   119  				},
   120  				podName:       podName,
   121  				containerName: containerName,
   122  				ports:         nil,
   123  			},
   124  			wantErr: false,
   125  			want:    nil,
   126  		},
   127  		{
   128  			name: "with different connections",
   129  			args: args{
   130  				execClientCustomizer: func(client *exec.MockClient) {
   131  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   132  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil)
   133  				},
   134  				podName:       podName,
   135  				containerName: containerName,
   136  				ports:         inputPorts,
   137  			},
   138  			wantErr: false,
   139  			want: []api.ForwardedPort{
   140  				{ContainerPort: 20001},
   141  				{ContainerPort: 631},
   142  				{ContainerPort: 63342},
   143  			},
   144  		},
   145  	}
   146  	for _, tt := range tests {
   147  		t.Run(tt.name, func(t *testing.T) {
   148  			ctrl := gomock.NewController(t)
   149  			execClient := exec.NewMockClient(ctrl)
   150  			tt.args.execClientCustomizer(execClient)
   151  
   152  			got, err := DetectRemotePortsBoundOnLoopback(context.Background(), execClient, tt.args.podName, tt.args.containerName, tt.args.ports)
   153  			if (err != nil) != tt.wantErr {
   154  				t.Errorf("detectRemotePortsBoundOnLoopback() error = %v, wantErr %v", err, tt.wantErr)
   155  				return
   156  			}
   157  			if diff := cmp.Diff(tt.want, got); diff != "" {
   158  				t.Errorf("detectRemotePortsBoundOnLoopback() mismatch (-want +got):\n%s", diff)
   159  			}
   160  		})
   161  	}
   162  }
   163  
   164  func TestGetListeningConnections(t *testing.T) {
   165  	type args struct {
   166  		execClientCustomizer func(client *exec.MockClient)
   167  		podName              string
   168  		containerName        string
   169  	}
   170  	tests := []struct {
   171  		name    string
   172  		args    args
   173  		want    []Connection
   174  		wantErr bool
   175  	}{
   176  		{
   177  			name: "error while executing command",
   178  			args: args{
   179  				execClientCustomizer: func(client *exec.MockClient) {
   180  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   181  						Return(nil, nil, errors.New("some-err"))
   182  				},
   183  				podName:       podName,
   184  				containerName: containerName,
   185  			},
   186  			wantErr: true,
   187  		},
   188  		{
   189  			name: "no active connections",
   190  			args: args{
   191  				execClientCustomizer: func(client *exec.MockClient) {
   192  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   193  						Return(strings.Split(`
   194  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   195  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops
   196  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   197  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops
   198  `, "\n"), nil, nil)
   199  				},
   200  				podName:       podName,
   201  				containerName: containerName,
   202  			},
   203  			wantErr: false,
   204  			want:    nil,
   205  		},
   206  		{
   207  			name: "with different connections",
   208  			args: args{
   209  				execClientCustomizer: func(client *exec.MockClient) {
   210  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   211  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil)
   212  				},
   213  				podName:       podName,
   214  				containerName: containerName,
   215  			},
   216  			wantErr: false,
   217  			want: []Connection{
   218  				{LocalAddress: "127.0.0.1", LocalPort: 20001, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "LISTEN"},
   219  				{LocalAddress: "10.10.10.105", LocalPort: 6443, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "LISTEN"},
   220  				{LocalAddress: "0.0.0.0", LocalPort: 22, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "LISTEN"},
   221  				{LocalAddress: "0.0.0.0", LocalPort: 5355, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "LISTEN"},
   222  				{
   223  					LocalAddress:  "0000:0000:0000:0000:0000:0000:0000:0001",
   224  					LocalPort:     631,
   225  					RemoteAddress: "0000:0000:0000:0000:0000:0000:0000:0000",
   226  					RemotePort:    0,
   227  					State:         "LISTEN",
   228  				},
   229  				{
   230  					LocalAddress:  "0000:0000:0000:0000:0000:FFFF:7F00:0001",
   231  					LocalPort:     63342,
   232  					RemoteAddress: "0000:0000:0000:0000:0000:0000:0000:0000",
   233  					RemotePort:    0,
   234  					State:         "LISTEN",
   235  				},
   236  				{
   237  					LocalAddress:  "0000:0000:0000:0000:0000:0000:0000:0000",
   238  					LocalPort:     5000,
   239  					RemoteAddress: "0000:0000:0000:0000:0000:0000:0000:0000",
   240  					RemotePort:    0,
   241  					State:         "LISTEN",
   242  				},
   243  			},
   244  		},
   245  	}
   246  	for _, tt := range tests {
   247  		t.Run(tt.name, func(t *testing.T) {
   248  			ctrl := gomock.NewController(t)
   249  			execClient := exec.NewMockClient(ctrl)
   250  			tt.args.execClientCustomizer(execClient)
   251  
   252  			got, err := GetListeningConnections(context.Background(), execClient, tt.args.podName, tt.args.containerName)
   253  			if (err != nil) != tt.wantErr {
   254  				t.Errorf("getListeningConnections() error = %v, wantErr %v", err, tt.wantErr)
   255  				return
   256  			}
   257  			if diff := cmp.Diff(tt.want, got); diff != "" {
   258  				t.Errorf("getListeningConnections() mismatch (-want +got):\n%s", diff)
   259  			}
   260  		})
   261  	}
   262  }
   263  
   264  func TestGetConnections(t *testing.T) {
   265  	type args struct {
   266  		execClientCustomizer func(client *exec.MockClient)
   267  		podName              string
   268  		containerName        string
   269  		statePredicate       func(state int) bool
   270  	}
   271  	tests := []struct {
   272  		name    string
   273  		args    args
   274  		want    []Connection
   275  		wantErr bool
   276  	}{
   277  		{
   278  			name: "error while executing command",
   279  			args: args{
   280  				execClientCustomizer: func(client *exec.MockClient) {
   281  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   282  						Return(nil, nil, errors.New("some-err"))
   283  				},
   284  				podName:       podName,
   285  				containerName: containerName,
   286  			},
   287  			wantErr: true,
   288  		},
   289  		{
   290  			name: "no active connections",
   291  			args: args{
   292  				execClientCustomizer: func(client *exec.MockClient) {
   293  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   294  						Return(strings.Split(`
   295  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   296  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops
   297  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   298  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops
   299  `, "\n"), nil, nil)
   300  				},
   301  				podName:       podName,
   302  				containerName: containerName,
   303  			},
   304  			wantErr: false,
   305  			want:    nil,
   306  		},
   307  		{
   308  			name: "non-matching filter on state",
   309  			args: args{
   310  				execClientCustomizer: func(client *exec.MockClient) {
   311  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   312  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil)
   313  				},
   314  				podName:       podName,
   315  				containerName: containerName,
   316  				statePredicate: func(state int) bool {
   317  					return stateToString(state) == "some unknown state"
   318  				},
   319  			},
   320  			wantErr: false,
   321  			want:    nil,
   322  		},
   323  		{
   324  			name: "filter on state: ESTABLISHED",
   325  			args: args{
   326  				execClientCustomizer: func(client *exec.MockClient) {
   327  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   328  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil)
   329  				},
   330  				podName:       podName,
   331  				containerName: containerName,
   332  				statePredicate: func(state int) bool {
   333  					return stateToString(state) == "ESTABLISHED"
   334  				},
   335  			},
   336  			wantErr: false,
   337  			want: []Connection{
   338  				{LocalAddress: "10.10.10.105", LocalPort: 56454, RemoteAddress: "52.46.136.110", RemotePort: 443, State: "ESTABLISHED"},
   339  				{LocalAddress: "10.10.10.105", LocalPort: 34750, RemoteAddress: "142.250.75.238", RemotePort: 443, State: "ESTABLISHED"},
   340  			},
   341  		},
   342  		{
   343  			name: "all connections",
   344  			args: args{
   345  				execClientCustomizer: func(client *exec.MockClient) {
   346  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   347  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil)
   348  				},
   349  				podName:       podName,
   350  				containerName: containerName,
   351  			},
   352  			wantErr: false,
   353  			want: []Connection{
   354  				{LocalAddress: "127.0.0.1", LocalPort: 20001, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "LISTEN"},
   355  				{LocalAddress: "10.10.10.105", LocalPort: 6443, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "LISTEN"},
   356  				{LocalAddress: "0.0.0.0", LocalPort: 22, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "LISTEN"},
   357  				{LocalAddress: "0.0.0.0", LocalPort: 5355, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "LISTEN"},
   358  				{LocalAddress: "10.10.10.105", LocalPort: 41142, RemoteAddress: "142.250.178.133", RemotePort: 443, State: "TIME_WAIT"},
   359  				{LocalAddress: "10.10.10.105", LocalPort: 56454, RemoteAddress: "52.46.136.110", RemotePort: 443, State: "ESTABLISHED"},
   360  				{LocalAddress: "10.10.10.105", LocalPort: 34750, RemoteAddress: "142.250.75.238", RemotePort: 443, State: "ESTABLISHED"},
   361  				{LocalAddress: "224.0.0.251", LocalPort: 5353, RemoteAddress: "0.0.0.0", RemotePort: 0, State: "CLOSE"},
   362  				{
   363  					LocalAddress:  "0000:0000:0000:0000:0000:0000:0000:0001",
   364  					LocalPort:     631,
   365  					RemoteAddress: "0000:0000:0000:0000:0000:0000:0000:0000",
   366  					RemotePort:    0,
   367  					State:         "LISTEN",
   368  				},
   369  				{
   370  					LocalAddress:  "0000:0000:0000:0000:0000:FFFF:7F00:0001",
   371  					LocalPort:     63342,
   372  					RemoteAddress: "0000:0000:0000:0000:0000:0000:0000:0000",
   373  					RemotePort:    0,
   374  					State:         "LISTEN",
   375  				},
   376  				{
   377  					LocalAddress:  "0000:0000:0000:0000:0000:0000:0000:0000",
   378  					LocalPort:     5000,
   379  					RemoteAddress: "0000:0000:0000:0000:0000:0000:0000:0000",
   380  					RemotePort:    0,
   381  					State:         "LISTEN",
   382  				},
   383  				{
   384  					LocalAddress:  "0000:0000:0000:0000:0000:0000:0000:0000",
   385  					LocalPort:     35074,
   386  					RemoteAddress: "0000:0000:0000:0000:0000:0000:0000:0000",
   387  					RemotePort:    0,
   388  					State:         "CLOSE",
   389  				},
   390  				{
   391  					LocalAddress:  "0000:0000:0000:0000:0000:0000:0000:0000",
   392  					LocalPort:     33760,
   393  					RemoteAddress: "0000:0000:0000:0000:0000:0000:0000:0000",
   394  					RemotePort:    0,
   395  					State:         "CLOSE",
   396  				},
   397  			},
   398  		},
   399  	}
   400  	for _, tt := range tests {
   401  		t.Run(tt.name, func(t *testing.T) {
   402  			ctrl := gomock.NewController(t)
   403  			execClient := exec.NewMockClient(ctrl)
   404  			tt.args.execClientCustomizer(execClient)
   405  
   406  			got, err := GetConnections(context.Background(), execClient, tt.args.podName, tt.args.containerName, tt.args.statePredicate)
   407  			if (err != nil) != tt.wantErr {
   408  				t.Errorf("getListeningConnections() error = %v, wantErr %v", err, tt.wantErr)
   409  				return
   410  			}
   411  			if diff := cmp.Diff(tt.want, got); diff != "" {
   412  				t.Errorf("getListeningConnections() mismatch (-want +got):\n%s", diff)
   413  			}
   414  		})
   415  	}
   416  }
   417  
   418  func TestCheckAppPortsListening(t *testing.T) {
   419  	type args struct {
   420  		execClientCustomizer func(client *exec.MockClient)
   421  		containerPortMapping map[string][]int
   422  		timeout              time.Duration
   423  	}
   424  	tests := []struct {
   425  		name    string
   426  		args    args
   427  		wantErr bool
   428  	}{
   429  		{
   430  			name:    "no container port mapping",
   431  			wantErr: false,
   432  		},
   433  		{
   434  			name:    "container with no ports",
   435  			wantErr: false,
   436  			args: args{
   437  				containerPortMapping: map[string][]int{
   438  					containerName:   {},
   439  					"my-other-cont": {},
   440  				},
   441  				timeout: 5 * time.Second,
   442  			},
   443  		},
   444  		{
   445  			name: "error while checking for ports",
   446  			args: args{
   447  				execClientCustomizer: func(client *exec.MockClient) {
   448  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Any(), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   449  						Return(nil, []string{"an error"}, errors.New("some error")).AnyTimes()
   450  				},
   451  				containerPortMapping: map[string][]int{
   452  					// all ports are opened, as decoded from aggregatedContentFromProcNetFiles
   453  					containerName:   {20001, 6443, 22},
   454  					"my-other-cont": {5355},
   455  				},
   456  				timeout: 5 * time.Second,
   457  			},
   458  			wantErr: true,
   459  		},
   460  		{
   461  			name: "too small timeout reached while checking for ports, even if they are all opened",
   462  			args: args{
   463  				execClientCustomizer: func(client *exec.MockClient) {
   464  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Any(), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   465  						Return(nil, []string{"an error"}, errors.New("some error")).AnyTimes()
   466  				},
   467  				containerPortMapping: map[string][]int{
   468  					// all ports are opened, as decoded from aggregatedContentFromProcNetFiles
   469  					containerName: {20001, 6443, 22},
   470  					// all ports are opened, as decoded from aggregatedContentFromProcNetFiles
   471  					"my-other-cont": {5355},
   472  				},
   473  				timeout: 1 * time.Millisecond,
   474  			},
   475  			wantErr: true,
   476  		},
   477  		{
   478  			name: "at least one of the ports are not opened",
   479  			args: args{
   480  				execClientCustomizer: func(client *exec.MockClient) {
   481  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   482  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil).AnyTimes()
   483  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq("my-other-cont"), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   484  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil).AnyTimes()
   485  				},
   486  				containerPortMapping: map[string][]int{
   487  					// all ports are coming from aggregatedContentFromProcNetFiles
   488  					containerName: {20001, 6443, 22},
   489  					// port 5355 is coming from aggregatedContentFromProcNetFiles, but 12345 is intentionally not there
   490  					"my-other-cont": {5355, 12345},
   491  				},
   492  				timeout: 5 * time.Second,
   493  			},
   494  			wantErr: true,
   495  		},
   496  		{
   497  			name: "all ports are opened in the container",
   498  			args: args{
   499  				execClientCustomizer: func(client *exec.MockClient) {
   500  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq(containerName), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   501  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil).AnyTimes()
   502  					client.EXPECT().ExecuteCommand(gomock.Any(), gomock.Eq(cmd), gomock.Eq(podName), gomock.Eq("my-other-cont"), gomock.Eq(false), gomock.Nil(), gomock.Nil()).
   503  						Return(strings.Split(aggregatedContentFromProcNetFiles, "\n"), nil, nil).AnyTimes()
   504  				},
   505  				containerPortMapping: map[string][]int{
   506  					// all ports are opened, as decoded from aggregatedContentFromProcNetFiles
   507  					containerName: {20001, 6443, 22},
   508  					// all ports are opened, as decoded from aggregatedContentFromProcNetFiles
   509  					"my-other-cont": {5355},
   510  				},
   511  				timeout: 6 * time.Second,
   512  			},
   513  			wantErr: false,
   514  		},
   515  	}
   516  	for _, tt := range tests {
   517  		t.Run(tt.name, func(t *testing.T) {
   518  			ctrl := gomock.NewController(t)
   519  			execClient := exec.NewMockClient(ctrl)
   520  			if tt.args.execClientCustomizer != nil {
   521  				tt.args.execClientCustomizer(execClient)
   522  			}
   523  
   524  			gotErr := CheckAppPortsListening(context.Background(), execClient, podName, tt.args.containerPortMapping, tt.args.timeout)
   525  			if (gotErr != nil) != tt.wantErr {
   526  				t.Errorf("CheckAppPortsListening() error = %v, wantErr %v", gotErr, tt.wantErr)
   527  			}
   528  		})
   529  	}
   530  }
   531  

View as plain text