def test_get_server_with_server(mocker, nbdir, state, result, start): """Test that .get_server() returns a suitable server if it is accepting requests, and that it start up a new server unless a suitable server exists that is either starting up or running. Here, a suitable server is a server which renders the given notebook.""" serverManager = ServerManager() mock_start = mocker.patch.object(serverManager, 'start_server') filename = osp.abspath('foo/ham.ipynb') server_info = mocker.Mock(spec=dict) server = ServerProcess(mocker.Mock(spec=QProcess), osp.abspath(nbdir), state=state, server_info=server_info) serverManager.servers.append(server) res = serverManager.get_server(filename) if result: assert res == server_info else: assert res is None if start: mock_start.assert_called_once_with(filename) else: mock_start.assert_not_called()
def test_start_server(mocker, dark, under_home): """Test that .start_server() starts a process with the correct script file, notebook dir, and dark argument; that it stores the server process in `.servers`; and that it calls ._check_server_running().""" serverManager = ServerManager(dark) mock_check = mocker.patch.object(serverManager, '_check_server_started') mock_QProcess = mocker.patch( 'spyder_notebook.utils.servermanager.QProcess', spec=QProcess) mocker.patch('spyder_notebook.utils.servermanager.get_home_dir', return_value='foo') if under_home: filename = osp.join('foo', 'bar', 'ham.ipynb') nbdir = osp.join('foo') else: filename = osp.join('notfoo', 'bar', 'ham.ipynb') nbdir = osp.join('notfoo', 'bar') serverManager.start_server(filename) mock_QProcess.return_value.start.assert_called_once() args = mock_QProcess.return_value.start.call_args[0] import spyder_notebook.server.main assert args[1][0] == spyder_notebook.server.main.__file__ assert '--notebook-dir={}'.format(nbdir) in args[1] assert ('--dark' in args[1]) == dark assert len(serverManager.servers) == 1 assert serverManager.servers[0].process == mock_QProcess.return_value assert serverManager.servers[0].notebook_dir == nbdir mock_check.assert_called_once()
def test_handle_finished(mocker, qtbot): """Test that .handle_finished() changes the state.""" server = ServerProcess(mocker.Mock(spec=QProcess), '') serverManager = ServerManager() serverManager.handle_finished(server, mocker.Mock(), mocker.Mock()) assert server.state == ServerState.FINISHED
def test_handle_error(mocker, qtbot): """Test that .handle_error() changes the state and emits signal.""" server = ServerProcess(mocker.Mock(spec=QProcess), '') serverManager = ServerManager() with qtbot.waitSignal(serverManager.sig_server_errored): serverManager.handle_error(server, mocker.Mock()) assert server.state == ServerState.ERROR
def test_get_server_without_servers(mocker, start_arg): """Test that .get_server() calls .start_server() when there are no servers only if `start` is True.""" serverManager = ServerManager() mock_start = mocker.patch.object(serverManager, 'start_server') filename = osp.abspath('ham.ipynb') res = serverManager.get_server(filename, start=start_arg) assert res is None if start_arg: mock_start.assert_called_once_with(filename) else: mock_start.assert_not_called()
def test_read_standard_output(mocker): """Test that .read_standard_output() stores the output.""" before = 'before\n' output = 'Αθήνα\n' # check that we can handle non-ascii mock_read = mocker.Mock(return_value=QByteArray(output.encode())) mock_process = mocker.Mock(spec=QProcess, readAllStandardOutput=mock_read) server = ServerProcess(mock_process, '', output=before) serverManager = ServerManager() serverManager.servers = [server] serverManager.read_server_output(server) mock_read.assert_called_once() assert server.output == before + output
def test_check_server_started_if_errored(mocker, qtbot): """Test that .check_server_started() does not do anything if server state is ERROR.""" fake_open = mocker.patch('spyder_notebook.utils.servermanager.open') mock_QTimer = mocker.patch('spyder_notebook.utils.servermanager.QTimer', spec=QTimer) mock_process = mocker.Mock(spec=QProcess, processId=lambda: 7) server_process = ServerProcess( mock_process, 'notebookdir', 'interpreter', state=ServerState.ERROR) serverManager = ServerManager() serverManager._check_server_started(server_process) fake_open.assert_not_called() mock_QTimer.assert_not_called() assert server_process.state == ServerState.ERROR
def test_check_server_started_if_started(mocker, qtbot): """Test that .check_server_started() emits sig_server_started if there is a json file with the correct name and completes the server info.""" fake_open = mocker.patch('spyder_notebook.utils.servermanager.open', mocker.mock_open(read_data='{"foo": 42}')) mocker.patch('spyder_notebook.utils.servermanager.jupyter_runtime_dir', return_value='runtimedir') mock_process = mocker.Mock(spec=QProcess, processId=lambda: 7) server_process = ServerProcess(mock_process, 'notebookdir', 'interpreter') serverManager = ServerManager() with qtbot.waitSignal(serverManager.sig_server_started): serverManager._check_server_started(server_process) fake_open.assert_called_once_with( osp.join('runtimedir', 'nbserver-7.json'), encoding='utf-8') assert server_process.state == ServerState.RUNNING assert server_process.server_info == {'foo': 42}
def test_shutdown_all_servers(mocker): """Test that .shutdown_all_servers() does shutdown all running servers, but not servers in another state.""" mock_shutdown = mocker.patch( 'spyder_notebook.utils.servermanager.notebookapp.shutdown_server') server1 = ServerProcess( mocker.Mock(spec=QProcess), '', '', state=ServerState.RUNNING, server_info=mocker.Mock(dict)) server2 = ServerProcess( mocker.Mock(spec=QProcess), '', '', state=ServerState.ERROR, server_info=mocker.Mock(dict)) serverManager = ServerManager() serverManager.servers = [server1, server2] serverManager.shutdown_all_servers() assert mock_shutdown.called_once_with(server1.server_info) assert server1.state == ServerState.FINISHED assert server2.state == ServerState.ERROR
def test_check_server_started_if_timed_out(mocker, qtbot): """Test that .check_server_started() emits sig_server_timed_out if after an hour there is still no json file.""" fake_open = mocker.patch('spyder_notebook.utils.servermanager.open', side_effect=OSError) mocker.patch('spyder_notebook.utils.servermanager.jupyter_runtime_dir', return_value='runtimedir') mock_process = mocker.Mock(spec=QProcess, processId=lambda: 7) one_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1) server_process = ServerProcess( mock_process, 'notebookdir', 'interpreter', starttime=one_hour_ago) serverManager = ServerManager() with qtbot.waitSignal(serverManager.sig_server_timed_out): serverManager._check_server_started(server_process) fake_open.assert_called_once_with( osp.join('runtimedir', 'nbserver-7.json'), encoding='utf-8') assert server_process.state == ServerState.TIMED_OUT
def test_check_server_started_if_not_started(mocker, qtbot): """Test that .check_server_started() repeats itself on a timer if there is no json file with the correct name.""" fake_open = mocker.patch('spyder_notebook.utils.servermanager.open', side_effect=OSError) mocker.patch('spyder_notebook.utils.servermanager.jupyter_runtime_dir', return_value='runtimedir') mock_QTimer = mocker.patch('spyder_notebook.utils.servermanager.QTimer', spec=QTimer) mock_process = mocker.Mock(spec=QProcess, processId=lambda: 7) server_process = ServerProcess(mock_process, 'notebookdir', 'interpreter') serverManager = ServerManager() serverManager._check_server_started(server_process) fake_open.assert_called_once_with( osp.join('runtimedir', 'nbserver-7.json'), encoding='utf-8') assert server_process.state == ServerState.STARTING mock_QTimer.singleShot.assert_called_once()
def __init__(self, options): super().__init__() if options.dark: self.setStyleSheet(qdarkstyle.load_stylesheet_from_environment()) self.server_manager = ServerManager(options.dark) QApplication.instance().aboutToQuit.connect( self.server_manager.shutdown_all_servers) self.tabwidget = NotebookTabWidget(self, self.server_manager, dark_theme=options.dark) if options.notebook: self.tabwidget.open_notebook(options.notebook) else: self.tabwidget.maybe_create_welcome_client() self.setCentralWidget(self.tabwidget) self._setup_menu()
def __init__(self, parent, testing=False): """Constructor.""" if testing: self.CONF_FILE = False SpyderPluginWidget.__init__(self, parent) self.testing = testing self.fileswitcher_dlg = None self.main = parent self.recent_notebooks = self.get_option('recent_notebooks', default=[]) self.recent_notebook_menu = QMenu(_("Open recent"), self) layout = QVBoxLayout() new_notebook_btn = create_toolbutton(self, icon=ima.icon('options_more'), tip=_('Open a new notebook'), triggered=self.create_new_client) menu_btn = create_toolbutton(self, icon=ima.icon('tooloptions'), tip=_('Options')) self.menu_actions = self.get_plugin_actions() menu_btn.setMenu(self._options_menu) menu_btn.setPopupMode(menu_btn.InstantPopup) corner_widgets = {Qt.TopRightCorner: [new_notebook_btn, menu_btn]} dark_theme = is_dark_interface() self.server_manager = ServerManager(dark_theme) self.tabwidget = NotebookTabWidget( self, self.server_manager, menu=self._options_menu, actions=self.menu_actions, corner_widgets=corner_widgets, dark_theme=dark_theme) self.tabwidget.currentChanged.connect(self.refresh_plugin) layout.addWidget(self.tabwidget) self.setLayout(layout)