fix: ensure metadata is projected for scim tests to ensure stable tests (#9305)

# Which Problems Are Solved
- SCIM tests are flaky due to metadata being set by the tests while
shortly after being read by the application, resulting in a race
condition

# How the Problems Are Solved
- whenever metadata is set, the projection is awaited

# Additional Context
Part of #8140

Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
This commit is contained in:
Lars 2025-02-05 16:40:56 +01:00 committed by GitHub
parent 361f7a2edc
commit 4dc7a58a25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 47 additions and 58 deletions

View File

@ -23,6 +23,7 @@ import (
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
"github.com/zitadel/zitadel/internal/integration/scim" "github.com/zitadel/zitadel/internal/integration/scim"
"github.com/zitadel/zitadel/internal/test" "github.com/zitadel/zitadel/internal/test"
"github.com/zitadel/zitadel/pkg/grpc/management"
) )
var ( var (
@ -695,3 +696,39 @@ func buildTooManyOperationsRequest() *scim.BulkRequest {
return req return req
} }
func setProvisioningDomain(t require.TestingT, userID, provisioningDomain string) {
setAndEnsureMetadata(t, userID, "urn:zitadel:scim:provisioningDomain", provisioningDomain)
}
func setAndEnsureMetadata(t require.TestingT, userID, key, value string) {
_, err := Instance.Client.Mgmt.SetUserMetadata(CTX, &management.SetUserMetadataRequest{
Id: userID,
Key: key,
Value: []byte(value),
})
require.NoError(t, err)
// ensure metadata is projected
ensureMetadataProjected(t, userID, key, value)
}
func ensureMetadataProjected(t require.TestingT, userID, key, value string) {
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
require.EventuallyWithT(t, func(tt *assert.CollectT) {
md, err := Instance.Client.Mgmt.GetUserMetadata(CTX, &management.GetUserMetadataRequest{
Id: userID,
Key: key,
})
require.NoError(tt, err)
require.Equal(tt, value, string(md.Metadata.Value))
}, retryDuration, tick)
}
func removeProvisioningDomain(t require.TestingT, userID string) {
_, err := Instance.Client.Mgmt.RemoveUserMetadata(CTX, &management.RemoveUserMetadataRequest{
Id: userID,
Key: "urn:zitadel:scim:provisioningDomain",
})
require.NoError(t, err)
}

View File

@ -395,12 +395,7 @@ func TestCreateUser_metadata(t *testing.T) {
} }
func TestCreateUser_scopedExternalID(t *testing.T) { func TestCreateUser_scopedExternalID(t *testing.T) {
_, err := Instance.Client.Mgmt.SetUserMetadata(CTX, &management.SetUserMetadataRequest{ setProvisioningDomain(t, Instance.Users.Get(integration.UserTypeOrgOwner).ID, "fooBar")
Id: Instance.Users.Get(integration.UserTypeOrgOwner).ID,
Key: "urn:zitadel:scim:provisioningDomain",
Value: []byte("fooBar"),
})
require.NoError(t, err)
createdUser, err := Instance.Client.SCIM.Users.Create(CTX, Instance.DefaultOrg.Id, fullUserJson) createdUser, err := Instance.Client.SCIM.Users.Create(CTX, Instance.DefaultOrg.Id, fullUserJson)
require.NoError(t, err) require.NoError(t, err)
@ -409,11 +404,7 @@ func TestCreateUser_scopedExternalID(t *testing.T) {
_, err = Instance.Client.UserV2.DeleteUser(CTX, &user.DeleteUserRequest{UserId: createdUser.ID}) _, err = Instance.Client.UserV2.DeleteUser(CTX, &user.DeleteUserRequest{UserId: createdUser.ID})
require.NoError(t, err) require.NoError(t, err)
_, err = Instance.Client.Mgmt.RemoveUserMetadata(CTX, &management.RemoveUserMetadataRequest{ removeProvisioningDomain(t, Instance.Users.Get(integration.UserTypeOrgOwner).ID)
Id: Instance.Users.Get(integration.UserTypeOrgOwner).ID,
Key: "urn:zitadel:scim:provisioningDomain",
})
require.NoError(t, err)
}() }()
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute) retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)

View File

