Skip to content

Commit 8568e63

Browse files
author
Piotr
committed
some tests
1 parent da9fb5b commit 8568e63

File tree

2 files changed

+251
-0
lines changed

2 files changed

+251
-0
lines changed

tests/follow_test.go

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package tests
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"io"
7+
"os"
8+
"os/exec"
9+
"strings"
10+
"sync"
11+
"testing"
12+
"time"
13+
14+
"github.com/stretchr/testify/assert"
15+
)
16+
17+
func readOutput(t *testing.T, stdout io.ReadCloser, outputChan chan string, followChan chan bool, wg *sync.WaitGroup) {
18+
defer wg.Done()
19+
reader := bufio.NewReader(stdout)
20+
for {
21+
line, err := reader.ReadString('\n')
22+
if err == io.EOF {
23+
return
24+
}
25+
if err != nil {
26+
t.Logf("Error reading stdout: %v", err)
27+
return
28+
}
29+
// Log all lines for debugging
30+
t.Logf("Received line: %s", strings.TrimSpace(line))
31+
// Signal when we see the "Following file changes" message
32+
if strings.Contains(line, "Following file changes") {
33+
select {
34+
case followChan <- true:
35+
default:
36+
}
37+
}
38+
// Only capture actual test lines, not debug/info messages
39+
if strings.Contains(line, "test line") && !strings.Contains(line, "level=") {
40+
outputChan <- strings.TrimSpace(line)
41+
}
42+
}
43+
}
44+
45+
func TestLogdyE2E_FollowFullRead(t *testing.T) {
46+
// Create a named pipe
47+
pipeName := "/tmp/logdy-test-pipe-full"
48+
49+
// Remove existing pipe if it exists
50+
if _, err := os.Stat(pipeName); err == nil {
51+
os.Remove(pipeName)
52+
}
53+
54+
err := exec.Command("mkfifo", pipeName).Run()
55+
if err != nil {
56+
t.Fatalf("Failed to create pipe: %v", err)
57+
}
58+
defer os.Remove(pipeName)
59+
60+
t.Logf("Created named pipe: %s", pipeName)
61+
62+
// Channel to communicate the pipe writer
63+
pipeWriterChan := make(chan *os.File)
64+
65+
// Open pipe for writing in a goroutine
66+
go func() {
67+
pipeWriter, err := os.OpenFile(pipeName, os.O_WRONLY, 0644)
68+
assert.NoError(t, err)
69+
pipeWriterChan <- pipeWriter // Send the writer to the main goroutine
70+
}()
71+
72+
// Start logdy process in follow mode with full-read and fallthrough enabled
73+
cmd := exec.Command("go", "run", "../main.go", "follow", "--full-read", "-t", pipeName)
74+
75+
// Get stdout pipe
76+
stdout, err := cmd.StdoutPipe()
77+
assert.NoError(t, err)
78+
79+
// Create channels to collect output lines and signal following started
80+
outputChan := make(chan string, 100) // Buffered channel to prevent blocking
81+
followChan := make(chan bool, 1) // Channel to signal when following starts
82+
83+
// Start the process
84+
err = cmd.Start()
85+
assert.NoError(t, err)
86+
87+
// Use WaitGroup to manage the goroutine
88+
var wg sync.WaitGroup
89+
wg.Add(1)
90+
go readOutput(t, stdout, outputChan, followChan, &wg)
91+
92+
// Wait for the pipe writer
93+
var pipeWriter *os.File
94+
select {
95+
case pipeWriter = <-pipeWriterChan:
96+
defer pipeWriter.Close()
97+
case <-time.After(5 * time.Second):
98+
t.Fatal("Timeout waiting for pipe writer")
99+
}
100+
101+
// Write all test lines to the pipe
102+
allTestLines := []string{
103+
"test line 1",
104+
"test line 2",
105+
"test line 3",
106+
"test line 4",
107+
}
108+
109+
for _, line := range allTestLines {
110+
t.Logf("Writing line: %s", line)
111+
_, err := pipeWriter.WriteString(line + "\n")
112+
assert.NoError(t, err)
113+
// Small delay between writes
114+
time.Sleep(1 * time.Millisecond)
115+
}
116+
wg.Done()
117+
118+
// Collect output with timeout
119+
receivedLines := make([]string, 0)
120+
expectedLines := 4
121+
timeout := time.After(5 * time.Second)
122+
123+
for i := 0; i < expectedLines; i++ {
124+
select {
125+
case line := <-outputChan:
126+
t.Logf("Collected line: %s", line)
127+
receivedLines = append(receivedLines, line)
128+
case <-timeout:
129+
t.Fatalf("Timeout waiting for output. Got %d lines, expected %d. Received lines: %v",
130+
len(receivedLines), expectedLines, receivedLines)
131+
}
132+
}
133+
134+
// Kill the process since we're done testing
135+
if err := cmd.Process.Kill(); err != nil {
136+
t.Errorf("Failed to kill process: %v", err)
137+
}
138+
139+
// Wait for the output reader goroutine to finish
140+
wg.Wait()
141+
142+
// Verify output matches expected
143+
assert.Equal(t, expectedLines, len(receivedLines))
144+
for i, line := range receivedLines {
145+
assert.Equal(t, fmt.Sprintf("test line %d", i+1), line)
146+
}
147+
}

