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  }