Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: uber/kraken
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: df51ec915891af166146d5968082e7f0b755eca8
Choose a base ref
..
head repository: uber/kraken
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b32b3e1fac1a27336b4fe9620892a266d59530da
Choose a head ref
Showing with 53 additions and 37 deletions.
  1. +5 −3 lib/backend/constants.go
  2. +7 −7 lib/backend/manager.go
  3. +41 −27 lib/backend/manager_test.go
8 changes: 5 additions & 3 deletions lib/backend/constants.go
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
package backend

import (
"github.com/uber/kraken/core"
"github.com/uber/kraken/utils/memsize"

"github.com/c2h5oh/datasize"
@@ -24,8 +25,9 @@ const (
DefaultBufferGuard datasize.ByteSize = 10 * datasize.MB
DefaultConcurrency int = 10
DefaultListMaxKeys int = 250
)

// Name and namespace of an empty blob used to check readiness.
ReadinessCheckBlobNamespace string = "readiness/blob"
ReadinessCheckBlobName string = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
var (
ReadinessCheckNamespace string = core.NamespaceFixture()
ReadinessCheckName string = core.DigestFixture().Hex()
)
14 changes: 7 additions & 7 deletions lib/backend/manager.go
Original file line number Diff line number Diff line change
@@ -14,11 +14,11 @@
package backend

import (
"bytes"
"errors"
"fmt"
"regexp"

"github.com/uber/kraken/lib/backend/backenderrors"
"github.com/uber/kraken/utils/bandwidth"
"github.com/uber/kraken/utils/log"

@@ -143,16 +143,16 @@ func (m *Manager) GetClient(namespace string) (Client, error) {
return nil, ErrNamespaceNotFound
}

// CheckReadiness returns whether the backends are ready (by trying to download a file).
// IsReady returns whether the backends are ready (reachable).
// A backend must be explicitly configured as required for readiness to be checked.
func (m *Manager) CheckReadiness() error {
for _, backend := range m.backends {
if !backend.mustReady {
for _, b := range m.backends {
if !b.mustReady {
continue
}
err := backend.client.Download(ReadinessCheckBlobNamespace, ReadinessCheckBlobName, bytes.NewBuffer([]byte{}))
if err != nil {
return fmt.Errorf("backend for namespace %s not ready: %s", backend.regexp.String(), err)
_, err := b.client.Stat(ReadinessCheckNamespace, ReadinessCheckName)
if err != nil && err != backenderrors.ErrBlobNotFound {
return fmt.Errorf("backend for namespace '%s' not ready: %s", b.regexp.String(), err)
}
}
return nil
68 changes: 41 additions & 27 deletions lib/backend/manager_test.go
Original file line number Diff line number Diff line change
@@ -14,11 +14,12 @@
package backend_test

import (
"bytes"
"errors"
"testing"

"github.com/uber-go/tally"
"github.com/uber/kraken/core"
"github.com/uber/kraken/lib/backend"
. "github.com/uber/kraken/lib/backend"
"github.com/uber/kraken/lib/backend/backenderrors"
"github.com/uber/kraken/lib/backend/namepath"
@@ -164,36 +165,40 @@ func TestManagerCheckReadiness(t *testing.T) {
n2 := "bar/*"

tests := []struct {
name string
mustReady1 bool
mustReady2 bool
mockDownload1Err error
mockDownload2Err error
expectedErr error
name string
mustReady1 bool
mustReady2 bool
mockStat1Err error
mockStat2Err error
expectedRes bool
expectedErr error
}{
{
name: "both required, both pass",
mustReady1: true,
mustReady2: true,
mockDownload1Err: nil,
mockDownload2Err: nil,
expectedErr: nil,
name: "both required, both pass (one with nil, one with NotFound)",
mustReady1: true,
mustReady2: true,
mockStat1Err: nil,
mockStat2Err: backenderrors.ErrBlobNotFound,
expectedRes: true,
expectedErr: nil,
},
{
name: "both required, only second fails",
mustReady1: true,
mustReady2: true,
mockDownload1Err: nil,
mockDownload2Err: errors.New("network error"),
expectedErr: errors.New("backend for namespace bar/* not ready: network error"),
name: "both required, only second fails",
mustReady1: true,
mustReady2: true,
mockStat1Err: nil,
mockStat2Err: errors.New("network error"),
expectedRes: false,
expectedErr: errors.New("backend for namespace 'bar/*' not ready: network error"),
},
{
name: "second required, only first fails",
mustReady1: false,
mustReady2: true,
mockDownload1Err: backenderrors.ErrBlobNotFound,
mockDownload2Err: nil,
expectedErr: nil,
name: "second required, only first fails",
mustReady1: false,
mustReady2: true,
mockStat1Err: errors.New("network error"),
mockStat2Err: backenderrors.ErrBlobNotFound,
expectedRes: true,
expectedErr: nil,
},
}

@@ -208,8 +213,17 @@ func TestManagerCheckReadiness(t *testing.T) {

m := ManagerFixture()

c1.EXPECT().Download(ReadinessCheckBlobNamespace, ReadinessCheckBlobName, bytes.NewBuffer([]byte{})).Return(tc.mockDownload1Err).AnyTimes()
c2.EXPECT().Download(ReadinessCheckBlobNamespace, ReadinessCheckBlobName, bytes.NewBuffer([]byte{})).Return(tc.mockDownload2Err).AnyTimes()
mockStat1 := &core.BlobInfo{}
mockStat2 := &core.BlobInfo{}
if tc.mockStat1Err != nil {
mockStat1 = nil
}
if tc.mockStat2Err != nil {
mockStat2 = nil
}

c1.EXPECT().Stat(backend.ReadinessCheckNamespace, backend.ReadinessCheckName).Return(mockStat1, tc.mockStat1Err).AnyTimes()
c2.EXPECT().Stat(backend.ReadinessCheckNamespace, backend.ReadinessCheckName).Return(mockStat2, tc.mockStat2Err).AnyTimes()

require.NoError(m.Register(n1, c1, tc.mustReady1))
require.NoError(m.Register(n2, c2, tc.mustReady2))