forked from mirror/client_golang
Pass warnings through on non-error responses (#599)
Return warnings as a separate string slice to simplify handling. Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com>
This commit is contained in:
parent
e7f6132a76
commit
1335ef46bd
|
@ -25,41 +25,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewErrorAPI(err error, warnings []string) Error {
|
type Warnings []string
|
||||||
if err == nil && warnings == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &ErrorAPI{err, warnings}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ErrorAPI struct {
|
|
||||||
err error
|
|
||||||
warnings []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *ErrorAPI) Err() error {
|
|
||||||
return w.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *ErrorAPI) Error() string {
|
|
||||||
if w.err != nil {
|
|
||||||
return w.err.Error()
|
|
||||||
}
|
|
||||||
return "Warnings: " + strings.Join(w.warnings, " , ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *ErrorAPI) Warnings() []string {
|
|
||||||
return w.warnings
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error encapsulates an error + warning
|
|
||||||
type Error interface {
|
|
||||||
error
|
|
||||||
// Err returns the underlying error.
|
|
||||||
Err() error
|
|
||||||
// Warnings returns a list of warnings.
|
|
||||||
Warnings() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultRoundTripper is used if no RoundTripper is set in Config.
|
// DefaultRoundTripper is used if no RoundTripper is set in Config.
|
||||||
var DefaultRoundTripper http.RoundTripper = &http.Transport{
|
var DefaultRoundTripper http.RoundTripper = &http.Transport{
|
||||||
|
@ -91,30 +57,30 @@ func (cfg *Config) roundTripper() http.RoundTripper {
|
||||||
// Client is the interface for an API client.
|
// Client is the interface for an API client.
|
||||||
type Client interface {
|
type Client interface {
|
||||||
URL(ep string, args map[string]string) *url.URL
|
URL(ep string, args map[string]string) *url.URL
|
||||||
Do(context.Context, *http.Request) (*http.Response, []byte, Error)
|
Do(context.Context, *http.Request) (*http.Response, []byte, Warnings, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoGetFallback will attempt to do the request as-is, and on a 405 it will fallback to a GET request.
|
// DoGetFallback will attempt to do the request as-is, and on a 405 it will fallback to a GET request.
|
||||||
func DoGetFallback(c Client, ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Error) {
|
func DoGetFallback(c Client, ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Warnings, error) {
|
||||||
req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(args.Encode()))
|
req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(args.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, NewErrorAPI(err, nil)
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
resp, body, err := c.Do(ctx, req)
|
resp, body, warnings, err := c.Do(ctx, req)
|
||||||
if resp != nil && resp.StatusCode == http.StatusMethodNotAllowed {
|
if resp != nil && resp.StatusCode == http.StatusMethodNotAllowed {
|
||||||
u.RawQuery = args.Encode()
|
u.RawQuery = args.Encode()
|
||||||
req, err = http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err = http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, NewErrorAPI(err, nil)
|
return nil, nil, warnings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp, body, NewErrorAPI(err, nil)
|
return resp, body, warnings, err
|
||||||
}
|
}
|
||||||
return resp, body, nil
|
return resp, body, warnings, nil
|
||||||
}
|
}
|
||||||
return c.Do(ctx, req)
|
return c.Do(ctx, req)
|
||||||
}
|
}
|
||||||
|
@ -154,7 +120,7 @@ func (c *httpClient) URL(ep string, args map[string]string) *url.URL {
|
||||||
return &u
|
return &u
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, Error) {
|
func (c *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, Warnings, error) {
|
||||||
if ctx != nil {
|
if ctx != nil {
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
}
|
}
|
||||||
|
@ -166,7 +132,7 @@ func (c *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response,
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, NewErrorAPI(err, nil)
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var body []byte
|
var body []byte
|
||||||
|
@ -186,5 +152,5 @@ func (c *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response,
|
||||||
case <-done:
|
case <-done:
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, body, NewErrorAPI(err, nil)
|
return resp, body, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ func TestDoGetFallback(t *testing.T) {
|
||||||
client := &httpClient{client: *(server.Client())}
|
client := &httpClient{client: *(server.Client())}
|
||||||
|
|
||||||
// Do a post, and ensure that the post succeeds.
|
// Do a post, and ensure that the post succeeds.
|
||||||
_, b, err := DoGetFallback(client, context.TODO(), u, v)
|
_, b, _, err := DoGetFallback(client, context.TODO(), u, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error doing local request: %v", err)
|
t.Fatalf("Error doing local request: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ func TestDoGetFallback(t *testing.T) {
|
||||||
|
|
||||||
// Do a fallbcak to a get.
|
// Do a fallbcak to a get.
|
||||||
u.Path = "/blockPost"
|
u.Path = "/blockPost"
|
||||||
_, b, err = DoGetFallback(client, context.TODO(), u, v)
|
_, b, _, err = DoGetFallback(client, context.TODO(), u, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error doing local request: %v", err)
|
t.Fatalf("Error doing local request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -197,26 +196,13 @@ const (
|
||||||
|
|
||||||
// Error is an error returned by the API.
|
// Error is an error returned by the API.
|
||||||
type Error struct {
|
type Error struct {
|
||||||
Type ErrorType
|
Type ErrorType
|
||||||
Msg string
|
Msg string
|
||||||
Detail string
|
Detail string
|
||||||
warnings []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
func (e *Error) Error() string {
|
||||||
if e.Type != "" || e.Msg != "" {
|
return fmt.Sprintf("%s: %s", e.Type, e.Msg)
|
||||||
return fmt.Sprintf("%s: %s", e.Type, e.Msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Warnings: " + strings.Join(e.warnings, " , ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Error) Err() error {
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Error) Warnings() []string {
|
|
||||||
return w.warnings
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Range represents a sliced time range.
|
// Range represents a sliced time range.
|
||||||
|
@ -230,34 +216,34 @@ type Range struct {
|
||||||
// API provides bindings for Prometheus's v1 API.
|
// API provides bindings for Prometheus's v1 API.
|
||||||
type API interface {
|
type API interface {
|
||||||
// Alerts returns a list of all active alerts.
|
// Alerts returns a list of all active alerts.
|
||||||
Alerts(ctx context.Context) (AlertsResult, api.Error)
|
Alerts(ctx context.Context) (AlertsResult, error)
|
||||||
// AlertManagers returns an overview of the current state of the Prometheus alert manager discovery.
|
// AlertManagers returns an overview of the current state of the Prometheus alert manager discovery.
|
||||||
AlertManagers(ctx context.Context) (AlertManagersResult, api.Error)
|
AlertManagers(ctx context.Context) (AlertManagersResult, error)
|
||||||
// CleanTombstones removes the deleted data from disk and cleans up the existing tombstones.
|
// CleanTombstones removes the deleted data from disk and cleans up the existing tombstones.
|
||||||
CleanTombstones(ctx context.Context) api.Error
|
CleanTombstones(ctx context.Context) error
|
||||||
// Config returns the current Prometheus configuration.
|
// Config returns the current Prometheus configuration.
|
||||||
Config(ctx context.Context) (ConfigResult, api.Error)
|
Config(ctx context.Context) (ConfigResult, error)
|
||||||
// DeleteSeries deletes data for a selection of series in a time range.
|
// DeleteSeries deletes data for a selection of series in a time range.
|
||||||
DeleteSeries(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) api.Error
|
DeleteSeries(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) error
|
||||||
// Flags returns the flag values that Prometheus was launched with.
|
// Flags returns the flag values that Prometheus was launched with.
|
||||||
Flags(ctx context.Context) (FlagsResult, api.Error)
|
Flags(ctx context.Context) (FlagsResult, error)
|
||||||
// LabelValues performs a query for the values of the given label.
|
// LabelValues performs a query for the values of the given label.
|
||||||
LabelValues(ctx context.Context, label string) (model.LabelValues, api.Error)
|
LabelValues(ctx context.Context, label string) (model.LabelValues, error)
|
||||||
// Query performs a query for the given time.
|
// Query performs a query for the given time.
|
||||||
Query(ctx context.Context, query string, ts time.Time) (model.Value, api.Error)
|
Query(ctx context.Context, query string, ts time.Time) (model.Value, api.Warnings, error)
|
||||||
// QueryRange performs a query for the given range.
|
// QueryRange performs a query for the given range.
|
||||||
QueryRange(ctx context.Context, query string, r Range) (model.Value, api.Error)
|
QueryRange(ctx context.Context, query string, r Range) (model.Value, api.Warnings, error)
|
||||||
// Series finds series by label matchers.
|
// Series finds series by label matchers.
|
||||||
Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, api.Error)
|
Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, error)
|
||||||
// Snapshot creates a snapshot of all current data into snapshots/<datetime>-<rand>
|
// Snapshot creates a snapshot of all current data into snapshots/<datetime>-<rand>
|
||||||
// under the TSDB's data directory and returns the directory as response.
|
// under the TSDB's data directory and returns the directory as response.
|
||||||
Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, api.Error)
|
Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error)
|
||||||
// Rules returns a list of alerting and recording rules that are currently loaded.
|
// Rules returns a list of alerting and recording rules that are currently loaded.
|
||||||
Rules(ctx context.Context) (RulesResult, api.Error)
|
Rules(ctx context.Context) (RulesResult, error)
|
||||||
// Targets returns an overview of the current state of the Prometheus target discovery.
|
// Targets returns an overview of the current state of the Prometheus target discovery.
|
||||||
Targets(ctx context.Context) (TargetsResult, api.Error)
|
Targets(ctx context.Context) (TargetsResult, error)
|
||||||
// TargetsMetadata returns metadata about metrics currently scraped by the target.
|
// TargetsMetadata returns metadata about metrics currently scraped by the target.
|
||||||
TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, api.Error)
|
TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AlertsResult contains the result from querying the alerts endpoint.
|
// AlertsResult contains the result from querying the alerts endpoint.
|
||||||
|
@ -534,73 +520,70 @@ type httpAPI struct {
|
||||||
client api.Client
|
client api.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Alerts(ctx context.Context) (AlertsResult, api.Error) {
|
func (h *httpAPI) Alerts(ctx context.Context) (AlertsResult, error) {
|
||||||
u := h.client.URL(epAlerts, nil)
|
u := h.client.URL(epAlerts, nil)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return AlertsResult{}, api.NewErrorAPI(err, nil)
|
return AlertsResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return AlertsResult{}, apiErr
|
return AlertsResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var res AlertsResult
|
var res AlertsResult
|
||||||
err = json.Unmarshal(body, &res)
|
return res, json.Unmarshal(body, &res)
|
||||||
return res, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) AlertManagers(ctx context.Context) (AlertManagersResult, api.Error) {
|
func (h *httpAPI) AlertManagers(ctx context.Context) (AlertManagersResult, error) {
|
||||||
u := h.client.URL(epAlertManagers, nil)
|
u := h.client.URL(epAlertManagers, nil)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return AlertManagersResult{}, api.NewErrorAPI(err, nil)
|
return AlertManagersResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return AlertManagersResult{}, apiErr
|
return AlertManagersResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var res AlertManagersResult
|
var res AlertManagersResult
|
||||||
err = json.Unmarshal(body, &res)
|
return res, json.Unmarshal(body, &res)
|
||||||
return res, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) CleanTombstones(ctx context.Context) api.Error {
|
func (h *httpAPI) CleanTombstones(ctx context.Context) error {
|
||||||
u := h.client.URL(epCleanTombstones, nil)
|
u := h.client.URL(epCleanTombstones, nil)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, u.String(), nil)
|
req, err := http.NewRequest(http.MethodPost, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.NewErrorAPI(err, nil)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, apiErr := h.client.Do(ctx, req)
|
_, _, _, err = h.client.Do(ctx, req)
|
||||||
return apiErr
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Config(ctx context.Context) (ConfigResult, api.Error) {
|
func (h *httpAPI) Config(ctx context.Context) (ConfigResult, error) {
|
||||||
u := h.client.URL(epConfig, nil)
|
u := h.client.URL(epConfig, nil)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ConfigResult{}, api.NewErrorAPI(err, nil)
|
return ConfigResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return ConfigResult{}, apiErr
|
return ConfigResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var res ConfigResult
|
var res ConfigResult
|
||||||
err = json.Unmarshal(body, &res)
|
return res, json.Unmarshal(body, &res)
|
||||||
return res, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) DeleteSeries(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) api.Error {
|
func (h *httpAPI) DeleteSeries(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) error {
|
||||||
u := h.client.URL(epDeleteSeries, nil)
|
u := h.client.URL(epDeleteSeries, nil)
|
||||||
q := u.Query()
|
q := u.Query()
|
||||||
|
|
||||||
|
@ -615,47 +598,45 @@ func (h *httpAPI) DeleteSeries(ctx context.Context, matches []string, startTime
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, u.String(), nil)
|
req, err := http.NewRequest(http.MethodPost, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.NewErrorAPI(err, nil)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, apiErr := h.client.Do(ctx, req)
|
_, _, _, err = h.client.Do(ctx, req)
|
||||||
return apiErr
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Flags(ctx context.Context) (FlagsResult, api.Error) {
|
func (h *httpAPI) Flags(ctx context.Context) (FlagsResult, error) {
|
||||||
u := h.client.URL(epFlags, nil)
|
u := h.client.URL(epFlags, nil)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FlagsResult{}, api.NewErrorAPI(err, nil)
|
return FlagsResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return FlagsResult{}, apiErr
|
return FlagsResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var res FlagsResult
|
var res FlagsResult
|
||||||
err = json.Unmarshal(body, &res)
|
return res, json.Unmarshal(body, &res)
|
||||||
return res, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) LabelValues(ctx context.Context, label string) (model.LabelValues, api.Error) {
|
func (h *httpAPI) LabelValues(ctx context.Context, label string) (model.LabelValues, error) {
|
||||||
u := h.client.URL(epLabelValues, map[string]string{"name": label})
|
u := h.client.URL(epLabelValues, map[string]string{"name": label})
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, api.NewErrorAPI(err, nil)
|
return nil, err
|
||||||
}
|
}
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return nil, apiErr
|
return nil, err
|
||||||
}
|
}
|
||||||
var labelValues model.LabelValues
|
var labelValues model.LabelValues
|
||||||
err = json.Unmarshal(body, &labelValues)
|
return labelValues, json.Unmarshal(body, &labelValues)
|
||||||
return labelValues, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time) (model.Value, api.Error) {
|
func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time) (model.Value, api.Warnings, error) {
|
||||||
u := h.client.URL(epQuery, nil)
|
u := h.client.URL(epQuery, nil)
|
||||||
q := u.Query()
|
q := u.Query()
|
||||||
|
|
||||||
|
@ -664,16 +645,16 @@ func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time) (model.
|
||||||
q.Set("time", ts.Format(time.RFC3339Nano))
|
q.Set("time", ts.Format(time.RFC3339Nano))
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := api.DoGetFallback(h.client, ctx, u, q)
|
_, body, warnings, err := api.DoGetFallback(h.client, ctx, u, q)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return nil, apiErr
|
return nil, warnings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var qres queryResult
|
var qres queryResult
|
||||||
return model.Value(qres.v), api.NewErrorAPI(json.Unmarshal(body, &qres), nil)
|
return model.Value(qres.v), warnings, json.Unmarshal(body, &qres)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) QueryRange(ctx context.Context, query string, r Range) (model.Value, api.Error) {
|
func (h *httpAPI) QueryRange(ctx context.Context, query string, r Range) (model.Value, api.Warnings, error) {
|
||||||
u := h.client.URL(epQueryRange, nil)
|
u := h.client.URL(epQueryRange, nil)
|
||||||
q := u.Query()
|
q := u.Query()
|
||||||
|
|
||||||
|
@ -688,17 +669,17 @@ func (h *httpAPI) QueryRange(ctx context.Context, query string, r Range) (model.
|
||||||
q.Set("end", end)
|
q.Set("end", end)
|
||||||
q.Set("step", step)
|
q.Set("step", step)
|
||||||
|
|
||||||
_, body, apiErr := api.DoGetFallback(h.client, ctx, u, q)
|
_, body, warnings, err := api.DoGetFallback(h.client, ctx, u, q)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return nil, apiErr
|
return nil, warnings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var qres queryResult
|
var qres queryResult
|
||||||
|
|
||||||
return model.Value(qres.v), api.NewErrorAPI(json.Unmarshal(body, &qres), nil)
|
return model.Value(qres.v), warnings, json.Unmarshal(body, &qres)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, api.Error) {
|
func (h *httpAPI) Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, error) {
|
||||||
u := h.client.URL(epSeries, nil)
|
u := h.client.URL(epSeries, nil)
|
||||||
q := u.Query()
|
q := u.Query()
|
||||||
|
|
||||||
|
@ -713,20 +694,19 @@ func (h *httpAPI) Series(ctx context.Context, matches []string, startTime time.T
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, api.NewErrorAPI(err, nil)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return nil, apiErr
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var mset []model.LabelSet
|
var mset []model.LabelSet
|
||||||
err = json.Unmarshal(body, &mset)
|
return mset, json.Unmarshal(body, &mset)
|
||||||
return mset, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, api.Error) {
|
func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) {
|
||||||
u := h.client.URL(epSnapshot, nil)
|
u := h.client.URL(epSnapshot, nil)
|
||||||
q := u.Query()
|
q := u.Query()
|
||||||
|
|
||||||
|
@ -736,56 +716,53 @@ func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult,
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, u.String(), nil)
|
req, err := http.NewRequest(http.MethodPost, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return SnapshotResult{}, api.NewErrorAPI(err, nil)
|
return SnapshotResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return SnapshotResult{}, apiErr
|
return SnapshotResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var res SnapshotResult
|
var res SnapshotResult
|
||||||
err = json.Unmarshal(body, &res)
|
return res, json.Unmarshal(body, &res)
|
||||||
return res, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Rules(ctx context.Context) (RulesResult, api.Error) {
|
func (h *httpAPI) Rules(ctx context.Context) (RulesResult, error) {
|
||||||
u := h.client.URL(epRules, nil)
|
u := h.client.URL(epRules, nil)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return RulesResult{}, api.NewErrorAPI(err, nil)
|
return RulesResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return RulesResult{}, apiErr
|
return RulesResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var res RulesResult
|
var res RulesResult
|
||||||
err = json.Unmarshal(body, &res)
|
return res, json.Unmarshal(body, &res)
|
||||||
return res, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Targets(ctx context.Context) (TargetsResult, api.Error) {
|
func (h *httpAPI) Targets(ctx context.Context) (TargetsResult, error) {
|
||||||
u := h.client.URL(epTargets, nil)
|
u := h.client.URL(epTargets, nil)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return TargetsResult{}, api.NewErrorAPI(err, nil)
|
return TargetsResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return TargetsResult{}, apiErr
|
return TargetsResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var res TargetsResult
|
var res TargetsResult
|
||||||
err = json.Unmarshal(body, &res)
|
return res, json.Unmarshal(body, &res)
|
||||||
return res, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, api.Error) {
|
func (h *httpAPI) TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, error) {
|
||||||
u := h.client.URL(epTargetsMetadata, nil)
|
u := h.client.URL(epTargetsMetadata, nil)
|
||||||
q := u.Query()
|
q := u.Query()
|
||||||
|
|
||||||
|
@ -797,17 +774,16 @@ func (h *httpAPI) TargetsMetadata(ctx context.Context, matchTarget string, metri
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, api.NewErrorAPI(err, nil)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, body, apiErr := h.client.Do(ctx, req)
|
_, body, _, err := h.client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return nil, apiErr
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var res []MetricMetadata
|
var res []MetricMetadata
|
||||||
err = json.Unmarshal(body, &res)
|
return res, json.Unmarshal(body, &res)
|
||||||
return res, api.NewErrorAPI(err, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// apiClient wraps a regular client and processes successful API responses.
|
// apiClient wraps a regular client and processes successful API responses.
|
||||||
|
@ -839,19 +815,17 @@ func errorTypeAndMsgFor(resp *http.Response) (ErrorType, string) {
|
||||||
return ErrBadResponse, fmt.Sprintf("bad response code %d", resp.StatusCode)
|
return ErrBadResponse, fmt.Sprintf("bad response code %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, api.Error) {
|
func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, api.Warnings, error) {
|
||||||
resp, body, apiErr := c.Client.Do(ctx, req)
|
resp, body, warnings, err := c.Client.Do(ctx, req)
|
||||||
if apiErr != nil {
|
if err != nil {
|
||||||
return resp, body, apiErr
|
return resp, body, warnings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
code := resp.StatusCode
|
code := resp.StatusCode
|
||||||
|
|
||||||
var err api.Error
|
|
||||||
|
|
||||||
if code/100 != 2 && !apiError(code) {
|
if code/100 != 2 && !apiError(code) {
|
||||||
errorType, errorMsg := errorTypeAndMsgFor(resp)
|
errorType, errorMsg := errorTypeAndMsgFor(resp)
|
||||||
return resp, body, &Error{
|
return resp, body, warnings, &Error{
|
||||||
Type: errorType,
|
Type: errorType,
|
||||||
Msg: errorMsg,
|
Msg: errorMsg,
|
||||||
Detail: string(body),
|
Detail: string(body),
|
||||||
|
@ -862,7 +836,7 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [
|
||||||
|
|
||||||
if http.StatusNoContent != code {
|
if http.StatusNoContent != code {
|
||||||
if jsonErr := json.Unmarshal(body, &result); jsonErr != nil {
|
if jsonErr := json.Unmarshal(body, &result); jsonErr != nil {
|
||||||
return resp, body, &Error{
|
return resp, body, warnings, &Error{
|
||||||
Type: ErrBadResponse,
|
Type: ErrBadResponse,
|
||||||
Msg: jsonErr.Error(),
|
Msg: jsonErr.Error(),
|
||||||
}
|
}
|
||||||
|
@ -871,20 +845,18 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [
|
||||||
|
|
||||||
if apiError(code) != (result.Status == "error") {
|
if apiError(code) != (result.Status == "error") {
|
||||||
err = &Error{
|
err = &Error{
|
||||||
Type: ErrBadResponse,
|
Type: ErrBadResponse,
|
||||||
Msg: "inconsistent body for response code",
|
Msg: "inconsistent body for response code",
|
||||||
warnings: result.Warnings,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if apiError(code) && result.Status == "error" {
|
if apiError(code) && result.Status == "error" {
|
||||||
err = &Error{
|
err = &Error{
|
||||||
Type: result.ErrorType,
|
Type: result.ErrorType,
|
||||||
Msg: result.Error,
|
Msg: result.Error,
|
||||||
warnings: result.Warnings,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, []byte(result.Data), err
|
return resp, []byte(result.Data), warnings, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type apiTest struct {
|
type apiTest struct {
|
||||||
do func() (interface{}, api.Error)
|
do func() (interface{}, api.Warnings, error)
|
||||||
inWarnings []string
|
inWarnings []string
|
||||||
inErr error
|
inErr error
|
||||||
inStatusCode int
|
inStatusCode int
|
||||||
|
@ -43,6 +43,7 @@ type apiTest struct {
|
||||||
reqParam url.Values
|
reqParam url.Values
|
||||||
reqMethod string
|
reqMethod string
|
||||||
res interface{}
|
res interface{}
|
||||||
|
warnings api.Warnings
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ func (c *apiTestClient) URL(ep string, args map[string]string) *url.URL {
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *apiTestClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, api.Error) {
|
func (c *apiTestClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, api.Warnings, error) {
|
||||||
|
|
||||||
test := c.curTest
|
test := c.curTest
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@ func (c *apiTestClient) Do(ctx context.Context, req *http.Request) (*http.Respon
|
||||||
resp.StatusCode = http.StatusOK
|
resp.StatusCode = http.StatusOK
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, b, api.NewErrorAPI(test.inErr, test.inWarnings)
|
return resp, b, test.inWarnings, test.inErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPIs(t *testing.T) {
|
func TestAPIs(t *testing.T) {
|
||||||
|
@ -101,81 +102,90 @@ func TestAPIs(t *testing.T) {
|
||||||
client: client,
|
client: client,
|
||||||
}
|
}
|
||||||
|
|
||||||
doAlertManagers := func() func() (interface{}, api.Error) {
|
doAlertManagers := func() func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.AlertManagers(context.Background())
|
v, err := promAPI.AlertManagers(context.Background())
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doCleanTombstones := func() func() (interface{}, api.Error) {
|
doCleanTombstones := func() func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return nil, promAPI.CleanTombstones(context.Background())
|
return nil, nil, promAPI.CleanTombstones(context.Background())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doConfig := func() func() (interface{}, api.Error) {
|
doConfig := func() func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.Config(context.Background())
|
v, err := promAPI.Config(context.Background())
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doDeleteSeries := func(matcher string, startTime time.Time, endTime time.Time) func() (interface{}, api.Error) {
|
doDeleteSeries := func(matcher string, startTime time.Time, endTime time.Time) func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return nil, promAPI.DeleteSeries(context.Background(), []string{matcher}, startTime, endTime)
|
return nil, nil, promAPI.DeleteSeries(context.Background(), []string{matcher}, startTime, endTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doFlags := func() func() (interface{}, api.Error) {
|
doFlags := func() func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.Flags(context.Background())
|
v, err := promAPI.Flags(context.Background())
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doLabelValues := func(label string) func() (interface{}, api.Error) {
|
doLabelValues := func(label string) func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.LabelValues(context.Background(), label)
|
v, err := promAPI.LabelValues(context.Background(), label)
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doQuery := func(q string, ts time.Time) func() (interface{}, api.Error) {
|
doQuery := func(q string, ts time.Time) func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.Query(context.Background(), q, ts)
|
return promAPI.Query(context.Background(), q, ts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doQueryRange := func(q string, rng Range) func() (interface{}, api.Error) {
|
doQueryRange := func(q string, rng Range) func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.QueryRange(context.Background(), q, rng)
|
return promAPI.QueryRange(context.Background(), q, rng)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doSeries := func(matcher string, startTime time.Time, endTime time.Time) func() (interface{}, api.Error) {
|
doSeries := func(matcher string, startTime time.Time, endTime time.Time) func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.Series(context.Background(), []string{matcher}, startTime, endTime)
|
v, err := promAPI.Series(context.Background(), []string{matcher}, startTime, endTime)
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doSnapshot := func(skipHead bool) func() (interface{}, api.Error) {
|
doSnapshot := func(skipHead bool) func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.Snapshot(context.Background(), skipHead)
|
v, err := promAPI.Snapshot(context.Background(), skipHead)
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doRules := func() func() (interface{}, api.Error) {
|
doRules := func() func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.Rules(context.Background())
|
v, err := promAPI.Rules(context.Background())
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doTargets := func() func() (interface{}, api.Error) {
|
doTargets := func() func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.Targets(context.Background())
|
v, err := promAPI.Targets(context.Background())
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doTargetsMetadata := func(matchTarget string, metric string, limit string) func() (interface{}, api.Error) {
|
doTargetsMetadata := func(matchTarget string, metric string, limit string) func() (interface{}, api.Warnings, error) {
|
||||||
return func() (interface{}, api.Error) {
|
return func() (interface{}, api.Warnings, error) {
|
||||||
return promAPI.TargetsMetadata(context.Background(), matchTarget, metric, limit)
|
v, err := promAPI.TargetsMetadata(context.Background(), matchTarget, metric, limit)
|
||||||
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,6 +259,51 @@ func TestAPIs(t *testing.T) {
|
||||||
},
|
},
|
||||||
err: errors.New("client_error: client error: 404"),
|
err: errors.New("client_error: client error: 404"),
|
||||||
},
|
},
|
||||||
|
// Warning only.
|
||||||
|
{
|
||||||
|
do: doQuery("2", testTime),
|
||||||
|
inWarnings: []string{"warning"},
|
||||||
|
inRes: &queryResult{
|
||||||
|
Type: model.ValScalar,
|
||||||
|
Result: &model.Scalar{
|
||||||
|
Value: 2,
|
||||||
|
Timestamp: model.TimeFromUnix(testTime.Unix()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
reqMethod: "POST",
|
||||||
|
reqPath: "/api/v1/query",
|
||||||
|
reqParam: url.Values{
|
||||||
|
"query": []string{"2"},
|
||||||
|
"time": []string{testTime.Format(time.RFC3339Nano)},
|
||||||
|
},
|
||||||
|
res: &model.Scalar{
|
||||||
|
Value: 2,
|
||||||
|
Timestamp: model.TimeFromUnix(testTime.Unix()),
|
||||||
|
},
|
||||||
|
warnings: []string{"warning"},
|
||||||
|
},
|
||||||
|
// Warning + error.
|
||||||
|
{
|
||||||
|
do: doQuery("2", testTime),
|
||||||
|
inWarnings: []string{"warning"},
|
||||||
|
inRes: "some body",
|
||||||
|
inStatusCode: 404,
|
||||||
|
inErr: &Error{
|
||||||
|
Type: ErrClient,
|
||||||
|
Msg: "client error: 404",
|
||||||
|
Detail: "some body",
|
||||||
|
},
|
||||||
|
|
||||||
|
reqMethod: "POST",
|
||||||
|
reqPath: "/api/v1/query",
|
||||||
|
reqParam: url.Values{
|
||||||
|
"query": []string{"2"},
|
||||||
|
"time": []string{testTime.Format(time.RFC3339Nano)},
|
||||||
|
},
|
||||||
|
err: errors.New("client_error: client error: 404"),
|
||||||
|
warnings: []string{"warning"},
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
do: doQueryRange("2", Range{
|
do: doQueryRange("2", Range{
|
||||||
|
@ -705,7 +760,11 @@ func TestAPIs(t *testing.T) {
|
||||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||||
client.curTest = test
|
client.curTest = test
|
||||||
|
|
||||||
res, err := test.do()
|
res, warnings, err := test.do()
|
||||||
|
|
||||||
|
if (test.inWarnings == nil) != (warnings == nil) && !reflect.DeepEqual(test.inWarnings, warnings) {
|
||||||
|
t.Fatalf("mismatch in warnings expected=%v actual=%v", test.inWarnings, warnings)
|
||||||
|
}
|
||||||
|
|
||||||
if test.err != nil {
|
if test.err != nil {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -740,17 +799,18 @@ type testClient struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiClientTest struct {
|
type apiClientTest struct {
|
||||||
code int
|
code int
|
||||||
response interface{}
|
response interface{}
|
||||||
expectedBody string
|
expectedBody string
|
||||||
expectedErr *Error
|
expectedErr *Error
|
||||||
|
expectedWarnings api.Warnings
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testClient) URL(ep string, args map[string]string) *url.URL {
|
func (c *testClient) URL(ep string, args map[string]string) *url.URL {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, api.Error) {
|
func (c *testClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, api.Warnings, error) {
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
c.Fatalf("context was not passed down")
|
c.Fatalf("context was not passed down")
|
||||||
}
|
}
|
||||||
|
@ -777,7 +837,7 @@ func (c *testClient) Do(ctx context.Context, req *http.Request) (*http.Response,
|
||||||
StatusCode: test.code,
|
StatusCode: test.code,
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, b, nil
|
return resp, b, test.expectedWarnings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPIClientDo(t *testing.T) {
|
func TestAPIClientDo(t *testing.T) {
|
||||||
|
@ -896,10 +956,10 @@ func TestAPIClientDo(t *testing.T) {
|
||||||
Warnings: []string{"a"},
|
Warnings: []string{"a"},
|
||||||
},
|
},
|
||||||
expectedErr: &Error{
|
expectedErr: &Error{
|
||||||
Type: ErrBadResponse,
|
Type: ErrBadResponse,
|
||||||
Msg: "inconsistent body for response code",
|
Msg: "inconsistent body for response code",
|
||||||
warnings: []string{"a"},
|
|
||||||
},
|
},
|
||||||
|
expectedWarnings: []string{"a"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,7 +975,17 @@ func TestAPIClientDo(t *testing.T) {
|
||||||
|
|
||||||
tc.ch <- test
|
tc.ch <- test
|
||||||
|
|
||||||
_, body, err := client.Do(context.Background(), tc.req)
|
_, body, warnings, err := client.Do(context.Background(), tc.req)
|
||||||
|
|
||||||
|
if test.expectedWarnings != nil {
|
||||||
|
if !reflect.DeepEqual(test.expectedWarnings, warnings) {
|
||||||
|
t.Fatalf("mismatch in warnings expected=%v actual=%v", test.expectedWarnings, warnings)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if warnings != nil {
|
||||||
|
t.Fatalf("unexpexted warnings: %v", warnings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if test.expectedErr != nil {
|
if test.expectedErr != nil {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -933,15 +1003,6 @@ func TestAPIClientDo(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(test.expectedErr.Warnings()) != len(err.Warnings()) {
|
|
||||||
t.Fatalf("expected warnings length :%v, but got:%v", len(test.expectedErr.Warnings()), len(err.Warnings()))
|
|
||||||
}
|
|
||||||
|
|
||||||
for x, warning := range test.expectedErr.Warnings() {
|
|
||||||
if warning != err.Warnings()[x] {
|
|
||||||
t.Fatalf("expected warning :%v, but got:%v", warning, err.Warnings()[x])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue