315 lines
8.2 KiB
Go
315 lines
8.2 KiB
Go
package apps
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
func TestParseSourceDir(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
source string
|
|
want string
|
|
}{
|
|
{"file URI", "file:///opt/wild-cloud/apps/myapp", "/opt/wild-cloud/apps/myapp"},
|
|
{"empty string", "", ""},
|
|
{"no scheme", "/opt/wild-cloud/apps/myapp", ""},
|
|
{"unsupported scheme", "git://example.com/repo", ""},
|
|
{"http scheme", "http://example.com/app", ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := parseSourceDir(tt.source)
|
|
if got != tt.want {
|
|
t.Errorf("parseSourceDir(%q) = %q, want %q", tt.source, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilesDiffer(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "drift-files-*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
fileA := filepath.Join(tmpDir, "a.txt")
|
|
fileB := filepath.Join(tmpDir, "b.txt")
|
|
fileC := filepath.Join(tmpDir, "c.txt")
|
|
fileMissing := filepath.Join(tmpDir, "missing.txt")
|
|
|
|
os.WriteFile(fileA, []byte("hello"), 0644)
|
|
os.WriteFile(fileB, []byte("hello"), 0644)
|
|
os.WriteFile(fileC, []byte("world"), 0644)
|
|
|
|
t.Run("identical files", func(t *testing.T) {
|
|
if filesDiffer(fileA, fileB) {
|
|
t.Error("expected identical files to not differ")
|
|
}
|
|
})
|
|
|
|
t.Run("different files", func(t *testing.T) {
|
|
if !filesDiffer(fileA, fileC) {
|
|
t.Error("expected different files to differ")
|
|
}
|
|
})
|
|
|
|
t.Run("one missing", func(t *testing.T) {
|
|
if !filesDiffer(fileA, fileMissing) {
|
|
t.Error("expected missing file to differ")
|
|
}
|
|
})
|
|
|
|
t.Run("both missing", func(t *testing.T) {
|
|
if filesDiffer(fileMissing, filepath.Join(tmpDir, "also-missing.txt")) {
|
|
t.Error("expected both missing to not differ")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestDirsDiffer(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "drift-dirs-*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create two identical directories
|
|
dirA := filepath.Join(tmpDir, "a")
|
|
dirB := filepath.Join(tmpDir, "b")
|
|
os.MkdirAll(dirA, 0755)
|
|
os.MkdirAll(dirB, 0755)
|
|
os.WriteFile(filepath.Join(dirA, "file.txt"), []byte("same"), 0644)
|
|
os.WriteFile(filepath.Join(dirB, "file.txt"), []byte("same"), 0644)
|
|
|
|
t.Run("identical directories", func(t *testing.T) {
|
|
if dirsDiffer(dirA, dirB) {
|
|
t.Error("expected identical directories to not differ")
|
|
}
|
|
})
|
|
|
|
// Create a directory with different content
|
|
dirC := filepath.Join(tmpDir, "c")
|
|
os.MkdirAll(dirC, 0755)
|
|
os.WriteFile(filepath.Join(dirC, "file.txt"), []byte("different"), 0644)
|
|
|
|
t.Run("different content", func(t *testing.T) {
|
|
if !dirsDiffer(dirA, dirC) {
|
|
t.Error("expected directories with different content to differ")
|
|
}
|
|
})
|
|
|
|
// Directory with extra file
|
|
dirD := filepath.Join(tmpDir, "d")
|
|
os.MkdirAll(dirD, 0755)
|
|
os.WriteFile(filepath.Join(dirD, "file.txt"), []byte("same"), 0644)
|
|
os.WriteFile(filepath.Join(dirD, "extra.txt"), []byte("extra"), 0644)
|
|
|
|
t.Run("extra file in second", func(t *testing.T) {
|
|
if !dirsDiffer(dirA, dirD) {
|
|
t.Error("expected directories with different file counts to differ")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCheckSourceDrift_NoDrift(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "drift-source-*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create source directory with manifest
|
|
sourceDir := filepath.Join(tmpDir, "source", "myapp")
|
|
os.MkdirAll(sourceDir, 0755)
|
|
sourceManifest := AppManifest{Version: "1.0.0"}
|
|
data, _ := yaml.Marshal(sourceManifest)
|
|
os.WriteFile(filepath.Join(sourceDir, "manifest.yaml"), data, 0644)
|
|
|
|
// Create package dir (it exists)
|
|
packageDir := filepath.Join(tmpDir, "package")
|
|
os.MkdirAll(packageDir, 0755)
|
|
|
|
// Installed manifest with same version
|
|
manifest := &AppManifest{
|
|
Version: "1.0.0",
|
|
Source: "file://" + sourceDir,
|
|
}
|
|
|
|
m := &Manager{}
|
|
result := m.checkSourceDrift(manifest, packageDir)
|
|
if result != nil {
|
|
t.Errorf("expected no drift, got %+v", result)
|
|
}
|
|
}
|
|
|
|
func TestCheckSourceDrift_VersionDrift(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "drift-source-*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create source directory with newer version
|
|
sourceDir := filepath.Join(tmpDir, "source", "myapp")
|
|
os.MkdirAll(sourceDir, 0755)
|
|
sourceManifest := AppManifest{Version: "2.0.0"}
|
|
data, _ := yaml.Marshal(sourceManifest)
|
|
os.WriteFile(filepath.Join(sourceDir, "manifest.yaml"), data, 0644)
|
|
|
|
// Create package dir
|
|
packageDir := filepath.Join(tmpDir, "package")
|
|
os.MkdirAll(packageDir, 0755)
|
|
|
|
// Installed manifest with older version
|
|
manifest := &AppManifest{
|
|
Version: "1.0.0",
|
|
Source: "file://" + sourceDir,
|
|
}
|
|
|
|
m := &Manager{}
|
|
result := m.checkSourceDrift(manifest, packageDir)
|
|
if result == nil {
|
|
t.Fatal("expected drift, got nil")
|
|
}
|
|
if !result.Drifted {
|
|
t.Error("expected Drifted to be true")
|
|
}
|
|
if result.CurrentVersion != "1.0.0" {
|
|
t.Errorf("expected CurrentVersion '1.0.0', got %q", result.CurrentVersion)
|
|
}
|
|
if result.AvailableVersion != "2.0.0" {
|
|
t.Errorf("expected AvailableVersion '2.0.0', got %q", result.AvailableVersion)
|
|
}
|
|
}
|
|
|
|
func TestCheckSourceDrift_NoSource(t *testing.T) {
|
|
manifest := &AppManifest{
|
|
Version: "1.0.0",
|
|
Source: "", // ejected app
|
|
}
|
|
|
|
m := &Manager{}
|
|
result := m.checkSourceDrift(manifest, "/nonexistent")
|
|
if result != nil {
|
|
t.Errorf("expected nil for ejected app, got %+v", result)
|
|
}
|
|
}
|
|
|
|
func TestCheckSourceDrift_PackageMissing(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "drift-source-*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Source exists but .package/ does not
|
|
sourceDir := filepath.Join(tmpDir, "source", "myapp")
|
|
os.MkdirAll(sourceDir, 0755)
|
|
|
|
manifest := &AppManifest{
|
|
Version: "1.0.0",
|
|
Source: "file://" + sourceDir,
|
|
}
|
|
|
|
packageDir := filepath.Join(tmpDir, "nonexistent-package")
|
|
|
|
m := &Manager{}
|
|
result := m.checkSourceDrift(manifest, packageDir)
|
|
if result == nil {
|
|
t.Fatal("expected drift for missing package dir, got nil")
|
|
}
|
|
if !result.Drifted {
|
|
t.Error("expected Drifted to be true")
|
|
}
|
|
}
|
|
|
|
func TestCheckSourceDrift_SourceDirMissing(t *testing.T) {
|
|
// Source URI points to a directory that doesn't exist
|
|
manifest := &AppManifest{
|
|
Version: "1.0.0",
|
|
Source: "file:///nonexistent/path/myapp",
|
|
}
|
|
|
|
packageDir := "/tmp" // exists but irrelevant
|
|
|
|
m := &Manager{}
|
|
result := m.checkSourceDrift(manifest, packageDir)
|
|
if result != nil {
|
|
t.Errorf("expected nil when source dir is missing, got %+v", result)
|
|
}
|
|
}
|
|
|
|
func TestComputeDrift_EjectedApp(t *testing.T) {
|
|
// Ejected app: Source is empty, so source and compilation drift should be nil
|
|
manifest := &AppManifest{
|
|
Version: "1.0.0",
|
|
Source: "",
|
|
}
|
|
|
|
m := &Manager{}
|
|
result := m.computeDrift("test-instance", "myapp", "/tmp", "", "added", manifest)
|
|
|
|
// For an ejected app with status "added", nothing to check — should be nil
|
|
if result != nil {
|
|
t.Errorf("expected nil drift for ejected 'added' app, got %+v", result)
|
|
}
|
|
}
|
|
|
|
func TestComputeDrift_NotDeployed(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "drift-compute-*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Source-managed app that is only "added" (not deployed)
|
|
sourceDir := filepath.Join(tmpDir, "source")
|
|
os.MkdirAll(sourceDir, 0755)
|
|
|
|
// Source manifest with newer version
|
|
sourceManifest := AppManifest{Version: "2.0.0"}
|
|
data, _ := yaml.Marshal(sourceManifest)
|
|
os.WriteFile(filepath.Join(sourceDir, "manifest.yaml"), data, 0644)
|
|
|
|
// App directory with .package
|
|
appDir := filepath.Join(tmpDir, "app")
|
|
packageDir := filepath.Join(appDir, ".package")
|
|
os.MkdirAll(packageDir, 0755)
|
|
|
|
manifest := &AppManifest{
|
|
Version: "1.0.0",
|
|
Source: "file://" + sourceDir,
|
|
}
|
|
|
|
m := &Manager{}
|
|
result := m.computeDrift("test-instance", "myapp", appDir, "", "added", manifest)
|
|
|
|
if result == nil {
|
|
t.Fatal("expected drift info, got nil")
|
|
}
|
|
|
|
// Should have source drift (version mismatch)
|
|
if result.Source == nil || !result.Source.Drifted {
|
|
t.Error("expected source drift for version mismatch")
|
|
}
|
|
|
|
// Should NOT have deploy drift (status is "added")
|
|
if result.Deploy != nil {
|
|
t.Error("expected no deploy drift for 'added' status")
|
|
}
|
|
}
|
|
|
|
func TestComputeDrift_NilManifest(t *testing.T) {
|
|
m := &Manager{}
|
|
result := m.computeDrift("test-instance", "myapp", "/tmp", "", "running", nil)
|
|
if result != nil {
|
|
t.Errorf("expected nil drift for nil manifest, got %+v", result)
|
|
}
|
|
}
|