github.com/vmware/transport-go@v1.3.4/bus/store_manager_test.go (about) 1 // Copyright 2019-2020 VMware, Inc. 2 // SPDX-License-Identifier: BSD-2-Clause 3 4 package bus 5 6 import ( 7 "github.com/google/uuid" 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/mock" 10 "reflect" 11 "sync" 12 "sync/atomic" 13 "testing" 14 ) 15 16 func createTestStoreManager() StoreManager { 17 return newStoreManager(GetBus()) 18 } 19 20 func TestStoreManager_CreateStore(t *testing.T) { 21 storeManager := createTestStoreManager() 22 assert.NotNil(t, storeManager) 23 24 wg := sync.WaitGroup{} 25 26 for i := 0; i < 50; i++ { 27 wg.Add(1) 28 go func() { 29 store := storeManager.CreateStore("testStore") 30 assert.NotNil(t, store) 31 assert.Equal(t, store.GetName(), "testStore") 32 assert.Equal(t, store, storeManager.GetStore("testStore")) 33 wg.Done() 34 }() 35 } 36 37 wg.Wait() 38 39 store2 := storeManager.CreateStore("testStore2") 40 assert.NotEqual(t, store2, storeManager.GetStore("testStore")) 41 } 42 43 func TestStoreManager_GetStore(t *testing.T) { 44 storeManager := createTestStoreManager() 45 storeManager.CreateStore("testStore") 46 store := storeManager.GetStore("testStore") 47 assert.Equal(t, store.GetName(), "testStore") 48 49 assert.Nil(t, storeManager.GetStore("invalid-store")) 50 } 51 52 func TestStoreManager_DestroyStore(t *testing.T) { 53 storeManager := createTestStoreManager() 54 storeManager.CreateStore("testStore") 55 56 var counter int32 = 0 57 58 wg := sync.WaitGroup{} 59 60 for i := 0; i < 50; i++ { 61 wg.Add(1) 62 go func() { 63 if storeManager.DestroyStore("testStore") { 64 atomic.AddInt32(&counter, 1) 65 } 66 assert.Nil(t, storeManager.GetStore("testStore")) 67 wg.Done() 68 }() 69 } 70 71 wg.Wait() 72 73 // Verify that only one of the DestroyStore calls was successful (has returned true) 74 assert.Equal(t, counter, int32(1)) 75 } 76 77 func TestStoreManager_ConfigureStoreSyncChannel(t *testing.T) { 78 m := createTestStoreManager() 79 id := uuid.New() 80 con := &MockBridgeConnection{Id: &id} 81 82 subId := uuid.New() 83 s := &MockBridgeSubscription{ 84 Id: &subId, 85 } 86 syncChannelDst := "/topic-prefix/transport-store-sync." + id.String() 87 con.On("Subscribe", syncChannelDst).Return(s, nil) 88 con.On("SendMessage", syncChannelDst, mock.Anything).Return(nil) 89 m.ConfigureStoreSyncChannel(con, "/topic-prefix", "/pub-prefix") 90 91 storeManagerImpl := m.(*storeManager) 92 93 conf, ok := storeManagerImpl.syncChannels[id] 94 assert.True(t, ok) 95 assert.NotNil(t, conf.syncChannelName) 96 assert.Equal(t, conf.pubPrefix, "/pub-prefix/") 97 assert.Equal(t, conf.topicPrefix, "/topic-prefix/") 98 assert.Equal(t, conf.conn, con) 99 100 syncCh, _ := storeManagerImpl.eventBus.GetChannelManager().GetChannel(conf.syncChannelName) 101 assert.True(t, syncCh.galactic) 102 103 err := m.ConfigureStoreSyncChannel(con, "/topic-prefix", "/pub-prefix") 104 assert.EqualError(t, err, "store sync channel already configured for this connection") 105 } 106 107 func TestStoreManager_OpenGalacticStore(t *testing.T) { 108 m := createTestStoreManager() 109 id := uuid.New() 110 con := &MockBridgeConnection{Id: &id} 111 112 var s BusStore 113 var err error 114 115 s, err = m.OpenGalacticStore("galacticStore", con) 116 117 assert.Nil(t, s) 118 assert.EqualError(t, err, "sync channel is not configured for this connection") 119 120 subId := uuid.New() 121 sub := &MockBridgeSubscription{ 122 Id: &subId, 123 } 124 con.On("Subscribe", mock.Anything).Return(sub, nil) 125 con.On("SendJSONMessage", mock.Anything, mock.Anything).Return(nil) 126 con.On("SendMessage", mock.Anything, mock.Anything, mock.Anything).Return(nil) 127 m.ConfigureStoreSyncChannel(con, "/topic-prefix", "/pub-prefix") 128 129 storeManagerImpl := m.(*storeManager) 130 131 conf, _ := storeManagerImpl.syncChannels[id] 132 assert.NotNil(t, conf) 133 134 s, err = m.OpenGalacticStore("galacticStore", con) 135 136 assert.Nil(t, err) 137 assert.True(t, s.IsGalactic()) 138 139 wg := sync.WaitGroup{} 140 wg.Add(1) 141 142 s.WhenReady(func() { 143 assert.Equal(t, len(s.AllValues()), 2) 144 assert.Equal(t, s.GetValue("id1"), "value1") 145 assert.Equal(t, s.GetValue("id2"), "value2") 146 147 wg.Done() 148 }) 149 150 var jsonBlob = []byte(`{ 151 "storeId": "galacticStore", 152 "responseType": "storeContentResponse", 153 "items": { 154 "id1": "value1", 155 "id2": "value2" 156 } 157 }`) 158 159 storeManagerImpl.eventBus.SendResponseMessage(conf.syncChannelName, jsonBlob, nil) 160 wg.Wait() 161 } 162 163 type MockStoreItem struct { 164 From string `json:"from"` 165 Message string `json:"message"` 166 } 167 168 func TestStoreManager_OpenGalacticStoreWithType(t *testing.T) { 169 m := createTestStoreManager() 170 id := uuid.New() 171 con := &MockBridgeConnection{Id: &id} 172 173 subId := uuid.New() 174 sub := &MockBridgeSubscription{ 175 Id: &subId, 176 } 177 con.On("Subscribe", mock.Anything).Return(sub, nil) 178 con.On("SendJSONMessage", mock.Anything, mock.Anything).Return(nil) 179 con.On("SendMessage", mock.Anything, mock.Anything).Return(nil) 180 m.ConfigureStoreSyncChannel(con, "/topic-prefix", "/pub-prefix") 181 182 storeManagerImpl := m.(*storeManager) 183 184 conf, _ := storeManagerImpl.syncChannels[id] 185 assert.NotNil(t, conf) 186 187 store, _ := m.OpenGalacticStoreWithItemType("galacticStore", con, reflect.TypeOf(MockStoreItem{})) 188 189 store2, err := m.OpenGalacticStoreWithItemType("galacticStore", con, reflect.TypeOf(MockStoreItem{})) 190 191 assert.Equal(t, store, store2) 192 assert.Nil(t, err) 193 194 assert.True(t, store.IsGalactic()) 195 196 wg := sync.WaitGroup{} 197 wg.Add(1) 198 199 store.WhenReady(func() { 200 201 assert.Equal(t, len(store.AllValues()), 1) 202 assert.Equal(t, store.GetValue("id1"), MockStoreItem{ 203 From: "test-user", 204 Message: "test-message", 205 }) 206 207 wg.Done() 208 }) 209 210 var jsonBlob = []byte(`{ 211 "storeId": "galacticStore", 212 "responseType": "storeContentResponse", 213 "items": { 214 "id1": { 215 "from": "test-user", 216 "message": "test-message" 217 } 218 } 219 }`) 220 221 storeManagerImpl.eventBus.SendResponseMessage(conf.syncChannelName, jsonBlob, nil) 222 wg.Wait() 223 } 224 225 func TestStoreManager_OpenGalacticStoreWithLocalStoreId(t *testing.T) { 226 227 m := createTestStoreManager() 228 id := uuid.New() 229 con := &MockBridgeConnection{Id: &id} 230 subId := uuid.New() 231 sub := &MockBridgeSubscription{ 232 Id: &subId, 233 } 234 con.On("Subscribe", mock.Anything).Return(sub, nil) 235 con.On("SendMessage", mock.Anything, mock.Anything).Return(nil) 236 m.ConfigureStoreSyncChannel(con, "/topic-prefix", "/pub-prefix") 237 238 localStore := m.CreateStore("localStore") 239 240 store, err := m.OpenGalacticStoreWithItemType("localStore", con, reflect.TypeOf(MockStoreItem{})) 241 242 assert.EqualError(t, err, "cannot open galactic store: there is a local store with the same name") 243 assert.Equal(t, store, localStore) 244 }