Beispiel #1
0
func TestLinearJitterBackoff(t *testing.T) {
	t.Parallel()
	c := pester.New()
	c.Backoff = pester.LinearJitterBackoff
	c.KeepLog = true

	nonExistantURL := "http://localhost:9000/foo"

	_, err := c.Get(nonExistantURL)
	if err == nil {
		t.Fatal("expected to get an error")
	}

	// in the event of an error, let's see what the logs were
	t.Log("\n", c.LogString())

	var startTime int64
	var delta int64
	for i, e := range c.ErrLog {
		switch i {
		case 0:
			startTime = e.Time.Unix()
		case 1:
			delta += 1
		case 2:
			delta += 2
		case 3:
			delta += 3
		}

		if got, want := e.Time.Unix(), startTime+delta; withinEpsilon(got, want, 0.0) {
			t.Errorf("got time %d, want %d (within epsilon of start time %d)", got, want, startTime)
		}
	}
}
Beispiel #2
0
// NewClient create a default client with resilient HTTP client.
func NewClient() Client {
	c := pester.New()
	c.Timeout = 5 * time.Minute
	c.MaxRetries = 8
	c.Backoff = pester.ExponentialBackoff
	return Client{doer: c}
}
func (m Marathon) getClient() *pester.Client {
	client := pester.New()
	client.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: m.NoVerifySsl,
		},
	}

	return client
}
Beispiel #4
0
func TestExponentialBackoff(t *testing.T) {
	t.Parallel()

	c := pester.New()
	c.MaxRetries = 4
	c.Backoff = pester.ExponentialBackoff
	c.KeepLog = true

	nonExistantURL := "http://localhost:9000/foo"

	_, err := c.Get(nonExistantURL)
	if err == nil {
		t.Fatal("expected to get an error")
	}

	// in the event of an error, let's see what the logs were
	t.Log("\n", c.LogString())

	if got, want := len(c.ErrLog), c.MaxRetries; got != want {
		t.Fatalf("got %d errors, want %d", got, want)
	}

	var startTime int64
	var delta int64
	for i, e := range c.ErrLog {
		switch i {
		case 0:
			startTime = e.Time.Unix()
		case 1:
			delta += 1
		case 2:
			delta += 2
		case 3:
			delta += 4
		}
		if got, want := e.Time.Unix(), startTime+delta; got != want {
			t.Errorf("got time %d, want %d (%d greater than start time %d)", got, want, delta, startTime)
		}
	}
}
Beispiel #5
0
func TestConcurrentRequests(t *testing.T) {
	t.Parallel()

	c := pester.New()
	c.Concurrency = 4
	c.KeepLog = true

	nonExistantURL := "http://localhost:9000/foo"

	_, err := c.Get(nonExistantURL)
	if err == nil {
		t.Fatal("expected to get an error")
	}

	// in the event of an error, let's see what the logs were
	t.Log("\n", c.LogString())

	if got, want := len(c.ErrLog), c.Concurrency*c.MaxRetries; got != want {
		t.Error("got %d attempts, want %d", got, want)
	}

}
Beispiel #6
0
func TestDefaultBackoff(t *testing.T) {
	t.Parallel()

	c := pester.New()
	c.KeepLog = true

	nonExistantURL := "http://localhost:9000/foo"

	_, err := c.Get(nonExistantURL)
	if err == nil {
		t.Fatal("expected to get an error")
	}

	// in the event of an error, let's see what the logs were
	t.Log("\n", c.LogString())

	if got, want := c.Concurrency, 1; got != want {
		t.Error("got %d, want %d for concurrency", got, want)
	}

	if got, want := len(c.ErrLog), c.MaxRetries; got != want {
		t.Fatalf("got %d errors, want %d", got, want)
	}

	var startTime int64
	for i, e := range c.ErrLog {
		if i == 0 {
			startTime = e.Time.Unix()
			continue
		}
		if got, want := e.Time.Unix(), startTime+int64(i); got != want {
			t.Errorf("got time %d, want %d (%d greater than start time %d)", got, want, i, startTime)
		}
	}

}
Beispiel #7
0
func main() {
	// set everything up
	var port int
	flag.IntVar(&port, "port", 9000, "set the port for the rando response server")
	flag.Parse()

	log.Printf("Starting a rando response server on :%d ...\n\n", port)

	go func() {
		http.HandleFunc("/", randoHandler)
		log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
	}()

	//////////////////////////////////////////////////////
	// begin running through each of the pestor methods //
	//////////////////////////////////////////////////////

	log.Println("> pester.Get default")
	{ // drop in replacement for http.Get and other client methods
		resp, err := pester.Get(fmt.Sprintf("http://localhost:%d", port))
		if err != nil {
			log.Fatalf("error GETing default", err)
		}
		defer resp.Body.Close()

		log.Printf("GET :%d %s \n\n", port, resp.Status)
	}

	log.Println("> pester.Get with set backoff stategy, concurrency and retries increased")
	{ // control the resiliency
		client := pester.New()
		client.Concurrency = 3
		client.MaxRetries = 5
		client.Backoff = pester.ExponentialJitterBackoff
		client.KeepLog = true

		resp, err := client.Get(fmt.Sprintf("http://localhost:%d", port))
		if err != nil {
			log.Fatalf("error GETing with all options, %s\n\n", client.LogString())
		}
		defer resp.Body.Close()

		log.Printf("Exponential Jitter Backoff :%d %s [request %d, retry %d]\n\n", port, resp.Status, client.SuccessReqNum, client.SuccessRetryNum)
	}

	log.Println("> pester.Get with custom backoff strategy")
	{ // set a custom backoff strategy
		client := pester.New()
		client.Backoff = func(retry int) time.Duration {
			return time.Duration(retry*200) * time.Millisecond
		}
		client.Timeout = 5 * time.Second
		client.KeepLog = true

		resp, err := client.Get(fmt.Sprintf("http://localhost:%d", port))
		if err != nil {
			log.Fatalf("error GETing custom backoff\n\n", client.LogString())
		}
		defer resp.Body.Close()

		log.Printf("Custom backoff :%d %s [request %d, retry %d]\n\n", port, resp.Status, client.SuccessReqNum, client.SuccessRetryNum)
	}

	log.Println("> pester.Post with defaults")
	{ // use the pester.Post drop in replacement
		resp, err := pester.Post(fmt.Sprintf("http://localhost:%d", port), "text/plain", strings.NewReader("data"))
		if err != nil {
			log.Fatalf("error POSTing with defaults - %v\n\n", err)
		}
		defer resp.Body.Close()

		log.Printf("POST :%d %s\n\n", port, resp.Status)
	}

	log.Println("> pester.Head with defaults")
	{ // use the pester.Head drop in replacement
		resp, err := pester.Head(fmt.Sprintf("http://localhost:%d", port))
		if err != nil {
			log.Fatalf("error HEADing with defaults - %v\n\n", err)
		}
		defer resp.Body.Close()

		log.Printf("HEAD :%d %s\n\n", port, resp.Status)
	}

	log.Println("> pester.PostForm with defaults")
	{ // use the pester.Head drop in replacement
		resp, err := pester.PostForm(fmt.Sprintf("http://localhost:%d", port), url.Values{"param1": []string{"val1a", "val1b"}, "param2": []string{"val2"}})
		if err != nil {
			log.Fatalf("error POSTing a form with defaults - %v\n\n", err)
		}
		defer resp.Body.Close()

		log.Printf("POST (form) :%d %s\n\n", port, resp.Status)
	}

	log.Println("> pester Do with POST")
	{ // use the pester version of http.Client.Do
		req, err := http.NewRequest("POST", fmt.Sprintf("http://localhost:%d", port), strings.NewReader("data"))
		if err != nil {
			log.Fatal("Unable to create a new http request", err)
		}
		resp, err := pester.Do(req)
		if err != nil {
			log.Fatalf("error POSTing with Do() - %v\n\n", err)
		}
		defer resp.Body.Close()

		log.Printf("Do() POST :%d %s\n\n", port, resp.Status)
	}

}