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 }