backend: Faster remote backend tests

The remote backend tests spent most of their execution time sleeping in
various polling and backoff waits. This is unnecessary when testing
against a mock server, so reduce all of these delays when under test to
much lower values.

Only one remaining test has an artificial delay: verifying the discovery
of services against an unknown hostname. This times out at DNS
resolution, which is more difficult to fix than seems worth it at this
time.
This commit is contained in:
Alisdair McDiarmid 2020-11-18 15:35:48 -05:00
parent db82b80c9d
commit eee57280f6
6 changed files with 31 additions and 15 deletions

View File

@ -542,8 +542,8 @@ func TestRemote_applyApprovedExternally(t *testing.T) {
t.Fatalf("error starting operation: %v", err)
}
// Wait 2 seconds to make sure the run started.
time.Sleep(2 * time.Second)
// Wait 50 milliseconds to make sure the run started.
time.Sleep(50 * time.Millisecond)
wl, err := b.client.Workspaces.List(
ctx,
@ -617,8 +617,8 @@ func TestRemote_applyDiscardedExternally(t *testing.T) {
t.Fatalf("error starting operation: %v", err)
}
// Wait 2 seconds to make sure the run started.
time.Sleep(2 * time.Second)
// Wait 50 milliseconds to make sure the run started.
time.Sleep(50 * time.Millisecond)
wl, err := b.client.Workspaces.List(
ctx,
@ -871,7 +871,7 @@ func TestRemote_applyLockTimeout(t *testing.T) {
"approve": "yes",
})
op.StateLockTimeout = 5 * time.Second
op.StateLockTimeout = 50 * time.Millisecond
op.UIIn = input
op.UIOut = b.CLI
op.Workspace = backend.DefaultStateName
@ -887,8 +887,8 @@ func TestRemote_applyLockTimeout(t *testing.T) {
case <-sigint:
// Stop redirecting SIGINT signals.
signal.Stop(sigint)
case <-time.After(10 * time.Second):
t.Fatalf("expected lock timeout after 5 seconds, waited 10 seconds")
case <-time.After(200 * time.Millisecond):
t.Fatalf("expected lock timeout after 50 milliseconds, waited 200 milliseconds")
}
if len(input.answers) != 2 {

View File

@ -24,6 +24,13 @@ var (
errRunOverridden = errors.New("overridden using the UI or API")
)
var (
backoffMin = 1000.0
backoffMax = 3000.0
runPollInterval = 3 * time.Second
)
// backoff will perform exponential backoff based on the iteration and
// limited by the provided min and max (in milliseconds) durations.
func backoff(min, max float64, iter int) time.Duration {
@ -43,7 +50,7 @@ func (b *Remote) waitForRun(stopCtx, cancelCtx context.Context, op *backend.Oper
return r, stopCtx.Err()
case <-cancelCtx.Done():
return r, cancelCtx.Err()
case <-time.After(backoff(1000, 3000, i)):
case <-time.After(backoff(backoffMin, backoffMax, i)):
// Timer up, show status
}
@ -260,7 +267,7 @@ func (b *Remote) costEstimate(stopCtx, cancelCtx context.Context, op *backend.Op
return stopCtx.Err()
case <-cancelCtx.Done():
return cancelCtx.Err()
case <-time.After(1 * time.Second):
case <-time.After(backoff(backoffMin, backoffMax, i)):
}
// Retrieve the cost estimate to get its current status.
@ -454,7 +461,7 @@ func (b *Remote) confirm(stopCtx context.Context, op *backend.Operation, opts *t
return
case <-stopCtx.Done():
return
case <-time.After(3 * time.Second):
case <-time.After(runPollInterval):
// Retrieve the run again to get its current status.
r, err := b.client.Runs.Read(stopCtx, r.ID)
if err != nil {

View File

@ -360,7 +360,7 @@ func (m *mockLogReader) Read(l []byte) (int, error) {
if written, err := m.read(l); err != io.ErrNoProgress {
return written, err
}
time.Sleep(500 * time.Millisecond)
time.Sleep(1 * time.Millisecond)
}
}

View File

@ -20,6 +20,8 @@ import (
"github.com/hashicorp/terraform/tfdiags"
)
var planConfigurationVersionsPollInterval = 500 * time.Millisecond
func (b *Remote) opPlan(stopCtx, cancelCtx context.Context, op *backend.Operation, w *tfe.Workspace) (*tfe.Run, error) {
log.Printf("[INFO] backend/remote: starting Plan operation")
@ -213,7 +215,7 @@ in order to capture the filesystem context the remote workspace expects:
return nil, context.Canceled
case <-cancelCtx.Done():
return nil, context.Canceled
case <-time.After(500 * time.Millisecond):
case <-time.After(planConfigurationVersionsPollInterval):
cv, err = b.client.ConfigurationVersions.Read(stopCtx, cv.ID)
if err != nil {
return nil, generalError("Failed to retrieve configuration version", err)

View File

@ -620,7 +620,7 @@ func TestRemote_planLockTimeout(t *testing.T) {
"approve": "yes",
})
op.StateLockTimeout = 5 * time.Second
op.StateLockTimeout = 50 * time.Millisecond
op.UIIn = input
op.UIOut = b.CLI
op.Workspace = backend.DefaultStateName
@ -636,8 +636,8 @@ func TestRemote_planLockTimeout(t *testing.T) {
case <-sigint:
// Stop redirecting SIGINT signals.
signal.Stop(sigint)
case <-time.After(10 * time.Second):
t.Fatalf("expected lock timeout after 5 seconds, waited 10 seconds")
case <-time.After(200 * time.Millisecond):
t.Fatalf("expected lock timeout after 50 milliseconds, waited 200 milliseconds")
}
if len(input.answers) != 2 {

View File

@ -4,6 +4,7 @@ import (
"flag"
"os"
"testing"
"time"
_ "github.com/hashicorp/terraform/internal/logging"
)
@ -14,5 +15,11 @@ func TestMain(m *testing.M) {
// Make sure TF_FORCE_LOCAL_BACKEND is unset
os.Unsetenv("TF_FORCE_LOCAL_BACKEND")
// Reduce delays to make tests run faster
backoffMin = 1.0
backoffMax = 1.0
planConfigurationVersionsPollInterval = 1 * time.Millisecond
runPollInterval = 1 * time.Millisecond
os.Exit(m.Run())
}