mirror of
https://github.com/hanzoai/base.git
synced 2026-10-21 03:41:50 +00:00
deploy / build (push) Waiting to run
core/sqlite_math_required.go failed any cgo build not carrying the
sqlite_math_functions tag, by referencing a symbol that was never defined
anywhere. So `go build ./...` — no tags, default CGO_ENABLED — did not
work in this repo or in any repo importing core, and the error named a
symbol rather than the problem:
undefined: cgoBuildNeedsSQLiteMathFunctions
The capability it was protecting is real. tools/search emits acos, cos,
sin and radians for geoDistance, and SQLite only has those when compiled
with SQLITE_ENABLE_MATH_FUNCTIONS. Measured, per config:
CGO_ENABLED=0 present (what the Dockerfile ships)
CGO_ENABLED=1 ABSENT <- the one deficient config
CGO_ENABLED=1 -tags sqlite_math_functions present
CGO_ENABLED=1 -tags libsqlite3 present <- blocked anyway
The tag was a proxy for the capability, and the proxy was wrong. Row four
is the config the driver's own doc comment calls production: that tag
links the system sqlcipher, so the amalgamation's -D flag is never
compiled and the tag decides nothing, yet the guard rejected the build.
It also could not have caught a system libsqlcipher genuinely missing the
functions, and no library can satisfy it from the inside, because build
tags are chosen by the top-level build command.
Replace it with a measurement. VerifySQLiteMathFunctions runs the
geoDistance expression once per process against a throwaway in-memory
database and DefaultDBConnect refuses to hand back a connection when the
answer is no, so a deficient binary dies at startup with the three ways
to fix it rather than at a customer's failed search. A probe that could
not run at all is not an error: this reports a measured absence, never a
failure to measure.
Detection is strictly better than before. tools/search already had
TestTokenFunctionsGeoDistanceExec executing the real emitted SQL, and it
fails on the deficient config today; core now carries its own, since
tools/search does not import core and its failure said nothing about
this package.
build, all four configs above exit 0 (was: 2 of 4 refused)
go test ./... CGO_ENABLED=0 64 packages ok, 0 failures
go test ./core -run SQLiteMath CGO=1 FAIL, as it should
Co-authored-by: Hanzo Dev <[email protected]>
71 lines
2.7 KiB
Go
71 lines
2.7 KiB
Go
package core
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/hanzoai/dbx"
|
|
)
|
|
|
|
// engineHasMathFunctions asks the linked SQLite directly, with no help from the
|
|
// code under test, so the tests below have a ground truth to compare against.
|
|
func engineHasMathFunctions(t *testing.T) bool {
|
|
t.Helper()
|
|
|
|
db, err := dbx.Open("sqlite", "file:core_math_truth?mode=memory")
|
|
if err != nil {
|
|
// The probe treats this as inconclusive and so must the test, but a
|
|
// build where it always happens has a guard that can never fire.
|
|
t.Skipf("no usable sqlite driver registered: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
var distance float64
|
|
|
|
return db.NewQuery(mathProbeSQL).Row(&distance) == nil
|
|
}
|
|
|
|
// TestSQLiteMathFunctions fails a build whose linked SQLite cannot answer the
|
|
// search layer's geoDistance filter — the job the old compile-time guard in
|
|
// sqlite_math_required.go was doing, done by measuring the engine instead of
|
|
// asserting a build tag. It is reproduced here rather than left to
|
|
// TestTokenFunctionsGeoDistanceExec in tools/search because that package does
|
|
// not import core, so its failure says nothing about this one.
|
|
func TestSQLiteMathFunctions(t *testing.T) {
|
|
if !engineHasMathFunctions(t) {
|
|
t.Fatal("the SQLite engine linked into this build has no math functions; " +
|
|
"build with CGO_ENABLED=0, -tags sqlite_math_functions, or -tags libsqlite3")
|
|
}
|
|
}
|
|
|
|
// TestVerifySQLiteMathFunctionsAgreesWithEngine pins the probe to the engine.
|
|
// A probe that stopped working — a DSN that no longer opens, a driver error
|
|
// phrased some other way — would go on returning nil and quietly pass every
|
|
// deficient build, which is the one failure this file cannot afford.
|
|
func TestVerifySQLiteMathFunctionsAgreesWithEngine(t *testing.T) {
|
|
present := engineHasMathFunctions(t)
|
|
err := VerifySQLiteMathFunctions()
|
|
|
|
switch {
|
|
case present && err != nil:
|
|
t.Fatalf("engine has the math functions but the probe rejected the build: %v", err)
|
|
case !present && err == nil:
|
|
t.Fatal("engine has no math functions but the probe passed the build")
|
|
}
|
|
}
|
|
|
|
// TestSQLiteMathProbeIsConclusive guards the escape hatch. VerifySQLiteMathFunctions
|
|
// declines to fail a build it could not measure, so a probe that never manages
|
|
// to open its database is indistinguishable from a healthy one. Here it must open.
|
|
func TestSQLiteMathProbeIsConclusive(t *testing.T) {
|
|
db, err := dbx.Open("sqlite", "file:base_sqlite_math_probe?mode=memory")
|
|
if err != nil {
|
|
t.Fatalf("the probe's own DSN does not open, so the probe can only ever return inconclusive: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
var distance float64
|
|
if err := db.NewQuery(mathProbeSQL).Row(&distance); err == nil && distance <= 0 {
|
|
t.Fatalf("expected a positive distance from the probe expression, got %v", distance)
|
|
}
|
|
}
|