diff options
Diffstat (limited to 'pkg/ilist/list_test.go')
-rw-r--r-- | pkg/ilist/list_test.go | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/pkg/ilist/list_test.go b/pkg/ilist/list_test.go new file mode 100644 index 000000000..7f2b90e0c --- /dev/null +++ b/pkg/ilist/list_test.go @@ -0,0 +1,233 @@ +// Copyright 2016 The Netstack Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ilist + +import ( + "runtime" + "testing" +) + +type testEntry struct { + Entry + value int +} + +type direct struct { + directEntry + value int +} + +func verifyEquality(t *testing.T, entries []testEntry, l *List) { + i := 0 + for it := l.Front(); it != nil; it = it.Next() { + e := it.(*testEntry) + if e != &entries[i] { + _, file, line, _ := runtime.Caller(1) + t.Errorf("Wrong entry at index (%s:%d): %v", file, line, i) + return + } + i++ + } + + if i != len(entries) { + _, file, line, _ := runtime.Caller(1) + t.Errorf("Wrong number of entries (%s:%d)", file, line) + return + } + + i = 0 + for it := l.Back(); it != nil; it = it.Prev() { + e := it.(*testEntry) + if e != &entries[len(entries)-1-i] { + _, file, line, _ := runtime.Caller(1) + t.Errorf("Wrong entry at index (%s:%d): %v", file, line, i) + return + } + i++ + } + + if i != len(entries) { + _, file, line, _ := runtime.Caller(1) + t.Errorf("Wrong number of entries (%s:%d)", file, line) + return + } +} + +func TestZeroEmpty(t *testing.T) { + var l List + if l.Front() != nil { + t.Error("Front is non-nil") + } + if l.Back() != nil { + t.Error("Back is non-nil") + } +} + +func TestPushBack(t *testing.T) { + var l List + + // Test single entry insertion. + var entry testEntry + l.PushBack(&entry) + + e := l.Front().(*testEntry) + if e != &entry { + t.Error("Wrong entry returned") + } + + // Test inserting 100 entries. + l.Reset() + var entries [100]testEntry + for i := range entries { + l.PushBack(&entries[i]) + } + + verifyEquality(t, entries[:], &l) +} + +func TestPushFront(t *testing.T) { + var l List + + // Test single entry insertion. + var entry testEntry + l.PushFront(&entry) + + e := l.Front().(*testEntry) + if e != &entry { + t.Error("Wrong entry returned") + } + + // Test inserting 100 entries. + l.Reset() + var entries [100]testEntry + for i := range entries { + l.PushFront(&entries[len(entries)-1-i]) + } + + verifyEquality(t, entries[:], &l) +} + +func TestRemove(t *testing.T) { + // Remove entry from single-element list. + var l List + var entry testEntry + l.PushBack(&entry) + l.Remove(&entry) + if l.Front() != nil { + t.Error("List is empty") + } + + var entries [100]testEntry + + // Remove single element from lists of lengths 2 to 101. + for n := 1; n <= len(entries); n++ { + for extra := 0; extra <= n; extra++ { + l.Reset() + for i := 0; i < n; i++ { + if extra == i { + l.PushBack(&entry) + } + l.PushBack(&entries[i]) + } + if extra == n { + l.PushBack(&entry) + } + + l.Remove(&entry) + verifyEquality(t, entries[:n], &l) + } + } +} + +func TestReset(t *testing.T) { + var l List + + // Resetting list of one element. + l.PushBack(&testEntry{}) + if l.Front() == nil { + t.Error("List is empty") + } + + l.Reset() + if l.Front() != nil { + t.Error("List is not empty") + } + + // Resetting list of 10 elements. + for i := 0; i < 10; i++ { + l.PushBack(&testEntry{}) + } + + if l.Front() == nil { + t.Error("List is empty") + } + + l.Reset() + if l.Front() != nil { + t.Error("List is not empty") + } + + // Resetting empty list. + l.Reset() + if l.Front() != nil { + t.Error("List is not empty") + } +} + +func BenchmarkIterateForward(b *testing.B) { + var l List + for i := 0; i < 1000000; i++ { + l.PushBack(&testEntry{value: i}) + } + + for i := b.N; i > 0; i-- { + tmp := 0 + for e := l.Front(); e != nil; e = e.Next() { + tmp += e.(*testEntry).value + } + } +} + +func BenchmarkIterateBackward(b *testing.B) { + var l List + for i := 0; i < 1000000; i++ { + l.PushBack(&testEntry{value: i}) + } + + for i := b.N; i > 0; i-- { + tmp := 0 + for e := l.Back(); e != nil; e = e.Prev() { + tmp += e.(*testEntry).value + } + } +} + +func BenchmarkDirectIterateForward(b *testing.B) { + var l directList + for i := 0; i < 1000000; i++ { + l.PushBack(&direct{value: i}) + } + + for i := b.N; i > 0; i-- { + tmp := 0 + for e := l.Front(); e != nil; e = e.Next() { + tmp += e.value + } + } +} + +func BenchmarkDirectIterateBackward(b *testing.B) { + var l directList + for i := 0; i < 1000000; i++ { + l.PushBack(&direct{value: i}) + } + + for i := b.N; i > 0; i-- { + tmp := 0 + for e := l.Back(); e != nil; e = e.Prev() { + tmp += e.value + } + } +} |