Skip to content

Commit d256dd7

Browse files
Crash--claude
andcommitted
test(rabbitmq): bootstrap global CouchDB views in TestMain
Tests in this package call lifecycle.Create / instance.Get directly without going through testutils.NewSetup → GetTestInstance → stack.Start, so they never trigger couchdb.InitGlobalDB themselves. They've historically relied on the side effect of earlier model/* test packages bootstrapping the global DB and on the design doc persisting in the shared CouchDB service across test binaries. Go's test result cache (persisted via actions/setup-go cache) can let those packages be skipped, breaking the implicit dependency. The CI flake on PR #4716 manifested as TestSyncCreatedOrgContact failing with "CouchDB(not_found): missing" because instance.Service.Get queried _design/domain-and-aliases on a global instances DB where that design doc had never been created. A more robust fix would be to make instance.Service.Get treat any CouchDB "not_found" as ErrNotFound (it currently only handles no_db_file / "Database does not exist."). That would remove the implicit dependency for every package, not just this one. The repercussions on other Get callers haven't been fully audited yet, so this localized bootstrap stays in place until the broader change is vetted. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a45dc6c commit d256dd7

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

pkg/rabbitmq/main_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package rabbitmq_test
2+
3+
import (
4+
"context"
5+
"log"
6+
"os"
7+
"strings"
8+
"testing"
9+
10+
"github.com/cozy/cozy-stack/pkg/config/config"
11+
"github.com/cozy/cozy-stack/pkg/couchdb"
12+
"github.com/spf13/viper"
13+
)
14+
15+
// TestMain bootstraps the views and indexes that production stacks create
16+
// at startup via stack.Start → couchdb.InitGlobalDB. Tests in this package
17+
// call lifecycle.Create / instance.Get directly without going through
18+
// testutils.NewSetup → GetTestInstance → stack.Start, so they never trigger
19+
// that init themselves.
20+
//
21+
// They've historically relied on the side effect that earlier model/* test
22+
// packages bootstrap the global DB and that the design doc persists in the
23+
// shared CouchDB service across test binaries — but Go's test result cache
24+
// can let those packages be skipped (cached "ok"), and then this implicit
25+
// dependency breaks. See the CI flake debugged on PR #4716: the second
26+
// lifecycle.Create call inside TestSyncCreatedOrgContact failed with
27+
// "CouchDB(not_found): missing" because instance.Service.Get queried
28+
// _design/domain-and-aliases on the global instances DB and that design
29+
// doc had never been created.
30+
//
31+
// TODO: the more robust fix is to make instance.Service.Get treat any
32+
// CouchDB "not_found" as ErrNotFound (it currently only handles
33+
// no_db_file / "Database does not exist."). That would remove the implicit
34+
// dependency for every package, not just this one. The repercussions on
35+
// other Get callers haven't been fully audited though, so this localized
36+
// bootstrap stays in place until that broader change is vetted.
37+
func TestMain(m *testing.M) {
38+
if err := loadTestConfigForMain(); err != nil {
39+
log.Fatalf("rabbitmq tests: could not load test config: %s", err)
40+
}
41+
// Best-effort: if CouchDB is unreachable, individual tests that need it
42+
// will fail via testutils.NeedCouchdb(t). We don't want TestMain itself
43+
// to hard-fail in environments where CouchDB is intentionally absent.
44+
if _, err := couchdb.CheckStatus(context.Background()); err == nil {
45+
if err := couchdb.InitGlobalDB(context.Background()); err != nil {
46+
log.Printf("rabbitmq tests: could not init global CouchDB: %s", err)
47+
}
48+
}
49+
os.Exit(m.Run())
50+
}
51+
52+
// loadTestConfigForMain mirrors config.UseTestFile but without the
53+
// *testing.T plumbing so it can be called from TestMain.
54+
func loadTestConfigForMain() error {
55+
v := viper.New()
56+
v.SetConfigName("cozy.test")
57+
v.AddConfigPath("$HOME/.cozy")
58+
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
59+
v.SetEnvPrefix("cozy")
60+
v.AutomaticEnv()
61+
v.SetDefault("host", "localhost")
62+
v.SetDefault("port", 8080)
63+
v.SetDefault("assets", "./assets")
64+
v.SetDefault("subdomains", "nested")
65+
v.SetDefault("fs.url", "mem://test")
66+
v.SetDefault("couchdb.url", "http://localhost:5984/")
67+
v.SetDefault("log.level", "info")
68+
if err := v.ReadInConfig(); err != nil {
69+
if _, isMissing := err.(viper.ConfigFileNotFoundError); !isMissing {
70+
return err
71+
}
72+
}
73+
return config.UseViper(v)
74+
}

0 commit comments

Comments
 (0)