github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/utils/concurrentmap/concurrentmap_test.go (about) 1 // Copyright 2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package concurrentmap 16 17 import ( 18 "sync" 19 "testing" 20 ) 21 22 func TestConcurrentMapConstructor(t *testing.T) { 23 m := New[int, string]() 24 if m == nil { 25 t.Fatal("New concurrent map is nil") 26 } 27 if m.m == nil { 28 t.Error("New concurrent map's underlying map is nil") 29 } 30 if len(m.m) != 0 { 31 t.Error("New concurrent map's underlying map is not empty") 32 } 33 } 34 35 func TestConcurrentMapSetAndGet(t *testing.T) { 36 m := New[int, string]() 37 m.Set(1, "a") 38 39 // Test that the value is set 40 if val, found := m.Get(1); !found || val != "a" { 41 t.Errorf("Got %s, want %s", val, "a") 42 } 43 // Test that the value is not set for a different key 44 if val, found := m.Get(2); found || val != "" { 45 t.Errorf("Got %s, want an empty value and a not found", val) 46 } 47 } 48 49 func TestConcurrentMapDelete(t *testing.T) { 50 m := New[int, string]() 51 m.Set(1, "a") 52 m.Delete(1) 53 54 // Test that the value is deleted 55 if _, found := m.Get(1); found { 56 t.Errorf("Expected key 1 to be deleted") 57 } 58 } 59 60 func TestConcurrentMapLen(t *testing.T) { 61 m := New[int, string]() 62 m.Set(1, "a") 63 m.Set(2, "b") 64 m.Set(3, "b") 65 66 // Test that the length is correct 67 if m.Len() != 3 { 68 t.Errorf("Expected length 3, got %d", m.Len()) 69 } 70 } 71 72 func TestConcurrentMapDeepCopy(t *testing.T) { 73 m := New[int, string]() 74 m.Set(1, "a") 75 copy := m.DeepCopy() 76 m.Set(1, "b") 77 78 // Test that the copy is not affected by the original 79 if val, _ := copy.Get(1); val != "a" { 80 t.Errorf("DeepCopy failed, expected 'a', got '%s'", val) 81 } 82 } 83 84 func TestConcurrentMapIter(t *testing.T) { 85 m := New[int, string]() 86 m.Set(1, "a") 87 m.Set(2, "b") 88 m.Set(3, "c") 89 90 counter := 0 91 elements := make(map[int]string) 92 m.Iter(func(key int, value string) bool { 93 counter++ 94 elements[key] = value 95 return true 96 }) 97 98 // Test that the iterator iterates over all elements 99 if counter != 3 { 100 t.Errorf("Iter failed, expected to iterate 3 times, iterated %d times", counter) 101 } 102 103 // Test that iteration yeilds all elements 104 if len(elements) != 3 { 105 t.Errorf("Iter failed, there should be 3 elements in the map, got %d", len(elements)) 106 } 107 if elements[1] != "a" || elements[2] != "b" || elements[3] != "c" { 108 t.Errorf("Iter failed, expected to have 3 elements in the map, with correct values: %v", elements) 109 } 110 } 111 112 func TestConcurrentMapSetAndGetWithConcurrency(t *testing.T) { 113 m := New[int, int]() 114 var wg sync.WaitGroup 115 116 // Set 100 elements concurrently 117 for i := 0; i < 100; i++ { 118 wg.Add(1) 119 go func(i int) { 120 defer wg.Done() 121 m.Set(i, i) 122 }(i) 123 } 124 125 // Wait for al goroutines to finish 126 wg.Wait() 127 128 // Test that all elements are set 129 for i := 0; i < 100; i++ { 130 if val, found := m.Get(i); !found || val != i { 131 t.Errorf("Got %d, want %d", val, i) 132 } 133 } 134 }