github.com/adevinta/lava@v0.7.2/internal/engine/targetserver_test.go (about)

     1  // Copyright 2023 Adevinta
     2  
     3  package engine
     4  
     5  import (
     6  	"fmt"
     7  	"testing"
     8  
     9  	types "github.com/adevinta/vulcan-types"
    10  
    11  	"github.com/adevinta/lava/internal/config"
    12  	"github.com/adevinta/lava/internal/containers"
    13  )
    14  
    15  func TestGetTargetAddr(t *testing.T) {
    16  	tests := []struct {
    17  		name       string
    18  		target     config.Target
    19  		want       string
    20  		wantNilErr bool
    21  	}{
    22  		{
    23  			name: "IPv4",
    24  			target: config.Target{
    25  				AssetType:  types.IP,
    26  				Identifier: "127.0.0.1",
    27  			},
    28  			want:       "127.0.0.1",
    29  			wantNilErr: true,
    30  		},
    31  		{
    32  			name: "IPv6",
    33  			target: config.Target{
    34  				AssetType:  types.IP,
    35  				Identifier: "::1",
    36  			},
    37  			want:       "::1",
    38  			wantNilErr: true,
    39  		},
    40  		{
    41  			name: "Hostname",
    42  			target: config.Target{
    43  				AssetType:  types.Hostname,
    44  				Identifier: "example.com",
    45  			},
    46  			want:       "example.com",
    47  			wantNilErr: true,
    48  		},
    49  		{
    50  			name: "WebAddress port",
    51  			target: config.Target{
    52  				AssetType:  types.WebAddress,
    53  				Identifier: "https://example.com:1234/path",
    54  			},
    55  			want:       "example.com:1234",
    56  			wantNilErr: true,
    57  		},
    58  		{
    59  			name: "WebAddress scheme",
    60  			target: config.Target{
    61  				AssetType:  types.WebAddress,
    62  				Identifier: "https://example.com/path",
    63  			},
    64  			want:       "example.com:443",
    65  			wantNilErr: true,
    66  		},
    67  		{
    68  			name: "WebAddress unknown scheme",
    69  			target: config.Target{
    70  				AssetType:  types.WebAddress,
    71  				Identifier: "unknown://example.com/path",
    72  			},
    73  			want:       "example.com",
    74  			wantNilErr: true,
    75  		},
    76  		{
    77  			name: "invalid WebAddress",
    78  			target: config.Target{
    79  				AssetType:  types.WebAddress,
    80  				Identifier: "https://example.com:invalidport/path",
    81  			},
    82  			want:       "",
    83  			wantNilErr: false,
    84  		},
    85  		{
    86  			name: "GitRepository scp-like syntax",
    87  			target: config.Target{
    88  				AssetType:  types.GitRepository,
    89  				Identifier: "git@github.com:adevinta/lava.git",
    90  			},
    91  			want:       "github.com:22",
    92  			wantNilErr: true,
    93  		},
    94  		{
    95  			name: "GitRepository https",
    96  			target: config.Target{
    97  				AssetType:  types.GitRepository,
    98  				Identifier: "https://example.com/path/to/repo.git/",
    99  			},
   100  			want:       "example.com:443",
   101  			wantNilErr: true,
   102  		},
   103  		{
   104  			name: "GitRepository git",
   105  			target: config.Target{
   106  				AssetType:  types.GitRepository,
   107  				Identifier: "git://example.com/~user/path/to/repo.git/",
   108  			},
   109  			want:       "example.com:9418",
   110  			wantNilErr: true,
   111  		},
   112  		{
   113  			name: "GitRepository git port",
   114  			target: config.Target{
   115  				AssetType:  types.GitRepository,
   116  				Identifier: "git://example.com:443/~user/path/to/repo.git/",
   117  			},
   118  			want:       "example.com:443",
   119  			wantNilErr: true,
   120  		},
   121  		{
   122  			name: "invalid GitRepository URL",
   123  			target: config.Target{
   124  				AssetType:  types.GitRepository,
   125  				Identifier: "https://example.com:invalidport/path/to/repo.git/",
   126  			},
   127  			want:       "",
   128  			wantNilErr: false,
   129  		},
   130  		{
   131  			name: "invalid asset type",
   132  			target: config.Target{
   133  				AssetType:  types.IPRange,
   134  				Identifier: "127.0.0.1/8",
   135  			},
   136  			want:       "",
   137  			wantNilErr: false,
   138  		},
   139  		{
   140  			name: "GitRepository with empty host",
   141  			target: config.Target{
   142  				AssetType:  types.GitRepository,
   143  				Identifier: "/path",
   144  			},
   145  			want:       "",
   146  			wantNilErr: false,
   147  		},
   148  		{
   149  			name: "WebAddress with empty host",
   150  			target: config.Target{
   151  				AssetType:  types.WebAddress,
   152  				Identifier: "/path",
   153  			},
   154  			want:       "",
   155  			wantNilErr: false,
   156  		},
   157  	}
   158  
   159  	for _, tt := range tests {
   160  		t.Run(tt.name, func(t *testing.T) {
   161  			got, err := getTargetAddr(tt.target)
   162  
   163  			if (err == nil) != tt.wantNilErr {
   164  				t.Errorf("unexpected error: %v", err)
   165  			}
   166  
   167  			if got != tt.want {
   168  				t.Errorf("unexpected host: got: %v, want: %v", got, tt.want)
   169  			}
   170  		})
   171  	}
   172  }
   173  
   174  func TestTargetServer_mkIntIdentifier(t *testing.T) {
   175  	cli, err := containers.NewDockerdClient(testRuntime)
   176  	if err != nil {
   177  		t.Fatalf("unexpected error: %v", err)
   178  	}
   179  	defer cli.Close()
   180  
   181  	hostGatewayHostname := cli.HostGatewayHostname()
   182  
   183  	tests := []struct {
   184  		name       string
   185  		target     config.Target
   186  		want       string
   187  		wantNilErr bool
   188  	}{
   189  		{
   190  			name: "local IP",
   191  			target: config.Target{
   192  				Identifier: "127.0.0.1",
   193  				AssetType:  "IP",
   194  			},
   195  			want:       hostGatewayHostname,
   196  			wantNilErr: true,
   197  		},
   198  		{
   199  			name: "remote IP",
   200  			target: config.Target{
   201  				Identifier: "192.168.1.1",
   202  				AssetType:  "IP",
   203  			},
   204  			want:       hostGatewayHostname,
   205  			wantNilErr: true,
   206  		},
   207  		{
   208  			name: "local Hostname",
   209  			target: config.Target{
   210  				Identifier: "localhost",
   211  				AssetType:  "Hostname",
   212  			},
   213  			want:       hostGatewayHostname,
   214  			wantNilErr: true,
   215  		},
   216  		{
   217  			name: "remote Hostname",
   218  			target: config.Target{
   219  				Identifier: "example.com",
   220  				AssetType:  "Hostname",
   221  			},
   222  			want:       hostGatewayHostname,
   223  			wantNilErr: true,
   224  		},
   225  		{
   226  			name: "local WebAddress",
   227  			target: config.Target{
   228  				Identifier: "http://127.0.0.1:12345/path",
   229  				AssetType:  "WebAddress",
   230  			},
   231  			want:       fmt.Sprintf("http://%v:12345/path", hostGatewayHostname),
   232  			wantNilErr: true,
   233  		},
   234  		{
   235  			name: "remote WebAddress",
   236  			target: config.Target{
   237  				Identifier: "http://192.168.1.1/path",
   238  				AssetType:  "WebAddress",
   239  			},
   240  			want:       fmt.Sprintf("http://%v/path", hostGatewayHostname),
   241  			wantNilErr: true,
   242  		},
   243  		{
   244  			name: "local GitRepository",
   245  			target: config.Target{
   246  				Identifier: "ssh://git@localhost:12345/path/to/repo.git",
   247  				AssetType:  "GitRepository",
   248  			},
   249  			want:       fmt.Sprintf("ssh://git@%v:12345/path/to/repo.git", hostGatewayHostname),
   250  			wantNilErr: true,
   251  		},
   252  		{
   253  			name: "remote GitRepository",
   254  			target: config.Target{
   255  				Identifier: "git@example.com:/path/to/repo.git",
   256  				AssetType:  "GitRepository",
   257  			},
   258  			want:       fmt.Sprintf("ssh://git@%v/path/to/repo.git", hostGatewayHostname),
   259  			wantNilErr: true,
   260  		},
   261  		{
   262  			name: "multiple host occurrences",
   263  			target: config.Target{
   264  				Identifier: "localhost://localhost:12345/path",
   265  				AssetType:  "WebAddress",
   266  			},
   267  			want:       fmt.Sprintf("localhost://%v:12345/path", hostGatewayHostname),
   268  			wantNilErr: true,
   269  		},
   270  		{
   271  			name: "DockerImage",
   272  			target: config.Target{
   273  				Identifier: "alpine:3.18",
   274  				AssetType:  "DockerImage",
   275  			},
   276  			want:       "",
   277  			wantNilErr: false,
   278  		},
   279  		{
   280  			name: "invalid GitRepository",
   281  			target: config.Target{
   282  				Identifier: "ssh://git@localhost:invalidport/path/to/repo.git",
   283  				AssetType:  "GitRepository",
   284  			},
   285  			want:       "",
   286  			wantNilErr: false,
   287  		},
   288  		{
   289  			name: "invalid WebAddress",
   290  			target: config.Target{
   291  				Identifier: "http://127.0.0.1:invalidport/path",
   292  				AssetType:  "WebAddress",
   293  			},
   294  			want:       "",
   295  			wantNilErr: false,
   296  		},
   297  	}
   298  
   299  	for _, tt := range tests {
   300  		t.Run(tt.name, func(t *testing.T) {
   301  			srv, err := newTargetServer(testRuntime)
   302  			if err != nil {
   303  				t.Fatalf("unexpected error: %v", err)
   304  			}
   305  			defer srv.Close()
   306  
   307  			got, err := srv.mkIntIdentifier(tt.target)
   308  
   309  			if (err == nil) != tt.wantNilErr {
   310  				t.Errorf("unexpected error: %v", err)
   311  			}
   312  
   313  			if got != tt.want {
   314  				t.Errorf("unexpected target: got: %v, want: %v", got, tt.want)
   315  			}
   316  		})
   317  	}
   318  }
   319  
   320  func TestParseGitURL(t *testing.T) {
   321  	tests := []struct {
   322  		name     string
   323  		url      string
   324  		wantHost string
   325  	}{
   326  		{
   327  			name:     "url",
   328  			url:      "https://example.com:443/path/to/repo.git/",
   329  			wantHost: "example.com:443",
   330  		},
   331  		{
   332  			name:     "scp long",
   333  			url:      "user@example.com:/~user/path/to/repo.git/",
   334  			wantHost: "example.com",
   335  		},
   336  		{
   337  			name:     "scp short",
   338  			url:      "example.com:/",
   339  			wantHost: "example.com",
   340  		},
   341  		{
   342  			name:     "local path",
   343  			url:      "/path/to/repo.git/",
   344  			wantHost: "",
   345  		},
   346  		{
   347  			name:     "scp with colon",
   348  			url:      "foo:bar",
   349  			wantHost: "foo",
   350  		},
   351  		{
   352  			name:     "local path with colon",
   353  			url:      "./foo:bar",
   354  			wantHost: "",
   355  		},
   356  		{
   357  			name:     "slash",
   358  			url:      "/",
   359  			wantHost: "",
   360  		},
   361  		{
   362  			name:     "colon",
   363  			url:      ":",
   364  			wantHost: "",
   365  		},
   366  		{
   367  			name:     "colon slash",
   368  			url:      ":/",
   369  			wantHost: "",
   370  		},
   371  		{
   372  			name:     "slash colon",
   373  			url:      "/:",
   374  			wantHost: "",
   375  		},
   376  	}
   377  
   378  	for _, tt := range tests {
   379  		t.Run(tt.name, func(t *testing.T) {
   380  			u, err := parseGitURL(tt.url)
   381  			if err != nil {
   382  				t.Fatalf("unexpected error: %v", err)
   383  			}
   384  
   385  			if u.Host != tt.wantHost {
   386  				t.Errorf("unexpected host: got: %v, want: %v)", u.Host, tt.wantHost)
   387  			}
   388  		})
   389  	}
   390  }