package command import ( "sync" "testing" "github.com/hashicorp/vault/api" credAppRole "github.com/hashicorp/vault/builtin/credential/approle" vaulthttp "github.com/hashicorp/vault/http" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/vault" logxi "github.com/mgutz/logxi/v1" ) func TestAppRole_Integ_ConcurrentLogins(t *testing.T) { var err error coreConfig := &vault.CoreConfig{ DisableMlock: true, DisableCache: true, Logger: logxi.NullLog, CredentialBackends: map[string]logical.Factory{ "approle": credAppRole.Factory, }, } cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{ HandlerFunc: vaulthttp.Handler, }) cluster.Start() defer cluster.Cleanup() cores := cluster.Cores vault.TestWaitActive(t, cores[0].Core) client := cores[0].Client err = client.Sys().EnableAuthWithOptions("approle", &api.EnableAuthOptions{ Type: "approle", }) if err != nil { t.Fatal(err) } _, err = client.Logical().Write("auth/approle/role/role1", map[string]interface{}{ "bind_secret_id": "true", "period": "300", }) if err != nil { t.Fatal(err) } secret, err := client.Logical().Write("auth/approle/role/role1/secret-id", nil) if err != nil { t.Fatal(err) } secretID := secret.Data["secret_id"].(string) secret, err = client.Logical().Read("auth/approle/role/role1/role-id") if err != nil { t.Fatal(err) } roleID := secret.Data["role_id"].(string) wg := &sync.WaitGroup{} for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() secret, err := client.Logical().Write("auth/approle/login", map[string]interface{}{ "role_id": roleID, "secret_id": secretID, }) if err != nil { t.Fatal(err) } if secret.Auth.ClientToken == "" { t.Fatalf("expected a successful login") } }() } wg.Wait() }