mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-29 22:02:01 +00:00
Initial Move from Azure DevOps to GitHub
This commit is contained in:
492
src/Explorer/Notebook/NotebookComponent/epics.test.ts
Normal file
492
src/Explorer/Notebook/NotebookComponent/epics.test.ts
Normal file
@@ -0,0 +1,492 @@
|
||||
import * as Immutable from "immutable";
|
||||
import { ActionsObservable, StateObservable } from "redux-observable";
|
||||
import { Subject } from "rxjs";
|
||||
import { toArray } from "rxjs/operators";
|
||||
import { makeNotebookRecord } from "@nteract/commutable";
|
||||
import { actions, state } from "@nteract/core";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import { CdbAppState, makeCdbRecord } from "./types";
|
||||
import { launchWebSocketKernelEpic } from "./epics";
|
||||
import { NotebookUtil } from "../NotebookUtil";
|
||||
|
||||
import { sessions } from "rx-jupyter";
|
||||
|
||||
describe("Extract kernel from notebook", () => {
|
||||
it("Reads metadata kernelspec first", () => {
|
||||
const fakeNotebook = makeNotebookRecord({
|
||||
metadata: Immutable.Map({
|
||||
kernelspec: {
|
||||
display_name: "Python 3",
|
||||
language: "python",
|
||||
name: "python3"
|
||||
},
|
||||
language_info: {
|
||||
name: "python",
|
||||
version: "3.7.3",
|
||||
mimetype: "text/x-python",
|
||||
codemirror_mode: {
|
||||
name: "ipython",
|
||||
version: 3
|
||||
},
|
||||
pygments_lexer: "ipython3",
|
||||
nbconvert_exporter: "python",
|
||||
file_extension: ".py"
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const result = NotebookUtil.extractNewKernel("blah", fakeNotebook);
|
||||
expect(result.kernelSpecName).toEqual("python3");
|
||||
});
|
||||
|
||||
it("Reads language info in metadata if kernelspec not present", () => {
|
||||
const fakeNotebook = makeNotebookRecord({
|
||||
metadata: Immutable.Map({
|
||||
language_info: {
|
||||
name: "python",
|
||||
version: "3.7.3",
|
||||
mimetype: "text/x-python",
|
||||
codemirror_mode: {
|
||||
name: "ipython",
|
||||
version: 3
|
||||
},
|
||||
pygments_lexer: "ipython3",
|
||||
nbconvert_exporter: "python",
|
||||
file_extension: ".py"
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const result = NotebookUtil.extractNewKernel("blah", fakeNotebook);
|
||||
expect(result.kernelSpecName).toEqual("python");
|
||||
});
|
||||
|
||||
it("Returns nothing if no kernelspec nor language info is found in metadata", () => {
|
||||
const fakeNotebook = makeNotebookRecord({
|
||||
metadata: Immutable.Map({
|
||||
blah: "this should be ignored"
|
||||
})
|
||||
});
|
||||
|
||||
const result = NotebookUtil.extractNewKernel("blah", fakeNotebook);
|
||||
expect(result.kernelSpecName).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe("launchWebSocketKernelEpic", () => {
|
||||
const createSpy = sinon.spy(sessions, "create");
|
||||
|
||||
const contentRef = "fakeContentRef";
|
||||
const kernelRef = "fake";
|
||||
const initialState = {
|
||||
app: state.makeAppRecord({
|
||||
host: state.makeJupyterHostRecord({
|
||||
type: "jupyter",
|
||||
token: "eh",
|
||||
basePath: "/"
|
||||
})
|
||||
}),
|
||||
comms: state.makeCommsRecord(),
|
||||
config: Immutable.Map({}),
|
||||
core: state.makeStateRecord({
|
||||
kernelRef: "fake",
|
||||
entities: state.makeEntitiesRecord({
|
||||
contents: state.makeContentsRecord({
|
||||
byRef: Immutable.Map({
|
||||
fakeContentRef: state.makeNotebookContentRecord()
|
||||
})
|
||||
}),
|
||||
kernels: state.makeKernelsRecord({
|
||||
byRef: Immutable.Map({
|
||||
fake: state.makeRemoteKernelRecord({
|
||||
type: "websocket",
|
||||
channels: new Subject<any>(),
|
||||
kernelSpecName: "fancy",
|
||||
id: "0"
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}),
|
||||
cdb: makeCdbRecord({
|
||||
databaseAccountName: "dbAccountName",
|
||||
defaultExperience: "defaultExperience"
|
||||
})
|
||||
};
|
||||
|
||||
it("launches remote kernels", async () => {
|
||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||
|
||||
const cwd = "/";
|
||||
const kernelId = "123";
|
||||
const kernelSpecName = "kernelspecname";
|
||||
const sessionId = "sessionId";
|
||||
|
||||
const action$ = ActionsObservable.of(
|
||||
actions.launchKernelByName({
|
||||
contentRef,
|
||||
kernelRef,
|
||||
kernelSpecName,
|
||||
cwd,
|
||||
selectNextKernel: true
|
||||
})
|
||||
);
|
||||
|
||||
(sessions as any).__setResponse({
|
||||
originalEvent: undefined,
|
||||
xhr: new XMLHttpRequest(),
|
||||
request: null,
|
||||
status: 200,
|
||||
response: {
|
||||
id: sessionId,
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: "",
|
||||
type: "notebook",
|
||||
kernel: {
|
||||
id: kernelId,
|
||||
name: "kernel_launched",
|
||||
last_activity: "2019-11-07T14:29:54.432454Z",
|
||||
execution_state: "starting",
|
||||
connections: 0
|
||||
},
|
||||
notebook: {
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: ""
|
||||
}
|
||||
},
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
});
|
||||
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(responseActions).toMatchObject([
|
||||
{
|
||||
type: actions.LAUNCH_KERNEL_SUCCESSFUL,
|
||||
payload: {
|
||||
contentRef,
|
||||
kernelRef,
|
||||
selectNextKernel: true,
|
||||
kernel: {
|
||||
info: null,
|
||||
sessionId: sessionId,
|
||||
type: "websocket",
|
||||
kernelSpecName,
|
||||
cwd,
|
||||
id: kernelId
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("launches any kernel with no kernelspecs in the state", async () => {
|
||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||
|
||||
const cwd = "/";
|
||||
const kernelId = "123";
|
||||
const kernelSpecName = "kernelspecname";
|
||||
const sessionId = "sessionId";
|
||||
|
||||
const action$ = ActionsObservable.of(
|
||||
actions.launchKernelByName({
|
||||
contentRef,
|
||||
kernelRef,
|
||||
kernelSpecName,
|
||||
cwd,
|
||||
selectNextKernel: true
|
||||
})
|
||||
);
|
||||
|
||||
(sessions as any).__setResponse({
|
||||
originalEvent: undefined,
|
||||
xhr: new XMLHttpRequest(),
|
||||
request: null,
|
||||
status: 200,
|
||||
response: {
|
||||
id: sessionId,
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: "",
|
||||
type: "notebook",
|
||||
kernel: {
|
||||
id: kernelId,
|
||||
name: "kernel_launched",
|
||||
last_activity: "2019-11-07T14:29:54.432454Z",
|
||||
execution_state: "starting",
|
||||
connections: 0
|
||||
},
|
||||
notebook: {
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: ""
|
||||
}
|
||||
},
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
});
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: kernelSpecName
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("launches no kernel if no kernel is specified and state has no kernelspecs", async () => {
|
||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||
|
||||
const cwd = "/";
|
||||
const kernelId = "123";
|
||||
const kernelSpecName = "kernelspecname";
|
||||
const sessionId = "sessionId";
|
||||
|
||||
const action$ = ActionsObservable.of(
|
||||
actions.launchKernelByName({
|
||||
contentRef,
|
||||
kernelRef,
|
||||
kernelSpecName: undefined,
|
||||
cwd,
|
||||
selectNextKernel: true
|
||||
})
|
||||
);
|
||||
|
||||
(sessions as any).__setResponse({
|
||||
originalEvent: undefined,
|
||||
xhr: new XMLHttpRequest(),
|
||||
request: null,
|
||||
status: 200,
|
||||
response: {
|
||||
id: sessionId,
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: "",
|
||||
type: "notebook",
|
||||
kernel: {
|
||||
id: kernelId,
|
||||
name: "kernel_launched",
|
||||
last_activity: "2019-11-07T14:29:54.432454Z",
|
||||
execution_state: "starting",
|
||||
connections: 0
|
||||
},
|
||||
notebook: {
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: ""
|
||||
}
|
||||
},
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
});
|
||||
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(responseActions).toMatchObject([
|
||||
{
|
||||
type: actions.LAUNCH_KERNEL_FAILED
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("emits an error if backend returns an error", async () => {
|
||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||
|
||||
const cwd = "/";
|
||||
const action$ = ActionsObservable.of(
|
||||
actions.launchKernelByName({
|
||||
contentRef,
|
||||
kernelRef,
|
||||
kernelSpecName: undefined,
|
||||
cwd,
|
||||
selectNextKernel: true
|
||||
})
|
||||
);
|
||||
|
||||
(sessions as any).__setResponse({
|
||||
originalEvent: undefined,
|
||||
xhr: new XMLHttpRequest(),
|
||||
request: null,
|
||||
status: 500,
|
||||
response: null,
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
});
|
||||
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(responseActions).toMatchObject([
|
||||
{
|
||||
type: actions.LAUNCH_KERNEL_FAILED
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
describe("Choose correct kernelspecs to launch", () => {
|
||||
beforeAll(() => {
|
||||
// Initialize kernelspecs with 2 supported kernels
|
||||
const createKernelSpecsRecord = (): Immutable.RecordOf<state.KernelspecsRecordProps> =>
|
||||
state.makeKernelspecsRecord({
|
||||
byRef: Immutable.Map({
|
||||
kernelspecsref: state.makeKernelspecsByRefRecord({
|
||||
defaultKernelName: "kernel2",
|
||||
byName: Immutable.Map({
|
||||
kernel1: state.makeKernelspec({
|
||||
name: "kernel1",
|
||||
argv: Immutable.List([]),
|
||||
env: Immutable.Map(),
|
||||
interruptMode: "interruptMode1",
|
||||
language: "language1",
|
||||
displayName: "Kernel One",
|
||||
metadata: Immutable.Map(),
|
||||
resources: Immutable.Map()
|
||||
}),
|
||||
kernel2: state.makeKernelspec({
|
||||
name: "kernel2",
|
||||
argv: Immutable.List([]),
|
||||
env: Immutable.Map(),
|
||||
interruptMode: "interruptMode2",
|
||||
language: "language2",
|
||||
displayName: "Kernel Two",
|
||||
metadata: Immutable.Map(),
|
||||
resources: Immutable.Map()
|
||||
})
|
||||
})
|
||||
})
|
||||
}),
|
||||
refs: Immutable.List(["kernelspecsref"])
|
||||
});
|
||||
initialState.core = initialState.core
|
||||
.setIn(["entities", "kernelspecs"], createKernelSpecsRecord())
|
||||
.set("currentKernelspecsRef", "kernelspecsref");
|
||||
|
||||
// some fake response we don't care about
|
||||
(sessions as any).__setResponse({
|
||||
originalEvent: undefined,
|
||||
xhr: new XMLHttpRequest(),
|
||||
request: null,
|
||||
status: 200,
|
||||
response: {
|
||||
id: "sessionId",
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: "",
|
||||
type: "notebook",
|
||||
kernel: {
|
||||
id: "kernelId",
|
||||
name: "kernel_launched",
|
||||
last_activity: "2019-11-07T14:29:54.432454Z",
|
||||
execution_state: "starting",
|
||||
connections: 0
|
||||
},
|
||||
notebook: {
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: ""
|
||||
}
|
||||
},
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
});
|
||||
});
|
||||
|
||||
it("launches supported kernel in kernelspecs", async () => {
|
||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||
|
||||
const action$ = ActionsObservable.of(
|
||||
actions.launchKernelByName({
|
||||
contentRef,
|
||||
kernelRef,
|
||||
kernelSpecName: "kernel2",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true
|
||||
})
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: "kernel2"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("launches undefined kernel uses default kernel from kernelspecs", async () => {
|
||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||
|
||||
const action$ = ActionsObservable.of(
|
||||
actions.launchKernelByName({
|
||||
contentRef,
|
||||
kernelRef,
|
||||
kernelSpecName: undefined,
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true
|
||||
})
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: "kernel2"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("launches unsupported kernel uses default kernel from kernelspecs", async () => {
|
||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||
|
||||
const action$ = ActionsObservable.of(
|
||||
actions.launchKernelByName({
|
||||
contentRef,
|
||||
kernelRef,
|
||||
kernelSpecName: "This is an unknown kernelspec",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true
|
||||
})
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: "kernel2"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("launches unsupported kernel uses kernelspecs with similar name", async () => {
|
||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||
|
||||
const action$ = ActionsObservable.of(
|
||||
actions.launchKernelByName({
|
||||
contentRef,
|
||||
kernelRef,
|
||||
kernelSpecName: "ernel1",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true
|
||||
})
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: "kernel1"
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user