blob: 0ae21b35695894147e392b41a0b5df9eaa53e075 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-env mocha */
'use strict';
const test = require('./test');
let Debugger = require("../src/debugger");
const assert = require('assert');
const nock = require('nock');
const fetch = require('isomorphic-fetch');
const mockRequire = require('mock-require');
function mockNgrokLibrary(connect, kill) {
mockRequire("ngrok", {
connect: connect || function() {
console.log('ngrok.connect called');
},
kill: kill || function() {
console.log('ngrok.kill called');
}
});
// the modules have been loaded from another test file before,
// so we need to re-require them in the reverse order
// to make the mockRequire("ngrok") have an effect
mockRequire.reRequire("../src/agents/ngrok");
mockRequire.reRequire("../src/agentmgr");
Debugger = mockRequire.reRequire("../src/debugger");
}
describe('ngrok', function() {
this.timeout(30000);
before(function() {
test.isDockerInstalled();
});
beforeEach(async function() {
await test.beforeEach();
});
afterEach(function() {
test.afterEach();
});
it("should connect to ngrok if selected", async function() {
test.mockActionAndInvocation(
"myaction",
// should not use this code if we specify local sources which return CORRECT
`const main = () => ({ msg: 'WRONG' });`,
{},
{ msg: "CORRECT" }
);
// validate that it connects to ngrok
// leaving it at that for now - more validation would be quite difficult
const ngrok = nock('http://127.0.0.1', {
filteringScope: scope => /^http:\/\/127\.0\.0\.1:.*/.test(scope),
})
.post('/api/tunnels')
.reply(201, { "public_url":"https://UNIT_TEST.ngrok.io" });
// wskdebug myaction --ngrok -p ${test.port}
const argv = {
port: test.port,
action: "myaction",
ngrok: true
};
const dbgr = new Debugger(argv);
await dbgr.start();
// no need to run() for this test
await dbgr.stop();
assert(ngrok.isDone(), "Expected these HTTP requests: " + ngrok.pendingMocks().join());
});
/*
Runtime setup:
[ wskdebug ]------<start>-----+
^ |
| |
<handle> |
| v
[ local server ]<---------[ local ngrok ]
^
|
|
[ ngrok.io ]
^
|
[ openwhisk action ]----------+
Test setup:
[ wskdebug ]------<start>-----+
^ |
| |
<handle> |
| v
[ local server ] [ MOCKED ngrok ]
^ |
| <pass on port>
| |
| |
[ MOCKED invocation call ] <--+
*/
it("should handle action invocation using ngrok", async function() {
const actionName = "myaction";
// port of the local server started by wskdebug to be expecting calls from ngrok
// which we will do in this test
let ngrokServerPort;
mockNgrokLibrary(function(opts) {
ngrokServerPort = opts.addr;
return "https://UNIT_TEST.ngrok.io";
});
// should not use this code if we specify local sources which return CORRECT
const code = `const main = () => ({ msg: 'WRONG' });`;
let ngrokAuth;
test.mockAction(actionName, code);
test.mockCreateBackupAction(actionName);
// ngrok agent installation
// custom version instead of test.mockInstallAgent() to catch the ngrokAuth
test.openwhiskNock()
.put(
`${test.openwhiskApiUrlActions()}/${actionName}?overwrite=true`,
body => {
ngrokAuth = body.parameters.find(e => e.key === "$ngrokAuth").value;
return body.annotations.some(v => v.key === "wskdebug" && v.value === true);
}
)
.matchHeader("authorization", test.openwhiskApiAuthHeader())
.reply(200, test.nodejsActionDescription(actionName));
// wskdebug myaction --ngrok -p ${test.port}
const argv = {
port: test.port,
action: actionName,
sourcePath: "action.js",
ngrok: true
};
process.chdir("test/nodejs/plain-flat");
const dbgr = new Debugger(argv);
await dbgr.start();
dbgr.run();
// wait for everything to startup
await test.sleep(10);
try {
const response = await fetch(`http://127.0.0.1:${ngrokServerPort}`, {
method: "POST",
headers: {
authorization: ngrokAuth
},
body: JSON.stringify({
$activationId: "1234567890"
})
});
assert.strictEqual(response.status, 200);
const result = await response.json();
assert.strictEqual(result.msg, "CORRECT");
} finally {
await dbgr.stop();
}
assert(nock.isDone(), "Expected these HTTP requests: " + nock.pendingMocks().join());
});
});