Skip to content

Commit

Permalink
Add regression test
Browse files Browse the repository at this point in the history
  • Loading branch information
catsby committed Feb 4, 2020
1 parent f18031d commit 8ea43ab
Showing 1 changed file with 122 additions and 0 deletions.
122 changes: 122 additions & 0 deletions physical/mysql/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ package mysql
import (
"os"
"testing"
"time"

log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/sdk/helper/logging"
"github.com/hashicorp/vault/sdk/physical"

_ "github.com/go-sql-driver/mysql"
mysql "github.com/go-sql-driver/mysql"

mysqlhelper "github.com/hashicorp/vault/helper/testhelpers/mysql"
)

func TestMySQLBackend(t *testing.T) {
Expand Down Expand Up @@ -107,3 +111,121 @@ func TestMySQLHABackend(t *testing.T) {

physical.ExerciseHABackend(t, b.(physical.HABackend), b2.(physical.HABackend))
}

// TestMySQLHABackend_LockFailPanic is a regression test for the panic shown in
// https://github.com/hashicorp/vault/issues/8203 and patched in
// https://github.com/hashicorp/vault/pull/8229
func TestMySQLHABackend_LockFailPanic(t *testing.T) {
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret")
defer cleanup()

cfg, err := mysql.ParseDSN(connURL)
if err != nil {
t.Fatal(err)
}

if err := mysqlhelper.TestCredsExist(t, connURL, cfg.User, cfg.Passwd); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}

table := "test"
logger := logging.NewVaultLogger(log.Debug)
config := map[string]string{
"address": cfg.Addr,
"database": cfg.DBName,
"table": table,
"username": cfg.User,
"password": cfg.Passwd,
"ha_enabled": "true",
}

b, err := NewMySQLBackend(config, logger)
if err != nil {
t.Fatalf("Failed to create new backend: %v", err)
}

defer func() {
mysql := b.(*MySQLBackend)
_, err := mysql.client.Exec("DROP TABLE IF EXISTS " + mysql.dbTable + " ," + mysql.dbLockTable)
if err != nil {
t.Fatalf("Failed to drop table: %v", err)
}
}()

b2, err := NewMySQLBackend(config, logger)
if err != nil {
t.Fatalf("Failed to create new backend: %v", err)
}

b1ha := b.(physical.HABackend)
b2ha := b2.(physical.HABackend)

// Copied from ExerciseHABackend - ensuring things are normal at this point
// Get the lock
lock, err := b1ha.LockWith("foo", "bar")
if err != nil {
t.Fatalf("initial lock: %v", err)
}

// Attempt to lock
leaderCh, err := lock.Lock(nil)
if err != nil {
t.Fatalf("lock attempt 1: %v", err)
}
if leaderCh == nil {
t.Fatalf("missing leaderCh")
}

// Check the value
held, val, err := lock.Value()
if err != nil {
t.Fatalf("err: %v", err)
}
if !held {
t.Errorf("should be held")
}
if val != "bar" {
t.Errorf("expected value bar: %v", err)
}

// Second acquisition should fail
lock2, err := b2ha.LockWith("foo", "baz")
if err != nil {
t.Fatalf("lock 2: %v", err)
}

// Cancel attempt in 50 msec
stopCh := make(chan struct{})
time.AfterFunc(3*time.Second, func() {
close(stopCh)
})

// Attempt to lock - can't lock because lock1 is held - this is normal
leaderCh2, err := lock2.Lock(stopCh)
if err != nil {
t.Fatalf("stop lock 2: %v", err)
}
if leaderCh2 != nil {
t.Errorf("should not have gotten leaderCh: %v", leaderCh2)
}
// end normal

// modify the connection string of lock2. When Lock() is called, a new
// connection is created using the configuration. If that connection cannot be
// created, there was a panic due to not returning with the connection error.
// Here we intentionally break the config for b2, so a new connection can't be
// made, which would trigger the panic shown in
// https://github.com/hashicorp/vault/issues/8203
haLock := lock2.(*MySQLHALock)
haLock.in.conf["username"] = "fake"

// Cancel attempt in 50 msec
stopCh2 := make(chan struct{})
time.AfterFunc(3*time.Second, func() {
close(stopCh2)
})
leaderCh2, err = lock2.Lock(stopCh2)
if err == nil {
t.Fatalf("expected error, got none")
}
}

0 comments on commit 8ea43ab

Please sign in to comment.