github.com/uber/kraken@v0.1.4/tracker/trackerserver/announce_test.go (about)

     1  // Copyright (c) 2016-2019 Uber Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package trackerserver
    15  
    16  import (
    17  	"errors"
    18  	"fmt"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/uber/kraken/core"
    23  	"github.com/uber/kraken/lib/hashring"
    24  	"github.com/uber/kraken/lib/hostlist"
    25  	"github.com/uber/kraken/tracker/announceclient"
    26  	"github.com/uber/kraken/utils/testutil"
    27  
    28  	"github.com/golang/mock/gomock"
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func newAnnounceClient(pctx core.PeerContext, addr string) announceclient.Client {
    33  	return announceclient.New(pctx, hashring.NoopPassiveRing(hostlist.Fixture(addr)), nil)
    34  }
    35  
    36  func TestAnnounceSinglePeerResponse(t *testing.T) {
    37  	for _, version := range []int{announceclient.V1, announceclient.V2} {
    38  		t.Run(fmt.Sprintf("V%d", version), func(t *testing.T) {
    39  			require := require.New(t)
    40  
    41  			config := Config{AnnounceInterval: 5 * time.Second}
    42  
    43  			mocks, cleanup := newServerMocks(t, config)
    44  			defer cleanup()
    45  
    46  			addr, stop := testutil.StartServer(mocks.handler())
    47  			defer stop()
    48  
    49  			blob := core.NewBlobFixture()
    50  			pctx := core.PeerContextFixture()
    51  
    52  			client := newAnnounceClient(pctx, addr)
    53  
    54  			peers := []*core.PeerInfo{core.PeerInfoFixture()}
    55  
    56  			mocks.originStore.EXPECT().GetOrigins(blob.Digest).Return(nil, nil)
    57  			mocks.peerStore.EXPECT().GetPeers(
    58  				blob.MetaInfo.InfoHash(), gomock.Any()).Return(peers, nil)
    59  			mocks.peerStore.EXPECT().UpdatePeer(
    60  				blob.MetaInfo.InfoHash(), core.PeerInfoFromContext(pctx, false)).Return(nil)
    61  
    62  			result, interval, err := client.Announce(
    63  				blob.Digest, blob.MetaInfo.InfoHash(), false, version)
    64  			require.NoError(err)
    65  			require.Equal(peers, result)
    66  			require.Equal(config.AnnounceInterval, interval)
    67  		})
    68  	}
    69  }
    70  
    71  func TestAnnounceUnavailablePeerStoreCanStillProvideOrigins(t *testing.T) {
    72  	require := require.New(t)
    73  
    74  	mocks, cleanup := newServerMocks(t, Config{})
    75  	defer cleanup()
    76  
    77  	addr, stop := testutil.StartServer(mocks.handler())
    78  	defer stop()
    79  
    80  	pctx := core.PeerContextFixture()
    81  	blob := core.NewBlobFixture()
    82  	origins := []*core.PeerInfo{core.OriginPeerInfoFixture()}
    83  
    84  	client := newAnnounceClient(pctx, addr)
    85  
    86  	storeErr := errors.New("some storage error")
    87  
    88  	mocks.peerStore.EXPECT().UpdatePeer(
    89  		blob.MetaInfo.InfoHash(), core.PeerInfoFromContext(pctx, false)).Return(storeErr)
    90  	mocks.peerStore.EXPECT().GetPeers(
    91  		blob.MetaInfo.InfoHash(), gomock.Any()).Return(nil, storeErr)
    92  	mocks.originStore.EXPECT().GetOrigins(blob.Digest).Return(origins, nil)
    93  
    94  	result, _, err := client.Announce(
    95  		blob.Digest, blob.MetaInfo.InfoHash(), false, announceclient.V2)
    96  	require.NoError(err)
    97  	require.Equal(origins, result)
    98  }
    99  
   100  func TestAnnouceUnavailableOriginClusterCanStillProvidePeers(t *testing.T) {
   101  	require := require.New(t)
   102  
   103  	mocks, cleanup := newServerMocks(t, Config{})
   104  	defer cleanup()
   105  
   106  	addr, stop := testutil.StartServer(mocks.handler())
   107  	defer stop()
   108  
   109  	pctx := core.PeerContextFixture()
   110  	blob := core.NewBlobFixture()
   111  
   112  	client := newAnnounceClient(pctx, addr)
   113  
   114  	peers := []*core.PeerInfo{core.PeerInfoFixture()}
   115  
   116  	mocks.peerStore.EXPECT().UpdatePeer(
   117  		blob.MetaInfo.InfoHash(), core.PeerInfoFromContext(pctx, false)).Return(nil)
   118  	mocks.peerStore.EXPECT().GetPeers(
   119  		blob.MetaInfo.InfoHash(), gomock.Any()).Return(peers, nil)
   120  	mocks.originStore.EXPECT().GetOrigins(blob.Digest).Return(nil, errors.New("some error"))
   121  
   122  	result, _, err := client.Announce(
   123  		blob.Digest, blob.MetaInfo.InfoHash(), false, announceclient.V2)
   124  	require.NoError(err)
   125  	require.Equal(peers, result)
   126  }
   127  
   128  func TestAnnounceRequestGetDigestBackwardsCompatibility(t *testing.T) {
   129  	d := core.DigestFixture()
   130  	h := core.InfoHashFixture()
   131  	p := core.PeerInfoFixture()
   132  
   133  	tests := []struct {
   134  		desc    string
   135  		request *announceclient.Request
   136  	}{
   137  		{
   138  			"name only (old version)",
   139  			&announceclient.Request{
   140  				Name:     d.Hex(),
   141  				InfoHash: h,
   142  				Peer:     p,
   143  			},
   144  		}, {
   145  			"digest and name (current version)",
   146  			&announceclient.Request{
   147  				Name:     d.Hex(),
   148  				Digest:   &d,
   149  				InfoHash: h,
   150  				Peer:     p,
   151  			},
   152  		}, {
   153  			"digest only (future version)",
   154  			&announceclient.Request{
   155  				Digest:   &d,
   156  				InfoHash: h,
   157  				Peer:     p,
   158  			},
   159  		},
   160  	}
   161  	for _, test := range tests {
   162  		t.Run(test.desc, func(t *testing.T) {
   163  			require := require.New(t)
   164  
   165  			result, err := test.request.GetDigest()
   166  			require.NoError(err)
   167  			require.Equal(d, result)
   168  		})
   169  	}
   170  }