Archived
Wait out a failed lookup of the registry's name in a build, and say it was the resolver (issue 1748)
mesh/delivery delivered
mesh/check pass 0b312218f90f on c834e4f82137 | unit 1762 run, 0 kept, 4 skipped | integration 3040 run, 0 kept, 16 skipped | over bound: integration (…
mesh/delivery delivered
mesh/check pass 0b312218f90f on c834e4f82137 | unit 1762 run, 0 kept, 4 skipped | integration 3040 run, 0 kept, 16 skipped | over bound: integration (…
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -152,3 +153,67 @@ func TestAnImagePushWaitsForARegistryHeldStill(t *testing.T) {
|
||||
type errorString string
|
||||
|
||||
func (e errorString) Error() string { return string(e) }
|
||||
|
||||
// A resolver that does not answer for a moment (novox/hq issue 1748): a lookup of the registry's name that
|
||||
// timed out failed the build at once, though the same name resolved a second later.
|
||||
|
||||
const lookupTimeout = "Head \"http://novox.internal:5100/v2/x/blobs/sha256:1\": dial tcp: lookup novox.internal on 10.10.0.3:53: " +
|
||||
"read udp 10.10.0.3:44790->10.10.0.3:53: i/o timeout"
|
||||
|
||||
type lookupTimedOut struct{}
|
||||
|
||||
func (lookupTimedOut) Error() string { return lookupTimeout }
|
||||
|
||||
func TestABuildWaitsOutAResolverThatDoesNotAnswerAndGoesOn(t *testing.T) { // 1748/AC1
|
||||
waitingFor(t, 5*time.Second)
|
||||
said := saying(t)
|
||||
calls := 0
|
||||
err := waitForRegistry(context.Background(), "novox.internal:5100", "HEAD /v2/x", func() error {
|
||||
calls++
|
||||
if calls < 3 {
|
||||
return lookupTimedOut{}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("a lookup timing out twice failed the build: %v", err)
|
||||
}
|
||||
if calls != 3 {
|
||||
t.Errorf("tried %d times, want 3", calls)
|
||||
}
|
||||
log := strings.Join(said(), "\n")
|
||||
if !strings.Contains(log, "resolver did not answer") || !strings.Contains(log, "answers again") {
|
||||
t.Errorf("the build's log does not say the resolver was waited for, and that it came back:\n%s", log)
|
||||
}
|
||||
}
|
||||
|
||||
func TestABuildFailsNamingTheResolverWhenItDoesNotAnswerPastTheBound(t *testing.T) { // 1748/AC2
|
||||
waitingFor(t, 100*time.Millisecond)
|
||||
saying(t)
|
||||
started := time.Now()
|
||||
err := waitForRegistry(context.Background(), "novox.internal:5100", "HEAD /v2/x", func() error { return lookupTimedOut{} })
|
||||
if err == nil {
|
||||
t.Fatal("a resolver that never answered let the build go on")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "resolver did not answer") || !strings.Contains(err.Error(), "i/o timeout") {
|
||||
t.Errorf("the failure does not name the resolver: %v", err)
|
||||
}
|
||||
if strings.Contains(err.Error(), "refused every connection") {
|
||||
t.Errorf("the failure blames a refusal: %v", err)
|
||||
}
|
||||
if waited := time.Since(started); waited < 100*time.Millisecond {
|
||||
t.Errorf("failed after %s, before the bound", waited)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnErrorThatIsNeitherARefusalNorALookupFailsAtOnce(t *testing.T) { // 1748/AC3
|
||||
waitingFor(t, 5*time.Second)
|
||||
calls := 0
|
||||
err := waitForRegistry(context.Background(), "novox.internal:5100", "HEAD /v2/x", func() error {
|
||||
calls++
|
||||
return errors.New("401 unauthorized")
|
||||
})
|
||||
if err == nil || calls != 1 {
|
||||
t.Fatalf("err %v after %d calls, want a failure at once", err, calls)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user