-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test(groups): add grants tests for groups API #5403
base: llb-normalized-grants
Are you sure you want to change the base?
Conversation
ffbb1c6
to
e18100e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool, thanks for this!
fa1bac8
to
8a31f36
Compare
Looks like you need a "go mod tidy" |
// genAuthTokenCtx creates an auth.VerifierContext which contains a valid auth token | ||
// for a user which is associated with roles in the roles parameter | ||
// this function creates an authMethod, account, user at global scope | ||
func genAuthTokenCtx(t *testing.T, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a prefix of Test
to the function since it's only used for testing. So nobody accidentally calls it. I think we have a pattern of this in Boundary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the function takes *testing.T
as its first parameter so I don't think this can be accidentally called outside of test but I'll add test...
prefix to its name 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also note that this function is defined in an _test.go
file, which means it does not get compiled into the final binary. As such it can only be called via the tests. The pattern of using a Test
prefix is usually for things defined in testing.go
.
wantIDs: []string{globalGroup.PublicId, org1Group.PublicId, org2Group.PublicId, proj1Group.PublicId, proj2Group.PublicId, proj3Group.PublicId}, | ||
}, | ||
{ | ||
name: "org role grant children IDs only org children", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So descendants
will also include items in the current scope which is org2Group
. I expected only proj2Group
and proj3Group
to be returned just like GetGroup
works with descendants
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, this is a bad test name. The role is in global
with descendant
access - calling list
at org2
will return org2, proj2, proj3
. AFAIK, there's no way to make a list
exclude the "listing scope". You always get all the groups in ScopeId
of the list call.
proj2Group := iam.TestGroup(t, conn, proj2.GetPublicId(), iam.WithDescription("proj2"), iam.WithName("proj2")) | ||
proj3Group := iam.TestGroup(t, conn, proj3.GetPublicId(), iam.WithDescription("proj3"), iam.WithName("proj3")) | ||
|
||
t.Run("List", func(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add test coverage for:
- List with grant string with specific scope id
- Test permission error with type that is not a group
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added tests to cover both cases
}, | ||
}, | ||
{ | ||
name: "global_role_grant_all_specific_permissions", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test and the previous are the same or? Unless I am missing the difference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another test I forgot to rename 🤦
}, | ||
}, | ||
{ | ||
name: "global_role_grant_all_specific_permissions", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test name here is also the same as the last 2 tests. Not distinct enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch! my bad, will push a fix soon
t.Run("update", func(t *testing.T) { | ||
testcases := []struct { | ||
name string | ||
setupScopesResourcesRoles func(t *testing.T, conn *db.DB, iamRepo *iam.Repository) (*iam.Group, []roleRequest) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why we can't pass only roleRequest
and allow the for loop to create a test group to follow the pattern of other tests? is it because we want to create groups in different scopes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because in some cases we need ID of the group for testing resource-specific grant string
e44604f
to
8e8eceb
Compare
} | ||
|
||
for _, tc := range testcases { | ||
t.Run(tc.name, func(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use the Get call to test the behaviour of output_fields
? We could also create a separate test that does this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO output_fields
should be tested across all CRUDL methods, not just the the read operations. I'm still working on adding a specific output_fields
tests which encompasses all the method types.
testcases := []struct { | ||
name string | ||
userFunc func() *iam.User | ||
canCreateInScopes []string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, why don't we follow what we do for Get
between tests where we attempt an action and evaluate the result for each group. Makes it easier add to it and to follow
inputWantErrMap: map[*pbs.CreateGroupRequest]error{
{Id: globalGroup.PublicId}: nil,
{Id: org1Group.PublicId}: nil,
{Id: proj1Group.PublicId}: nil,
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
}
internal/iam/testing.go
Outdated
ctx := context.Background() | ||
rw := db.New(conn) | ||
repo, err := NewRepository(ctx, rw, rw, kmsCache) | ||
require.NoError(t, err) | ||
u, err := NewUser(ctx, scopeID) | ||
require.NoError(t, err) | ||
user, err := repo.CreateUser(ctx, u) | ||
require.NoError(t, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part of it can be done with iam.TestUser
require.NoError(t, err) | ||
user, err := repo.CreateUser(ctx, u) | ||
require.NoError(t, err) | ||
for _, trg := range testRoleGrants { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about splitting this up some more. Have functions that only creates the target resource(direct,group or managed_group) and another function that does the associating of the target resources to roles set in TestRoleGrantsRequest
by type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO that makes writing the test table more complicated since they cannot be normalized across all types of grants associations.
I wanted to incorporate all grants type to under one setup interface (func() *iam.User
) so the table-driven tests can use the same table so tests don't need to be repeated. I'm happy to make them more distinct though but I'm afraid people might ended up ignoring the more complicated test setup (like LDAP/OIDC)
44f89b4
to
4c13c6a
Compare
// TestRoleWithGrants creates a role suitable for testing along with grants | ||
// Functional options for GrantScopes aren't used to express that | ||
// this function does not provide any default grant scope unlike TestRole | ||
func TestRoleWithGrants(t testing.TB, conn *db.DB, scopeId string, grantScopeIDs []string, grants []string) *Role { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will be moved to an unexported function if the setup pattern is accepted
Add tests that validate covering grants in preparation for grants system rework