/* * * 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 }