4
4
package testutil // import "go.opentelemetry.io/collector/internal/testutil"
5
5
6
6
import (
7
+ "fmt"
7
8
"net"
8
9
"os/exec"
9
10
"runtime"
@@ -31,15 +32,44 @@ func GetAvailableLocalAddress(t testing.TB) string {
31
32
// which do not show up under the "netstat -ano" but can only be found by
32
33
// "netsh interface ipv4 show excludedportrange protocol=tcp". We'll use []exclusions to hold those ranges and
33
34
// retry if the port returned by GetAvailableLocalAddress falls in one of those them.
35
+ network := "tcp4"
34
36
var exclusions []portpair
35
37
portFound := false
36
38
if runtime .GOOS == "windows" {
37
- exclusions = getExclusionsList (t )
39
+ exclusions = getExclusionsList (network , t )
38
40
}
39
41
40
42
var endpoint string
41
43
for ! portFound {
42
- endpoint = findAvailableAddress (t )
44
+ endpoint = findAvailableAddress (network , t )
45
+ _ , port , err := net .SplitHostPort (endpoint )
46
+ require .NoError (t , err )
47
+ portFound = true
48
+ if runtime .GOOS == "windows" {
49
+ for _ , pair := range exclusions {
50
+ if port >= pair .first && port <= pair .last {
51
+ portFound = false
52
+ break
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ return endpoint
59
+ }
60
+
61
+ // GetAvailableLocalIPv6Address is IPv6 version of GetAvailableLocalAddress.
62
+ func GetAvailableLocalIPv6Address (t testing.TB ) string {
63
+ network := "tcp6"
64
+ var exclusions []portpair
65
+ portFound := false
66
+ if runtime .GOOS == "windows" {
67
+ exclusions = getExclusionsList (network , t )
68
+ }
69
+
70
+ var endpoint string
71
+ for ! portFound {
72
+ endpoint = findAvailableAddress (network , t )
43
73
_ , port , err := net .SplitHostPort (endpoint )
44
74
require .NoError (t , err )
45
75
portFound = true
@@ -72,8 +102,17 @@ func GetAvailableLocalAddressPrometheus(t testing.TB) *config.Prometheus {
72
102
}
73
103
}
74
104
75
- func findAvailableAddress (t testing.TB ) string {
76
- ln , err := net .Listen ("tcp" , "localhost:0" )
105
+ func findAvailableAddress (network string , t testing.TB ) string {
106
+ var host string
107
+ switch network {
108
+ case "tcp" , "tcp4" :
109
+ host = "localhost"
110
+ case "tcp6" :
111
+ host = "[::1]"
112
+ }
113
+ require .NotZero (t , host , "network must be either of tcp, tcp4 or tcp6" )
114
+
115
+ ln , err := net .Listen ("tcp" , fmt .Sprintf ("%s:0" , host ))
77
116
require .NoError (t , err , "Failed to get a free local port" )
78
117
// There is a possible race if something else takes this same port before
79
118
// the test uses it, however, that is unlikely in practice.
@@ -84,8 +123,16 @@ func findAvailableAddress(t testing.TB) string {
84
123
}
85
124
86
125
// Get excluded ports on Windows from the command: netsh interface ipv4 show excludedportrange protocol=tcp
87
- func getExclusionsList (t testing.TB ) []portpair {
88
- cmdTCP := exec .Command ("netsh" , "interface" , "ipv4" , "show" , "excludedportrange" , "protocol=tcp" )
126
+ func getExclusionsList (network string , t testing.TB ) []portpair {
127
+ var cmdTCP * exec.Cmd
128
+ switch network {
129
+ case "tcp" , "tcp4" :
130
+ cmdTCP = exec .Command ("netsh" , "interface" , "ipv4" , "show" , "excludedportrange" , "protocol=tcp" )
131
+ case "tcp6" :
132
+ cmdTCP = exec .Command ("netsh" , "interface" , "ipv6" , "show" , "excludedportrange" , "protocol=tcp" )
133
+ }
134
+ require .NotZero (t , cmdTCP , "network must be either of tcp, tcp4 or tcp6" )
135
+
89
136
outputTCP , errTCP := cmdTCP .CombinedOutput ()
90
137
require .NoError (t , errTCP )
91
138
exclusions := createExclusionsList (string (outputTCP ), t )
0 commit comments