| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| //go:build !build_with_native_toolchain |
| // +build !build_with_native_toolchain |
| |
| package netstack |
| |
| import ( |
| "context" |
| "testing" |
| |
| "fidl/fuchsia/net/neighbor" |
| |
| "github.com/google/go-cmp/cmp" |
| ) |
| |
| // TestNeighborEntryIteratorGetNext verifies correct batching behavior and |
| // ordering of entries when receiving entries via EntryIterator.GetNext. |
| func TestNeighborEntryIteratorGetNext(t *testing.T) { |
| tests := []struct { |
| name string |
| existingItemCount uint64 |
| batchSizes []uint64 |
| }{ |
| // An idle item will always be sent, even if there are no existing entries. |
| { |
| name: "One", |
| existingItemCount: 0, |
| batchSizes: []uint64{1}, |
| }, |
| // A full batch consistents of existing items and one idle item. |
| { |
| name: "Max", |
| existingItemCount: neighbor.MaxItemBatchSize - 1, |
| batchSizes: []uint64{ |
| neighbor.MaxItemBatchSize, |
| }, |
| }, |
| // Another batch is needed to send the extra idle item. |
| { |
| name: "OverMax", |
| existingItemCount: neighbor.MaxItemBatchSize, |
| batchSizes: []uint64{ |
| neighbor.MaxItemBatchSize, |
| 1, |
| }, |
| }, |
| { |
| name: "OverMaxTwice", |
| existingItemCount: neighbor.MaxItemBatchSize * 2, |
| batchSizes: []uint64{ |
| neighbor.MaxItemBatchSize, |
| neighbor.MaxItemBatchSize, |
| 1, |
| }, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| var wantItems []neighbor.EntryIteratorItem |
| |
| // Fill the list with existing items, then append the idle item to |
| // indicate the end of existing items. |
| for i := uint64(0); i < test.existingItemCount; i++ { |
| entry := neighbor.Entry{} |
| // Repurpose the interface field as a sequence number, used later to |
| // ensure the ordering of entries. |
| entry.SetInterface(i) |
| wantItems = append(wantItems, neighbor.EntryIteratorItemWithExisting(entry)) |
| } |
| wantItems = append(wantItems, neighbor.EntryIteratorItemWithIdle(neighbor.IdleEvent{})) |
| |
| it := neighborEntryIterator{ |
| items: wantItems, |
| } |
| |
| var gotItems []neighbor.EntryIteratorItem |
| |
| // Check item batch sizes and collect all items received. |
| for _, want := range test.batchSizes { |
| entries, err := it.GetNext(context.Background()) |
| if err != nil { |
| t.Errorf("it.GetNext(_): %s", err) |
| } |
| if got := uint64(len(entries)); got != want { |
| t.Errorf("got len(it.GetNext(_)) = %d, want = %d", got, want) |
| } |
| gotItems = append(gotItems, entries...) |
| } |
| |
| // Ensure ordering of items by diffing the interface field. |
| if diff := cmp.Diff(wantItems, gotItems); diff != "" { |
| t.Fatalf("item mismatch (-want +got):\n%s", diff) |
| } |
| }) |
| } |
| } |