mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-08 02:17:25 +02:00
fix(test): stop the Windows test job from failing at random (#6182)
* fix(persistence): don't format a nil-model row in wrapCursor * test(plugins): assert task queue delay against the first dispatch, not consecutive gaps * test(artwork): let the e2e worker wait outlast one retry * chore: trim comments * fix(persistence): guard dbFolder and dbMediaFile String() against a nil model
This commit is contained in:
parent
8b4125267e
commit
0429fb3d40
7 changed files with 39 additions and 6 deletions
|
|
@ -56,7 +56,8 @@ func runWorkerUntil(ctx context.Context, worker *artwork.Worker, until func() bo
|
|||
runCtx, cancel := context.WithCancel(ctx)
|
||||
done := make(chan error, 1)
|
||||
go func() { done <- worker.Run(runCtx) }()
|
||||
Eventually(until, 5*time.Second, 10*time.Millisecond).Should(BeTrue())
|
||||
// Long enough for one retry (3-7s backoff, 5s poll tick).
|
||||
Eventually(until, 15*time.Second, 10*time.Millisecond).Should(BeTrue())
|
||||
cancel()
|
||||
Eventually(done, 2*time.Second).Should(Receive(BeNil()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,14 @@ type dbFolder struct {
|
|||
ImageFiles string `structs:"-" json:"-"`
|
||||
}
|
||||
|
||||
// String guards the promoted Folder.String(), which would dereference a nil Folder.
|
||||
func (f dbFolder) String() string {
|
||||
if f.Folder == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return f.Folder.String()
|
||||
}
|
||||
|
||||
func (f *dbFolder) PostScan() error {
|
||||
var err error
|
||||
if f.ImageFiles != "" {
|
||||
|
|
|
|||
|
|
@ -310,6 +310,13 @@ var _ = Describe("FolderRepository", func() {
|
|||
})
|
||||
})
|
||||
|
||||
Describe("dbFolder.String", func() {
|
||||
It("does not dereference a nil Folder", func() {
|
||||
Expect(fmt.Sprint(dbFolder{})).To(Equal("<nil>"))
|
||||
Expect(fmt.Sprint(&dbFolder{})).To(Equal("<nil>"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("wrapFolderCursor", func() {
|
||||
It("does not panic when the cursor yields a dbFolder with nil Folder", func() {
|
||||
// Simulate what queryWithStableResults does on the rows.Err() path:
|
||||
|
|
|
|||
|
|
@ -38,6 +38,14 @@ type dbMediaFile struct {
|
|||
RgTrackPeak *float64 `structs:"-" json:"-"`
|
||||
}
|
||||
|
||||
// String guards the promoted MediaFile.String(), which would dereference a nil MediaFile.
|
||||
func (m dbMediaFile) String() string {
|
||||
if m.MediaFile == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return m.MediaFile.String()
|
||||
}
|
||||
|
||||
func (m *dbMediaFile) PostScan() error {
|
||||
m.RGTrackGain = m.RgTrackGain
|
||||
m.RGTrackPeak = m.RgTrackPeak
|
||||
|
|
|
|||
|
|
@ -1203,6 +1203,13 @@ var _ = Describe("MediaRepository", func() {
|
|||
})
|
||||
})
|
||||
|
||||
Describe("dbMediaFile.String", func() {
|
||||
It("does not dereference a nil MediaFile", func() {
|
||||
Expect(fmt.Sprint(dbMediaFile{})).To(Equal("<nil>"))
|
||||
Expect(fmt.Sprint(&dbMediaFile{})).To(Equal("<nil>"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("wrapMediaFileCursor", func() {
|
||||
It("does not panic when the cursor yields a dbMediaFile with nil MediaFile", func() {
|
||||
// Simulate what queryWithStableResults does on the rows.Err() path:
|
||||
|
|
|
|||
|
|
@ -378,8 +378,9 @@ func wrapCursor[D, T any](cursor iter.Seq2[D, error], toModel func(D) *T) iter.S
|
|||
for row, err := range cursor {
|
||||
m := toModel(row)
|
||||
if m == nil {
|
||||
// Don't format row: its String() derefs the nil model (golang/go#81238).
|
||||
var zero T
|
||||
yield(zero, fmt.Errorf("unexpected nil %T (%v): %w", zero, row, err))
|
||||
yield(zero, fmt.Errorf("unexpected nil %T: %w", zero, err))
|
||||
return
|
||||
}
|
||||
if !yield(*m, err) || err != nil {
|
||||
|
|
|
|||
|
|
@ -689,11 +689,12 @@ var _ = Describe("TaskQueueService", func() {
|
|||
copy(times, dispatchTimes)
|
||||
mu.Unlock()
|
||||
|
||||
// Consecutive dispatches should have at least ~160ms gap (80% of 200ms)
|
||||
// Wake-up latency varies per worker, so check offsets from the first dispatch, not gaps.
|
||||
for i := 1; i < len(times); i++ {
|
||||
gap := times[i].Sub(times[i-1])
|
||||
Expect(gap).To(BeNumerically(">=", 160*time.Millisecond),
|
||||
fmt.Sprintf("gap between dispatch %d and %d was %v, expected >= 160ms", i-1, i, gap))
|
||||
offset := times[i].Sub(times[0])
|
||||
minOffset := time.Duration(i)*200*time.Millisecond - 50*time.Millisecond
|
||||
Expect(offset).To(BeNumerically(">=", minOffset),
|
||||
fmt.Sprintf("dispatch %d ran %v after the first, expected >= %v", i, offset, minOffset))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue