mirror of
https://github.com/elyby/chrly.git
synced 2024-12-24 14:09:56 +05:30
211 lines
5.9 KiB
Go
211 lines
5.9 KiB
Go
package mojang
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
var awaitDelay = 20 * time.Millisecond
|
|
|
|
type mojangUsernamesToUuidsRequestMock struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (o *mojangUsernamesToUuidsRequestMock) UsernamesToUuids(ctx context.Context, usernames []string) ([]*ProfileInfo, error) {
|
|
args := o.Called(ctx, usernames)
|
|
var result []*ProfileInfo
|
|
if casted, ok := args.Get(0).([]*ProfileInfo); ok {
|
|
result = casted
|
|
}
|
|
|
|
return result, args.Error(1)
|
|
}
|
|
|
|
type batchUuidsProviderGetUuidResult struct {
|
|
Result *ProfileInfo
|
|
Error error
|
|
}
|
|
|
|
type batchUuidsProviderTestSuite struct {
|
|
suite.Suite
|
|
|
|
Provider *BatchUuidsProvider
|
|
|
|
MojangApi *mojangUsernamesToUuidsRequestMock
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) SetupTest() {
|
|
s.MojangApi = &mojangUsernamesToUuidsRequestMock{}
|
|
s.Provider = NewBatchUuidsProvider(
|
|
s.MojangApi.UsernamesToUuids,
|
|
3,
|
|
awaitDelay,
|
|
false,
|
|
)
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) TearDownTest() {
|
|
s.MojangApi.AssertExpectations(s.T())
|
|
s.Provider.StopQueue()
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) GetUuidAsync(username string) <-chan *batchUuidsProviderGetUuidResult {
|
|
return s.GetUuidAsyncWithCtx(context.Background(), username)
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) GetUuidAsyncWithCtx(ctx context.Context, username string) <-chan *batchUuidsProviderGetUuidResult {
|
|
startedChan := make(chan any)
|
|
c := make(chan *batchUuidsProviderGetUuidResult, 1)
|
|
go func() {
|
|
close(startedChan)
|
|
profile, err := s.Provider.GetUuid(ctx, username)
|
|
c <- &batchUuidsProviderGetUuidResult{
|
|
Result: profile,
|
|
Error: err,
|
|
}
|
|
close(c)
|
|
}()
|
|
|
|
<-startedChan
|
|
|
|
return c
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) TestGetUuidForFewUsernamesSuccessfully() {
|
|
expectedUsernames := []string{"username1", "username2"}
|
|
expectedResult1 := &ProfileInfo{Id: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", Name: "username1"}
|
|
expectedResult2 := &ProfileInfo{Id: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", Name: "username2"}
|
|
|
|
s.MojangApi.On("UsernamesToUuids", mock.Anything, expectedUsernames).Once().Return([]*ProfileInfo{
|
|
expectedResult1,
|
|
expectedResult2,
|
|
}, nil)
|
|
|
|
chan1 := s.GetUuidAsync("username1")
|
|
chan2 := s.GetUuidAsync("username2")
|
|
|
|
s.Require().Empty(chan1)
|
|
s.Require().Empty(chan2)
|
|
|
|
time.Sleep(time.Duration(float64(awaitDelay) * 1.5))
|
|
|
|
result1 := <-chan1
|
|
result2 := <-chan2
|
|
|
|
s.Require().NoError(result1.Error)
|
|
s.Require().Equal(expectedResult1, result1.Result)
|
|
|
|
s.Require().NoError(result2.Error)
|
|
s.Require().Equal(expectedResult2, result2.Result)
|
|
|
|
// Await a few more iterations to ensure, that no requests will be performed when there are no additional tasks
|
|
time.Sleep(awaitDelay * 3)
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) TestGetUuidForManyUsernamesSplitByMultipleIterations() {
|
|
var emptyResponse []string
|
|
|
|
s.MojangApi.On("UsernamesToUuids", mock.Anything, []string{"username1", "username2", "username3"}).Once().Return(emptyResponse, nil)
|
|
s.MojangApi.On("UsernamesToUuids", mock.Anything, []string{"username4"}).Once().Return(emptyResponse, nil)
|
|
|
|
resultChan1 := s.GetUuidAsync("username1")
|
|
resultChan2 := s.GetUuidAsync("username2")
|
|
resultChan3 := s.GetUuidAsync("username3")
|
|
resultChan4 := s.GetUuidAsync("username4")
|
|
|
|
time.Sleep(time.Duration(float64(awaitDelay) * 1.5))
|
|
|
|
s.Require().NotEmpty(resultChan1)
|
|
s.Require().NotEmpty(resultChan2)
|
|
s.Require().NotEmpty(resultChan3)
|
|
s.Require().Empty(resultChan4)
|
|
|
|
time.Sleep(time.Duration(float64(awaitDelay) * 1.5))
|
|
|
|
s.Require().NotEmpty(resultChan4)
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) TestGetUuidForManyUsernamesWhenOneOfContextIsDeadlined() {
|
|
var emptyResponse []string
|
|
|
|
s.MojangApi.On("UsernamesToUuids", mock.Anything, []string{"username1", "username2", "username4"}).Once().Return(emptyResponse, nil)
|
|
|
|
ctx, cancelCtx := context.WithCancel(context.Background())
|
|
|
|
resultChan1 := s.GetUuidAsync("username1")
|
|
resultChan2 := s.GetUuidAsync("username2")
|
|
resultChan3 := s.GetUuidAsyncWithCtx(ctx, "username3")
|
|
resultChan4 := s.GetUuidAsync("username4")
|
|
|
|
cancelCtx()
|
|
|
|
time.Sleep(time.Duration(float64(awaitDelay) * 0.5))
|
|
|
|
s.Empty(resultChan1)
|
|
s.Empty(resultChan2)
|
|
s.NotEmpty(resultChan3, "canceled context must immediately release the job")
|
|
s.Empty(resultChan4)
|
|
|
|
result3 := <-resultChan3
|
|
s.Nil(result3.Result)
|
|
s.ErrorIs(result3.Error, context.Canceled)
|
|
|
|
time.Sleep(awaitDelay)
|
|
|
|
s.Require().NotEmpty(resultChan1)
|
|
s.Require().NotEmpty(resultChan2)
|
|
s.Require().NotEmpty(resultChan4)
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) TestGetUuidForManyUsernamesFireOnFull() {
|
|
s.Provider.fireOnFull = true
|
|
|
|
var emptyResponse []string
|
|
|
|
s.MojangApi.On("UsernamesToUuids", mock.Anything, []string{"username1", "username2", "username3"}).Once().Return(emptyResponse, nil)
|
|
s.MojangApi.On("UsernamesToUuids", mock.Anything, []string{"username4"}).Once().Return(emptyResponse, nil)
|
|
|
|
resultChan1 := s.GetUuidAsync("username1")
|
|
resultChan2 := s.GetUuidAsync("username2")
|
|
resultChan3 := s.GetUuidAsync("username3")
|
|
resultChan4 := s.GetUuidAsync("username4")
|
|
|
|
time.Sleep(time.Duration(float64(awaitDelay) * 0.5))
|
|
|
|
s.Require().NotEmpty(resultChan1)
|
|
s.Require().NotEmpty(resultChan2)
|
|
s.Require().NotEmpty(resultChan3)
|
|
s.Require().Empty(resultChan4)
|
|
|
|
time.Sleep(time.Duration(float64(awaitDelay) * 1.5))
|
|
|
|
s.Require().NotEmpty(resultChan4)
|
|
}
|
|
|
|
func (s *batchUuidsProviderTestSuite) TestGetUuidForFewUsernamesWithAnError() {
|
|
expectedUsernames := []string{"username1", "username2"}
|
|
expectedError := errors.New("mock error")
|
|
|
|
s.MojangApi.On("UsernamesToUuids", mock.Anything, expectedUsernames).Once().Return(nil, expectedError)
|
|
|
|
resultChan1 := s.GetUuidAsync("username1")
|
|
resultChan2 := s.GetUuidAsync("username2")
|
|
|
|
result1 := <-resultChan1
|
|
s.Assert().Nil(result1.Result)
|
|
s.Assert().Equal(expectedError, result1.Error)
|
|
|
|
result2 := <-resultChan2
|
|
s.Assert().Nil(result2.Result)
|
|
s.Assert().Equal(expectedError, result2.Error)
|
|
}
|
|
|
|
func TestBatchUuidsProvider(t *testing.T) {
|
|
suite.Run(t, new(batchUuidsProviderTestSuite))
|
|
}
|