Solve intermittent build errors

This commit is contained in:
nikitar020 2019-03-14 20:05:05 +07:00
parent 4710948cd1
commit b3cf187c01
3 changed files with 99 additions and 54 deletions

View File

@ -67,6 +67,7 @@ type GUI struct {
selectionRegionMode buffer.SelectionRegionMode
mainThreadFunc chan func()
wakerEnded chan bool
}
func Min(x, y int) int {
@ -412,16 +413,6 @@ func (gui *GUI) Render() error {
gl.Disable(gl.DEPTH_TEST)
gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
go func() {
for {
<-ticker.C
gui.logger.Sync()
}
}()
gui.terminal.SetProgram(program)
latestVersion := ""
@ -502,9 +493,13 @@ Buffer Size: %d lines
}
}
close(stop) // Tell waker to end.
gui.logger.Debug("Stopping render...")
close(stop) // Tell waker to end...
<-gui.wakerEnded // ...and wait it to end
gui.logger.Debug("Render stopped")
gui.logger.Debugf("Stopping render...")
return nil
}
@ -514,9 +509,11 @@ Buffer Size: %d lines
// redrawn. Limiting is applied on wakeups to avoid excessive CPU
// usage when the terminal is being updated rapidly.
func (gui *GUI) waker(stop <-chan struct{}) {
gui.wakerEnded = make(chan bool)
dirty := gui.terminal.Dirty()
var nextWake <-chan time.Time
var last time.Time
forLoop:
for {
select {
case <-dirty:
@ -540,9 +537,10 @@ func (gui *GUI) waker(stop <-chan struct{}) {
glfw.PostEmptyEvent()
nextWake = nil
case <-stop:
return
break forLoop
}
}
gui.wakerEnded <- true
}
func (gui *GUI) renderTerminalData(shouldLock bool) {
@ -819,9 +817,15 @@ func (gui *GUI) Screenshot(path string) {
if err != nil {
panic(err)
}
file, _ := os.Create(path)
file, err := os.Create(path)
if err != nil {
panic(err)
}
defer file.Close()
png.Encode(file, img)
err = png.Encode(file, img)
if err != nil {
panic(err)
}
}
func (gui *GUI) windowPosChangeCallback(w *glfw.Window, xpos int, ypos int) {

15
main.go
View File

@ -12,6 +12,7 @@ import (
"github.com/liamg/aminal/platform"
"github.com/liamg/aminal/terminal"
"github.com/riywo/loginshell"
"time"
)
type callback func(terminal *terminal.Terminal, g *gui.GUI)
@ -32,7 +33,17 @@ func initialize(unitTestfunc callback, configOverride *config.Config) {
fmt.Printf("Failed to create logger: %s\n", err)
os.Exit(1)
}
defer logger.Sync()
ticker := time.NewTicker(time.Second)
go func() {
for {
<-ticker.C
logger.Sync()
}
}()
defer func() {
ticker.Stop()
logger.Sync()
}()
if conf.CPUProfile != "" {
logger.Infof("Starting CPU profiling...")
@ -61,7 +72,7 @@ func initialize(unitTestfunc callback, configOverride *config.Config) {
guestProcess, err := pty.CreateGuestProcess(shellStr)
if err != nil {
pty.Close()
logger.Fatalf("Failed to start your shell: %s", err)
logger.Fatalf("Failed to start your shell \"%s\": %s", shellStr, err)
}
defer guestProcess.Close()

View File

@ -5,17 +5,15 @@ package main
import (
"flag"
"fmt"
"github.com/carlogit/phash"
"github.com/liamg/aminal/config"
"github.com/liamg/aminal/gui"
"github.com/liamg/aminal/terminal"
"os"
"runtime"
"strings"
"testing"
"time"
"github.com/liamg/aminal/config"
"github.com/liamg/aminal/gui"
"github.com/liamg/aminal/terminal"
"github.com/carlogit/phash"
)
var termRef *terminal.Terminal
@ -47,10 +45,14 @@ func hash(path string) string {
return imageHash
}
func imagesAreEqual(expected string, actual string) int {
expectedHash := hash(expected)
actualHash := hash(actual)
return phash.GetDistance(expectedHash, actualHash)
}
func compareImages(expected string, actual string) {
template := hash(expected)
screen := hash(actual)
distance := phash.GetDistance(template, screen)
distance := imagesAreEqual(expected, actual)
if distance != 0 {
os.Exit(terminate(fmt.Sprintf("Screenshot \"%s\" doesn't match expected image \"%s\". Distance of hashes difference: %d\n",
actual, expected, distance)))
@ -58,19 +60,48 @@ func compareImages(expected string, actual string) {
}
func send(terminal *terminal.Terminal, cmd string) {
terminal.Write([]byte(cmd))
err := terminal.Write([]byte(cmd))
if err != nil {
panic(err)
}
}
func enter(terminal *terminal.Terminal) {
terminal.Write([]byte("\n"))
err := terminal.Write([]byte("\n"))
if err != nil {
panic(err)
}
}
func validateScreen(img string) {
func validateScreen(img string, waitForChange bool) {
fmt.Printf("taking screenshot: %s and comparing...", img)
guiRef.Screenshot(img)
compareImages(strings.Join([]string{"vttest/", img}, ""), img)
fmt.Printf("compare OK\n")
enter(termRef)
sleep()
if waitForChange {
fmt.Print("Waiting for screen change...")
attempts := 10
for {
sleep()
actualScren := "temp.png"
guiRef.Screenshot(actualScren)
distance := imagesAreEqual(actualScren, img)
if distance != 0 {
break
}
fmt.Printf(" %d", attempts)
attempts--
if attempts <= 0 {
break
}
}
fmt.Print("done\n")
}
}
func TestMain(m *testing.M) {
@ -115,12 +146,12 @@ func TestCursorMovement(t *testing.T) {
os.Exit(terminate(fmt.Sprintf("ActiveBuffer doesn't match vttest template vttest/test-cursor-movement-1")))
}
validateScreen("test-cursor-movement-1.png")
validateScreen("test-cursor-movement-2.png")
validateScreen("test-cursor-movement-3.png")
validateScreen("test-cursor-movement-4.png")
validateScreen("test-cursor-movement-5.png")
validateScreen("test-cursor-movement-6.png")
validateScreen("test-cursor-movement-1.png", true)
validateScreen("test-cursor-movement-2.png", true)
validateScreen("test-cursor-movement-3.png", true)
validateScreen("test-cursor-movement-4.png", true)
validateScreen("test-cursor-movement-5.png", true)
validateScreen("test-cursor-movement-6.png", false)
g.Close()
}
@ -142,21 +173,21 @@ func TestScreenFeatures(t *testing.T) {
send(term, "2\n")
sleep()
validateScreen("test-screen-features-1.png")
validateScreen("test-screen-features-2.png")
validateScreen("test-screen-features-3.png")
validateScreen("test-screen-features-4.png")
validateScreen("test-screen-features-5.png")
validateScreen("test-screen-features-6.png")
validateScreen("test-screen-features-7.png")
validateScreen("test-screen-features-8.png")
validateScreen("test-screen-features-9.png")
validateScreen("test-screen-features-10.png")
validateScreen("test-screen-features-11.png")
validateScreen("test-screen-features-12.png")
validateScreen("test-screen-features-13.png")
validateScreen("test-screen-features-14.png")
validateScreen("test-screen-features-15.png")
validateScreen("test-screen-features-1.png", true)
validateScreen("test-screen-features-2.png", true)
validateScreen("test-screen-features-3.png", true)
validateScreen("test-screen-features-4.png", true)
validateScreen("test-screen-features-5.png", true)
validateScreen("test-screen-features-6.png", true)
validateScreen("test-screen-features-7.png", true)
validateScreen("test-screen-features-8.png", true)
validateScreen("test-screen-features-9.png", true)
validateScreen("test-screen-features-10.png", true)
validateScreen("test-screen-features-11.png", true)
validateScreen("test-screen-features-12.png", true)
validateScreen("test-screen-features-13.png", true)
validateScreen("test-screen-features-14.png", true)
validateScreen("test-screen-features-15.png", false)
g.Close()
}
@ -178,10 +209,9 @@ func TestSixel(t *testing.T) {
send(term, "clear\n")
sleep()
send(term, "cat example.sixel\n")
sleep(4)
sleep(10) // Displaying SIXEL graphics *sometimes* takes long time. Excessive synchronization???
guiRef.Screenshot("test-sixel.png")
validateScreen("test-sixel.png")
validateScreen("test-sixel.png", false)
g.Close()
}