github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/internal/states/statemgr/statemgr_fake.go (about)

     1  package statemgr
     2  
     3  import (
     4  	"errors"
     5  	"sync"
     6  
     7  	"github.com/eliastor/durgaform/internal/states"
     8  )
     9  
    10  // NewFullFake returns a full state manager that really only supports transient
    11  // snapshots. This is primarily intended for testing and is not suitable for
    12  // general use.
    13  //
    14  // The persistent part of the interface is stubbed out as an in-memory store,
    15  // and so its snapshots are effectively also transient.
    16  //
    17  // The given Transient implementation is used to implement the transient
    18  // portion of the interface. If nil is given, NewTransientInMemory is
    19  // automatically called to create an in-memory transient manager with no
    20  // initial transient snapshot.
    21  //
    22  // If the given initial state is non-nil then a copy of it will be used as
    23  // the initial persistent snapshot.
    24  //
    25  // The Locker portion of the returned manager uses a local mutex to simulate
    26  // mutually-exclusive access to the fake persistent portion of the object.
    27  func NewFullFake(t Transient, initial *states.State) Full {
    28  	if t == nil {
    29  		t = NewTransientInMemory(nil)
    30  	}
    31  
    32  	// The "persistent" part of our manager is actually just another in-memory
    33  	// transient used to fake a secondary storage layer.
    34  	fakeP := NewTransientInMemory(initial.DeepCopy())
    35  
    36  	return &fakeFull{
    37  		t:     t,
    38  		fakeP: fakeP,
    39  	}
    40  }
    41  
    42  type fakeFull struct {
    43  	t     Transient
    44  	fakeP Transient
    45  
    46  	lockLock sync.Mutex
    47  	locked   bool
    48  }
    49  
    50  var _ Full = (*fakeFull)(nil)
    51  
    52  func (m *fakeFull) State() *states.State {
    53  	return m.t.State()
    54  }
    55  
    56  func (m *fakeFull) WriteState(s *states.State) error {
    57  	return m.t.WriteState(s)
    58  }
    59  
    60  func (m *fakeFull) RefreshState() error {
    61  	return m.t.WriteState(m.fakeP.State())
    62  }
    63  
    64  func (m *fakeFull) PersistState() error {
    65  	return m.fakeP.WriteState(m.t.State())
    66  }
    67  
    68  func (m *fakeFull) GetRootOutputValues() (map[string]*states.OutputValue, error) {
    69  	return m.State().RootModule().OutputValues, nil
    70  }
    71  
    72  func (m *fakeFull) Lock(info *LockInfo) (string, error) {
    73  	m.lockLock.Lock()
    74  	defer m.lockLock.Unlock()
    75  
    76  	if m.locked {
    77  		return "", &LockError{
    78  			Err:  errors.New("fake state manager is locked"),
    79  			Info: info,
    80  		}
    81  	}
    82  
    83  	m.locked = true
    84  	return "placeholder", nil
    85  }
    86  
    87  func (m *fakeFull) Unlock(id string) error {
    88  	m.lockLock.Lock()
    89  	defer m.lockLock.Unlock()
    90  
    91  	if !m.locked {
    92  		return errors.New("fake state manager is not locked")
    93  	}
    94  	if id != "placeholder" {
    95  		return errors.New("wrong lock id for fake state manager")
    96  	}
    97  
    98  	m.locked = false
    99  	return nil
   100  }
   101  
   102  // NewUnlockErrorFull returns a state manager that is useful for testing errors
   103  // (mostly Unlock errors) when used with the clistate.Locker interface. Lock()
   104  // does not return an error because clistate.Locker Lock()s the state at the
   105  // start of Unlock(), so Lock() must succeeded for Unlock() to get called.
   106  func NewUnlockErrorFull(t Transient, initial *states.State) Full {
   107  	return &fakeErrorFull{}
   108  }
   109  
   110  type fakeErrorFull struct{}
   111  
   112  var _ Full = (*fakeErrorFull)(nil)
   113  
   114  func (m *fakeErrorFull) State() *states.State {
   115  	return nil
   116  }
   117  
   118  func (m *fakeErrorFull) GetRootOutputValues() (map[string]*states.OutputValue, error) {
   119  	return nil, errors.New("fake state manager error")
   120  }
   121  
   122  func (m *fakeErrorFull) WriteState(s *states.State) error {
   123  	return errors.New("fake state manager error")
   124  }
   125  
   126  func (m *fakeErrorFull) RefreshState() error {
   127  	return errors.New("fake state manager error")
   128  }
   129  
   130  func (m *fakeErrorFull) PersistState() error {
   131  	return errors.New("fake state manager error")
   132  }
   133  
   134  func (m *fakeErrorFull) Lock(info *LockInfo) (string, error) {
   135  	return "placeholder", nil
   136  }
   137  
   138  func (m *fakeErrorFull) Unlock(id string) error {
   139  	return errors.New("fake state manager error")
   140  }