1
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
1.8 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
// QueuedHTTPTester represents an HTTP transport tester that uses
// queued writes
type QueuedHTTPTester struct {
client http.Client
url string
waitURL string
br *bytes.Reader
}
// NewHTTPTester returns an instantiated HTTP tester.
func NewQueuedHTTPTester(addr, path string) *QueuedHTTPTester {
return &QueuedHTTPTester{
client: http.Client{},
url: fmt.Sprintf("http://%s%s?queue", addr, path),
waitURL: fmt.Sprintf("http://%s%s?queue&wait", addr, path),
}
}
// String returns a string representation of the tester.
func (h *QueuedHTTPTester) String() string {
return h.url
}
// Prepare prepares the tester for execution.
func (h *QueuedHTTPTester) Prepare(stmt string, bSz int, _ bool) error {
s := make([]string, bSz)
for i := 0; i < len(s); i++ {
s[i] = stmt
}
b, err := json.Marshal(s)
if err != nil {
return err
}
h.br = bytes.NewReader(b)
return nil
}
// Once executes a single test request.
func (h *QueuedHTTPTester) Once() (time.Duration, error) {
h.br.Seek(0, io.SeekStart)
start := time.Now()
resp, err := h.client.Post(h.url, "application/json", h.br)
if err != nil {
return 0, err
}
defer resp.Body.Close()
_, err = io.ReadAll(resp.Body)
if err != nil {
return 0, err
}
if resp.StatusCode != http.StatusOK {
return 0, fmt.Errorf("received %s", resp.Status)
}
dur := time.Since(start)
return dur, nil
}
// Close closes the tester
func (h *QueuedHTTPTester) Close() error {
start := time.Now()
resp, err := h.client.Post(h.waitURL, "application/json", h.br)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Close() received %s", resp.Status)
}
fmt.Println("Queued tester wait request took", time.Since(start))
return nil
}