github.com/wolfi-dev/wolfictl@v0.16.11/pkg/distro/detect_test.go (about)

     1  package distro
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/go-git/go-git/v5"
    10  	"github.com/go-git/go-git/v5/config"
    11  	"github.com/go-git/go-git/v5/plumbing"
    12  	"github.com/go-git/go-git/v5/plumbing/object"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestDetect(t *testing.T) {
    18  	// Create a test directory with a few git repos, some of which are distro-related
    19  	tempDir, err := os.MkdirTemp("", "test-distro-detect-")
    20  	require.NoError(t, err)
    21  	t.Cleanup(func() {
    22  		err := os.RemoveAll(tempDir)
    23  		require.NoError(t, err)
    24  	})
    25  
    26  	repos := []struct {
    27  		name       string
    28  		remoteURLs []string
    29  	}{
    30  		{
    31  			name: "my-wolfi",
    32  			remoteURLs: []string{
    33  				"https://github.com/wolfi-dev/os.git",
    34  				"https://foo.git",
    35  			},
    36  		},
    37  		{
    38  			name: "some-other-repo",
    39  			remoteURLs: []string{
    40  				"https://some-other-repo.git",
    41  			},
    42  		},
    43  		{
    44  			name: "my-advisories",
    45  			remoteURLs: []string{
    46  				"git@github.com:wolfi-dev/advisories.git",
    47  			},
    48  		},
    49  	}
    50  
    51  	repoAbsolutePath := func(repoName string) string {
    52  		return filepath.Join(tempDir, repoName)
    53  	}
    54  
    55  	for _, r := range repos {
    56  		repoDir := repoAbsolutePath(r.name)
    57  		err := os.Mkdir(repoDir, 0o755)
    58  		require.NoError(t, err)
    59  
    60  		_, err = git.PlainInit(repoDir, false)
    61  		require.NoError(t, err)
    62  
    63  		repo, err := git.PlainOpen(repoDir)
    64  		require.NoError(t, err)
    65  
    66  		_, err = repo.CreateRemote(&config.RemoteConfig{
    67  			Name: "origin",
    68  			URLs: r.remoteURLs,
    69  		})
    70  		require.NoError(t, err)
    71  
    72  		// We need to create a commit so that HEAD exists.
    73  		w, err := repo.Worktree()
    74  		require.NoError(t, err)
    75  		commit, err := w.Commit("Initial commit", &git.CommitOptions{
    76  			AllowEmptyCommits: true,
    77  			Author: &object.Signature{
    78  				Name:  "test",
    79  				Email: "test@test.com",
    80  				When:  time.Unix(0, 0),
    81  			},
    82  		})
    83  		require.NoError(t, err)
    84  
    85  		// Create a branch named "main" and set it as the HEAD of the repository.
    86  		mainRef := plumbing.NewHashReference("refs/heads/main", commit)
    87  		err = repo.Storer.SetReference(mainRef)
    88  		require.NoError(t, err)
    89  
    90  		// Create a symbolic reference named "refs/remotes/origin/main" that points to the local "main" branch.
    91  		originMainRef := plumbing.NewSymbolicReference("refs/remotes/origin/main", mainRef.Name())
    92  		err = repo.Storer.SetReference(originMainRef)
    93  		require.NoError(t, err)
    94  
    95  		symbolicRef := plumbing.NewSymbolicReference(plumbing.HEAD, mainRef.Name())
    96  		err = repo.Storer.SetReference(symbolicRef)
    97  		require.NoError(t, err)
    98  	}
    99  
   100  	originalWorkDir, err := os.Getwd()
   101  	require.NoError(t, err)
   102  	t.Cleanup(func() {
   103  		_ = os.Chdir(originalWorkDir) //nolint:errCheck
   104  	})
   105  
   106  	newWorkDir := repoAbsolutePath(repos[0].name)
   107  	err = os.Chdir(newWorkDir)
   108  	require.NoError(t, err)
   109  
   110  	// Run the function under test
   111  
   112  	d, err := Detect()
   113  	require.NoError(t, err)
   114  
   115  	// Check the results
   116  
   117  	// (We need to resolve the symlinks because this test uses temp dirs, which are symlinked on some operating systems.)
   118  	expectedDistroRepoDir, err := filepath.EvalSymlinks(repoAbsolutePath(repos[0].name))
   119  	require.NoError(t, err)
   120  	expectedAdvisoriesRepoDir, err := filepath.EvalSymlinks(repoAbsolutePath(repos[2].name))
   121  	require.NoError(t, err)
   122  
   123  	assert.Equal(t, "Wolfi", d.Absolute.Name)
   124  	assert.Equal(t, expectedDistroRepoDir, d.Local.PackagesRepo.Dir)
   125  	assert.Equal(t, expectedAdvisoriesRepoDir, d.Local.AdvisoriesRepo.Dir)
   126  	assert.Equal(t, "https://packages.wolfi.dev/os", d.Absolute.APKRepositoryURL)
   127  }
   128  
   129  func TestDetectV2(t *testing.T) {
   130  	tempDir, err := os.MkdirTemp("", "test-distro-detect-")
   131  	require.NoError(t, err)
   132  	t.Cleanup(func() {
   133  		err := os.RemoveAll(tempDir)
   134  		require.NoError(t, err)
   135  	})
   136  
   137  	r := struct {
   138  		name       string
   139  		remoteURLs []string
   140  	}{
   141  		name: "my-wolfi",
   142  		remoteURLs: []string{
   143  			"https://github.com/wolfi-dev/os.git",
   144  			"https://foo.git",
   145  		},
   146  	}
   147  
   148  	repoDir := filepath.Join(tempDir, r.name)
   149  	err = os.Mkdir(repoDir, 0o755)
   150  	require.NoError(t, err)
   151  
   152  	_, err = git.PlainInit(repoDir, false)
   153  	require.NoError(t, err)
   154  
   155  	repo, err := git.PlainOpen(repoDir)
   156  	require.NoError(t, err)
   157  
   158  	_, err = repo.CreateRemote(&config.RemoteConfig{
   159  		Name: "origin",
   160  		URLs: r.remoteURLs,
   161  	})
   162  	require.NoError(t, err)
   163  
   164  	// We need to create a commit so that HEAD exists.
   165  	w, err := repo.Worktree()
   166  	require.NoError(t, err)
   167  	commit, err := w.Commit("Initial commit", &git.CommitOptions{
   168  		AllowEmptyCommits: true,
   169  		Author: &object.Signature{
   170  			Name:  "test",
   171  			Email: "test@test.com",
   172  			When:  time.Unix(0, 0),
   173  		},
   174  	})
   175  	require.NoError(t, err)
   176  
   177  	// Create a branch named "main" and set it as the HEAD of the repository.
   178  	mainRef := plumbing.NewHashReference("refs/heads/main", commit)
   179  	err = repo.Storer.SetReference(mainRef)
   180  	require.NoError(t, err)
   181  
   182  	// Create a symbolic reference named "refs/remotes/origin/main" that points to the local "main" branch.
   183  	originMainRef := plumbing.NewSymbolicReference("refs/remotes/origin/main", mainRef.Name())
   184  	err = repo.Storer.SetReference(originMainRef)
   185  	require.NoError(t, err)
   186  
   187  	symbolicRef := plumbing.NewSymbolicReference(plumbing.HEAD, mainRef.Name())
   188  	err = repo.Storer.SetReference(symbolicRef)
   189  	require.NoError(t, err)
   190  
   191  	originalWorkDir, err := os.Getwd()
   192  	require.NoError(t, err)
   193  	t.Cleanup(func() {
   194  		_ = os.Chdir(originalWorkDir) //nolint:errCheck
   195  	})
   196  
   197  	err = os.Chdir(repoDir)
   198  	require.NoError(t, err)
   199  
   200  	// Run the function under test
   201  
   202  	d, err := DetectV2()
   203  	require.NoError(t, err)
   204  
   205  	// Check the results
   206  
   207  	// (We need to resolve the symlinks because this test uses temp dirs, which are symlinked on some operating systems.)
   208  	expectedDistroRepoDir, err := filepath.EvalSymlinks(func(repoName string) string {
   209  		return filepath.Join(tempDir, repoName)
   210  	}(r.name))
   211  	require.NoError(t, err)
   212  
   213  	assert.Equal(t, "Wolfi", d.Absolute.Name)
   214  	assert.Equal(t, expectedDistroRepoDir, d.Local.PackagesRepo.Dir)
   215  	assert.Equal(t, "https://packages.wolfi.dev/os", d.Absolute.APKRepositoryURL)
   216  }