mirror of https://github.com/portainer/portainer
78 lines
1.5 KiB
Go
78 lines
1.5 KiB
Go
package users
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
portainer "github.com/portainer/portainer/api"
|
|
"github.com/portainer/portainer/api/crypto"
|
|
"github.com/portainer/portainer/api/datastore"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
type mockPasswordStrengthChecker struct{}
|
|
|
|
func (m *mockPasswordStrengthChecker) Check(string) bool {
|
|
return true
|
|
}
|
|
|
|
func TestConcurrentUserCreation(t *testing.T) {
|
|
_, store := datastore.MustNewTestStore(t, true, false)
|
|
|
|
h := &Handler{
|
|
passwordStrengthChecker: &mockPasswordStrengthChecker{},
|
|
CryptoService: &crypto.Service{},
|
|
DataStore: store,
|
|
}
|
|
|
|
ucp := userCreatePayload{
|
|
Username: "portainer",
|
|
Password: "password",
|
|
Role: int(portainer.AdministratorRole),
|
|
}
|
|
|
|
m, err := json.Marshal(ucp)
|
|
require.NoError(t, err)
|
|
|
|
errGroup := &errgroup.Group{}
|
|
|
|
n := 100
|
|
|
|
for range n {
|
|
errGroup.Go(func() error {
|
|
req, err := http.NewRequest(http.MethodPost, "/users", bytes.NewReader(m))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := h.userCreate(httptest.NewRecorder(), req); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
err = errGroup.Wait()
|
|
require.Error(t, err)
|
|
|
|
users, err := store.User().ReadAll()
|
|
require.NotEmpty(t, users)
|
|
require.NoError(t, err)
|
|
|
|
userCreated := false
|
|
for _, u := range users {
|
|
if u.Username == ucp.Username {
|
|
require.False(t, userCreated)
|
|
userCreated = true
|
|
}
|
|
}
|
|
|
|
require.True(t, userCreated)
|
|
}
|