From 209b72b8179090745595048a17a51d1a14c7e026 Mon Sep 17 00:00:00 2001 From: andig Date: Wed, 22 Jul 2026 11:56:07 +0200 Subject: [PATCH] Fix startup deadlock with existing metrics database (#32043) --- go.mod | 2 +- go.sum | 4 ++-- server/db/db_test.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6b5112e70..84de61530 100644 --- a/go.mod +++ b/go.mod @@ -69,7 +69,7 @@ require ( github.com/koron/go-ssdp v0.9.1 github.com/korylprince/ipnetgen v1.0.1 github.com/libp2p/zeroconf/v2 v2.2.0 - github.com/libtnb/sqlite v1.2.0 + github.com/libtnb/sqlite v1.1.2 github.com/lorenzodonini/ocpp-go v0.19.0 github.com/lunixbochs/struc v0.0.0-20241101090106-8d528fa2c543 github.com/mabunixda/wattpilot v1.8.5 diff --git a/go.sum b/go.sum index 17a4ea78f..6526b6c00 100644 --- a/go.sum +++ b/go.sum @@ -343,8 +343,8 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= -github.com/libtnb/sqlite v1.2.0 h1:XsA7jsXHH2qmFkTWoy5YCKJybzHzWQ0flqDFP5Y9Yto= -github.com/libtnb/sqlite v1.2.0/go.mod h1:O6vURH5fa5IgSmXd/qLAL2zSnYFUd7xSIumsmX3BrSI= +github.com/libtnb/sqlite v1.1.2 h1:3g8nez8MwdEhn+oqt3bfKWnYJxk0ZGTO0kVA1WT+hjQ= +github.com/libtnb/sqlite v1.1.2/go.mod h1:2PGCWOR6HqqXuoIVMmwfJ655epvRO8sw0b9kHWuKNsQ= github.com/lunixbochs/struc v0.0.0-20241101090106-8d528fa2c543 h1:GxMuVb9tJajC1QpbQwYNY1ZAo1EIE8I+UclBjOfjz/M= github.com/lunixbochs/struc v0.0.0-20241101090106-8d528fa2c543/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= github.com/mabunixda/wattpilot v1.8.5 h1:pjm//7dnEiR0OHfMZ+SLlLV557Y0LMrxgjwudOsuHbQ= diff --git a/server/db/db_test.go b/server/db/db_test.go index 3366c961f..ef15a8e89 100644 --- a/server/db/db_test.go +++ b/server/db/db_test.go @@ -2,8 +2,10 @@ package db import ( "testing" + "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestUnitNewDriver(t *testing.T) { @@ -63,3 +65,36 @@ func TestUnitNewDriver(t *testing.T) { }) } } + +type migrationParent struct { + Id int `gorm:"column:id;primarykey"` +} + +func (migrationParent) TableName() string { return "migration_parents" } + +type migrationChild struct { + ParentId int `gorm:"column:parent_id"` + Parent migrationParent `gorm:"foreignkey:ParentId;references:Id"` +} + +func (migrationChild) TableName() string { return "migration_children" } + +// TestUnitMigrateConstraint guards against migrator implementations that pin a +// connection and then query the pool again: the single connection deadlocks. +func TestUnitMigrateConstraint(t *testing.T) { + db, err := New("sqlite", t.TempDir()+"/evcc.db") + require.NoError(t, err) + + // existing table without the foreign key, forces the migrator to recreate it + require.NoError(t, db.Exec("CREATE TABLE migration_children (parent_id integer)").Error) + + done := make(chan error, 1) + go func() { done <- db.AutoMigrate(new(migrationParent), new(migrationChild)) }() + + select { + case err := <-done: + require.NoError(t, err) + case <-time.After(10 * time.Second): + t.Fatal("AutoMigrate deadlocked") + } +}