Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ jobs:
version: latest

test:
runs-on: ubuntu-latest
strategy:
matrix:
os:
- ubuntu-latest
- macos-26

runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7

Expand Down
3 changes: 2 additions & 1 deletion cmd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing"

"github.com/1broseidon/ketch/config"
"github.com/1broseidon/ketch/internal/testutil"
"github.com/1broseidon/ketch/scrape"
)

Expand Down Expand Up @@ -100,7 +101,7 @@ func TestRunConfigSetNeverEchoesSecrets(t *testing.T) {

for _, test := range tests {
t.Run(test.key, func(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
testutil.SetIsolatedConfigHome(t)
output, err := captureStderr(t, func() error {
return runConfigSet(nil, []string{test.key, test.value})
})
Expand Down
4 changes: 3 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"path/filepath"
"reflect"
"testing"

"github.com/1broseidon/ketch/internal/testutil"
)

func TestParallelBackendIsAppendedWithoutChangingDefault(t *testing.T) {
Expand Down Expand Up @@ -50,7 +52,7 @@ func TestEffectiveKeysReturnCopies(t *testing.T) {
}

func TestSaveEnforcesPrivateMode(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
testutil.SetIsolatedConfigHome(t)
path, err := Path()
if err != nil {
t.Fatal(err)
Expand Down
8 changes: 5 additions & 3 deletions config/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"reflect"
"strings"
"testing"

"github.com/1broseidon/ketch/internal/testutil"
)

// clearKetchEnv unsets every KETCH_* variable for the test so ambient
Expand All @@ -28,7 +30,7 @@ func TestEnvVarNaming(t *testing.T) {

func TestLoadEnvOverlay(t *testing.T) {
clearKetchEnv(t)
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
testutil.SetIsolatedConfigHome(t)
t.Setenv("KETCH_BACKEND", "ddg")
t.Setenv("KETCH_LIMIT", "9")
t.Setenv("KETCH_CACHE_TTL", "30m")
Expand Down Expand Up @@ -94,7 +96,7 @@ func TestLoadEnvOverridesFile(t *testing.T) {

func TestLoadInvalidEnvIsLoudButBestEffort(t *testing.T) {
clearKetchEnv(t)
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
testutil.SetIsolatedConfigHome(t)
t.Setenv("KETCH_LIMIT", "abc")
t.Setenv("KETCH_CACHE_TTL", "nope")
t.Setenv("KETCH_BACKEND", "ddg")
Expand All @@ -116,7 +118,7 @@ func TestLoadInvalidEnvIsLoudButBestEffort(t *testing.T) {

func TestLoadEmptyEnvValueIsUnset(t *testing.T) {
clearKetchEnv(t)
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
testutil.SetIsolatedConfigHome(t)
t.Setenv("KETCH_LIMIT", "")

res, err := Load()
Expand Down
13 changes: 13 additions & 0 deletions internal/testutil/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package testutil

import "testing"

// SetIsolatedConfigHome prevents tests from using the user's config directory.
func SetIsolatedConfigHome(t testing.TB) string {
t.Helper()

dir := t.TempDir()
t.Setenv("HOME", dir)
t.Setenv("XDG_CONFIG_HOME", dir)
return dir
}
7 changes: 4 additions & 3 deletions mcp/smoke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
//
// go test -tags mcpsmoke ./mcp/... -run TestMCPServerSmoke -v
//
// The server subprocess runs with XDG_CACHE_HOME/XDG_CONFIG_HOME pointed at
// a temp dir, so it sees default config (grepapp needs no key) and a fresh
// The server subprocess runs with HOME/XDG_CACHE_HOME/XDG_CONFIG_HOME pointed
// at a temp dir, so it sees default config (grepapp needs no key) and a fresh
// page cache — which lets the scrape subtest prove shared-cache reuse.
package mcp_test

Expand Down Expand Up @@ -41,6 +41,7 @@ func TestMCPServerSmoke(t *testing.T) {
isolated := t.TempDir()
serve := exec.Command(bin, "mcp", "serve")
serve.Env = append(os.Environ(),
"HOME="+isolated,
"XDG_CACHE_HOME="+isolated,
"XDG_CONFIG_HOME="+isolated,
)
Expand Down Expand Up @@ -152,7 +153,7 @@ func TestMCPServerSmoke(t *testing.T) {
}

// The server writes through its shared, server-lifetime cache handle;
// with XDG_CACHE_HOME isolated, this file exists only if that handle
// with HOME/XDG_CACHE_HOME isolated, this file exists only if that handle
// was actually opened and used.
cachePath := filepath.Join(isolated, "ketch", "cache.db")
info, err := os.Stat(cachePath)
Expand Down