@ -18,7 +18,6 @@ import (
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
"github.com/zitadel/zitadel/internal/integration/scim" "github.com/zitadel/zitadel/internal/integration/scim"
"github.com/zitadel/zitadel/internal/test" "github.com/zitadel/zitadel/internal/test"
"github.com/zitadel/zitadel/pkg/grpc/management"
"github.com/zitadel/zitadel/pkg/grpc/user/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2"
) )
@ -203,31 +202,17 @@ func TestGetUser(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// set provisioning domain of service user // set provisioning domain of service user
_, err = Instance.Client.Mgmt.SetUserMetadata(CTX, &management.SetUserMetadataRequest{ setProvisioningDomain(t, Instance.Users.Get(integration.UserTypeOrgOwner).ID, "fooBar")
Id: Instance.Users.Get(integration.UserTypeOrgOwner).ID,
Key: "urn:zitadel:scim:provisioningDomain",
Value: []byte("fooBar"),
})
require.NoError(t, err)
// set externalID for provisioning domain // set externalID for provisioning domain
_, err = Instance.Client.Mgmt.SetUserMetadata(CTX, &management.SetUserMetadataRequest{ setAndEnsureMetadata(t, createdUser.ID, "urn:zitadel:scim:fooBar:externalId", "100-scopedExternalId")
Id: createdUser.ID,
Key: "urn:zitadel:scim:fooBar:externalId",
Value: []byte("100-scopedExternalId"),
})
require.NoError(t, err)
return createdUser.ID return createdUser.ID
}, },
cleanup: func(userID string) { cleanup: func(userID string) {
_, err := Instance.Client.UserV2.DeleteUser(CTX, &user.DeleteUserRequest{UserId: userID}) _, err := Instance.Client.UserV2.DeleteUser(CTX, &user.DeleteUserRequest{UserId: userID})
require.NoError(t, err) require.NoError(t, err)
_, err = Instance.Client.Mgmt.RemoveUserMetadata(CTX, &management.RemoveUserMetadataRequest{ removeProvisioningDomain(t, Instance.Users.Get(integration.UserTypeOrgOwner).ID)
Id: Instance.Users.Get(integration.UserTypeOrgOwner).ID,
Key: "urn:zitadel:scim:provisioningDomain",
})
require.NoError(t, err)
}, },
want: &resources.ScimUser{ want: &resources.ScimUser{
ExternalID: "100-scopedExternalId", ExternalID: "100-scopedExternalId",

View File

@ -20,7 +20,6 @@ import (
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
"github.com/zitadel/zitadel/internal/integration/scim" "github.com/zitadel/zitadel/internal/integration/scim"
"github.com/zitadel/zitadel/internal/test" "github.com/zitadel/zitadel/internal/test"
"github.com/zitadel/zitadel/pkg/grpc/management"
"github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/object/v2"
user_v2 "github.com/zitadel/zitadel/pkg/grpc/user/v2" user_v2 "github.com/zitadel/zitadel/pkg/grpc/user/v2"
) )
@ -372,20 +371,10 @@ func TestListUser(t *testing.T) {
resp := createHumanUser(t, CTX, Instance.DefaultOrg.Id, 102) resp := createHumanUser(t, CTX, Instance.DefaultOrg.Id, 102)
// set provisioning domain of service user // set provisioning domain of service user
_, err := Instance.Client.Mgmt.SetUserMetadata(CTX, &management.SetUserMetadataRequest{ setProvisioningDomain(t, Instance.Users.Get(integration.UserTypeOrgOwner).ID, "fooBar")
Id: Instance.Users.Get(integration.UserTypeOrgOwner).ID,
Key: "urn:zitadel:scim:provisioningDomain",
Value: []byte("fooBar"),
})
require.NoError(t, err)
// set externalID for provisioning domain // set externalID for provisioning domain
_, err = Instance.Client.Mgmt.SetUserMetadata(CTX, &management.SetUserMetadataRequest{ setAndEnsureMetadata(t, resp.UserId, "urn:zitadel:scim:fooBar:externalId", "100-scopedExternalId")
Id: resp.UserId,
Key: "urn:zitadel:scim:fooBar:externalId",
Value: []byte("100-scopedExternalId"),
})
require.NoError(t, err)
return &scim.ListRequest{ return &scim.ListRequest{
Filter: gu.Ptr(fmt.Sprintf(`id eq "%s"`, resp.UserId)), Filter: gu.Ptr(fmt.Sprintf(`id eq "%s"`, resp.UserId)),
} }
@ -396,11 +385,7 @@ func TestListUser(t *testing.T) {
}, },
cleanup: func(t require.TestingT) { cleanup: func(t require.TestingT) {
// delete provisioning domain of service user // delete provisioning domain of service user
_, err := Instance.Client.Mgmt.RemoveUserMetadata(CTX, &management.RemoveUserMetadataRequest{ removeProvisioningDomain(t, Instance.Users.Get(integration.UserTypeOrgOwner).ID)
Id: Instance.Users.Get(integration.UserTypeOrgOwner).ID,
Key: "urn:zitadel:scim:provisioningDomain",
})
require.NoError(t, err)
}, },
}, },
} }

View File

@ -316,12 +316,7 @@ func TestReplaceUser_scopedExternalID(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// set provisioning domain of service user // set provisioning domain of service user
_, err = Instance.Client.Mgmt.SetUserMetadata(CTX, &management.SetUserMetadataRequest{ setProvisioningDomain(t, Instance.Users.Get(integration.UserTypeOrgOwner).ID, "fooBazz")
Id: Instance.Users.Get(integration.UserTypeOrgOwner).ID,
Key: "urn:zitadel:scim:provisioningDomain",
Value: []byte("fooBazz"),
})
require.NoError(t, err)
// replace the user with provisioning domain set // replace the user with provisioning domain set
_, err = Instance.Client.SCIM.Users.Replace(CTX, Instance.DefaultOrg.Id, createdUser.ID, minimalUserWithExternalIDJson) _, err = Instance.Client.SCIM.Users.Replace(CTX, Instance.DefaultOrg.Id, createdUser.ID, minimalUserWithExternalIDJson)
@ -347,9 +342,5 @@ func TestReplaceUser_scopedExternalID(t *testing.T) {
_, err = Instance.Client.UserV2.DeleteUser(CTX, &user.DeleteUserRequest{UserId: createdUser.ID}) _, err = Instance.Client.UserV2.DeleteUser(CTX, &user.DeleteUserRequest{UserId: createdUser.ID})
require.NoError(t, err) require.NoError(t, err)
_, err = Instance.Client.Mgmt.RemoveUserMetadata(CTX, &management.RemoveUserMetadataRequest{ removeProvisioningDomain(t, Instance.Users.Get(integration.UserTypeOrgOwner).ID)
Id: Instance.Users.Get(integration.UserTypeOrgOwner).ID,
Key: "urn:zitadel:scim:provisioningDomain",
})
require.NoError(t, err)
} }