github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/portset/portset_test.go (about)

     1  package portset
     2  
     3  import (
     4  	"slices"
     5  	"strconv"
     6  	"testing"
     7  )
     8  
     9  func assertPanic(t *testing.T, f func()) {
    10  	t.Helper()
    11  	defer func() {
    12  		if r := recover(); r == nil {
    13  			t.Error("expected panic, got none")
    14  		}
    15  	}()
    16  	f()
    17  }
    18  
    19  func TestPortSetBadPort(t *testing.T) {
    20  	var s PortSet
    21  	assertPanic(t, func() { s.Contains(0) })
    22  	assertPanic(t, func() { s.Add(0) })
    23  	assertPanic(t, func() { s.AddRange(0, 1) })
    24  	assertPanic(t, func() { s.AddRange(1, 0) })
    25  	assertPanic(t, func() { s.AddRange(1, 1) })
    26  }
    27  
    28  func assertPortSetFirst(t *testing.T, s *PortSet, from uint16) {
    29  	t.Helper()
    30  	if first := s.First(); first != from {
    31  		t.Errorf("expected first to be %d, got %d", from, first)
    32  	}
    33  }
    34  
    35  func TestPortSetEmptyFirst(t *testing.T) {
    36  	var s PortSet
    37  	assertPortSetFirst(t, &s, 0)
    38  }
    39  
    40  func assertPortSetCount(t *testing.T, s *PortSet, from, to uint16) {
    41  	t.Helper()
    42  	if count, expectedCount := s.Count(), uint(to-from)+1; count != expectedCount {
    43  		t.Errorf("expected count to be %d, got %d", expectedCount, count)
    44  	}
    45  }
    46  
    47  func assertPortSetSingleRange(t *testing.T, s *PortSet, from, to uint16) {
    48  	t.Helper()
    49  	if r := s.RangeSet(); len(r.ranges) != 1 || r.ranges[0].From != from || r.ranges[0].To != to {
    50  		t.Errorf("expected single range %d-%d, got %v", from, to, r)
    51  	}
    52  }
    53  
    54  func assertPortSetContainsSingleRange(t *testing.T, s *PortSet, from, to uint16) {
    55  	t.Helper()
    56  	for i := uint(1); i < uint(from); i++ {
    57  		if s.Contains(uint16(i)) {
    58  			t.Errorf("contains unexpected port %d", i)
    59  		}
    60  	}
    61  	for i := uint(from); i <= uint(to); i++ {
    62  		if !s.Contains(uint16(i)) {
    63  			t.Errorf("expected port %d to be in set", i)
    64  		}
    65  	}
    66  	for i := uint(to) + 1; i < 65536; i++ {
    67  		if s.Contains(uint16(i)) {
    68  			t.Errorf("contains unexpected port %d", i)
    69  		}
    70  	}
    71  }
    72  
    73  func portSetAddRange(s *PortSet, from, to uint16) {
    74  	for i := uint(from); i <= uint(to); i++ {
    75  		s.Add(uint16(i))
    76  	}
    77  }
    78  
    79  func testPortSetSingleRange(t *testing.T, from, to uint16) {
    80  	var s0, s1 PortSet
    81  
    82  	s0.AddRange(from, to)
    83  	assertPortSetFirst(t, &s0, from)
    84  	assertPortSetCount(t, &s0, from, to)
    85  	assertPortSetSingleRange(t, &s0, from, to)
    86  	assertPortSetContainsSingleRange(t, &s0, from, to)
    87  
    88  	portSetAddRange(&s1, from, to)
    89  	if s0 != s1 {
    90  		t.Error("expected AddRange to be equivalent to consecutive Add calls")
    91  	}
    92  }
    93  
    94  func TestPortSetSingleRange(t *testing.T) {
    95  	testRanges := [...]uint16{1, 2, 62, 63, 64, 65, 126, 127, 128, 129, 254, 255, 256, 257, 65534, 65535}
    96  	for _, from := range testRanges {
    97  		for _, to := range testRanges {
    98  			if from >= to {
    99  				continue
   100  			}
   101  			t.Run(strconv.FormatUint(uint64(from), 10)+"-"+strconv.FormatUint(uint64(to), 10), func(t *testing.T) {
   102  				testPortSetSingleRange(t, from, to)
   103  			})
   104  		}
   105  	}
   106  }
   107  
   108  func testPortSetMultipleRanges(t *testing.T, portRangeSet PortRangeSet) {
   109  	var portSet PortSet
   110  	for _, r := range portRangeSet.ranges {
   111  		portSet.AddRange(r.From, r.To)
   112  	}
   113  
   114  	for i := uint(1); i < 65536; i++ {
   115  		portSetContains := portSet.Contains(uint16(i))
   116  		portRangeSetContains := portRangeSet.Contains(uint16(i))
   117  		if portSetContains != portRangeSetContains {
   118  			t.Errorf("mismatched results for port %d: portSet says %t, portRangeSet says %t", i, portSetContains, portRangeSetContains)
   119  		}
   120  	}
   121  
   122  	if portSetRangeCount := portSet.RangeCount(); portSetRangeCount != uint(len(portRangeSet.ranges)) {
   123  		t.Errorf("expected range count to be %d, got %d", len(portRangeSet.ranges), portSetRangeCount)
   124  	}
   125  
   126  	if portSetRangeSet := portSet.RangeSet(); !slices.Equal(portSetRangeSet.ranges, portRangeSet.ranges) {
   127  		t.Errorf("expected ranges to be %v, got %v", portRangeSet.ranges, portSetRangeSet.ranges)
   128  	}
   129  }
   130  
   131  func TestPortSetMultipleRanges(t *testing.T) {
   132  	testPortRangeSets := [...]PortRangeSet{
   133  		{},
   134  		{ranges: []PortRange{{From: 62, To: 63}}},
   135  		{ranges: []PortRange{{From: 62, To: 64}}},
   136  		{ranges: []PortRange{{From: 62, To: 65}}},
   137  		{ranges: []PortRange{{From: 62, To: 126}}},
   138  		{ranges: []PortRange{{From: 62, To: 127}}},
   139  		{ranges: []PortRange{{From: 62, To: 128}}},
   140  		{ranges: []PortRange{{From: 62, To: 129}}},
   141  		{ranges: []PortRange{{From: 62, To: 254}}},
   142  		{ranges: []PortRange{{From: 62, To: 255}}},
   143  		{ranges: []PortRange{{From: 62, To: 256}}},
   144  		{ranges: []PortRange{{From: 62, To: 257}}},
   145  		{ranges: []PortRange{{From: 62, To: 63}, {From: 126, To: 127}}},
   146  		{ranges: []PortRange{{From: 62, To: 64}, {From: 126, To: 128}}},
   147  		{ranges: []PortRange{{From: 62, To: 65}, {From: 126, To: 129}}},
   148  		{ranges: []PortRange{{From: 62, To: 63}, {From: 126, To: 127}, {From: 254, To: 255}}},
   149  		{ranges: []PortRange{{From: 62, To: 64}, {From: 126, To: 128}, {From: 254, To: 256}}},
   150  		{ranges: []PortRange{{From: 62, To: 65}, {From: 126, To: 129}, {From: 254, To: 257}}},
   151  	}
   152  	for i, portRangeSet := range testPortRangeSets {
   153  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   154  			testPortSetMultipleRanges(t, portRangeSet)
   155  		})
   156  	}
   157  }
   158  
   159  func testPortSetParse(t *testing.T, portSetString string, expectedNoError bool, expectedRanges []PortRange) {
   160  	var portSet PortSet
   161  	if err := portSet.Parse(portSetString); (err == nil) != expectedNoError {
   162  		t.Errorf("unexpected error: %v", err)
   163  	}
   164  	if rangeSet := portSet.RangeSet(); !slices.Equal(rangeSet.ranges, expectedRanges) {
   165  		t.Errorf("expected ranges to be %v, got %v", expectedRanges, rangeSet.ranges)
   166  	}
   167  }
   168  
   169  func TestPortSetParse(t *testing.T) {
   170  	testData := []struct {
   171  		portSetString   string
   172  		expectedNoError bool
   173  		expectedRanges  []PortRange
   174  	}{
   175  		{"", true, []PortRange{}},
   176  		{"1", true, []PortRange{{From: 1, To: 1}}},
   177  		{"1,", true, []PortRange{{From: 1, To: 1}}},
   178  		{"1,1", true, []PortRange{{From: 1, To: 1}}},
   179  		{"1,2", true, []PortRange{{From: 1, To: 2}}},
   180  		{"1-2", true, []PortRange{{From: 1, To: 2}}},
   181  		{"1-2,3", true, []PortRange{{From: 1, To: 3}}},
   182  		{"1-2,3-4", true, []PortRange{{From: 1, To: 4}}},
   183  		{"1-4,2,3", true, []PortRange{{From: 1, To: 4}}},
   184  		{"1-4,2-3", true, []PortRange{{From: 1, To: 4}}},
   185  		{"1,2,4,5", true, []PortRange{{From: 1, To: 2}, {From: 4, To: 5}}},
   186  		{"1-2,4-5", true, []PortRange{{From: 1, To: 2}, {From: 4, To: 5}}},
   187  		{"1-65535", true, []PortRange{{From: 1, To: 65535}}},
   188  		{"0", false, []PortRange{}},
   189  		{"0,1", false, []PortRange{}},
   190  		{"0-1", false, []PortRange{}},
   191  		{"1-0", false, []PortRange{}},
   192  		{"2-1", false, []PortRange{}},
   193  		{"1-65536", false, []PortRange{}},
   194  		{"1-65535,65536", false, []PortRange{{From: 1, To: 65535}}},
   195  		{"abc", false, []PortRange{}},
   196  		{"1-abc", false, []PortRange{}},
   197  		{"abc-1", false, []PortRange{}},
   198  		{",", false, []PortRange{}},
   199  		{"-", false, []PortRange{}},
   200  		{",1", false, []PortRange{}},
   201  		{"-1", false, []PortRange{}},
   202  		{"1-", false, []PortRange{}},
   203  		{"1-,", false, []PortRange{}},
   204  		{"1,-", false, []PortRange{{From: 1, To: 1}}},
   205  		{",-1", false, []PortRange{}},
   206  		{"-,1", false, []PortRange{}},
   207  	}
   208  	for i, data := range testData {
   209  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   210  			testPortSetParse(t, data.portSetString, data.expectedNoError, data.expectedRanges)
   211  		})
   212  	}
   213  }