github.com/kastenhq/syft@v0.0.0-20230821225854-0710af25cdbe/syft/pkg/cataloger/golang/parse_go_binary_test.go (about)

     1  package golang
     2  
     3  import (
     4  	"bufio"
     5  	"io"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"runtime/debug"
    10  	"strconv"
    11  	"syscall"
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/kastenhq/syft/syft/file"
    18  	"github.com/kastenhq/syft/syft/internal/fileresolver"
    19  	"github.com/kastenhq/syft/syft/pkg"
    20  )
    21  
    22  // make will run the default make target for the given test fixture path
    23  func runMakeTarget(t *testing.T, fixtureName string) {
    24  	cwd, err := os.Getwd()
    25  	require.NoError(t, err)
    26  	fixtureDir := filepath.Join(cwd, "test-fixtures/", fixtureName)
    27  
    28  	t.Logf("Generating Fixture in %q", fixtureDir)
    29  
    30  	cmd := exec.Command("make")
    31  	cmd.Dir = fixtureDir
    32  
    33  	stderr, err := cmd.StderrPipe()
    34  	require.NoError(t, err)
    35  
    36  	stdout, err := cmd.StdoutPipe()
    37  	require.NoError(t, err)
    38  
    39  	err = cmd.Start()
    40  	require.NoError(t, err)
    41  
    42  	show := func(label string, reader io.ReadCloser) {
    43  		scanner := bufio.NewScanner(reader)
    44  		scanner.Split(bufio.ScanLines)
    45  		for scanner.Scan() {
    46  			t.Logf("%s: %s", label, scanner.Text())
    47  		}
    48  	}
    49  	go show("out", stdout)
    50  	go show("err", stderr)
    51  
    52  	if err := cmd.Wait(); err != nil {
    53  		if exiterr, ok := err.(*exec.ExitError); ok {
    54  			// The program has exited with an exit code != 0
    55  
    56  			// This works on both Unix and Windows. Although package
    57  			// syscall is generally platform dependent, WaitStatus is
    58  			// defined for both Unix and Windows and in both cases has
    59  			// an ExitStatus() method with the same signature.
    60  			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
    61  				if status.ExitStatus() != 0 {
    62  					t.Fatalf("failed to generate fixture: rc=%d", status.ExitStatus())
    63  				}
    64  			}
    65  		} else {
    66  			t.Fatalf("unable to get generate fixture result: %+v", err)
    67  		}
    68  	}
    69  }
    70  
    71  func Test_getGOARCHFromBin(t *testing.T) {
    72  	runMakeTarget(t, "archs")
    73  
    74  	tests := []struct {
    75  		name     string
    76  		filepath string
    77  		expected string
    78  	}{
    79  		{
    80  			name:     "pe",
    81  			filepath: "test-fixtures/archs/binaries/hello-win-amd64",
    82  			// see: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#machine-types
    83  			expected: strconv.Itoa(0x8664),
    84  		},
    85  		{
    86  			name:     "elf-ppc64",
    87  			filepath: "test-fixtures/archs/binaries/hello-linux-ppc64le",
    88  			expected: "ppc64",
    89  		},
    90  		{
    91  			name:     "mach-o-arm64",
    92  			filepath: "test-fixtures/archs/binaries/hello-mach-o-arm64",
    93  			expected: "arm64",
    94  		},
    95  		{
    96  			name:     "linux-arm",
    97  			filepath: "test-fixtures/archs/binaries/hello-linux-arm",
    98  			expected: "arm",
    99  		},
   100  		{
   101  			name:     "xcoff-32bit",
   102  			filepath: "internal/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec",
   103  			expected: strconv.Itoa(0x1DF),
   104  		},
   105  		{
   106  			name:     "xcoff-64bit",
   107  			filepath: "internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec",
   108  			expected: strconv.Itoa(0x1F7),
   109  		},
   110  	}
   111  
   112  	for _, tt := range tests {
   113  		f, err := os.Open(tt.filepath)
   114  		require.NoError(t, err)
   115  		arch, err := getGOARCHFromBin(f)
   116  		require.NoError(t, err, "test name: %s", tt.name)
   117  		assert.Equal(t, tt.expected, arch)
   118  	}
   119  
   120  }
   121  
   122  func TestBuildGoPkgInfo(t *testing.T) {
   123  	const (
   124  		goCompiledVersion = "1.18"
   125  		archDetails       = "amd64"
   126  	)
   127  	defaultBuildSettings := map[string]string{
   128  		"GOARCH":  "amd64",
   129  		"GOOS":    "darwin",
   130  		"GOAMD64": "v1",
   131  	}
   132  
   133  	unmodifiedMain := pkg.Package{
   134  		Name:     "github.com/kastenhq/syft",
   135  		Language: pkg.Go,
   136  		Type:     pkg.GoModulePkg,
   137  		Version:  "(devel)",
   138  		PURL:     "pkg:golang/github.com/anchore/syft@(devel)",
   139  		Locations: file.NewLocationSet(
   140  			file.NewLocationFromCoordinates(
   141  				file.Coordinates{
   142  					RealPath:     "/a-path",
   143  					FileSystemID: "layer-id",
   144  				},
   145  			).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   146  		),
   147  		MetadataType: pkg.GolangBinMetadataType,
   148  		Metadata: pkg.GolangBinMetadata{
   149  			GoCompiledVersion: goCompiledVersion,
   150  			Architecture:      archDetails,
   151  			BuildSettings:     defaultBuildSettings,
   152  			MainModule:        "github.com/kastenhq/syft",
   153  		},
   154  	}
   155  
   156  	tests := []struct {
   157  		name     string
   158  		mod      *ExtendedBuildInfo
   159  		arch     string
   160  		expected []pkg.Package
   161  	}{
   162  		{
   163  			name:     "parse an empty mod",
   164  			mod:      nil,
   165  			expected: []pkg.Package(nil),
   166  		},
   167  		{
   168  			name: "package without name",
   169  			mod: &ExtendedBuildInfo{
   170  				&debug.BuildInfo{
   171  					Deps: []*debug.Module{
   172  						{
   173  							Path: "github.com/adrg/xdg",
   174  						},
   175  						{
   176  							Path:    "",
   177  							Version: "v0.2.1",
   178  						},
   179  					},
   180  				}, "",
   181  			},
   182  			expected: []pkg.Package{
   183  				{
   184  					Name:     "github.com/adrg/xdg",
   185  					PURL:     "pkg:golang/github.com/adrg/xdg",
   186  					Language: pkg.Go,
   187  					Type:     pkg.GoModulePkg,
   188  					Locations: file.NewLocationSet(
   189  						file.NewLocationFromCoordinates(
   190  							file.Coordinates{
   191  								RealPath:     "/a-path",
   192  								FileSystemID: "layer-id",
   193  							},
   194  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   195  					),
   196  					MetadataType: pkg.GolangBinMetadataType,
   197  					Metadata:     pkg.GolangBinMetadata{},
   198  				},
   199  			},
   200  		},
   201  		{
   202  			name:     "buildGoPkgInfo parses a blank mod and returns no packages",
   203  			mod:      &ExtendedBuildInfo{&debug.BuildInfo{}, ""},
   204  			expected: []pkg.Package(nil),
   205  		},
   206  		{
   207  			name: "parse a mod without main module",
   208  			arch: archDetails,
   209  			mod: &ExtendedBuildInfo{
   210  				&debug.BuildInfo{
   211  					GoVersion: goCompiledVersion,
   212  					Settings: []debug.BuildSetting{
   213  						{Key: "GOARCH", Value: archDetails},
   214  						{Key: "GOOS", Value: "darwin"},
   215  						{Key: "GOAMD64", Value: "v1"},
   216  					},
   217  					Deps: []*debug.Module{
   218  						{
   219  							Path:    "github.com/adrg/xdg",
   220  							Version: "v0.2.1",
   221  							Sum:     "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=",
   222  						},
   223  					},
   224  				}, "",
   225  			},
   226  			expected: []pkg.Package{
   227  				{
   228  					Name:     "github.com/adrg/xdg",
   229  					Version:  "v0.2.1",
   230  					PURL:     "pkg:golang/github.com/adrg/xdg@v0.2.1",
   231  					Language: pkg.Go,
   232  					Type:     pkg.GoModulePkg,
   233  					Locations: file.NewLocationSet(
   234  						file.NewLocationFromCoordinates(
   235  							file.Coordinates{
   236  								RealPath:     "/a-path",
   237  								FileSystemID: "layer-id",
   238  							},
   239  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   240  					),
   241  					MetadataType: pkg.GolangBinMetadataType,
   242  					Metadata: pkg.GolangBinMetadata{
   243  						GoCompiledVersion: goCompiledVersion,
   244  						Architecture:      archDetails,
   245  						H1Digest:          "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=",
   246  					},
   247  				},
   248  			},
   249  		},
   250  		{
   251  			name: "parse a mod with path but no main module",
   252  			arch: archDetails,
   253  			mod: &ExtendedBuildInfo{
   254  				&debug.BuildInfo{
   255  					GoVersion: goCompiledVersion,
   256  					Settings: []debug.BuildSetting{
   257  						{Key: "GOARCH", Value: archDetails},
   258  						{Key: "GOOS", Value: "darwin"},
   259  						{Key: "GOAMD64", Value: "v1"},
   260  					},
   261  					Path: "github.com/a/b/c",
   262  				}, "boringcrypto + fips",
   263  			},
   264  			expected: []pkg.Package{
   265  				{
   266  					Name:     "github.com/a/b/c",
   267  					Version:  "(devel)",
   268  					PURL:     "pkg:golang/github.com/a/b/c@(devel)",
   269  					Language: pkg.Go,
   270  					Type:     pkg.GoModulePkg,
   271  					Locations: file.NewLocationSet(
   272  						file.NewLocationFromCoordinates(
   273  							file.Coordinates{
   274  								RealPath:     "/a-path",
   275  								FileSystemID: "layer-id",
   276  							},
   277  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   278  					),
   279  					MetadataType: pkg.GolangBinMetadataType,
   280  					Metadata: pkg.GolangBinMetadata{
   281  						GoCompiledVersion: goCompiledVersion,
   282  						Architecture:      archDetails,
   283  						H1Digest:          "",
   284  						BuildSettings: map[string]string{
   285  							"GOAMD64": "v1",
   286  							"GOARCH":  "amd64",
   287  							"GOOS":    "darwin",
   288  						},
   289  						MainModule:     "github.com/a/b/c",
   290  						CryptoSettings: "boringcrypto + fips",
   291  					},
   292  				},
   293  			},
   294  		},
   295  		{
   296  			name: "parse a mod without packages",
   297  			arch: archDetails,
   298  			mod: &ExtendedBuildInfo{
   299  				&debug.BuildInfo{
   300  					GoVersion: goCompiledVersion,
   301  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   302  					Settings: []debug.BuildSetting{
   303  						{Key: "GOARCH", Value: archDetails},
   304  						{Key: "GOOS", Value: "darwin"},
   305  						{Key: "GOAMD64", Value: "v1"},
   306  					},
   307  				}, "",
   308  			},
   309  			expected: []pkg.Package{unmodifiedMain},
   310  		},
   311  		{
   312  			name: "parse main mod and replace devel pseudo version and ldflags exists (but contains no version)",
   313  			arch: archDetails,
   314  			mod: &ExtendedBuildInfo{
   315  				&debug.BuildInfo{
   316  					GoVersion: goCompiledVersion,
   317  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   318  					Settings: []debug.BuildSetting{
   319  						{Key: "GOARCH", Value: archDetails},
   320  						{Key: "GOOS", Value: "darwin"},
   321  						{Key: "GOAMD64", Value: "v1"},
   322  						{Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"},
   323  						{Key: "vcs.time", Value: "2022-10-14T19:54:57Z"},
   324  						{Key: "-ldflags", Value: `build	-ldflags="-w -s -extldflags '-static' -X blah=foobar`},
   325  					},
   326  				}, "",
   327  			},
   328  			expected: []pkg.Package{
   329  				{
   330  					Name:     "github.com/kastenhq/syft",
   331  					Language: pkg.Go,
   332  					Type:     pkg.GoModulePkg,
   333  					Version:  "v0.0.0-20221014195457-41bc6bb41035",
   334  					PURL:     "pkg:golang/github.com/anchore/syft@v0.0.0-20221014195457-41bc6bb41035",
   335  					Locations: file.NewLocationSet(
   336  						file.NewLocationFromCoordinates(
   337  							file.Coordinates{
   338  								RealPath:     "/a-path",
   339  								FileSystemID: "layer-id",
   340  							},
   341  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   342  					),
   343  					MetadataType: pkg.GolangBinMetadataType,
   344  					Metadata: pkg.GolangBinMetadata{
   345  						GoCompiledVersion: goCompiledVersion,
   346  						Architecture:      archDetails,
   347  						BuildSettings: map[string]string{
   348  							"GOARCH":       archDetails,
   349  							"GOOS":         "darwin",
   350  							"GOAMD64":      "v1",
   351  							"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
   352  							"vcs.time":     "2022-10-14T19:54:57Z",
   353  							"-ldflags":     `build	-ldflags="-w -s -extldflags '-static' -X blah=foobar`,
   354  						},
   355  						MainModule: "github.com/kastenhq/syft",
   356  					},
   357  				},
   358  			},
   359  		},
   360  		{
   361  			name: "parse main mod and replace devel version with one from ldflags with vcs. build settings",
   362  			arch: archDetails,
   363  			mod: &ExtendedBuildInfo{
   364  				&debug.BuildInfo{
   365  					GoVersion: goCompiledVersion,
   366  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   367  					Settings: []debug.BuildSetting{
   368  						{Key: "GOARCH", Value: archDetails},
   369  						{Key: "GOOS", Value: "darwin"},
   370  						{Key: "GOAMD64", Value: "v1"},
   371  						{Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"},
   372  						{Key: "vcs.time", Value: "2022-10-14T19:54:57Z"},
   373  						{Key: "-ldflags", Value: `build	-ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`},
   374  					},
   375  				}, "",
   376  			},
   377  			expected: []pkg.Package{
   378  				{
   379  					Name:     "github.com/kastenhq/syft",
   380  					Language: pkg.Go,
   381  					Type:     pkg.GoModulePkg,
   382  					Version:  "v0.79.0",
   383  					PURL:     "pkg:golang/github.com/anchore/syft@v0.79.0",
   384  					Locations: file.NewLocationSet(
   385  						file.NewLocationFromCoordinates(
   386  							file.Coordinates{
   387  								RealPath:     "/a-path",
   388  								FileSystemID: "layer-id",
   389  							},
   390  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   391  					),
   392  					MetadataType: pkg.GolangBinMetadataType,
   393  					Metadata: pkg.GolangBinMetadata{
   394  						GoCompiledVersion: goCompiledVersion,
   395  						Architecture:      archDetails,
   396  						BuildSettings: map[string]string{
   397  							"GOARCH":       archDetails,
   398  							"GOOS":         "darwin",
   399  							"GOAMD64":      "v1",
   400  							"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
   401  							"vcs.time":     "2022-10-14T19:54:57Z",
   402  							"-ldflags":     `build	-ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`,
   403  						},
   404  						MainModule: "github.com/kastenhq/syft",
   405  					},
   406  				},
   407  			},
   408  		},
   409  		{
   410  			name: "parse main mod and replace devel version with one from ldflags without any vcs. build settings",
   411  			arch: archDetails,
   412  			mod: &ExtendedBuildInfo{
   413  				&debug.BuildInfo{
   414  					GoVersion: goCompiledVersion,
   415  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   416  					Settings: []debug.BuildSetting{
   417  						{Key: "GOARCH", Value: archDetails},
   418  						{Key: "GOOS", Value: "darwin"},
   419  						{Key: "GOAMD64", Value: "v1"},
   420  						{Key: "-ldflags", Value: `build	-ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`},
   421  					},
   422  				}, "",
   423  			},
   424  			expected: []pkg.Package{
   425  				{
   426  					Name:     "github.com/kastenhq/syft",
   427  					Language: pkg.Go,
   428  					Type:     pkg.GoModulePkg,
   429  					Version:  "v0.79.0",
   430  					PURL:     "pkg:golang/github.com/anchore/syft@v0.79.0",
   431  					Locations: file.NewLocationSet(
   432  						file.NewLocationFromCoordinates(
   433  							file.Coordinates{
   434  								RealPath:     "/a-path",
   435  								FileSystemID: "layer-id",
   436  							},
   437  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   438  					),
   439  					MetadataType: pkg.GolangBinMetadataType,
   440  					Metadata: pkg.GolangBinMetadata{
   441  						GoCompiledVersion: goCompiledVersion,
   442  						Architecture:      archDetails,
   443  						BuildSettings: map[string]string{
   444  							"GOARCH":   archDetails,
   445  							"GOOS":     "darwin",
   446  							"GOAMD64":  "v1",
   447  							"-ldflags": `build	-ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`,
   448  						},
   449  						MainModule: "github.com/kastenhq/syft",
   450  					},
   451  				},
   452  			},
   453  		},
   454  		{
   455  			name: "parse main mod and replace devel version with one from ldflags main.version without any vcs. build settings",
   456  			arch: archDetails,
   457  			mod: &ExtendedBuildInfo{
   458  				&debug.BuildInfo{
   459  					GoVersion: goCompiledVersion,
   460  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   461  					Settings: []debug.BuildSetting{
   462  						{Key: "GOARCH", Value: archDetails},
   463  						{Key: "GOOS", Value: "darwin"},
   464  						{Key: "GOAMD64", Value: "v1"},
   465  						{Key: "-ldflags", Value: `build	-ldflags="-w -s -extldflags '-static' -X main.version=0.79.0`},
   466  					},
   467  				}, "",
   468  			},
   469  			expected: []pkg.Package{
   470  				{
   471  					Name:     "github.com/kastenhq/syft",
   472  					Language: pkg.Go,
   473  					Type:     pkg.GoModulePkg,
   474  					Version:  "v0.79.0",
   475  					PURL:     "pkg:golang/github.com/anchore/syft@v0.79.0",
   476  					Locations: file.NewLocationSet(
   477  						file.NewLocationFromCoordinates(
   478  							file.Coordinates{
   479  								RealPath:     "/a-path",
   480  								FileSystemID: "layer-id",
   481  							},
   482  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   483  					),
   484  					MetadataType: pkg.GolangBinMetadataType,
   485  					Metadata: pkg.GolangBinMetadata{
   486  						GoCompiledVersion: goCompiledVersion,
   487  						Architecture:      archDetails,
   488  						BuildSettings: map[string]string{
   489  							"GOARCH":   archDetails,
   490  							"GOOS":     "darwin",
   491  							"GOAMD64":  "v1",
   492  							"-ldflags": `build	-ldflags="-w -s -extldflags '-static' -X main.version=0.79.0`,
   493  						},
   494  						MainModule: "github.com/kastenhq/syft",
   495  					},
   496  				},
   497  			},
   498  		},
   499  		{
   500  			name: "parse main mod and replace devel version with one from ldflags main.Version without any vcs. build settings",
   501  			arch: archDetails,
   502  			mod: &ExtendedBuildInfo{
   503  				&debug.BuildInfo{
   504  					GoVersion: goCompiledVersion,
   505  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   506  					Settings: []debug.BuildSetting{
   507  						{Key: "GOARCH", Value: archDetails},
   508  						{Key: "GOOS", Value: "darwin"},
   509  						{Key: "GOAMD64", Value: "v1"},
   510  						{Key: "-ldflags", Value: `build	-ldflags="-w -s -extldflags '-static' -X main.Version=0.79.0`},
   511  					},
   512  				}, "",
   513  			},
   514  			expected: []pkg.Package{
   515  				{
   516  					Name:     "github.com/kastenhq/syft",
   517  					Language: pkg.Go,
   518  					Type:     pkg.GoModulePkg,
   519  					Version:  "v0.79.0",
   520  					PURL:     "pkg:golang/github.com/anchore/syft@v0.79.0",
   521  					Locations: file.NewLocationSet(
   522  						file.NewLocationFromCoordinates(
   523  							file.Coordinates{
   524  								RealPath:     "/a-path",
   525  								FileSystemID: "layer-id",
   526  							},
   527  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   528  					),
   529  					MetadataType: pkg.GolangBinMetadataType,
   530  					Metadata: pkg.GolangBinMetadata{
   531  						GoCompiledVersion: goCompiledVersion,
   532  						Architecture:      archDetails,
   533  						BuildSettings: map[string]string{
   534  							"GOARCH":   archDetails,
   535  							"GOOS":     "darwin",
   536  							"GOAMD64":  "v1",
   537  							"-ldflags": `build	-ldflags="-w -s -extldflags '-static' -X main.Version=0.79.0`,
   538  						},
   539  						MainModule: "github.com/kastenhq/syft",
   540  					},
   541  				},
   542  			},
   543  		},
   544  		{
   545  			name: "parse main mod and replace devel version with a pseudo version",
   546  			arch: archDetails,
   547  			mod: &ExtendedBuildInfo{
   548  				&debug.BuildInfo{
   549  					GoVersion: goCompiledVersion,
   550  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   551  					Settings: []debug.BuildSetting{
   552  						{Key: "GOARCH", Value: archDetails},
   553  						{Key: "GOOS", Value: "darwin"},
   554  						{Key: "GOAMD64", Value: "v1"},
   555  						{Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"},
   556  						{Key: "vcs.time", Value: "2022-10-14T19:54:57Z"},
   557  					},
   558  				}, "",
   559  			},
   560  			expected: []pkg.Package{
   561  				{
   562  					Name:     "github.com/kastenhq/syft",
   563  					Language: pkg.Go,
   564  					Type:     pkg.GoModulePkg,
   565  					Version:  "v0.0.0-20221014195457-41bc6bb41035",
   566  					PURL:     "pkg:golang/github.com/anchore/syft@v0.0.0-20221014195457-41bc6bb41035",
   567  					Locations: file.NewLocationSet(
   568  						file.NewLocationFromCoordinates(
   569  							file.Coordinates{
   570  								RealPath:     "/a-path",
   571  								FileSystemID: "layer-id",
   572  							},
   573  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   574  					),
   575  					MetadataType: pkg.GolangBinMetadataType,
   576  					Metadata: pkg.GolangBinMetadata{
   577  						GoCompiledVersion: goCompiledVersion,
   578  						Architecture:      archDetails,
   579  						BuildSettings: map[string]string{
   580  							"GOARCH":       archDetails,
   581  							"GOOS":         "darwin",
   582  							"GOAMD64":      "v1",
   583  							"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
   584  							"vcs.time":     "2022-10-14T19:54:57Z",
   585  						},
   586  						MainModule: "github.com/kastenhq/syft",
   587  					},
   588  				},
   589  			},
   590  		},
   591  		{
   592  			name: "parse a populated mod string and returns packages but no source info",
   593  			arch: archDetails,
   594  			mod: &ExtendedBuildInfo{
   595  				&debug.BuildInfo{
   596  					GoVersion: goCompiledVersion,
   597  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   598  					Settings: []debug.BuildSetting{
   599  						{Key: "GOARCH", Value: archDetails},
   600  						{Key: "GOOS", Value: "darwin"},
   601  						{Key: "GOAMD64", Value: "v1"},
   602  					},
   603  					Deps: []*debug.Module{
   604  						{
   605  							Path:    "github.com/adrg/xdg",
   606  							Version: "v0.2.1",
   607  							Sum:     "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=",
   608  						},
   609  						{
   610  							Path:    "github.com/anchore/client-go",
   611  							Version: "v0.0.0-20210222170800-9c70f9b80bcf",
   612  							Sum:     "h1:DYssiUV1pBmKqzKsm4mqXx8artqC0Q8HgZsVI3lMsAg=",
   613  						},
   614  					},
   615  				}, "",
   616  			},
   617  			expected: []pkg.Package{
   618  				{
   619  					Name:     "github.com/adrg/xdg",
   620  					Version:  "v0.2.1",
   621  					PURL:     "pkg:golang/github.com/adrg/xdg@v0.2.1",
   622  					Language: pkg.Go,
   623  					Type:     pkg.GoModulePkg,
   624  					Locations: file.NewLocationSet(
   625  						file.NewLocationFromCoordinates(
   626  							file.Coordinates{
   627  								RealPath:     "/a-path",
   628  								FileSystemID: "layer-id",
   629  							},
   630  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   631  					),
   632  					MetadataType: pkg.GolangBinMetadataType,
   633  					Metadata: pkg.GolangBinMetadata{
   634  						GoCompiledVersion: goCompiledVersion,
   635  						Architecture:      archDetails,
   636  						H1Digest:          "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=",
   637  						MainModule:        "github.com/kastenhq/syft",
   638  					},
   639  				},
   640  				{
   641  					Name:     "github.com/anchore/client-go",
   642  					Version:  "v0.0.0-20210222170800-9c70f9b80bcf",
   643  					PURL:     "pkg:golang/github.com/anchore/client-go@v0.0.0-20210222170800-9c70f9b80bcf",
   644  					Language: pkg.Go,
   645  					Type:     pkg.GoModulePkg,
   646  					Locations: file.NewLocationSet(
   647  						file.NewLocationFromCoordinates(
   648  							file.Coordinates{
   649  								RealPath:     "/a-path",
   650  								FileSystemID: "layer-id",
   651  							},
   652  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   653  					),
   654  					MetadataType: pkg.GolangBinMetadataType,
   655  					Metadata: pkg.GolangBinMetadata{
   656  						GoCompiledVersion: goCompiledVersion,
   657  						Architecture:      archDetails,
   658  						H1Digest:          "h1:DYssiUV1pBmKqzKsm4mqXx8artqC0Q8HgZsVI3lMsAg=",
   659  						MainModule:        "github.com/kastenhq/syft",
   660  					},
   661  				},
   662  				unmodifiedMain,
   663  			},
   664  		},
   665  		{
   666  			name: "parse a populated mod string and returns packages when a replace directive exists",
   667  			arch: archDetails,
   668  			mod: &ExtendedBuildInfo{
   669  				&debug.BuildInfo{
   670  					GoVersion: goCompiledVersion,
   671  					Main:      debug.Module{Path: "github.com/kastenhq/syft", Version: "(devel)"},
   672  					Settings: []debug.BuildSetting{
   673  						{Key: "GOARCH", Value: archDetails},
   674  						{Key: "GOOS", Value: "darwin"},
   675  						{Key: "GOAMD64", Value: "v1"},
   676  					},
   677  					Deps: []*debug.Module{
   678  						{
   679  							Path:    "golang.org/x/sys",
   680  							Version: "v0.0.0-20211006194710-c8a6f5223071",
   681  							Sum:     "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=",
   682  						},
   683  						{
   684  							Path:    "golang.org/x/term",
   685  							Version: "v0.0.0-20210927222741-03fcf44c2211",
   686  							Sum:     "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=",
   687  							Replace: &debug.Module{
   688  								Path:    "golang.org/x/term",
   689  								Version: "v0.0.0-20210916214954-140adaaadfaf",
   690  								Sum:     "h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI=",
   691  							},
   692  						},
   693  					},
   694  				}, "",
   695  			},
   696  			expected: []pkg.Package{
   697  				{
   698  					Name:     "golang.org/x/sys",
   699  					Version:  "v0.0.0-20211006194710-c8a6f5223071",
   700  					PURL:     "pkg:golang/golang.org/x/sys@v0.0.0-20211006194710-c8a6f5223071",
   701  					Language: pkg.Go,
   702  					Type:     pkg.GoModulePkg,
   703  					Locations: file.NewLocationSet(
   704  						file.NewLocationFromCoordinates(
   705  							file.Coordinates{
   706  								RealPath:     "/a-path",
   707  								FileSystemID: "layer-id",
   708  							},
   709  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   710  					),
   711  					MetadataType: pkg.GolangBinMetadataType,
   712  					Metadata: pkg.GolangBinMetadata{
   713  						GoCompiledVersion: goCompiledVersion,
   714  						Architecture:      archDetails,
   715  						H1Digest:          "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=",
   716  						MainModule:        "github.com/kastenhq/syft",
   717  					}},
   718  				{
   719  					Name:     "golang.org/x/term",
   720  					Version:  "v0.0.0-20210916214954-140adaaadfaf",
   721  					PURL:     "pkg:golang/golang.org/x/term@v0.0.0-20210916214954-140adaaadfaf",
   722  					Language: pkg.Go,
   723  					Type:     pkg.GoModulePkg,
   724  					Locations: file.NewLocationSet(
   725  						file.NewLocationFromCoordinates(
   726  							file.Coordinates{
   727  								RealPath:     "/a-path",
   728  								FileSystemID: "layer-id",
   729  							},
   730  						).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
   731  					),
   732  					MetadataType: pkg.GolangBinMetadataType,
   733  					Metadata: pkg.GolangBinMetadata{
   734  						GoCompiledVersion: goCompiledVersion,
   735  						Architecture:      archDetails,
   736  						H1Digest:          "h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI=",
   737  						MainModule:        "github.com/kastenhq/syft",
   738  					},
   739  				},
   740  				unmodifiedMain,
   741  			},
   742  		},
   743  	}
   744  
   745  	for _, test := range tests {
   746  		t.Run(test.name, func(t *testing.T) {
   747  			for i := range test.expected {
   748  				p := &test.expected[i]
   749  				p.SetID()
   750  			}
   751  			location := file.NewLocationFromCoordinates(
   752  				file.Coordinates{
   753  					RealPath:     "/a-path",
   754  					FileSystemID: "layer-id",
   755  				},
   756  			)
   757  
   758  			c := goBinaryCataloger{}
   759  			pkgs := c.buildGoPkgInfo(fileresolver.Empty{}, location, test.mod, test.arch)
   760  			assert.Equal(t, test.expected, pkgs)
   761  		})
   762  	}
   763  }
   764  
   765  func Test_extractVersionFromLDFlags(t *testing.T) {
   766  	tests := []struct {
   767  		name             string
   768  		ldflags          string
   769  		wantMajorVersion string
   770  		wantFullVersion  string
   771  	}{
   772  		{
   773  			name:    "empty ldflags",
   774  			ldflags: "",
   775  		},
   776  		{
   777  			name:             "syft ldflags",
   778  			ldflags:          `	build	-ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0 -X github.com/anchore/syft/internal/version.gitCommit=b2b332e8b2b66af0905e98b54ebd713a922be1a8 -X github.com/anchore/syft/internal/version.buildDate=2023-04-21T16:20:25Z -X github.com/anchore/syft/internal/version.gitDescription=v0.79.0 "`,
   779  			wantMajorVersion: "0",
   780  			wantFullVersion:  "v0.79.0",
   781  		},
   782  		{
   783  			name: "kubectl ldflags",
   784  			ldflags: `	build	-asmflags=all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes
   785  	build	-compiler=gc
   786  	build	-gcflags="all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes "
   787  	build	-ldflags="all=-X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.buildDate=2023-04-12T12:16:51Z' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.buildDate=2023-04-12T12:16:51Z' -X 'k8s.io/client-go/pkg/version.buildDate=2023-04-12T12:16:51Z' -X 'k8s.io/component-base/version.buildDate=2023-04-12T12:16:51Z' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitCommit=a1a87a0a2bcd605820920c6b0e618a8ab7d117d4' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitCommit=a1a87a0a2bcd605820920c6b0e618a8ab7d117d4' -X 'k8s.io/client-go/pkg/version.gitCommit=a1a87a0a2bcd605820920c6b0e618a8ab7d117d4' -X 'k8s.io/component-base/version.gitCommit=a1a87a0a2bcd605820920c6b0e618a8ab7d117d4' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitTreeState=clean' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitTreeState=clean' -X 'k8s.io/client-go/pkg/version.gitTreeState=clean' -X 'k8s.io/component-base/version.gitTreeState=clean' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitVersion=v1.25.9' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitVersion=v1.25.9' -X 'k8s.io/client-go/pkg/version.gitVersion=v1.25.9' -X 'k8s.io/component-base/version.gitVersion=v1.25.9' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitMajor=1' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitMajor=1' -X 'k8s.io/client-go/pkg/version.gitMajor=1' -X 'k8s.io/component-base/version.gitMajor=1' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitMinor=25' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitMinor=25' -X 'k8s.io/client-go/pkg/version.gitMinor=25' -X 'k8s.io/component-base/version.gitMinor=25'  -s -w"`,
   788  			wantMajorVersion: "1",
   789  			wantFullVersion:  "v1.25.9",
   790  		},
   791  		{
   792  			name:             "nerdctl ldflags",
   793  			ldflags:          `	build	-ldflags="-s -w -X github.com/containerd/nerdctl/pkg/version.Version=v1.3.1 -X github.com/containerd/nerdctl/pkg/version.Revision=b224b280ff3086516763c7335fc0e0997aca617a"`,
   794  			wantMajorVersion: "1",
   795  			wantFullVersion:  "v1.3.1",
   796  		},
   797  		{
   798  			name:             "limactl ldflags",
   799  			ldflags:          `	build	-ldflags="-s -w -X github.com/lima-vm/lima/pkg/version.Version=v0.15.1"`,
   800  			wantMajorVersion: "0",
   801  			wantFullVersion:  "v0.15.1",
   802  		},
   803  		{
   804  			name:             "terraform ldflags",
   805  			ldflags:          `	build	-ldflags="-w -s -X 'github.com/hashicorp/terraform/version.Version=1.4.6' -X 'github.com/hashicorp/terraform/version.Prerelease='"`,
   806  			wantMajorVersion: "1",
   807  			wantFullVersion:  "v1.4.6",
   808  		},
   809  		{
   810  			name: "kube-apiserver ldflags",
   811  			ldflags: `	build	-asmflags=all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes
   812  	build	-buildmode=exe
   813  	build	-compiler=gc
   814  	build	-gcflags="all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes "
   815  	build	-ldflags="all=-X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.buildDate=2023-04-14T13:14:42Z' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.buildDate=2023-04-14T13:14:42Z' -X 'k8s.io/client-go/pkg/version.buildDate=2023-04-14T13:14:42Z' -X 'k8s.io/component-base/version.buildDate=2023-04-14T13:14:42Z' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitCommit=4c9411232e10168d7b050c49a1b59f6df9d7ea4b' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitCommit=4c9411232e10168d7b050c49a1b59f6df9d7ea4b' -X 'k8s.io/client-go/pkg/version.gitCommit=4c9411232e10168d7b050c49a1b59f6df9d7ea4b' -X 'k8s.io/component-base/version.gitCommit=4c9411232e10168d7b050c49a1b59f6df9d7ea4b' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitTreeState=clean' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitTreeState=clean' -X 'k8s.io/client-go/pkg/version.gitTreeState=clean' -X 'k8s.io/component-base/version.gitTreeState=clean' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitVersion=v1.27.1' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitVersion=v1.27.1' -X 'k8s.io/client-go/pkg/version.gitVersion=v1.27.1' -X 'k8s.io/component-base/version.gitVersion=v1.27.1' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitMajor=1' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitMajor=1' -X 'k8s.io/client-go/pkg/version.gitMajor=1' -X 'k8s.io/component-base/version.gitMajor=1' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitMinor=27' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitMinor=27' -X 'k8s.io/client-go/pkg/version.gitMinor=27' -X 'k8s.io/component-base/version.gitMinor=27'  -s -w"`,
   816  			wantMajorVersion: "1",
   817  			wantFullVersion:  "v1.27.1",
   818  		},
   819  		{
   820  			name: "prometheus ldflags",
   821  			ldflags: `	build	-ldflags="-X github.com/prometheus/common/version.Version=2.44.0 -X github.com/prometheus/common/version.Revision=1ac5131f698ebc60f13fe2727f89b115a41f6558 -X github.com/prometheus/common/version.Branch=HEAD -X github.com/prometheus/common/version.BuildUser=root@739e8181c5db -X github.com/prometheus/common/version.BuildDate=20230514-06:18:11  -extldflags '-static'"
   822  	build	-tags=netgo,builtinassets,stringlabels`,
   823  			wantMajorVersion: "2",
   824  			wantFullVersion:  "v2.44.0",
   825  		},
   826  		{
   827  			name: "influxdb ldflags",
   828  			ldflags: `	build	-ldflags="-s -w -X main.version=v2.7.1 -X main.commit=407fa622e9 -X main.date=2023-04-28T13:24:27Z -linkmode=external -extld=/musl/x86_64/bin/musl-gcc -extldflags '-fno-PIC -static-pie -Wl,-z,stack-size=8388608'"
   829  	build	-tags=assets,sqlite_foreign_keys,sqlite_json,static_build,noasm`,
   830  			wantMajorVersion: "2",
   831  			wantFullVersion:  "v2.7.1",
   832  		},
   833  		{
   834  			name:             "gitea ldflags",
   835  			ldflags:          `	build	-ldflags=" -X \"main.MakeVersion=GNU Make 4.1\" -X \"main.Version=1.19.3\" -X \"main.Tags=bindata sqlite sqlite_unlock_notify\" "`,
   836  			wantMajorVersion: "1",
   837  			wantFullVersion:  "v1.19.3",
   838  		},
   839  		{
   840  			name:             "docker sbom cli ldflags",
   841  			ldflags:          `	build	-ldflags="-w -s -extldflags '-static' -X github.com/docker/sbom-cli-plugin/internal/version.version=0.6.1-SNAPSHOT-02cf1c8 -X github.com/docker/sbom-cli-plugin/internal/version.gitCommit=02cf1c888ad6662109ac6e3be618392514a56316 -X github.com/docker/sbom-cli-plugin/internal/version.gitDescription=v0.6.1-dirty "`,
   842  			wantMajorVersion: "0",
   843  			wantFullVersion:  "v0.6.1-SNAPSHOT-02cf1c8",
   844  		},
   845  		{
   846  			name:             "docker scout ldflags",
   847  			ldflags:          `	build	-ldflags="-w -s -extldflags '-static' -X github.com/docker/scout-cli-plugin/internal.version=0.10.0 "`,
   848  			wantMajorVersion: "0",
   849  			wantFullVersion:  "v0.10.0",
   850  		},
   851  		{
   852  			name:             "influx telegraf ldflags",
   853  			ldflags:          `	build	-ldflags="-w -s -X github.com/influxdata/telegraf/internal.Commit=a3a884a1 -X github.com/influxdata/telegraf/internal.Branch=HEAD -X github.com/influxdata/telegraf/internal.Version=1.26.2"`,
   854  			wantMajorVersion: "1",
   855  			wantFullVersion:  "v1.26.2",
   856  		},
   857  		{
   858  			name:             "argocd ldflags",
   859  			ldflags:          `	build	-ldflags="-X github.com/argoproj/argo-cd/v2/common.version=2.7.2 -X github.com/argoproj/argo-cd/v2/common.buildDate=2023-05-12T14:06:49Z -X github.com/argoproj/argo-cd/v2/common.gitCommit=cbee7e6011407ed2d1066c482db74e97e0cc6bdb -X github.com/argoproj/argo-cd/v2/common.gitTreeState=clean -X github.com/argoproj/argo-cd/v2/common.kubectlVersion=v0.24.2 -extldflags=\"-static\""`,
   860  			wantMajorVersion: "2",
   861  			wantFullVersion:  "v2.7.2",
   862  		},
   863  		{
   864  			name:             "kustomize ldflags",
   865  			ldflags:          `	build	-ldflags="-s -X sigs.k8s.io/kustomize/api/provenance.version=kustomize/v4.5.7 -X sigs.k8s.io/kustomize/api/provenance.gitCommit=56d82a8378dfc8dc3b3b1085e5a6e67b82966bd7 -X sigs.k8s.io/kustomize/api/provenance.buildDate=2022-08-02T16:35:54Z "`,
   866  			wantMajorVersion: "4",
   867  			wantFullVersion:  "v4.5.7",
   868  		},
   869  		//////////////////////////////////////////////////////////////////
   870  		// negative cases
   871  		{
   872  			name:    "hugo ldflags",
   873  			ldflags: `	build	-ldflags="-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=gohugoio"`,
   874  		},
   875  		{
   876  			name:    "ghostunnel ldflags",
   877  			ldflags: `	build	-ldflags="-X main.version=77d9aaa"`,
   878  		},
   879  		{
   880  			name:    "opa ldflags",
   881  			ldflags: `build	-ldflags=" -X github.com/open-policy-agent/opa/version.Hostname=9549178459bc"`,
   882  		},
   883  		///////////////////////////////////////////////////////////////////
   884  		// trickier cases
   885  		{
   886  			name:             "macvlan plugin for cri-o ldflags",
   887  			ldflags:          `	build	-ldflags="-extldflags -static -X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=v1.2.0"`,
   888  			wantMajorVersion: "1",
   889  			wantFullVersion:  "v1.2.0",
   890  		},
   891  		{
   892  			name:             "coder ldflags",
   893  			ldflags:          `	build	-ldflags="-s -w -X 'github.com/coder/coder/buildinfo.tag=0.23.4'"`,
   894  			wantMajorVersion: "0",
   895  			wantFullVersion:  "v0.23.4",
   896  		},
   897  		///////////////////////////////////////////////////////////////////
   898  		// don't know how to handle these... yet
   899  		//{
   900  		//	// package name: pkgName: "github.com/krakendio/krakend-ce/v2",
   901  		//	name:             "krakenD ldflags",
   902  		//	ldflags:          `	build	-ldflags="-X github.com/luraproject/lura/v2/core.KrakendVersion=2.3.2 -X github.com/luraproject/lura/v2/core.GoVersion=1.20.4 -X github.com/luraproject/lura/v2/core.GlibcVersion=GLIBC-2.31_(debian-11) "`,
   903  		//	wantMajorVersion: "2.3.2",
   904  		//	wantFullVersion:  "v2.3.2",
   905  		//},
   906  		//{
   907  		//	// package name: pkgName: "github.com/krakendio/krakend-ce/v2",
   908  		//	name:             "krakenD ldflags -- answer embedded in the middle",
   909  		//	ldflags:          `	build	-ldflags=" -X github.com/luraproject/lura/v2/core.GoVersion=1.20.4 -X github.com/luraproject/lura/v2/core.KrakendVersion=2.3.2 -X github.com/luraproject/lura/v2/core.GlibcVersion=GLIBC-2.31_(debian-11) "`,
   910  		//	wantMajorVersion: "2.3.2",
   911  		//	wantFullVersion:  "v2.3.2",
   912  		//},
   913  	}
   914  	for _, tt := range tests {
   915  		t.Run(tt.name, func(t *testing.T) {
   916  			gotMajorVersion, gotFullVersion := extractVersionFromLDFlags(tt.ldflags)
   917  			assert.Equal(t, tt.wantMajorVersion, gotMajorVersion, "unexpected major version")
   918  			assert.Equal(t, tt.wantFullVersion, gotFullVersion, "unexpected full version")
   919  		})
   920  	}
   921  }