From bc2767c87c4090798c4c7d15e101ed066e947301 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 22 Jul 2026 23:51:28 +0300 Subject: =?UTF-8?q?test:=20DTail=20fork=20=E2=80=94=20integration=20test?= =?UTF-8?q?=20suite=20and=20fixtures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed development of the integration test suite (integrationtests/) covering DCat, DGrep, DMap (serverless + server mode), DTail follow, DServer, DTailHealth, journal source reads, auth-key fast reconnect, interactive query reload, client-deadline/timeout behaviour, and the single-mode read/output path. Includes real test fixtures (dserver*.cfg, dmap_csv_multifile_*.csv.in, test_server_*.json, *.expected golden files) and deterministic synchronization helpers (waitContains-style barriers) replacing racy fixed-timing assertions. Accidental debug/output dumps that earlier commits added here (captured client output, strace logs, ad-hoc turbo_test_output/manual_output/test_output files, throwaway debug scripts) are intentionally excluded and gitignored. Co-Authored-By: Claude Opus 4.8 --- integrationtests/dmap_csv_multifile_test.go | 92 +++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 integrationtests/dmap_csv_multifile_test.go (limited to 'integrationtests/dmap_csv_multifile_test.go') diff --git a/integrationtests/dmap_csv_multifile_test.go b/integrationtests/dmap_csv_multifile_test.go new file mode 100644 index 0000000..2b86e06 --- /dev/null +++ b/integrationtests/dmap_csv_multifile_test.go @@ -0,0 +1,92 @@ +package integrationtests + +import ( + "context" + "fmt" + "testing" +) + +// TestDMapCSVMultiFile regression-tests the bug where the CSV log-format +// parser consumed the first line of every file as a header, silently +// treating the second (and later) files' header rows as data rows and +// corrupting aggregates. With two CSV files that have 2 and 3 data rows +// respectively we must observe exactly 5 data rows — not 6. +func TestDMapCSVMultiFile(t *testing.T) { + cleanupTmpFiles(t) + testLogger := NewTestLogger("TestDMapCSVMultiFile") + defer testLogger.WriteLogFile() + runDualModeTest(t, DualModeTest{ + Name: "TestDMapCSVMultiFile", + ServerlessTest: func(t *testing.T) { testDMapCSVMultiFileServerless(t, testLogger) }, + ServerTest: func(t *testing.T) { testDMapCSVMultiFileWithServer(t, testLogger) }, + }) +} + +func testDMapCSVMultiFileServerless(t *testing.T, logger *TestLogger) { + inFileA := "dmap_csv_multifile_a.csv.in" + inFileB := "dmap_csv_multifile_b.csv.in" + csvFile := "dmap_csv_multifile_serverless.csv.tmp" + expectedCsvFile := "dmap_csv_multifile.csv.expected" + queryFile := fmt.Sprintf("%s.query", csvFile) + outFile := "dmap_csv_multifile_serverless.stdout.tmp" + cleanupFiles(t, csvFile, queryFile, outFile) + + query := fmt.Sprintf("select count($line) group by * logformat csv outfile %s", csvFile) + + ctxTimeout, cancel := createTestContextWithTimeout(t) + ctx := WithTestLogger(ctxTimeout, logger) + defer cancel() + _, err := runCommand(ctx, t, outFile, + "../dmap", "--query", query, "--cfg", "none", inFileA, inFileB) + if err != nil { + t.Error(err) + return + } + + if err := compareFilesContentsWithContext(ctx, t, csvFile, expectedCsvFile); err != nil { + t.Error(err) + } + if err := verifyQueryFile(t, queryFile, query); err != nil { + t.Error(err) + } +} + +func testDMapCSVMultiFileWithServer(t *testing.T, logger *TestLogger) { + ctx := WithTestLogger(context.Background(), logger) + inFileA := "dmap_csv_multifile_a.csv.in" + inFileB := "dmap_csv_multifile_b.csv.in" + csvFile := "dmap_csv_multifile_server.csv.tmp" + expectedCsvFile := "dmap_csv_multifile.csv.expected" + queryFile := fmt.Sprintf("%s.query", csvFile) + outFile := "dmap_csv_multifile_server.stdout.tmp" + cleanupFiles(t, csvFile, queryFile, outFile) + + server := NewTestServer(t) + if err := server.Start("error"); err != nil { + t.Error(err) + return + } + + query := fmt.Sprintf("select count($line) group by * logformat csv outfile %s", csvFile) + + args := NewCommandArgs() + args.Servers = []string{server.Address()} + args.TrustAllHosts = true + args.NoColor = true + args.Files = []string{inFileA, inFileB} + args.ExtraArgs = []string{"--query", query} + + _, err := runCommand(server.ctx, t, outFile, + "../dmap", args.ToSlice()...) + if err != nil { + t.Error(err) + return + } + + if err := compareFilesContentsWithContext(ctx, t, csvFile, expectedCsvFile); err != nil { + t.Error(err) + } + if err := verifyQueryFile(t, queryFile, query); err != nil { + t.Error(err) + } +} -- cgit v1.2.3