appium-adb-test
Version:
Android Debug Bridge interface
256 lines (211 loc) • 28.3 kB
JavaScript
;
var _regeneratorRuntime = require('babel-runtime/regenerator')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
var _interopRequireWildcard = require('babel-runtime/helpers/interop-require-wildcard')['default'];
var _this = this;
var _chai = require('chai');
var _chai2 = _interopRequireDefault(_chai);
var _chaiAsPromised = require('chai-as-promised');
var _chaiAsPromised2 = _interopRequireDefault(_chaiAsPromised);
var _ = require('../..');
var _2 = _interopRequireDefault(_);
var _libHelpersJs = require('../../lib/helpers.js');
var helpers = _interopRequireWildcard(_libHelpersJs);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _teen_process = require('teen_process');
var teen_process = _interopRequireWildcard(_teen_process);
var _appiumSupport = require('appium-support');
var appiumSupport = _interopRequireWildcard(_appiumSupport);
var _appiumTestSupport = require('appium-test-support');
_chai2['default'].use(_chaiAsPromised2['default']);
var selendroidTestApp = _path2['default'].resolve(helpers.rootDir, 'test', 'fixtures', 'selendroid-test-app.apk'),
helperJarPath = _path2['default'].resolve(helpers.rootDir, 'jars'),
keystorePath = _path2['default'].resolve(helpers.rootDir, 'test', 'fixtures', 'appiumtest.keystore'),
keyAlias = 'appiumtest',
password = 'android',
selendroidTestAppPackage = 'io.selendroid.testapp',
java_dummy_path = 'java_dummy_path',
java_home = 'java_home',
tempDir = appiumSupport.tempDir,
fs = appiumSupport.fs;
describe('signing', function () {
var adb = new _2['default']();
adb.keystorePath = keystorePath;
adb.keyAlias = keyAlias;
adb.keystorePassword = password;
adb.keyPassword = password;
describe('signWithDefaultCert', (0, _appiumTestSupport.withMocks)({ teen_process: teen_process, helpers: helpers }, function (mocks) {
it('should call exec with correct args', function callee$2$0() {
var signPath;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
signPath = _path2['default'].resolve(helperJarPath, 'sign.jar');
mocks.helpers.expects("getJavaForOs").returns(java_dummy_path);
mocks.teen_process.expects("exec").once().withExactArgs(java_dummy_path, ['-jar', signPath, selendroidTestApp, '--override']).returns("");
context$3$0.next = 5;
return _regeneratorRuntime.awrap(adb.signWithDefaultCert(selendroidTestApp));
case 5:
mocks.teen_process.verify();
case 6:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should throw error for invalid file path', function callee$2$0() {
var dummyPath;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
dummyPath = "dummyPath";
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.signWithDefaultCert(dummyPath).should.eventually.be.rejected);
case 3:
mocks.teen_process.verify();
mocks.helpers.verify();
case 5:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('signWithCustomCert', (0, _appiumTestSupport.withMocks)({ teen_process: teen_process, helpers: helpers }, function (mocks) {
it('should call exec with correct args', function callee$2$0() {
var jarsigner;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
jarsigner = _path2['default'].resolve(java_home, 'bin', 'jarsigner');
if (appiumSupport.system.isWindows()) {
jarsigner = jarsigner + '.exe';
}
adb.useKeystore = true;
mocks.helpers.expects("getJavaHome").returns(java_home);
mocks.helpers.expects("getJavaForOs").returns(java_dummy_path);
mocks.teen_process.expects("exec").withExactArgs(java_dummy_path, ['-jar', _path2['default'].resolve(helperJarPath, 'unsign.jar'), selendroidTestApp]).returns("");
mocks.teen_process.expects("exec").withExactArgs(jarsigner, ['-sigalg', 'MD5withRSA', '-digestalg', 'SHA1', '-keystore', keystorePath, '-storepass', password, '-keypass', password, selendroidTestApp, keyAlias]).returns("");
context$3$0.next = 9;
return _regeneratorRuntime.awrap(adb.signWithCustomCert(selendroidTestApp));
case 9:
mocks.teen_process.verify();
mocks.helpers.verify();
case 11:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('getKeystoreMd5', (0, _appiumTestSupport.withMocks)({ teen_process: teen_process }, function (mocks) {
it('should call exec with correct args', function callee$2$0() {
var h, keytool, md5Str, md5;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
h = "a-fA-F0-9";
keytool = _path2['default'].resolve(java_home, 'bin', 'keytool');
md5Str = ['.*MD5.*((?:[', h, ']{2}:){15}[', h, ']{2})'].join('');
md5 = new RegExp(md5Str, 'mi');
adb.useKeystore = true;
mocks.teen_process.expects("exec").once().withExactArgs(keytool, ['-v', '-list', '-alias', keyAlias, '-keystore', keystorePath, '-storepass', password]).returns("");
context$3$0.next = 8;
return _regeneratorRuntime.awrap(adb.getKeystoreMd5(keytool, md5));
case 8:
mocks.teen_process.verify();
case 9:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
// Skipping as unable to mock mkdirp, this case is covered in e2e tests for now.
// TODO: find ways to mock mkdirp
describe.skip('zipAlignApk', (0, _appiumTestSupport.withMocks)({ teen_process: teen_process, adb: adb, appiumSupport: appiumSupport, fs: fs, tempDir: tempDir }, function (mocks) {
it('should call exec with correct args', function callee$2$0() {
var alignedApk;
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
alignedApk = "dummy_path";
mocks.tempDir.expects('path').once().withExactArgs({ prefix: 'appium', suffix: '.tmp' }).returns(alignedApk);
mocks.adb.expects('initZipAlign').once().withExactArgs().returns("");
mocks.appiumSupport.expects('mkdirp').once().withExactArgs(_path2['default'].dirname(alignedApk)).returns("");
mocks.teen_process.expects("exec").once().withExactArgs(adb.binaries.zipalign, ['-f', '4', selendroidTestApp, alignedApk]);
mocks.fs.expects("mv").once().withExactArgs(alignedApk, selendroidTestApp, { mkdirp: true }).returns("");
context$3$0.next = 8;
return _regeneratorRuntime.awrap(adb.zipAlignApk(selendroidTestApp));
case 8:
mocks.adb.verify();
mocks.appiumSupport.verify();
mocks.teen_process.verify();
mocks.tempDir.verify();
mocks.fs.verify();
case 13:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
describe('checkApkCert', (0, _appiumTestSupport.withMocks)({ teen_process: teen_process, helpers: helpers, adb: adb }, function (mocks) {
it('should return false for apk not present', function callee$2$0() {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
mocks.helpers.expects("getJavaForOs").returns(java_dummy_path);
context$3$0.next = 3;
return _regeneratorRuntime.awrap(adb.checkApkCert('dummyPath', 'dummyPackage'));
case 3:
context$3$0.sent.should.be['false'];
mocks.helpers.verify();
case 5:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should call exec and zipAlign when not using keystore', function callee$2$0() {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
mocks.helpers.expects("getJavaForOs").returns(java_dummy_path);
mocks.teen_process.expects("exec").once().withExactArgs(java_dummy_path, ['-jar', _path2['default'].resolve(helperJarPath, 'verify.jar'), selendroidTestApp]).returns("");
mocks.adb.expects('zipAlignApk').once().withExactArgs(selendroidTestApp).returns("");
adb.useKeystore = false;
context$3$0.next = 6;
return _regeneratorRuntime.awrap(adb.checkApkCert(selendroidTestApp, selendroidTestAppPackage));
case 6:
mocks.adb.verify();
mocks.teen_process.verify();
mocks.helpers.verify();
case 9:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
it('should call checkCustomApkCert when using keystore', function callee$2$0() {
return _regeneratorRuntime.async(function callee$2$0$(context$3$0) {
while (1) switch (context$3$0.prev = context$3$0.next) {
case 0:
mocks.helpers.expects("getJavaForOs").returns(java_dummy_path);
mocks.adb.expects('checkCustomApkCert').once().withExactArgs(selendroidTestApp, selendroidTestAppPackage).returns("");
adb.useKeystore = true;
context$3$0.next = 5;
return _regeneratorRuntime.awrap(adb.checkApkCert(selendroidTestApp, selendroidTestAppPackage));
case 5:
mocks.adb.verify();
mocks.helpers.verify();
case 7:
case 'end':
return context$3$0.stop();
}
}, null, _this);
});
}));
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvdW5pdC9hcGstc2lnbmluZy1zcGVjcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O29CQUFpQixNQUFNOzs7OzhCQUNJLGtCQUFrQjs7OztnQkFDN0IsT0FBTzs7Ozs0QkFDRSxzQkFBc0I7O0lBQW5DLE9BQU87O29CQUNGLE1BQU07Ozs7NEJBQ08sY0FBYzs7SUFBaEMsWUFBWTs7NkJBQ08sZ0JBQWdCOztJQUFuQyxhQUFhOztpQ0FDQyxxQkFBcUI7O0FBRy9DLGtCQUFLLEdBQUcsNkJBQWdCLENBQUM7O0FBRXpCLElBQU0saUJBQWlCLEdBQUcsa0JBQUssT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFDbkMseUJBQXlCLENBQUM7SUFDM0QsYUFBYSxHQUFHLGtCQUFLLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNyRCxZQUFZLEdBQUcsa0JBQUssT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFDbkMscUJBQXFCLENBQUM7SUFDbEQsUUFBUSxHQUFHLFlBQVk7SUFDdkIsUUFBUSxHQUFHLFNBQVM7SUFDcEIsd0JBQXdCLEdBQUcsdUJBQXVCO0lBQ2xELGVBQWUsR0FBRyxpQkFBaUI7SUFDbkMsU0FBUyxHQUFHLFdBQVc7SUFDdkIsT0FBTyxHQUFHLGFBQWEsQ0FBQyxPQUFPO0lBQy9CLEVBQUUsR0FBRyxhQUFhLENBQUMsRUFBRSxDQUFDOztBQUU1QixRQUFRLENBQUMsU0FBUyxFQUFFLFlBQU07QUFDeEIsTUFBSSxHQUFHLEdBQUcsbUJBQVMsQ0FBQztBQUNwQixLQUFHLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztBQUNoQyxLQUFHLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztBQUN4QixLQUFHLENBQUMsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDO0FBQ2hDLEtBQUcsQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDOztB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LCJmaWxlIjoidGVzdC91bml0L2Fway1zaWduaW5nLXNwZWNzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XHJcbmltcG9ydCBjaGFpQXNQcm9taXNlZCBmcm9tICdjaGFpLWFzLXByb21pc2VkJztcclxuaW1wb3J0IEFEQiBmcm9tICcuLi8uLic7XHJcbmltcG9ydCAqIGFzIGhlbHBlcnMgZnJvbSAnLi4vLi4vbGliL2hlbHBlcnMuanMnO1xyXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcclxuaW1wb3J0ICogYXMgdGVlbl9wcm9jZXNzIGZyb20gJ3RlZW5fcHJvY2Vzcyc7XHJcbmltcG9ydCAqIGFzIGFwcGl1bVN1cHBvcnQgZnJvbSAnYXBwaXVtLXN1cHBvcnQnO1xyXG5pbXBvcnQgeyB3aXRoTW9ja3MgfSBmcm9tICdhcHBpdW0tdGVzdC1zdXBwb3J0JztcclxuXHJcblxyXG5jaGFpLnVzZShjaGFpQXNQcm9taXNlZCk7XHJcblxyXG5jb25zdCBzZWxlbmRyb2lkVGVzdEFwcCA9IHBhdGgucmVzb2x2ZShoZWxwZXJzLnJvb3REaXIsICd0ZXN0JywgJ2ZpeHR1cmVzJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NlbGVuZHJvaWQtdGVzdC1hcHAuYXBrJyksXHJcbiAgICAgIGhlbHBlckphclBhdGggPSBwYXRoLnJlc29sdmUoaGVscGVycy5yb290RGlyLCAnamFycycpLFxyXG4gICAgICBrZXlzdG9yZVBhdGggPSBwYXRoLnJlc29sdmUoaGVscGVycy5yb290RGlyLCAndGVzdCcsICdmaXh0dXJlcycsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYXBwaXVtdGVzdC5rZXlzdG9yZScpLFxyXG4gICAgICBrZXlBbGlhcyA9ICdhcHBpdW10ZXN0JyxcclxuICAgICAgcGFzc3dvcmQgPSAnYW5kcm9pZCcsXHJcbiAgICAgIHNlbGVuZHJvaWRUZXN0QXBwUGFja2FnZSA9ICdpby5zZWxlbmRyb2lkLnRlc3RhcHAnLFxyXG4gICAgICBqYXZhX2R1bW15X3BhdGggPSAnamF2YV9kdW1teV9wYXRoJyxcclxuICAgICAgamF2YV9ob21lID0gJ2phdmFfaG9tZScsXHJcbiAgICAgIHRlbXBEaXIgPSBhcHBpdW1TdXBwb3J0LnRlbXBEaXIsXHJcbiAgICAgIGZzID0gYXBwaXVtU3VwcG9ydC5mcztcclxuXHJcbmRlc2NyaWJlKCdzaWduaW5nJywgKCkgPT4ge1xyXG4gIGxldCBhZGIgPSBuZXcgQURCKCk7XHJcbiAgYWRiLmtleXN0b3JlUGF0aCA9IGtleXN0b3JlUGF0aDtcclxuICBhZGIua2V5QWxpYXMgPSBrZXlBbGlhcztcclxuICBhZGIua2V5c3RvcmVQYXNzd29yZCA9IHBhc3N3b3JkO1xyXG4gIGFkYi5rZXlQYXNzd29yZCA9IHBhc3N3b3JkO1xyXG5cclxuICBkZXNjcmliZSgnc2lnbldpdGhEZWZhdWx0Q2VydCcsIHdpdGhNb2Nrcyh7dGVlbl9wcm9jZXNzLCBoZWxwZXJzfSwgKG1vY2tzKSA9PiB7XHJcbiAgICBpdCgnc2hvdWxkIGNhbGwgZXhlYyB3aXRoIGNvcnJlY3QgYXJncycsIGFzeW5jICgpID0+IHtcclxuICAgICAgbGV0IHNpZ25QYXRoID0gcGF0aC5yZXNvbHZlKGhlbHBlckphclBhdGgsICdzaWduLmphcicpO1xyXG4gICAgICBtb2Nrcy5oZWxwZXJzLmV4cGVjdHMoXCJnZXRKYXZhRm9yT3NcIilcclxuICAgICAgICAucmV0dXJucyhqYXZhX2R1bW15X3BhdGgpO1xyXG4gICAgICBtb2Nrcy50ZWVuX3Byb2Nlc3MuZXhwZWN0cyhcImV4ZWNcIilcclxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoamF2YV9kdW1teV9wYXRoLCBbJy1qYXInLCBzaWduUGF0aCwgc2VsZW5kcm9pZFRlc3RBcHAsICctLW92ZXJyaWRlJ10pXHJcbiAgICAgICAgLnJldHVybnMoXCJcIik7XHJcbiAgICAgIChhd2FpdCBhZGIuc2lnbldpdGhEZWZhdWx0Q2VydChzZWxlbmRyb2lkVGVzdEFwcCkpO1xyXG4gICAgICBtb2Nrcy50ZWVuX3Byb2Nlc3MudmVyaWZ5KCk7XHJcbiAgICB9KTtcclxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgZmlsZSBwYXRoJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICBsZXQgZHVtbXlQYXRoID0gXCJkdW1teVBhdGhcIjtcclxuICAgICAgYXdhaXQgYWRiLnNpZ25XaXRoRGVmYXVsdENlcnQoZHVtbXlQYXRoKS5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZDtcclxuICAgICAgbW9ja3MudGVlbl9wcm9jZXNzLnZlcmlmeSgpO1xyXG4gICAgICBtb2Nrcy5oZWxwZXJzLnZlcmlmeSgpO1xyXG4gICAgfSk7XHJcbiAgfSkpO1xyXG4gIGRlc2NyaWJlKCdzaWduV2l0aEN1c3RvbUNlcnQnLCB3aXRoTW9ja3Moe3RlZW5fcHJvY2VzcywgaGVscGVyc30sIChtb2NrcykgPT4ge1xyXG4gICAgaXQoJ3Nob3VsZCBjYWxsIGV4ZWMgd2l0aCBjb3JyZWN0IGFyZ3MnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGxldCBqYXJzaWduZXIgPSBwYXRoLnJlc29sdmUoamF2YV9ob21lLCAnYmluJywgJ2phcnNpZ25lcicpO1xyXG4gICAgICBpZiAoYXBwaXVtU3VwcG9ydC5zeXN0ZW0uaXNXaW5kb3dzKCkpIHtcclxuICAgICAgICBqYXJzaWduZXIgPSBqYXJzaWduZXIgKyAnLmV4ZSc7XHJcbiAgICAgIH1cclxuICAgICAgYWRiLnVzZUtleXN0b3JlID0gdHJ1ZTtcclxuICAgICAgbW9ja3MuaGVscGVycy5leHBlY3RzKFwiZ2V0SmF2YUhvbWVcIilcclxuICAgICAgICAucmV0dXJucyhqYXZhX2hvbWUpO1xyXG4gICAgICBtb2Nrcy5oZWxwZXJzLmV4cGVjdHMoXCJnZXRKYXZhRm9yT3NcIilcclxuICAgICAgICAucmV0dXJucyhqYXZhX2R1bW15X3BhdGgpO1xyXG4gICAgICBtb2Nrcy50ZWVuX3Byb2Nlc3MuZXhwZWN0cyhcImV4ZWNcIilcclxuICAgICAgICAud2l0aEV4YWN0QXJncyhqYXZhX2R1bW15X3BhdGgsIFsnLWphcicsIHBhdGgucmVzb2x2ZShoZWxwZXJKYXJQYXRoLCAndW5zaWduLmphcicpLCBzZWxlbmRyb2lkVGVzdEFwcF0pXHJcbiAgICAgICAgLnJldHVybnMoXCJcIik7XHJcbiAgICAgIG1vY2tzLnRlZW5fcHJvY2Vzcy5leHBlY3RzKFwiZXhlY1wiKVxyXG4gICAgICAgIC53aXRoRXhhY3RBcmdzKGphcnNpZ25lciwgWyctc2lnYWxnJywgJ01ENXdpdGhSU0EnLCAnLWRpZ2VzdGFsZycsICdTSEExJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLWtleXN0b3JlJywga2V5c3RvcmVQYXRoLCAnLXN0b3JlcGFzcycsIHBhc3N3b3JkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcta2V5cGFzcycsIHBhc3N3b3JkLCBzZWxlbmRyb2lkVGVzdEFwcCwga2V5QWxpYXNdKVxyXG4gICAgICAgIC5yZXR1cm5zKFwiXCIpO1xyXG4gICAgICAoYXdhaXQgYWRiLnNpZ25XaXRoQ3VzdG9tQ2VydChzZWxlbmRyb2lkVGVzdEFwcCkpO1xyXG4gICAgICBtb2Nrcy50ZWVuX3Byb2Nlc3MudmVyaWZ5KCk7XHJcbiAgICAgIG1vY2tzLmhlbHBlcnMudmVyaWZ5KCk7XHJcbiAgICB9KTtcclxuICB9KSk7XHJcbiAgZGVzY3JpYmUoJ2dldEtleXN0b3JlTWQ1Jywgd2l0aE1vY2tzKHt0ZWVuX3Byb2Nlc3N9LCAobW9ja3MpID0+IHtcclxuICAgIGl0KCdzaG91bGQgY2FsbCBleGVjIHdpdGggY29ycmVjdCBhcmdzJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICBsZXQgaCA9IFwiYS1mQS1GMC05XCI7XHJcbiAgICAgIGxldCBrZXl0b29sID0gcGF0aC5yZXNvbHZlKGphdmFfaG9tZSwgJ2JpbicsICdrZXl0b29sJyk7XHJcbiAgICAgIGxldCBtZDVTdHIgPSBbJy4qTUQ1LiooKD86WycsIGgsICddezJ9Oil7MTV9WycsIGgsICddezJ9KSddLmpvaW4oJycpO1xyXG4gICAgICBsZXQgbWQ1ID0gbmV3IFJlZ0V4cChtZDVTdHIsICdtaScpO1xyXG4gICAgICBhZGIudXNlS2V5c3RvcmUgPSB0cnVlO1xyXG4gICAgICBtb2Nrcy50ZWVuX3Byb2Nlc3MuZXhwZWN0cyhcImV4ZWNcIilcclxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3Moa2V5dG9vbCwgWyctdicsICctbGlzdCcsICctYWxpYXMnLCBrZXlBbGlhcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcta2V5c3RvcmUnLCBrZXlzdG9yZVBhdGgsICctc3RvcmVwYXNzJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3N3b3JkXSlcclxuICAgICAgICAucmV0dXJucyhcIlwiKTtcclxuICAgICAgKGF3YWl0IGFkYi5nZXRLZXlzdG9yZU1kNShrZXl0b29sLCBtZDUpKTtcclxuICAgICAgbW9ja3MudGVlbl9wcm9jZXNzLnZlcmlmeSgpO1xyXG4gICAgfSk7XHJcbiAgfSkpO1xyXG4gIC8vIFNraXBwaW5nIGFzIHVuYWJsZSB0byBtb2NrIG1rZGlycCwgdGhpcyBjYXNlIGlzIGNvdmVyZWQgaW4gZTJlIHRlc3RzIGZvciBub3cuXHJcbiAgLy8gVE9ETzogZmluZCB3YXlzIHRvIG1vY2sgbWtkaXJwXHJcbiAgZGVzY3JpYmUuc2tpcCgnemlwQWxpZ25BcGsnLCB3aXRoTW9ja3Moe3RlZW5fcHJvY2VzcywgYWRiLCBhcHBpdW1TdXBwb3J0LCBmcywgdGVtcERpcn0sIChtb2NrcykgPT4ge1xyXG4gICAgaXQoJ3Nob3VsZCBjYWxsIGV4ZWMgd2l0aCBjb3JyZWN0IGFyZ3MnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGxldCBhbGlnbmVkQXBrID0gXCJkdW1teV9wYXRoXCI7XHJcbiAgICAgIG1vY2tzLnRlbXBEaXIuZXhwZWN0cygncGF0aCcpXHJcbiAgICAgICAgLm9uY2UoKS53aXRoRXhhY3RBcmdzKHtwcmVmaXg6ICdhcHBpdW0nLCBzdWZmaXg6ICcudG1wJ30pXHJcbiAgICAgICAgLnJldHVybnMoYWxpZ25lZEFwayk7XHJcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCdpbml0WmlwQWxpZ24nKVxyXG4gICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncygpXHJcbiAgICAgICAgLnJldHVybnMoXCJcIik7XHJcbiAgICAgIG1vY2tzLmFwcGl1bVN1cHBvcnQuZXhwZWN0cygnbWtkaXJwJylcclxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MocGF0aC5kaXJuYW1lKGFsaWduZWRBcGspKVxyXG4gICAgICAgIC5yZXR1cm5zKFwiXCIpO1xyXG4gICAgICBtb2Nrcy50ZWVuX3Byb2Nlc3MuZXhwZWN0cyhcImV4ZWNcIilcclxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoYWRiLmJpbmFyaWVzLnppcGFsaWduLCBbJy1mJywgJzQnLCBzZWxlbmRyb2lkVGVzdEFwcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ25lZEFwa10pO1xyXG4gICAgICBtb2Nrcy5mcy5leHBlY3RzKFwibXZcIilcclxuICAgICAgICAub25jZSgpLndpdGhFeGFjdEFyZ3MoYWxpZ25lZEFwaywgc2VsZW5kcm9pZFRlc3RBcHAsIHsgbWtkaXJwOiB0cnVlIH0pXHJcbiAgICAgICAgLnJldHVybnMoXCJcIik7XHJcbiAgICAgIGF3YWl0IGFkYi56aXBBbGlnbkFwayhzZWxlbmRyb2lkVGVzdEFwcCk7XHJcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcclxuICAgICAgbW9ja3MuYXBwaXVtU3VwcG9ydC52ZXJpZnkoKTtcclxuICAgICAgbW9ja3MudGVlbl9wcm9jZXNzLnZlcmlmeSgpO1xyXG4gICAgICBtb2Nrcy50ZW1wRGlyLnZlcmlmeSgpO1xyXG4gICAgICBtb2Nrcy5mcy52ZXJpZnkoKTtcclxuICAgIH0pO1xyXG4gIH0pKTtcclxuICBkZXNjcmliZSgnY2hlY2tBcGtDZXJ0Jywgd2l0aE1vY2tzKHt0ZWVuX3Byb2Nlc3MsIGhlbHBlcnMsIGFkYn0sIChtb2NrcykgPT4ge1xyXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGFwayBub3QgcHJlc2VudCcsIGFzeW5jICgpID0+IHtcclxuICAgICAgbW9ja3MuaGVscGVycy5leHBlY3RzKFwiZ2V0SmF2YUZvck9zXCIpXHJcbiAgICAgICAgLnJldHVybnMoamF2YV9kdW1teV9wYXRoKTtcclxuICAgICAgKGF3YWl0IGFkYi5jaGVja0Fwa0NlcnQoJ2R1bW15UGF0aCcsICdkdW1teVBhY2thZ2UnKSkuc2hvdWxkLmJlLmZhbHNlO1xyXG4gICAgICBtb2Nrcy5oZWxwZXJzLnZlcmlmeSgpO1xyXG4gICAgfSk7XHJcbiAgICBpdCgnc2hvdWxkIGNhbGwgZXhlYyBhbmQgemlwQWxpZ24gd2hlbiBub3QgdXNpbmcga2V5c3RvcmUnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIG1vY2tzLmhlbHBlcnMuZXhwZWN0cyhcImdldEphdmFGb3JPc1wiKVxyXG4gICAgICAgICAgIC5yZXR1cm5zKGphdmFfZHVtbXlfcGF0aCk7XHJcbiAgICAgIG1vY2tzLnRlZW5fcHJvY2Vzcy5leHBlY3RzKFwiZXhlY1wiKVxyXG4gICAgICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhqYXZhX2R1bW15X3BhdGgsIFsnLWphcicsIHBhdGgucmVzb2x2ZShoZWxwZXJKYXJQYXRoLCAndmVyaWZ5LmphcicpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZW5kcm9pZFRlc3RBcHBdKVxyXG4gICAgICAgICAgIC5yZXR1cm5zKFwiXCIpO1xyXG4gICAgICBtb2Nrcy5hZGIuZXhwZWN0cygnemlwQWxpZ25BcGsnKVxyXG4gICAgICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhzZWxlbmRyb2lkVGVzdEFwcClcclxuICAgICAgICAgICAucmV0dXJucyhcIlwiKTtcclxuICAgICAgYWRiLnVzZUtleXN0b3JlID0gZmFsc2U7XHJcbiAgICAgIGF3YWl0IGFkYi5jaGVja0Fwa0NlcnQoc2VsZW5kcm9pZFRlc3RBcHAsIHNlbGVuZHJvaWRUZXN0QXBwUGFja2FnZSk7XHJcbiAgICAgIG1vY2tzLmFkYi52ZXJpZnkoKTtcclxuICAgICAgbW9ja3MudGVlbl9wcm9jZXNzLnZlcmlmeSgpO1xyXG4gICAgICBtb2Nrcy5oZWxwZXJzLnZlcmlmeSgpO1xyXG4gICAgfSk7XHJcbiAgICBpdCgnc2hvdWxkIGNhbGwgY2hlY2tDdXN0b21BcGtDZXJ0IHdoZW4gdXNpbmcga2V5c3RvcmUnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIG1vY2tzLmhlbHBlcnMuZXhwZWN0cyhcImdldEphdmFGb3JPc1wiKVxyXG4gICAgICAgICAgIC5yZXR1cm5zKGphdmFfZHVtbXlfcGF0aCk7XHJcbiAgICAgIG1vY2tzLmFkYi5leHBlY3RzKCdjaGVja0N1c3RvbUFwa0NlcnQnKVxyXG4gICAgICAgICAgIC5vbmNlKCkud2l0aEV4YWN0QXJncyhzZWxlbmRyb2lkVGVzdEFwcCwgc2VsZW5kcm9pZFRlc3RBcHBQYWNrYWdlKVxyXG4gICAgICAgICAgIC5yZXR1cm5zKFwiXCIpO1xyXG4gICAgICBhZGIudXNlS2V5c3RvcmUgPSB0cnVlO1xyXG4gICAgICBhd2FpdCBhZGIuY2hlY2tBcGtDZXJ0KHNlbGVuZHJvaWRUZXN0QXBwLCBzZWxlbmRyb2lkVGVzdEFwcFBhY2thZ2UpO1xyXG4gICAgICBtb2Nrcy5hZGIudmVyaWZ5KCk7XHJcbiAgICAgIG1vY2tzLmhlbHBlcnMudmVyaWZ5KCk7XHJcbiAgICB9KTtcclxuICB9KSk7XHJcbn0pO1xyXG4iXSwic291cmNlUm9vdCI6Ii4uXFwuLlxcLi4ifQ==