github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/iratesce/race_test.go (about)

     1  /*
     2   * Copyright (c) 2021-present Sigma-Soft, Ltd.
     3   * @author: Dmitry Molchanovsky
     4   */
     5  
     6  package iratesce
     7  
     8  import (
     9  	"context"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/stretchr/testify/require"
    15  	"github.com/voedger/voedger/pkg/appdef"
    16  	"github.com/voedger/voedger/pkg/irates"
    17  	"github.com/voedger/voedger/pkg/istructs"
    18  )
    19  
    20  func TestRace_Buckets(t *testing.T) {
    21  	buckets := Provide(time.Now)
    22  
    23  	sTotalRegLimitName := "TotalRegLimitName"
    24  	sAddrRegLimitName := "TotalRegLimitName"
    25  
    26  	totalRegKey := irates.BucketKey{
    27  		RateLimitName: sTotalRegLimitName,
    28  		App:           istructs.AppQName_test1_app1,
    29  		QName:         appdef.NewQName("test", "test"),
    30  		RemoteAddr:    "",
    31  		Workspace:     1,
    32  	}
    33  
    34  	totalRegistrationQuota := irates.BucketState{
    35  		Period:             24 * time.Hour,
    36  		MaxTokensPerPeriod: 100,
    37  		TakenTokens:        0,
    38  	}
    39  
    40  	addrRegKey := irates.BucketKey{
    41  		RateLimitName: sAddrRegLimitName,
    42  		App:           istructs.AppQName_test1_app1,
    43  		QName:         appdef.NewQName("test", "test"),
    44  		RemoteAddr:    "addr",
    45  		Workspace:     1,
    46  	}
    47  
    48  	addrRegistrationQuota := irates.BucketState{
    49  		Period:             24 * time.Hour,
    50  		MaxTokensPerPeriod: 120,
    51  		TakenTokens:        0,
    52  	}
    53  
    54  	buckets.SetDefaultBucketState(sTotalRegLimitName, totalRegistrationQuota)
    55  	buckets.SetDefaultBucketState(sAddrRegLimitName, addrRegistrationQuota)
    56  
    57  	keys := []irates.BucketKey{totalRegKey, addrRegKey}
    58  	var finish sync.WaitGroup
    59  	ctx, cancel := context.WithCancel(context.Background())
    60  	start := sync.WaitGroup{}
    61  
    62  	var getTokensForRegistration = func() {
    63  		defer finish.Done()
    64  		start.Done()
    65  		for ctx.Err() == nil {
    66  			_ = buckets.TakeTokens(keys, 1)
    67  		}
    68  	}
    69  
    70  	var getBucketState = func() {
    71  		defer finish.Done()
    72  		start.Done()
    73  		for ctx.Err() == nil {
    74  			_, err := buckets.GetBucketState(totalRegKey)
    75  			require.NoError(t, err)
    76  		}
    77  	}
    78  
    79  	var setBucketState = func() {
    80  		defer finish.Done()
    81  		start.Done()
    82  		for ctx.Err() == nil {
    83  			buckets.SetDefaultBucketState(sTotalRegLimitName, totalRegistrationQuota)
    84  		}
    85  	}
    86  
    87  	for i := 0; i < 10; i++ {
    88  		start.Add(3)
    89  		finish.Add(3)
    90  		go getTokensForRegistration()
    91  		go getBucketState()
    92  		go setBucketState()
    93  	}
    94  
    95  	start.Wait()
    96  	time.Sleep(time.Second)
    97  	cancel()
    98  	finish.Wait()
    99  }