blob: e2d763555ca7d06dd5812a6a88f67e8cbf217b69 [file] [log] [blame]
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package grpc
import (
"container/list"
"fmt"
"reflect"
"testing"
)
var linkedMapTestData = make([]*stickyStoreEntry, 5)
func TestLinkedMapPutGet(t *testing.T) {
m := newLinkedMap()
m.put("one", linkedMapTestData[0])
if got, ok := m.get("one"); !ok || got != linkedMapTestData[0] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 1, got, ok, "one")
}
m.put("two", linkedMapTestData[1])
if got, ok := m.get("two"); !ok || got != linkedMapTestData[1] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 2, got, ok, "two")
}
m.put("oneone", linkedMapTestData[4])
if got, ok := m.get("one"); !ok || got != linkedMapTestData[4] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 1, got, ok, "oneone")
}
}
func TestLinkedMapRemove(t *testing.T) {
m := newLinkedMap()
m.put("one", linkedMapTestData[0])
if got, ok := m.get("one"); !ok || got != linkedMapTestData[0] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 1, got, ok, "one")
}
m.put("two", linkedMapTestData[1])
if got, ok := m.get("two"); !ok || got != linkedMapTestData[1] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 2, got, ok, "two")
}
if got, ok := m.remove("one"); !ok || got != linkedMapTestData[0] {
t.Errorf("m.Remove(%v) = %v, %v, want %v, true", 1, got, ok, "one")
}
if got, ok := m.get("one"); ok {
t.Errorf("m.Get(%v) = %v, %v, want _, false", 1, got, ok)
}
// 2 should still in the map.
if got, ok := m.get("two"); !ok || got != linkedMapTestData[1] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 2, got, ok, "two")
}
}
func TestLinkedMapLen(t *testing.T) {
m := newLinkedMap()
if got := m.len(); got != 0 {
t.Errorf("m.Len() = %v, want %v", got, 0)
}
m.put("one", linkedMapTestData[0])
if got := m.len(); got != 1 {
t.Errorf("m.Len() = %v, want %v", got, 1)
}
m.put("two", linkedMapTestData[1])
if got := m.len(); got != 2 {
t.Errorf("m.Len() = %v, want %v", got, 2)
}
m.put("one", linkedMapTestData[4])
if got := m.len(); got != 2 {
t.Errorf("m.Len() = %v, want %v", got, 2)
}
// Internal checks.
if got := len(m.m); got != 2 {
t.Errorf("len(m.m) = %v, want %v", got, 2)
}
if got := m.l.Len(); got != 2 {
t.Errorf("m.l.Len() = %v, want %v", got, 2)
}
}
func TestLinkedMapClear(t *testing.T) {
m := newLinkedMap()
m.put("one", linkedMapTestData[0])
if got, ok := m.get("one"); !ok || got != linkedMapTestData[0] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 1, got, ok, "one")
}
m.put("two", linkedMapTestData[1])
if got, ok := m.get("two"); !ok || got != linkedMapTestData[1] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 2, got, ok, "two")
}
m.clear()
if got, ok := m.get("one"); ok {
t.Errorf("m.Get(%v) = %v, %v, want _, false", 1, got, ok)
}
if got, ok := m.get("two"); ok {
t.Errorf("m.Get(%v) = %v, %v, want _, false", 2, got, ok)
}
if got := m.len(); got != 0 {
t.Errorf("m.Len() = %v, want %v", got, 0)
}
}
func TestLinkedMapRemoveOldest(t *testing.T) {
m := newLinkedMap()
m.put("one", linkedMapTestData[0])
m.put("two", linkedMapTestData[1])
m.put("three", linkedMapTestData[2])
m.put("four", linkedMapTestData[3])
if got, ok := m.get("one"); !ok || got != linkedMapTestData[0] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 1, got, ok, "one")
}
if got, ok := m.get("two"); !ok || got != linkedMapTestData[1] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 2, got, ok, "two")
}
if got, ok := m.get("three"); !ok || got != linkedMapTestData[2] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 3, got, ok, "three")
}
if got, ok := m.get("four"); !ok || got != linkedMapTestData[3] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 4, got, ok, "four")
}
if err := checkListOrdered(m.l, []string{"one", "two", "three", "four"}); err != nil {
t.Fatalf("m.l is not expected: %v", err)
}
m.put("three", linkedMapTestData[2])
if err := checkListOrdered(m.l, []string{"one", "two", "four", "three"}); err != nil {
t.Fatalf("m.l is not expected: %v", err)
}
m.put("four", linkedMapTestData[3])
if err := checkListOrdered(m.l, []string{"one", "two", "three", "four"}); err != nil {
t.Fatalf("m.l is not expected: %v", err)
}
m.removeOldest()
if got, ok := m.get("one"); ok {
t.Errorf("m.Get(%v) = %v, %v, want _, false", 1, got, ok)
}
if err := checkListOrdered(m.l, []string{"two", "three", "four"}); err != nil {
t.Fatalf("m.l is not expected: %v", err)
}
m.get("two") // 2 is refreshed, 3 becomes the oldest
if err := checkListOrdered(m.l, []string{"three", "four", "two"}); err != nil {
t.Fatalf("m.l is not expected: %v", err)
}
m.removeOldest()
if got, ok := m.get("three"); ok {
t.Errorf("m.Get(%v) = %v, %v, want _, false", 3, got, ok)
}
// 2 and 4 are still in map.
if got, ok := m.get("two"); !ok || got != linkedMapTestData[1] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 2, got, ok, "two")
}
if got, ok := m.get("four"); !ok || got != linkedMapTestData[3] {
t.Errorf("m.Get(%v) = %v, %v, want %v, true", 4, got, ok, "four")
}
}
func checkListOrdered(l *list.List, want []string) error {
got := make([]string, 0, len(want))
for p := l.Front(); p != nil; p = p.Next() {
got = append(got, p.Value.(*linkedMapKVPair).key)
}
if !reflect.DeepEqual(got, want) {
return fmt.Errorf("list elements: %v, want %v", got, want)
}
return nil
}