Skip to content

Commit e136cac

Browse files
alexbrainmanrsc
authored andcommitted
net: make TestInterfaceAddrsWithNetsh more robust
TestInterfaceAddrsWithNetsh invokes Windows netsh command passing it a particular interface name. This approach somehow does not work on some computers (see issue for details). Change that to call netsh without specifying any interface name. This provides output for all interfaces available. So we can achieve same goal parsing this output. Also makes test faster because we only need to invoke netsh once. Fixes #14130. Change-Id: I7911692ca64e372af1e1f9d6acb718c67071de67 Reviewed-on: https://go-review.googlesource.com/19441 Reviewed-by: Volker Dobler <[email protected]> Run-TryBot: Russ Cox <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Russ Cox <[email protected]>
1 parent 0c02bc0 commit e136cac

File tree

1 file changed

+82
-23
lines changed

1 file changed

+82
-23
lines changed

src/net/net_windows_test.go

+82-23
Original file line numberDiff line numberDiff line change
@@ -314,20 +314,43 @@ func TestInterfacesWithNetsh(t *testing.T) {
314314
}
315315
}
316316

317-
func netshInterfaceIPv4ShowAddress(name string) ([]string, error) {
318-
out, err := runCmd("netsh", "interface", "ipv4", "show", "address", "name=\""+name+"\"")
319-
if err != nil {
320-
return nil, err
321-
}
317+
func netshInterfaceIPv4ShowAddress(name string, netshOutput []byte) []string {
322318
// adress information is listed like:
319+
//
320+
//Configuration for interface "Local Area Connection"
321+
// DHCP enabled: Yes
323322
// IP Address: 10.0.0.2
324323
// Subnet Prefix: 10.0.0.0/24 (mask 255.255.255.0)
325324
// IP Address: 10.0.0.3
326325
// Subnet Prefix: 10.0.0.0/24 (mask 255.255.255.0)
326+
// Default Gateway: 10.0.0.254
327+
// Gateway Metric: 0
328+
// InterfaceMetric: 10
329+
//
330+
//Configuration for interface "Loopback Pseudo-Interface 1"
331+
// DHCP enabled: No
332+
// IP Address: 127.0.0.1
333+
// Subnet Prefix: 127.0.0.0/8 (mask 255.0.0.0)
334+
// InterfaceMetric: 50
335+
//
327336
addrs := make([]string, 0)
328337
var addr, subnetprefix string
329-
lines := bytes.Split(out, []byte{'\r', '\n'})
338+
var processingOurInterface bool
339+
lines := bytes.Split(netshOutput, []byte{'\r', '\n'})
330340
for _, line := range lines {
341+
if !processingOurInterface {
342+
if !bytes.HasPrefix(line, []byte("Configuration for interface")) {
343+
continue
344+
}
345+
if !bytes.Contains(line, []byte(`"`+name+`"`)) {
346+
continue
347+
}
348+
processingOurInterface = true
349+
continue
350+
}
351+
if len(line) == 0 {
352+
break
353+
}
331354
if bytes.Contains(line, []byte("Subnet Prefix:")) {
332355
f := bytes.Split(line, []byte{':'})
333356
if len(f) == 2 {
@@ -351,18 +374,50 @@ func netshInterfaceIPv4ShowAddress(name string) ([]string, error) {
351374
}
352375
}
353376
}
354-
return addrs, nil
377+
return addrs
355378
}
356379

357-
func netshInterfaceIPv6ShowAddress(name string) ([]string, error) {
380+
func netshInterfaceIPv6ShowAddress(name string, netshOutput []byte) []string {
381+
// adress information is listed like:
382+
//
383+
//Address ::1 Parameters
384+
//---------------------------------------------------------
385+
//Interface Luid : Loopback Pseudo-Interface 1
386+
//Scope Id : 0.0
387+
//Valid Lifetime : infinite
388+
//Preferred Lifetime : infinite
389+
//DAD State : Preferred
390+
//Address Type : Other
391+
//Skip as Source : false
392+
//
393+
//Address XXXX::XXXX:XXXX:XXXX:XXXX%11 Parameters
394+
//---------------------------------------------------------
395+
//Interface Luid : Local Area Connection
396+
//Scope Id : 0.11
397+
//Valid Lifetime : infinite
398+
//Preferred Lifetime : infinite
399+
//DAD State : Preferred
400+
//Address Type : Other
401+
//Skip as Source : false
402+
//
403+
358404
// TODO: need to test ipv6 netmask too, but netsh does not outputs it
359-
out, err := runCmd("netsh", "interface", "ipv6", "show", "address", "interface=\""+name+"\"")
360-
if err != nil {
361-
return nil, err
362-
}
405+
var addr string
363406
addrs := make([]string, 0)
364-
lines := bytes.Split(out, []byte{'\r', '\n'})
407+
lines := bytes.Split(netshOutput, []byte{'\r', '\n'})
365408
for _, line := range lines {
409+
if addr != "" {
410+
if len(line) == 0 {
411+
addr = ""
412+
continue
413+
}
414+
if string(line) != "Interface Luid : "+name {
415+
continue
416+
}
417+
addrs = append(addrs, addr)
418+
addr = ""
419+
continue
420+
}
366421
if !bytes.HasPrefix(line, []byte("Address")) {
367422
continue
368423
}
@@ -383,9 +438,9 @@ func netshInterfaceIPv6ShowAddress(name string) ([]string, error) {
383438
f[0] = []byte(ParseIP(string(f[0])).String())
384439
}
385440

386-
addrs = append(addrs, string(bytes.ToLower(bytes.TrimSpace(f[0]))))
441+
addr = string(bytes.ToLower(bytes.TrimSpace(f[0])))
387442
}
388-
return addrs, nil
443+
return addrs
389444
}
390445

391446
func TestInterfaceAddrsWithNetsh(t *testing.T) {
@@ -395,6 +450,16 @@ func TestInterfaceAddrsWithNetsh(t *testing.T) {
395450
if !isEnglishOS(t) {
396451
t.Skip("English version of OS required for this test")
397452
}
453+
454+
outIPV4, err := runCmd("netsh", "interface", "ipv4", "show", "address")
455+
if err != nil {
456+
t.Fatal(err)
457+
}
458+
outIPV6, err := runCmd("netsh", "interface", "ipv6", "show", "address", "level=verbose")
459+
if err != nil {
460+
t.Fatal(err)
461+
}
462+
398463
ift, err := Interfaces()
399464
if err != nil {
400465
t.Fatal(err)
@@ -431,14 +496,8 @@ func TestInterfaceAddrsWithNetsh(t *testing.T) {
431496
}
432497
sort.Strings(have)
433498

434-
want, err := netshInterfaceIPv4ShowAddress(ifi.Name)
435-
if err != nil {
436-
t.Fatal(err)
437-
}
438-
wantIPv6, err := netshInterfaceIPv6ShowAddress(ifi.Name)
439-
if err != nil {
440-
t.Fatal(err)
441-
}
499+
want := netshInterfaceIPv4ShowAddress(ifi.Name, outIPV4)
500+
wantIPv6 := netshInterfaceIPv6ShowAddress(ifi.Name, outIPV6)
442501
want = append(want, wantIPv6...)
443502
sort.Strings(want)
444503

0 commit comments

Comments
 (0)