Skip to content

Commit

Permalink
some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Piotr committed Dec 10, 2024
1 parent da9fb5b commit 8568e63
Show file tree
Hide file tree
Showing 2 changed files with 251 additions and 0 deletions.
147 changes: 147 additions & 0 deletions tests/follow_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package tests

import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"strings"
"sync"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func readOutput(t *testing.T, stdout io.ReadCloser, outputChan chan string, followChan chan bool, wg *sync.WaitGroup) {
defer wg.Done()
reader := bufio.NewReader(stdout)
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
return
}
if err != nil {
t.Logf("Error reading stdout: %v", err)
return
}
// Log all lines for debugging
t.Logf("Received line: %s", strings.TrimSpace(line))
// Signal when we see the "Following file changes" message
if strings.Contains(line, "Following file changes") {
select {
case followChan <- true:
default:
}
}
// Only capture actual test lines, not debug/info messages
if strings.Contains(line, "test line") && !strings.Contains(line, "level=") {
outputChan <- strings.TrimSpace(line)
}
}
}

func TestLogdyE2E_FollowFullRead(t *testing.T) {
// Create a named pipe
pipeName := "/tmp/logdy-test-pipe-full"

// Remove existing pipe if it exists
if _, err := os.Stat(pipeName); err == nil {
os.Remove(pipeName)
}

err := exec.Command("mkfifo", pipeName).Run()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
defer os.Remove(pipeName)

t.Logf("Created named pipe: %s", pipeName)

// Channel to communicate the pipe writer
pipeWriterChan := make(chan *os.File)

// Open pipe for writing in a goroutine
go func() {
pipeWriter, err := os.OpenFile(pipeName, os.O_WRONLY, 0644)
assert.NoError(t, err)
pipeWriterChan <- pipeWriter // Send the writer to the main goroutine
}()

// Start logdy process in follow mode with full-read and fallthrough enabled
cmd := exec.Command("go", "run", "../main.go", "follow", "--full-read", "-t", pipeName)

// Get stdout pipe
stdout, err := cmd.StdoutPipe()
assert.NoError(t, err)

// Create channels to collect output lines and signal following started
outputChan := make(chan string, 100) // Buffered channel to prevent blocking
followChan := make(chan bool, 1) // Channel to signal when following starts

// Start the process
err = cmd.Start()
assert.NoError(t, err)

// Use WaitGroup to manage the goroutine
var wg sync.WaitGroup
wg.Add(1)
go readOutput(t, stdout, outputChan, followChan, &wg)

// Wait for the pipe writer
var pipeWriter *os.File
select {
case pipeWriter = <-pipeWriterChan:
defer pipeWriter.Close()
case <-time.After(5 * time.Second):
t.Fatal("Timeout waiting for pipe writer")
}

// Write all test lines to the pipe
allTestLines := []string{
"test line 1",
"test line 2",
"test line 3",
"test line 4",
}

for _, line := range allTestLines {
t.Logf("Writing line: %s", line)
_, err := pipeWriter.WriteString(line + "\n")
assert.NoError(t, err)
// Small delay between writes
time.Sleep(1 * time.Millisecond)
}
wg.Done()

// Collect output with timeout
receivedLines := make([]string, 0)
expectedLines := 4
timeout := time.After(5 * time.Second)

for i := 0; i < expectedLines; i++ {
select {
case line := <-outputChan:
t.Logf("Collected line: %s", line)
receivedLines = append(receivedLines, line)
case <-timeout:
t.Fatalf("Timeout waiting for output. Got %d lines, expected %d. Received lines: %v",
len(receivedLines), expectedLines, receivedLines)
}
}

// Kill the process since we're done testing
if err := cmd.Process.Kill(); err != nil {
t.Errorf("Failed to kill process: %v", err)
}

// Wait for the output reader goroutine to finish
wg.Wait()

// Verify output matches expected
assert.Equal(t, expectedLines, len(receivedLines))
for i, line := range receivedLines {
assert.Equal(t, fmt.Sprintf("test line %d", i+1), line)
}
}
104 changes: 104 additions & 0 deletions tests/stdin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package tests

import (
"bufio"
"io"
"os/exec"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func runCmd(cmds []string, t *testing.T) {
// Start logdy process in stdin mode with fallthrough enabled
// -t enables fallthrough so we can see the output
cmd := exec.Command("go", cmds...)

// Get stdin pipe
stdin, err := cmd.StdinPipe()
assert.NoError(t, err)

// Get stdout pipe
stdout, err := cmd.StdoutPipe()
assert.NoError(t, err)

// Start the process
err = cmd.Start()
assert.NoError(t, err)

// Create a channel to collect output lines
outputChan := make(chan string)

// Start goroutine to read stdout
go func() {
reader := bufio.NewReader(stdout)
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
close(outputChan)
return
}
if err != nil {
t.Errorf("Error reading stdout: %v", err)
close(outputChan)
return
}
// Only collect lines that contain our test data
if strings.Contains(line, "test line") {
outputChan <- strings.TrimSpace(line)
}
}
}()

// Give the process a moment to start up
time.Sleep(1 * time.Second)

// Write test data to stdin
testLines := []string{
"test line 1",
"test line 2",
"test line 3",
}

for _, line := range testLines {
_, err := io.WriteString(stdin, line+"\n")
assert.NoError(t, err)
}

// Collect output with timeout
receivedLines := make([]string, 0)
timeout := time.After(5 * time.Second)

for i := 0; i < len(testLines); i++ {
select {
case line, ok := <-outputChan:
if !ok {
t.Fatal("Output channel closed before receiving all expected lines")
}
receivedLines = append(receivedLines, line)
case <-timeout:
t.Fatal("Timeout waiting for output")
}
}

// Kill the process since we're done testing
if err := cmd.Process.Kill(); err != nil {
t.Errorf("Failed to kill process: %v", err)
}

// Verify output matches input
assert.Equal(t, len(testLines), len(receivedLines))
for i, testLine := range testLines {
assert.Contains(t, receivedLines[i], testLine)
}
}

func TestLogdyE2E_NoCommand(t *testing.T) {
runCmd([]string{"run", "../main.go", "-t"}, t)
}

func TestLogdyE2E_StdinCommand(t *testing.T) {
runCmd([]string{"run", "../main.go", "stdin", "-t"}, t)
}

0 comments on commit 8568e63

Please sign in to comment.