www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit be966955865b24b48c46ce6ae6b7695742d2d29a
parent 94dad8029d94833f043412dfdb0382bf76fbcf14
Author: Martin von Gagern <Martin.vGagern@gmx.net>
Date:   Mon, 28 Nov 2016 00:57:53 +0100

Improved Docker for Mac support (#568)

* Exit cleanly after invalid screenshot test name

This avoids waiting forever.

* Auto-detect host IP in Docker for Mac environment

This checks all available network addresses to find one which the Selenium
container can connect to.  That way we don't have to analyze network
settings or similar to figure out the main public IP address of the machine.

* Make server less sensitive to current working directory

That way it becomes possible to run screenshotter.js from within the
Screenshotter directory, and still server all files as intended.

Diffstat:
Mdockers/Screenshotter/screenshotter.js | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Mserver.js | 17+++++++++--------
2 files changed, 98 insertions(+), 29 deletions(-)

diff --git a/dockers/Screenshotter/screenshotter.js b/dockers/Screenshotter/screenshotter.js @@ -6,6 +6,7 @@ var fs = require("fs"); var http = require("http"); var jspngopt = require("jspngopt"); var net = require("net"); +var os = require("os"); var pako = require("pako"); var path = require("path"); var selenium = require("selenium-webdriver"); @@ -130,12 +131,21 @@ function guessDockerIPs() { process.exit(2); } katexIP = katexIP || config[1]; + return; } catch (e) { - var ip = cmd("docker", "inspect", - "-f", "{{.NetworkSettings.Gateway}}", opts.container); - seleniumIP = seleniumIP || ip; - katexIP = katexIP || ip; + // Apparently no boot2docker, continue + } + if (!process.env.DOCKER_HOST && os.type() === "Darwin") { + // Docker for Mac + seleniumIP = seleniumIP || "localhost"; + katexIP = katexIP || "*any*"; // see findHostIP + return; } + // Native Docker on Linux or remote Docker daemon or similar + var gatewayIP = cmd("docker", "inspect", + "-f", "{{.NetworkSettings.Gateway}}", opts.container); + seleniumIP = seleniumIP || gatewayIP; + katexIP = katexIP || gatewayIP; } if (!seleniumURL && opts.container) { @@ -192,13 +202,6 @@ function startServer() { // Wait for container to become ready function tryConnect() { - if (!katexIP) { - katexIP = "localhost"; - } - if (!katexURL) { - katexURL = "http://" + katexIP + ":" + katexPort + "/"; - console.log("KaTeX URL is " + katexURL); - } if (!seleniumIP) { process.nextTick(buildDriver); return; @@ -253,7 +256,7 @@ function setSize(reqW, reqH) { var actualW = img.width; var actualH = img.height; if (actualW === targetW && actualH === targetH) { - process.nextTick(takeScreenshots); + findHostIP(); return; } if (++attempts > 5) { @@ -273,6 +276,64 @@ function imageDimensions(img) { } ////////////////////////////////////////////////////////////////////// +// Work out how to connect to host KaTeX server + +function findHostIP() { + if (!katexIP) { + katexIP = "localhost"; + } + if (katexIP !== "*any*" || katexURL) { + if (!katexURL) { + katexURL = "http://" + katexIP + ":" + katexPort + "/"; + console.log("KaTeX URL is " + katexURL); + } + process.nextTick(takeScreenshots); + return; + } + + // Now we need to find an IP the container can connect to. + // First, install a server component to get notified of successful connects + app.get("/ss-connect.js", function(req, res, next) { + if (!katexURL) { + katexIP = req.query.ip; + katexURL = "http://" + katexIP + ":" + katexPort + "/"; + console.log("KaTeX URL is " + katexURL); + process.nextTick(takeScreenshots); + } + res.setHeader("Content-Type", "text/javascript"); + res.send("//OK"); + }); + + // Next, enumerate all network addresses + var ips = []; + var devs = os.networkInterfaces(); + for (var dev in devs) { + if (devs.hasOwnProperty(dev)) { + var addrs = devs[dev]; + for (var i = 0; i < addrs.length; ++i) { + var addr = addrs[i].address; + if (/:/.test(addr)) { + addr = "[" + addr + "]"; + } + ips.push(addr); + } + } + } + console.log("Looking for host IP among " + ips.join(", ")); + + // Load a data: URI document which attempts to contact each of these IPs + var html = "<!doctype html>\n<html><body>\n"; + html += ips.map(function(ip) { + return '<script src="http://' + ip + ':' + katexPort + + '/ss-connect.js?ip=' + encodeURIComponent(ip) + + '" defer></script>'; + }).join("\n"); + html += "\n</body></html>"; + html = "data:text/html," + encodeURIComponent(html); + driver.get(html); +} + +////////////////////////////////////////////////////////////////////// // Take the screenshots var countdown = listOfCases.length; @@ -288,6 +349,11 @@ function takeScreenshot(key) { var itm = data[key]; if (!itm) { console.error("Test case " + key + " not known!"); + listOfFailed.push(key); + if (exitStatus === 0) { + exitStatus = 1; + } + oneDone(); return; } @@ -303,15 +369,7 @@ function takeScreenshot(key) { if (opts.wait) { browserSideWait(1000 * opts.wait); } - driver.takeScreenshot().then(haveScreenshot).then(function() { - if (--countdown === 0) { - if (listOfFailed.length) { - console.error("Failed: " + listOfFailed.join(" ")); - } - // devServer.close(cb) will take too long. - process.exit(exitStatus); - } - }, check); + driver.takeScreenshot().then(haveScreenshot).then(oneDone, check); function haveScreenshot(img) { img = imageDimensions(img); @@ -360,6 +418,16 @@ function takeScreenshot(key) { }); } } + + function oneDone() { + if (--countdown === 0) { + if (listOfFailed.length) { + console.error("Failed: " + listOfFailed.join(" ")); + } + // devServer.close(cb) will take too long. + process.exit(exitStatus); + } + } } // Wait using a timeout call in the browser, to ensure that the wait diff --git a/server.js b/server.js @@ -17,11 +17,11 @@ var serveBrowserified = function(file, standaloneName) { return function(req, res, next) { var files; if (Array.isArray(file)) { - files = file; + files = file.map(function(f) { return path.join(__dirname, f); }); } else if (file.indexOf("*") !== -1) { - files = glob.sync(file); + files = glob.sync(file, {cwd: __dirname}); } else { - files = [file]; + files = [path.join(__dirname, file)]; } var options = {}; @@ -41,7 +41,7 @@ var serveBrowserified = function(file, standaloneName) { }; }; -app.get("/katex.js", serveBrowserified("./katex", "katex")); +app.get("/katex.js", serveBrowserified("katex", "katex")); app.use("/test/jasmine", express["static"]( path.dirname( @@ -49,20 +49,21 @@ app.use("/test/jasmine", ) ) ); -app.get("/test/katex-spec.js", serveBrowserified("./test/*[Ss]pec.js")); +app.get("/test/katex-spec.js", serveBrowserified("test/*[Ss]pec.js")); app.get("/contrib/auto-render/auto-render.js", - serveBrowserified("./contrib/auto-render/auto-render", + serveBrowserified("contrib/auto-render/auto-render", "renderMathInElement")); app.get("/katex.css", function(req, res, next) { - fs.readFile("static/katex.less", {encoding: "utf8"}, function(err, data) { + var lessfile = path.join(__dirname, "static", "katex.less"); + fs.readFile(lessfile, {encoding: "utf8"}, function(err, data) { if (err) { next(err); return; } less.render(data, { - paths: ["./static"], + paths: [path.join(__dirname, "static")], filename: "katex.less", }, function(err, output) { if (err) {