github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/git/v2/remote_test.go (about)

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package git
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"reflect"
    23  	"testing"
    24  )
    25  
    26  type stringWithError struct {
    27  	str string
    28  	err error
    29  }
    30  
    31  // usernameVendor returns a func that vends logins and errors from the provided slices, in order
    32  func usernameVendor(logins []stringWithError) func() (string, error) {
    33  	index := 0
    34  	return func() (string, error) {
    35  		item := logins[index%len(logins)]
    36  		index++
    37  		return item.str, item.err
    38  	}
    39  }
    40  
    41  // fakeTokenGetter returns a func that vends tokens from the provided slice, in order
    42  func fakeTokenGetter(tokens []string) func(org string) (string, error) {
    43  	index := 0
    44  	return func(_ string) (string, error) {
    45  		token := tokens[index%len(tokens)]
    46  		index++
    47  		return token, nil
    48  	}
    49  }
    50  
    51  func TestSSHRemoteResolverFactory(t *testing.T) {
    52  	factory := sshRemoteResolverFactory{
    53  		host: "ssh.host.com",
    54  		username: usernameVendor([]stringWithError{
    55  			{str: "zero", err: nil},
    56  			{str: "first", err: nil},
    57  			{str: "second", err: errors.New("oops")},
    58  			{str: "third", err: nil},
    59  			// For publish remote test with unique fork name
    60  			{str: "fourth", err: nil},
    61  		}),
    62  	}
    63  
    64  	central := factory.CentralRemote("org", "repo")
    65  	for i, expected := range []stringWithError{
    66  		{str: "git@ssh.host.com:org/repo.git", err: nil},
    67  		{str: "git@ssh.host.com:org/repo.git", err: nil},
    68  		{str: "git@ssh.host.com:org/repo.git", err: nil},
    69  	} {
    70  		actualRemote, actualErr := central()
    71  		if actualRemote != expected.str {
    72  			t.Errorf("central remote test %d returned incorrect remote, expected %v got %v", i, expected.str, actualRemote)
    73  		}
    74  		if !reflect.DeepEqual(actualErr, expected.err) {
    75  			t.Errorf("central remote test %d returned incorrect error, expected %v got %v", i, expected.err, actualErr)
    76  		}
    77  	}
    78  	publish := factory.PublishRemote("org", "repo")
    79  
    80  	// Test with unique fork name before
    81  	expected := "git@ssh.host.com:zero/fork-repo.git"
    82  	actualRemote, actualErr := publish("fork-repo")
    83  	if actualRemote != expected {
    84  		t.Errorf("publish remote test with different fork name returned incorrect remote, expected %v got %v", expected, actualRemote)
    85  	}
    86  	if actualErr != nil {
    87  		t.Errorf("publish remote test with different fork name returned an unexpected error: %v", actualErr)
    88  	}
    89  	// Test with default fork name
    90  	for i, expected := range []stringWithError{
    91  		{str: "git@ssh.host.com:first/repo.git", err: nil},
    92  		{str: "", err: errors.New("oops")},
    93  		{str: "git@ssh.host.com:third/repo.git", err: nil},
    94  	} {
    95  		actualRemote, actualErr := publish("")
    96  		if actualRemote != expected.str {
    97  			t.Errorf("publish remote test %d returned incorrect remote, expected %v got %v", i, expected.str, actualRemote)
    98  		}
    99  		if !reflect.DeepEqual(actualErr, expected.err) {
   100  			t.Errorf("publish remote test %d returned incorrect error, expected %v got %v", i, expected.err, actualErr)
   101  		}
   102  	}
   103  	// Test with unique fork name after
   104  	expected = "git@ssh.host.com:fourth/fork-repo.git"
   105  	actualRemote, actualErr = publish("fork-repo")
   106  	if actualRemote != expected {
   107  		t.Errorf("publish remote test with different fork name returned incorrect remote, expected %v got %v", expected, actualRemote)
   108  	}
   109  	if actualErr != nil {
   110  		t.Errorf("publish remote test with different fork name returned an unexpected error: %v", actualErr)
   111  	}
   112  }
   113  
   114  func TestHTTPResolverFactory_NoAuth(t *testing.T) {
   115  	t.Run("CentralRemote", func(t *testing.T) {
   116  		expected := "https://some-host.com/org/repo"
   117  		res, err := (&httpResolverFactory{host: "some-host.com"}).CentralRemote("org", "repo")()
   118  		if err != nil {
   119  			t.Fatalf("CentralRemote: %v", err)
   120  		}
   121  		if res != expected {
   122  			t.Errorf("Expected result to be %s, was %s", expected, res)
   123  		}
   124  	})
   125  
   126  	t.Run("PublishRemote", func(t *testing.T) {
   127  		expectedErr := "username not configured, no publish repo available"
   128  		_, err := (&httpResolverFactory{host: "some-host.com"}).PublishRemote("org", "repo")("")
   129  		if err == nil || err.Error() != expectedErr {
   130  			t.Errorf("expectedErr to be %s, was %v", expectedErr, err)
   131  		}
   132  	})
   133  }
   134  
   135  func TestHTTPResolverFactory(t *testing.T) {
   136  	factory := httpResolverFactory{
   137  		host: "host.com",
   138  		username: usernameVendor([]stringWithError{
   139  			{str: "first", err: nil},
   140  			{str: "second", err: errors.New("oops")},
   141  			{str: "third", err: nil},
   142  			// this is called twice for publish remote resolution
   143  			// For testing publish remote with a unique forkName
   144  			{str: "zero", err: nil},
   145  			{str: "zero", err: nil},
   146  			// testing publish remote with default forkName
   147  			{str: "first", err: nil},
   148  			{str: "first", err: nil},
   149  			{str: "second", err: errors.New("oops")},
   150  			{str: "third", err: nil},
   151  			{str: "third", err: nil},
   152  			{str: "fourth", err: nil},
   153  			{str: "fourth", err: errors.New("oops")},
   154  			// For testing publish remote with a unique forkName
   155  			{str: "fifth", err: nil},
   156  			{str: "fifth", err: nil},
   157  		}),
   158  		token: fakeTokenGetter([]string{"one", "three"}), // only called when username succeeds
   159  	}
   160  
   161  	central := factory.CentralRemote("org", "repo")
   162  	for i, expected := range []stringWithError{
   163  		{str: "https://first:one@host.com/org/repo", err: nil},
   164  		{str: "", err: fmt.Errorf("could not resolve username: %w", errors.New("oops"))},
   165  		{str: "https://third:three@host.com/org/repo", err: nil},
   166  	} {
   167  		actualRemote, actualErr := central()
   168  		if actualRemote != expected.str {
   169  			t.Errorf("central remote test %d returned incorrect remote, expected %v got %v", i, expected.str, actualRemote)
   170  		}
   171  		if !reflect.DeepEqual(actualErr, expected.err) {
   172  			t.Errorf("central remote test %d returned incorrect error, expected %v got %v", i, expected.err, actualErr)
   173  		}
   174  	}
   175  
   176  	publish := factory.PublishRemote("org", "repo")
   177  	// test publish with a different fork name before
   178  	expected := "https://zero:one@host.com/zero/fork-repo"
   179  	actualRemote, actualErr := publish("fork-repo")
   180  	if actualRemote != expected {
   181  		t.Errorf("publish remote with a different fork name returned incorrect remote, expected %v got %v", expected, actualRemote)
   182  	}
   183  	if actualErr != nil {
   184  		t.Errorf("publish remote with a different fork name returned an unexpected error: %v", actualErr)
   185  	}
   186  
   187  	// Test with default fork name
   188  	for i, expected := range []stringWithError{
   189  		{str: "https://first:three@host.com/first/repo", err: nil},
   190  		{str: "", err: fmt.Errorf("could not resolve username: %w", errors.New("oops"))},
   191  		{str: "https://third:one@host.com/third/repo", err: nil},
   192  		{str: "", err: fmt.Errorf("could not resolve remote: %w", fmt.Errorf("could not resolve username: %w", errors.New("oops")))},
   193  	} {
   194  		actualRemote, actualErr := publish("")
   195  		if actualRemote != expected.str {
   196  			t.Errorf("publish remote test %d returned incorrect remote, expected %v got %v", i, expected.str, actualRemote)
   197  		}
   198  		if !reflect.DeepEqual(actualErr, expected.err) {
   199  			t.Errorf("publish remote test %d returned incorrect error, expected %v got %v", i, expected.err, actualErr)
   200  		}
   201  	}
   202  	// test publish with a different fork name after
   203  	expected = "https://fifth:three@host.com/fifth/fork-repo"
   204  	actualRemote, actualErr = publish("fork-repo")
   205  	if actualRemote != expected {
   206  		t.Errorf("publish remote with a different fork name returned incorrect remote, expected %v got %v", expected, actualRemote)
   207  	}
   208  	if actualErr != nil {
   209  		t.Errorf("publish remote with a different fork name returned an unexpected error: %v", actualErr)
   210  	}
   211  }