mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
Initial implementation
This commit is contained in:
parent
ae6c7477a5
commit
8ea54fbffc
166
spec/c9ShellHandler.spec.ts
Normal file
166
spec/c9ShellHandler.spec.ts
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
describe('C9 shell handler', () => {
|
||||||
|
const webContentsMocked = { send: jest.fn() };
|
||||||
|
const mockSpawnEvents = new Map<String, any>();
|
||||||
|
const mockSpawn = jest.fn();
|
||||||
|
const mockGetCommandLineArgs = jest.fn();
|
||||||
|
const mockGetGuid = jest.fn();
|
||||||
|
const mockKill = jest.fn();
|
||||||
|
let mockIsWindows: boolean;
|
||||||
|
|
||||||
|
jest.mock('child_process', () => {
|
||||||
|
return {
|
||||||
|
spawn: mockSpawn,
|
||||||
|
ChildProcess: () => {},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.mock('../src/common/utils', () => {
|
||||||
|
return {
|
||||||
|
getCommandLineArgs: mockGetCommandLineArgs,
|
||||||
|
getGuid: mockGetGuid,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.mock('../src/common/env', () => {
|
||||||
|
return {
|
||||||
|
isDevEnv: false,
|
||||||
|
isElectronQA: true,
|
||||||
|
isMac: false,
|
||||||
|
isWindowsOS: mockIsWindows,
|
||||||
|
isLinux: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks().resetModules().resetAllMocks();
|
||||||
|
mockSpawnEvents.clear();
|
||||||
|
mockSpawn.mockImplementation((_cmd, _args) => {
|
||||||
|
return {
|
||||||
|
on: (event, callback) => {
|
||||||
|
mockSpawnEvents.set(event, callback);
|
||||||
|
},
|
||||||
|
stdout: { on: jest.fn() },
|
||||||
|
stderr: { on: jest.fn() },
|
||||||
|
kill: mockKill,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
mockIsWindows = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('launch', () => {
|
||||||
|
it('success', () => {
|
||||||
|
const { loadC9Shell } = require('../src/app/c9-shell-handler');
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: { status: 'starting' },
|
||||||
|
});
|
||||||
|
|
||||||
|
mockSpawnEvents.get('spawn')();
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: expect.objectContaining({ status: 'active' }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('failure', () => {
|
||||||
|
const { loadC9Shell } = require('../src/app/c9-shell-handler');
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: { status: 'starting' },
|
||||||
|
});
|
||||||
|
|
||||||
|
mockSpawnEvents.get('close')(1);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: expect.objectContaining({ status: 'inactive' }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with attach', () => {
|
||||||
|
mockGetCommandLineArgs.mockReturnValue('--c9pipe=custompipe');
|
||||||
|
|
||||||
|
const { loadC9Shell } = require('../src/app/c9-shell-handler');
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: { status: 'active', pipeName: 'symphony-c9-custompipe' },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cached status on relaunch', () => {
|
||||||
|
const { loadC9Shell } = require('../src/app/c9-shell-handler');
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: { status: 'starting' },
|
||||||
|
});
|
||||||
|
|
||||||
|
mockSpawnEvents.get('spawn')();
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: expect.objectContaining({ status: 'active' }),
|
||||||
|
});
|
||||||
|
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: expect.objectContaining({ status: 'active' }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('args', () => {
|
||||||
|
mockGetGuid.mockReturnValue('just-another-guid');
|
||||||
|
|
||||||
|
const { loadC9Shell } = require('../src/app/c9-shell-handler');
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(mockSpawn).toBeCalledWith(
|
||||||
|
expect.stringContaining('c9shell.exe'),
|
||||||
|
['--symphonyHost', 'just-another-guid'],
|
||||||
|
{ stdio: 'pipe' },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('non-windows', () => {
|
||||||
|
mockIsWindows = false;
|
||||||
|
|
||||||
|
const { loadC9Shell } = require('../src/app/c9-shell-handler');
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(mockSpawn).not.toBeCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('terminate', () => {
|
||||||
|
it('success', () => {
|
||||||
|
const {
|
||||||
|
loadC9Shell,
|
||||||
|
terminateC9Shell,
|
||||||
|
} = require('../src/app/c9-shell-handler');
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: { status: 'starting' },
|
||||||
|
});
|
||||||
|
|
||||||
|
terminateC9Shell(webContentsMocked as any);
|
||||||
|
expect(mockKill).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('no terminate if never started', () => {
|
||||||
|
const { terminateC9Shell } = require('../src/app/c9-shell-handler');
|
||||||
|
terminateC9Shell(webContentsMocked as any);
|
||||||
|
expect(mockKill).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('no terminate if already exited', () => {
|
||||||
|
const {
|
||||||
|
loadC9Shell,
|
||||||
|
terminateC9Shell,
|
||||||
|
} = require('../src/app/c9-shell-handler');
|
||||||
|
loadC9Shell(webContentsMocked as any);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: { status: 'starting' },
|
||||||
|
});
|
||||||
|
|
||||||
|
mockSpawnEvents.get('close')(1);
|
||||||
|
expect(webContentsMocked.send).lastCalledWith('c9-status-event', {
|
||||||
|
status: expect.objectContaining({ status: 'inactive' }),
|
||||||
|
});
|
||||||
|
|
||||||
|
terminateC9Shell(webContentsMocked as any);
|
||||||
|
expect(mockKill).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -39,14 +39,21 @@ class C9ShellHandler {
|
|||||||
*/
|
*/
|
||||||
public setStatusCallback(callback: StatusCallback) {
|
public setStatusCallback(callback: StatusCallback) {
|
||||||
this._statusCallback = callback;
|
this._statusCallback = callback;
|
||||||
if (!this._statusCallback) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this._curStatus) {
|
if (this._curStatus) {
|
||||||
this._statusCallback(this._curStatus);
|
this._statusCallback(this._curStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates the c9shell process if it was started by this handler.
|
||||||
|
*/
|
||||||
|
public terminateShell() {
|
||||||
|
if (!this._c9shell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._c9shell.kill();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the current shell status and notify the callback if set.
|
* Update the current shell status and notify the callback if set.
|
||||||
*/
|
*/
|
||||||
@ -107,12 +114,7 @@ class C9ShellHandler {
|
|||||||
|
|
||||||
const c9Shell = spawn(
|
const c9Shell = spawn(
|
||||||
c9ShellPath,
|
c9ShellPath,
|
||||||
[
|
['--symphonyHost', uniquePipeName, ...customC9ShellArgList],
|
||||||
'--allowmultiproc',
|
|
||||||
'--symphonyHost',
|
|
||||||
uniquePipeName,
|
|
||||||
...customC9ShellArgList,
|
|
||||||
],
|
|
||||||
{
|
{
|
||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
},
|
},
|
||||||
@ -159,3 +161,13 @@ export const loadC9Shell = (sender: WebContents) => {
|
|||||||
});
|
});
|
||||||
c9ShellHandler.startShell();
|
c9ShellHandler.startShell();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates the C9 shell process asynchronously, if it is running.
|
||||||
|
*/
|
||||||
|
export const terminateC9Shell = (_sender: WebContents) => {
|
||||||
|
if (!c9ShellHandler) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
c9ShellHandler.terminateShell();
|
||||||
|
};
|
||||||
|
@ -19,7 +19,7 @@ import { activityDetection } from './activity-detection';
|
|||||||
import { analytics } from './analytics-handler';
|
import { analytics } from './analytics-handler';
|
||||||
import appStateHandler from './app-state-handler';
|
import appStateHandler from './app-state-handler';
|
||||||
import { closeC9Pipe, connectC9Pipe, writeC9Pipe } from './c9-pipe-handler';
|
import { closeC9Pipe, connectC9Pipe, writeC9Pipe } from './c9-pipe-handler';
|
||||||
import { loadC9Shell } from './c9-shell-handler';
|
import { loadC9Shell, terminateC9Shell } from './c9-shell-handler';
|
||||||
import { getCitrixMediaRedirectionStatus } from './citrix-handler';
|
import { getCitrixMediaRedirectionStatus } from './citrix-handler';
|
||||||
import { CloudConfigDataTypes, config, ICloudConfig } from './config-handler';
|
import { CloudConfigDataTypes, config, ICloudConfig } from './config-handler';
|
||||||
import { downloadHandler } from './download-handler';
|
import { downloadHandler } from './download-handler';
|
||||||
@ -378,6 +378,9 @@ ipcMain.on(
|
|||||||
case apiCmds.launchCloud9:
|
case apiCmds.launchCloud9:
|
||||||
loadC9Shell(event.sender);
|
loadC9Shell(event.sender);
|
||||||
break;
|
break;
|
||||||
|
case apiCmds.terminateCloud9:
|
||||||
|
terminateC9Shell(event.sender);
|
||||||
|
break;
|
||||||
case apiCmds.updateAndRestart:
|
case apiCmds.updateAndRestart:
|
||||||
autoUpdate.updateAndRestart();
|
autoUpdate.updateAndRestart();
|
||||||
break;
|
break;
|
||||||
|
@ -66,6 +66,7 @@ export enum apiCmds {
|
|||||||
getCitrixMediaRedirectionStatus = 'get-citrix-media-redirection-status',
|
getCitrixMediaRedirectionStatus = 'get-citrix-media-redirection-status',
|
||||||
getSources = 'getSources',
|
getSources = 'getSources',
|
||||||
launchCloud9 = 'launch-cloud9',
|
launchCloud9 = 'launch-cloud9',
|
||||||
|
terminateCloud9 = 'terminate-cloud9',
|
||||||
connectCloud9Pipe = 'connect-cloud9-pipe',
|
connectCloud9Pipe = 'connect-cloud9-pipe',
|
||||||
writeCloud9Pipe = 'write-cloud9-pipe',
|
writeCloud9Pipe = 'write-cloud9-pipe',
|
||||||
closeCloud9Pipe = 'close-cloud9-pipe',
|
closeCloud9Pipe = 'close-cloud9-pipe',
|
||||||
|
@ -91,6 +91,7 @@ if (ssfWindow.ssf) {
|
|||||||
ssfWindow.ssf.getCitrixMediaRedirectionStatus,
|
ssfWindow.ssf.getCitrixMediaRedirectionStatus,
|
||||||
registerClientBanner: ssfWindow.ssf.registerClientBanner,
|
registerClientBanner: ssfWindow.ssf.registerClientBanner,
|
||||||
launchCloud9: ssfWindow.ssf.launchCloud9,
|
launchCloud9: ssfWindow.ssf.launchCloud9,
|
||||||
|
terminateCloud9: ssfWindow.ssf.terminateCloud9,
|
||||||
connectCloud9Pipe: ssfWindow.ssf.connectCloud9Pipe,
|
connectCloud9Pipe: ssfWindow.ssf.connectCloud9Pipe,
|
||||||
updateAndRestart: ssfWindow.ssf.updateAndRestart,
|
updateAndRestart: ssfWindow.ssf.updateAndRestart,
|
||||||
downloadUpdate: ssfWindow.ssf.downloadUpdate,
|
downloadUpdate: ssfWindow.ssf.downloadUpdate,
|
||||||
|
@ -798,6 +798,15 @@ export class SSFApi {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates the Cloud9 client.
|
||||||
|
*/
|
||||||
|
public terminateCloud9(): void {
|
||||||
|
ipcRenderer.send(apiName.symphonyApi, {
|
||||||
|
cmd: apiCmds.terminateCloud9,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows JS to install new update and restart SDA
|
* Allows JS to install new update and restart SDA
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user