diff options
-rw-r--r-- | .github/workflows/lint.yml | 39 | ||||
-rw-r--r-- | .github/workflows/tests.yml | 70 | ||||
-rw-r--r-- | .travis.yml | 38 | ||||
-rwxr-xr-x | .travis/linters.sh | 8 | ||||
-rwxr-xr-x | .travis/tests.sh | 37 | ||||
-rw-r--r-- | go.sum | 1 | ||||
-rw-r--r-- | netboot/netconf_integ_test.go | 67 |
7 files changed, 157 insertions, 103 deletions
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..fea79b9 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,39 @@ +name: Lint + +on: + push: + tags: + - v* + branches: + - master + pull_request: + +jobs: + golangci: + name: golangci-lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: latest + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true then the action will use pre-installed Go + # skip-go-installation: true +# checklicenses: +# name: checklicenses +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v2 +# - name: check license headers +# run: | +# set -exu +# go get -u github.com/u-root/u-root/tools/checklicenses +# $(go env GOPATH)/bin/checklicenses -c .ci/checklicenses_config.json diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..2777592 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,70 @@ +name: Tests + +on: [push, pull_request] + +jobs: + unit-tests: + runs-on: ubuntu-latest + strategy: + matrix: + go: ['1.13', '1.14', '1.15', '1.16'] + env: + GO111MODULE: on + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + stable: false + go-version: ${{ matrix.go }} + - name: run unit tests + run: | + go get -v -t ./... + echo "" > "${GITHUB_WORKSPACE}"/coverage.txt + for d in $(go list ./...); do + go test -v -race -coverprofile=profile.out -covermode=atomic "${d}" + if [ -f profile.out ]; then + cat profile.out >> "${GITHUB_WORKSPACE}"/coverage.txt + rm profile.out + fi + done + - name: report coverage to codecov + uses: codecov/codecov-action@v1 + with: + files: coverage.txt + flags: unittests + fail_ci_if_error: true + verbose: true + integration-tests: + runs-on: ubuntu-latest + strategy: + matrix: + go: ['1.13', '1.14', '1.15', '1.16'] + env: + GO111MODULE: on + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + stable: false + go-version: ${{ matrix.go }} + - name: run integ tests + run: | + go get -v -t -tags=integration ./... + echo "" > "${GITHUB_WORKSPACE}"/coverage.txt + for d in $(go list -tags=integration ./...); do + go test -c -tags=integration -v -race -coverprofile=profile.out -covermode=atomic "${d}" + testbin="./$(basename $d).test" + # only run it if it was built - i.e. if there are integ tests + test -x "${testbin}" && sudo "./${testbin}" + if [ -f profile.out ]; then + cat profile.out >> "${GITHUB_WORKSPACE}"/coverage.txt + rm profile.out + fi + done + - name: report coverage to codecov + uses: codecov/codecov-action@v1 + with: + files: coverage.txt + flags: integtests + fail_ci_if_error: true + verbose: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5eb24e4..0000000 --- a/.travis.yml +++ /dev/null @@ -1,38 +0,0 @@ -language: go - -sudo: required - -go: - - "1.13" - - "1.14" - - "1.15" - -env: - - TEST_SUITE=unit - - TEST_SUITE=linters - -before_install: - - go get -t -v ./... - -before_script: - - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'; - fi - -script: | - set -x - case $TEST_SUITE in - unit) - ./.travis/tests.sh - ;; - linters) - ./.travis/linters.sh - ;; - *) - echo "[!] Unknown test suite: ${TEST_SUITE}. Exiting." - exit 1 - esac - -after_success: - - bash <(curl -s https://codecov.io/bash) - diff --git a/.travis/linters.sh b/.travis/linters.sh deleted file mode 100755 index 8c7dd8d..0000000 --- a/.travis/linters.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e - -GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint -$GOPATH/bin/golangci-lint run - -GO111MODULE=on go mod tidy diff --git a/.travis/tests.sh b/.travis/tests.sh deleted file mode 100755 index 28346e3..0000000 --- a/.travis/tests.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -# because things are never simple. -# See https://github.com/codecov/example-go#caveat-multiple-files - -set -e -echo "" > coverage.txt - -# show the network configuration. This can help troubleshooting integration -# tests. -ip a - -GO_TEST_OPTS=() -if [[ "$TRAVIS_GO_VERSION" =~ ^1.(9|10|11|12)$ ]] -then - # We use fmt.Errorf with verb "%w" which appeared only in Go1.13. - # So the code compiles and works with Go1.12, but error descriptions - # looks uglier and it does not pass "vet" tests on Go<1.13. - GO_TEST_OPTS+='-vet=off' -fi - -for d in $(go list ./... | grep -v vendor); do - go test -race -coverprofile=profile.out -covermode=atomic ${GO_TEST_OPTS[@]} $d - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi - # integration tests - go test -c -cover -tags=integration -race -covermode=atomic ${GO_TEST_OPTS[@]} $d - testbin="./$(basename $d).test" - # only run it if it was built - i.e. if there are integ tests - test -x "${testbin}" && sudo "./${testbin}" -test.coverprofile=profile.out - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm -f profile.out - fi -done @@ -8,6 +8,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= diff --git a/netboot/netconf_integ_test.go b/netboot/netconf_integ_test.go index 30a7232..099296c 100644 --- a/netboot/netconf_integ_test.go +++ b/netboot/netconf_integ_test.go @@ -3,6 +3,9 @@ package netboot import ( + "fmt" + "io/ioutil" + "log" "net" "testing" "time" @@ -11,10 +14,9 @@ import ( "github.com/stretchr/testify/require" ) -// Travis-CI uses ens4, and this test assumes that such interface -// exists and is configurable. If you are running this test locally, -// you may need to adjust this value. -var ifname = "ens4" +// The test assumes that the interface exists and is configurable. +// If you are running this test locally, you may need to adjust this value. +var ifname = "eth0" func TestIfUp(t *testing.T) { iface, err := IfUp(ifname, 2*time.Second) @@ -28,24 +30,49 @@ func TestIfUpTimeout(t *testing.T) { } func TestConfigureInterface(t *testing.T) { - nc := NetConf{ - Addresses: []AddrConf{ - AddrConf{IPNet: net.IPNet{IP: net.ParseIP("10.20.30.40")}}, + // Linux-only. `netboot.ConfigureInterface` writes to /etc/resolv.conf when + // `NetConf.DNSServers` is set. In this test we make a backup of resolv.conf + // and subsequently restore it. This is really ugly, and not safe if + // multiple tests do the same. + resolvconf, err := ioutil.ReadFile("/etc/resolv.conf") + if err != nil { + panic(fmt.Sprintf("Failed to read /etc/resolv.conf: %v", err)) + } + type testCase struct { + Name string + NetConf *NetConf + } + testCases := []testCase{ + { + Name: "just IP addr", + NetConf: &NetConf{ + Addresses: []AddrConf{ + AddrConf{IPNet: net.IPNet{IP: net.ParseIP("10.20.30.40")}}, + }, + }, + }, + { + Name: "IP addr, DNS, and routers", + NetConf: &NetConf{ + Addresses: []AddrConf{ + AddrConf{IPNet: net.IPNet{IP: net.ParseIP("10.20.30.40")}}, + }, + DNSServers: []net.IP{net.ParseIP("8.8.8.8")}, + DNSSearchList: []string{"slackware.it"}, + Routers: []net.IP{net.ParseIP("10.20.30.254")}, + }, }, } - err := ConfigureInterface(ifname, &nc) - require.NoError(t, err) -} + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + require.NoError(t, ConfigureInterface(ifname, tc.NetConf)) -func TestConfigureInterfaceWithRouteAndDNS(t *testing.T) { - nc := NetConf{ - Addresses: []AddrConf{ - AddrConf{IPNet: net.IPNet{IP: net.ParseIP("10.20.30.40")}}, - }, - DNSServers: []net.IP{net.ParseIP("8.8.8.8")}, - DNSSearchList: []string{"slackware.it"}, - Routers: []net.IP{net.ParseIP("10.20.30.254")}, + // after the test, restore the content of /etc/resolv.conf . The permissions + // are used only if it didn't exist. + if err = ioutil.WriteFile("/etc/resolv.conf", resolvconf, 0644); err != nil { + panic(fmt.Sprintf("Failed to restore /etc/resolv.conf: %v", err)) + } + log.Printf("Restored /etc/resolv.conf") + }) } - err := ConfigureInterface(ifname, &nc) - require.NoError(t, err) } |