Skip to content

Commit 801db3a

Browse files
committed
Handle process termination race
The process might get terminated before EOF, so add a check for that specific error. This does a bit of refactoring too to decouple line-reading from line-parsing.
1 parent 19a24c5 commit 801db3a

File tree

1 file changed

+36
-45
lines changed

1 file changed

+36
-45
lines changed

transformation_test/transformation_test.go

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"bytes"
2020
"context"
2121
"encoding/json"
22+
"errors"
2223
"flag"
2324
"fmt"
2425
"io"
@@ -443,60 +444,50 @@ func (transformationConfig transformationTest) runOTelTestInner(t *testing.T, na
443444
t.Fatal("Failed to start command:", err)
444445
}
445446

446-
var errors []any
447+
var errorList []any
447448

448449
// Read from stderr until EOF and put any errors in `errors`.
449450
eg.Go(func() error {
450451
consumingCount := 0
451-
r := bufio.NewReader(stderr)
452-
d := json.NewDecoder(r)
453-
for {
452+
s := bufio.NewScanner(stderr)
453+
for s.Scan() {
454+
line := s.Text()
454455
log := map[string]any{}
455-
if err := d.Decode(&log); err == io.EOF {
456-
return nil
457-
} else if err != nil {
458-
// Not valid JSON, just print the raw stderr.
459-
// This happens when the config is invalid.
460-
buf, err2 := io.ReadAll(d.Buffered())
461-
if err2 != nil {
462-
return err
456+
if err := json.Unmarshal([]byte(line), &log); err == nil {
457+
t.Logf("collector log output: %s", line)
458+
delete(log, "ts")
459+
level, _ := log["level"].(string)
460+
if level != "info" && level != "debug" && level != "None" {
461+
errorList = append(errorList, log)
463462
}
464-
buf2, err2 := io.ReadAll(r)
465-
if err2 != nil {
466-
return err
467-
}
468-
stderr := fmt.Sprintf("%s%s", string(buf), string(buf2))
469-
t.Logf("collector stderr:\n%s", stderr)
470-
stderr = sanitizeStacktrace(t, stderr)
471-
errors = append(errors, map[string]any{"stderr": stderr})
472-
return nil
473-
}
474-
b, err := json.Marshal(log)
475-
if err != nil {
476-
t.Errorf("failed to marshal otel log: %v", err)
477-
} else {
478-
t.Logf("collector log output: %s", b)
479-
}
480-
delete(log, "ts")
481-
level, _ := log["level"].(string)
482-
if level != "info" && level != "debug" && level != "None" {
483-
errors = append(errors, log)
484-
}
485-
msg, _ := log["msg"].(string)
486-
if strings.HasPrefix(msg, "Consuming files") {
487-
consumingCount += 1
488-
if consumingCount == 2 {
489-
// We've processed the entire input file. Signal the collector to stop.
490-
if err := cmd.Process.Signal(os.Interrupt); err != nil {
491-
t.Errorf("failed to signal process: %v", err)
463+
msg, _ := log["msg"].(string)
464+
if strings.HasPrefix(msg, "Consuming files") {
465+
consumingCount += 1
466+
if consumingCount == 2 {
467+
// We've processed the entire input file. Signal the collector to stop.
468+
if err := cmd.Process.Signal(os.Interrupt); err != nil {
469+
t.Errorf("failed to signal process: %v", err)
470+
}
492471
}
493472
}
473+
stacktrace, ok := log["stacktrace"].(string)
474+
if ok {
475+
log["stacktrace"] = sanitizeStacktrace(t, stacktrace)
476+
}
477+
} else {
478+
t.Logf("collector stderr:\n%s", line)
479+
line = sanitizeStacktrace(t, line)
480+
errorList = append(errorList, map[string]any{"stderr": line})
494481
}
495-
stacktrace, ok := log["stacktrace"].(string)
496-
if ok {
497-
log["stacktrace"] = sanitizeStacktrace(t, stacktrace)
482+
}
483+
if err := s.Err(); err != nil {
484+
if errors.Is(err, os.ErrClosed) {
485+
t.Logf("encountered non-fatal scanner error: %s", err)
486+
} else {
487+
return err
498488
}
499489
}
490+
return nil
500491
})
501492
// Read and sanitize requests.
502493
eg.Go(func() error {
@@ -529,8 +520,8 @@ func (transformationConfig transformationTest) runOTelTestInner(t *testing.T, na
529520
if exitErr != nil {
530521
got = append(got, map[string]any{"exit_error": exitErr.Error()})
531522
}
532-
if len(errors) != 0 {
533-
got = append(got, map[string]any{"collector_errors": errors})
523+
if len(errorList) != 0 {
524+
got = append(got, map[string]any{"collector_errors": errorList})
534525
}
535526
return got
536527
}

0 commit comments

Comments
 (0)