git-lfs/tasklog/log_test.go
Taylor Blau 7c244da198 tasklog/log.go: print "done" messages with a trailing period
We use package 'tasklog' to print progress messages to the command line
interface, as in the case of 'git-migrate-import(1)' or
'git-lfs-prune(1)'.

This package aims to mimic the style of upstream Git's progress log
lines, which are identical in every way, except for the trailing period
at the end of 'done'.

Git does print this period, but Git LFS does not. Let's make the two
more similar by having LFS print this period, too.
2019-08-23 17:04:37 -04:00

210 lines
4.9 KiB
Go

package tasklog
import (
"bytes"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type ChanTask chan *Update
func (e ChanTask) Updates() <-chan *Update { return e }
func (e ChanTask) Throttled() bool { return true }
type UnthrottledChanTask chan *Update
func (e UnthrottledChanTask) Updates() <-chan *Update { return e }
func (e UnthrottledChanTask) Throttled() bool { return false }
func TestLoggerLogsTasks(t *testing.T) {
var buf bytes.Buffer
task := make(chan *Update)
go func() {
task <- &Update{"first", time.Now(), false}
task <- &Update{"second", time.Now(), false}
close(task)
}()
l := NewLogger(&buf, ForceProgress(true))
l.throttle = 0
l.widthFn = func() int { return 0 }
l.Enqueue(ChanTask(task))
l.Close()
assert.Equal(t, "first\rsecond\rsecond, done.\n", buf.String())
}
func TestLoggerLogsSuppressesProgress(t *testing.T) {
var buf bytes.Buffer
task := make(chan *Update)
go func() {
task <- &Update{"first", time.Now(), false}
task <- &Update{"second", time.Now(), false}
close(task)
}()
l := NewLogger(&buf, ForceProgress(false))
l.throttle = 0
l.widthFn = func() int { return 0 }
l.Enqueue(ChanTask(task))
l.Close()
assert.Equal(t, "second, done.\n", buf.String())
}
func TestLoggerLogsMultipleTasksInOrder(t *testing.T) {
var buf bytes.Buffer
t1 := make(chan *Update)
go func() {
t1 <- &Update{"first", time.Now(), false}
t1 <- &Update{"second", time.Now(), false}
close(t1)
}()
t2 := make(chan *Update)
go func() {
t2 <- &Update{"third", time.Now(), false}
t2 <- &Update{"fourth", time.Now(), false}
close(t2)
}()
l := NewLogger(&buf, ForceProgress(true))
l.throttle = 0
l.widthFn = func() int { return 0 }
l.Enqueue(ChanTask(t1), ChanTask(t2))
l.Close()
assert.Equal(t, strings.Join([]string{
"first\r",
"second\r",
"second, done.\n",
"third\r",
"fourth\r",
"fourth, done.\n",
}, ""), buf.String())
}
func TestLoggerLogsMultipleTasksWithoutBlocking(t *testing.T) {
var buf bytes.Buffer
l := NewLogger(&buf, ForceProgress(true))
l.throttle = 0
t1, t2 := make(chan *Update), make(chan *Update)
l.widthFn = func() int { return 0 }
l.Enqueue(ChanTask(t1))
t1 <- &Update{"first", time.Now(), false}
l.Enqueue(ChanTask(t2))
close(t1)
t2 <- &Update{"second", time.Now(), false}
close(t2)
l.Close()
assert.Equal(t, strings.Join([]string{
"first\r",
"first, done.\n",
"second\r",
"second, done.\n",
}, ""), buf.String())
}
func TestLoggerThrottlesWrites(t *testing.T) {
var buf bytes.Buffer
t1 := make(chan *Update)
go func() {
start := time.Now()
t1 <- &Update{"first", start, false} // t = 0 ms, throttle was open
t1 <- &Update{"forced", start.Add(10 * time.Millisecond), true} // t = 10+ε ms, throttle is closed
t1 <- &Update{"second", start.Add(10 * time.Millisecond), false} // t = 10+ε ms, throttle is closed
t1 <- &Update{"third", start.Add(26 * time.Millisecond), false} // t = 20+ε ms, throttle was open
close(t1) // t = 20+2ε ms, throttle is closed
}()
l := NewLogger(&buf, ForceProgress(true))
l.widthFn = func() int { return 0 }
l.throttle = 15 * time.Millisecond
l.Enqueue(ChanTask(t1))
l.Close()
assert.Equal(t, strings.Join([]string{
"first\r",
"forced\r",
"third\r",
"third, done.\n",
}, ""), buf.String())
}
func TestLoggerThrottlesLastWrite(t *testing.T) {
var buf bytes.Buffer
t1 := make(chan *Update)
go func() {
start := time.Now()
t1 <- &Update{"first", start, false} // t = 0 ms, throttle was open
t1 <- &Update{"second", start.Add(10 * time.Millisecond), false} // t = 10+ε ms, throttle is closed
close(t1) // t = 10+2ε ms, throttle is closed
}()
l := NewLogger(&buf, ForceProgress(true))
l.widthFn = func() int { return 0 }
l.throttle = 15 * time.Millisecond
l.Enqueue(ChanTask(t1))
l.Close()
assert.Equal(t, strings.Join([]string{
"first\r",
"second, done.\n",
}, ""), buf.String())
}
func TestLoggerLogsAllDurableUpdates(t *testing.T) {
var buf bytes.Buffer
l := NewLogger(&buf, ForceProgress(true))
l.widthFn = func() int { return 0 }
l.throttle = 15 * time.Minute
t1 := make(chan *Update)
go func() {
t1 <- &Update{"first", time.Now(), false} // t = 0+ε ms, throttle is open
t1 <- &Update{"second", time.Now(), false} // t = 0+2ε ms, throttle is closed
close(t1) // t = 0+3ε ms, throttle is closed
}()
l.Enqueue(UnthrottledChanTask(t1))
l.Close()
assert.Equal(t, strings.Join([]string{
"first\r",
"second\r",
"second, done.\n",
}, ""), buf.String())
}
func TestLoggerHandlesSilentTasks(t *testing.T) {
var buf bytes.Buffer
task := make(chan *Update)
close(task)
l := NewLogger(&buf, ForceProgress(true))
l.Enqueue(ChanTask(task))
l.Close()
assert.Equal(t, "", buf.String())
}