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 }