* Add bulk set (replace) channel memberships API
PUT /api/v4/channels/{channel_id}/members accepts a complete desired
membership list and reconciles it against the current state, adding
missing users and removing extras while leaving existing members
untouched. Results stream back as NDJSON with configurable batch size
and delay to manage server load. Sysadmin only. Private channels
cannot be emptied entirely.
Rows created before the CreatedBy/UpdatedBy columns were added have NULL
in those fields, causing a scan error when reading them. Wraps those
columns with COALESCE(..., '') in the tableSelectQuery and in the Upsert
RETURNING clause.
Also removes the propertyValueColumns shared variable, inlining the
column lists directly in each INSERT statement to match the pattern used
in the property field store.
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* Add pluggable AI actions menu with rewrite submenu and plugin extension point
* Use cascading hover popover for AI actions submenus
* Fix lint errors in AI actions menu and related files
* Update i18n strings for AI actions menu
* Fix coding guideline violations in AI actions menu and tests
* Fix spacing
* Fix stylelint errors in use_rewrite.scss
* Support ReactNode for AI action menu item text
* Fix empty menu guard, keyboard a11y, and rewrite follow-up placeholder
* Hide rewrite actions while a rewrite is in progress
* Remove subMenuHeader from plugin API and pass isRHS context to plugin components
* Support simple click actions in AI action menu plugin API
* Fix import order in ai_actions_menu tests
* Flip AI actions submenu to open left when insufficient space on right
Adapts the viewport-aware positioning pattern from the existing SubMenu
component so the cascading submenu renders on the side with more space.
* Only flip submenu to left when right space is insufficient
run-shard-tests.sh called gotestsum directly without --format, so it
fell back to gotestsum's default (pkgname) instead of the testname
format set by the Makefile. Pass --format "${GOTESTSUM_FORMAT:-testname}"
to match the Makefile default.
Co-authored-by: Mattermost Build <build@mattermost.com>
Replace the unquoted heredoc (which embedded GITHUB_HEAD_REF into a
generated script) with a cp of the existing run-shard-tests.sh, which
already handles the light-only case. Pass BUILD_NUMBER and TEST_TARGET
as explicit docker env vars instead of interpolating them into script
content.
TestChannelStore sub-tests create channels, members, and team members
using fake TeamIds and UserIds (model.NewId() for non-existent rows).
These records are left in the database and cause integrity tests
(TestCheck*) running in the same binary to fail their full-table scans.
Register a t.Cleanup on TestChannelStore that purges the affected
tables entirely. A blanket purge is safe: the schema enforces no FK
constraints, and every test suite creates its own data independently.
* Add search engine health Prometheus metric
Expose mattermost_search_engine_status as a GaugeFunc that
returns 0 when ES/OS is configured but unreachable, and 1
otherwise. This lets SRE build Grafana alerts for the case
where the search backend silently falls back to database
search (as happened on Hub with a misconfigured OpenSearch).
The gauge reads the IsHealthy flag set by the engine watcher,
so it fires on the first health-check failure (~60 s) rather
than waiting for the engine to be fully stopped.
* Test the new search engine status gauge
* Add health flag to fast-fail when ES is offline
When Elasticsearch goes offline, the watcher takes up to 3 health
check cycles (~180 s) to detect the outage and stop the engine.
During that window every search query blocks for 30 s before
falling back to the database, and indexing goroutines pile up
unboundedly — causing server-wide slowness, posting failures,
and duplicate posts from client retries (MM-66612).
Introduce a `healthy` atomic flag on each ES/OpenSearch engine.
The watcher sets it to false on the *first* health-check failure
and back to true on success. `Broker.GetActiveEngines()` now
requires both `IsActive()` and `IsHealthy()`, so all search and
indexing operations skip the unhealthy engine immediately. The
existing 3-failure stop/restart cycle is unchanged and continues
to handle full recovery.
* Fix other tests
* Fix unrelated flaky test
* Use atomic.int32 everywhere
* Revert "Fix unrelated flaky test"
This reverts commit a289015637.
* Improve coverage for ActiveEngine/GetActiveEngines
* Document expectations on SearchEngineInterface
* Use mock.On("call").Unset
* Remove healthCalls to avoid a flaky test
* Be explicit on Unset
* Log any change in the health of the search engine
* Test the healthy<->unhealthy changes are logged
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* [MM-68266] Pass through menu props to popout menu item, guard at menu definition to avoid null component blocking keyboard navigation
* fix tests
* Update webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/sidebar_channel_menu.test.tsx
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* MM-66937 Remove existing code for handling composition in SuggestionBox
This breaks the ability to autocomplete on Korean characters that haven't been
committed on Firefox. Both the previous and new versions seem to work fine on
Chrome though.
* Add E2E test for SuggestionBox composition in Find Channels modal
* Fix misnamed field
* MM-68235: Rename user-visible "Custom Profile Attributes" to "User Attributes"
Update all English i18n translation values and inline
defaultMessage strings to use the current product name
"User Attributes" instead of the old "Custom Profile
Attributes" / CPA naming.
Add naming-history comments to key CPA source files
(model, app, api4, admin component) explaining that
internal identifiers retain the old naming for backward
compatibility with REST APIs, WebSocket events, and the
Property System Architecture group name. This helps
future developers understand the mapping without needing
to track down the rename history.
* Fix missed lowercase "custom profile attribute" strings
* MM-67505 Add AnalyticsQueryTimeout setting and use when refreshing materialized views
* Fix last minute i18n change
* Disallow 0 values for AnalyticsQueryTimeout
* Fix E2E test config
* Fix post store tests crashing
* Update snapshot and revert accidental changes to it
* Add HealthCheck to search engine interface
The watcher (next commit) needs a way to probe whether
ES/OS is still reachable. Each backend does a cluster
health request with a 5 s timeout, snapshotting the
client under the read lock so the network call doesn't
block Stop()/Start().
* Add search engine background watcher
The old fire-and-forget ps.Go() calls for ES startup
had no retry, no health monitoring, and no backoff.
If Start() failed at boot the engine stayed down until
the next config change or server restart.
Replace with a single watcher goroutine that:
- retries Start() with exponential backoff (15 s–5 m)
- runs periodic health checks once active
- stops the engine after N consecutive failures
- reacts immediately to config/license changes
- shuts down cleanly via context cancellation
* Add tests for search engine watcher
Covers retry-then-health transition, exponential
backoff capping, disable/enable park-unpark via
notify, intermittent vs threshold health failures,
and edge cases (Start ok but not active, rapid
config changes, failure counter reset).
* Address review comments
* make i18n-extract
* Make Stop() a no-op if already stopped
Both Elasticsearch and OpenSearch Stop() methods returned an error
when the engine was already stopped. This forced every caller to
handle or ignore a non-error condition. Returning nil instead is
more idiomatic and simplifies all call sites.
* Simplify config listener branches
Merge the connectionChanged and startingES/stoppingES branches
into one. Since Stop() is now a no-op when already stopped, we
can always call Stop() then notify the watcher regardless of
which condition triggered the change.
* Restore license listener conditional order
Keep the original order (license-added first, license-removed
second) to reduce diff noise. The conditions are mutually
exclusive so the order has no semantic effect.
* Log consecutive failures in retry phase
Track and log consecutiveFailures when Start() fails or returns
nil but the engine is not active, so operators can see how many
attempts have been made alongside the backoff duration.
* Clarify health check timer reset placement
Add a comment explaining why the timer reset lives outside the
if/else: both success and below-threshold failure share the same
health interval, while the critical-failure path continues before
reaching this point.
* Remove nested select in disabled-engine path
Replace the nested select block with timer.Stop() + continue.
The main loop's select already handles ctx.Done() and notify,
so stopping the timer is enough to park until one of those fires.
* Add context.Context to Start()
Accept a context in SearchEngineInterface.Start() and propagate
it to all network calls (checkMaxVersion, fetchServerInfo, index
template creation). This lets the watcher's cancellable context
flow through to the HTTP client, so a stuck Start() call returns
promptly on shutdown instead of blocking until TCP timeout.
* Simplify startSearchEngineWatcher comment
Focus on the actual reason (long-lived, owns its lifecycle)
rather than the shutdown-blocking detail, which is less relevant
now that Start() accepts a cancellable context.
* Make the comment on the goroutine more accurate
* Fix log
* Revert the branches merge
This was causing a race condition in the TestElasticsearchAggregation
test.
* Own Start/Stop by the engine watcher
The config listener simply notifies now, so it's easier to follow the
logic of the calls.
* Refactor the engine watcher into its own type
Simplify the code by:
1. Moving the whole watcher into its own type, so that the
PlatformService contains an instance of it, instead of all the locks
and channels
2. Splitting the main loop into functions. John Carmack may not like
this, but it's way easier to read and follow.
* make i18n-extract
* Rename notify > reevaluate
* Park the watcher if there is no license
* Call reevaluate from within requestRestart
* Use RequestTimeoutSeconds instead of hardcoded 5s
* Use atomic.Int32 in the tests as well
* Add defensive code ta watcher exit
Stop the engine if it was still running when the watcher exits, having a
safety net for scenarios like race conditions between Start and a
cancelled context.
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* Fix FIPS-incompatible passwords and config in e2e test suites
FIPS OpenSSL requires PBKDF2 HMAC keys >= 14 bytes, so the server
now enforces PasswordSettings.MinimumLength >= 14 under FIPS builds.
The e2e suites were failing (Cypress 0/447, Playwright 16/353) because
they used short passwords and set MinimumLength below the FIPS floor.
- Add newTestPassword() to both Cypress and Playwright utilities,
returning a static FIPS-compliant password (>= 14 chars)
- Replace all short hardcoded Mattermost user passwords ('passwd',
'Test123456!', 'Testing123', 'Password123!') with newTestPassword()
- Raise PasswordSettings.MinimumLength from 5 to 14 in default configs
- Update password validation tests for the FIPS minimum (error messages,
default expectations, test password lengths)
* Fix additional FIPS e2e test failures
- Revert server-constant-dependent assertions (MinimumLength defaults
and validation errors) since those depend on FIPS build tags, not config
- Fix short hardcoded passwords in signup, forgot_password, and
existing_email_address specs to use newTestPassword()
- Fix password_spec cancel test to use a different password than
testUser.password (both resolve to newTestPassword())
- Fix Playwright password reset test to use newTestPassword() instead
of pw.random.id() (7 chars, too short for MinimumLength=14)
- Update password help text assertions to match MinimumLength=14 config
- Use regex for Playwright signup page password error locator
- Fix import order in ABAC support.ts
* Fix FIPS vs non-FIPS build-dependent e2e test assertions
The server's password minimum constants differ between FIPS (14) and
non-FIPS (8/5) builds. Make three test assertions adaptive:
- MM-T1770: Accept default MinimumLength of either 8 or 14
- MM-T1771: Match validation error with either 5 or 14 as the minimum
- MM-T1773: Reload after save and compare against actual server config,
since saving MinimumLength=5 (webapp default) is rejected on FIPS
* e2e: upgrade demo plugin to v0.11.0 and configure required settings
* update demo plugin download link
---------
Co-authored-by: sabril <5334504+saturninoabril@users.noreply.github.com>
* MM-63588: Add e2e tests for System Console Custom Profile Attributes
Add Playwright e2e tests for the System Console User Attributes page,
covering CRUD operations for custom profile attribute field definitions.
Tests cover:
- Page navigation and empty state display
- Creating text, select, and multiselect attributes with options
- Editing attribute names
- Deleting attributes (saved and unsaved)
- Duplicating attributes
- Changing attribute types (Text to Phone)
- Configuring visibility (Always show/Hide when empty/Always hide)
- Toggling "Editable by users" setting
- Batch creation (multiple attributes at once)
- Persistence verification after page reload
- Validation warnings (empty name, duplicate names)
Follows the same patterns established in MM-62558 / PR #30722 for
Profile Popup CPA tests, reusing shared helpers for field setup/cleanup.
* Fix 6 failing e2e tests for System Console User Attributes
- Remove .clear() before .fill() to prevent value-based locators from
going stale (edit name, persist after reload tests)
- Hover on visibility submenu instead of click, use force:true to handle
DOM detach during menu animation (visibility test)
- Press Escape to close dot menu before clicking Save, since the
"Editable by users" toggle keeps the menu open (editable test)
- Fix expected validation text: use "Attribute names must be unique."
instead of "Attribute name already taken." (duplicate names test)
- Increase timeout for Save button disabled assertion after deleting
unsaved attribute (delete unsaved test)
* Fix stale locators, flaky save check, and document dirty-state bug
- Use data-testid locators instead of value-based selectors for inputs
that get mutated by fill() (edit name + persist reload tests)
- Wait for Save button to return to disabled after save before API
check to avoid flaky field-not-found failures
- Add test.fail() for Save-stays-enabled bug after deleting an unsaved
row so CI passes today and alerts when the app bug is fixed
- Add LOCATOR NOTE to file header explaining the lazy locator pitfall
* Address CodeRabbit review: save helper, locator fix, test rename
- Add saveAndWaitForSettled() helper and apply to all 11 save paths
for consistent post-save stabilization before API verification
- Fix deptInput locator: use input[value] instead of broken
filter({hasText}) which doesn't match input element children
- Rename "different types" test to "multiple text attributes" to
match actual coverage
* MM-63588: add SystemProperties page object and refactor spec to POM
Extract all UI selectors from user_attributes.spec.ts into a
SystemProperties page object class, eliminating inline selectors
from the test file. Replace coarse networkidle with waitForResponse
on the actual save API endpoint.
* fix playwright e2e test failures
- selectType was failing as 'select' caught both 'select' and 'multi-select'
- Prior behavior where Save button wasn't returning to disabled appears to be working now, removing test.fail()
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* Reapply "Strip remote_id field from user patch API requests (#35910)" (#35996)
This reverts commit d1ca297721.
* Fix SetUserRemoteID to use test's own database in parallel mode
Replace testlib.SetUserRemoteID (which used mainHelper's shared
database) with a squirrel query against GetInternalMasterDB(), which
resolves to the correct per-test pooled database under parallel
execution.
* fix: add explicit permission grant in team members test
TestGetTeamMembersForUserRoleDataSanitization was relying on a permission
side-effect leaked from concurrent tests. Under fullyparallel, another test
temporarily adds PermissionReadOtherUsersTeams to system_user role, which
the team admin subtest accidentally benefits from. Under sequential execution
(binary parameters mode), no concurrent test leaks this permission, so the
team admin correctly gets 403.
Fix by explicitly granting ReadOtherUsersTeams in the subtest setup, matching
the pattern used in adjacent subtests.
Release Note
NONE
Co-authored-by: Claude <claude@anthropic.com>
* fix: remove explanatory comment per review feedback
---------
Co-authored-by: Claude <claude@anthropic.com>
* Remove system_secure_connection_manager role
The dedicated role for delegating secure connection management is no
longer needed. The manage_secure_connections permission remains and
continues to be granted to system admins via AllPermissions.
Removes the role definition, migration, permissions migration, UI
components, i18n strings, and all associated tests across server,
webapp, and e2e-tests.
The allow-failure input was defined twice in the workflow_call inputs,
causing GitHub Actions to reject the workflow with 0 jobs on master push.
Duplicate was introduced in #35743 merge.
Release Note
NONE
Co-authored-by: Claude <claude@anthropic.com>
* ci: re-enable server test coverage with 4-shard parallelism
The test-coverage job was disabled due to OOM failures when running all
tests with coverage instrumentation in a single process. Re-enable it
by distributing the workload across 4 parallel runners using the shard
infrastructure from the sharding PRs.
Changes:
- Replace disabled single-runner test-coverage with 4-shard matrix
- Add merge-coverage job to combine per-shard cover.out files
- Upload merged coverage to Codecov with server flag
- Skip per-shard Codecov upload when sharding is active
- Add coverage profile merging to run-shard-tests.sh for multi-run shards
- Restore original condition: skip coverage on release branch PRs
- Keep fullyparallel=true (fast within each shard)
- Keep continue-on-error=true (coverage never blocks PRs)
Co-authored-by: Claude <claude@anthropic.com>
* fix: disable fullyparallel for coverage shards
t.Parallel() + t.Setenv() panics kill entire test binaries under
fullyparallel mode. With 4-shard splitting, serial execution within
each shard should still be fast enough (~15 min). We can re-enable
fullyparallel once the incompatible tests are fixed.
Co-authored-by: Claude <claude@anthropic.com>
* fix: add checkout to coverage merge job for Codecov file mapping
Codecov needs the source tree to map coverage data to files.
Without checkout, the upload succeeds but reports 0% coverage
because it can't associate cover.out lines with source files.
Co-authored-by: Claude <claude@anthropic.com>
* ci: add codecov.yml and retain merged coverage artifact
Add codecov.yml with:
- Project coverage: track against parent commit, 1% threshold, advisory
- Patch coverage: 50% target for new code, advisory (warns, doesn't block)
- Ignore generated code (retrylayer, timerlayer, serial_gen, mocks,
storetest, plugintest, searchtest) — these inflate the denominator
from 146K to 100K statements, rebasing coverage from 36% to 53%
- PR comments on coverage changes with condensed layout
Save merged cover.out as artifact with 30-day retention (~3.5MB/run).
90-day retention was considered (~6.3GB total vs ~2.1GB at 30 days)
but deferred to keep storage costs low.
#### Release Note
```release-note
NONE
```
Co-authored-by: Claude <claude@anthropic.com>
* ci: add codecov.yml to exclude generated code and enable PR comments (#35748)
* ci: add codecov.yml to exclude generated code and enable PR comments
Add Codecov configuration to improve coverage signal quality:
- Exclude generated code from coverage denominator:
- store/retrylayer (~10k stmts, auto-generated retry wrappers)
- store/timerlayer (~14k lines, auto-generated timing wrappers)
- *_serial_gen.go (serialization codegen)
- **/mocks (mockery-generated mocks)
- Exclude test infrastructure:
- store/storetest (~63k lines, test helpers not production code)
- plugin/plugintest (plugin test helpers)
- Exclude thin wrappers:
- model/client4.go (~4k stmts, HTTP client methods tested via integration)
- Enable PR comments with condensed layout
- Set project threshold at 0.5% drop tolerance
- Set patch target at 60% for new/changed lines
This rebases the effective coverage metric from ~33.8% to ~43% by
removing ~50k non-production statements from the denominator, giving
a more accurate picture of actual test coverage.
Co-authored-by: Claude <claude@anthropic.com>
* Update codecov.yml
---------
Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
* fix: bump upload-artifact to v7 and add client4.go to codecov ignore
- Align upload-artifact pin with the rest of the workflow (v4 → v7)
- Add model/client4.go to codecov.yml ignore list as documented in PR description
Co-authored-by: Claude <claude@anthropic.com>
* fix(ci): address Jesse review feedback on coverage sharding
- Remove client4.go from codecov ignore list (coverage is meaningful)
- Remove historical comment block above test-coverage job
- Set fullyparallel back to true (safe per-shard since each runs
different packages; parallel test fixes tracked in #35751)
- Replace merge-coverage job with per-shard Codecov uploads using
flags parameter; configure after_n_builds: 4 so Codecov waits for
all shards before reporting status
- Add clarifying comment in run-shard-tests.sh explaining intra-shard
coverage merge (multiple gotestsum runs) vs cross-shard merge
(handled natively by Codecov)
- Simplify codecov.yml: remove verbose comments, use informational
status checks, streamlined ignore list
Co-authored-by: Claude <claude@anthropic.com>
* fix(ci): set fullyparallel back to false for coverage shards
Coverage shards 1-3 failed with hundreds of test failures because
fullyparallel: true causes panics and races in tests that use
t.Setenv, os.Setenv, and os.Chdir without parallel-safe alternatives.
The parallel-safety fixes are tracked in a separate PR chain:
- #35746: t.Setenv → test hooks
- #35749: os.Setenv → parallel-safe alternatives
- #35750: os.Chdir → t.Chdir
- #35751: flip fullyparallel: true (final step)
Once that chain merges, fullyparallel can be enabled for coverage too.
Co-authored-by: Claude <claude@anthropic.com>
* fix(ci): split fullyparallel and allow-failure into separate inputs
Previously fullyparallel controlled both parallel test execution AND
continue-on-error, meaning disabling parallelism also made coverage
failures blocking. Split into two independent inputs:
- fullyparallel: controls ENABLE_FULLY_PARALLEL_TESTS (test execution)
- allow-failure: controls continue-on-error (advisory vs blocking)
Coverage shards now run with fullyparallel: true (Claudio's original
approach) and allow-failure: true (failures don't block PRs until
parallel-safety fixes land in #35746 → #35751).
Co-authored-by: Claude <claude@anthropic.com>
* ci: use per-flag after_n_builds for server and webapp coverage
Replace the global after_n_builds: 2 with per-flag values:
- server: after_n_builds: 4 (one per shard)
- webapp: after_n_builds: 1 (single merged upload)
Tag the webapp Codecov upload with flags: webapp so each flag
independently waits for its expected upload count. This prevents
Codecov from firing notifications with incomplete data when the
webapp upload arrives before all server shards complete.
Addresses review feedback from @esarafianou.
Co-authored-by: Claude <claude@anthropic.com>
* fix: consolidate codecov config into .github/codecov.yml
Move all codecov configuration into the existing .github/codecov.yml
instead of introducing a duplicate file at the repo root. Merges
improvements from the root file (broader ignore list, informational
statuses, require_ci_to_pass: false) while preserving the webapp flag
from the original config. Updates after_n_builds to 5 (4 server + 1
webapp).
Co-authored-by: Claude <claude@anthropic.com>
---------
Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
* adds team member data sanitizing
* assert using require
* adds data sanitizing to team members for user endpoint
* team admin data visibility now tests with different user
* Fix interactive dialog bugs: dynamic select lookups, radio values, and field refresh
- Cache sanitized fields in AppsForm to preserve object identity across
renders, preventing AsyncSelect from remounting and re-triggering
dynamic select lookups on every keystroke in any field
- Normalize radio field default values to plain strings in getDefaultValue()
so the value shape is consistent with what RadioSetting.onChange returns
(e.target.value). Accept both string and {label, value} object shapes
downstream for backwards compatibility.
- Fix radio field [object Object] in submission by extracting .value from
AppSelectOption objects in convertAppFormValuesToDialogSubmission
- Include selected_field in refresh submission so plugins know which field
triggered the refresh. Use a shallow copy of accumulatedValues to avoid
permanently contaminating the accumulated state.
- Send empty string for cleared select fields in refresh submissions.
Previously, extractPrimitiveValues skipped null values and the spread
merge never overwrote stale accumulated keys.
* refactor(brand_image_setting): migrate to function component
* test(brand_image_setting): update tests
Migrated tests to React Testing Library.
* refactor(brand_image_setting): wrap functions with useCallback
* test(brand_image_setting): use nock to mock fetch api
* test(brand_image_setting): use findby query instead of getby
* test(brand_image_setting): remove unnecessary scope assertion
* chore(brand_image_setting): split useEffect into two
Also extracted the handleSave function and wrapped it in useCallback.
* test(brand_image_setting): add e2e test for deleting brand image
* test(brand_image_setting): use destructured functions
* chore: delete unnecessary comment
* Revert "test(brand_image_setting): use destructured functions"
This reverts commit 71dc6628ed.
* Fix bad merge
* Fully revert changes to test from merge
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Binary parameters tests run unsharded on a single runner. With
fullyparallel enabled, all ~755 api4 tests run concurrently, causing
resource exhaustion (too many server instances, WebSocket hubs, and DB
connections). The test binary gets killed after 11 minutes with no
individual test failures — just overwhelmed resources.
Disabling fullyparallel for this specific job lets binary parameters
tests pass while we evaluate moving them to a nightly/weekly schedule.
Co-authored-by: Claude <claude@anthropic.com>
* Fixed a bug where signup link showed up when signup was disabled
* Removed unused component
* fixed test name
* CI
* fixed a test
* fixed a commit
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* Strip remote_id from user patch API requests
* Ignore remote_id in user update API endpoints
Add SetUserRemoteID test helper in testlib to set remote_id via direct SQL,
bypassing the now-protected store Update method. Update existing tests in
app and api4 packages to use the new helper.
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* ci: enable fullyparallel mode for server tests
Replace os.Setenv, os.Chdir, and global state mutations with
parallel-safe alternatives (t.Setenv, t.Chdir, test hooks) across
37 files. Refactor GetLogRootPath and MM_INSTALL_TYPE to use
package-level test hooks instead of environment variables.
This enables gotestsum --fullparallel, allowing all test packages
to run with maximum parallelism within each shard.
Co-authored-by: Claude <claude@anthropic.com>
* ci: split fullyparallel from continue-on-error in workflow template
- Add new boolean input 'allow-failure' separate from 'fullyparallel'
- Change continue-on-error to use allow-failure instead of fullyparallel
- Update server-ci.yml to pass allow-failure: true for test coverage job
- Allows independent control of parallel execution and failure tolerance
Co-authored-by: Claude <claude@anthropic.com>
* fix: protect TestOverrideLogRootPath with sync.Mutex for parallel tests
- Replace global var TestOverrideLogRootPath with mutex-protected functions
- Add SetTestOverrideLogRootPath() and getTestOverrideLogRootPath() functions
- Update GetLogRootPath() to use thread-safe getter
- Update all test files to use SetTestOverrideLogRootPath() with t.Cleanup()
- Fixes race condition when running tests with t.Parallel()
Co-authored-by: Claude <claude@anthropic.com>
* fix: configure audit settings before server setup in tests
- Move ExperimentalAuditSettings from UpdateConfig() to config defaults
- Pass audit config via app.Config() option in SetupWithServerOptions()
- Fixes audit test setup ordering to configure BEFORE server initialization
- Resolves CodeRabbit's audit config timing issue in api4 tests
Co-authored-by: Claude <claude@anthropic.com>
* fix: implement SetTestOverrideLogRootPath mutex in logger.go
The previous commit updated test callers to use SetTestOverrideLogRootPath()
but didn't actually create the function in config/logger.go, causing build
failures across all CI shards. This commit:
- Replaces the exported var TestOverrideLogRootPath with mutex-protected
unexported state (testOverrideLogRootPath + testOverrideLogRootMu)
- Adds exported SetTestOverrideLogRootPath() setter
- Adds unexported getTestOverrideLogRootPath() getter
- Updates GetLogRootPath() to use the thread-safe getter
- Fixes log_test.go callers that were missed in the previous commit
Co-authored-by: Claude <claude@anthropic.com>
* fix(test): use SetupConfig for access_control feature flag registration
InitAccessControlPolicy() checks FeatureFlags.AttributeBasedAccessControl
at route registration time during server startup. Setting the flag via
UpdateConfig after Setup() is too late — routes are never registered
and API calls return 404.
Use SetupConfig() to pass the feature flag in the initial config before
server startup, ensuring routes are properly registered.
Co-authored-by: Claude <claude@anthropic.com>
* fix(test): restore BurnOnRead flag state in TestRevealPost subtest
The 'feature not enabled' subtest disables BurnOnRead without restoring
it via t.Cleanup. Subsequent subtests inherit the disabled state, which
can cause 501 errors when they expect the feature to be available.
Add t.Cleanup to restore FeatureFlags.BurnOnRead = true after the
subtest completes.
Co-authored-by: Claude <claude@anthropic.com>
* fix(test): restore EnableSharedChannelsMemberSync flag via t.Cleanup
The test disables EnableSharedChannelsMemberSync without restoring it.
If the subtest exits early (e.g., require failure), later sibling
subtests inherit a disabled flag and become flaky.
Add t.Cleanup to restore the flag after the subtest completes.
Co-authored-by: Claude <claude@anthropic.com>
* Fix test parallelism: use instance-scoped overrides and init-time audit config
Replace package-level test globals (TestOverrideInstallType,
SetTestOverrideLogRootPath) with fields on PlatformService so each test
gets its own instance without process-wide mutation. Fix three audit
tests (TestUserLoginAudit, TestLogoutAuditAuthStatus,
TestUpdatePasswordAudit) that configured the audit logger after server
init — the audit logger only reads config at startup, so pass audit
settings via app.Config() at init time instead.
Also revert the Go 1.24.13 downgrade and bump mattermost-govet to
v2.0.2 for Go 1.25.8 compatibility.
* Fix audit unit tests
* Fix MMCLOUDURL unit tests
* Fixed unit tests using MM_NOTIFY_ADMIN_COOL_OFF_DAYS
* Make app migrations idempotent for parallel test safety
Change System().Save() to System().SaveOrUpdate() in all migration
completion markers. When two parallel tests share a database pool entry,
both may race through the check-then-insert migration pattern. Save()
causes a duplicate key fatal crash; SaveOrUpdate() makes the second
write a harmless no-op.
* test: address review feedback on fullyparallel PR
- Use SetLogRootPathOverride() setter instead of direct field access
in platform/support_packet_test.go and platform/log_test.go (pvev)
- Restore TestGetLogRootPath in config/logger_test.go to keep
MM_LOG_PATH env var coverage; test uses t.Setenv so it runs
serially which is fine (pvev)
- Fix misleading comment in config_test.go: code uses t.Setenv,
not os.Setenv (jgheithcock)
Co-authored-by: Claude <claude@anthropic.com>
* fix: add missing os import in post_test.go
The os import was dropped during a merge conflict resolution while
burn-on-read shared channel tests from master still use os.Setenv.
Co-authored-by: Claude <claude@anthropic.com>
---------
Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: wiggin77 <wiggin77@warpmail.net>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Replace hardcoded test passwords with model.NewTestPassword()
Add model.NewTestPassword() utility that generates 14+ character
passwords meeting complexity requirements for FIPS compliance. Replace
all short hardcoded test passwords across the test suite with calls to
this function.
* Enforce FIPS compliance for passwords and HMAC keys
FIPS OpenSSL requires HMAC keys to be at least 14 bytes. PBKDF2 uses
the password as the HMAC key internally, so short passwords cause
PKCS5_PBKDF2_HMAC to fail.
- Add FIPSEnabled and PasswordFIPSMinimumLength build-tag constants
- Raise the password minimum length floor to 14 when compiled with
requirefips, applied in SetDefaults only when unset and validated
independently in IsValid
- Return ErrMismatchedHashAndPassword for too-short passwords in
PBKDF2 CompareHashAndPassword rather than a cryptic OpenSSL error
- Validate atmos/camo HMAC key length under FIPS and lengthen test
keys accordingly
- Adjust password validation tests to use PasswordFIPSMinimumLength
so they work under both FIPS and non-FIPS builds
* CI: shard FIPS test suite and extract merge template
Run FIPS tests on PRs that touch go.mod or have 'fips' in the branch
name. Shard FIPS tests across 4 runners matching the normal Postgres
suite. Extract the test result merge logic into a reusable workflow
template to deduplicate the normal and FIPS merge jobs.
* more
* Fix email test helper to respect FIPS minimum password length
* Fix test helpers to respect FIPS minimum password length
* Remove unnecessary "disable strict password requirements" blocks from test helpers
* Fix CodeRabbit review comments on PR #35905
- Add server-test-merge-template.yml to server-ci.yml pull_request.paths
so changes to the reusable merge workflow trigger Server CI validation
- Skip merge-postgres-fips-test-results job when test-postgres-normal-fips
was skipped, preventing failures due to missing artifacts
- Set guest.Password on returned guest in CreateGuestAndClient helper
to keep contract consistent with CreateUserWithClient
- Use shared LowercaseLetters/UppercaseLetters/NUMBERS/PasswordFIPSMinimumLength
constants in NewTestPassword() to avoid drift if FIPS floor changes
https://claude.ai/code/session_01HmE9QkZM3cAoXn2J7XrK2f
* Rename FIPS test artifact to match server-ci-report pattern
The server-ci-report job searches for artifacts matching "*-test-logs",
so rename from postgres-server-test-logs-fips to
postgres-server-fips-test-logs to be included in the report.
---------
Co-authored-by: Claude <noreply@anthropic.com>