state/remote: export ClientLocker, test for implementation
This adds unit tests (that will fail at compile time) if various structs don't implement the right interfaces for locking
This commit is contained in:
parent
6798cd5911
commit
efe754183b
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
func TestRemoteClient_impl(t *testing.T) {
|
||||
var _ remote.Client = new(RemoteClient)
|
||||
var _ remote.ClientLocker = new(RemoteClient)
|
||||
}
|
||||
|
||||
func TestRemoteClient(t *testing.T) {
|
||||
|
|
|
@ -6,6 +6,10 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func TestBackupState_locker(t *testing.T) {
|
||||
var _ Locker = new(BackupState)
|
||||
}
|
||||
|
||||
func TestBackupState(t *testing.T) {
|
||||
f, err := ioutil.TempFile("", "tf")
|
||||
if err != nil {
|
||||
|
|
|
@ -2,6 +2,8 @@ package remote
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform/state"
|
||||
)
|
||||
|
||||
// Client is the interface that must be implemented for a remote state
|
||||
|
@ -13,6 +15,15 @@ type Client interface {
|
|||
Delete() error
|
||||
}
|
||||
|
||||
// ClientLocker is an optional interface that allows a remote state
|
||||
// backend to enable state lock/unlock.
|
||||
type ClientLocker interface {
|
||||
Client
|
||||
|
||||
Lock(*state.LockInfo) (string, error)
|
||||
Unlock(string) error
|
||||
}
|
||||
|
||||
// Payload is the return value from the remote state storage.
|
||||
type Payload struct {
|
||||
MD5 []byte
|
||||
|
|
|
@ -3,6 +3,7 @@ package remote
|
|||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/hashicorp/terraform/state"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
|
@ -62,24 +63,17 @@ func (s *State) PersistState() error {
|
|||
}
|
||||
|
||||
// Lock calls the Client's Lock method if it's implemented.
|
||||
func (s *State) Lock(reason string) error {
|
||||
if c, ok := s.Client.(stateLocker); ok {
|
||||
return c.Lock(reason)
|
||||
func (s *State) Lock(info *state.LockInfo) (string, error) {
|
||||
if c, ok := s.Client.(ClientLocker); ok {
|
||||
return c.Lock(info)
|
||||
}
|
||||
return nil
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Unlock calls the Client's Unlock method if it's implemented.
|
||||
func (s *State) Unlock() error {
|
||||
if c, ok := s.Client.(stateLocker); ok {
|
||||
return c.Unlock()
|
||||
func (s *State) Unlock(id string) error {
|
||||
if c, ok := s.Client.(ClientLocker); ok {
|
||||
return c.Unlock(id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// stateLocker mirrors the state.Locker interface. This can be implemented by
|
||||
// Clients to provide methods for locking and unlocking remote state.
|
||||
type stateLocker interface {
|
||||
Lock(reason string) error
|
||||
Unlock() error
|
||||
}
|
||||
|
|
|
@ -24,4 +24,5 @@ func TestState_impl(t *testing.T) {
|
|||
var _ state.StateWriter = new(State)
|
||||
var _ state.StatePersister = new(State)
|
||||
var _ state.StateRefresher = new(State)
|
||||
var _ state.Locker = new(State)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue