golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/rangeset_test.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build go1.21
     6  
     7  package quic
     8  
     9  import (
    10  	"reflect"
    11  	"testing"
    12  )
    13  
    14  func TestRangeSize(t *testing.T) {
    15  	for _, test := range []struct {
    16  		r    i64range[int64]
    17  		want int64
    18  	}{{
    19  		r:    i64range[int64]{0, 100},
    20  		want: 100,
    21  	}, {
    22  		r:    i64range[int64]{10, 20},
    23  		want: 10,
    24  	}} {
    25  		if got := test.r.size(); got != test.want {
    26  			t.Errorf("%+v.size = %v, want %v", test.r, got, test.want)
    27  		}
    28  	}
    29  }
    30  
    31  func TestRangeContains(t *testing.T) {
    32  	r := i64range[int64]{5, 10}
    33  	for _, i := range []int64{0, 4, 10, 15} {
    34  		if r.contains(i) {
    35  			t.Errorf("%v.contains(%v) = true, want false", r, i)
    36  		}
    37  	}
    38  	for _, i := range []int64{5, 6, 7, 8, 9} {
    39  		if !r.contains(i) {
    40  			t.Errorf("%v.contains(%v) = false, want true", r, i)
    41  		}
    42  	}
    43  }
    44  
    45  func TestRangesetAdd(t *testing.T) {
    46  	for _, test := range []struct {
    47  		desc string
    48  		set  rangeset[int64]
    49  		add  i64range[int64]
    50  		want rangeset[int64]
    51  	}{{
    52  		desc: "add to empty set",
    53  		set:  rangeset[int64]{},
    54  		add:  i64range[int64]{0, 100},
    55  		want: rangeset[int64]{{0, 100}},
    56  	}, {
    57  		desc: "add empty range",
    58  		set:  rangeset[int64]{},
    59  		add:  i64range[int64]{100, 100},
    60  		want: rangeset[int64]{},
    61  	}, {
    62  		desc: "append nonadjacent range",
    63  		set:  rangeset[int64]{{100, 200}},
    64  		add:  i64range[int64]{300, 400},
    65  		want: rangeset[int64]{{100, 200}, {300, 400}},
    66  	}, {
    67  		desc: "prepend nonadjacent range",
    68  		set:  rangeset[int64]{{100, 200}},
    69  		add:  i64range[int64]{0, 50},
    70  		want: rangeset[int64]{{0, 50}, {100, 200}},
    71  	}, {
    72  		desc: "insert nonadjacent range",
    73  		set:  rangeset[int64]{{100, 200}, {500, 600}},
    74  		add:  i64range[int64]{300, 400},
    75  		want: rangeset[int64]{{100, 200}, {300, 400}, {500, 600}},
    76  	}, {
    77  		desc: "prepend adjacent range",
    78  		set:  rangeset[int64]{{100, 200}},
    79  		add:  i64range[int64]{50, 100},
    80  		want: rangeset[int64]{{50, 200}},
    81  	}, {
    82  		desc: "append adjacent range",
    83  		set:  rangeset[int64]{{100, 200}},
    84  		add:  i64range[int64]{200, 250},
    85  		want: rangeset[int64]{{100, 250}},
    86  	}, {
    87  		desc: "prepend overlapping range",
    88  		set:  rangeset[int64]{{100, 200}},
    89  		add:  i64range[int64]{50, 150},
    90  		want: rangeset[int64]{{50, 200}},
    91  	}, {
    92  		desc: "append overlapping range",
    93  		set:  rangeset[int64]{{100, 200}},
    94  		add:  i64range[int64]{150, 250},
    95  		want: rangeset[int64]{{100, 250}},
    96  	}, {
    97  		desc: "replace range",
    98  		set:  rangeset[int64]{{100, 200}},
    99  		add:  i64range[int64]{50, 250},
   100  		want: rangeset[int64]{{50, 250}},
   101  	}, {
   102  		desc: "prepend and combine",
   103  		set:  rangeset[int64]{{100, 200}, {300, 400}, {500, 600}},
   104  		add:  i64range[int64]{50, 300},
   105  		want: rangeset[int64]{{50, 400}, {500, 600}},
   106  	}, {
   107  		desc: "combine several ranges",
   108  		set:  rangeset[int64]{{100, 200}, {300, 400}, {500, 600}, {700, 800}, {900, 1000}},
   109  		add:  i64range[int64]{300, 850},
   110  		want: rangeset[int64]{{100, 200}, {300, 850}, {900, 1000}},
   111  	}} {
   112  		test := test
   113  		t.Run(test.desc, func(t *testing.T) {
   114  			got := test.set
   115  			got.add(test.add.start, test.add.end)
   116  			if !reflect.DeepEqual(got, test.want) {
   117  				t.Errorf("add [%v,%v) to %v", test.add.start, test.add.end, test.set)
   118  				t.Errorf("  got: %v", got)
   119  				t.Errorf(" want: %v", test.want)
   120  			}
   121  		})
   122  	}
   123  }
   124  
   125  func TestRangesetSub(t *testing.T) {
   126  	for _, test := range []struct {
   127  		desc string
   128  		set  rangeset[int64]
   129  		sub  i64range[int64]
   130  		want rangeset[int64]
   131  	}{{
   132  		desc: "subtract from empty set",
   133  		set:  rangeset[int64]{},
   134  		sub:  i64range[int64]{0, 100},
   135  		want: rangeset[int64]{},
   136  	}, {
   137  		desc: "subtract empty range",
   138  		set:  rangeset[int64]{{0, 100}},
   139  		sub:  i64range[int64]{0, 0},
   140  		want: rangeset[int64]{{0, 100}},
   141  	}, {
   142  		desc: "subtract not present in set",
   143  		set:  rangeset[int64]{{0, 100}, {200, 300}},
   144  		sub:  i64range[int64]{100, 200},
   145  		want: rangeset[int64]{{0, 100}, {200, 300}},
   146  	}, {
   147  		desc: "subtract prefix",
   148  		set:  rangeset[int64]{{100, 200}},
   149  		sub:  i64range[int64]{0, 150},
   150  		want: rangeset[int64]{{150, 200}},
   151  	}, {
   152  		desc: "subtract suffix",
   153  		set:  rangeset[int64]{{100, 200}},
   154  		sub:  i64range[int64]{150, 300},
   155  		want: rangeset[int64]{{100, 150}},
   156  	}, {
   157  		desc: "subtract middle",
   158  		set:  rangeset[int64]{{0, 100}},
   159  		sub:  i64range[int64]{40, 60},
   160  		want: rangeset[int64]{{0, 40}, {60, 100}},
   161  	}, {
   162  		desc: "subtract from two ranges",
   163  		set:  rangeset[int64]{{0, 100}, {200, 300}},
   164  		sub:  i64range[int64]{50, 250},
   165  		want: rangeset[int64]{{0, 50}, {250, 300}},
   166  	}, {
   167  		desc: "subtract removes range",
   168  		set:  rangeset[int64]{{0, 100}, {200, 300}, {400, 500}},
   169  		sub:  i64range[int64]{200, 300},
   170  		want: rangeset[int64]{{0, 100}, {400, 500}},
   171  	}, {
   172  		desc: "subtract removes multiple ranges",
   173  		set:  rangeset[int64]{{0, 100}, {200, 300}, {400, 500}, {600, 700}},
   174  		sub:  i64range[int64]{50, 650},
   175  		want: rangeset[int64]{{0, 50}, {650, 700}},
   176  	}, {
   177  		desc: "subtract only range",
   178  		set:  rangeset[int64]{{0, 100}},
   179  		sub:  i64range[int64]{0, 100},
   180  		want: rangeset[int64]{},
   181  	}} {
   182  		test := test
   183  		t.Run(test.desc, func(t *testing.T) {
   184  			got := test.set
   185  			got.sub(test.sub.start, test.sub.end)
   186  			if !reflect.DeepEqual(got, test.want) {
   187  				t.Errorf("sub [%v,%v) from %v", test.sub.start, test.sub.end, test.set)
   188  				t.Errorf("  got: %v", got)
   189  				t.Errorf(" want: %v", test.want)
   190  			}
   191  		})
   192  	}
   193  }
   194  
   195  func TestRangesetContains(t *testing.T) {
   196  	var s rangeset[int64]
   197  	s.add(10, 20)
   198  	s.add(30, 40)
   199  	for i := int64(0); i < 50; i++ {
   200  		want := (i >= 10 && i < 20) || (i >= 30 && i < 40)
   201  		if got := s.contains(i); got != want {
   202  			t.Errorf("%v.contains(%v) = %v, want %v", s, i, got, want)
   203  		}
   204  	}
   205  }
   206  
   207  func TestRangesetRangeContaining(t *testing.T) {
   208  	var s rangeset[int64]
   209  	s.add(10, 20)
   210  	s.add(30, 40)
   211  	for _, test := range []struct {
   212  		v    int64
   213  		want i64range[int64]
   214  	}{
   215  		{0, i64range[int64]{0, 0}},
   216  		{9, i64range[int64]{0, 0}},
   217  		{10, i64range[int64]{10, 20}},
   218  		{15, i64range[int64]{10, 20}},
   219  		{19, i64range[int64]{10, 20}},
   220  		{20, i64range[int64]{0, 0}},
   221  		{29, i64range[int64]{0, 0}},
   222  		{30, i64range[int64]{30, 40}},
   223  		{39, i64range[int64]{30, 40}},
   224  		{40, i64range[int64]{0, 0}},
   225  	} {
   226  		got := s.rangeContaining(test.v)
   227  		if got != test.want {
   228  			t.Errorf("%v.rangeContaining(%v) = %v, want %v", s, test.v, got, test.want)
   229  		}
   230  	}
   231  }
   232  
   233  func TestRangesetLimits(t *testing.T) {
   234  	for _, test := range []struct {
   235  		s       rangeset[int64]
   236  		wantMin int64
   237  		wantMax int64
   238  		wantEnd int64
   239  	}{{
   240  		s:       rangeset[int64]{},
   241  		wantMin: 0,
   242  		wantMax: 0,
   243  		wantEnd: 0,
   244  	}, {
   245  		s:       rangeset[int64]{{10, 20}},
   246  		wantMin: 10,
   247  		wantMax: 19,
   248  		wantEnd: 20,
   249  	}, {
   250  		s:       rangeset[int64]{{10, 20}, {30, 40}, {50, 60}},
   251  		wantMin: 10,
   252  		wantMax: 59,
   253  		wantEnd: 60,
   254  	}} {
   255  		if got, want := test.s.min(), test.wantMin; got != want {
   256  			t.Errorf("%+v.min() = %v, want %v", test.s, got, want)
   257  		}
   258  		if got, want := test.s.max(), test.wantMax; got != want {
   259  			t.Errorf("%+v.max() = %v, want %v", test.s, got, want)
   260  		}
   261  		if got, want := test.s.end(), test.wantEnd; got != want {
   262  			t.Errorf("%+v.end() = %v, want %v", test.s, got, want)
   263  		}
   264  	}
   265  }
   266  
   267  func TestRangesetIsRange(t *testing.T) {
   268  	for _, test := range []struct {
   269  		s    rangeset[int64]
   270  		r    i64range[int64]
   271  		want bool
   272  	}{{
   273  		s:    rangeset[int64]{{0, 100}},
   274  		r:    i64range[int64]{0, 100},
   275  		want: true,
   276  	}, {
   277  		s:    rangeset[int64]{{0, 100}},
   278  		r:    i64range[int64]{0, 101},
   279  		want: false,
   280  	}, {
   281  		s:    rangeset[int64]{{0, 10}, {11, 100}},
   282  		r:    i64range[int64]{0, 100},
   283  		want: false,
   284  	}, {
   285  		s:    rangeset[int64]{},
   286  		r:    i64range[int64]{0, 0},
   287  		want: true,
   288  	}, {
   289  		s:    rangeset[int64]{},
   290  		r:    i64range[int64]{0, 1},
   291  		want: false,
   292  	}} {
   293  		if got := test.s.isrange(test.r.start, test.r.end); got != test.want {
   294  			t.Errorf("%+v.isrange(%v, %v) = %v, want %v", test.s, test.r.start, test.r.end, got, test.want)
   295  		}
   296  	}
   297  }
   298  
   299  func TestRangesetNumRanges(t *testing.T) {
   300  	for _, test := range []struct {
   301  		s    rangeset[int64]
   302  		want int
   303  	}{{
   304  		s:    rangeset[int64]{},
   305  		want: 0,
   306  	}, {
   307  		s:    rangeset[int64]{{0, 100}},
   308  		want: 1,
   309  	}, {
   310  		s:    rangeset[int64]{{0, 100}, {200, 300}},
   311  		want: 2,
   312  	}} {
   313  		if got, want := test.s.numRanges(), test.want; got != want {
   314  			t.Errorf("%+v.numRanges() = %v, want %v", test.s, got, want)
   315  		}
   316  	}
   317  }