173 lines
4.4 KiB
Go
173 lines
4.4 KiB
Go
// Copyright IBM Corp. 2020, 2026
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package client
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"path/filepath"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/boundary/internal/clientcache/internal/daemon"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestClient_New(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
t.Run("nil addr", func(t *testing.T) {
|
|
_, err := New(ctx, nil)
|
|
assert.ErrorContains(t, err, "address is nil")
|
|
})
|
|
t.Run("schema not unix", func(t *testing.T) {
|
|
u, err := url.Parse("http://127.0.0.1/v2/something")
|
|
require.NoError(t, err)
|
|
_, err = New(ctx, u)
|
|
assert.ErrorContains(t, err, "address does not have a unix schema")
|
|
})
|
|
t.Run("schema not unix", func(t *testing.T) {
|
|
u, err := url.Parse("unix://")
|
|
require.NoError(t, err)
|
|
_, err = New(ctx, u)
|
|
assert.ErrorContains(t, err, "address path is empty")
|
|
})
|
|
t.Run("success", func(t *testing.T) {
|
|
u, err := url.Parse("unix:///User/boundary/test.sock")
|
|
require.NoError(t, err)
|
|
c, err := New(ctx, u)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, c)
|
|
})
|
|
}
|
|
|
|
func TestClient(t *testing.T) {
|
|
ctx := context.Background()
|
|
testPath := "/v1/test_endpoint"
|
|
|
|
tmpDir := t.TempDir()
|
|
unixSocket := filepath.Join(tmpDir, "test.sock")
|
|
l, err := net.Listen("unix", unixSocket)
|
|
require.NoError(t, err)
|
|
|
|
var assertRequest func(*http.Request)
|
|
writeResp := func(w http.ResponseWriter) {
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc(testPath, http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { // Mock for the proxy handler.
|
|
assertRequest(req)
|
|
writeResp(rw)
|
|
}))
|
|
|
|
var serverShutdown sync.WaitGroup
|
|
serverShutdown.Add(1)
|
|
go func() {
|
|
defer serverShutdown.Done()
|
|
http.Serve(l, mux)
|
|
}()
|
|
|
|
u, err := url.Parse(fmt.Sprintf("unix://%s", unixSocket))
|
|
require.NoError(t, err)
|
|
c, err := New(ctx, u)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("not found", func(t *testing.T) {
|
|
r, err := c.Get(ctx, "/unknown/path", nil)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, r)
|
|
r.HttpResponse().Body.Close()
|
|
assert.Equal(t, http.StatusNotFound, r.HttpResponse().StatusCode)
|
|
})
|
|
|
|
t.Run("empty response", func(t *testing.T) {
|
|
assertRequest = func(r *http.Request) {
|
|
assert.Equal(t, r.Method, http.MethodGet)
|
|
assert.NotEmpty(t, r.Header.Get(daemon.VersionHeaderKey))
|
|
}
|
|
r, err := c.Get(ctx, testPath, nil)
|
|
assert.NoError(t, err)
|
|
apiErr, err := r.Decode(nil)
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, apiErr)
|
|
assert.NotNil(t, r)
|
|
})
|
|
|
|
t.Run("empty response", func(t *testing.T) {
|
|
assertRequest = func(r *http.Request) {
|
|
assert.Equal(t, r.Method, http.MethodGet)
|
|
assert.NotEmpty(t, r.Header.Get(daemon.VersionHeaderKey))
|
|
}
|
|
r, err := c.Get(ctx, testPath, nil)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, r)
|
|
|
|
apiErr, err := r.Decode(nil)
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, apiErr)
|
|
assert.Empty(t, r.Body)
|
|
})
|
|
|
|
t.Run("empty json object", func(t *testing.T) {
|
|
assertRequest = func(r *http.Request) {
|
|
assert.Equal(t, r.Method, http.MethodGet)
|
|
assert.NotEmpty(t, r.Header.Get(daemon.VersionHeaderKey))
|
|
}
|
|
writeResp = func(w http.ResponseWriter) {
|
|
w.Write([]byte("{}"))
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
r, err := c.Get(ctx, testPath, nil)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, r)
|
|
|
|
apiErr, err := r.Decode(nil)
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, apiErr)
|
|
assert.Equal(t, "{}", string(r.Body.Bytes()))
|
|
})
|
|
|
|
t.Run("query params", func(t *testing.T) {
|
|
v := url.Values{}
|
|
v.Add("foo", "bar")
|
|
|
|
assertRequest = func(r *http.Request) {
|
|
assert.Equal(t, r.Method, http.MethodGet)
|
|
assert.Equal(t, v, r.URL.Query())
|
|
assert.NotEmpty(t, r.Header.Get(daemon.VersionHeaderKey))
|
|
}
|
|
r, err := c.Get(ctx, testPath, &v)
|
|
assert.NoError(t, err)
|
|
apiErr, err := r.Decode(nil)
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, apiErr)
|
|
assert.NotNil(t, r)
|
|
})
|
|
|
|
t.Run("empty json object", func(t *testing.T) {
|
|
assertRequest = func(r *http.Request) {
|
|
assert.Equal(t, r.Method, http.MethodPost)
|
|
assert.NotEmpty(t, r.Header.Get(daemon.VersionHeaderKey))
|
|
b, err := io.ReadAll(r.Body)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, string(b), `{"foo":"bar"}`)
|
|
}
|
|
r, err := c.Post(ctx, testPath, map[string]interface{}{"foo": "bar"})
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, r)
|
|
|
|
apiErr, err := r.Decode(nil)
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, apiErr)
|
|
})
|
|
|
|
l.Close()
|
|
serverShutdown.Wait()
|
|
}
|