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) {
|
func TestRemoteClient_impl(t *testing.T) {
|
||||||
var _ remote.Client = new(RemoteClient)
|
var _ remote.Client = new(RemoteClient)
|
||||||
|
var _ remote.ClientLocker = new(RemoteClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoteClient(t *testing.T) {
|
func TestRemoteClient(t *testing.T) {
|
||||||
|
|
|
@ -6,6 +6,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestBackupState_locker(t *testing.T) {
|
||||||
|
var _ Locker = new(BackupState)
|
||||||
|
}
|
||||||
|
|
||||||
func TestBackupState(t *testing.T) {
|
func TestBackupState(t *testing.T) {
|
||||||
f, err := ioutil.TempFile("", "tf")
|
f, err := ioutil.TempFile("", "tf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package remote
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client is the interface that must be implemented for a remote state
|
// Client is the interface that must be implemented for a remote state
|
||||||
|
@ -13,6 +15,15 @@ type Client interface {
|
||||||
Delete() error
|
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.
|
// Payload is the return value from the remote state storage.
|
||||||
type Payload struct {
|
type Payload struct {
|
||||||
MD5 []byte
|
MD5 []byte
|
||||||
|
|
|
@ -3,6 +3,7 @@ package remote
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/state"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"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.
|
// Lock calls the Client's Lock method if it's implemented.
|
||||||
func (s *State) Lock(reason string) error {
|
func (s *State) Lock(info *state.LockInfo) (string, error) {
|
||||||
if c, ok := s.Client.(stateLocker); ok {
|
if c, ok := s.Client.(ClientLocker); ok {
|
||||||
return c.Lock(reason)
|
return c.Lock(info)
|
||||||
}
|
}
|
||||||
return nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock calls the Client's Unlock method if it's implemented.
|
// Unlock calls the Client's Unlock method if it's implemented.
|
||||||
func (s *State) Unlock() error {
|
func (s *State) Unlock(id string) error {
|
||||||
if c, ok := s.Client.(stateLocker); ok {
|
if c, ok := s.Client.(ClientLocker); ok {
|
||||||
return c.Unlock()
|
return c.Unlock(id)
|
||||||
}
|
}
|
||||||
return nil
|
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.StateWriter = new(State)
|
||||||
var _ state.StatePersister = new(State)
|
var _ state.StatePersister = new(State)
|
||||||
var _ state.StateRefresher = new(State)
|
var _ state.StateRefresher = new(State)
|
||||||
|
var _ state.Locker = new(State)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue