github.com/jfrog/build-info-go@v1.9.26/utils/goutils_test.go (about)

     1  package utils
     2  
     3  import (
     4  	"github.com/stretchr/testify/assert"
     5  	"os"
     6  	"path/filepath"
     7  	"reflect"
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  func TestListToMap(t *testing.T) {
    13  	content := `github.com/you/hello
    14  github.com/dsnet/compress:v0.0.0-20171208185109-cc9eb1d7ad76
    15  github.com/golang/snappy:v0.0.0-20180518054509-2e65f85255db
    16  github.com/mholt/archiver:v2.1.0+incompatible
    17  github.com/nwaples/rardecode:v0.0.0-20171029023500-e06696f847ae
    18  github.com/pierrec/lz4:v2.0.5+incompatible
    19  github.com/ulikunitz/xz:v0.5.4
    20  rsc.io/quote:v1.5.2
    21  rsc.io/sampler:v1.3.0
    22  	`
    23  
    24  	actual := listToMap(content)
    25  	expected := map[string]bool{
    26  		"github.com/dsnet/compress:v0.0.0-20171208185109-cc9eb1d7ad76":    true,
    27  		"github.com/golang/snappy:v0.0.0-20180518054509-2e65f85255db":     true,
    28  		"github.com/mholt/archiver:v2.1.0+incompatible":                   true,
    29  		"github.com/nwaples/rardecode:v0.0.0-20171029023500-e06696f847ae": true,
    30  		"github.com/pierrec/lz4:v2.0.5+incompatible":                      true,
    31  		"github.com/ulikunitz/xz:v0.5.4":                                  true,
    32  		"rsc.io/quote:v1.5.2":                                             true,
    33  		"rsc.io/sampler:v1.3.0":                                           true,
    34  	}
    35  
    36  	if !reflect.DeepEqual(expected, actual) {
    37  		t.Errorf("Expecting: \n%v \nGot: \n%v", expected, actual)
    38  	}
    39  }
    40  
    41  func TestGetProjectRoot(t *testing.T) {
    42  	wd, err := os.Getwd()
    43  	assert.NoError(t, err)
    44  	defer func() {
    45  		assert.NoError(t, os.Chdir(wd))
    46  	}()
    47  
    48  	// CD into a directory with a go.mod file.
    49  	projectRoot := filepath.Join("testdata", "project")
    50  	assert.NoError(t, os.Chdir(projectRoot))
    51  
    52  	// Make projectRoot an absolute path.
    53  	projectRoot, err = os.Getwd()
    54  	assert.NoError(t, err)
    55  
    56  	// Get the project root.
    57  	root, err := GetProjectRoot()
    58  	assert.NoError(t, err)
    59  	assert.Equal(t, projectRoot, root)
    60  
    61  	// CD back to the original directory.
    62  	assert.NoError(t, os.Chdir(wd))
    63  
    64  	// CD into a subdirectory in the same project, and expect to get the same project root.
    65  	projectSubDirectory := filepath.Join("testdata", "project", "dir")
    66  	assert.NoError(t, os.Chdir(projectSubDirectory))
    67  	root, err = GetProjectRoot()
    68  	assert.NoError(t, err)
    69  	assert.Equal(t, projectRoot, root)
    70  
    71  	// CD back to the original directory.
    72  	if !assert.NoError(t, os.Chdir(wd)) {
    73  		return
    74  	}
    75  
    76  	// Now CD into a directory outside the project, and expect to get a different project root.
    77  	noProjectRoot := filepath.Join("testdata", "noproject")
    78  	assert.NoError(t, os.Chdir(noProjectRoot))
    79  	root, err = GetProjectRoot()
    80  	assert.NoError(t, err)
    81  	assert.NotEqual(t, projectRoot, root)
    82  }
    83  
    84  func TestGetDependenciesList(t *testing.T) {
    85  	testGetDependenciesList(t, "testGoList")
    86  }
    87  
    88  func TestGetDependenciesListWithIgnoreErrors(t *testing.T) {
    89  	// In some cases, we see that running go list on some Go packages may fail.
    90  	// We should allow ignoring the errors in such cases and build the Go dependency tree, even if partial.
    91  	testGetDependenciesList(t, "testBadGoList")
    92  }
    93  
    94  func testGetDependenciesList(t *testing.T, testDir string) {
    95  	log := NewDefaultLogger(ERROR)
    96  	goModPath := filepath.Join("testdata", "mods", testDir)
    97  	err := os.Rename(filepath.Join(goModPath, "go.mod.txt"), filepath.Join(goModPath, "go.mod"))
    98  	assert.NoError(t, err)
    99  	defer func() {
   100  		err = os.Rename(filepath.Join(goModPath, "go.mod"), filepath.Join(goModPath, "go.mod.txt"))
   101  		assert.NoError(t, err)
   102  	}()
   103  	err = os.Rename(filepath.Join(goModPath, "go.sum.txt"), filepath.Join(goModPath, "go.sum"))
   104  	assert.NoError(t, err)
   105  	defer func() {
   106  		err = os.Rename(filepath.Join(goModPath, "go.sum"), filepath.Join(goModPath, "go.sum.txt"))
   107  		assert.NoError(t, err)
   108  	}()
   109  	originSumFileContent, err := getGoSum(goModPath, log)
   110  	err = os.Rename(filepath.Join(goModPath, "test.go.txt"), filepath.Join(goModPath, "test.go"))
   111  	assert.NoError(t, err)
   112  	defer func() {
   113  		err = os.Rename(filepath.Join(goModPath, "test.go"), filepath.Join(goModPath, "test.go.txt"))
   114  		assert.NoError(t, err)
   115  	}()
   116  	actual, err := GetDependenciesList(goModPath, log)
   117  	assert.NoError(t, err)
   118  
   119  	// Since Go 1.16 'go list' command won't automatically update go.mod and go.sum.
   120  	// Check that we roll back changes properly.
   121  	newSumFileContent, err := getGoSum(goModPath, log)
   122  	assert.Equal(t, newSumFileContent, originSumFileContent, "go.sum has been modified and didn't rollback properly")
   123  
   124  	expected := map[string]bool{
   125  		"golang.org/x/text:v0.3.3": true,
   126  		"rsc.io/quote:v1.5.2":      true,
   127  		"rsc.io/sampler:v1.3.0":    true,
   128  		testDir + ":":              true,
   129  	}
   130  	assert.Equal(t, expected, actual)
   131  }
   132  
   133  func TestParseGoPathWindows(t *testing.T) {
   134  	log := NewDefaultLogger(DEBUG)
   135  	if !IsWindows() {
   136  		log.Debug("Skipping the test since not running on Windows OS")
   137  		return
   138  	}
   139  	tests := []struct {
   140  		name     string
   141  		goPath   string
   142  		expected string
   143  	}{
   144  		{"One go path", "C:\\Users\\JFrog\\go", "C:\\Users\\JFrog\\go"},
   145  		{"Multiple go paths", "C:\\Users\\JFrog\\go;C:\\Users\\JFrog\\go2;C:\\Users\\JFrog\\go3", "C:\\Users\\JFrog\\go"},
   146  		{"Empty path", "", ""},
   147  	}
   148  
   149  	runGoPathTests(tests, t)
   150  }
   151  
   152  func TestParseGoPathUnix(t *testing.T) {
   153  	if IsWindows() {
   154  		return
   155  	}
   156  	tests := []struct {
   157  		name     string
   158  		goPath   string
   159  		expected string
   160  	}{
   161  		{"One go path", "/Users/jfrog/go", "/Users/jfrog/go"},
   162  		{"Multiple go paths", "/Users/jfrog/go:/Users/jfrog/go2:/Users/jfrog/go3", "/Users/jfrog/go"},
   163  		{"Empty path", "", ""},
   164  	}
   165  
   166  	runGoPathTests(tests, t)
   167  }
   168  
   169  func runGoPathTests(tests []struct {
   170  	name     string
   171  	goPath   string
   172  	expected string
   173  }, t *testing.T) {
   174  	for _, test := range tests {
   175  		t.Run(test.name, func(t *testing.T) {
   176  			actual := parseGoPath(test.goPath)
   177  			if !strings.EqualFold(actual, test.expected) {
   178  				t.Errorf("Test name: %s: Expected: %v, Got: %v", test.name, test.expected, actual)
   179  			}
   180  		})
   181  	}
   182  }