File: reader_pause_test.go

package info (click to toggle)
moor 2.10.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,960 kB
  • sloc: sh: 229; ansic: 12; xml: 6; makefile: 5
file content (138 lines) | stat: -rw-r--r-- 4,426 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package reader

import (
	"os"
	"strings"
	"testing"
	"time"

	"github.com/alecthomas/chroma/v2/formatters"
	"github.com/alecthomas/chroma/v2/styles"
	"github.com/walles/moor/v2/internal/linemetadata"
	"gotest.tools/v3/assert"
)

func TestPauseAfterNLines(t *testing.T) {
	pauseAfterLines := 1

	// Get ourselves a reader
	twoLines := strings.NewReader("one\ntwo\n")
	testMe, err := NewFromStream(
		"TestPauseAfterNLines",
		twoLines,
		formatters.TTY,
		ReaderOptions{
			PauseAfterLines: &pauseAfterLines,
			Style:           styles.Get("native"),
		})
	assert.NilError(t, err)

	// Expect pause since we configured the reader to pause after 1 line ^
	for testMe.PauseStatus.Load() != true {
	}
	assert.Assert(t, testMe.PauseStatus.Load() == true,
		"Reader should be paused after reading %d lines", pauseAfterLines)

	// Verify that we have *not* received a done notification yet
	assert.Assert(t, testMe.ReadingDone.Load() == false,
		"Reader should not be done yet, only paused")

	// Check that the reader has exactly the first line and nothing else
	lines := testMe.GetLines(linemetadata.Index{}, 2).Lines
	assert.Equal(t, len(lines), 1,
		"Reader should have exactly one line after pausing")
	assert.Equal(t, lines[0].Plain(), "one",
		"Reader should have the first line after pausing")

	// Tell reader to continue
	testMe.SetPauseAfterLines(99)

	// More lines allowed, expect pause to be over
	for testMe.PauseStatus.Load() != false {
	}
	assert.Assert(t, testMe.PauseStatus.Load() == false,
		"Reader should be unpaused after continuing")

	// Expect a done notification
	<-testMe.MaybeDone
	assert.Assert(t, testMe.ReadingDone.Load() == true,
		"Reader should be done after reading all lines")

	// Check that the reader has both lines
	lines = testMe.GetLines(linemetadata.Index{}, 3).Lines
	assert.Equal(t, len(lines), 2,
		"Reader should have two lines after unpausing")
	assert.Equal(t, lines[0].Plain(), "one",
		"Reader should have the first line after unpausing")
	assert.Equal(t, lines[1].Plain(), "two",
		"Reader should have the second line after unpausing")
}

// Test pausing behavior after we're done reading from a file, and then another line is added.
func TestPauseAfterNLines_Polling(t *testing.T) {
	pauseAfterLines := 1

	// Create a file with a line in it
	file, err := os.CreateTemp("", "TestPauseAfterNLines_Polling")
	assert.NilError(t, err)
	defer os.Remove(file.Name()) //nolint:errcheck
	_, err = file.WriteString("one\n")
	assert.NilError(t, err)

	// Point a reader at the file
	testMe, err := NewFromFilename(file.Name(), formatters.TTY, ReaderOptions{
		PauseAfterLines: &pauseAfterLines,
		Style:           styles.Get("native"),
	})
	assert.NilError(t, err)

	// Expect pause since we configured the reader to pause after 1 line ^
	for testMe.PauseStatus.Load() != true {
	}
	assert.Assert(t, testMe.PauseStatus.Load() == true,
		"Reader should be paused after reading %d lines", pauseAfterLines)

	// Verify state before we add another line to the file
	lines := testMe.GetLines(linemetadata.Index{}, 2).Lines
	assert.Equal(t, len(lines), 1,
		"Reader should have exactly one line after pausing")
	assert.Equal(t, lines[0].Plain(), "one",
		"Reader should have the first line after pausing")

	// Write another line to the file
	_, err = file.WriteString("two\n")
	assert.NilError(t, err)

	// Wait up to two seconds for tailFile() to give us the new line even though
	// we are paused. That shouldn't happen. If it does we fail here.
	//
	// tailFile() polls every second, so two seconds should cover it.
	for range 20 {
		allLines := testMe.GetLines(linemetadata.Index{}, 10)
		if len(allLines.Lines) == 2 {
			assert.Assert(t, false, "Reader should not have received a new line while paused")
		}
		time.Sleep(100 * time.Millisecond)
	}

	// No new line while paused, good! Unpause.
	testMe.SetPauseAfterLines(99)

	// Give the new line two seconds to arrive
	var bothLines []NumberedLine
	for range 20 {
		bothLines = testMe.GetLines(linemetadata.Index{}, 10).Lines
		if len(bothLines) > 1 {
			break
		}
		time.Sleep(100 * time.Millisecond)
	}

	// Verify that we have both lines now
	assert.Equal(t, len(bothLines), 2,
		"Reader should have two lines after unpausing")
	assert.Equal(t, bothLines[0].Plain(), "one",
		"Reader should have the first line after unpausing")
	assert.Equal(t, bothLines[1].Plain(), "two",
		"Reader should have the second line after unpausing")
}