279 lines
7.7 KiB
Go
279 lines
7.7 KiB
Go
package apt
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// createTestSolver creates a test solver with default configuration
|
|
func createTestSolver(t *testing.T) *Solver {
|
|
tmpDir := t.TempDir()
|
|
repos := []RepoConfig{
|
|
{
|
|
BaseURL: "http://deb.debian.org/debian",
|
|
Components: []string{"main"},
|
|
Priority: 500,
|
|
},
|
|
}
|
|
solver, err := NewSolver(tmpDir, "amd64", repos)
|
|
require.NoError(t, err)
|
|
return solver
|
|
}
|
|
|
|
func TestSolverCreation(t *testing.T) {
|
|
// Test creating a new solver
|
|
solver := createTestSolver(t)
|
|
assert.NotNil(t, solver)
|
|
assert.NotNil(t, solver.repos)
|
|
}
|
|
|
|
func TestMockDepsolve(t *testing.T) {
|
|
solver := createTestSolver(t)
|
|
|
|
// Test mock depsolve with empty package list
|
|
result, err := solver.mockDepsolve([]string{})
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, result)
|
|
assert.Empty(t, result.Packages)
|
|
|
|
// Test mock depsolve with some packages
|
|
packages := []string{"base-files", "systemd", "linux-image-amd64"}
|
|
result, err = solver.mockDepsolve(packages)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, result)
|
|
|
|
// Check that we got PackageSpec structs with correct names
|
|
expectedNames := []string{"base-files", "systemd", "linux-image-amd64"}
|
|
actualNames := make([]string, len(result.Packages))
|
|
for i, pkg := range result.Packages {
|
|
actualNames[i] = pkg.Name
|
|
}
|
|
assert.Equal(t, expectedNames, actualNames)
|
|
}
|
|
|
|
func TestDepsolve(t *testing.T) {
|
|
solver := createTestSolver(t)
|
|
|
|
// Test depsolve with empty package list
|
|
result, err := solver.Depsolve([]string{}, 0)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, result)
|
|
assert.Empty(t, result.Packages)
|
|
|
|
// Test depsolve with some packages (should fall back to mock)
|
|
packages := []string{"base-files", "systemd", "linux-image-amd64"}
|
|
result, err = solver.Depsolve(packages, 0)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, result)
|
|
|
|
// Check that we got PackageSpec structs with correct names
|
|
expectedNames := []string{"base-files", "systemd", "linux-image-amd64"}
|
|
actualNames := make([]string, len(result.Packages))
|
|
for i, pkg := range result.Packages {
|
|
actualNames[i] = pkg.Name
|
|
}
|
|
assert.Equal(t, expectedNames, actualNames)
|
|
}
|
|
|
|
func TestParseAptOutput(t *testing.T) {
|
|
solver := createTestSolver(t)
|
|
|
|
// Test with empty output
|
|
result := solver.parseAptOutput("")
|
|
assert.Empty(t, result)
|
|
|
|
// Test with valid package names
|
|
output := `base-files
|
|
systemd
|
|
linux-image-amd64
|
|
grub-common`
|
|
result = solver.parseAptOutput(output)
|
|
expected := []string{"base-files", "systemd", "linux-image-amd64", "grub-common"}
|
|
assert.ElementsMatch(t, expected, result)
|
|
|
|
// Test with dependency keywords (should be filtered out)
|
|
output = `Depends: base-files
|
|
PreDepends: systemd
|
|
Breaks: old-package
|
|
Replaces: old-package
|
|
Conflicts: conflicting-package
|
|
Recommends: recommended-package
|
|
Suggests: suggested-package
|
|
Enhances: enhanced-package
|
|
|Depends: alternative-package
|
|
|PreDepends: alternative-pre-depends
|
|
Enhances: enhanced-package
|
|
base-files
|
|
systemd`
|
|
result = solver.parseAptOutput(output)
|
|
expected = []string{"base-files", "systemd"}
|
|
assert.ElementsMatch(t, expected, result)
|
|
|
|
// Test with package names containing special characters (should be filtered out)
|
|
output = `base-files
|
|
<virtual-package>
|
|
>version-constraint
|
|
|alternative-package
|
|
base-files:amd64
|
|
systemd`
|
|
result = solver.parseAptOutput(output)
|
|
expected = []string{"base-files", "systemd"}
|
|
assert.ElementsMatch(t, expected, result)
|
|
|
|
// Test with mixed content
|
|
output = `Depends: base-files
|
|
systemd
|
|
Breaks: old-package
|
|
linux-image-amd64
|
|
|Depends: alternative
|
|
grub-common
|
|
Enhances: enhanced
|
|
bootc`
|
|
result = solver.parseAptOutput(output)
|
|
expected = []string{"systemd", "linux-image-amd64", "grub-common", "bootc"}
|
|
assert.ElementsMatch(t, expected, result)
|
|
}
|
|
|
|
func TestCreateAptConf(t *testing.T) {
|
|
solver := createTestSolver(t)
|
|
|
|
// Test creating apt configuration
|
|
aptConfPath, err := solver.createAptConf()
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, aptConfPath)
|
|
|
|
// Check that apt.conf was created
|
|
assert.FileExists(t, aptConfPath)
|
|
|
|
// Check that sources.list was created in the same directory as apt.conf
|
|
sourcesListPath := filepath.Join(filepath.Dir(aptConfPath), "sources.list")
|
|
assert.FileExists(t, sourcesListPath)
|
|
|
|
// Read and verify apt.conf content
|
|
aptConfContent, err := os.ReadFile(aptConfPath)
|
|
assert.NoError(t, err)
|
|
aptConfStr := string(aptConfContent)
|
|
assert.Contains(t, aptConfStr, "Dir::Etc::SourceList")
|
|
assert.Contains(t, aptConfStr, "sources.list")
|
|
|
|
// Read and verify sources.list content
|
|
sourcesListContent, err := os.ReadFile(sourcesListPath)
|
|
assert.NoError(t, err)
|
|
sourcesListStr := string(sourcesListContent)
|
|
assert.Contains(t, sourcesListStr, "deb.debian.org")
|
|
assert.Contains(t, sourcesListStr, "main")
|
|
}
|
|
|
|
func TestGetPackageVersion(t *testing.T) {
|
|
solver := createTestSolver(t)
|
|
|
|
// Test getting version for a package (may get real version or fall back to mock)
|
|
version, err := solver.getPackageVersion("base-files", "")
|
|
// Don't assert specific version since it depends on system state
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, version)
|
|
|
|
// Test getting version for non-existent package (should fall back to mock)
|
|
version, err = solver.getPackageVersion("non-existent-package", "")
|
|
// This might fail with real apt-cache, so we just check it doesn't panic
|
|
_ = version
|
|
_ = err
|
|
}
|
|
|
|
func TestRealDepsolve(t *testing.T) {
|
|
solver := createTestSolver(t)
|
|
|
|
// Test real depsolve (may fail if apt-cache is not available)
|
|
result, err := solver.realDepsolve([]string{"base-files"})
|
|
|
|
// We don't assert success here because apt-cache may not be available in test environment
|
|
// The important thing is that it doesn't panic
|
|
// Result might be nil if apt-cache fails, which is acceptable
|
|
_ = result
|
|
_ = err // Suppress unused variable warning
|
|
}
|
|
|
|
func TestSolverWithCustomRepos(t *testing.T) {
|
|
// Test creating solver with custom repositories
|
|
repos := []RepoConfig{
|
|
{
|
|
BaseURL: "http://deb.debian.org/debian",
|
|
Components: []string{"main"},
|
|
Priority: 500,
|
|
},
|
|
{
|
|
BaseURL: "https://git.raines.xyz/api/packages/particle-os/debian",
|
|
Components: []string{"trixie", "main"},
|
|
Priority: 400,
|
|
},
|
|
}
|
|
|
|
solver := &Solver{repos: repos}
|
|
assert.NotNil(t, solver)
|
|
assert.Equal(t, repos, solver.repos)
|
|
}
|
|
|
|
func TestDepsolveWithLargePackageList(t *testing.T) {
|
|
solver := createTestSolver(t)
|
|
|
|
// Test with a large package list
|
|
packages := make([]string, 100)
|
|
for i := 0; i < 100; i++ {
|
|
packages[i] = "package-" + string(rune('a'+i%26))
|
|
}
|
|
|
|
result, err := solver.Depsolve(packages, 0)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, result)
|
|
|
|
// Check that we got PackageSpec structs with correct names
|
|
actualNames := make([]string, len(result.Packages))
|
|
for i, pkg := range result.Packages {
|
|
actualNames[i] = pkg.Name
|
|
}
|
|
assert.Equal(t, packages, actualNames)
|
|
}
|
|
|
|
func TestParseAptOutputEdgeCases(t *testing.T) {
|
|
solver := createTestSolver(t)
|
|
|
|
// Test with only whitespace
|
|
result := solver.parseAptOutput(" \n\t \n ")
|
|
assert.Empty(t, result)
|
|
|
|
// Test with only dependency keywords
|
|
output := `Depends: package1
|
|
PreDepends: package2
|
|
Breaks: package3
|
|
Replaces: package4
|
|
Conflicts: package5
|
|
Recommends: package6
|
|
Suggests: package7
|
|
Enhances: package8
|
|
|Depends: package9
|
|
|PreDepends: package10`
|
|
result = solver.parseAptOutput(output)
|
|
assert.Empty(t, result)
|
|
|
|
// Test with only special characters
|
|
output = `<virtual>
|
|
>constraint
|
|
|alternative
|
|
package:arch`
|
|
result = solver.parseAptOutput(output)
|
|
assert.Empty(t, result)
|
|
|
|
// Test with mixed valid and invalid
|
|
output = `valid-package
|
|
Depends: invalid
|
|
another-valid
|
|
<virtual>
|
|
yet-another-valid`
|
|
result = solver.parseAptOutput(output)
|
|
expected := []string{"valid-package", "another-valid", "yet-another-valid"}
|
|
assert.ElementsMatch(t, expected, result)
|
|
}
|