Files
opentf/state/remote/testing.go
James Bardin 67bbebce08 Have consul state reutrn the lock ID
The lock ID isn't used because the lock is tied to the client, but
return the lock ID to match the behavior of other locks.
2017-02-15 14:44:43 -05:00

98 lines
2.0 KiB
Go

package remote
import (
"bytes"
"testing"
"github.com/hashicorp/terraform/state"
"github.com/hashicorp/terraform/terraform"
)
// TestClient is a generic function to test any client.
func TestClient(t *testing.T, c Client) {
var buf bytes.Buffer
s := state.TestStateInitial()
if err := terraform.WriteState(s, &buf); err != nil {
t.Fatalf("err: %s", err)
}
data := buf.Bytes()
if err := c.Put(data); err != nil {
t.Fatalf("put: %s", err)
}
p, err := c.Get()
if err != nil {
t.Fatalf("get: %s", err)
}
if !bytes.Equal(p.Data, data) {
t.Fatalf("bad: %#v", p)
}
if err := c.Delete(); err != nil {
t.Fatalf("delete: %s", err)
}
p, err = c.Get()
if err != nil {
t.Fatalf("get: %s", err)
}
if p != nil {
t.Fatalf("bad: %#v", p)
}
}
// Test the lock implementation for a remote.Client.
// This test requires 2 client instances, in oder to have multiple remote
// clients since some implementations may tie the client to the lock, or may
// have reentrant locks.
func TestRemoteLocks(t *testing.T, a, b Client) {
lockerA, ok := a.(state.Locker)
if !ok {
t.Fatal("client A not a state.Locker")
}
lockerB, ok := b.(state.Locker)
if !ok {
t.Fatal("client B not a state.Locker")
}
infoA := state.NewLockInfo()
infoA.Operation = "test"
infoA.Who = "clientA"
infoB := state.NewLockInfo()
infoB.Operation = "test"
infoB.Who = "clientB"
lockIDA, err := lockerA.Lock(infoA)
if err != nil {
t.Fatal("unable to get initial lock:", err)
}
_, err = lockerB.Lock(infoB)
if err == nil {
lockerA.Unlock(lockIDA)
t.Fatal("client B obtained lock while held by client A")
}
if err := lockerA.Unlock(lockIDA); err != nil {
t.Fatal("error unlocking client A", err)
}
lockIDB, err := lockerB.Lock(infoB)
if err != nil {
t.Fatal("unable to obtain lock from client B")
}
if lockIDB == lockIDA {
t.Fatalf("duplicate lock IDs: %q", lockIDB)
}
if err = lockerB.Unlock(lockIDB); err != nil {
t.Fatal("error unlocking client B:", err)
}
// TODO: Should we enforce that Unlock requires the correct ID?
}