...
1 package mocks
2
3 import (
4 "sync"
5 "testing"
6 "time"
7
8 "github.com/launchdarkly/go-server-sdk/v6/interfaces"
9 "github.com/launchdarkly/go-server-sdk/v6/subsystems"
10 "github.com/launchdarkly/go-server-sdk/v6/subsystems/ldstoretypes"
11
12 th "github.com/launchdarkly/go-test-helpers/v3"
13
14 "github.com/stretchr/testify/assert"
15 )
16
17
18 type MockDataSourceUpdates struct {
19 DataStore *CapturingDataStore
20 Statuses chan interfaces.DataSourceStatus
21 dataStoreStatusProvider *mockDataStoreStatusProvider
22 lastStatus interfaces.DataSourceStatus
23 lock sync.Mutex
24 }
25
26
27
28
29
30 func NewMockDataSourceUpdates(realStore subsystems.DataStore) *MockDataSourceUpdates {
31 dataStore := NewCapturingDataStore(realStore)
32 dataStoreStatusProvider := &mockDataStoreStatusProvider{
33 dataStore: dataStore,
34 status: interfaces.DataStoreStatus{Available: true},
35 statusCh: make(chan interfaces.DataStoreStatus, 10),
36 }
37 return &MockDataSourceUpdates{
38 DataStore: dataStore,
39 Statuses: make(chan interfaces.DataSourceStatus, 10),
40 dataStoreStatusProvider: dataStoreStatusProvider,
41 }
42 }
43
44
45 func (d *MockDataSourceUpdates) Init(allData []ldstoretypes.Collection) bool {
46 for _, coll := range allData {
47 AssertNotNil(coll.Kind)
48 }
49 err := d.DataStore.Init(allData)
50 return err == nil
51 }
52
53
54 func (d *MockDataSourceUpdates) Upsert(
55 kind ldstoretypes.DataKind,
56 key string,
57 newItem ldstoretypes.ItemDescriptor,
58 ) bool {
59 AssertNotNil(kind)
60 _, err := d.DataStore.Upsert(kind, key, newItem)
61 return err == nil
62 }
63
64
65 func (d *MockDataSourceUpdates) UpdateStatus(
66 newState interfaces.DataSourceState,
67 newError interfaces.DataSourceErrorInfo,
68 ) {
69 d.lock.Lock()
70 defer d.lock.Unlock()
71 if newState != d.lastStatus.State || newError.Kind != "" {
72 d.lastStatus = interfaces.DataSourceStatus{State: newState, LastError: newError}
73 d.Statuses <- d.lastStatus
74 }
75 }
76
77
78
79 func (d *MockDataSourceUpdates) GetDataStoreStatusProvider() interfaces.DataStoreStatusProvider {
80 return d.dataStoreStatusProvider
81 }
82
83
84 func (d *MockDataSourceUpdates) UpdateStoreStatus(newStatus interfaces.DataStoreStatus) {
85 d.dataStoreStatusProvider.statusCh <- newStatus
86 }
87
88
89 func (d *MockDataSourceUpdates) RequireStatusOf(
90 t *testing.T,
91 newState interfaces.DataSourceState,
92 ) interfaces.DataSourceStatus {
93 status := d.RequireStatus(t)
94 assert.Equal(t, string(newState), string(status.State))
95
96 return status
97 }
98
99
100 func (d *MockDataSourceUpdates) RequireStatus(t *testing.T) interfaces.DataSourceStatus {
101 return th.RequireValue(t, d.Statuses, time.Second, "timed out waiting for new data source status")
102 }
103
104 type mockDataStoreStatusProvider struct {
105 dataStore subsystems.DataStore
106 status interfaces.DataStoreStatus
107 statusCh chan interfaces.DataStoreStatus
108 lock sync.Mutex
109 }
110
111 func (m *mockDataStoreStatusProvider) GetStatus() interfaces.DataStoreStatus {
112 m.lock.Lock()
113 defer m.lock.Unlock()
114 return m.status
115 }
116
117 func (m *mockDataStoreStatusProvider) IsStatusMonitoringEnabled() bool {
118 return m.dataStore.IsStatusMonitoringEnabled()
119 }
120
121 func (m *mockDataStoreStatusProvider) AddStatusListener() <-chan interfaces.DataStoreStatus {
122 return m.statusCh
123 }
124
125 func (m *mockDataStoreStatusProvider) RemoveStatusListener(ch <-chan interfaces.DataStoreStatus) {
126 }
127
View as plain text