Every test binary that uses TestPool builds 16 stores in parallel, each
running the full migration set. Without DisableMorphLogging() the morph
debug stream from each store flows through to the test logger (which is
configured at LvlTrace), producing tens of thousands of "migrating (up)"
lines per shard — amplified further on shards that re-run flaky tests,
since every re-run spawns a fresh TestMain and a fresh pool.
Migration failures are still surfaced: engine.ApplyAll returns the
error, sqlstore.New wraps it as "failed to apply database migrations",
and both NewTestPool callers panic on a non-nil result.
Co-authored-by: Mattermost Build <build@mattermost.com>
* Avoid setting an empty value on slash command IconURL
When `PostEnablePostIconOverride` is enabled and no icon URL is
provided, the override icon URL was being set to empty and triggering
a warning. This change updates the behavior not to set the icon at
all, avoiding the triggering of the warn message while keeping the
behavior.
* Adds an additional check to the test
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* MM-68499 - auto run sync jobs on team admin abac policy creation
* Use child-policy flow for access-control sync ownership test
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* fix: detect ADFS when IdpDescriptorURL has no trailing slash
The ADFS detection in detectSAMLProviderType was checking for "/adfs/"
(with trailing slash) but standard ADFS IdpDescriptorURL values often
end with just "/adfs" (e.g. https://adfs.company.com/adfs), causing the
provider type to show as "unknown" in support packets.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: lowercase FederationMetadata pattern for case-insensitive matching
The normalizedURL is already lowercased, so comparing against the mixed-case
literal "/FederationMetadata/" made that branch unreachable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
The new TestRegisterPluginForSharedChannels tests added in #36126 broke
master CI because RegisterPluginForSharedChannels assigned opts.Displayname
directly to RemoteCluster.Name, which IsValid validates against the slug
regex ^[a-zA-Z0-9.\-_]+$. Display names with spaces (e.g. "legacy plugin")
fail validation. The tests didn't run in the PR's final CI shard and the
issue surfaced post-merge.
Add CleanRemoteName to the public model, mirroring CleanTeamName and
CleanUsername: lowercase, replace spaces and other disallowed characters
with hyphens, trim, truncate to RemoteNameMaxLength, fall back to NewId
when the result is empty. Use it in RegisterPluginForSharedChannels so
Name is always slug-valid while DisplayName keeps the human-readable label.
This also lets real plugins register with display names containing spaces.
* MM-67979 MM-67980: Add SMTP and push proxy connectivity to support packet
Adds a `notifications` section to `diagnostics.yaml` in the support
packet with SMTP email and push proxy connectivity probe results.
- `notifications.email.status`: ok/fail/disabled based on whether
SendEmailNotifications is enabled and an SMTP connection can be
established using mail.TestConnection()
- `notifications.push.status`: ok/fail/disabled based on whether
SendPushNotifications is enabled and an HTTP GET to the configured
PushNotificationServer URL succeeds
- Error messages are included in the `error` field on failure
- No email or push notification is sent during the probe
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix: handle errcheck lint violations in support_packet_test.go
Suppress unhandled error return values from rw.WriteString calls in
the mock SMTP server used in tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: use 127.0.0.1 directly in SMTP reachability test
Replace localhost:0 with 127.0.0.1:0 for the mock SMTP listener so
that it always binds to the loopback interface. In CI Docker containers
localhost may resolve to the container IP rather than 127.0.0.1, causing
the SMTP dial to fail with connection refused. Also switch from string
manipulation to net.TCPAddr type assertion for reliable host/port
extraction.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: override MM_EMAILSETTINGS_SMTPSERVER env var in SMTP reachability test
The CI environment sets MM_EMAILSETTINGS_SMTPSERVER=inbucket via
test.env. Mattermost's config Store.Set() calls GetEnvironment()
(os.Environ()) on every UpdateConfig, so env vars silently override
any programmatic config change. Use t.Setenv before UpdateConfig so
the env var points to 127.0.0.1 for the duration of the subtest.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add model.StatusDisabled constant and use it in support_packet.go
Replace "disabled" string literals with model.StatusDisabled for
consistency with model.StatusOk and model.StatusFail.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: use utils.GetHostnameFromSiteURL, extract testPushProxyConnection helper, set LDAP StatusDisabled
- Replace manual url.Parse with utils.GetHostnameFromSiteURL (consistent with app/config.go)
- Extract push proxy HTTP check into testPushProxyConnection with TODO to move to its own package
- Set d.LDAP.Status = model.StatusDisabled when LDAP is not configured
- Replace "disabled" string literals in tests with model.StatusDisabled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add status field to ElasticSearch diagnostics with ok/fail/disabled
When indexing is enabled, reports ok or fail based on TestConfig result.
When indexing is disabled or the engine is unavailable, reports disabled.
Backend/ServerVersion/ServerPlugins are still collected when the engine
exists regardless of indexing status.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: update Happy path test for LDAP and ES StatusDisabled assertions
Both are disabled in the test environment so they now report StatusDisabled.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: use GET /version endpoint for push proxy connectivity check
Use url.JoinPath to construct the /version path safely, replacing
raw root URL access. Also validate the HTTP status code so non-2xx/3xx
responses are treated as failures.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Add XML struct tags and multi-remote registration for shared channels plugin API
Phase 1: Add xml struct tags to model types used in SyncMsg (Post, User,
Reaction, Status, PostAcknowledgement, FileInfo, SyncResponse,
MembershipChangeMsg). Add custom MarshalXML/UnmarshalXML for SyncMsg
(Users map, MentionTransforms map), StringMap, and StringInterface.
Exclude Post.Metadata, PrevStatus, and server-internal FileInfo fields
from XML. JSON serialization is unaffected.
Phase 2: Lift the one-remote-per-plugin constraint so plugins can
register multiple remotes with different SiteURLs. Add SiteURL field to
RegisterPluginOpts (defaults to "plugin_<PluginID>" for backward
compatibility). Add GetAllByPluginID and GetBySiteURL store methods.
Rewrite registration to dedup by SiteURL instead of PluginID. Add
UnregisterPluginRemoteForSharedChannels for single-remote removal with
plugin ownership validation. Validate SiteURL is non-empty in
RemoteCluster.IsValid. Simplify IsPlugin() to check PluginID only.
* ci: compile mmctl e2e tests with requirefips when FIPS_ENABLED=true
Without this, the mmctl test binary was compiled without the requirefips
tag even in the FIPS container, leaving model.FIPSEnabled=false and
PasswordSettings.MinimumLength=8. Short passwords like "somepass" passed
validation and hashing silently succeeded, giving false confidence that
the tests were FIPS-clean.
* tests: fix short password in TestUserConvertCmdF for FIPS
"Valid bot to user convert" reached ConvertBotToUser with "password"
(8 chars), which fails MinimumLength=14 on FIPS builds.
* omit error_* fields if empty, add status code
* MM-68378: Add tests for 404-delete semantics in ES/OS indexing jobs
* MM-68378: Fix empty error fields and spurious failures for OS/ES bulk deletes
- Log resp.Status unconditionally in OnFailure so status-only failures
(resp.Error nil, err nil) are always identifiable
- Downgrade per-item OnFailure log from Error to Warn; the job-level
Error log already captures the aggregate failure
- Track real failures in a separate atomic counter shared between the
OnFailure callback and the close closure; 404 deletes (document not
found) are silently skipped and not counted
- Report num_failed from the real counter in close stats; retain
stats_num_failed as the raw SDK count for reference
* [MM-68231] Tighten post info authorization
Align post info channel access with the standard read path while preserving expected public-channel discoverability. Add regression coverage for guest and compliance-mode access checks.
Made-with: Cursor
* [MM-68231] Strengthen post info test coverage
Tighten the new post info regression coverage so the guest denial case proves its setup and the compliance case asserts the expected non-compliance behavior first.
Made-with: Cursor
* [MM-68231] Expand post info authorization coverage
Add focused regression coverage for invite-team access, compliance behavior on open teams, private-channel permission boundaries, and outsider denial for DM and GM post info.
Made-with: Cursor
* Adds version to the property group model
* Ensures that the REST API rejects v1 group calls
* Ensures field version and group version match
* Simplify property groups on app layer tests
* Add GetByID to PropertyGroupStore and enforce field/group version match on update
* Simplify bits of the code
* Fix i18n and add generic errors
* Fix PropertyGroupStore mock to return stable IDs and default zero version to V1
* Fix tests that were using nonexistent group IDs
* Fix rigidness on valid group names
* Update group not found slug
* Temporary allow to use tempaltes with v1
* Explicitly including tempaltes in the IsPSAv1 check for conflict check
* Return 404 on group not found and template explicit inclusion on patch API endpoint
* Fix CPA test that would use fields from unregistered groups
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
sqlstore's TestMain calls sqlstore.InitTest (which opens postgres and
drops tables) before mainHelper.Main, so the -test.list bailout added
in #36222 never fired and shard-split discovery failed on the GitHub
host. Bail out at the top of TestMain instead, and restore HEAVY_MS
so sqlstore can still be treated as whole.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Introduce model.SanitizeFilename and model.IsValidFilename, and
apply them in genFileInfoFromReader and FileInfo.IsValid. The
sanitizer uses filepath.Base, NFC-normalizes Unicode, strips ASCII
control characters, collapses backslashes to forward slashes, and
truncates to the VARCHAR(256) fileinfo.name column width.
* fix(mmctl): prevent nil pointer panic in websocket command on connection failure
When the WebSocket connection fails immediately, Listen() closes EventChannel
via defer. Reading from a closed channel with a plain receive returns nil,
causing a panic in ToJSON(). Switch to range so the loop exits cleanly,
add a nil guard, and surface ListenError to the caller.
Fixes MM-68351
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(mmctl): add unit tests for websocket nil event and ListenError handling
Extracts the event-processing loop into processWebSocketEvents to enable
unit testing, and adds tests covering the nil-event skip and error surfacing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(mmctl): add happy-path subtest for processWebSocketEvents
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* MM-67975: Add container CPU and memory limits to support packet diagnostics
Add two new optional fields to SupportPacketDiagnostics.Server:
- container_cpu_limit (float64): effective CPU limit in CPUs (e.g. 0.5, 2.0)
- container_memory_limit_mb (uint64): memory limit in MB
Both fields are populated from cgroups v2 (/sys/fs/cgroup/memory.max and
/sys/fs/cgroup/cpu.max) on Linux. Fields use omitempty so they are absent
from the output on bare metal or when no container limits are configured,
preserving backwards compatibility.
Non-Linux builds compile and produce no output for these fields via a
container_limits_other.go stub, following the existing memory_linux.go /
memory_other.go pattern.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Fix golangci-lint errors: govet shadow and gofmt formatting
- Fix govet shadow: use var memBytes uint64 + err = instead of memBytes, err :=
to avoid shadowing the outer err variable (which is reused after this block)
- Fix gofmt: add extra space before // 512 MB comment to align with
the longer v2CPUMax line in the same assignment block
* fix(platform): ceil memory MB conversion and return zero-values for missing cgroup files
- Use ceiling division for MemoryLimitMB so sub-1MB limits map to 1 instead
of 0 (which omitempty would silently drop)
- Absorb os.ErrNotExist in getContainerLimits so non-v2/bare-metal hosts
return ContainerLimits{}, nil as the function comment promises
- Update test: missing cgroup file now asserts zero-values, not an error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(platform): add subtest locking ceil-to-MB behavior for sub-MB memory limits
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(platform): add subtest for missing cpu.max returning zero values
Locks in the os.ErrNotExist branch for cpu.max (lines 57-60 in
container_limits_linux.go), which was previously unreachable via the
existing missing-memory test since that test returns early before
reading cpu.max.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Default template property field permissions to sysadmin
Templates define the schema that linked fields inherit, so their
permission levels should default to sysadmin rather than member. This
aligns the create handler with TestLinkedProperties expectations.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Require sysadmin for template property field creation
The target_type-based scope check lets team admins create template
fields with target_type=team, which would then inherit sysadmin-level
permission defaults and lock the creator out. Enforce manage_system for
any template creation so the permission gate matches the intent of the
"create template field as non-admin fails" test.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Surface ws_event type in oversized cluster publish message logs
When a best-effort UDP gossip send fails with "message too long", the log
only shows event: publish with no further context. Tag the ClusterMessage
with the originating WebSocket event type so it appears in the error log.
* Update enterprise.pin to latest after enterprise PR #2133 merged
https://claude.ai/code/session_01Y1Abg1eDjKQBJvy7XhCtG6
* Bump
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude <noreply@anthropic.com>
* gather plugin metrics and serve on /metrics
* tests
* fix recent conflicts from master
* fix linting
* address review feedback: feature flag, route guard, and unit tests for plugin metrics
- Add PluginMetricsCollection feature flag (default true) to allow disabling plugin metric collection without a deploy
- Only wrap the /metrics handler with plugin metric collection (not arbitrary plugin routes, which would cause double-listing)
- Extract wrapping logic into wrapMetricsHandler for clarity
- Add unit tests for addPluginLabelToMetrics covering no-label, existing-label, comments, empty lines, and multiple metrics cases
* fix integration tests to use /metrics route so wrapMetricsHandler runs
* switch addPluginLabelToMetrics to use expfmt for correct label injection
Replace string manipulation with expfmt parse→mutate→re-encode, which
correctly handles all metric types, timestamps, and malformed input.
Output is normalized: blank lines are dropped and TYPE headers are
injected for undeclared metrics. Update unit tests accordingly.
* refine addPluginLabelToMetrics: log warnings, drop sort, use assert.Contains
- Log a warning (instead of silently discarding) on parse or encode errors,
returning empty string in both cases
- Remove name sorting — metric family order is irrelevant to Prometheus scrapers
- Switch unit test assertions to assert.Contains per line so tests are
order-independent
* replace strPtr helper with model.NewPointer
* fix gofmt: remove extra blank line
* replace existing plugin_id label instead of appending a duplicate
If a plugin already exports a plugin_id label, overwrite it rather than
appending a second one, which would produce invalid Prometheus output.
Add test coverage for the replace path.
* add missing test coverage per mattermost-build feedback
- Unit test: malformed input returns empty string without panicking
- Integration: PluginMetricsCollection=false excludes plugin metrics
- Integration: plugin returning non-200 status excluded from response
- Integration: plugin returning empty body excluded from response
* rename PluginMetricsCollection to AggregatePluginMetrics, default false
---------
Co-authored-by: Jesse Hallam <jesse@mattermost.com>
* Fix bot import panic when user exists without bot record
The original importBot error handler re-declared `var appErr *model.AppError`
inside the CreateBot failure block, shadowing the outer appErr with a typed nil
pointer. When errors.As received this (*model.AppError)(nil), it was a non-nil
interface — so instead of returning false, it called AppError.Unwrap() on the
nil receiver, causing a panic.
This commit:
- Fixes the variable shadowing that caused the panic
- Adds recovery logic: when CreateBot fails because the username is taken,
look up the existing user and create/update just the bot record
- Fixes pre-existing silent error swallowing in Bot().GetByUsername — now
distinguishes store.ErrNotFound from real database errors
- Fixes pre-existing bug where DisplayName changes on re-import were lost
because DisplayName is stored in Users.FirstName, not the Bots table
- Adds logging at every step of the recovery path (Info for normal flow,
Warn for fallback/error paths)
- Uses distinct variable names (saveErr/updateErr) in the Save→Update
fallback to avoid the same class of variable-reuse hazard
- Adds comprehensive test suite (11 subtests) covering dry-run, apply,
re-import, recovery, regression/panic guard, idempotency, DisplayName
update, and plugin-owner edge cases
* Address review findings: tighten assertions, fix error ID, add coverage
- Use require.ErrorAs for store.ErrNotFound instead of generic require.Error
in the dry-run test, so it catches only not-found rather than any store error
- Add time.Sleep before idempotent re-import to ensure any real write would
produce a different UpdateAt timestamp at millisecond resolution
- Fix misleading error ID "app.bot.createbot.internal_error" to
"app.bot.update.internal_error" in the Update fallback path
- Add test for non-username CreateBot failure (email conflict) to cover
the error passthrough at line 907-908
* Add missing i18n translations for bot import error strings
Add translation entries for app.bot.update.internal_error,
app.import.import_bot.lookup_error, and
app.import.import_bot.user_not_found.error to fix enterprise CI
i18n check failure.
* MM-68160: Show post reminder ack in RHS for reply reminders
Set the reminder confirmation ephemeral post root_id to the thread root
when the reminder is set on a reply, matching how thread views key posts.
Re-enable websocket integration tests for reminders and add coverage for
reply vs root behavior.
Made-with: Cursor
* SetPostReminder: validate post before persisting reminder
Read the post and reminder metadata before inserting into PostReminders so
a failed GetSinglePost or metadata lookup cannot leave an orphaned row.
Made-with: Cursor
- Register per-item OnFailure callback to log each rejected document
with its error type and reason
- Restructure DoJob to close the bulk processor before marking a job
successful; check Stats().NumFailed after close and fail the job
when any documents were not indexed
- Use a sync.Once-guarded doClose helper so the processor is flushed
exactly once across all exit paths; non-success paths return and let
the defer handle the close
- Close function owns all its logging: warn with error on failure, info
on success; callers no longer need to log close errors themselves
- Fix ResponseBodyEnabled() hardcoded false → return l.trace so
per-item error JSON is visible when Trace=all is set
- Set job to error (rather than silently return) when createBulkProcessor
fails after the job has been claimed
- Add integration tests for both backends that apply a write block to
verify bulk failures are surfaced as job errors
- Add i18n strings for the two new error codes
* MM-67976: Add server uptime to support packet
Add process start time (started_at) and approximate host start time
(host_started_at, Linux only, derived from /proc/uptime) to the support
packet diagnostics. This helps diagnose restart loops and distinguish
process restarts from full machine/container reboots.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Add HostStartedAt assertions to support packet happy-path test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Revert unrelated changes
* Add unit tests for getHostUptimeSeconds and fix cross-platform portability
- Extract parseUptimeFile helper in uptime_linux.go to enable unit testing
with synthetic file paths without touching the real /proc/uptime
- Add uptime_linux_test.go covering all error paths (file read error,
empty file, non-numeric value) and happy-path parsing
- Add uptime_other_test.go asserting the non-Linux stub returns
ErrHostUptimeUnsupportedPlatform and zero seconds
- Guard HostStartedAt assertions in support_packet_test.go with
runtime.GOOS so the test correctly asserts zero-time on non-Linux
platforms instead of failing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: use t.TempDir() for guaranteed-missing path in uptime test
Replace the hard-coded /nonexistent/proc/uptime path with a path
constructed from t.TempDir() to guarantee the file is absent without
relying on filesystem layout assumptions. Also remove the misleading
comment about swapping implementations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Reorder Server struct fields and assignments to group process identity fields together
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add macOS support for host uptime in support packet
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* MM-67978: Add open file descriptor count to support packet diagnostics
Add OpenFileDescriptors and MaxFileDescriptors fields to
SupportPacketDiagnostics.Server. On Linux the open count is read from
/proc/self/fd; on macOS from /dev/fd. Both platforms use
syscall.Getrlimit(RLIMIT_NOFILE) for the soft limit. Unsupported
platforms (e.g. Windows) return -1 for both fields.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* MM-67978: Move OpenFileDescriptors/MaxFileDescriptors after TotalMemoryMB
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix: guard int64 overflow in getMaxFileDescriptors and update tests for unsupported platforms
Add overflow check before casting rlimit.Cur (uint64) to int64 in
getMaxFileDescriptors on Linux. Update fd_test.go and
support_packet_test.go assertions to accept -1 as a valid sentinel for
unsupported platforms instead of requiring a strictly positive value.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* revert: remove unrelated test refactoring from support_packet_test.go
Restore the three unrelated changes that crept into this branch:
- SetLogRootPathOverride instead of t.Setenv("MM_LOG_PATH", ...)
- installTypeOverride field instead of t.Setenv(envVarInstallType, ...)
- Restore explanatory comment in TestGetSanitizedConfigFile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Add a GoVersion field to SupportPacketDiagnostics.Server populated via
runtime.Version(), so support engineers can determine which Go version
a server was compiled with from the support packet alone.
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Populate server.process_id in diagnostics.yaml using os.Getpid(), making it easier to correlate support packet data with OS-level logs and confirm whether the server was restarted between an incident and packet generation.
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix(tests): widen ChannelMemberHistory time windows (MM-67041, MM-67037)
The 100ms query window (GetMillis()-100 to GetMillis()+100) is too
tight under CI load — DB writes can lag >100ms, causing the history
record to fall outside the window. Widen to ±10s and capture start
time before the operation.
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): use require.Eventually for DND status restore (MM-63533)
Replace time.Sleep(3s) + instant assert with require.Eventually polling
(15s timeout, 500ms interval). The recurring task runs every 1s but can
lag under CI load, making the fixed sleep unreliable.
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): fix PostReminder timing and increase WS timeout (MM-60329)
Set target time 1s in the future instead of now, giving the reminder
processor a clear tick to pick it up. Increase WebSocket wait from 5s
to 15s for CI load tolerance.
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): add error checks and poll for file infos (MM-46902)
File info association with posts can be async. Replace instant
assertion with require.Eventually polling. Also add proper error
checking on UploadFile and CreatePost calls.
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): fix thread membership race and WS timeout (MM-41285)
Replace instant GetUserThread assertion with require.Eventually polling
(10s timeout) since mention counts may not propagate immediately after
AddChannelMemberWithRootId. Increase WebSocket timeout from 2s to 15s.
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): use far-future timestamps in GetUptoNSizeFileTime (MM-53905)
PermanentDeleteBatch only cleans up to current time, and parallel tests
can create file infos that interfere with the cumulative size calc.
Extend the delete window and use timestamps 1 hour in the future to
ensure these test files are always 'most recent'.
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): use far-future timestamps in GetNthRecentPostTime (MM-64438)
GetNthRecentPostTime queries by global position across all posts.
Parallel tests creating posts shift the Nth position. Using timestamps
1 hour in the future ensures these test posts are always most recent.
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): space reply timestamps for unread count test (MM-41797)
makeSomePosts creates all posts without explicit CreateAt, so they can
share the same millisecond. MarkAsRead(rootPost.CreateAt) then marks
replies as read too, returning 0 instead of 2. Fix by overwriting
reply timestamps to be 1s after the root post.
Co-authored-by: Claude <claude@anthropic.com>
* test: re-enable MM-62895 and MM-61041 to probe for failures
Remove t.Skip for two long-dormant flaky tests to collect actual
failure data over 1-2 weeks of rebasing. Based on fullyparallel
branch so these run with every CI pass.
- MM-62895: TestUpdateOAuthApp (14mo, empty Jira, unknown root cause)
- MM-61041: TestAutocompleteUsersInChannel (17mo, fragile integration test)
Co-authored-by: Claude <claude@anthropic.com>
* test: add MM-64687 shared channel tests to probe
Remove t.Skip("MM-64687") from 5 shared channel sync tests to collect
failure data. The underlying sync mechanism was completely rewritten in
#35619 (ChannelMemberHistory cursor-based sync), so the original race
condition may no longer exist. Probing for 1-2 weeks before deciding
whether to permanently re-enable in #35762.
Tests:
- api4/shared_channel_metadata_test.go (4 subtests)
- app/shared_channel_membership_sync_self_referential_test.go (1 subtest)
Co-authored-by: Claude <claude@anthropic.com>
* test: re-enable TestResetPassword (stale skip from old build server)
The skip comment says 'should be investigated' — the test uses the same
inbucket mail pattern as other working tests (e.g. TestInviteUsersToTeam).
The 'old build server changes' it references are long resolved.
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): clean up far-future posts in GetNthRecentPostTime
Per review feedback from mgdelacroix: defer PermanentDelete for all
far-future posts so they don't leak into other tests that query
GetNthRecentPostTime. The file_info_store test (GetUptoNSizeFileTime)
already had cleanup via defer PermanentDelete.
Co-authored-by: Claude <claude@anthropic.com>
* ci: TEMPORARY enable race detector for PR testing (revert after)
Co-authored-by: Claude <claude@anthropic.com>
* fix(tests): add mutex to fix data race in shared channel sync test
The -race detector caught a data race in Test_4 (Sync failure and
recovery): the OnBatchSync/OnIndividualSync callbacks write to
successfulSyncs from the HTTP handler goroutine while assert.Eventually
reads it from the test goroutine. Add sync.Mutex to protect all
accesses to the shared slice.
Co-authored-by: Claude <claude@anthropic.com>
* fix(test): add mutex to TestSharedChannelPostMetadataSync for race safety
The syncedPosts/syncedPostsServerA/syncedPostsServerB slices are
written by OnPostSync callbacks running on HTTP server goroutines
and read by require.Eventually + assertions on the test goroutine.
Without synchronization, the race detector flags concurrent access.
Add sync.Mutex per subtest to protect all slice reads and writes,
matching the pattern used in TestSharedChannelMembershipSyncSelfReferential.
Co-authored-by: Claude <claude@anthropic.com>
* Revert "ci: TEMPORARY enable race detector for PR testing (revert after)"
This reverts commit b9af0e9003.
* fix: address review feedback from wiggin77
- Remove eager-evaluated len(infos) from require.Eventually message
(was always 0 since infos is nil at call time)
- Log errors from PermanentDelete in test cleanup
Co-authored-by: Claude <claude@anthropic.com>
* fix: rename shadowed err variable in test cleanup
Use delErr to avoid shadowing the outer err variable, which
triggers govet's shadow checker in CI.
Co-authored-by: Claude <claude@anthropic.com>
---------
Co-authored-by: Claude <claude@anthropic.com>