cloudron-e2e-test/test/selfhost-ec2-test.js
Johannes Zellner d6badf8a2b Cleanup DO instances after test runs
We should be doing this the same way as with caas tests
where we are smart enough to only delete those where
tests were successful
2016-09-09 10:04:09 +02:00

284 lines
9.3 KiB
JavaScript

/*
* This tests a flow for cloudron owner creating a selfhosted cloudron on ec2
* Owner creates a cloudron, activates it, installs and app and deletes the cloudron eventually
*
*/
'use strict';
var AppStore = require('../appstore.js'),
assert = require('assert'),
AWS = require('aws-sdk'),
child_process = require('child_process'),
Cloudron = require('../cloudron.js'),
common = require('../common.js'),
mailer = require('../mailer.js'),
semver = require('semver'),
sleep = require('../shell.js').sleep,
request = require('superagent-sync'),
util = require('util');
require('colors');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
const BOX_VERSION = process.env.BOX_VERSION;
const SELFHOST_DOMAIN = 'cloudron.club';
const EC2_TYPE = 't2.small';
const EC2_SIZE = 30;
const EC2_REGION = 'eu-central-1';
const EC2_SSH_KEY = 'id_rsa_e2e_selfhost';
const EC2_SUBNET = 'subnet-801402e9';
const EC2_SECURITY_GROUP = 'sg-b9a473d1';
const BACKUP_KEY = 'somesecret';
const BACKUP_BUCKET = 'selfhost-test';
const AWS_ACCESS_KEY = process.env.AWS_STAGING_ACCESS_KEY;
const AWS_ACCESS_SECRET = process.env.AWS_STAGING_SECRET_KEY;
function machine(args, options) {
// https://github.com/nodejs/node-v0.x-archive/issues/9265
options = options || { };
args = util.isArray(args) ? args : args.match(/[^\s"]+|"([^"]+)"/g);
args = args.map(function (e) { return e[0] === '"' ? e.slice(1, -1) : e; }); // remove the quotes
console.log('cloudron machine ' + args.join(' '));
try {
var cp = child_process.spawnSync('cloudron', ['machine'].concat(args), { stdio: [ options.stdin || 'pipe', options.stdout || 'pipe', 'pipe' ], encoding: options.encoding || 'utf8' });
return cp;
} catch (e) {
console.error(e);
throw e;
}
}
describe('Selfhost EC2 Cloudron creation', function () {
this.timeout(0);
var appStore = new AppStore('https://api.staging.cloudron.io');
var ec2 = new AWS.EC2({ accessKeyId: AWS_ACCESS_KEY, secretAccessKey: AWS_ACCESS_SECRET, region: EC2_REGION });
var owner = common.getOwner();
var cloudron, appId, backupInfo, instanceId, restoreInstanceId, migrateInstanceId;
var fromVersion, toVersion, nextVersion;
it('can query versions', function () {
var res = request.get('https://s3.amazonaws.com/staging-cloudron-releases/versions.json').end();
common.verifyResponse2xx(res);
var boxVersions = Object.keys(common.stripUnreachable(res.body)).sort(semver.rcompare);
fromVersion = boxVersions[2]; // we released a new version in before.js
toVersion = boxVersions[1];
assert.strictEqual(toVersion, BOX_VERSION);
nextVersion = boxVersions[0];
console.log('Will test update from %s to %s and then %s', fromVersion.yellow, toVersion.yellow, nextVersion.yellow);
});
it('can create a cloudron', function () {
var params = [
'--fqdn ' + SELFHOST_DOMAIN,
'--type ' + EC2_TYPE,
'--disk-size ' + EC2_SIZE,
'--region ' + EC2_REGION,
'--ssh-key ' + EC2_SSH_KEY,
'--access-key-id ' + AWS_ACCESS_KEY,
'--secret-access-key ' + AWS_ACCESS_SECRET,
'--subnet ' + EC2_SUBNET,
'--security-group ' + EC2_SECURITY_GROUP,
'--backup-key ' + BACKUP_KEY,
'--backup-bucket ' + BACKUP_BUCKET,
'--release ' + toVersion
];
var out = machine('create ec2 ' + params.join(' '));
console.log(out.stdout, out.stderr);
if (out.stdout.indexOf('You can now setup your Cloudron at') === -1) {
assert(false, 'Creation failed');
}
// Wohooo strings!
instanceId = out.stdout.split('\n').filter(function (l) { return l.indexOf(' ID: ') !== -1; })[0].split(':')[1].trim();
console.log('New instance created with ID', instanceId);
cloudron = new Cloudron({
domain: SELFHOST_DOMAIN,
setupToken: null,
version: toVersion,
ip: null
});
});
it('can activate the box', function () {
cloudron.activate(owner);
});
it('can login to the box', function () {
var token = cloudron.getOauthToken(owner);
cloudron.setCredentials(owner.password, token);
});
it('can take a breather', function () {
// ec2 can be really slow to come up. the addon containers take their own sweet time (they are "async" with the box startup)
// we end up sending email even before the mail container is ready
sleep(120);
});
it('can enable email', function () {
cloudron.setEmailEnabled(true);
});
it('send mail to cloudron user', function (done) {
mailer.sendMailToCloudronUser(owner.username + '@' + SELFHOST_DOMAIN, done);
});
it('did receive mail', function (done) {
cloudron.checkMail(owner, done);
});
var location = 'test' + (Math.random() * 10000).toFixed();
it('can install app', function () {
var manifest = appStore.getManifest(common.TESTAPP_ID, common.TESTAPP_VERSION);
appId = cloudron.installApp(location, manifest);
});
it('can populate the addons', function () {
cloudron.populateAddons(cloudron.appFqdn(location));
});
it('can check the addons', function () {
cloudron.checkAddons(cloudron.appFqdn(location), owner);
});
it('can update the box', function () {
cloudron.checkForUpdates();
var params = [
SELFHOST_DOMAIN,
'--yes',
'--ssh-key ' + EC2_SSH_KEY,
'--username ' + owner.username,
'--password ' + owner.password
];
var out = machine('update ' + params.join(' '));
console.log(out.stdout, out.stderr);
if (out.stdout.indexOf('You can now use your Cloudron at') === -1) {
assert(false, 'Update failed');
}
});
it('wait for app to be ready', function () {
cloudron.waitForApp(appId);
});
it('can configure app', function () {
location = location + 'x';
cloudron.configureApp(appId, location);
});
it('can check the addons', function () {
cloudron.checkAddons(cloudron.appFqdn(location), owner);
});
it('can reboot the cloudron', function () {
cloudron.reboot();
});
it('runs the app', function () {
cloudron.waitForApp(appId);
});
it('can check the addons', function () {
cloudron.checkAddons(cloudron.appFqdn(location), owner);
});
it('can check mail', function (done) {
cloudron.checkMail(owner, done);
});
it('can backup the box', function () {
backupInfo = cloudron.backup();
assert.strictEqual(backupInfo.dependsOn.length, 1);
});
it('can restore the box', function () {
var params = [
'--fqdn ' + SELFHOST_DOMAIN,
'--type ' + EC2_TYPE,
'--disk-size ' + EC2_SIZE,
'--region ' + EC2_REGION,
'--ssh-key ' + EC2_SSH_KEY,
'--access-key-id ' + AWS_ACCESS_KEY,
'--secret-access-key ' + AWS_ACCESS_SECRET,
'--subnet ' + EC2_SUBNET,
'--security-group ' + EC2_SECURITY_GROUP,
'--backup-key ' + BACKUP_KEY,
'--backup-bucket ' + BACKUP_BUCKET,
'--backup ' + backupInfo.id,
];
var out = machine('restore ec2 ' + params.join(' '));
console.log(out.stdout, out.stderr);
if (out.stdout.indexOf('You can now use your Cloudron at') === -1) {
assert(false, 'Restore failed');
}
restoreInstanceId = out.stdout.split('\n').filter(function (l) { return l.indexOf(' ID: ') !== -1; })[0].split(':')[1].trim();
console.log('New instance created with ID', restoreInstanceId);
});
it('runs the app', function () {
cloudron.waitForApp(appId);
});
// Only works so far with upgrades, as the app needs to be restarted for the test to suceed
xit('can check the addons', function () {
cloudron.checkAddons(cloudron.appFqdn(location), owner);
});
it('can migrate cloudron', function () {
var params = [
'--fqdn ' + SELFHOST_DOMAIN,
'--ssh-key ' + EC2_SSH_KEY,
'--access-key-id ' + AWS_ACCESS_KEY,
'--secret-access-key ' + AWS_ACCESS_SECRET,
];
var out = machine('migrate ec2 ' + params.join(' '));
console.log(out.stdout, out.stderr);
if (out.stdout.indexOf('You can now use your Cloudron at') === -1) {
assert(false, 'Migrate failed');
}
migrateInstanceId = out.stdout.split('\n').filter(function (l) { return l.indexOf(' ID: ') !== -1; })[0].split(':')[1].trim();
console.log('New instance created with ID', restoreInstanceId);
});
it('runs the app', function () {
cloudron.waitForApp(appId);
});
it('can uninstall app', function () {
cloudron.uninstallApp(appId);
});
it('can delete the cloudron', function (done) {
console.log('Cleanup EC2 instances', instanceId, restoreInstanceId, migrateInstanceId);
var params = {
InstanceIds: [ instanceId, restoreInstanceId, migrateInstanceId ]
};
ec2.terminateInstances(params, function (error) {
if (error) console.log(error);
done();
});
});
});