Skip to content

Commit afdf7dc

Browse files
authored
Move transport and testing pacakges (#21)
1 parent 6825ccb commit afdf7dc

File tree

19 files changed

+1578
-0
lines changed

19 files changed

+1578
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ Provided packages:
1616
* `github.com/elastic/elastic-agent-libs/mapstr` is the old `github.com/elastic/beats/v7/libbeat/common.MapStr`. It is an extra layer on top of `map[string]interface{}`.
1717
* `github.com/elastic/elastic-agent-libs/safemapstr` contains safe operations for `mapstr.M`.
1818
* `github.com/elastic/elastic-agent-libs/str` the previous `stringset.go` file from `github.com/elastic/beats/v7/libbeat/common`. It provides a string set implementation.
19+
* `github.com/elastic/elastic-agent-libs/testing` Testing helpers for network communication and outputs.
20+
* `github.com/elastic/elastic-agent-libs/transport` Dialers for testing, TLS, etc.
1921
* `github.com/elastic/elastic-agent-libs/transport/tlscommon` TLS configuration and validation, CA pinning, etc.

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,26 @@ go 1.17
55
require (
66
github.com/Microsoft/go-winio v0.5.2
77
github.com/elastic/go-ucfg v0.8.4
8+
github.com/fatih/color v1.13.0
89
github.com/hashicorp/go-multierror v1.1.1
910
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
1011
github.com/magefile/mage v1.12.1
12+
github.com/mattn/go-colorable v0.1.12
1113
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
1214
github.com/spf13/cobra v1.3.0
1315
github.com/stretchr/testify v1.7.0
1416
go.elastic.co/ecszap v1.0.0
1517
go.uber.org/zap v1.21.0
1618
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
19+
golang.org/x/net v0.0.0-20211020060615-d418f374d309
1720
golang.org/x/sys v0.0.0-20220209214540-3681064d5158
1821
)
1922

2023
require (
2124
github.com/davecgh/go-spew v1.1.1 // indirect
2225
github.com/hashicorp/errwrap v1.0.0 // indirect
2326
github.com/inconshreveable/mousetrap v1.0.0 // indirect
27+
github.com/mattn/go-isatty v0.0.14 // indirect
2428
github.com/pkg/errors v0.9.1 // indirect
2529
github.com/pmezard/go-difflib v1.0.0 // indirect
2630
github.com/spf13/pflag v1.0.5 // indirect

go.sum

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
110110
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
111111
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
112112
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
113+
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
113114
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
114115
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
115116
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -262,12 +263,14 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
262263
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
263264
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
264265
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
266+
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
265267
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
266268
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
267269
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
268270
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
269271
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
270272
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
273+
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
271274
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
272275
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
273276
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
@@ -463,6 +466,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
463466
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
464467
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
465468
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
469+
golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI=
470+
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
466471
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
467472
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
468473
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=

testing/available_port.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package testing
19+
20+
import "net"
21+
22+
// AvailableTCP4Port returns an unused TCP port for 127.0.0.1.
23+
func AvailableTCP4Port() (uint16, error) {
24+
resolved, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:0")
25+
if err != nil {
26+
return 0, err
27+
}
28+
29+
listener, err := net.ListenTCP("tcp4", resolved)
30+
if err != nil {
31+
return 0, err
32+
}
33+
defer listener.Close()
34+
35+
tcpAddr := uint16(listener.Addr().(*net.TCPAddr).Port)
36+
37+
return tcpAddr, nil
38+
}

testing/console.go

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package testing
19+
20+
import (
21+
"fmt"
22+
"io"
23+
"os"
24+
"runtime"
25+
"strings"
26+
27+
"github.com/fatih/color"
28+
"github.com/mattn/go-colorable"
29+
)
30+
31+
// ConsoleDriver outputs test result to the given stdout/stderr descriptors
32+
type ConsoleDriver struct {
33+
Stdout io.Writer
34+
level int
35+
reported bool
36+
killer func()
37+
result string
38+
}
39+
40+
// NewConsoleDriver initializes and returns a new console driver with output to given file
41+
func NewConsoleDriver(stdout io.Writer) *ConsoleDriver {
42+
return NewConsoleDriverWithKiller(stdout, func() { os.Exit(1) })
43+
}
44+
45+
// NewConsoleDriverWithKiller initializes and returns a new console driver with output file
46+
// Killer function will be called on fatal errors
47+
func NewConsoleDriverWithKiller(stdout io.Writer, killer func()) *ConsoleDriver {
48+
// On Windows we must wrap file outputs with a Colorable to achieve the right
49+
// escape sequences.
50+
if f, ok := stdout.(*os.File); ok && runtime.GOOS == "windows" {
51+
stdout = colorable.NewColorable(f)
52+
}
53+
return &ConsoleDriver{
54+
Stdout: stdout,
55+
level: 0,
56+
killer: killer,
57+
reported: true,
58+
}
59+
}
60+
61+
func (d *ConsoleDriver) Run(name string, f func(Driver)) {
62+
if !d.reported {
63+
fmt.Fprintln(d.Stdout, "")
64+
}
65+
d.printf("%s...", name)
66+
67+
// Run sub func
68+
driver := &ConsoleDriver{
69+
Stdout: d.Stdout,
70+
level: d.level + 1,
71+
killer: d.killer,
72+
}
73+
f(driver)
74+
75+
if !driver.reported {
76+
color.New(color.FgGreen).Fprintf(driver.Stdout, "OK\n")
77+
driver.reported = true
78+
}
79+
80+
if driver.result != "" {
81+
driver.Info("result", driver.indent(driver.result))
82+
}
83+
84+
d.reported = true
85+
}
86+
87+
func (d *ConsoleDriver) Info(field, value string) {
88+
if !d.reported {
89+
fmt.Fprintln(d.Stdout, "")
90+
}
91+
d.printf("%s: %s\n", field, value)
92+
d.reported = true
93+
}
94+
95+
func (d *ConsoleDriver) Warn(field, reason string) {
96+
if !d.reported {
97+
fmt.Fprintln(d.Stdout, "")
98+
}
99+
d.printf("%s... ", field)
100+
color.New(color.FgYellow).Fprintf(d.Stdout, "WARN ")
101+
fmt.Fprintln(d.Stdout, reason)
102+
d.reported = true
103+
}
104+
105+
func (d *ConsoleDriver) Error(field string, err error) {
106+
if err == nil {
107+
d.ok(field)
108+
return
109+
}
110+
d.error(field, err)
111+
}
112+
113+
func (d *ConsoleDriver) Fatal(field string, err error) {
114+
if err == nil {
115+
d.ok(field)
116+
return
117+
}
118+
d.error(field, err)
119+
d.killer()
120+
}
121+
122+
func (d *ConsoleDriver) Result(data string) {
123+
d.result = data
124+
}
125+
126+
func (d *ConsoleDriver) ok(field string) {
127+
if !d.reported {
128+
fmt.Fprintln(d.Stdout, "")
129+
}
130+
d.printf("%s... ", field)
131+
color.New(color.FgGreen).Fprintf(d.Stdout, "OK\n")
132+
d.reported = true
133+
}
134+
135+
func (d *ConsoleDriver) error(field string, err error) {
136+
if !d.reported {
137+
fmt.Fprintln(d.Stdout, "")
138+
}
139+
d.printf("%s... ", field)
140+
color.New(color.FgRed).Fprintf(d.Stdout, "ERROR ")
141+
fmt.Fprintln(d.Stdout, err.Error())
142+
d.reported = true
143+
}
144+
145+
func (d *ConsoleDriver) printf(format string, args ...interface{}) {
146+
for i := 0; i < d.level; i++ {
147+
fmt.Fprint(d.Stdout, " ")
148+
}
149+
fmt.Fprintf(d.Stdout, format, args...)
150+
}
151+
152+
func (d *ConsoleDriver) indent(data string) string {
153+
res := "\n"
154+
for _, line := range strings.Split(data, "\n") {
155+
res += strings.Repeat(" ", d.level+2) + line + "\n"
156+
}
157+
return res
158+
}

testing/console_test.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package testing
19+
20+
import (
21+
"bufio"
22+
"bytes"
23+
"errors"
24+
"testing"
25+
26+
"github.com/fatih/color"
27+
"github.com/stretchr/testify/assert"
28+
)
29+
30+
func init() {
31+
color.NoColor = true
32+
}
33+
34+
func TestConsoleDriverInfo(t *testing.T) {
35+
buffer, output, driver := createDriver(nil)
36+
37+
driver.Info("field", "value")
38+
39+
output.Flush()
40+
assert.Equal(t, buffer.String(), "field: value\n")
41+
}
42+
43+
func TestConsoleDriverWarn(t *testing.T) {
44+
buffer, output, driver := createDriver(nil)
45+
46+
driver.Warn("warning", "you got a warning")
47+
48+
output.Flush()
49+
assert.Equal(t, buffer.String(), "warning... WARN you got a warning\n")
50+
}
51+
52+
func TestConsoleDriverError(t *testing.T) {
53+
buffer, output, driver := createDriver(nil)
54+
55+
err := errors.New("This is an error")
56+
57+
driver.Error("no error", nil)
58+
driver.Error("error", err)
59+
60+
output.Flush()
61+
assert.Equal(t, buffer.String(), "no error... OK\nerror... ERROR This is an error\n")
62+
}
63+
64+
func TestConsoleDriverFatal(t *testing.T) {
65+
var killed bool
66+
buffer, output, driver := createDriver(func() { killed = true })
67+
68+
err := errors.New("This is an error")
69+
70+
driver.Fatal("no error", nil)
71+
driver.Fatal("error", err)
72+
73+
output.Flush()
74+
assert.True(t, killed)
75+
assert.Equal(t, buffer.String(), "no error... OK\nerror... ERROR This is an error\n")
76+
}
77+
78+
func TestConsoleDriverRun(t *testing.T) {
79+
buffer, output, driver := createDriver(nil)
80+
81+
var called bool
82+
driver.Run("test", func(d Driver) {
83+
called = true
84+
})
85+
86+
output.Flush()
87+
assert.True(t, called)
88+
assert.Equal(t, buffer.String(), "test...OK\n")
89+
}
90+
91+
func TestConsoleDriverResult(t *testing.T) {
92+
buffer, output, driver := createDriver(nil)
93+
94+
driver.Run("test", func(d Driver) {
95+
d.Result("This is a multiline\nresult")
96+
})
97+
98+
output.Flush()
99+
assert.Equal(t, buffer.String(), "test...OK\n result: \n This is a multiline\n result\n\n")
100+
}
101+
102+
func TestConsoleDriverRunWithReports(t *testing.T) {
103+
buffer, output, driver := createDriver(nil)
104+
105+
var called bool
106+
err := errors.New("This is an error")
107+
driver.Run("test", func(d Driver) {
108+
called = true
109+
d.Info("field", "value")
110+
d.Error("error", err)
111+
})
112+
113+
output.Flush()
114+
assert.True(t, called)
115+
assert.Equal(t, buffer.String(), "test...\n field: value\n error... ERROR This is an error\n")
116+
}
117+
118+
func createDriver(killer func()) (*bytes.Buffer, *bufio.Writer, *ConsoleDriver) {
119+
buffer := bytes.NewBufferString("")
120+
output := bufio.NewWriter(buffer)
121+
var driver *ConsoleDriver
122+
if killer != nil {
123+
driver = NewConsoleDriverWithKiller(output, killer)
124+
} else {
125+
driver = NewConsoleDriver(output)
126+
}
127+
return buffer, output, driver
128+
}

0 commit comments

Comments
 (0)