synapsecns/sanguine

View on GitHub
core/processlog/logs_test.go

Summary

Maintainability
A
2 hrs
Test Coverage
package processlog_test

import (
    "bytes"
    "context"
    "fmt"
    "github.com/Flaque/filet"
    "github.com/stretchr/testify/assert"
    "github.com/synapsecns/sanguine/core/processlog"
    "io"
    "os"
    "strings"
    "testing"
    "time"
)

// TestWritePrintFunc tests the writePrintFunc function.
func TestWritePrintFunc(t *testing.T) {
    // Create a new pipe for stdout and write some data to it.
    stdOutR, stdOutW := io.Pipe()
    go func() {
        defer func(stdOutW *io.PipeWriter) {
            err := stdOutW.Close()
            assert.Nil(t, err)
        }(stdOutW)
        _, err := stdOutW.Write([]byte("stdout data"))
        if err != nil {
            t.Errorf("unexpected error: %v", err)
        }
    }()

    // Create a new pipe for stderr and write some data to it.
    stdErrR, stdErrW := io.Pipe()
    go func() {
        defer func(stdErrW *io.PipeWriter) {
            err := stdErrW.Close()
            assert.Nil(t, err)
        }(stdErrW)
        _, err := stdErrW.Write([]byte("stderr data"))
        if err != nil {
            t.Errorf("unexpected error: %v", err)
        }
    }()

    // Create a new buffer for the print function.
    var buf bytes.Buffer

    // Create a new context with a timeout.
    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel()

    // Call the writePrintFunc function.
    processlog.WritePrintFunc(ctx, func(s []byte) {
        buf.WriteString(fmt.Sprintf("%s ", s))
    }, time.Second, stdOutR, stdErrR)

    // Check that the buffer contains the expected data.
    actual := strings.Split(strings.TrimSuffix(buf.String(), " "), " ")
    expected := strings.Split("stderr datastdout data", " ")

    if len(actual) != len(expected) {
        t.Errorf("expected %q, but got %q", expected, buf.String())
    }
}

type bufCloser struct {
    *bytes.Buffer
}

// Mock.
func (b bufCloser) Close() error {
    return nil
}

// TestPipeSingleOutput tests the pipeSingleOutput function.
func TestPipeSingleOutput(t *testing.T) {
    // Create a new temporary file.
    tmpfile, err := os.CreateTemp("", "example")
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
    defer func() {
        _ = os.Remove(tmpfile.Name())
    }()

    // Create a new buffer with some data.
    data := "test data"
    buf := bufCloser{bytes.NewBufferString(data)}

    // Call the pipeSingleOutput function.
    err = processlog.PipeSingleOutput(tmpfile, buf)

    // Check that the function returned no error.
    if err != nil {
        t.Errorf("unexpected error: %v", err)
    }

    // Check that the file contains the expected data.
    fileData, err := os.ReadFile(tmpfile.Name())
    if err != nil {
        t.Errorf("unexpected error: %v", err)
    }
    if string(fileData) != data {
        t.Errorf("expected %q, but got %q", data, string(fileData))
    }
}

// TestPipeCombinedOutput tests the pipeCombinedOutput function.
func TestPipeCombinedOutput(t *testing.T) {
    // Create a new temporary file.
    tmpfile, err := os.CreateTemp("", "example")
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
    defer func(name string) {
        err := os.Remove(name)
        if err != nil {
            return
        }
    }(tmpfile.Name())

    // Create some mock data.
    data1 := "test data 1"
    data2 := "test data 2"
    data3 := "test data 3"
    buf1 := bufCloser{bytes.NewBufferString(data1)}
    buf2 := bufCloser{bytes.NewBufferString(data2)}
    buf3 := bufCloser{bytes.NewBufferString(data3)}

    // Call the pipeCombinedOutput function with the mock data.
    err = processlog.PipeCombinedOutput(context.Background(), tmpfile, nil, buf1, buf2, buf3)

    // Check that the function returned no error.
    if err != nil {
        t.Errorf("unexpected error: %v", err)
    }

    // Check that the file contains the expected data.
    fileData, err := os.ReadFile(tmpfile.Name())
    if err != nil {
        t.Errorf("unexpected error: %v", err)
    }
    expectedData := data1 + "\n" + data2 + "\n" + data3 + "\n"
    if len(strings.Split(expectedData, "\n")) != len(strings.Split(string(fileData), "\n")) {
        t.Errorf("expected %q, but got %q", expectedData, string(fileData))
    }
}

// TestStartLogs tests the StartLogs function.
func TestStartLogs(t *testing.T) {
    // Create a new temporary directory.
    tmpdir, err := os.MkdirTemp("", "example")
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
    defer func(path string) {
        _ = os.RemoveAll(path)
    }(tmpdir)

    // Create some mock data.
    data1 := "test data 1"
    data2 := "test data 2"
    data3 := "test data 3"
    buf1 := bytes.NewBufferString(data1)
    buf2 := bytes.NewBufferString(data2)
    acc := bytes.NewBufferString(data3)

    // Set up the arguments for the StartLogs function.
    logDir := filet.TmpDir(t, tmpdir)
    logFileName := "test"
    logFrequency := 1 * time.Second
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
    args := []processlog.StdStreamLogArgsOption{
        processlog.WithStdOut(bufCloser{buf1}),
        processlog.WithStdErr(bufCloser{buf2}),
        processlog.WithLogDir(logDir),
        processlog.WithLogFileName(logFileName),
        processlog.WithLogFrequency(logFrequency),
        processlog.WithAccumulator(acc),
        processlog.WithCtx(ctx),
    }

    // Call the StartLogs function.
    res, err := processlog.StartLogs(args...)
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }

    // Wait for the log files to be written.
    time.Sleep(2 * time.Second)

    // Check that the separate stdout file contains the expected data.
    stdOutData, err := os.ReadFile(res.StdOutFile())
    if err != nil {
        t.Errorf("unexpected error: %v", err)
    }
    if string(stdOutData) != data1 {
        t.Errorf("expected %q, but got %q", data1+"\n", string(stdOutData))
    }

    // Check that the separate stderr file contains the expected data.
    stdErrData, err := os.ReadFile(res.StdErrFile())
    if err != nil {
        t.Errorf("unexpected error: %v", err)
    }
    if string(stdErrData) != data2 {
        t.Errorf("expected %q, but got %q", data2+"\n", string(stdErrData))
    }

    // Check that the combined log file contains the expected data.
    combinedData, err := os.ReadFile(res.CombinedFile())
    if err != nil {
        t.Errorf("unexpected error: %v", err)
    }
    if !(len(string(combinedData)) >= len(stdErrData)+len(stdOutData)) {
        t.Error("failed to combine")
    }
}