aboutsummaryrefslogtreecommitdiffstats
path: root/client/go/util
diff options
context:
space:
mode:
Diffstat (limited to 'client/go/util')
-rw-r--r--client/go/util/http.go55
-rw-r--r--client/go/util/http_test.go46
-rw-r--r--client/go/util/io.go39
-rw-r--r--client/go/util/print.go63
4 files changed, 203 insertions, 0 deletions
diff --git a/client/go/util/http.go b/client/go/util/http.go
new file mode 100644
index 00000000000..24e2416117c
--- /dev/null
+++ b/client/go/util/http.go
@@ -0,0 +1,55 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// A HTTP wrapper which handles some errors and provides a way to replace the HTTP client by a mock.
+// Author: bratseth
+
+package util
+
+import (
+ "net/http"
+ "net/url"
+ "strings"
+ "time"
+)
+
+// Set this to a mock HttpClient instead to unit test HTTP requests
+var ActiveHttpClient = CreateClient(time.Second * 10)
+
+type HttpClient interface {
+ Do(request *http.Request, timeout time.Duration) (response *http.Response, error error)
+}
+
+type defaultHttpClient struct {
+ client *http.Client
+}
+
+func (c *defaultHttpClient) Do(request *http.Request, timeout time.Duration) (response *http.Response, error error) {
+ if c.client.Timeout != timeout { // Create a new client with the right timeout
+ c.client = &http.Client{Timeout: timeout,}
+ }
+ return c.client.Do(request)
+}
+
+func CreateClient(timeout time.Duration) HttpClient {
+ return &defaultHttpClient{
+ client: &http.Client{Timeout: timeout,},
+ }
+}
+
+// Convenience function for doing a HTTP GET
+func HttpGet(host string, path string, description string) *http.Response {
+ url, urlError := url.Parse(host + path)
+ if urlError != nil {
+ Error("Invalid target url '" + host + path + "'")
+ return nil
+ }
+ return HttpDo(&http.Request{URL: url,}, time.Second * 10, description)
+}
+
+func HttpDo(request *http.Request, timeout time.Duration, description string) *http.Response {
+ response, error := ActiveHttpClient.Do(request, timeout)
+ if error != nil {
+ Error("Could not connect to", strings.ToLower(description), "at", request.URL.Host)
+ Detail(error.Error())
+ }
+ return response
+}
diff --git a/client/go/util/http_test.go b/client/go/util/http_test.go
new file mode 100644
index 00000000000..03b155488d9
--- /dev/null
+++ b/client/go/util/http_test.go
@@ -0,0 +1,46 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// Basic testing of our HTTP client wrapper
+// Author: bratseth
+
+package util
+
+import (
+ "bytes"
+ "github.com/stretchr/testify/assert"
+ "io/ioutil"
+ "net/http"
+ "testing"
+ "time"
+)
+
+type mockHttpClient struct {}
+
+func (c mockHttpClient) Do(request *http.Request, timeout time.Duration) (response *http.Response, error error) {
+ var status int
+ var body string
+ if request.URL.String() == "http://host/okpath" {
+ status = 200
+ body = "OK body"
+ } else {
+ status = 500
+ body = "Unexpected url body"
+ }
+
+ return &http.Response{
+ StatusCode: status,
+ Header: make(http.Header),
+ Body: ioutil.NopCloser(bytes.NewBufferString(body)),
+ },
+ nil
+}
+
+func TestHttpRequest(t *testing.T) {
+ ActiveHttpClient = mockHttpClient{}
+
+ response := HttpGet("http://host", "/okpath", "description")
+ assert.Equal(t, 200, response.StatusCode)
+
+ response = HttpGet("http://host", "/otherpath", "description")
+ assert.Equal(t, 500, response.StatusCode)
+}
+
diff --git a/client/go/util/io.go b/client/go/util/io.go
new file mode 100644
index 00000000000..d7b849ba9a4
--- /dev/null
+++ b/client/go/util/io.go
@@ -0,0 +1,39 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// File utilities.
+// Author: bratseth
+
+package util
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "strings"
+)
+
+// Returns true if the given path exists
+func PathExists(path string) bool {
+ _, err := os.Stat(path)
+ return ! errors.Is(err, os.ErrNotExist)
+}
+
+// Returns true is the given path points to an existing directory
+func IsDirectory(path string) bool {
+ info, err := os.Stat(path)
+ return ! errors.Is(err, os.ErrNotExist) && info.IsDir()
+}
+
+// Returns the content of a reader as a string
+func ReaderToString(reader io.Reader) string {
+ buffer := new(strings.Builder)
+ io.Copy(buffer, reader)
+ return buffer.String()
+}
+
+// Returns the content of a reader as a byte array
+func ReaderToBytes(reader io.Reader) []byte {
+ buffer := new(bytes.Buffer)
+ buffer.ReadFrom(reader)
+ return buffer.Bytes()
+}
diff --git a/client/go/util/print.go b/client/go/util/print.go
new file mode 100644
index 00000000000..91a223a3c3a
--- /dev/null
+++ b/client/go/util/print.go
@@ -0,0 +1,63 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// Print functions for color-coded text.
+// Author: bratseth
+
+package util
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+)
+
+// Set this to have output written somewhere else than os.Stdout
+var Out io.Writer
+
+func init() {
+ Out = os.Stdout
+}
+
+// Prints in default color
+func Print(messages ...string) {
+ print("", messages)
+}
+
+// Prints in a color appropriate for errors
+func Error(messages ...string) {
+ print("\033[31m", messages)
+}
+
+// Prints in a color appropriate for success messages
+func Success(messages ...string) {
+ print("\033[32m", messages)
+}
+
+// Prints in a color appropriate for detail messages
+func Detail(messages ...string) {
+ print("\033[33m", messages)
+}
+
+// Prints all the text of the given reader
+func PrintReader(reader io.Reader) {
+ bodyBytes := ReaderToBytes(reader)
+ var prettyJSON bytes.Buffer
+ parseError := json.Indent(&prettyJSON, bodyBytes, "", " ")
+ if parseError != nil { // Not JSON: Print plainly
+ Print(string(bodyBytes))
+ } else {
+ Print(string(prettyJSON.Bytes()))
+ }
+}
+
+func print(prefix string, messages []string) {
+ fmt.Fprint(Out, prefix)
+ for i := 0; i < len(messages); i++ {
+ fmt.Fprint(Out, messages[i])
+ if (i < len(messages) - 1) {
+ fmt.Fprint(Out, " ")
+ }
+ }
+ fmt.Fprintln(Out, "")
+}