2016-04-04 02:20:07 +00:00
|
|
|
package http_response
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"testing"
|
|
|
|
"time"
|
2016-05-23 12:33:43 +00:00
|
|
|
|
|
|
|
"github.com/influxdata/telegraf/internal"
|
2017-05-09 23:21:04 +00:00
|
|
|
"github.com/influxdata/telegraf/testutil"
|
2016-05-23 12:33:43 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
2016-04-04 02:20:07 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func setUpTestMux() http.Handler {
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
mux.HandleFunc("/redirect", func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
http.Redirect(w, req, "/good", http.StatusMovedPermanently)
|
|
|
|
})
|
|
|
|
mux.HandleFunc("/good", func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
fmt.Fprintf(w, "hit the good page!")
|
|
|
|
})
|
2017-02-01 14:21:08 +00:00
|
|
|
mux.HandleFunc("/jsonresponse", func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
fmt.Fprintf(w, "\"service_status\": \"up\", \"healthy\" : \"true\"")
|
|
|
|
})
|
2016-04-04 02:20:07 +00:00
|
|
|
mux.HandleFunc("/badredirect", func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
http.Redirect(w, req, "/badredirect", http.StatusMovedPermanently)
|
|
|
|
})
|
|
|
|
mux.HandleFunc("/mustbepostmethod", func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != "POST" {
|
|
|
|
http.Error(w, "method wasn't post", http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
fmt.Fprintf(w, "used post correctly!")
|
|
|
|
})
|
|
|
|
mux.HandleFunc("/musthaveabody", func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
body, err := ioutil.ReadAll(req.Body)
|
|
|
|
req.Body.Close()
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, "couldn't read request body", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if string(body) == "" {
|
|
|
|
http.Error(w, "body was empty", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
fmt.Fprintf(w, "sent a body!")
|
|
|
|
})
|
|
|
|
mux.HandleFunc("/twosecondnap", func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
time.Sleep(time.Second * 2)
|
|
|
|
return
|
|
|
|
})
|
|
|
|
return mux
|
|
|
|
}
|
|
|
|
|
2016-05-19 11:08:25 +00:00
|
|
|
func TestHeaders(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
cHeader := r.Header.Get("Content-Type")
|
|
|
|
assert.Equal(t, "Hello", r.Host)
|
|
|
|
assert.Equal(t, "application/json", cHeader)
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL,
|
|
|
|
Method: "GET",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 2},
|
2016-05-19 11:08:25 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
"Host": "Hello",
|
|
|
|
},
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2016-05-19 11:08:25 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusOK, value)
|
2016-05-19 11:08:25 +00:00
|
|
|
}
|
|
|
|
|
2016-04-04 02:20:07 +00:00
|
|
|
func TestFields(t *testing.T) {
|
|
|
|
mux := setUpTestMux()
|
|
|
|
ts := httptest.NewServer(mux)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL + "/good",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2016-04-04 02:20:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusOK, value)
|
2017-06-06 20:39:07 +00:00
|
|
|
response_value, ok := acc.StringField("http_response", "result_type")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, "success", response_value)
|
2016-04-04 02:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestRedirects(t *testing.T) {
|
|
|
|
mux := setUpTestMux()
|
|
|
|
ts := httptest.NewServer(mux)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL + "/redirect",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2016-04-04 02:20:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusOK, value)
|
2016-04-04 02:20:07 +00:00
|
|
|
|
|
|
|
h = &HTTPResponse{
|
|
|
|
Address: ts.URL + "/badredirect",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
acc = testutil.Accumulator{}
|
|
|
|
err = h.Gather(&acc)
|
2017-06-06 20:39:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok = acc.IntField("http_response", "http_response_code")
|
|
|
|
require.False(t, ok)
|
2017-06-06 20:39:07 +00:00
|
|
|
response_value, ok := acc.StringField("http_response", "result_type")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, "connection_failed", response_value)
|
2016-04-04 02:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMethod(t *testing.T) {
|
|
|
|
mux := setUpTestMux()
|
|
|
|
ts := httptest.NewServer(mux)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL + "/mustbepostmethod",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "POST",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2016-04-04 02:20:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusOK, value)
|
2016-04-04 02:20:07 +00:00
|
|
|
|
|
|
|
h = &HTTPResponse{
|
|
|
|
Address: ts.URL + "/mustbepostmethod",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
acc = testutil.Accumulator{}
|
|
|
|
err = h.Gather(&acc)
|
2016-04-04 02:20:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok = acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusMethodNotAllowed, value)
|
2016-04-04 02:20:07 +00:00
|
|
|
|
|
|
|
//check that lowercase methods work correctly
|
|
|
|
h = &HTTPResponse{
|
|
|
|
Address: ts.URL + "/mustbepostmethod",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "head",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
acc = testutil.Accumulator{}
|
|
|
|
err = h.Gather(&acc)
|
2016-04-04 02:20:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok = acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusMethodNotAllowed, value)
|
2016-04-04 02:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBody(t *testing.T) {
|
|
|
|
mux := setUpTestMux()
|
|
|
|
ts := httptest.NewServer(mux)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL + "/musthaveabody",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2016-04-04 02:20:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusOK, value)
|
2016-04-04 02:20:07 +00:00
|
|
|
|
|
|
|
h = &HTTPResponse{
|
|
|
|
Address: ts.URL + "/musthaveabody",
|
|
|
|
Method: "GET",
|
2016-05-23 12:33:43 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
acc = testutil.Accumulator{}
|
|
|
|
err = h.Gather(&acc)
|
2016-04-04 02:20:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
value, ok = acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusBadRequest, value)
|
2016-04-04 02:20:07 +00:00
|
|
|
}
|
|
|
|
|
2017-02-01 14:21:08 +00:00
|
|
|
func TestStringMatch(t *testing.T) {
|
|
|
|
mux := setUpTestMux()
|
|
|
|
ts := httptest.NewServer(mux)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL + "/good",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
|
|
|
ResponseStringMatch: "hit the good page",
|
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2017-02-01 14:21:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2017-05-09 23:21:04 +00:00
|
|
|
value, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusOK, value)
|
|
|
|
value, ok = acc.IntField("http_response", "response_string_match")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, 1, value)
|
2017-06-06 20:39:07 +00:00
|
|
|
response_value, ok := acc.StringField("http_response", "result_type")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, "success", response_value)
|
2017-05-09 23:21:04 +00:00
|
|
|
_, ok = acc.FloatField("http_response", "response_time")
|
|
|
|
require.True(t, ok)
|
2017-02-01 14:21:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestStringMatchJson(t *testing.T) {
|
|
|
|
mux := setUpTestMux()
|
|
|
|
ts := httptest.NewServer(mux)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL + "/jsonresponse",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
|
|
|
ResponseStringMatch: "\"service_status\": \"up\"",
|
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2017-02-01 14:21:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2017-05-09 23:21:04 +00:00
|
|
|
value, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusOK, value)
|
|
|
|
value, ok = acc.IntField("http_response", "response_string_match")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, 1, value)
|
2017-06-06 20:39:07 +00:00
|
|
|
response_value, ok := acc.StringField("http_response", "result_type")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, "success", response_value)
|
2017-05-09 23:21:04 +00:00
|
|
|
_, ok = acc.FloatField("http_response", "response_time")
|
|
|
|
require.True(t, ok)
|
2017-02-01 14:21:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestStringMatchFail(t *testing.T) {
|
|
|
|
mux := setUpTestMux()
|
|
|
|
ts := httptest.NewServer(mux)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL + "/good",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
|
|
|
ResponseStringMatch: "hit the bad page",
|
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2017-02-01 14:21:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2017-05-09 23:21:04 +00:00
|
|
|
value, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, http.StatusOK, value)
|
|
|
|
value, ok = acc.IntField("http_response", "response_string_match")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, 0, value)
|
2017-06-06 20:39:07 +00:00
|
|
|
response_value, ok := acc.StringField("http_response", "result_type")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, "response_string_mismatch", response_value)
|
2017-05-09 23:21:04 +00:00
|
|
|
_, ok = acc.FloatField("http_response", "response_time")
|
|
|
|
require.True(t, ok)
|
2017-02-01 14:21:08 +00:00
|
|
|
}
|
|
|
|
|
2016-04-04 02:20:07 +00:00
|
|
|
func TestTimeout(t *testing.T) {
|
2017-05-09 23:21:04 +00:00
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("Skipping test with sleep in short mode.")
|
|
|
|
}
|
|
|
|
|
2016-04-04 02:20:07 +00:00
|
|
|
mux := setUpTestMux()
|
|
|
|
ts := httptest.NewServer(mux)
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
h := &HTTPResponse{
|
|
|
|
Address: ts.URL + "/twosecondnap",
|
|
|
|
Body: "{ 'test': 'data'}",
|
|
|
|
Method: "GET",
|
2017-05-16 22:25:30 +00:00
|
|
|
ResponseTimeout: internal.Duration{Duration: time.Second},
|
2016-04-07 01:57:49 +00:00
|
|
|
Headers: map[string]string{
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
},
|
2016-04-04 02:20:07 +00:00
|
|
|
FollowRedirects: true,
|
|
|
|
}
|
2017-05-09 23:21:04 +00:00
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := h.Gather(&acc)
|
2017-06-06 20:39:07 +00:00
|
|
|
require.NoError(t, err)
|
2017-05-09 23:21:04 +00:00
|
|
|
|
2017-06-06 20:39:07 +00:00
|
|
|
_, ok := acc.IntField("http_response", "http_response_code")
|
|
|
|
require.False(t, ok)
|
|
|
|
response_value, ok := acc.StringField("http_response", "result_type")
|
|
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, "timeout", response_value)
|
|
|
|
_, ok = acc.FloatField("http_response", "response_time")
|
2017-05-09 23:21:04 +00:00
|
|
|
require.False(t, ok)
|
2016-04-04 02:20:07 +00:00
|
|
|
}
|