github.com/database64128/shadowsocks-go@v1.7.0/portset/portset_test.go (about)

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