github.com/swisspost/terratest@v0.0.0-20230214120104-7ec6de2e1ae0/modules/http-helper/continuous.go (about)

     1  package http_helper
     2  
     3  import (
     4  	"crypto/tls"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/gruntwork-io/terratest/modules/logger"
     9  	"github.com/gruntwork-io/terratest/modules/testing"
    10  )
    11  
    12  type GetResponse struct {
    13  	StatusCode int
    14  	Body       string
    15  }
    16  
    17  // Continuously check the given URL every 1 second until the stopChecking channel receives a signal to stop.
    18  // This function will return a sync.WaitGroup that can be used to wait for the checking to stop, and a read only channel
    19  // to stream the responses for each check.
    20  // Note that the channel has a buffer of 1000, after which it will start to drop the send events
    21  func ContinuouslyCheckUrl(
    22  	t testing.TestingT,
    23  	url string,
    24  	stopChecking <-chan bool,
    25  	sleepBetweenChecks time.Duration,
    26  ) (*sync.WaitGroup, <-chan GetResponse) {
    27  	var wg sync.WaitGroup
    28  	wg.Add(1)
    29  	responses := make(chan GetResponse, 1000)
    30  	go func() {
    31  		defer wg.Done()
    32  		defer close(responses)
    33  		for {
    34  			select {
    35  			case <-stopChecking:
    36  				logger.Logf(t, "Got signal to stop downtime checks for URL %s.\n", url)
    37  				return
    38  			case <-time.After(sleepBetweenChecks):
    39  				statusCode, body, err := HttpGetE(t, url, &tls.Config{})
    40  				// Non-blocking send, defaulting to logging a warning if there is no channel reader
    41  				select {
    42  				case responses <- GetResponse{StatusCode: statusCode, Body: body}:
    43  					// do nothing since all we want to do is send the response
    44  				default:
    45  					logger.Logf(t, "WARNING: ContinuouslyCheckUrl responses channel buffer is full")
    46  				}
    47  				logger.Logf(t, "Got response %d and err %v from URL at %s", statusCode, err, url)
    48  				if err != nil {
    49  					// We use Errorf instead of Fatalf here because Fatalf is not goroutine safe, while Errorf is. Refer
    50  					// to the docs on `T`: https://godoc.org/testing#T
    51  					t.Errorf("Failed to make HTTP request to the URL at %s: %s\n", url, err.Error())
    52  				} else if statusCode != 200 {
    53  					// We use Errorf instead of Fatalf here because Fatalf is not goroutine safe, while Errorf is. Refer
    54  					// to the docs on `T`: https://godoc.org/testing#T
    55  					t.Errorf("Got a non-200 response (%d) from the URL at %s, which means there was downtime! Response body: %s", statusCode, url, body)
    56  				}
    57  			}
    58  		}
    59  	}()
    60  	return &wg, responses
    61  }