package app import ( "bytes" "context" "errors" "io" "net/http" "os" "path/filepath" "strings" "testing" "git.stormux.org/storm/cthulhu/internal/tentacle" ) func TestUpgradePreparationFailurePreservesInstallation(t *testing.T) { repository, data := install_fixture(t) set_install_transport(t, func(*http.Request) (*http.Response, error) { return &http.Response{ StatusCode: 200, Body: io.NopCloser(bytes.NewReader(data)), Header: make(http.Header), }, nil }) registryPath := filepath.Join(t.TempDir(), "tentacles.toml") owner, _ := managed_tentacle_fixture(t, registryPath, false) owner.fetchRepository = func(context.Context, string) (tentacle.Repository, error) { return repository, nil } if err := owner.Start(context.Background()); err != nil { t.Fatal(err) } manage := func(action string) error { return owner.Manage(context.Background(), tentacle.ManagementRequest{ Action: action, URL: repository.URL, ID: func() string { if action == "install" || action == "upgrade" { return "echo" } return "" }(), }) } if err := manage("repository-add"); err != nil { t.Fatal(err) } if err := manage("install"); err != nil { t.Fatal(err) } id := tentacle.PackageID(repository, "echo") wait_managed_state(t, owner, id, "disabled") before := owner.Snapshot().Entries[0].Entry repository.Revision = strings.Repeat("b", 40) repository.Tentacles[0].Version = "0.2" if err := manage("repository-refresh"); err != nil { t.Fatal(err) } owner.preparePackage = func(context.Context, string, tentacle.Repository, string) (*tentacle.PreparedPackage, error) { return nil, errors.New("simulated download failure") } if err := manage("upgrade"); err == nil { t.Fatal("upgrade unexpectedly succeeded") } after := owner.Snapshot().Entries[0].Entry if after.Version != before.Version || after.Enabled != before.Enabled || after.PackageDirectory != before.PackageDirectory { t.Fatalf("failed upgrade changed installation: before=%+v after=%+v", before, after) } if _, err := os.Stat(before.PackageDirectory); err != nil { t.Fatalf("failed upgrade removed installed package: %v", err) } }