open-nomad/client/state/upgrade_test.go

110 lines
2.7 KiB
Go
Raw Normal View History

package state
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/boltdb/bolt"
"github.com/hashicorp/nomad/helper/boltdd"
"github.com/hashicorp/nomad/helper/testlog"
"github.com/hashicorp/nomad/helper/uuid"
"github.com/stretchr/testify/require"
)
// TestUpgrade_NeedsUpgrade_New asserts new state dbs do not need upgrading.
func TestUpgrade_NeedsUpgrade_New(t *testing.T) {
t.Parallel()
db, cleanup := setupBoltDB(t)
defer cleanup()
up, err := NeedsUpgrade(db.DB().BoltDB())
require.NoError(t, err)
require.False(t, up)
}
// TestUpgrade_NeedsUpgrade_Old asserts state dbs with just the alloctions
// bucket *do* need upgrading.
func TestUpgrade_NeedsUpgrade_Old(t *testing.T) {
t.Parallel()
dir, err := ioutil.TempDir("", "nomadtest")
require.NoError(t, err)
defer os.RemoveAll(dir)
db, err := bolt.Open(filepath.Join(dir, "state.db"), 0666, nil)
require.NoError(t, err)
defer db.Close()
// Create the allocations bucket which exists in both the old and 0.9
// schemas
require.NoError(t, db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucket(allocationsBucketName)
return err
}))
up, err := NeedsUpgrade(db)
require.NoError(t, err)
require.True(t, up)
// Adding meta should mark it as upgraded
require.NoError(t, db.Update(addMeta))
up, err = NeedsUpgrade(db)
require.NoError(t, err)
require.False(t, up)
}
// TestUpgrade_DeleteInvalidAllocs asserts invalid allocations are deleted
// during state upgades instead of failing the entire agent.
func TestUpgrade_DeleteInvalidAllocs_NoAlloc(t *testing.T) {
t.Parallel()
dir, err := ioutil.TempDir("", "nomadtest")
require.NoError(t, err)
defer os.RemoveAll(dir)
db, err := boltdd.Open(filepath.Join(dir, "state.db"), 0666, nil)
require.NoError(t, err)
defer db.Close()
allocID := []byte(uuid.Generate())
// Create an allocation bucket with no `alloc` key. This is an observed
// pre-0.9 state corruption that should result in the allocation being
// dropped while allowing the upgrade to continue.
require.NoError(t, db.Update(func(tx *boltdd.Tx) error {
parentBkt, err := tx.CreateBucket(allocationsBucketName)
if err != nil {
return err
}
_, err = parentBkt.CreateBucket(allocID)
return err
}))
// Perform the Upgrade
require.NoError(t, db.Update(func(tx *boltdd.Tx) error {
return UpgradeAllocs(testlog.HCLogger(t), tx)
}))
// Assert invalid allocation bucket was removed
require.NoError(t, db.View(func(tx *boltdd.Tx) error {
parentBkt := tx.Bucket(allocationsBucketName)
if parentBkt == nil {
return fmt.Errorf("parent allocations bucket should not have been removed")
}
if parentBkt.Bucket(allocID) != nil {
return fmt.Errorf("invalid alloc bucket should have been deleted")
}
return nil
}))
}