#1: Add logging mechanic and remove awaiting of finishing of all textures requests in usernames queue

This commit is contained in:
ErickSkrauch 2019-04-25 00:45:04 +03:00
parent 50a19202a5
commit 533afcc689
3 changed files with 221 additions and 23 deletions

View File

@ -8,6 +8,8 @@ import (
"syscall"
"time"
"github.com/mono83/slf/wd"
"github.com/elyby/chrly/api/mojang"
)
@ -23,6 +25,7 @@ var allowedUsernamesRegex = regexp.MustCompile(`^[\w_]{3,16}$`)
type JobsQueue struct {
Storage Storage
Logger wd.Watchdog
onFirstCall sync.Once
queue jobsQueue
@ -38,6 +41,7 @@ func (ctx *JobsQueue) GetTexturesForUsername(username string) chan *mojang.Signe
responseChan := make(chan *mojang.SignedTexturesResponse)
if !allowedUsernamesRegex.MatchString(username) {
ctx.Logger.IncCounter("mojang_textures.invalid_username", 1)
go func() {
responseChan <- nil
close(responseChan)
@ -46,8 +50,12 @@ func (ctx *JobsQueue) GetTexturesForUsername(username string) chan *mojang.Signe
return responseChan
}
ctx.Logger.IncCounter("mojang_textures.request", 1)
uuid, err := ctx.Storage.GetUuid(username)
if err == nil && uuid == "" {
ctx.Logger.IncCounter("mojang_textures.usernames.cache_hit_nil", 1)
go func() {
responseChan <- nil
close(responseChan)
@ -58,12 +66,15 @@ func (ctx *JobsQueue) GetTexturesForUsername(username string) chan *mojang.Signe
isFirstListener := ctx.broadcast.AddListener(username, responseChan)
if isFirstListener {
start := time.Now()
// TODO: respond nil if processing takes more than 5 seconds
resultChan := make(chan *mojang.SignedTexturesResponse)
if uuid == "" {
ctx.Logger.IncCounter("mojang_textures.usernames.queued", 1)
ctx.queue.Enqueue(&jobItem{username, resultChan})
} else {
ctx.Logger.IncCounter("mojang_textures.usernames.cache_hit", 1)
go func() {
resultChan <- ctx.getTextures(uuid)
}()
@ -73,7 +84,10 @@ func (ctx *JobsQueue) GetTexturesForUsername(username string) chan *mojang.Signe
result := <-resultChan
close(resultChan)
ctx.broadcast.BroadcastAndRemove(username, result)
ctx.Logger.RecordTimer("mojang_textures.result_time", time.Since(start))
}()
} else {
ctx.Logger.IncCounter("mojang_textures.already_in_queue", 1)
}
return responseChan
@ -85,7 +99,9 @@ func (ctx *JobsQueue) startQueue() {
for forever() {
start := time.Now()
ctx.queueRound()
time.Sleep(uuidsQueuePeriod - time.Since(start))
elapsed := time.Since(start)
ctx.Logger.RecordTimer("mojang_textures.usernames.round_time", elapsed)
time.Sleep(uuidsQueuePeriod - elapsed)
}
}()
}
@ -95,7 +111,10 @@ func (ctx *JobsQueue) queueRound() {
return
}
queueSize := ctx.queue.Size()
jobs := ctx.queue.Dequeue(100)
ctx.Logger.UpdateGauge("mojang_textures.usernames.iteration_size", int64(len(jobs)))
ctx.Logger.UpdateGauge("mojang_textures.usernames.queue_size", int64(queueSize-len(jobs)))
var usernames []string
for _, job := range jobs {
usernames = append(usernames, job.Username)
@ -108,14 +127,12 @@ func (ctx *JobsQueue) queueRound() {
job.RespondTo <- nil
}
}()
maybeShouldPanic(err)
ctx.maybeShouldPanic(err)
return
}
var wg sync.WaitGroup
for _, job := range jobs {
wg.Add(1)
go func(job *jobItem) {
var uuid string
// Profiles in response not ordered, so we must search each username over full array
@ -129,27 +146,30 @@ func (ctx *JobsQueue) queueRound() {
ctx.Storage.StoreUuid(job.Username, uuid)
if uuid == "" {
job.RespondTo <- nil
ctx.Logger.IncCounter("mojang_textures.usernames.uuid_miss", 1)
} else {
job.RespondTo <- ctx.getTextures(uuid)
ctx.Logger.IncCounter("mojang_textures.usernames.uuid_hit", 1)
}
wg.Done()
}(job)
}
wg.Wait()
}
func (ctx *JobsQueue) getTextures(uuid string) *mojang.SignedTexturesResponse {
existsTextures, err := ctx.Storage.GetTextures(uuid)
if err == nil {
ctx.Logger.IncCounter("mojang_textures.textures.cache_hit", 1)
return existsTextures
}
shouldCache := true
ctx.Logger.IncCounter("mojang_textures.textures.request", 1)
start := time.Now()
result, err := uuidToTextures(uuid, true)
ctx.Logger.RecordTimer("mojang_textures.textures.request_time", time.Since(start))
shouldCache := true
if err != nil {
maybeShouldPanic(err)
ctx.maybeShouldPanic(err)
shouldCache = false
}
@ -161,9 +181,15 @@ func (ctx *JobsQueue) getTextures(uuid string) *mojang.SignedTexturesResponse {
}
// Starts to panic if there's an unexpected error
func maybeShouldPanic(err error) {
func (ctx *JobsQueue) maybeShouldPanic(err error) {
ctx.Logger.Debug("Got response error :err", wd.ErrParam(err))
switch err.(type) {
case mojang.ResponseError:
if _, ok := err.(*mojang.TooManyRequestsError); ok {
ctx.Logger.Warning("Got 429 Too Many Requests :err", wd.ErrParam(err))
}
return
case net.Error:
if err.(net.Error).Timeout() {

View File

@ -3,14 +3,17 @@ package queue
import (
"crypto/rand"
"encoding/base64"
"github.com/elyby/chrly/api/mojang"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"net"
"strings"
"syscall"
"testing"
"time"
"github.com/elyby/chrly/api/mojang"
mocks "github.com/elyby/chrly/tests"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"testing"
)
type mojangApiMocks struct {
@ -69,6 +72,7 @@ type queueTestSuite struct {
Queue *JobsQueue
Storage *mockStorage
MojangApi *mojangApiMocks
Logger *mocks.WdMock
Iterate func()
iterateChan chan bool
@ -81,8 +85,9 @@ func (suite *queueTestSuite) SetupSuite() {
func (suite *queueTestSuite) SetupTest() {
suite.Storage = &mockStorage{}
suite.Logger = &mocks.WdMock{}
suite.Queue = &JobsQueue{Storage: suite.Storage}
suite.Queue = &JobsQueue{Storage: suite.Storage, Logger: suite.Logger}
suite.iterateChan = make(chan bool)
forever = func() bool {
@ -106,15 +111,27 @@ func (suite *queueTestSuite) TearDownTest() {
suite.done()
suite.MojangApi.AssertExpectations(suite.T())
suite.Storage.AssertExpectations(suite.T())
suite.Logger.AssertExpectations(suite.T())
}
func (suite *queueTestSuite) TestReceiveTexturesForOneUsernameWithoutAnyCache() {
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.usernames.queued", int64(1)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(1)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(0)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.usernames.round_time", mock.Anything)
suite.Logger.On("IncCounter", "mojang_textures.textures.request", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.textures.request_time", mock.Anything).Once()
suite.Logger.On("IncCounter", "mojang_textures.usernames.uuid_hit", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Once()
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
suite.Storage.On("StoreTextures", expectedResult).Once()
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
}, nil)
@ -132,6 +149,16 @@ func (suite *queueTestSuite) TestReceiveTexturesForFewUsernamesWithoutAnyCache()
expectedResult1 := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
expectedResult2 := &mojang.SignedTexturesResponse{Id: "4566e69fc90748ee8d71d7ba5aa00d20", Name: "Thinkofdeath"}
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Twice()
suite.Logger.On("IncCounter", "mojang_textures.usernames.queued", int64(1)).Twice()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(2)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(0)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.usernames.round_time", mock.Anything)
suite.Logger.On("IncCounter", "mojang_textures.textures.request", int64(1)).Twice()
suite.Logger.On("RecordTimer", "mojang_textures.textures.request_time", mock.Anything).Twice()
suite.Logger.On("IncCounter", "mojang_textures.usernames.uuid_hit", int64(1)).Twice()
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Twice()
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
suite.Storage.On("GetUuid", "Thinkofdeath").Once().Return("", &ValueNotFound{})
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
@ -140,6 +167,7 @@ func (suite *queueTestSuite) TestReceiveTexturesForFewUsernamesWithoutAnyCache()
suite.Storage.On("GetTextures", "4566e69fc90748ee8d71d7ba5aa00d20").Once().Return(nil, &ValueNotFound{})
suite.Storage.On("StoreTextures", expectedResult1).Once()
suite.Storage.On("StoreTextures", expectedResult2).Once()
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb", "Thinkofdeath"}).Once().Return([]*mojang.ProfileInfo{
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
{Id: "4566e69fc90748ee8d71d7ba5aa00d20", Name: "Thinkofdeath"},
@ -159,10 +187,17 @@ func (suite *queueTestSuite) TestReceiveTexturesForFewUsernamesWithoutAnyCache()
func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithCachedUuid() {
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.usernames.cache_hit", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.textures.request", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.textures.request_time", mock.Anything).Once()
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Once()
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("0d252b7218b648bfb86c2ae476954d32", nil)
// Storage.StoreUuid shouldn't be called
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
suite.Storage.On("StoreTextures", expectedResult).Once()
// MojangApi.UsernamesToUuids shouldn't be called
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(expectedResult, nil)
@ -177,10 +212,16 @@ func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithCachedUuid() {
func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithFullyCachedResult() {
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.usernames.cache_hit", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.textures.cache_hit", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Once()
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("0d252b7218b648bfb86c2ae476954d32", nil)
// Storage.StoreUuid shouldn't be called
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(expectedResult, nil)
// Storage.StoreTextures shouldn't be called
// MojangApi.UsernamesToUuids shouldn't be called
// MojangApi.UuidToTextures shouldn't be called
@ -193,10 +234,14 @@ func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithFullyCachedResult
}
func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithCachedUnknownUuid() {
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.usernames.cache_hit_nil", int64(1)).Once()
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", nil)
// Storage.StoreUuid shouldn't be called
// Storage.GetTextures shouldn't be called
// Storage.StoreTextures shouldn't be called
// MojangApi.UsernamesToUuids shouldn't be called
// MojangApi.UuidToTextures shouldn't be called
@ -213,23 +258,50 @@ func (suite *queueTestSuite) TestReceiveTexturesForMoreThan100Usernames() {
usernames[i] = randStr(8)
}
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Times(120)
suite.Logger.On("IncCounter", "mojang_textures.usernames.queued", int64(1)).Times(120)
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(100)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(20)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(20)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(0)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.usernames.round_time", mock.Anything).Twice()
suite.Logger.On("IncCounter", "mojang_textures.usernames.uuid_miss", int64(1)).Times(120)
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Times(120)
suite.Storage.On("GetUuid", mock.Anything).Times(120).Return("", &ValueNotFound{})
suite.Storage.On("StoreUuid", mock.Anything, "").Times(120) // if username is not compared to uuid, then receive ""
// Storage.GetTextures and Storage.SetTextures shouldn't be called
suite.MojangApi.On("UsernamesToUuids", usernames[0:100]).Once().Return([]*mojang.ProfileInfo{}, nil)
suite.MojangApi.On("UsernamesToUuids", usernames[100:120]).Once().Return([]*mojang.ProfileInfo{}, nil)
for _, username := range usernames {
suite.Queue.GetTexturesForUsername(username)
channels := make([]chan *mojang.SignedTexturesResponse, 120)
for i, username := range usernames {
channels[i] = suite.Queue.GetTexturesForUsername(username)
}
suite.Iterate()
suite.Iterate()
for _, channel := range channels {
<-channel
}
}
func (suite *queueTestSuite) TestReceiveTexturesForTheSameUsernames() {
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Twice()
suite.Logger.On("IncCounter", "mojang_textures.usernames.queued", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.already_in_queue", int64(1)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(1)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(0)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.usernames.round_time", mock.Anything)
suite.Logger.On("IncCounter", "mojang_textures.textures.request", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.textures.request_time", mock.Anything).Once()
suite.Logger.On("IncCounter", "mojang_textures.usernames.uuid_hit", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Once()
suite.Storage.On("GetUuid", "maksimkurb").Twice().Return("", &ValueNotFound{})
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
@ -251,10 +323,22 @@ func (suite *queueTestSuite) TestReceiveTexturesForTheSameUsernames() {
func (suite *queueTestSuite) TestReceiveTexturesForUsernameThatAlreadyProcessing() {
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Twice()
suite.Logger.On("IncCounter", "mojang_textures.usernames.queued", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.already_in_queue", int64(1)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(1)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(0)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.usernames.round_time", mock.Anything)
suite.Logger.On("IncCounter", "mojang_textures.textures.request", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.textures.request_time", mock.Anything).Once()
suite.Logger.On("IncCounter", "mojang_textures.usernames.uuid_hit", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Once()
suite.Storage.On("GetUuid", "maksimkurb").Twice().Return("", &ValueNotFound{})
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
suite.Storage.On("StoreTextures", expectedResult).Once()
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
}, nil)
@ -278,9 +362,18 @@ func (suite *queueTestSuite) TestReceiveTexturesForUsernameThatAlreadyProcessing
}
func (suite *queueTestSuite) TestDoNothingWhenNoTasks() {
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Once()
suite.Logger.On("IncCounter", "mojang_textures.usernames.queued", int64(1)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(1)).Once()
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(0)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.usernames.round_time", mock.Anything)
suite.Logger.On("IncCounter", "mojang_textures.usernames.uuid_miss", int64(1)).Once()
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Once()
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
suite.Storage.On("StoreUuid", "maksimkurb", "").Once()
// Storage.GetTextures and Storage.StoreTextures shouldn't be called
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{}, nil)
// Perform first iteration and await it finish
@ -313,9 +406,17 @@ var expectedErrors = []error{
}
func (suite *queueTestSuite) TestShouldNotPanicWhenExpectedErrorReturnedFromUsernameToUuidRequest() {
suite.Logger.On("IncCounter", mock.Anything, mock.Anything)
suite.Logger.On("UpdateGauge", mock.Anything, mock.Anything)
suite.Logger.On("RecordTimer", mock.Anything, mock.Anything)
suite.Logger.On("Debug", "Got response error :err", mock.Anything).Times(len(expectedErrors))
suite.Logger.On("Warning", "Got 429 Too Many Requests :err", mock.Anything).Once()
suite.Storage.On("GetUuid", "maksimkurb").Return("", &ValueNotFound{})
for _, err := range expectedErrors {
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return(nil, err)
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
suite.Iterate()
suite.Assert().Nil(<-resultChan)
@ -325,15 +426,23 @@ func (suite *queueTestSuite) TestShouldNotPanicWhenExpectedErrorReturnedFromUser
}
func (suite *queueTestSuite) TestShouldNotPanicWhenExpectedErrorReturnedFromUuidToTexturesRequest() {
suite.Logger.On("IncCounter", mock.Anything, mock.Anything)
suite.Logger.On("UpdateGauge", mock.Anything, mock.Anything)
suite.Logger.On("RecordTimer", mock.Anything, mock.Anything)
suite.Logger.On("Debug", "Got response error :err", mock.Anything).Times(len(expectedErrors))
suite.Logger.On("Warning", "Got 429 Too Many Requests :err", mock.Anything).Once()
suite.Storage.On("GetUuid", "maksimkurb").Return("", &ValueNotFound{})
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32")
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Return(nil, &ValueNotFound{})
// Storage.StoreTextures shouldn't be called
for _, err := range expectedErrors {
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
// Storage.StoreTextures shouldn't be called
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
}, nil)
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(nil, err)
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
suite.Iterate()
suite.Assert().Nil(<-resultChan)
@ -343,6 +452,8 @@ func (suite *queueTestSuite) TestShouldNotPanicWhenExpectedErrorReturnedFromUuid
}
func (suite *queueTestSuite) TestReceiveTexturesForNotAllowedMojangUsername() {
suite.Logger.On("IncCounter", "mojang_textures.invalid_username", int64(1)).Once()
resultChan := suite.Queue.GetTexturesForUsername("Not allowed")
suite.Assert().Nil(<-resultChan)
}

61
tests/wd_mock.go Normal file
View File

@ -0,0 +1,61 @@
package tests
import (
"time"
"github.com/mono83/slf"
"github.com/mono83/slf/wd"
"github.com/stretchr/testify/mock"
)
type WdMock struct {
mock.Mock
}
func (m *WdMock) Trace(message string, p ...slf.Param) {
m.Called(message)
}
func (m *WdMock) Debug(message string, p ...slf.Param) {
m.Called(message)
}
func (m *WdMock) Info(message string, p ...slf.Param) {
m.Called(message)
}
func (m *WdMock) Warning(message string, p ...slf.Param) {
m.Called(message)
}
func (m *WdMock) Error(message string, p ...slf.Param) {
m.Called(message)
}
func (m *WdMock) Alert(message string, p ...slf.Param) {
m.Called(message)
}
func (m *WdMock) Emergency(message string, p ...slf.Param) {
m.Called(message)
}
func (m *WdMock) IncCounter(name string, value int64, p ...slf.Param) {
m.Called(name, value)
}
func (m *WdMock) UpdateGauge(name string, value int64, p ...slf.Param) {
m.Called(name, value)
}
func (m *WdMock) RecordTimer(name string, d time.Duration, p ...slf.Param) {
m.Called(name, d)
}
func (m *WdMock) Timer(name string, p ...slf.Param) slf.Timer {
return slf.NewTimer(name, p, m)
}
func (m *WdMock) WithParams(p ...slf.Param) wd.Watchdog {
panic("this method shouldn't be used")
}