Exercise real server startup on backend test runs and gate releases on fresh-install, previous-stable upgrade, and entrypoint smoke checks across supported databases.
96 lines
3.4 KiB
Go
96 lines
3.4 KiB
Go
package test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
storepb "github.com/usememos/memos/proto/gen/store"
|
|
"github.com/usememos/memos/store"
|
|
)
|
|
|
|
// setSchemaVersion overwrites the recorded schema version so upgrade guard rails
|
|
// can be exercised without fabricating a whole legacy database.
|
|
func setSchemaVersion(ctx context.Context, t *testing.T, ts *store.Store, schemaVersion string) {
|
|
t.Helper()
|
|
|
|
basicSetting, err := ts.GetInstanceBasicSetting(ctx)
|
|
require.NoError(t, err)
|
|
|
|
basicSetting.SchemaVersion = schemaVersion
|
|
_, err = ts.UpsertInstanceSetting(ctx, &storepb.InstanceSetting{
|
|
Key: storepb.InstanceSettingKey_BASIC,
|
|
Value: &storepb.InstanceSetting_BasicSetting{BasicSetting: basicSetting},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
stored, err := ts.GetInstanceBasicSetting(ctx)
|
|
require.NoError(t, err)
|
|
require.Equal(t, schemaVersion, stored.SchemaVersion, "schema version should be persisted")
|
|
}
|
|
|
|
// TestMigrationRejectsDowngrade verifies a database written by a newer Memos is
|
|
// refused rather than silently re-migrated. Starting an old binary against a
|
|
// newer database is the most common way a rollback corrupts data.
|
|
func TestMigrationRejectsDowngrade(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
|
|
currentVersion, err := ts.GetCurrentSchemaVersion()
|
|
require.NoError(t, err)
|
|
|
|
// Pretend the database was written by a much newer release.
|
|
setSchemaVersion(ctx, t, ts, "99.0.0")
|
|
|
|
err = ts.Migrate(ctx)
|
|
require.Error(t, err, "migrating a newer database should fail")
|
|
require.Contains(t, err.Error(), "cannot downgrade schema version",
|
|
"error should explain the downgrade was refused")
|
|
require.Contains(t, err.Error(), currentVersion,
|
|
"error should name the version the binary supports")
|
|
}
|
|
|
|
// TestMigrationRejectsPreV022Installation verifies installations older than the
|
|
// supported floor are refused with actionable upgrade instructions instead of
|
|
// failing partway through a migration.
|
|
func TestMigrationRejectsPreV022Installation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
|
|
// 0.21.x predates moving schema tracking from migration_history to system_setting.
|
|
setSchemaVersion(ctx, t, ts, "0.21.0")
|
|
|
|
err := ts.Migrate(ctx)
|
|
require.Error(t, err, "migrating a pre-0.22 installation should fail")
|
|
require.Contains(t, err.Error(), "too old to upgrade directly")
|
|
require.Contains(t, err.Error(), "0.25.3",
|
|
"error should name the intermediate version to upgrade through")
|
|
}
|
|
|
|
// TestMigrationAcceptsMinimumSupportedVersion pins the other side of the
|
|
// supported-version boundary: 0.22.0 must clear the floor check that rejects
|
|
// 0.21.x.
|
|
//
|
|
// This asserts only that the floor check passes, not that the whole migration
|
|
// succeeds. The store here has a current schema relabelled as 0.22.0, so
|
|
// replaying the 0.22-onward migrations against it legitimately fails on tables
|
|
// that were since renamed. Verifying a real 0.22 replay needs a genuine 0.22
|
|
// database, which is the container tier's job.
|
|
func TestMigrationAcceptsMinimumSupportedVersion(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ctx := context.Background()
|
|
ts := NewTestingStore(ctx, t)
|
|
|
|
setSchemaVersion(ctx, t, ts, "0.22.0")
|
|
|
|
if err := ts.Migrate(ctx); err != nil {
|
|
require.NotContains(t, err.Error(), "too old to upgrade directly",
|
|
"0.22.0 is the supported floor and must clear the minimum-version check")
|
|
}
|
|
}
|