github.com/braveheart12/just@v0.8.7/ledger/recentstorage/recentstorage_concrete_test.go (about) 1 /* 2 * Copyright 2019 Insolar 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package recentstorage 18 19 import ( 20 "bytes" 21 "sync" 22 "testing" 23 24 "github.com/insolar/insolar/core" 25 "github.com/insolar/insolar/instrumentation/inslogger" 26 "github.com/insolar/insolar/testutils" 27 "github.com/stretchr/testify/require" 28 ) 29 30 func TestNewRecentIndexStorage(t *testing.T) { 31 t.Parallel() 32 jetID := testutils.RandomID() 33 index := NewRecentIndexStorage(jetID, 123) 34 require.NotNil(t, index) 35 require.NotNil(t, index.indexes) 36 require.Equal(t, 123, index.DefaultTTL) 37 } 38 39 func TestNewRecentIndexStorage_AddId(t *testing.T) { 40 t.Parallel() 41 ctx := inslogger.TestContext(t) 42 jetID := testutils.RandomID() 43 s := NewRecentIndexStorage(jetID, 123) 44 45 wg := sync.WaitGroup{} 46 wg.Add(3) 47 48 go func() { 49 s.AddObject(ctx, *core.NewRecordID(123, []byte{1})) 50 wg.Done() 51 }() 52 go func() { 53 s.AddObject(ctx, *core.NewRecordID(123, []byte{2})) 54 wg.Done() 55 }() 56 go func() { 57 s.AddObject(ctx, *core.NewRecordID(123, []byte{3})) 58 wg.Done() 59 }() 60 61 wg.Wait() 62 require.Equal(t, 3, len(s.GetObjects())) 63 } 64 65 func TestPendingStorage_AddPendingRequest(t *testing.T) { 66 t.Parallel() 67 ctx := inslogger.TestContext(t) 68 jetID := testutils.RandomID() 69 70 s := NewPendingStorage(jetID) 71 72 obj1 := *core.NewRecordID(0, nil) 73 obj2 := *core.NewRecordID(1, nil) 74 75 wg := sync.WaitGroup{} 76 wg.Add(3) 77 78 expectedIDs := []core.RecordID{ 79 *core.NewRecordID(123, []byte{1}), 80 *core.NewRecordID(123, []byte{2}), 81 *core.NewRecordID(123, []byte{3}), 82 } 83 go func() { 84 s.AddPendingRequest(ctx, obj1, expectedIDs[0]) 85 wg.Done() 86 }() 87 go func() { 88 s.AddPendingRequest(ctx, obj1, expectedIDs[1]) 89 wg.Done() 90 }() 91 go func() { 92 s.AddPendingRequest(ctx, obj2, expectedIDs[2]) 93 wg.Done() 94 }() 95 wg.Wait() 96 97 contains := func(slice []core.RecordID, x core.RecordID) bool { 98 for _, n := range slice { 99 if x == n { 100 return true 101 } 102 } 103 return false 104 } 105 requests := s.GetRequests() 106 require.Equal(t, 2, len(requests)) 107 for key, objContext := range requests { 108 if bytes.Equal(key.Bytes(), obj1.Bytes()) { 109 require.Equal(t, 2, len(objContext.Requests)) 110 require.Equal(t, true, contains(objContext.Requests, expectedIDs[0])) 111 require.Equal(t, true, contains(objContext.Requests, expectedIDs[1])) 112 } else { 113 require.Equal(t, 1, len(objContext.Requests)) 114 require.Equal(t, expectedIDs[2], objContext.Requests[0]) 115 } 116 } 117 } 118 119 func TestPendingStorage_RemovePendingRequest(t *testing.T) { 120 t.Parallel() 121 ctx := inslogger.TestContext(t) 122 jetID := testutils.RandomID() 123 124 s := NewPendingStorage(jetID) 125 126 obj := *core.NewRecordID(0, nil) 127 128 expectedIDs := []core.RecordID{ 129 *core.NewRecordID(123, []byte{1}), 130 } 131 extraIDs := []core.RecordID{ 132 *core.NewRecordID(123, []byte{2}), 133 *core.NewRecordID(123, []byte{3}), 134 *core.NewRecordID(123, []byte{4}), 135 } 136 s.requests = map[core.RecordID]*lockedPendingObjectContext{ 137 obj: { 138 Context: &PendingObjectContext{ 139 Requests: []core.RecordID{expectedIDs[0], extraIDs[0], extraIDs[1], extraIDs[2]}, 140 }, 141 }, 142 } 143 144 wg := sync.WaitGroup{} 145 wg.Add(3) 146 go func() { 147 s.RemovePendingRequest(ctx, obj, extraIDs[0]) 148 wg.Done() 149 }() 150 go func() { 151 s.RemovePendingRequest(ctx, obj, extraIDs[1]) 152 wg.Done() 153 }() 154 go func() { 155 s.RemovePendingRequest(ctx, obj, extraIDs[2]) 156 wg.Done() 157 }() 158 wg.Wait() 159 160 require.Equal( 161 t, 162 map[core.RecordID]PendingObjectContext{ 163 obj: { 164 Active: true, 165 Requests: []core.RecordID{expectedIDs[0]}, 166 }, 167 }, 168 s.GetRequests(), 169 ) 170 } 171 172 func TestPendingStorage_RemovePendingRequest_RemoveNothingIfThereIsNothing(t *testing.T) { 173 t.Parallel() 174 ctx := inslogger.TestContext(t) 175 jetID := testutils.RandomID() 176 objID := testutils.RandomID() 177 anotherObj := *core.NewRecordID(123, nil) 178 s := NewPendingStorage(jetID) 179 180 s.requests = map[core.RecordID]*lockedPendingObjectContext{ 181 objID: { 182 Context: &PendingObjectContext{ 183 Requests: []core.RecordID{}, 184 }, 185 }, 186 } 187 188 s.RemovePendingRequest(ctx, anotherObj, testutils.RandomID()) 189 190 require.Equal( 191 t, 192 map[core.RecordID]PendingObjectContext{ 193 objID: { 194 Requests: []core.RecordID{}, 195 }, 196 }, 197 s.GetRequests(), 198 ) 199 } 200 201 func TestNewRecentStorageProvider(t *testing.T) { 202 t.Parallel() 203 // Act 204 provider := NewRecentStorageProvider(888) 205 206 // Assert 207 require.Equal(t, 888, provider.DefaultTTL) 208 require.NotNil(t, provider.pendingStorages) 209 require.NotNil(t, provider.indexStorages) 210 } 211 212 func TestRecentStorageProvider_GetStorage(t *testing.T) { 213 t.Parallel() 214 // Arrange 215 provider := NewRecentStorageProvider(8) 216 217 // Act 218 wg := sync.WaitGroup{} 219 wg.Add(8) 220 221 for i := 0; i < 8; i++ { 222 go func() { 223 id := testutils.RandomJet() 224 storage := provider.GetIndexStorage(inslogger.TestContext(t), id) 225 require.NotNil(t, storage) 226 pendingStorage := provider.GetPendingStorage(inslogger.TestContext(t), id) 227 require.NotNil(t, pendingStorage) 228 wg.Done() 229 }() 230 } 231 232 wg.Wait() 233 234 // Assert 235 require.Equal(t, 8, len(provider.indexStorages)) 236 require.Equal(t, 8, len(provider.pendingStorages)) 237 } 238 239 func TestRecentStorage_markForDelete(t *testing.T) { 240 t.Parallel() 241 candidates := make([]core.RecordID, 0, 100) 242 expect := make([]core.RecordID, 0, 50) 243 recentStorageMap := make(map[core.RecordID]recentObjectMeta) 244 245 for i := 0; i < 100; i++ { 246 rID := testutils.RandomID() 247 candidates = append(candidates, rID) 248 if i%2 == 0 { 249 expect = append(expect, rID) 250 } else { 251 recentStorageMap[rID] = recentObjectMeta{i} 252 } 253 } 254 255 recentStorage := NewRecentIndexStorage(testutils.RandomJet(), 888) 256 recentStorage.indexes = recentStorageMap 257 258 markedCandidates := recentStorage.markForDelete(candidates) 259 260 require.Equal(t, expect, markedCandidates) 261 } 262 263 func TestRecentStorageProvider_DecreaseIndexesTTL(t *testing.T) { 264 t.Parallel() 265 // Arrange 266 ctx := inslogger.TestContext(t) 267 268 firstJet := testutils.RandomJet() 269 secondJet := testutils.RandomJet() 270 271 provider := NewRecentStorageProvider(8) 272 provider.GetIndexStorage(ctx, firstJet).AddObject(ctx, testutils.RandomID()) 273 provider.GetIndexStorage(ctx, firstJet).AddObject(ctx, testutils.RandomID()) 274 275 removedFirst := testutils.RandomID() 276 removedSecond := testutils.RandomID() 277 provider.GetIndexStorage(ctx, secondJet).AddObjectWithTLL(ctx, removedFirst, 1) 278 provider.GetIndexStorage(ctx, secondJet).AddObjectWithTLL(ctx, removedSecond, 1) 279 280 // Act 281 result := provider.DecreaseIndexesTTL(ctx) 282 283 // Assert 284 provider.indexLock.Lock() 285 defer provider.indexLock.Unlock() 286 require.NotNil(t, result) 287 require.Equal(t, 1, len(provider.indexStorages)) 288 require.Equal(t, 1, len(result)) 289 require.Equal(t, 2, len(result[secondJet])) 290 if removedFirst != result[secondJet][0] && removedFirst != result[secondJet][1] { 291 require.Fail(t, "return result is broken") 292 } 293 if removedSecond != result[secondJet][1] && removedSecond != result[secondJet][0] { 294 require.Fail(t, "return result is broken") 295 } 296 for _, index := range provider.indexStorages[firstJet].indexes { 297 require.Equal(t, 7, index.ttl) 298 } 299 } 300 301 func TestRecentStorageProvider_DecreaseIndexesTTL_WorksOnEmptyStorage(t *testing.T) { 302 t.Parallel() 303 // Arrange 304 ctx := inslogger.TestContext(t) 305 provider := NewRecentStorageProvider(8) 306 307 // Act 308 result := provider.DecreaseIndexesTTL(ctx) 309 310 // Assert 311 require.Equal(t, map[core.RecordID][]core.RecordID{}, result) 312 } 313 314 func TestPendingStorageConcrete_GetRequestsForObject(t *testing.T) { 315 t.Parallel() 316 317 objID := testutils.RandomID() 318 requestID := testutils.RandomID() 319 320 unexpectedID := testutils.RandomID() 321 unexpectedReqID := testutils.RandomID() 322 323 pendingStorage := &PendingStorageConcrete{ 324 requests: map[core.RecordID]*lockedPendingObjectContext{ 325 objID: { 326 Context: &PendingObjectContext{ 327 Requests: []core.RecordID{requestID}, 328 }, 329 }, 330 unexpectedID: { 331 Context: &PendingObjectContext{ 332 Requests: []core.RecordID{unexpectedReqID}, 333 }, 334 }, 335 }, 336 } 337 338 requests := pendingStorage.GetRequestsForObject(objID) 339 340 require.Equal(t, 1, len(requests)) 341 require.Equal(t, requestID, requests[0]) 342 } 343 344 func TestPendingStorageConcrete_GetRequestsForObject_NoObject(t *testing.T) { 345 t.Parallel() 346 347 unexpectedReqID := testutils.RandomID() 348 349 pendingStorage := &PendingStorageConcrete{ 350 requests: map[core.RecordID]*lockedPendingObjectContext{}, 351 } 352 353 requests := pendingStorage.GetRequestsForObject(unexpectedReqID) 354 355 require.Nil(t, requests) 356 } 357 358 func TestPendingStorageConcrete_SetContextToObject(t *testing.T) { 359 t.Parallel() 360 361 pendingStorage := &PendingStorageConcrete{ 362 requests: map[core.RecordID]*lockedPendingObjectContext{}, 363 } 364 expectedObj := testutils.RandomID() 365 expectedContext := PendingObjectContext{ 366 Active: true, 367 Requests: []core.RecordID{testutils.RandomID(), testutils.RandomID()}, 368 } 369 370 pendingStorage.SetContextToObject(inslogger.TestContext(t), expectedObj, expectedContext) 371 372 require.Equal(t, 1, len(pendingStorage.requests)) 373 require.Equal(t, expectedContext, *pendingStorage.requests[expectedObj].Context) 374 } 375 376 func TestPendingStorageConcrete_RemovePendingRequest_RemoveFromStart(t *testing.T) { 377 t.Parallel() 378 379 objID := testutils.RandomID() 380 first := testutils.RandomID() 381 second := testutils.RandomID() 382 pendingStorage := &PendingStorageConcrete{ 383 requests: map[core.RecordID]*lockedPendingObjectContext{ 384 385 objID: { 386 Context: &PendingObjectContext{ 387 Requests: []core.RecordID{first, second}, 388 }, 389 }, 390 }, 391 } 392 393 pendingStorage.RemovePendingRequest(inslogger.TestContext(t), objID, first) 394 395 require.Equal(t, 1, len(pendingStorage.requests[objID].Context.Requests)) 396 require.Equal(t, second, pendingStorage.requests[objID].Context.Requests[0]) 397 } 398 399 func TestPendingStorageConcrete_RemovePendingRequest_RemoveFromEnd(t *testing.T) { 400 t.Parallel() 401 402 objID := testutils.RandomID() 403 first := testutils.RandomID() 404 second := testutils.RandomID() 405 pendingStorage := &PendingStorageConcrete{ 406 requests: map[core.RecordID]*lockedPendingObjectContext{ 407 408 objID: { 409 Context: &PendingObjectContext{ 410 Requests: []core.RecordID{first, second}, 411 }, 412 }, 413 }, 414 } 415 416 pendingStorage.RemovePendingRequest(inslogger.TestContext(t), objID, second) 417 418 require.Equal(t, 1, len(pendingStorage.requests[objID].Context.Requests)) 419 require.Equal(t, first, pendingStorage.requests[objID].Context.Requests[0]) 420 } 421 422 func TestPendingStorageConcrete_RemovePendingRequest_RemoveFromMiddle(t *testing.T) { 423 t.Parallel() 424 425 objID := testutils.RandomID() 426 first := testutils.RandomID() 427 second := testutils.RandomID() 428 third := testutils.RandomID() 429 pendingStorage := &PendingStorageConcrete{ 430 requests: map[core.RecordID]*lockedPendingObjectContext{ 431 432 objID: { 433 Context: &PendingObjectContext{ 434 Requests: []core.RecordID{first, second, third}, 435 }, 436 }, 437 }, 438 } 439 440 pendingStorage.RemovePendingRequest(inslogger.TestContext(t), objID, second) 441 442 require.Equal(t, 2, len(pendingStorage.requests[objID].Context.Requests)) 443 require.Equal(t, first, pendingStorage.requests[objID].Context.Requests[0]) 444 require.Equal(t, third, pendingStorage.requests[objID].Context.Requests[1]) 445 } 446 447 func TestPendingStorageConcrete_RemovePendingRequest_NothingHappensIfNoRequests(t *testing.T) { 448 t.Parallel() 449 450 objID := testutils.RandomID() 451 pendingStorage := &PendingStorageConcrete{ 452 requests: map[core.RecordID]*lockedPendingObjectContext{ 453 454 objID: { 455 Context: &PendingObjectContext{}, 456 }, 457 }, 458 } 459 460 pendingStorage.RemovePendingRequest(inslogger.TestContext(t), objID, testutils.RandomID()) 461 462 require.Equal(t, 1, len(pendingStorage.requests)) 463 _, ok := pendingStorage.requests[objID] 464 require.Equal(t, true, ok) 465 } 466 467 func TestPendingStorageConcrete_RemovePendingRequest_RemoveOnlyOne(t *testing.T) { 468 t.Parallel() 469 470 first := testutils.RandomID() 471 objID := testutils.RandomID() 472 473 pendingStorage := &PendingStorageConcrete{ 474 requests: map[core.RecordID]*lockedPendingObjectContext{ 475 objID: { 476 Context: &PendingObjectContext{ 477 Requests: []core.RecordID{first}, 478 }, 479 }, 480 }, 481 } 482 483 pendingStorage.RemovePendingRequest(inslogger.TestContext(t), objID, first) 484 485 require.Equal(t, 0, len(pendingStorage.requests[objID].Context.Requests)) 486 } 487 488 func TestPendingStorageConcrete_RemovePendingRequest_RemoveNotExisting(t *testing.T) { 489 t.Parallel() 490 491 objID := testutils.RandomID() 492 first := testutils.RandomID() 493 second := testutils.RandomID() 494 third := testutils.RandomID() 495 pendingStorage := &PendingStorageConcrete{ 496 requests: map[core.RecordID]*lockedPendingObjectContext{ 497 498 objID: { 499 Context: &PendingObjectContext{ 500 Requests: []core.RecordID{first, second}, 501 }, 502 }, 503 }, 504 } 505 506 pendingStorage.RemovePendingRequest(inslogger.TestContext(t), objID, third) 507 508 require.Equal(t, 2, len(pendingStorage.requests[objID].Context.Requests)) 509 require.Equal(t, first, pendingStorage.requests[objID].Context.Requests[0]) 510 require.Equal(t, second, pendingStorage.requests[objID].Context.Requests[1]) 511 }