2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-03-28 18:39:22 +00:00
|
|
|
|
2022-07-13 16:12:31 +00:00
|
|
|
package watch
|
|
|
|
|
|
|
|
import (
|
2022-07-14 18:45:51 +00:00
|
|
|
"errors"
|
2022-07-13 16:12:31 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestMap(t *testing.T) {
|
2022-10-14 09:26:42 +00:00
|
|
|
m := NewMap[string, testVal]()
|
2022-07-13 16:12:31 +00:00
|
|
|
|
|
|
|
// Set without init is a no-op
|
|
|
|
{
|
|
|
|
m.Set("hello", "world")
|
|
|
|
require.Equal(t, 0, m.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Getting from empty map
|
|
|
|
{
|
|
|
|
got, ok := m.Get("hello")
|
|
|
|
require.False(t, ok)
|
|
|
|
require.Empty(t, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
var called bool
|
|
|
|
cancelMock := func() {
|
|
|
|
called = true
|
|
|
|
}
|
|
|
|
|
|
|
|
// InitWatch successful
|
|
|
|
{
|
|
|
|
m.InitWatch("hello", cancelMock)
|
|
|
|
require.Equal(t, 1, m.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get still returns false
|
|
|
|
{
|
|
|
|
got, ok := m.Get("hello")
|
|
|
|
require.False(t, ok)
|
|
|
|
require.Empty(t, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set successful
|
|
|
|
{
|
|
|
|
require.True(t, m.Set("hello", "world"))
|
|
|
|
require.Equal(t, 1, m.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get successful
|
|
|
|
{
|
|
|
|
got, ok := m.Get("hello")
|
|
|
|
require.True(t, ok)
|
2022-10-14 09:26:42 +00:00
|
|
|
require.Equal(t, "world", string(got))
|
2022-07-13 16:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// CancelWatch successful
|
|
|
|
{
|
|
|
|
m.CancelWatch("hello")
|
|
|
|
require.Equal(t, 0, m.Len())
|
|
|
|
require.True(t, called)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get no-op
|
|
|
|
{
|
|
|
|
got, ok := m.Get("hello")
|
|
|
|
require.False(t, ok)
|
|
|
|
require.Empty(t, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set no-op
|
|
|
|
{
|
|
|
|
require.False(t, m.Set("hello", "world"))
|
|
|
|
require.Equal(t, 0, m.Len())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMap_ForEach(t *testing.T) {
|
2022-10-14 09:26:42 +00:00
|
|
|
m := NewMap[string, testVal]()
|
|
|
|
inputs := map[string]testVal{
|
|
|
|
"hello": "world",
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": "bat",
|
2022-07-13 16:12:31 +00:00
|
|
|
}
|
|
|
|
for k, v := range inputs {
|
|
|
|
m.InitWatch(k, nil)
|
|
|
|
m.Set(k, v)
|
|
|
|
}
|
|
|
|
require.Equal(t, 3, m.Len())
|
|
|
|
|
|
|
|
// returning true continues iteration
|
|
|
|
{
|
|
|
|
var count int
|
|
|
|
m.ForEachKey(func(k string) bool {
|
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
require.Equal(t, 3, count)
|
|
|
|
}
|
|
|
|
|
|
|
|
// returning false exits loop
|
|
|
|
{
|
|
|
|
var count int
|
|
|
|
m.ForEachKey(func(k string) bool {
|
|
|
|
count++
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
require.Equal(t, 1, count)
|
|
|
|
}
|
|
|
|
}
|
2022-07-14 18:45:51 +00:00
|
|
|
|
|
|
|
func TestMap_ForEachE(t *testing.T) {
|
2022-10-14 09:26:42 +00:00
|
|
|
m := NewMap[string, testVal]()
|
|
|
|
inputs := map[string]testVal{
|
|
|
|
"hello": "world",
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": "bat",
|
2022-07-14 18:45:51 +00:00
|
|
|
}
|
|
|
|
for k, v := range inputs {
|
|
|
|
m.InitWatch(k, nil)
|
|
|
|
m.Set(k, v)
|
|
|
|
}
|
|
|
|
require.Equal(t, 3, m.Len())
|
|
|
|
|
|
|
|
// returning nil error continues iteration
|
|
|
|
{
|
|
|
|
var count int
|
|
|
|
err := m.ForEachKeyE(func(k string) error {
|
|
|
|
count++
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
require.Equal(t, 3, count)
|
|
|
|
require.Nil(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// returning an error should exit immediately
|
|
|
|
{
|
|
|
|
var count int
|
|
|
|
err := m.ForEachKeyE(func(k string) error {
|
|
|
|
count++
|
|
|
|
return errors.New("boooo")
|
|
|
|
})
|
|
|
|
require.Equal(t, 1, count)
|
|
|
|
require.Errorf(t, err, "boo")
|
|
|
|
}
|
|
|
|
}
|
2022-10-14 09:26:42 +00:00
|
|
|
|
|
|
|
func TestMap_DeepCopy(t *testing.T) {
|
|
|
|
orig := NewMap[string, testVal]()
|
|
|
|
inputs := map[string]testVal{
|
|
|
|
"hello": "world",
|
|
|
|
"foo": "bar",
|
|
|
|
"baz": "bat",
|
|
|
|
}
|
|
|
|
for k, v := range inputs {
|
|
|
|
orig.InitWatch(k, nil)
|
|
|
|
orig.Set(k, v)
|
|
|
|
}
|
|
|
|
require.Equal(t, 3, orig.Len())
|
|
|
|
|
|
|
|
clone := orig.DeepCopy()
|
|
|
|
require.Equal(t, 3, clone.Len())
|
|
|
|
|
|
|
|
orig.CancelWatch("hello")
|
|
|
|
require.NotEqual(t, orig.Len(), clone.Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
type testVal string
|
|
|
|
|
|
|
|
func (tv testVal) DeepCopy() testVal { return tv }
|