tests/stdin_test.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package tests
2+
3+
import (
4+
"bufio"
5+
"io"
6+
"os/exec"
7+
"strings"
8+
"testing"
9+
"time"
10+
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func runCmd(cmds []string, t *testing.T) {
15+
// Start logdy process in stdin mode with fallthrough enabled
16+
// -t enables fallthrough so we can see the output
17+
cmd := exec.Command("go", cmds...)
18+
19+
// Get stdin pipe
20+
stdin, err := cmd.StdinPipe()
21+
assert.NoError(t, err)
22+
23+
// Get stdout pipe
24+
stdout, err := cmd.StdoutPipe()
25+
assert.NoError(t, err)
26+
27+
// Start the process
28+
err = cmd.Start()
29+
assert.NoError(t, err)
30+
31+
// Create a channel to collect output lines
32+
outputChan := make(chan string)
33+
34+
// Start goroutine to read stdout
35+
go func() {
36+
reader := bufio.NewReader(stdout)
37+
for {
38+
line, err := reader.ReadString('\n')
39+
if err == io.EOF {
40+
close(outputChan)
41+
return
42+
}
43+
if err != nil {
44+
t.Errorf("Error reading stdout: %v", err)
45+
close(outputChan)
46+
return
47+
}
48+
// Only collect lines that contain our test data
49+
if strings.Contains(line, "test line") {
50+
outputChan <- strings.TrimSpace(line)
51+
}
52+
}
53+
}()
54+
55+
// Give the process a moment to start up
56+
time.Sleep(1 * time.Second)
57+
58+
// Write test data to stdin
59+
testLines := []string{
60+
"test line 1",
61+
"test line 2",
62+
"test line 3",
63+
}
64+
65+
for _, line := range testLines {
66+
_, err := io.WriteString(stdin, line+"\n")
67+
assert.NoError(t, err)
68+
}
69+
70+
// Collect output with timeout
71+
receivedLines := make([]string, 0)
72+
timeout := time.After(5 * time.Second)
73+
74+
for i := 0; i < len(testLines); i++ {
75+
select {
76+
case line, ok := <-outputChan:
77+
if !ok {
78+
t.Fatal("Output channel closed before receiving all expected lines")
79+
}
80+
receivedLines = append(receivedLines, line)
81+
case <-timeout:
82+
t.Fatal("Timeout waiting for output")
83+
}
84+
}
85+
86+
// Kill the process since we're done testing
87+
if err := cmd.Process.Kill(); err != nil {
88+
t.Errorf("Failed to kill process: %v", err)
89+
}
90+
91+
// Verify output matches input
92+
assert.Equal(t, len(testLines), len(receivedLines))
93+
for i, testLine := range testLines {
94+
assert.Contains(t, receivedLines[i], testLine)
95+
}
96+
}
97+
98+
func TestLogdyE2E_NoCommand(t *testing.T) {
99+
runCmd([]string{"run", "../main.go", "-t"}, t)
100+
}
101+
102+
func TestLogdyE2E_StdinCommand(t *testing.T) {
103+
runCmd([]string{"run", "../main.go", "stdin", "-t"}, t)
104+
}

0 commit comments

Comments
 (0)