Skip to content

Commit 21c4632

Browse files
Fixes broken local macOS build and completes migration to GH actions (#160)
Signed-off-by: Adrian Cole <[email protected]>
1 parent 33137b2 commit 21c4632

File tree

9 files changed

+144
-171
lines changed

9 files changed

+144
-171
lines changed

.circleci/config.yml

Lines changed: 0 additions & 59 deletions
This file was deleted.

.github/workflows/commit.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,55 @@ on:
1717
workflow_dispatch:
1818

1919
jobs:
20+
test:
21+
name: "Run unit tests"
22+
runs-on: ${{ matrix.runner.os }}
23+
timeout-minutes: 90 # instead of 360 by default
24+
strategy:
25+
matrix:
26+
runner:
27+
# - os: macos-latest ## revisit once all tests are off ginkgo
28+
- os: ubuntu-latest
29+
steps:
30+
- name: "Checkout"
31+
uses: actions/checkout@v2
32+
33+
- name: "Install Go"
34+
uses: actions/setup-go@v2
35+
with:
36+
go-version: '1.16.2'
37+
38+
- name: "Install 'Docker for Mac' (Latest)"
39+
uses: docker-practice/actions-setup-docker@v1 # needed while TestGetEnvoyExtensionPush uses a real registry
40+
if: runner.os == 'macOS'
41+
with:
42+
docker_buildx: false # Install is flakey. When it, we can install it via docker/setup-buildx-action@v1
43+
timeout-minutes: 20 # fail fast if MacOS install takes too long
44+
45+
- name: "Init on first use"
46+
run: make init
47+
48+
- name: "Verify clean check-in"
49+
run: make check
50+
51+
- name: "Run unit tests"
52+
# prefetch implicit version needed by pkg/binary/envoy/controlplane/istio_test.go until #136. This avoids:
53+
# Unable to start Envoy process: fork/exec /home/circleci/.getenvoy/builds/standard/1.11.0/linux_glibc/bin/envoy: text file busy
54+
run: |
55+
go run cmd/getenvoy/main.go fetch standard:1.11.0
56+
make test
57+
58+
- name: "Generate test coverage report"
59+
if: runner.os == 'Linux' # no need to do this per operating system
60+
run: make coverage
61+
62+
- name: "Upload test coverage report"
63+
uses: actions/upload-artifact@v2
64+
if: runner.os == 'Linux' # no need to do this per operating system
65+
with:
66+
name: coverage
67+
path: build/coverage
68+
2069
bin:
2170
name: "Build the `getenvoy` binary for use in e2e tests"
2271
runs-on: ubuntu-latest

Makefile

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,9 @@ GO_TEST_EXTRA_OPTS ?=
4747

4848
# TODO(yskopets): include all packages into test run once blocking issues have been resolved, including
4949
# * https://github.com/tetratelabs/getenvoy/issues/87 `go test -race` fails
50-
# * https://github.com/tetratelabs/getenvoy/issues/88 `go test ./...` fails on Mac
51-
# * https://github.com/tetratelabs/getenvoy/issues/89 `go test github.com/tetratelabs/getenvoy/pkg/binary/envoy/controlplane` removes `/tmp` dir
5250
COVERAGE_PKG_LIST ?= $(shell go list ./pkg/... | grep -v -e github.com/tetratelabs/getenvoy/pkg/binary/envoy/controlplane -e github.com/tetratelabs/getenvoy/pkg/binary/envoy/debug)
5351
GO_COVERAGE_OPTS ?= -covermode=atomic -coverpkg=./...
54-
GO_COVERAGE_EXTRA_OPTS ?=
52+
GO_COVERAGE_EXTRA_OPTS ?= -p 1
5553

5654
E2E_PKG_LIST ?= ./test/e2e
5755
# Set the default timeout >10m as particularly rust e2e tests are slow https://golang.org/cmd/go/#hdr-Testing_flags
@@ -100,10 +98,6 @@ test: generate
10098
docker-compose up -d
10199
go test $(GO_TEST_OPTS) $(GO_TEST_EXTRA_OPTS) $(TEST_PKG_LIST)
102100

103-
.PHONY: test.ci
104-
test.ci: generate
105-
go test $(GO_TEST_OPTS) $(GO_TEST_EXTRA_OPTS) $(TEST_PKG_LIST)
106-
107101
.PHONY: e2e
108102
e2e: $(call GETENVOY_OUT_PATH,$(GOOS),$(GOARCH))
109103
docker-compose up -d

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ require (
3636
github.com/tetratelabs/getenvoy-package v0.0.0-20190730071641-da31aed4333e
3737
github.com/tetratelabs/log v0.0.0-20190710134534-eb04d1e84fb8
3838
github.com/tetratelabs/multierror v1.1.0
39-
gotest.tools v2.2.0+incompatible
4039
istio.io/api v0.0.0-20200227213531-891bf31f3c32
4140
istio.io/istio v0.0.0-20200304114959-c3c353285578
4241
rsc.io/letsencrypt v0.0.3 // indirect

pkg/binary/envoy/controlplane/istio.tmpl_test.go

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,55 +24,43 @@ import (
2424
"testing"
2525

2626
"github.com/mholt/archiver"
27-
"gotest.tools/assert"
27+
"github.com/stretchr/testify/require"
2828
)
2929

30-
func Test_VersionedIstioTemplate(t *testing.T) {
31-
t.Run(fmt.Sprintf("checking Istio bootstrap matches version %s", IstioVersion), func(t *testing.T) {
32-
got := retrieveIstioBootstrap(t)
33-
assert.Equal(t, istioBootStrapTemplate, string(got))
34-
})
35-
}
36-
37-
func retrieveIstioBootstrap(t *testing.T) []byte {
30+
// TestIstioBootStrapTemplateEqualsReleaseJson ensures istioBootStrapTemplate is exactly the same as what would have been
31+
// downloaded from the istio release for version IstioVersion.
32+
func TestIstioBootStrapTemplateEqualsReleaseJson(t *testing.T) {
3833
// Retrieve Istio tarball os doesn't matter we only car about the bootstrap JSON
39-
url := fmt.Sprintf("https://github.com/istio/istio/releases/download/%v/istio-%v-linux.tar.gz", IstioVersion, IstioVersion)
34+
url := fmt.Sprintf("https://github.com/istio/istio/releases/download/%s/istio-%s-linux.tar.gz", IstioVersion, IstioVersion)
4035
resp, err := http.Get(url)
41-
if err != nil {
42-
t.Fatal(err)
43-
}
36+
require.NoError(t, err, "error getting tarball for istio version %s", IstioVersion)
37+
4438
defer resp.Body.Close() //nolint
45-
if resp.StatusCode != http.StatusOK {
46-
t.Errorf("received %v status code", resp.StatusCode)
47-
}
48-
dst := os.TempDir()
39+
require.Equal(t, http.StatusOK, resp.StatusCode, "unexpected HTTP status from %s", url)
40+
41+
dst, err := ioutil.TempDir("", "")
42+
require.NoError(t, err, `ioutil.TempDir("", "") erred`)
4943
defer os.RemoveAll(dst)
44+
5045
tarball := filepath.Join(dst, "istio.tar.gz")
5146
f, err := os.OpenFile(tarball, os.O_CREATE|os.O_WRONLY, 0600)
52-
if err != nil {
53-
t.Fatal(err)
54-
}
47+
require.NoError(t, err, "Couldn't open file %s", tarball)
5548
defer f.Close() //nolint
49+
5650
_, err = io.Copy(f, resp.Body)
57-
if err != nil {
58-
t.Fatal(err)
59-
}
51+
require.NoError(t, err, "Couldn't download %s into %s", url, tarball)
6052

6153
// Walk the tarball until we find the bootstrap
54+
bootstrapName := "envoy_bootstrap_v2.json"
6255
var bytes []byte
63-
if walkErr := archiver.Walk(tarball, func(f archiver.File) error {
64-
if f.Name() == "envoy_bootstrap_v2.json" {
56+
err = archiver.Walk(tarball, func(f archiver.File) error {
57+
if f.Name() == bootstrapName {
6558
bytes, err = ioutil.ReadAll(f)
66-
if err != nil {
67-
return err
68-
}
59+
require.NoError(t, err, "error reading %s in %s", bootstrapName, url)
6960
}
7061
return nil
71-
}); walkErr != nil {
72-
t.Fatal(err)
73-
}
74-
if bytes == nil {
75-
t.Fatal("no boostrap found")
76-
}
77-
return bytes
62+
})
63+
64+
require.NotNil(t, bytes, "couldn't find %s in %s", bootstrapName, url)
65+
require.Equal(t, istioBootStrapTemplate, string(bytes), "istioBootStrapTemplate isn't the same as the istio %s distribution", IstioVersion)
7866
}

pkg/binary/envoy/controlplane/istio_test.go

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@ package controlplane
1616

1717
import (
1818
"context"
19-
"fmt"
2019
"io/ioutil"
2120
"os"
2221
"path/filepath"
2322
"testing"
2423
"time"
2524

26-
"github.com/stretchr/testify/assert"
25+
"github.com/stretchr/testify/require"
2726
"istio.io/istio/pilot/pkg/bootstrap"
2827
"istio.io/istio/tests/util"
2928

@@ -32,42 +31,44 @@ import (
3231
"github.com/tetratelabs/getenvoy/pkg/binary/envoytest"
3332
)
3433

35-
func TestMain(m *testing.M) {
36-
if err := envoytest.Fetch(); err != nil {
37-
fmt.Println(err)
38-
os.Exit(1)
39-
}
40-
os.Exit(m.Run())
41-
}
34+
func TestConnectsToMockPilotAsAGateway(t *testing.T) {
35+
err := envoytest.Fetch()
36+
require.NoError(t, err, "error running envoytest.Fetch()")
37+
_, teardown := setupMockPilot()
38+
defer teardown()
4239

43-
// NOTE: This test will fail on macOS due to an issue with Envoy, the same issue as debug logging
44-
func Test_IstioGateway(t *testing.T) {
45-
t.Run("connects to mock Pilot as a gateway", func(t *testing.T) {
46-
_, teardown := setupMockPilot()
47-
defer teardown()
48-
cfg := envoy.NewConfig(
49-
func(c *envoy.Config) {
50-
c.Mode = envoy.ParseMode("loadbalancer")
51-
c.XDSAddress = util.MockPilotGrpcAddr
52-
c.IPAddresses = []string{"1.1.1.1"}
53-
},
54-
)
55-
runtime, _ := envoy.NewRuntime(
56-
func(r *envoy.Runtime) { r.Config = cfg },
57-
debug.EnableEnvoyAdminDataCollection,
58-
Istio,
59-
)
60-
defer os.RemoveAll(runtime.DebugStore() + ".tar.gz")
61-
defer os.RemoveAll(runtime.DebugStore())
62-
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
63-
defer cancel()
64-
assert.NoError(t, envoytest.Run(ctx, runtime, ""))
65-
time.Sleep(time.Millisecond * 500) // Pilot config propagation
66-
assert.NoError(t, envoytest.Kill(ctx, runtime))
67-
gotListeners, _ := ioutil.ReadFile(filepath.Join(runtime.DebugStore(), "listeners.txt"))
68-
assert.Contains(t, string(gotListeners), "0.0.0.0_8443::0.0.0.0:8443")
69-
assert.Contains(t, string(gotListeners), "0.0.0.0_8080::0.0.0.0:8080")
70-
})
40+
cfg := envoy.NewConfig(
41+
func(c *envoy.Config) {
42+
c.Mode = envoy.ParseMode("loadbalancer")
43+
c.XDSAddress = util.MockPilotGrpcAddr
44+
c.IPAddresses = []string{"1.1.1.1"}
45+
},
46+
)
47+
48+
runtime, err := envoy.NewRuntime(
49+
func(r *envoy.Runtime) { r.Config = cfg },
50+
debug.EnableEnvoyAdminDataCollection,
51+
Istio,
52+
)
53+
require.NoError(t, err, "error creating envoy runtime")
54+
defer os.RemoveAll(runtime.DebugStore())
55+
56+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
57+
defer cancel()
58+
59+
err = envoytest.Run(ctx, runtime, "")
60+
require.NoError(t, err, "error running envoy")
61+
62+
time.Sleep(time.Millisecond * 500) // Pilot config propagation
63+
64+
err = envoytest.Kill(ctx, runtime)
65+
require.NoError(t, err, "error killing envoy")
66+
67+
gotListeners, err := ioutil.ReadFile(filepath.Join(runtime.DebugStore(), "listeners.txt"))
68+
require.NoError(t, err, "error killing envoy listeners")
69+
70+
require.Contains(t, string(gotListeners), "0.0.0.0_8443::0.0.0.0:8443")
71+
require.Contains(t, string(gotListeners), "0.0.0.0_8080::0.0.0.0:8080")
7172
}
7273

7374
func setupMockPilot() (*bootstrap.Server, util.TearDownFunc) {
@@ -76,6 +77,10 @@ func setupMockPilot() (*bootstrap.Server, util.TearDownFunc) {
7677
args.Config.FileDir = "testdata"
7778
args.Plugins = bootstrap.DefaultPlugins
7879
args.Mesh.MixerAddress = ""
80+
// In a normal macOS setup, you cannot write to /dev/stdout, which is the default path here.
81+
// While not Docker-specific, there are related notes here https://github.com/moby/moby/issues/31243
82+
// Since this test doesn't read access logs anyway, the easier workaround is to disable access logging.
83+
args.MeshConfig.AccessLogFile = ""
7984
args.Service.Registries = []string{}
8085
})
8186
}

pkg/binary/envoy/debug/lsof.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ type OpenFileStat struct {
4545
Name string `json:"name"` // name of the mount point and file system on which the file resides
4646
}
4747

48-
// EnableOpenFilesDataCollection is a preset option that registers collection of statistics of files opened by envoy instance(s)
48+
// EnableOpenFilesDataCollection is a preset option that registers collection of statistics of files opened by envoy
49+
// instance(s). This is unsupported on macOS/Darwin because it does not support process.OpenFiles
4950
func EnableOpenFilesDataCollection(r *envoy.Runtime) {
5051
if err := os.Mkdir(filepath.Join(r.DebugStore(), "lsof"), os.ModePerm); err != nil {
5152
log.Errorf("error in creating a directory to write open file data of envoy to: %v", err)
@@ -80,7 +81,7 @@ func retrieveOpenFilesData(r binary.Runner) error {
8081

8182
openFiles, err := envoyProcess.OpenFiles()
8283
if err != nil {
83-
return fmt.Errorf("error in getting open file statistics: %v", err)
84+
return fmt.Errorf("error in getting open file statistics: %w", err)
8485
}
8586

8687
for _, stat := range openFiles {

0 commit comments

Comments
 (0)