Skip to content

Commit 5a51e40

Browse files
committed
db: improve compaction test timeout observability
- set up a 1 minute timeout for any datadriven compactions; - print db logs on test failures; - upgrade datadriven to include a recent change to periodically log when a single command takes a long time. Informs #5277
1 parent d1a85df commit 5a51e40

10 files changed

+61
-53
lines changed

compaction_test.go

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -905,24 +905,34 @@ func runCompactionTest(
905905
rng := rand.New(rand.NewPCG(0, seed))
906906
t.Logf("seed: %d", seed)
907907

908+
var dbLog base.InMemLogger
909+
defer func() {
910+
if t.Failed() {
911+
t.Logf("db log:\n%s\n", dbLog.String())
912+
}
913+
}()
908914
var compactionLog bytes.Buffer
909-
compactionLogEventListener := &EventListener{
910-
CompactionEnd: func(info CompactionInfo) {
911-
// Ensure determinism.
912-
info.JobID = 1
913-
info.Duration = time.Second
914-
info.TotalDuration = time.Second
915-
fmt.Fprintln(&compactionLog, info.String())
915+
eventListener := TeeEventListener(
916+
MakeLoggingEventListener(&dbLog),
917+
EventListener{
918+
CompactionEnd: func(info CompactionInfo) {
919+
// Ensure determinism.
920+
info.JobID = 1
921+
info.Duration = time.Second
922+
info.TotalDuration = time.Second
923+
fmt.Fprintln(&compactionLog, info.String())
924+
},
916925
},
917-
}
926+
)
927+
918928
concurrencyLow, concurrencyHigh := 1, 1
919929
mkOpts := func() *Options {
920930
randVersion := FormatMajorVersion(int(minVersion) + rng.IntN(int(maxVersion)-int(minVersion)+1))
921931
opts := &Options{
922932
FS: vfs.NewMem(),
923933
DebugCheck: DebugCheckLevels,
924934
DisableAutomaticCompactions: true,
925-
EventListener: compactionLogEventListener,
935+
EventListener: &eventListener,
926936
FormatMajorVersion: randVersion,
927937
Logger: testutils.Logger{T: t},
928938
Comparer: cmp,
@@ -941,6 +951,7 @@ func runCompactionTest(
941951
require.NoError(t, closeAllSnapshots(d))
942952
require.NoError(t, d.Close())
943953
}
954+
dbLog.Reset()
944955
compactionLog.Reset()
945956
concurrencyLow, concurrencyHigh = 1, 1
946957
var err error
@@ -1009,7 +1020,7 @@ func runCompactionTest(
10091020
return ""
10101021

10111022
case "compact":
1012-
if err := runCompactCmd(td, d); err != nil {
1023+
if err := runCompactCmd(t, td, d); err != nil {
10131024
return err.Error()
10141025
}
10151026
s := describeLSM(d, verbose)
@@ -1029,6 +1040,8 @@ func runCompactionTest(
10291040
require.NoError(t, d.Close())
10301041
}
10311042

1043+
dbLog.Reset()
1044+
compactionLog.Reset()
10321045
var err error
10331046
if d, err = runDBDefineCmd(td, mkOpts()); err != nil {
10341047
return err.Error()
@@ -1212,7 +1225,7 @@ func runCompactionTest(
12121225
var s string
12131226
ch := make(chan error, 1)
12141227
go func() {
1215-
if err := runCompactCmd(td, d); err != nil {
1228+
if err := runCompactCmd(t, td, d); err != nil {
12161229
ch <- err
12171230
close(ch)
12181231
return
@@ -1276,12 +1289,10 @@ func runCompactionTest(
12761289
td.ScanArgs(t, "num-blocked", &numBlocked)
12771290
var cancelFunc atomic.Pointer[context.CancelFunc]
12781291
go func() {
1279-
compactFunc, cf, err := runCompactCmdAsync(td, d, true)
1280-
if err == nil {
1281-
cancelFunc.Store(&cf)
1282-
err = compactFunc()
1283-
}
1284-
if err != nil {
1292+
ctx, cf := context.WithCancel(context.Background())
1293+
compactFunc := runCompactCmdFn(ctx, t, td, d)
1294+
cancelFunc.Store(&cf)
1295+
if err := compactFunc(); err != nil {
12851296
ch <- err
12861297
close(ch)
12871298
return
@@ -1769,7 +1780,7 @@ func TestCompactionDeleteOnlyHints(t *testing.T) {
17691780
return buf.String()
17701781

17711782
case "compact":
1772-
if err := runCompactCmd(td, d); err != nil {
1783+
if err := runCompactCmd(t, td, d); err != nil {
17731784
return err.Error()
17741785
}
17751786
d.mu.Lock()

data_test.go

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -760,53 +760,50 @@ func runBuildSSTCmd(
760760
return *metadata, nil
761761
}
762762

763-
func runCompactCmdAsync(
764-
td *datadriven.TestData, d *DB, cancellable bool,
765-
) (compactFunc func() error, cancelFunc context.CancelFunc, err error) {
763+
// runCompactCmdFn reurns a function that runs the compaction in the given
764+
// command. The context can be cancellable.
765+
func runCompactCmdFn(
766+
ctx context.Context, t *testing.T, td *datadriven.TestData, d *DB,
767+
) (compactFunc func() error) {
766768
if len(td.CmdArgs) == 0 {
767-
return nil, nil, errors.Errorf("%s expects at least one argument", td.Cmd)
769+
td.Fatalf(t, "%s expects at least one argument", td.Cmd)
768770
}
769771
parts := strings.Split(td.CmdArgs[0].Key, "-")
770772
if len(parts) != 2 {
771-
return nil, nil, errors.Errorf("expected <begin>-<end>: %s", td.Input)
773+
td.Fatalf(t, "expected <begin>-<end>: %s", td.Input)
772774
}
773775
parallelize := td.HasArg("parallel")
774-
ctx := context.Background()
775-
if cancellable {
776-
ctx, cancelFunc = context.WithCancel(ctx)
777-
}
778776
if len(td.CmdArgs) >= 2 && strings.HasPrefix(td.CmdArgs[1].Key, "L") {
779777
levelString := td.CmdArgs[1].String()
780778
iStart := base.MakeInternalKey([]byte(parts[0]), base.SeqNumMax, InternalKeyKindMax)
781779
iEnd := base.MakeInternalKey([]byte(parts[1]), 0, 0)
782780
if levelString[0] != 'L' {
783-
if cancelFunc != nil {
784-
cancelFunc()
785-
}
786-
return nil, nil, errors.Errorf("expected L<n>: %s", levelString)
781+
td.Fatalf(t, "expected L<n>: %s", levelString)
787782
}
788783
level, err := strconv.Atoi(levelString[1:])
789784
if err != nil {
790-
if cancelFunc != nil {
791-
cancelFunc()
792-
}
793-
return nil, nil, err
785+
td.Fatalf(t, "cannot parse level number: %v", err)
794786
}
795787
return func() error {
796788
return d.manualCompact(ctx, iStart.UserKey, iEnd.UserKey, level, parallelize)
797-
}, cancelFunc, nil
789+
}
798790
}
799791
return func() error {
800792
return d.Compact(ctx, []byte(parts[0]), []byte(parts[1]), parallelize)
801-
}, cancelFunc, nil
793+
}
802794
}
803795

804-
func runCompactCmd(td *datadriven.TestData, d *DB) error {
805-
compactFunc, _, err := runCompactCmdAsync(td, d, false)
806-
if err != nil {
807-
return err
808-
}
809-
return compactFunc()
796+
func runCompactCmd(t *testing.T, td *datadriven.TestData, d *DB) error {
797+
ctx := context.Background()
798+
// Set up a 1-minute deadline to detect stuck compactions.
799+
ctx, cancelFn := context.WithDeadline(ctx, time.Now().Add(time.Minute))
800+
defer cancelFn()
801+
compactFunc := runCompactCmdFn(ctx, t, td, d)
802+
err := compactFunc()
803+
if ctx.Err() != nil {
804+
td.Fatalf(t, "compaction took too long")
805+
}
806+
return err
810807
}
811808

812809
// runDBDefineCmd prepares a database state, returning the opened

disk_usage_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func TestEstimateDiskUsageDataDriven(t *testing.T) {
103103
}
104104
return ""
105105
case "compact":
106-
if err := runCompactCmd(td, d); err != nil {
106+
if err := runCompactCmd(t, td, d); err != nil {
107107
return err.Error()
108108
}
109109
return runLSMCmd(td, d)

excise_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,15 +756,15 @@ func TestConcurrentExcise(t *testing.T) {
756756
tdClone = *td
757757
tdClone.CmdArgs = otherArgs
758758
if !async {
759-
err := runCompactCmd(td, d)
759+
err := runCompactCmd(t, td, d)
760760
if err != nil {
761761
return err.Error()
762762
}
763763
} else {
764764
wg.Add(1)
765765
go func() {
766766
defer wg.Done()
767-
_ = runCompactCmd(&tdClone, d)
767+
_ = runCompactCmd(t, &tdClone, d)
768768
}()
769769
<-bc.startBlock
770770
return "spun off in separate goroutine"

ingest_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,7 @@ func testIngestSharedImpl(
988988
return "ok"
989989

990990
case "compact":
991-
err := runCompactCmd(td, d)
991+
err := runCompactCmd(t, td, d)
992992
if err != nil {
993993
return err.Error()
994994
}

iterator_histories_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func TestIterHistories(t *testing.T) {
185185
}
186186
return fmt.Sprintf("wrote %d keys to batch %q\n", count, name)
187187
case "compact":
188-
if err := runCompactCmd(td, d); err != nil {
188+
if err := runCompactCmd(t, td, d); err != nil {
189189
return err.Error()
190190
}
191191
return runLSMCmd(td, d)

metrics_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ func TestMetrics(t *testing.T) {
329329
return ""
330330

331331
case "compact":
332-
if err := runCompactCmd(td, d); err != nil {
332+
if err := runCompactCmd(t, td, d); err != nil {
333333
return err.Error()
334334
}
335335

range_del_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func TestRangeDel(t *testing.T) {
6868
return runWaitForTableStatsCmd(td, d)
6969

7070
case "compact":
71-
if err := runCompactCmd(td, d); err != nil {
71+
if err := runCompactCmd(t, td, d); err != nil {
7272
return err.Error()
7373
}
7474
d.mu.Lock()

scan_internal_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func TestScanStatistics(t *testing.T) {
126126
}
127127
return fmt.Sprintf("wrote %d keys to batch %q\n", count, name)
128128
case "compact":
129-
if err := runCompactCmd(td, d); err != nil {
129+
if err := runCompactCmd(t, td, d); err != nil {
130130
return err.Error()
131131
}
132132
return runLSMCmd(td, d)
@@ -491,7 +491,7 @@ func TestScanInternal(t *testing.T) {
491491
}
492492
return fmt.Sprintf("wrote %d keys to batch %q\n", count, name)
493493
case "compact":
494-
if err := runCompactCmd(td, d); err != nil {
494+
if err := runCompactCmd(t, td, d); err != nil {
495495
return err.Error()
496496
}
497497
return runLSMCmd(td, d)

table_stats_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func TestTableStats(t *testing.T) {
175175
return s
176176

177177
case "compact":
178-
if err := runCompactCmd(td, d); err != nil {
178+
if err := runCompactCmd(t, td, d); err != nil {
179179
return err.Error()
180180
}
181181
d.mu.Lock()

0 commit comments

Comments
 (0)