diff --git a/internal/mocks/rpmmd/fixtures.go b/internal/mocks/rpmmd/fixtures.go index b76403862..2669b1886 100644 --- a/internal/mocks/rpmmd/fixtures.go +++ b/internal/mocks/rpmmd/fixtures.go @@ -182,3 +182,20 @@ func BadFetch(tmpdir string) Fixture { createBaseWorkersFixture(tmpdir), } } + +func OldChangesFixture(tmpdir string) Fixture { + return Fixture{ + fetchPackageList{ + generatePackageList(), + map[string]string{"base": "sha256:f34848ca92665c342abd5816c9e3eda0e82180671195362bcd0080544a3bc2ac"}, + nil, + }, + depsolve{ + createBaseDepsolveFixture(), + map[string]string{"base": "sha256:f34848ca92665c342abd5816c9e3eda0e82180671195362bcd0080544a3bc2ac"}, + nil, + }, + store.FixtureOldChanges(), + createBaseWorkersFixture(tmpdir), + } +} diff --git a/internal/store/fixtures.go b/internal/store/fixtures.go index 26039063c..eb2bd7be6 100644 --- a/internal/store/fixtures.go +++ b/internal/store/fixtures.go @@ -305,3 +305,45 @@ func FixtureEmpty() *Store { return s } + +// FixtureOldChanges contains a blueprint and old changes +// This simulates restarting the service and losing the old blueprints +func FixtureOldChanges() *Store { + var bName = "test-old-changes" + var b = blueprint.Blueprint{ + Name: bName, + Version: "0.0.0", + Packages: []blueprint.Package{}, + Modules: []blueprint.Package{}, + Groups: []blueprint.Group{}, + Customizations: nil, + } + + d := test_distro.New() + arch, err := d.GetArch(test_distro.TestArchName) + if err != nil { + panic(fmt.Sprintf("failed to get architecture %s for a test distro: %v", test_distro.TestArchName, err)) + } + + s := New(nil, arch, nil) + + s.PushBlueprint(b, "Initial commit") + b.Version = "0.0.1" + b.Packages = []blueprint.Package{{Name: "tmux", Version: "1.2.3"}} + s.PushBlueprint(b, "Add tmux package") + b.Version = "0.0.2" + b.Packages = []blueprint.Package{{Name: "tmux", Version: "*"}} + s.PushBlueprint(b, "Change tmux version") + + // Replace the associated blueprints. This simulates reading the store from + // disk which doesn't actually save the old blueprints to disk. + for bp := range s.blueprintsChanges { + for c := range s.blueprintsChanges[bp] { + change := s.blueprintsChanges[bp][c] + change.Blueprint = blueprint.Blueprint{} + s.blueprintsChanges[bp][c] = change + } + } + + return s +} diff --git a/internal/weldr/api_test.go b/internal/weldr/api_test.go index a7fe2724b..4064d7069 100644 --- a/internal/weldr/api_test.go +++ b/internal/weldr/api_test.go @@ -601,7 +601,47 @@ func TestBlueprintsDepsolve(t *testing.T) { } } -func TestBlueprintsUndo(t *testing.T) { +// TestOldBlueprintsUndo run tests with blueprint changes after a service restart +// Old blueprints are not saved, after a restart the changes are listed, but cannot be recalled +func TestOldBlueprintsUndo(t *testing.T) { + tempdir, err := ioutil.TempDir("", "weldr-tests-") + require.NoError(t, err) + defer os.RemoveAll(tempdir) + + api, _ := createWeldrAPI(tempdir, rpmmd_mock.OldChangesFixture) + rand.Seed(time.Now().UnixNano()) + // math/rand is good enough in this case + /* #nosec G404 */ + ignoreFields := []string{"commit", "timestamp"} + + test.TestRoute(t, api, true, "GET", "/api/v0/blueprints/changes/test-old-changes", ``, http.StatusOK, `{"blueprints":[{"changes":[{"commit":"","message":"Change tmux version","revision":null,"timestamp":""},{"commit":"","message":"Add tmux package","revision":null,"timestamp":""},{"commit":"","message":"Initial commit","revision":null,"timestamp":""}],"name":"test-old-changes","total":3}],"errors":[],"limit":20,"offset":0}`, ignoreFields...) + + resp := test.SendHTTP(api, true, "GET", "/api/v0/blueprints/changes/test-old-changes", ``) + body, err := ioutil.ReadAll(resp.Body) + require.Nil(t, err) + require.Equal(t, http.StatusOK, resp.StatusCode) + + var changes BlueprintsChangesV0 + err = json.Unmarshal(body, &changes) + require.Nil(t, err) + require.Equal(t, 1, len(changes.BlueprintsChanges)) + require.Equal(t, 3, len(changes.BlueprintsChanges[0].Changes)) + commit := changes.BlueprintsChanges[0].Changes[2].Commit + + // Undo a known commit, that is old + test.TestRoute(t, api, true, "POST", "/api/v0/blueprints/undo/test-old-changes/"+commit, ``, http.StatusOK, `{"status":true}`) + + // Check to make sure the undo is not present (can't undo something not there) + test.TestRoute(t, api, true, "GET", "/api/v0/blueprints/changes/test-old-changes", ``, http.StatusOK, `{"blueprints":[{"changes":[{"commit":"","message":"Change tmux version","revision":null,"timestamp":""},{"commit":"","message":"Add tmux package","revision":null,"timestamp":""},{"commit":"","message":"Initial commit","revision":null,"timestamp":""}],"name":"test-old-changes","total":3}],"errors":[],"limit":20,"offset":0}`, ignoreFields...) + + // Check to make sure it didn't create an empty blueprint + test.TestRoute(t, api, true, "GET", "/api/v0/blueprints/list", ``, http.StatusOK, `{"total":1,"offset":0,"limit":1,"blueprints":["test-old-changes"]}`) + + test.SendHTTP(api, true, "DELETE", "/api/v0/blueprints/delete/test-old-changes", ``) +} + +// TestNewBlueprintsUndo run tests with blueprint changes without a service restart +func TestNewBlueprintsUndo(t *testing.T) { tempdir, err := ioutil.TempDir("", "weldr-tests-") require.NoError(t, err) defer os.RemoveAll(tempdir)