manager.spec.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import {
  4. flakyIt as it,
  5. JupyterServer,
  6. testEmission
  7. } from '@jupyterlab/testutils';
  8. import { toArray } from '@lumino/algorithm';
  9. import { UUID } from '@lumino/coreutils';
  10. import {
  11. KernelManager,
  12. ServerConnection,
  13. Session,
  14. SessionAPI,
  15. SessionManager
  16. } from '../../src';
  17. /**
  18. * Start a new session on with a default name.
  19. */
  20. async function startNew(
  21. manager: SessionManager
  22. ): Promise<Session.ISessionConnection> {
  23. const session = await manager.startNew({
  24. path: UUID.uuid4(),
  25. name: UUID.uuid4(),
  26. type: 'MYTEST'
  27. });
  28. return session;
  29. }
  30. const server = new JupyterServer();
  31. beforeAll(async () => {
  32. await server.start();
  33. });
  34. afterAll(async () => {
  35. await server.shutdown();
  36. });
  37. describe('session/manager', () => {
  38. let kernelManager: KernelManager;
  39. let manager: SessionManager;
  40. let session: Session.ISessionConnection;
  41. beforeAll(() => {
  42. jest.setTimeout(20000);
  43. kernelManager = new KernelManager({ standby: 'never' });
  44. });
  45. beforeEach(async () => {
  46. manager = new SessionManager({ kernelManager, standby: 'never' });
  47. await manager.ready;
  48. session = await startNew(manager);
  49. await session.kernel!.info;
  50. });
  51. afterEach(() => {
  52. manager.dispose();
  53. });
  54. afterAll(async () => {
  55. const sessions = await SessionAPI.listRunning();
  56. await Promise.all(sessions.map(s => SessionAPI.shutdownSession(s.id)));
  57. });
  58. describe('SessionManager', () => {
  59. describe('#constructor()', () => {
  60. it('should create a new session manager', () => {
  61. expect(manager instanceof SessionManager).toBe(true);
  62. });
  63. });
  64. describe('#serverSettings', () => {
  65. it('should get the server settings', async () => {
  66. manager.dispose();
  67. const serverSettings = ServerConnection.makeSettings();
  68. const token = serverSettings.token;
  69. manager = new SessionManager({ kernelManager, serverSettings });
  70. await manager.ready;
  71. expect(manager.serverSettings.token).toBe(token);
  72. });
  73. });
  74. describe('#isReady', () => {
  75. it('should test whether the manager is ready', async () => {
  76. manager.dispose();
  77. manager = new SessionManager({ kernelManager });
  78. expect(manager.isReady).toBe(false);
  79. await manager.ready;
  80. expect(manager.isReady).toBe(true);
  81. });
  82. });
  83. describe('#ready', () => {
  84. it('should resolve when the manager is ready', async () => {
  85. await manager.ready;
  86. });
  87. });
  88. describe('#running()', () => {
  89. it('should get the running sessions', async () => {
  90. await manager.refreshRunning();
  91. const running = toArray(manager.running());
  92. expect(running.length).toBeGreaterThan(0);
  93. });
  94. });
  95. describe('#runningChanged', () => {
  96. it('should be emitted when the running sessions changed', async () => {
  97. const promise = testEmission(manager.runningChanged, {
  98. test: (sender, args) => {
  99. expect(sender).toBe(manager);
  100. expect(toArray(args).length).toBeGreaterThan(0);
  101. }
  102. });
  103. await startNew(manager);
  104. await promise;
  105. });
  106. it('should be emitted when a session is shut down', async () => {
  107. let called = false;
  108. const s = await startNew(manager);
  109. manager.runningChanged.connect(() => {
  110. called = true;
  111. });
  112. await s.shutdown();
  113. await manager.refreshRunning();
  114. expect(called).toBe(true);
  115. });
  116. it('should be emitted when a session is renamed', async () => {
  117. let called = false;
  118. manager.runningChanged.connect(() => {
  119. called = true;
  120. });
  121. await session.setPath(UUID.uuid4());
  122. await manager.refreshRunning();
  123. expect(called).toBe(true);
  124. });
  125. it('should be emitted when a session changes kernels', async () => {
  126. let called = false;
  127. manager.runningChanged.connect(() => {
  128. called = true;
  129. });
  130. await session.changeKernel({ name: session.kernel!.name });
  131. await manager.refreshRunning();
  132. expect(called).toBe(true);
  133. });
  134. });
  135. describe('#refreshRunning()', () => {
  136. // Sometimes there is an extra kernel_info_request, which means that a
  137. // future is prematurely disposed.
  138. it('should refresh the list of session ids', async () => {
  139. await manager.refreshRunning();
  140. const running = toArray(manager.running());
  141. expect(running.length).toBeGreaterThan(0);
  142. });
  143. });
  144. describe('#startNew()', () => {
  145. it('should start a session', async () => {
  146. const session = await startNew(manager);
  147. expect(session.id).toBeTruthy();
  148. return session.shutdown();
  149. });
  150. it('should emit a runningChanged signal', async () => {
  151. let called = false;
  152. manager.runningChanged.connect(() => {
  153. called = true;
  154. });
  155. await startNew(manager);
  156. expect(called).toBe(true);
  157. });
  158. });
  159. describe('#findByPath()', () => {
  160. it('should find an existing session by path', async () => {
  161. const newModel = await manager.findByPath(session.path);
  162. expect(newModel!.id).toBe(session.id);
  163. });
  164. });
  165. describe('#findById()', () => {
  166. it('should find an existing session by id', async () => {
  167. const newModel = await manager.findById(session.id);
  168. expect(newModel!.id).toBe(session.id);
  169. });
  170. });
  171. describe('#connectTo()', () => {
  172. it('should connect to a running session', () => {
  173. const newSession = manager.connectTo({ model: session.model });
  174. expect(newSession.id).toBe(session.id);
  175. expect(newSession.kernel!.id).toBe(session.kernel!.id);
  176. expect(newSession).not.toBe(session);
  177. expect(newSession.kernel).not.toBe(session.kernel);
  178. });
  179. });
  180. describe('shutdown()', () => {
  181. it('should shut down a session by id', async () => {
  182. const temp = await startNew(manager);
  183. await manager.shutdown(temp.id);
  184. expect(temp.isDisposed).toBe(true);
  185. });
  186. it('should emit a runningChanged signal', async () => {
  187. let called = false;
  188. const session = await startNew(manager);
  189. manager.runningChanged.connect((sender, sessions) => {
  190. // Make sure the sessions list does not have our shutdown session in it.
  191. if (!sessions.find(s => s.id === session.id)) {
  192. called = true;
  193. }
  194. });
  195. await manager.shutdown(session.id);
  196. expect(called).toBe(true);
  197. expect(session.isDisposed).toBe(true);
  198. });
  199. it('should dispose of all session instances asynchronously', async () => {
  200. const session0 = await startNew(manager);
  201. const session1 = manager.connectTo({ model: session0.model });
  202. const emission = testEmission(session1.disposed);
  203. await session0.shutdown();
  204. await emission;
  205. });
  206. });
  207. });
  208. });