mirror of
https://github.com/bitwarden/server
synced 2025-12-16 08:13:33 +00:00
[PM-25015] Add performance tests for Admin Console endpoints (#6235)
* Add GroupsRecipe to manage group creation and user relationships in organizations
* Add CollectionsRecipe to manage collection creation and user relationships in organizations
* Refactor OrganizationUsersControllerPerformanceTests to enhance performance testing and add new test cases
* Add OrganizationDomainRecipe to add verified domains for organizations
* Add more tests to OrganizationUsersControllerPerformanceTests and enhance seeding logic for organizations
- Updated performance tests to use dynamic domain generation for organization users.
- Refactored seeding methods in OrganizationWithUsersRecipe to accept user status and type.
- Modified AddToOrganization methods in CollectionsRecipe and GroupsRecipe to return created IDs.
- Adjusted DbSeederUtility to align with new seeding method signatures.
* Enhance OrganizationSeeder with additional configuration options and update seat calculation in OrganizationWithUsersRecipe to ensure a minimum of 1000 seats.
* Add performance tests for Groups, Organizations, Organization Users, and Provider Organizations controllers
- Introduced `GroupsControllerPerformanceTests` to validate the performance of the PutGroupAsync method.
- Added `OrganizationsControllerPerformanceTests` with multiple tests including DeleteOrganizationAsync, DeleteOrganizationWithTokenAsync, PostStorageAsync, and CreateWithoutPaymentAsync.
- Enhanced `OrganizationUsersControllerPerformanceTests` with DeleteSingleUserAccountAsync and InviteUsersAsync methods to test user account deletion and bulk invitations.
- Created `ProviderOrganizationsControllerPerformanceTests` to assess the performance of deleting provider organizations.
These tests ensure the reliability and efficiency of the respective controller actions under various scenarios.
* Refactor GroupsControllerPerformanceTests to use parameterized tests
- Renamed `GroupsControllerPerformanceTest` to `GroupsControllerPerformanceTests` for consistency.
- Updated `PutGroupAsync` method to use `[Theory]` with `InlineData` for dynamic user and collection counts.
- Adjusted organization user and collection seeding logic to utilize the new parameters.
- Enhanced logging to provide clearer performance metrics during tests.
* Update domain generation in GroupsControllerPerformanceTests for improved test consistency
* Remove ProviderOrganizationsControllerPerformanceTests
* Refactor performance tests for Groups, Organizations, and Organization Users controllers
- Updated method names for clarity and consistency, e.g., `PutGroupAsync` to `UpdateGroup_WithUsersAndCollections`.
- Enhanced test documentation with XML comments to describe the purpose of each test.
- Improved domain generation logic for consistency across tests.
- Adjusted logging to provide detailed performance metrics during test execution.
- Renamed several test methods to better reflect their functionality.
* Refactor performance tests in Organizations and Organization Users controllers
- Updated tests to use parameterized `[Theory]` attributes with `InlineData` for dynamic user, collection, and group counts.
- Enhanced logging to include detailed metrics such as user and collection counts during test execution.
- Marked several tests as skipped for performance considerations.
- Removed unused code and improved organization of test methods for clarity.
* Add bulk reinvite users performance test to OrganizationUsersControllerPerformanceTests
- Implemented a new performance test for the POST /organizations/{orgId}/users/reinvite endpoint.
- Utilized parameterized testing with `[Theory]` and `InlineData` to evaluate performance with varying user counts.
- Enhanced logging to capture request duration and response status for better performance insights.
- Updated OrganizationSeeder to conditionally set email based on user status during seeding.
* Refactor domain generation in performance tests to use OrganizationTestHelpers
- Updated domain generation logic in GroupsControllerPerformanceTests, OrganizationsControllerPerformanceTests, and OrganizationUsersControllerPerformanceTests to utilize the new GenerateRandomDomain method from OrganizationTestHelpers.
- This change enhances consistency and readability across the tests by centralizing domain generation logic.
* Update CollectionsRecipe to have better readability
* Update GroupsRecipe to have better readability
* Refactor authentication in performance tests to use centralized helper method. This change reduces code duplication across Groups, Organizations, and OrganizationUsers controller tests by implementing the `AuthenticateClientAsync` method in a new `PerformanceTestHelpers` class.
* Refactor OrganizationUsersControllerPerformanceTests to filter organization users by OrganizationId.
* Refactor CreateOrganizationUser method to improve handling of user status and key assignment based on invitation and confirmation states.
* Add XML documentation for CreateOrganizationUser method to clarify user status handling
This commit is contained in:
94
util/Seeder/Recipes/GroupsRecipe.cs
Normal file
94
util/Seeder/Recipes/GroupsRecipe.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
|
||||
namespace Bit.Seeder.Recipes;
|
||||
|
||||
public class GroupsRecipe(DatabaseContext db)
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds groups to an organization and creates relationships between users and groups.
|
||||
/// </summary>
|
||||
/// <param name="organizationId">The ID of the organization to add groups to.</param>
|
||||
/// <param name="groups">The number of groups to add.</param>
|
||||
/// <param name="organizationUserIds">The IDs of the users to create relationships with.</param>
|
||||
/// <param name="maxUsersWithRelationships">The maximum number of users to create relationships with.</param>
|
||||
public List<Guid> AddToOrganization(Guid organizationId, int groups, List<Guid> organizationUserIds, int maxUsersWithRelationships = 1000)
|
||||
{
|
||||
var groupList = CreateAndSaveGroups(organizationId, groups);
|
||||
|
||||
if (groupList.Any())
|
||||
{
|
||||
CreateAndSaveGroupUserRelationships(groupList, organizationUserIds, maxUsersWithRelationships);
|
||||
}
|
||||
|
||||
return groupList.Select(g => g.Id).ToList();
|
||||
}
|
||||
|
||||
private List<Core.AdminConsole.Entities.Group> CreateAndSaveGroups(Guid organizationId, int count)
|
||||
{
|
||||
var groupList = new List<Core.AdminConsole.Entities.Group>();
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
groupList.Add(new Core.AdminConsole.Entities.Group
|
||||
{
|
||||
Id = CoreHelpers.GenerateComb(),
|
||||
OrganizationId = organizationId,
|
||||
Name = $"Group {i + 1}"
|
||||
});
|
||||
}
|
||||
|
||||
if (groupList.Any())
|
||||
{
|
||||
db.BulkCopy(groupList);
|
||||
}
|
||||
|
||||
return groupList;
|
||||
}
|
||||
|
||||
private void CreateAndSaveGroupUserRelationships(
|
||||
List<Core.AdminConsole.Entities.Group> groups,
|
||||
List<Guid> organizationUserIds,
|
||||
int maxUsersWithRelationships)
|
||||
{
|
||||
if (!organizationUserIds.Any() || maxUsersWithRelationships <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var groupUsers = BuildGroupUserRelationships(groups, organizationUserIds, maxUsersWithRelationships);
|
||||
|
||||
if (groupUsers.Any())
|
||||
{
|
||||
db.BulkCopy(groupUsers);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates user-to-group relationships with distributed assignment patterns for realistic test data.
|
||||
/// Each user is assigned to one group, distributed evenly across available groups.
|
||||
/// </summary>
|
||||
private List<Core.AdminConsole.Entities.GroupUser> BuildGroupUserRelationships(
|
||||
List<Core.AdminConsole.Entities.Group> groups,
|
||||
List<Guid> organizationUserIds,
|
||||
int maxUsersWithRelationships)
|
||||
{
|
||||
var maxRelationships = Math.Min(organizationUserIds.Count, maxUsersWithRelationships);
|
||||
var groupUsers = new List<Core.AdminConsole.Entities.GroupUser>();
|
||||
|
||||
for (var i = 0; i < maxRelationships; i++)
|
||||
{
|
||||
var orgUserId = organizationUserIds[i];
|
||||
var groupIndex = i % groups.Count; // Round-robin distribution across groups
|
||||
|
||||
groupUsers.Add(new Core.AdminConsole.Entities.GroupUser
|
||||
{
|
||||
GroupId = groups[groupIndex].Id,
|
||||
OrganizationUserId = orgUserId
|
||||
});
|
||||
}
|
||||
|
||||
return groupUsers;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user