mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-03-11 17:48:44 -05:00
fix(e2e): drain event handlers and stop browser between tests
Async event handlers (via Watermill) from the previous test can hold SQLite connections, starving the next test's fixture setup PATCH request. Three changes fix this: 1. Track in-flight event handler goroutines with a WaitGroup. 2. Call WaitForPendingHandlers() in the test endpoint before truncating/inserting data. 3. Navigate the browser to about:blank in fixture teardown to stop notification polling and other frontend requests between tests.
This commit is contained in:
@@ -32,6 +32,11 @@ export const test = base.extend<{
|
||||
authenticatedPage: async ({page, apiContext, currentUser}, use) => {
|
||||
const {token} = await login(page, apiContext, currentUser)
|
||||
await use(page)
|
||||
// Navigate away to stop all frontend requests (notification polling, token
|
||||
// refresh, etc.) before the next test's fixture setup seeds the database.
|
||||
// Without this, the previous test's page can hold DB connections via API
|
||||
// requests, starving the next test's Factory.seed() PATCH call.
|
||||
await page.goto('about:blank').catch(() => {})
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
@@ -36,6 +37,19 @@ import (
|
||||
|
||||
var pubsub *gochannel.GoChannel
|
||||
|
||||
// activeHandlers tracks in-flight event handler goroutines so the test
|
||||
// endpoint can wait for them to finish before truncating tables.
|
||||
var activeHandlers sync.WaitGroup
|
||||
|
||||
// WaitForPendingHandlers blocks until all currently in-flight event handler
|
||||
// goroutines have completed (including retries). This is intended for the
|
||||
// testing endpoint to avoid connection starvation: async handlers from the
|
||||
// previous test can hold SQLite connections, starving the next test's seed
|
||||
// request.
|
||||
func WaitForPendingHandlers() {
|
||||
activeHandlers.Wait()
|
||||
}
|
||||
|
||||
// Event represents the event interface used by all events
|
||||
type Event interface {
|
||||
Name() string
|
||||
@@ -90,7 +104,19 @@ func InitEvents() (err error) {
|
||||
return nil
|
||||
})
|
||||
|
||||
// handlerTracker is a middleware that tracks in-flight handlers via the
|
||||
// activeHandlers WaitGroup. It wraps the entire processing chain
|
||||
// (including retries) so WaitForPendingHandlers() can drain all work.
|
||||
handlerTracker := func(h message.HandlerFunc) message.HandlerFunc {
|
||||
return func(msg *message.Message) ([]*message.Message, error) {
|
||||
activeHandlers.Add(1)
|
||||
defer activeHandlers.Done()
|
||||
return h(msg)
|
||||
}
|
||||
}
|
||||
|
||||
router.AddMiddleware(
|
||||
handlerTracker,
|
||||
poison,
|
||||
middleware.Retry{
|
||||
MaxRetries: 5,
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/events"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
|
||||
"github.com/labstack/echo/v5"
|
||||
@@ -61,6 +62,11 @@ func HandleTesting(c *echo.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
// Wait for all async event handlers from the previous test to complete
|
||||
// before modifying the database. Without this, handlers hold SQLite
|
||||
// connections and starve this request's truncate/insert operations.
|
||||
events.WaitForPendingHandlers()
|
||||
|
||||
truncate := c.QueryParam("truncate")
|
||||
if truncate == "true" || truncate == "" {
|
||||
err = db.RestoreAndTruncate(table, content)
|
||||
|
||||
Reference in New Issue
Block a user