179 lines
4.8 KiB
Go
179 lines
4.8 KiB
Go
package tests
|
||
|
||
import (
|
||
"fmt"
|
||
"sync"
|
||
"sync/atomic"
|
||
"time"
|
||
|
||
authpb "git.techease.ru/Smart-search/smart-search-back/pkg/pb/auth"
|
||
)
|
||
|
||
func (s *IntegrationSuite) TestConcurrent_Registration_WithSingleInviteCode() {
|
||
maxUses := 3
|
||
inviteCode := s.createActiveInviteCode(maxUses)
|
||
|
||
var wg sync.WaitGroup
|
||
var successCount int32
|
||
var errorCount int32
|
||
goroutines := 20
|
||
|
||
startBarrier := make(chan struct{})
|
||
|
||
for i := 0; i < goroutines; i++ {
|
||
wg.Add(1)
|
||
go func(idx int) {
|
||
defer wg.Done()
|
||
|
||
<-startBarrier
|
||
|
||
email := fmt.Sprintf("concurrent_reg_%d_%d@example.com", idx, time.Now().UnixNano())
|
||
|
||
_, err := s.authClient.Register(s.ctx, &authpb.RegisterRequest{
|
||
Email: email,
|
||
Password: "testpassword123",
|
||
Name: fmt.Sprintf("User %d", idx),
|
||
Phone: fmt.Sprintf("+1%010d", idx),
|
||
InviteCode: inviteCode,
|
||
Ip: "127.0.0.1",
|
||
UserAgent: "integration-test",
|
||
})
|
||
|
||
if err == nil {
|
||
atomic.AddInt32(&successCount, 1)
|
||
} else {
|
||
atomic.AddInt32(&errorCount, 1)
|
||
}
|
||
}(i)
|
||
}
|
||
|
||
close(startBarrier)
|
||
wg.Wait()
|
||
|
||
s.T().Logf("Registration results - Success: %d, Errors: %d", successCount, errorCount)
|
||
|
||
s.LessOrEqual(int(successCount), maxUses,
|
||
"Количество успешных регистраций (%d) не должно превышать лимит invite-кода (%d)", successCount, maxUses)
|
||
|
||
remainingUses := s.getInviteCodeUsageCount(inviteCode)
|
||
s.T().Logf("Remaining invite code uses: %d", remainingUses)
|
||
|
||
s.Equal(maxUses-int(successCount), remainingUses,
|
||
"Оставшееся количество использований должно соответствовать успешным регистрациям")
|
||
}
|
||
|
||
func (s *IntegrationSuite) TestConcurrent_Registration_InviteCodeDeactivation() {
|
||
maxUses := 2
|
||
inviteCode := s.createActiveInviteCode(maxUses)
|
||
|
||
s.True(s.isInviteCodeActive(inviteCode), "Invite code должен быть активен изначально")
|
||
|
||
var wg sync.WaitGroup
|
||
var successCount int32
|
||
goroutines := 10
|
||
|
||
startBarrier := make(chan struct{})
|
||
|
||
for i := 0; i < goroutines; i++ {
|
||
wg.Add(1)
|
||
go func(idx int) {
|
||
defer wg.Done()
|
||
|
||
<-startBarrier
|
||
|
||
email := fmt.Sprintf("deactivation_test_%d_%d@example.com", idx, time.Now().UnixNano())
|
||
|
||
_, err := s.authClient.Register(s.ctx, &authpb.RegisterRequest{
|
||
Email: email,
|
||
Password: "testpassword123",
|
||
Name: fmt.Sprintf("User %d", idx),
|
||
Phone: fmt.Sprintf("+2%010d", idx),
|
||
InviteCode: inviteCode,
|
||
Ip: "127.0.0.1",
|
||
UserAgent: "integration-test",
|
||
})
|
||
|
||
if err == nil {
|
||
atomic.AddInt32(&successCount, 1)
|
||
}
|
||
}(i)
|
||
}
|
||
|
||
close(startBarrier)
|
||
wg.Wait()
|
||
|
||
s.T().Logf("Registration success count: %d", successCount)
|
||
|
||
s.LessOrEqual(int(successCount), maxUses,
|
||
"Не должно быть больше %d успешных регистраций", maxUses)
|
||
|
||
remainingUses := s.getInviteCodeUsageCount(inviteCode)
|
||
s.GreaterOrEqual(remainingUses, 0,
|
||
"Количество использований не должно быть отрицательным")
|
||
}
|
||
|
||
func (s *IntegrationSuite) TestConcurrent_Registration_MultipleInviteCodes() {
|
||
inviteCode1 := s.createActiveInviteCode(2)
|
||
inviteCode2 := s.createActiveInviteCode(2)
|
||
|
||
var wg sync.WaitGroup
|
||
var success1, success2 int32
|
||
goroutines := 10
|
||
|
||
startBarrier := make(chan struct{})
|
||
|
||
for i := 0; i < goroutines; i++ {
|
||
wg.Add(1)
|
||
go func(idx int) {
|
||
defer wg.Done()
|
||
|
||
<-startBarrier
|
||
|
||
var code int64
|
||
if idx%2 == 0 {
|
||
code = inviteCode1
|
||
} else {
|
||
code = inviteCode2
|
||
}
|
||
|
||
email := fmt.Sprintf("multi_invite_%d_%d@example.com", idx, time.Now().UnixNano())
|
||
|
||
_, err := s.authClient.Register(s.ctx, &authpb.RegisterRequest{
|
||
Email: email,
|
||
Password: "testpassword123",
|
||
Name: fmt.Sprintf("User %d", idx),
|
||
Phone: fmt.Sprintf("+3%010d", idx),
|
||
InviteCode: code,
|
||
Ip: "127.0.0.1",
|
||
UserAgent: "integration-test",
|
||
})
|
||
|
||
if err == nil {
|
||
if code == inviteCode1 {
|
||
atomic.AddInt32(&success1, 1)
|
||
} else {
|
||
atomic.AddInt32(&success2, 1)
|
||
}
|
||
}
|
||
}(i)
|
||
}
|
||
|
||
close(startBarrier)
|
||
wg.Wait()
|
||
|
||
s.T().Logf("Multi-invite results - Code1: %d, Code2: %d", success1, success2)
|
||
|
||
s.LessOrEqual(int(success1), 2,
|
||
"Invite code 1 не должен превышать лимит")
|
||
s.LessOrEqual(int(success2), 2,
|
||
"Invite code 2 не должен превышать лимит")
|
||
|
||
remaining1 := s.getInviteCodeUsageCount(inviteCode1)
|
||
remaining2 := s.getInviteCodeUsageCount(inviteCode2)
|
||
|
||
s.Equal(2-int(success1), remaining1,
|
||
"Остаток invite code 1 должен соответствовать успешным регистрациям")
|
||
s.Equal(2-int(success2), remaining2,
|
||
"Остаток invite code 2 должен соответствовать успешным регистрациям")
|
||
}
|