diff --git a/.gitignore b/.gitignore index d49592be1d9..e828f88e877 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ **/node_modules/** npm-debug.log -coverage/ \ No newline at end of file +coverage/ + +test/encrypted/express-demo.json \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index dce4356f0c0..330843e6675 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,10 +44,16 @@ before_install: printf '\ny\n\ny\ny\n' | ./google-cloud-sdk/install.sh && cd $TRAVIS_BUILD_DIR; fi +- gcloud components update -q +- gcloud components update preview -q - openssl aes-256-cbc -K $encrypted_95e832a36b06_key -iv $encrypted_95e832a36b06_iv -in nodejs-docs-samples.json.enc -out nodejs-docs-samples.json -d - if [ -a nodejs-docs-samples.json ]; then gcloud auth activate-service-account --key-file nodejs-docs-samples.json; fi +- openssl aes-256-cbc -K $encrypted_4e84c7c7ab67_key -iv $encrypted_4e84c7c7ab67_iv -in test/encrypted/express-demo.json.enc -out test/encrypted/express-demo.json -d +- if [ -a test/encrypted/express-demo.json ]; then + gcloud auth activate-service-account --key-file test/encrypted/express-demo.json; + fi install: #Add app specific setup here diff --git a/package.json b/package.json index ddf938af216..1ff43530246 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "googleapis": "~2.1.3" }, "devDependencies": { + "async": "^1.5.0", "coveralls": "^2.11.4", "istanbul": "^0.4.0", "jshint": "~2.8.0", diff --git a/test/appengine/test.js b/test/appengine/test.js index 74c3030e18d..7f6791f1cae 100644 --- a/test/appengine/test.js +++ b/test/appengine/test.js @@ -15,6 +15,7 @@ var spawn = require('child_process').spawn; var request = require('request'); +var async = require('async'); var cwd = process.cwd(); @@ -25,6 +26,7 @@ function getPath(dir) { var sampleTests = [ { dir: 'express', + projectId: 'express-demo', cmd: 'node', arg1: './bin/www', msg: 'Hello World! Express.js on Google App Engine.' @@ -93,6 +95,36 @@ if (process.env.TRAVIS_NODE_VERSION !== 'stable') { }); } +function end(timeoutId, intervalId, proc) { + clearTimeout(timeoutId); + clearInterval(intervalId); + proc.kill('SIGKILL'); +} + +function testRequest(url, sample, cb) { + request(url, function (err, res, body) { + if (err) { + cb(err, false); + } else { + if (body && body.indexOf(sample.msg) !== -1 && + (res.statusCode === 200 || res.statusCode === sample.code)) { + cb(null, true); + } else { + cb(null, false); + } + } + }); +} + +function shouldHide(data) { + if (data && typeof data === 'function' && (data.indexOf('.../') !== -1 || + data.indexOf('...-') !== -1 || + data.indexOf('...\\') !== -1 || + data.indexOf('...|') !== -1)) { + return true; + } +} + describe('appengine/', function () { sampleTests.forEach(function (sample) { it(sample.dir + ': dependencies should install', function (done) { @@ -166,24 +198,110 @@ describe('appengine/', function () { } }); - timeoutId = setTimeout(end, 5000); - intervalId = setInterval(testRequest, 1000); + timeoutId = setTimeout(function () { + end(timeoutId, intervalId, proc); + }, 10000); + + // Give the server time to start up + setTimeout(function () { + intervalId = setInterval(function () { + var url = 'http://localhost:8080'; + testRequest(url, sample, function (err, _success) { + if (err) { + console.log(err); + } else { + success = _success; + } + end(timeoutId, intervalId, proc); + }); + }, 1000); + }, 2000); + }); + }); + + if (!process.env.TRAVIS) { + return; + } - function end() { - clearTimeout(timeoutId); - clearInterval(intervalId); - proc.kill('SIGKILL'); - } + it('should deploy all samples', function (done) { + this.timeout(10 * 60 * 1000); // 10 minutes + async.parallel(sampleTests.map(function (sample) { + if (sample.projectId) { + return function (cb) { + var calledDone = false; + var proc = spawn('gcloud', [ + 'preview', + 'app', + 'deploy', + 'app.yaml', + '-q', + '--project', + sample.projectId, + '--promote', + '--version', + 'demo' + ], { + cwd: getPath(sample.dir) + }); - function testRequest() { - request('http://localhost:8080', function (err, res, body) { - if (body && body.indexOf(sample.msg) !== -1 && - (res.statusCode === 200 || res.statusCode === sample.code)) { - success = true; - end(); + function finish(err) { + if (!calledDone) { + calledDone = true; + cb(err); + } } - }); + + proc.stderr.on('data', function (data) { + if (shouldHide(data)) { + return; + } + console.log(sample.projectId + ' stderr: ' + data); + }); + proc.stdout.on('data', function (data) { + if (shouldHide(data)) { + return; + } + console.log(sample.projectId + ' stdout: ' + data); + }); + proc.on('error', finish); + proc.on('exit', function (code) { + if (code !== 0) { + finish(new Error(sample.dir + ': failed to deploy!')); + } else { + var url = 'http://' + sample.projectId + '.appspot.com'; + var demoUrl = 'http://demo.' + sample.projectId + '.appspot.com'; + async.waterfall([ + function (cb) { + setTimeout(cb, 10000); + }, + function (cb) { + // Test "default" module + testRequest(url, sample, cb); + }, + function (result, cb) { + if (!result) { + cb(new Error(sample.dir + ': failed verification!')); + } else { + cb(); + } + }, + function (cb) { + // Test versioned url of "default" module + testRequest(demoUrl, sample, cb); + }, + function (result, cb) { + if (!result) { + cb(new Error(sample.dir + ': failed verification!')); + } else { + cb(); + } + } + ], finish); + } + }); + }; } - }); + return function (cb) { cb(); }; + }), done); }); }); diff --git a/test/encrypted/express-demo.json.enc b/test/encrypted/express-demo.json.enc new file mode 100644 index 00000000000..c8a52142e6b Binary files /dev/null and b/test/encrypted/express-demo.json.enc differ