github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/integration/generic-tests/dhclient_test.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build !race
     6  
     7  package integration
     8  
     9  import (
    10  	"fmt"
    11  	"io/ioutil"
    12  	"net"
    13  	"net/http"
    14  	"os"
    15  	"path/filepath"
    16  	"sync"
    17  	"testing"
    18  	"time"
    19  
    20  	"github.com/u-root/u-root/pkg/qemu"
    21  	"github.com/u-root/u-root/pkg/testutil"
    22  	"github.com/u-root/u-root/pkg/vmtest"
    23  )
    24  
    25  // TestDhclientQEMU4 uses QEMU's DHCP server to test dhclient.
    26  func TestDhclientQEMU4(t *testing.T) {
    27  	// TODO: support arm
    28  	if vmtest.TestArch() != "amd64" && vmtest.TestArch() != "arm64" {
    29  		t.Skipf("test not supported on %s", vmtest.TestArch())
    30  	}
    31  
    32  	// Create the file to download
    33  	dir, err := ioutil.TempDir("", "dhclient-")
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  	defer os.RemoveAll(dir)
    38  
    39  	want := "conteeent"
    40  	foobarFile := filepath.Join(dir, "foobar")
    41  	if err := ioutil.WriteFile(foobarFile, []byte(want), 0644); err != nil {
    42  		t.Fatal(err)
    43  	}
    44  
    45  	// Serve HTTP on the host on a random port.
    46  	http.Handle("/", http.FileServer(http.Dir(dir)))
    47  	ln, err := net.Listen("tcp", ":0")
    48  	if err != nil {
    49  		t.Fatal(err)
    50  	}
    51  
    52  	var wg sync.WaitGroup
    53  	s := &http.Server{}
    54  	wg.Add(1)
    55  	go func() {
    56  		_ = s.Serve(ln)
    57  		wg.Done()
    58  	}()
    59  	defer wg.Wait()
    60  	defer s.Close()
    61  
    62  	port := ln.Addr().(*net.TCPAddr).Port
    63  
    64  	dhcpClient, ccleanup := vmtest.QEMUTest(t, &vmtest.Options{
    65  		QEMUOpts: qemu.Options{
    66  			SerialOutput: vmtest.TestLineWriter(t, "client"),
    67  			Timeout:      30 * time.Second,
    68  			Devices: []qemu.Device{
    69  				qemu.ArbitraryArgs{
    70  					"-device", "e1000,netdev=host0",
    71  					"-netdev", "user,id=host0,net=192.168.0.0/24,dhcpstart=192.168.0.10,ipv6=off",
    72  				},
    73  			},
    74  		},
    75  		TestCmds: []string{
    76  			"dhclient -ipv6=false -v",
    77  			"ip a",
    78  			// Download a file to make sure dhclient configures kernel networking correctly.
    79  			fmt.Sprintf("wget http://192.168.0.2:%d/foobar", port),
    80  			"cat ./foobar",
    81  			"sleep 5",
    82  			"shutdown -h",
    83  		},
    84  	})
    85  	defer ccleanup()
    86  
    87  	if err := dhcpClient.Expect("Configured eth0 with IPv4 DHCP Lease"); err != nil {
    88  		t.Errorf("%s: %v", testutil.NowLog(), err)
    89  	}
    90  	if err := dhcpClient.Expect("inet 192.168.0.10"); err != nil {
    91  		t.Errorf("%s: %v", testutil.NowLog(), err)
    92  	}
    93  	// "cat ./foobar" should be outputting this.
    94  	if err := dhcpClient.Expect(want); err != nil {
    95  		t.Errorf("%s: %v", testutil.NowLog(), err)
    96  	}
    97  }
    98  
    99  func TestDhclientTimesOut(t *testing.T) {
   100  	// TODO: support arm
   101  	if vmtest.TestArch() != "amd64" && vmtest.TestArch() != "arm64" {
   102  		t.Skipf("test not supported on %s", vmtest.TestArch())
   103  	}
   104  
   105  	network := qemu.NewNetwork()
   106  	dhcpClient, ccleanup := vmtest.QEMUTest(t, &vmtest.Options{
   107  		Name: "TestQEMUDHCPTimesOut",
   108  		QEMUOpts: qemu.Options{
   109  			Timeout: 50 * time.Second,
   110  			Devices: []qemu.Device{
   111  				// An empty new network is easier than
   112  				// configuring QEMU not to expose any
   113  				// networking. At the moment.
   114  				network.NewVM(),
   115  			},
   116  		},
   117  		TestCmds: []string{
   118  			"dhclient -v -retry 2 -timeout 10",
   119  			"echo \"DHCP timed out\"",
   120  			"sleep 5",
   121  			"shutdown -h",
   122  		},
   123  	})
   124  	defer ccleanup()
   125  
   126  	if err := dhcpClient.Expect("Could not configure eth0 for IPv"); err != nil {
   127  		t.Error(err)
   128  	}
   129  	if err := dhcpClient.Expect("Could not configure eth0 for IPv"); err != nil {
   130  		t.Error(err)
   131  	}
   132  	if err := dhcpClient.Expect("DHCP timed out"); err != nil {
   133  		t.Error(err)
   134  	}
   135  }
   136  
   137  func TestDhclient6(t *testing.T) {
   138  	// TODO: support arm
   139  	if vmtest.TestArch() != "amd64" && vmtest.TestArch() != "arm64" {
   140  		t.Skipf("test not supported on %s", vmtest.TestArch())
   141  	}
   142  
   143  	// QEMU doesn't support DHCPv6 for getting IP configuration, so we have
   144  	// to supply our own server.
   145  	//
   146  	// We don't currently have a radvd server we can use, so we also cannot
   147  	// try to download a file using the DHCP configuration.
   148  	network := qemu.NewNetwork()
   149  	dhcpServer, scleanup := vmtest.QEMUTest(t, &vmtest.Options{
   150  		Name: "TestDhclient6_Server",
   151  		TestCmds: []string{
   152  			"ip link set eth0 up",
   153  			"pxeserver -6 -your-ip6=fec0::3 -4=false",
   154  		},
   155  		QEMUOpts: qemu.Options{
   156  			SerialOutput: vmtest.TestLineWriter(t, "server"),
   157  			Timeout:      30 * time.Second,
   158  			Devices: []qemu.Device{
   159  				network.NewVM(),
   160  			},
   161  		},
   162  	})
   163  	defer scleanup()
   164  
   165  	dhcpClient, ccleanup := vmtest.QEMUTest(t, &vmtest.Options{
   166  		Name: "TestDhclient6_Client",
   167  		TestCmds: []string{
   168  			"dhclient -ipv4=false -vv",
   169  			"ip a",
   170  			"shutdown -h",
   171  		},
   172  		QEMUOpts: qemu.Options{
   173  			SerialOutput: vmtest.TestLineWriter(t, "client"),
   174  			Timeout:      30 * time.Second,
   175  			Devices: []qemu.Device{
   176  				network.NewVM(),
   177  			},
   178  		},
   179  	})
   180  	defer ccleanup()
   181  
   182  	if err := dhcpServer.Expect("starting dhcpv6 server"); err != nil {
   183  		t.Errorf("%s dhcpv6 server: %v", testutil.NowLog(), err)
   184  	}
   185  	if err := dhcpClient.Expect("Configured eth0 with IPv6 DHCP Lease IP fec0::3"); err != nil {
   186  		t.Errorf("%s configure: %v", testutil.NowLog(), err)
   187  	}
   188  	if err := dhcpClient.Expect("inet6 fec0::3"); err != nil {
   189  		t.Errorf("%s ip: %v", testutil.NowLog(), err)
   190  	}
   191  }