mattermost/server/channels/app/platform/uptime_linux_test.go
Ben Schumacher 58052db8e3
[MM-67976] Add server uptime to support packet (#35838)
* 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>
2026-04-21 10:52:10 +00:00

63 lines
1.7 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
//go:build linux
package platform
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetHostUptimeSeconds(t *testing.T) {
t.Run("returns a positive value from /proc/uptime", func(t *testing.T) {
seconds, err := getHostUptimeSeconds()
require.NoError(t, err)
assert.Positive(t, seconds)
})
t.Run("error on unreadable file", func(t *testing.T) {
missingPath := t.TempDir() + "/uptime"
_, err := parseUptimeFile(missingPath)
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to read")
})
t.Run("error on empty file", func(t *testing.T) {
f, err := os.CreateTemp(t.TempDir(), "uptime")
require.NoError(t, err)
require.NoError(t, f.Close())
_, err = parseUptimeFile(f.Name())
require.Error(t, err)
assert.Contains(t, err.Error(), "unexpected /proc/uptime format")
})
t.Run("error on non-numeric first field", func(t *testing.T) {
f, err := os.CreateTemp(t.TempDir(), "uptime")
require.NoError(t, err)
_, err = f.WriteString("notanumber 0.00\n")
require.NoError(t, err)
require.NoError(t, f.Close())
_, err = parseUptimeFile(f.Name())
require.Error(t, err)
assert.Contains(t, err.Error(), "failed to parse /proc/uptime value")
})
t.Run("parses valid uptime correctly", func(t *testing.T) {
f, err := os.CreateTemp(t.TempDir(), "uptime")
require.NoError(t, err)
_, err = f.WriteString("12345.67 890.12\n")
require.NoError(t, err)
require.NoError(t, f.Close())
seconds, err := parseUptimeFile(f.Name())
require.NoError(t, err)
assert.Equal(t, int64(12345), seconds)
})
}