func TestHttpMetricUpdate(t *testing.T) {
	hmr := NewHttpMetricReporter()

	// add datapoint
	hm := &HttpMetric{gogrinder.Meta{"01_tc", "01_01_ts", 0, 0, gogrinder.Timestamp(time.Now()),
		gogrinder.Elapsed(600 * time.Millisecond), "something is wrong!"},
		gogrinder.Elapsed(500 * time.Millisecond), 10240, http.StatusOK}
	hmr.Update(hm)

	// check that datapoint was reported
	if exp, got := 600.0, readSummaryVec(hmr.elapsed,
		prometheus.Labels{"teststep": "01_01_ts"})[0].GetValue(); exp != got {
		t.Errorf("Expected elapsed %d, got %d.", exp, got)
	}
	if exp, got := 500.0, readSummaryVec(hmr.firstByte,
		prometheus.Labels{"teststep": "01_01_ts"})[0].GetValue(); exp != got {
		t.Errorf("Expected firstByte %d, got %d.", exp, got)
	}
	if exp, got := 10.0, readSummaryVec(hmr.bytes,
		prometheus.Labels{"teststep": "01_01_ts"})[0].GetValue(); exp != got {
		t.Errorf("Expected kb %d, got %d.", exp, got)
	}
	if exp, got := 1.0, readCounterVec(hmr.error,
		prometheus.Labels{"teststep": "01_01_ts"}); exp != got {
		t.Errorf("Expected error counter %f, got %f.", exp, got)
	}
	if exp, got := 1.0, readCounterVec(hmr.code,
		prometheus.Labels{"teststep": "01_01_ts", "code": "200"}); exp != got {
		t.Errorf("Expected code counter %f, got %f.", exp, got)
	}
}
Exemple #2
0
func (fb *metricReader) Read(p []byte) (n int, err error) {
	if fb.firstByteAfter == gogrinder.Elapsed(0) {
		fb.readFrom.ReadByte()
		fb.firstByteAfter = gogrinder.Elapsed(time.Now().Sub(fb.start))
		fb.readFrom.UnreadByte()
	}
	n, err = fb.readFrom.Read(p)
	fb.bytes += n
	return
}
Exemple #3
0
// RAW
func DoRaw(c *http.Client, r *http.Request, m *gogrinder.Meta) ([]byte, http.Header, *HttpMetric) {
	hm := &HttpMetric{*m, gogrinder.Elapsed(0), 0, 421} // http status Misdirected Request

	resp, err := c.Do(r)
	if err != nil {
		hm.Error += err.Error()
	}
	if resp != nil {
		defer resp.Body.Close()
		mr := newMetricReader(resp.Body)

		// read the response body
		raw, err := ioutil.ReadAll(mr)
		if err != nil {
			hm.Error += err.Error()
		}

		hm.FirstByte = mr.firstByteAfter
		hm.Bytes = mr.bytes
		hm.Code = resp.StatusCode
		return raw, resp.Header, hm
	}

	return nil, nil, hm
}
Exemple #4
0
func TestFirstByteAfterReader(t *testing.T) {
	time.Freeze(time.Now())
	defer time.Unfreeze()
	tr := testReader{}
	fbr := newMetricReader(tr)

	b1 := make([]byte, 4)
	fbr.Read(b1)

	body := string(b1)
	if !(body == "mark") {
		t.Fatalf("Read buffer was expected '%s', but was: '%v'", "mark", body)
	}
	if fbr.firstByteAfter != gogrinder.Elapsed(55*time.Millisecond) {
		t.Fatalf("First byte was expected after 55 ms but was: %v", fbr.firstByteAfter)
	}

	// read a second time
	b2 := make([]byte, 4)
	fbr.Read(b2)
	body = string(b2)
	if body != "fink" {
		t.Fatalf("Read buffer was expected '%s', but was: '%v'", "fink", body)
	}
}
Exemple #5
0
// JSON
func DoJson(c *http.Client, r *http.Request, m *gogrinder.Meta) (map[string]interface{}, http.Header, *HttpMetric) {
	hm := &HttpMetric{*m, gogrinder.Elapsed(0), 0, 421} // http status Misdirected Request
	resp, err := c.Do(r)
	if err != nil {
		hm.Error += err.Error()
	}
	if resp != nil {
		defer resp.Body.Close()
		mr := newMetricReader(resp.Body)

		// read the response body and parse as json
		raw, err := ioutil.ReadAll(mr)
		if err != nil {
			m.Error += err.Error()
		}
		doc := make(map[string]interface{})
		if len(raw) > 0 {
			if raw[0] == '[' {
				// a REST service response to be an array does not seem to be a good idea:
				// http://stackoverflow.com/questions/12293979/how-do-i-return-a-json-array-with-bottle
				// many applications do this anyway...
				// so for now we need a workaround:
				var array []interface{}
				err = json.Unmarshal(raw, &array)
				doc["data"] = array
			} else {
				err = json.Unmarshal(raw, &doc)
			}
			if err != nil {
				m.Error += err.Error()
			}
		}

		hm.FirstByte = mr.firstByteAfter
		hm.Bytes = mr.bytes
		hm.Code = resp.StatusCode
		return doc, resp.Header, hm
	}

	return nil, nil, hm
}
Exemple #6
0
// DOC
func Do(c *http.Client, r *http.Request, m *gogrinder.Meta) (*goquery.Document, http.Header, *HttpMetric) {
	hm := &HttpMetric{*m, gogrinder.Elapsed(0), 0, 421} // http status Misdirected Request
	resp, err := c.Do(r)
	if err != nil {
		hm.Error += err.Error()
	}
	if resp != nil {
		defer resp.Body.Close()
		mr := newMetricReader(resp.Body)

		// read the response body and parse into document
		doc, err := goquery.NewDocumentFromReader(mr)
		if err != nil {
			m.Error += err.Error()
		}

		hm.FirstByte = mr.firstByteAfter
		hm.Bytes = mr.bytes
		hm.Code = resp.StatusCode
		return doc, resp.Header, hm
	}

	return nil, nil, hm
}
Exemple #7
0
func newMetricReader(readFrom io.Reader) *metricReader {
	// wrap into buffered reader
	return &metricReader{0, time.Now(), gogrinder.Elapsed(0), bufio.NewReader(readFrom)}
}