mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
cmd/gogio: rip out cgo deps for x11
Instead rely on more tiny standalone tools. In this case, scrot lets us take png screenshots, and works well. On the plus side, we remove some large X Go deps, and we don't need nearly as much code. While at it, skip if any of the tools are missing, and actually defer the cleanup funcs so that they run when we fail the test early. Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
This commit is contained in:
@@ -4,10 +4,6 @@ go 1.13
|
||||
|
||||
require (
|
||||
gioui.org v0.0.0-20191030194120-b53c2a7c9d56
|
||||
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 // indirect
|
||||
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 // indirect
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802
|
||||
github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046
|
||||
github.com/chromedp/cdproto v0.0.0-20191009033829-c22f49c9ff0a
|
||||
github.com/chromedp/chromedp v0.5.1
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
gioui.org v0.0.0-20191030194120-b53c2a7c9d56 h1:ZC5qDUrd0+64qlceTlMC1DM3bjEqAMohfP+3aE3U5OE=
|
||||
gioui.org v0.0.0-20191030194120-b53c2a7c9d56/go.mod h1:KqFFi2Dq5gYA3FJ0sDOt8OBXoMsuxMtE8v2f0JExXAY=
|
||||
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 h1:1qlsVAQJXZHsaM8b6OLVo6muQUQd4CwkH/D3fnnbHXA=
|
||||
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
|
||||
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 h1:lTG4HQym5oPKjL7nGs+csTgiDna685ZXjxijkne828g=
|
||||
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046 h1:O/r2Sj+8QcMF7V5IcmiE2sMFV2q3J47BEirxbXJAdzA=
|
||||
github.com/BurntSushi/xgbutil v0.0.0-20190907113008-ad855c713046/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k=
|
||||
github.com/chromedp/cdproto v0.0.0-20191009033829-c22f49c9ff0a h1:AuIGvB6IuWpMEdfKQ+t77D6dzLpNftzxAsktehYyWn8=
|
||||
github.com/chromedp/cdproto v0.0.0-20191009033829-c22f49c9ff0a/go.mod h1:PfAWWKJqjlGFYJEidUM6aVIWPr0EpobeyVWEEmplX7g=
|
||||
github.com/chromedp/chromedp v0.5.1 h1:PAqhoCWCHzRphYnmmxLSiYk7EEwDplCm4woTCCaV2cQ=
|
||||
|
||||
@@ -39,11 +39,15 @@ type TestDriver interface {
|
||||
func runEndToEndTest(t *testing.T, driver TestDriver) {
|
||||
width, height := 800, 600
|
||||
cleanups := driver.Start(t, "testdata/red.go", width, height)
|
||||
for _, cleanup := range cleanups {
|
||||
defer cleanup()
|
||||
}
|
||||
|
||||
// The colors are split in four rectangular sections. Check the corners
|
||||
// of each of the sections. We check the corners left to right, top to
|
||||
// bottom, like when reading left-to-right text.
|
||||
wantColors := func(topLeft, topRight, botLeft, botRight color.RGBA) {
|
||||
t.Helper()
|
||||
img := driver.Screenshot()
|
||||
size := img.Bounds().Size()
|
||||
// We expect to receive a width*height screenshot.
|
||||
@@ -98,14 +102,10 @@ func runEndToEndTest(t *testing.T, driver TestDriver) {
|
||||
driver.Click(1*(width/4), 1*(height/4))
|
||||
driver.Click(3*(width/4), 3*(height/4))
|
||||
wantColors(red, white, black, red)
|
||||
|
||||
// Run the cleanup funcs from last to first, as if they were defers.
|
||||
for i := len(cleanups) - 1; i >= 0; i-- {
|
||||
cleanups[i]()
|
||||
}
|
||||
}
|
||||
|
||||
func wantColor(t *testing.T, img image.Image, x, y int, want color.Color) {
|
||||
t.Helper()
|
||||
r, g, b, _ := want.RGBA()
|
||||
got := img.At(x, y)
|
||||
r_, g_, b_, _ := got.RGBA()
|
||||
|
||||
+22
-34
@@ -11,6 +11,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/png"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
@@ -20,20 +21,12 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/xgb"
|
||||
"github.com/BurntSushi/xgb/xproto"
|
||||
"github.com/BurntSushi/xgbutil"
|
||||
"github.com/BurntSushi/xgbutil/xgraphics"
|
||||
)
|
||||
|
||||
type X11TestDriver struct {
|
||||
t *testing.T
|
||||
|
||||
display string
|
||||
|
||||
// conn holds the connection to X.
|
||||
conn *xgbutil.XUtil
|
||||
}
|
||||
|
||||
func (d *X11TestDriver) Start(t_ *testing.T, path string, width, height int) (cleanups []func()) {
|
||||
@@ -57,8 +50,15 @@ func (d *X11TestDriver) Start(t_ *testing.T, path string, width, height int) (cl
|
||||
xflags = append(xflags, "-screen", fmt.Sprintf("%dx%d", width, height))
|
||||
}
|
||||
xflags = append(xflags, d.display)
|
||||
if _, err := exec.LookPath(xprog); err != nil {
|
||||
d.t.Skipf("%s needed to run with -headless=%t", xprog, *headless)
|
||||
|
||||
for _, prog := range []string{
|
||||
xprog, // to run the X server
|
||||
"scrot", // to take screenshots
|
||||
"xdotool", // to send input
|
||||
} {
|
||||
if _, err := exec.LookPath(prog); err != nil {
|
||||
d.t.Skipf("%s needed to run", prog)
|
||||
}
|
||||
}
|
||||
|
||||
// First, build the app.
|
||||
@@ -99,9 +99,8 @@ func (d *X11TestDriver) Start(t_ *testing.T, path string, width, height int) (cl
|
||||
// Wait for up to 1s (100 * 10ms) for the X server to be ready.
|
||||
for i := 0; ; i++ {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
// This socket path isn't terribly portable, but the xgb
|
||||
// library we use does the same, and we only really care
|
||||
// about Linux here.
|
||||
// This socket path isn't terribly portable, but it's
|
||||
// okay for now.
|
||||
socket := fmt.Sprintf("/tmp/.X11-unix/X%s", d.display[1:])
|
||||
if _, err := os.Stat(socket); err == nil {
|
||||
break
|
||||
@@ -127,7 +126,7 @@ func (d *X11TestDriver) Start(t_ *testing.T, path string, width, height int) (cl
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cmd := exec.CommandContext(ctx, bin)
|
||||
out := &bytes.Buffer{}
|
||||
cmd.Env = append(os.Environ(), "DISPLAY="+d.display)
|
||||
cmd.Env = []string{"DISPLAY=" + d.display}
|
||||
cmd.Stdout = out
|
||||
cmd.Stderr = out
|
||||
if err := cmd.Start(); err != nil {
|
||||
@@ -145,24 +144,6 @@ func (d *X11TestDriver) Start(t_ *testing.T, path string, width, height int) (cl
|
||||
}()
|
||||
}
|
||||
|
||||
// Finally, connect to the X server.
|
||||
xgb.Logger.SetOutput(testLogWriter{d.t})
|
||||
xgbutil.Logger.SetOutput(testLogWriter{d.t})
|
||||
conn, err := xgbutil.NewConnDisplay(d.display)
|
||||
if err != nil {
|
||||
d.t.Fatal(err)
|
||||
}
|
||||
d.conn = conn
|
||||
cleanups = append(cleanups, func() {
|
||||
conn.Conn().Close()
|
||||
// TODO(mvdan): Figure out a way to remove this sleep
|
||||
// without introducing a panic. The xgb code will
|
||||
// encounter a panic if the Xorg server exits before xgb
|
||||
// has shut down fully.
|
||||
// See: https://github.com/BurntSushi/xgb/pull/44
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
})
|
||||
|
||||
// Wait for the gio app to render.
|
||||
// TODO(mvdan): synchronize with the app instead
|
||||
time.Sleep(400 * time.Millisecond)
|
||||
@@ -171,7 +152,14 @@ func (d *X11TestDriver) Start(t_ *testing.T, path string, width, height int) (cl
|
||||
}
|
||||
|
||||
func (d *X11TestDriver) Screenshot() image.Image {
|
||||
img, err := xgraphics.NewDrawable(d.conn, xproto.Drawable(d.conn.RootWin()))
|
||||
cmd := exec.Command("scrot", "--silent", "--overwrite", "/dev/stdout")
|
||||
cmd.Env = []string{"DISPLAY=" + d.display}
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
d.t.Errorf("%s", out)
|
||||
d.t.Fatal(err)
|
||||
}
|
||||
img, err := png.Decode(bytes.NewReader(out))
|
||||
if err != nil {
|
||||
d.t.Fatal(err)
|
||||
}
|
||||
@@ -184,7 +172,7 @@ func (d *X11TestDriver) xdotool(args ...interface{}) {
|
||||
strs[i] = fmt.Sprint(arg)
|
||||
}
|
||||
cmd := exec.Command("xdotool", strs...)
|
||||
cmd.Env = append(os.Environ(), "DISPLAY="+d.display)
|
||||
cmd.Env = []string{"DISPLAY=" + d.display}
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
d.t.Errorf("%s", out)
|
||||
d.t.Fatal(err)
|
||||
|
||||
Reference in New Issue
Block a user