mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
fix: background reader apart from global handler for testing (#1929)
Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com>
This commit is contained in:
parent
05a61897f2
commit
38efe4ec5f
@ -22,11 +22,10 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
_ tea.Model = (*attestLogFrame)(nil)
|
_ tea.Model = (*attestLogFrame)(nil)
|
||||||
_ cosignOutputReader = (*backgroundLineReader)(nil)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type attestLogFrame struct {
|
type attestLogFrame struct {
|
||||||
reader cosignOutputReader
|
reader *backgroundLineReader
|
||||||
prog progress.Progressable
|
prog progress.Progressable
|
||||||
lines []string
|
lines []string
|
||||||
completed bool
|
completed bool
|
||||||
@ -47,14 +46,16 @@ type attestLogFrameTickMsg struct {
|
|||||||
ID uint32
|
ID uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type cosignOutputReader interface {
|
|
||||||
Lines() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type backgroundLineReader struct {
|
type backgroundLineReader struct {
|
||||||
limit int
|
limit int
|
||||||
lines *queue.Queue[string]
|
lines *queue.Queue[string]
|
||||||
lock *sync.RWMutex
|
lock *sync.RWMutex
|
||||||
|
|
||||||
|
// This is added specifically for tests to assert when the background reader is done.
|
||||||
|
// The main UI uses the global ui wait group from the handler to otherwise block
|
||||||
|
// Shared concerns among multiple model made it difficult to test using the global wait group
|
||||||
|
// so this is added to allow tests to assert when the background reader is done.
|
||||||
|
running *sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Handler) handleAttestationStarted(e partybus.Event) []tea.Model {
|
func (m *Handler) handleAttestationStarted(e partybus.Event) []tea.Model {
|
||||||
@ -97,7 +98,7 @@ func (m *Handler) handleAttestationStarted(e partybus.Event) []tea.Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLogFrame(reader cosignOutputReader, prog progress.Progressable, borderStyle lipgloss.Style) attestLogFrame {
|
func newLogFrame(reader *backgroundLineReader, prog progress.Progressable, borderStyle lipgloss.Style) attestLogFrame {
|
||||||
return attestLogFrame{
|
return attestLogFrame{
|
||||||
reader: reader,
|
reader: reader,
|
||||||
prog: prog,
|
prog: prog,
|
||||||
@ -108,16 +109,23 @@ func newLogFrame(reader cosignOutputReader, prog progress.Progressable, borderSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newBackgroundLineReader(wg *sync.WaitGroup, reader io.Reader, stage *progress.Stage) *backgroundLineReader {
|
func newBackgroundLineReader(wg *sync.WaitGroup, reader io.Reader, stage *progress.Stage) *backgroundLineReader {
|
||||||
wg.Add(1)
|
|
||||||
r := &backgroundLineReader{
|
r := &backgroundLineReader{
|
||||||
limit: 7,
|
limit: 7,
|
||||||
lock: &sync.RWMutex{},
|
lock: &sync.RWMutex{},
|
||||||
lines: queue.New[string](),
|
lines: queue.New[string](),
|
||||||
|
running: &sync.WaitGroup{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tracks the background reader for the global handler wait group
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
// tracks the background reader for the local wait group (used in tests to decouple from the global handler wait group)
|
||||||
|
r.running.Add(1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
|
||||||
r.read(reader, stage)
|
r.read(reader, stage)
|
||||||
|
wg.Done()
|
||||||
|
r.running.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|||||||
@ -28,7 +28,7 @@ func TestHandler_handleAttestationStarted(t *testing.T) {
|
|||||||
// note: this model depends on a background reader. Multiple iterations ensures that the
|
// note: this model depends on a background reader. Multiple iterations ensures that the
|
||||||
// reader has time to at least start and process the test fixture before the runModel
|
// reader has time to at least start and process the test fixture before the runModel
|
||||||
// test harness completes (which is a fake event loop anyway).
|
// test harness completes (which is a fake event loop anyway).
|
||||||
iterations: 100,
|
iterations: 1,
|
||||||
eventFn: func(t *testing.T) partybus.Event {
|
eventFn: func(t *testing.T) partybus.Event {
|
||||||
reader := strings.NewReader("contents\nof\nstuff!")
|
reader := strings.NewReader("contents\nof\nstuff!")
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ func TestHandler_handleAttestationStarted(t *testing.T) {
|
|||||||
// note: this model depends on a background reader. Multiple iterations ensures that the
|
// note: this model depends on a background reader. Multiple iterations ensures that the
|
||||||
// reader has time to at least start and process the test fixture before the runModel
|
// reader has time to at least start and process the test fixture before the runModel
|
||||||
// test harness completes (which is a fake event loop anyway).
|
// test harness completes (which is a fake event loop anyway).
|
||||||
iterations: 100,
|
iterations: 1,
|
||||||
eventFn: func(t *testing.T) partybus.Event {
|
eventFn: func(t *testing.T) partybus.Event {
|
||||||
reader := strings.NewReader("contents\nof\nstuff!")
|
reader := strings.NewReader("contents\nof\nstuff!")
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ func TestHandler_handleAttestationStarted(t *testing.T) {
|
|||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
Sequence: log.sequence,
|
Sequence: log.sequence,
|
||||||
ID: log.id,
|
ID: log.id,
|
||||||
})
|
}, log.reader.running)
|
||||||
t.Log(got)
|
t.Log(got)
|
||||||
snaps.MatchSnapshot(t, got)
|
snaps.MatchSnapshot(t, got)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,13 +2,14 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runModel(t testing.TB, m tea.Model, iterations int, message tea.Msg) string {
|
func runModel(t testing.TB, m tea.Model, iterations int, message tea.Msg, h ...*sync.WaitGroup) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if iterations == 0 {
|
if iterations == 0 {
|
||||||
iterations = 1
|
iterations = 1
|
||||||
@ -29,6 +30,12 @@ func runModel(t testing.TB, m tea.Model, iterations int, message tea.Msg) string
|
|||||||
}
|
}
|
||||||
cmd = tea.Batch(nextCmds...)
|
cmd = tea.Batch(nextCmds...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, each := range h {
|
||||||
|
if each != nil {
|
||||||
|
each.Wait()
|
||||||
|
}
|
||||||
|
}
|
||||||
return m.View()
|
return m.View()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user