github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/ilist/list_test.go (about)

     1  // Copyright 2018 The gVisor Authors.
     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 ilist
    16  
    17  import (
    18  	"testing"
    19  )
    20  
    21  type testEntry struct {
    22  	Entry
    23  	value int
    24  }
    25  
    26  type direct struct {
    27  	directEntry
    28  	value int
    29  }
    30  
    31  func verifyEquality(t *testing.T, entries []testEntry, l *List) {
    32  	t.Helper()
    33  
    34  	i := 0
    35  	for it := l.Front(); it != nil; it = it.Next() {
    36  		e := it.(*testEntry)
    37  		if e != &entries[i] {
    38  			t.Errorf("Wrong entry at index %d", i)
    39  			return
    40  		}
    41  		i++
    42  	}
    43  
    44  	if i != len(entries) {
    45  		t.Errorf("Wrong number of entries; want = %d, got = %d", len(entries), i)
    46  		return
    47  	}
    48  
    49  	i = 0
    50  	for it := l.Back(); it != nil; it = it.Prev() {
    51  		e := it.(*testEntry)
    52  		if e != &entries[len(entries)-1-i] {
    53  			t.Errorf("Wrong entry at index %d", i)
    54  			return
    55  		}
    56  		i++
    57  	}
    58  
    59  	if i != len(entries) {
    60  		t.Errorf("Wrong number of entries; want = %d, got = %d", len(entries), i)
    61  		return
    62  	}
    63  }
    64  
    65  func TestZeroEmpty(t *testing.T) {
    66  	var l List
    67  	if l.Front() != nil {
    68  		t.Error("Front is non-nil")
    69  	}
    70  	if l.Back() != nil {
    71  		t.Error("Back is non-nil")
    72  	}
    73  }
    74  
    75  func TestPushBack(t *testing.T) {
    76  	var l List
    77  
    78  	// Test single entry insertion.
    79  	var entry testEntry
    80  	l.PushBack(&entry)
    81  
    82  	e := l.Front().(*testEntry)
    83  	if e != &entry {
    84  		t.Error("Wrong entry returned")
    85  	}
    86  
    87  	// Test inserting 100 entries.
    88  	l.Reset()
    89  	var entries [100]testEntry
    90  	for i := range entries {
    91  		l.PushBack(&entries[i])
    92  	}
    93  
    94  	verifyEquality(t, entries[:], &l)
    95  }
    96  
    97  func TestPushFront(t *testing.T) {
    98  	var l List
    99  
   100  	// Test single entry insertion.
   101  	var entry testEntry
   102  	l.PushFront(&entry)
   103  
   104  	e := l.Front().(*testEntry)
   105  	if e != &entry {
   106  		t.Error("Wrong entry returned")
   107  	}
   108  
   109  	// Test inserting 100 entries.
   110  	l.Reset()
   111  	var entries [100]testEntry
   112  	for i := range entries {
   113  		l.PushFront(&entries[len(entries)-1-i])
   114  	}
   115  
   116  	verifyEquality(t, entries[:], &l)
   117  }
   118  
   119  func TestRemove(t *testing.T) {
   120  	// Remove entry from single-element list.
   121  	var l List
   122  	var entry testEntry
   123  	l.PushBack(&entry)
   124  	l.Remove(&entry)
   125  	if l.Front() != nil {
   126  		t.Error("List is empty")
   127  	}
   128  
   129  	var entries [100]testEntry
   130  
   131  	// Remove single element from lists of lengths 2 to 101.
   132  	for n := 1; n <= len(entries); n++ {
   133  		for extra := 0; extra <= n; extra++ {
   134  			l.Reset()
   135  			for i := 0; i < n; i++ {
   136  				if extra == i {
   137  					l.PushBack(&entry)
   138  				}
   139  				l.PushBack(&entries[i])
   140  			}
   141  			if extra == n {
   142  				l.PushBack(&entry)
   143  			}
   144  
   145  			l.Remove(&entry)
   146  			verifyEquality(t, entries[:n], &l)
   147  		}
   148  	}
   149  }
   150  
   151  func TestReset(t *testing.T) {
   152  	var l List
   153  
   154  	// Resetting list of one element.
   155  	l.PushBack(&testEntry{})
   156  	if l.Front() == nil {
   157  		t.Error("List is empty")
   158  	}
   159  
   160  	l.Reset()
   161  	if l.Front() != nil {
   162  		t.Error("List is not empty")
   163  	}
   164  
   165  	// Resetting list of 10 elements.
   166  	for i := 0; i < 10; i++ {
   167  		l.PushBack(&testEntry{})
   168  	}
   169  
   170  	if l.Front() == nil {
   171  		t.Error("List is empty")
   172  	}
   173  
   174  	l.Reset()
   175  	if l.Front() != nil {
   176  		t.Error("List is not empty")
   177  	}
   178  
   179  	// Resetting empty list.
   180  	l.Reset()
   181  	if l.Front() != nil {
   182  		t.Error("List is not empty")
   183  	}
   184  }
   185  
   186  func BenchmarkIterateForward(b *testing.B) {
   187  	var l List
   188  	for i := 0; i < 1000000; i++ {
   189  		l.PushBack(&testEntry{value: i})
   190  	}
   191  
   192  	for i := b.N; i > 0; i-- {
   193  		tmp := 0
   194  		for e := l.Front(); e != nil; e = e.Next() {
   195  			tmp += e.(*testEntry).value
   196  		}
   197  	}
   198  }
   199  
   200  func BenchmarkIterateBackward(b *testing.B) {
   201  	var l List
   202  	for i := 0; i < 1000000; i++ {
   203  		l.PushBack(&testEntry{value: i})
   204  	}
   205  
   206  	for i := b.N; i > 0; i-- {
   207  		tmp := 0
   208  		for e := l.Back(); e != nil; e = e.Prev() {
   209  			tmp += e.(*testEntry).value
   210  		}
   211  	}
   212  }
   213  
   214  func BenchmarkDirectIterateForward(b *testing.B) {
   215  	var l directList
   216  	for i := 0; i < 1000000; i++ {
   217  		l.PushBack(&direct{value: i})
   218  	}
   219  
   220  	for i := b.N; i > 0; i-- {
   221  		tmp := 0
   222  		for e := l.Front(); e != nil; e = e.Next() {
   223  			tmp += e.value
   224  		}
   225  	}
   226  }
   227  
   228  func BenchmarkDirectIterateBackward(b *testing.B) {
   229  	var l directList
   230  	for i := 0; i < 1000000; i++ {
   231  		l.PushBack(&direct{value: i})
   232  	}
   233  
   234  	for i := b.N; i > 0; i-- {
   235  		tmp := 0
   236  		for e := l.Back(); e != nil; e = e.Prev() {
   237  			tmp += e.value
   238  		}
   239  	}
   240  }