Example #1
0
def test_get_connection_info():
    with TemporaryDirectory() as d:
        cf = os.path.join(d, 'kernel.json')
        connect.write_connection_file(cf, **sample_info)
        json_info = connect.get_connection_info(cf)
        info = connect.get_connection_info(cf, unpack=True)
    
    nt.assert_equal(type(json_info), type(""))
    sub_info = {k:v for k,v in info.items() if k in sample_info}
    nt.assert_equal(sub_info, sample_info)

    info2 = json.loads(json_info)
    info2['key'] = str_to_bytes(info2['key'])
    sub_info2 = {k:v for k,v in info.items() if k in sample_info}
    nt.assert_equal(sub_info2, sample_info)
Example #2
0
 def test_overwrite_file(self):
     with TemporaryDirectory() as d:
         fname = u'ƒ.js'
         src = pjoin(d, fname)
         with open(src, 'w') as f:
             f.write('first')
         mtime = touch(src)
         dest = pjoin(self.system_nbext, fname)
         install_nbextension(src)
         with open(src, 'w') as f:
             f.write('overwrite')
         mtime = touch(src, mtime - 100)
         install_nbextension(src, overwrite=True)
         with open(dest) as f:
             self.assertEqual(f.read(), 'overwrite')
Example #3
0
def test_get_connection_info():
    with TemporaryDirectory() as d:
        cf = os.path.join(d, 'kernel.json')
        connect.write_connection_file(cf, **sample_info)
        json_info = connect.get_connection_info(cf)
        info = connect.get_connection_info(cf, unpack=True)
    assert isinstance(json_info, str)

    sub_info = {k: v for k, v in info.items() if k in sample_info}
    assert sub_info == sample_info

    info2 = json.loads(json_info)
    info2['key'] = str_to_bytes(info2['key'])
    sub_info2 = {k: v for k, v in info.items() if k in sample_info}
    assert sub_info2 == sample_info
def test_load_connection_file_session():
    """test load_connection_file() after """
    session = Session()
    app = DummyConsoleApp(session=Session())
    app.initialize(argv=[])
    session = app.session

    with TemporaryDirectory() as d:
        cf = os.path.join(d, 'kernel.json')
        connect.write_connection_file(cf, **sample_info)
        app.connection_file = cf
        app.load_connection_file()

    nt.assert_equal(session.key, sample_info['key'])
    nt.assert_equal(session.signature_scheme, sample_info['signature_scheme'])
Example #5
0
def test_save_history():
    # Saving history from the kernel with %hist -f was failing because of
    # unicode problems on Python 2.
    with kernel() as kc, TemporaryDirectory() as td:
        file = os.path.join(td, 'hist.out')
        execute('a=1', kc=kc)
        wait_for_idle(kc)
        execute('b="abcþ"', kc=kc)
        wait_for_idle(kc)
        _, reply = execute("%hist -f " + file, kc=kc)
        assert reply['status'] == 'ok'
        with io.open(file, encoding='utf-8') as f:
            content = f.read()
        assert 'a=1' in content
        assert 'b="abcþ"' in content
Example #6
0
 def test_checkpoint_subdir(self):
     subd = u'sub ∂ir'
     cp_name = 'test-cp.ipynb'
     with TemporaryDirectory() as td:
         root = td
         os.mkdir(os.path.join(td, subd))
         fm = FileContentsManager(root_dir=root)
         cpm = fm.checkpoints
         cp_dir = cpm.checkpoint_path('cp', 'test.ipynb')
         cp_subdir = cpm.checkpoint_path('cp', '/%s/test.ipynb' % subd)
     self.assertNotEqual(cp_dir, cp_subdir)
     self.assertEqual(cp_dir, os.path.join(root, cpm.checkpoint_dir,
                                           cp_name))
     self.assertEqual(cp_subdir,
                      os.path.join(root, subd, cpm.checkpoint_dir, cp_name))
Example #7
0
def test_server_info_file():
    td = TemporaryDirectory()
    nbapp = NotebookApp(runtime_dir=td.name, log=logging.getLogger())
    def get_servers():
        return list(notebookapp.list_running_servers(nbapp.runtime_dir))
    nbapp.initialize(argv=[])
    nbapp.write_server_info_file()
    servers = get_servers()
    nt.assert_equal(len(servers), 1)
    nt.assert_equal(servers[0]['port'], nbapp.port)
    nt.assert_equal(servers[0]['url'], nbapp.connection_url)
    nbapp.remove_server_info_file()
    nt.assert_equal(get_servers(), [])

    # The ENOENT error should be silenced.
    nbapp.remove_server_info_file()
Example #8
0
    def link_package(self, path):
        """Link a package at the given path.
        """
        if not osp.exists(path) or not osp.isdir(path):
            raise ValueError('Can only link local directories')

        with TemporaryDirectory() as tempdir:
            info = self._extract_package(path, tempdir)

        if _is_extension(info['data']):
            return self.install_extension(path)

        # Add to metadata.
        config = self._read_build_config()
        linked = config.setdefault('linked_packages', dict())
        linked[info['name']] = info['source']
        self._write_build_config(config)
Example #9
0
 def test_update_file(self):
     with TemporaryDirectory() as d:
         fname = u'ƒ.js'
         src = pjoin(d, fname)
         with open(src, 'w') as f:
             f.write('first')
         mtime = touch(src)
         install_nbextension(src)
         self.assert_installed(fname)
         dest = pjoin(self.system_nbext, fname)
         old_mtime = os.stat(dest).st_mtime
         with open(src, 'w') as f:
             f.write('overwrite')
         touch(src, mtime + 10)
         install_nbextension(src)
         with open(dest) as f:
             self.assertEqual(f.read(), 'overwrite')
Example #10
0
 def start(self):
     self.test_dir = td = TemporaryDirectory()
     self.env_patch = patch.dict(os.environ, {
         'JUPYTER_CONFIG_DIR': pjoin(td.name, 'jupyter'),
         'JUPYTER_DATA_DIR': pjoin(td.name, 'jupyter_data'),
         'JUPYTER_RUNTIME_DIR': pjoin(td.name, 'jupyter_runtime'),
         'IPYTHONDIR': pjoin(td.name, 'ipython'),
     })
     self.env_patch.start()
     self.path_patch = patch.multiple(
         jupyter_core.paths,
         SYSTEM_JUPYTER_PATH=[pjoin(td.name, 'share', 'jupyter')],
         ENV_JUPYTER_PATH=[pjoin(td.name, 'env', 'share', 'jupyter')],
         SYSTEM_CONFIG_PATH=[pjoin(td.name, 'etc', 'jupyter')],
         ENV_CONFIG_PATH=[pjoin(td.name, 'env', 'etc', 'jupyter')],
     )
     self.path_patch.start()
Example #11
0
    def setUp(self):
        """Build an isolated config environment."""
        td = TemporaryDirectory()

        self.test_dir = py3compat.cast_unicode(td.name)
        self.data_dir = os.path.join(self.test_dir, 'data')
        self.config_dir = os.path.join(self.test_dir, 'config')
        self.system_data_dir = os.path.join(self.test_dir, 'system_data')
        self.system_path = [self.system_data_dir]

        # Use temp directory, not real user or system config paths
        self.patch_env = patch.dict(
            'os.environ', {
                'JUPYTER_CONFIG_DIR': self.config_dir,
                'JUPYTER_DATA_DIR': self.data_dir,
            })
        self.patch_env.start()
Example #12
0
 def test_overwrite_broken_symlink(self):
     with TemporaryDirectory() as d:
         f = u'ƒ.js'
         f2 = u'ƒ2.js'
         src = pjoin(d, f)
         src2 = pjoin(d, f2)
         touch(src)
         install_nbextension(src, symlink=True)
         os.rename(src, src2)
         install_nbextension(src2,
                             symlink=True,
                             overwrite=True,
                             destination=f)
     dest = pjoin(self.system_nbext, f)
     assert os.path.islink(dest)
     link = os.readlink(dest)
     self.assertEqual(link, src2)
    def test_dynamic_updates(self):
        app = self.app  # Get the actual EnterpriseGatewayApp instance
        s1 = time.time()
        name = app.config_file_name + '.py'
        with TemporaryDirectory('_1') as td1:
            os.environ['JUPYTER_CONFIG_DIR'] = td1
            config_file = pjoin(td1, name)
            with open(config_file, 'w') as f:
                f.writelines([
                    "c.EnterpriseGatewayApp.impersonation_enabled = False\n",
                    "c.AsyncMappingKernelManager.cull_connected = False\n"
                ])
            #  app.jupyter_path.append(td1)
            app.load_config_file()
            app.add_dynamic_configurable("EnterpriseGatewayApp", app)
            app.add_dynamic_configurable("RemoteMappingKernelManager",
                                         app.kernel_manager)
            with self.assertRaises(RuntimeError):
                app.add_dynamic_configurable("Bogus", app.log)

            self.assertEqual(app.impersonation_enabled, False)
            self.assertEqual(app.kernel_manager.cull_connected, False)

            # Ensure file update doesn't happen during same second as initial value.
            # This is necessary on test systems that don't have finer-grained
            # timestamps (of less than a second).
            s2 = time.time()
            if s2 - s1 < 1.0:
                time.sleep(1.0 - (s2 - s1))
            # update config file
            with open(config_file, 'w') as f:
                f.writelines([
                    "c.EnterpriseGatewayApp.impersonation_enabled = True\n",
                    "c.AsyncMappingKernelManager.cull_connected = True\n"
                ])

            # trigger reload and verify updates
            app.update_dynamic_configurables()
            self.assertEqual(app.impersonation_enabled, True)
            self.assertEqual(app.kernel_manager.cull_connected, True)

            # repeat to ensure no unexpected changes occurred
            app.update_dynamic_configurables()
            self.assertEqual(app.impersonation_enabled, True)
            self.assertEqual(app.kernel_manager.cull_connected, True)
Example #14
0
    def test_good_symlink(self):
        with TemporaryDirectory() as td:
            cm = FileContentsManager(root_dir=td)
            parent = 'test good symlink'
            name = 'good symlink'
            path = '{0}/{1}'.format(parent, name)
            _make_dir(cm, parent)

            file_model = cm.new(path=parent + '/zfoo.txt')

            # create a good symlink
            self.symlink(cm, file_model['path'], path)
            symlink_model = cm.get(path, content=False)
            dir_model = cm.get(parent)
            self.assertEqual(
                sorted(dir_model['content'], key=lambda x: x['name']),
                [symlink_model, file_model],
            )
Example #15
0
    def check_handler_with_file(self, inpath, handler):
        shell = self.shell
        configname = '{0}_image_handler'.format(handler)
        funcname = 'handle_image_{0}'.format(handler)

        assert hasattr(shell, configname)
        assert hasattr(shell, funcname)

        with TemporaryDirectory() as tmpdir:
            outpath = os.path.join(tmpdir, 'data')
            cmd = [sys.executable, SCRIPT_PATH, inpath, outpath]
            setattr(shell, configname, cmd)
            getattr(shell, funcname)(self.data, self.mime)
            # cmd is called and file is closed.  So it's safe to open now.
            with open(outpath, 'rb') as file:
                transferred = file.read()

        self.assertEqual(transferred, self.raw)
Example #16
0
    def test_recursive_symlink(self):
        with TemporaryDirectory() as td:
            cm = FileContentsManager(root_dir=td)
            path = 'test recursive symlink'
            _make_dir(cm, path)
            os_path = cm._get_os_path(path)
            os.symlink("recursive", os.path.join(os_path, "recursive"))
            file_model = cm.new_untitled(path=path, ext='.txt')

            model = cm.get(path)

            contents = {
                content['name']: content for content in model['content']
            }
            self.assertIn('untitled.txt', contents)
            self.assertEqual(contents['untitled.txt'], file_model)
            # recursive symlinks should not be shown in the contents manager
            self.assertNotIn('recursive', contents)
Example #17
0
 def test_log_collisions(self):
     app = MyApp()
     app.log = logging.getLogger()
     app.log.setLevel(logging.INFO)
     name = 'config'
     with TemporaryDirectory('_1') as td:
         with open(pjoin(td, name + '.py'), 'w') as f:
             f.write("get_config().Bar.b = 1")
         with open(pjoin(td, name + '.json'), 'w') as f:
             json.dump({'Bar': {'b': 2}}, f)
         with self.assertLogs(app.log, logging.WARNING) as captured:
             app.load_config_file(name, path=[td])
             app.init_bar()
     assert app.bar.b == 2
     output = '\n'.join(captured.output)
     assert 'Collision' in output
     assert '1 ignored, using 2' in output
     assert pjoin(td, name + '.py') in output
     assert pjoin(td, name + '.json') in output
Example #18
0
def test_find_connection_file():
    with TemporaryDirectory() as d:
        cf = 'kernel.json'
        app = DummyConsoleApp(runtime_dir=d, connection_file=cf)
        app.initialize()

        security_dir = app.runtime_dir
        profile_cf = os.path.join(security_dir, cf)

        with open(profile_cf, 'w') as f:
            f.write("{}")

        for query in (
            'kernel.json',
            'kern*',
            '*ernel*',
            'k*',
            ):
            assert connect.find_connection_file(query, path=security_dir) == profile_cf
Example #19
0
    def test_bad_symlink(self):
        with TemporaryDirectory() as td:
            cm = FileContentsManager(root_dir=td)
            path = 'test bad symlink'
            _make_dir(cm, path)

            file_model = cm.new_untitled(path=path, ext='.txt')

            # create a broken symlink
            self.symlink(cm, "target", '%s/%s' % (path, 'bad symlink'))
            model = cm.get(path)

            contents = {
                content['name']: content for content in model['content']
            }
            self.assertTrue('untitled.txt' in contents)
            self.assertEqual(contents['untitled.txt'], file_model)
            # broken symlinks should still be shown in the contents manager
            self.assertTrue('bad symlink' in contents)
Example #20
0
    def from_notebook_node(self, nb, resources=None, **kw):
        if not hasattr(self, "_ipynb_file"):
            self._ipynb_file = None
        url_root = "http://{}".format("localhost:{}".format(self.port))
        output_root = Path(resources["output_files_dir"])
        lab_path = self.lab_path()
        static_path = Path(notebook.__file__).parent / "static"
        nb_names = [
            resources["metadata"]["name"]
        ] + [
            str(ef)[:-6] for ef in self.extra_files
            if ef.name.endswith('.ipynb')
        ]

        urls = [
            "lab"
        ] + [
            "api/contents/{}.ipynb".format(nb_name)
            for nb_name in nb_names
        ] + [
            "api/contents/{}".format(ef)
            for ef in self.extra_files
            if not ef.name.endswith(".ipynb")
        ] + self.extra_urls

        with TemporaryDirectory() as tmpdir:
            urls += list(self.prepare_contents(tmpdir))
            urls += list(self.prepare_notebooks(tmpdir, nb, nb_names))
            self.fetch_all(tmpdir, url_root, urls, resources)

        self.copy_assets(output_root, lab_path, static_path)
        self.fix_urls(output_root, nb_names)
        self.fake_apis(output_root)
        self.fake_home(output_root)

        langinfo = nb.metadata.get('language_info', {})
        lexer = langinfo.get('pygments_lexer', langinfo.get('name', None))
        self.register_filter('highlight_code',
                             Highlight2HTML(pygments_lexer=lexer, parent=self))

        return super(HTMLExporter, self).from_notebook_node(
            nb, resources, **kw)
Example #21
0
    def test_get_os_path(self):
        # full filesystem path should be returned with correct operating system
        # separators.
        with TemporaryDirectory() as td:
            root = td
            fm = FileContentsManager(root_dir=root)
            path = fm._get_os_path('/path/to/notebook/test.ipynb')
            rel_path_list =  '/path/to/notebook/test.ipynb'.split('/')
            fs_path = os.path.join(fm.root_dir, *rel_path_list)
            self.assertEqual(path, fs_path)

            fm = FileContentsManager(root_dir=root)
            path = fm._get_os_path('test.ipynb')
            fs_path = os.path.join(fm.root_dir, 'test.ipynb')
            self.assertEqual(path, fs_path)

            fm = FileContentsManager(root_dir=root)
            path = fm._get_os_path('////test.ipynb')
            fs_path = os.path.join(fm.root_dir, 'test.ipynb')
            self.assertEqual(path, fs_path)
Example #22
0
    def test_403(self):
        if hasattr(os, 'getuid'):
            if os.getuid() == 0:
                raise SkipTest("Can't test permissions as root")
        if sys.platform.startswith('win'):
            raise SkipTest("Can't test permissions on Windows")

        with TemporaryDirectory() as td:
            cm = FileContentsManager(root_dir=td)
            model = cm.new_untitled(type='file')
            os_path = cm._get_os_path(model['path'])

            os.chmod(os_path, 0o400)
            try:
                with cm.open(os_path, 'w') as f:
                    f.write(u"don't care")
            except HTTPError as e:
                self.assertEqual(e.status_code, 403)
            else:
                self.fail("Should have raised HTTPError(403)")
Example #23
0
    def install_extension(self, extension, existing=None):
        """Install an extension package into JupyterLab.

        The extension is first validated.
        """
        extension = _normalize_path(extension)
        extensions = self.info['extensions']

        # Check for a core extensions.
        if extension in self.info['core_extensions']:
            config = self._read_build_config()
            uninstalled = config.get('uninstalled_core_extensions', [])
            if extension in uninstalled:
                uninstalled.remove(extension)
                config['uninstalled_core_extensions'] = uninstalled
                self._write_build_config(config)
            return

        # Create the app dirs if needed.
        self._ensure_app_dirs()

        # Install the package using a temporary directory.
        with TemporaryDirectory() as tempdir:
            info = self._install_extension(extension, tempdir)

        name = info['name']

        # Local directories get name mangled and stored in metadata.
        if info['is_dir']:
            config = self._read_build_config()
            local = config.setdefault('local_extensions', dict())
            local[name] = info['source']
            self._write_build_config(config)

        # Remove an existing extension with the same name and different path
        if name in extensions:
            other = extensions[name]
            if other['path'] != info['path'] and other['location'] == 'app':
                os.remove(other['path'])

        return True
Example #24
0
    def _update_local(self, name, source, dname, data, dtype):
        """Update a local dependency.  Return `True` if changed.
        """
        # Extract the package in a temporary directory.
        existing = data['filename']
        with TemporaryDirectory() as tempdir:
            info = self._extract_package(source, tempdir)

            # Bail if the file content has not changed.
            if info['filename'] == existing:
                return existing

            shutil.move(info['path'], pjoin(dname, info['filename']))

        # Remove the existing tarball and return the new file name.
        if existing:
            os.remove(pjoin(dname, existing))

        data['filename'] = info['filename']
        data['path'] = pjoin(data['tar_dir'], data['filename'])
        return info['filename']
def test_is_hidden():
    with TemporaryDirectory() as root:
        subdir1 = os.path.join(root, 'subdir')
        os.makedirs(subdir1)
        nt.assert_equal(is_hidden(subdir1, root), False)
        nt.assert_equal(is_file_hidden(subdir1), False)
        subdir2 = os.path.join(root, '.subdir2')
        os.makedirs(subdir2)
        nt.assert_equal(is_hidden(subdir2, root), True)
        nt.assert_equal(is_file_hidden(subdir2), True)
        subdir34 = os.path.join(root, 'subdir3', '.subdir4')
        os.makedirs(subdir34)
        nt.assert_equal(is_hidden(subdir34, root), True)
        nt.assert_equal(is_hidden(subdir34), True)

        subdir56 = os.path.join(root, '.subdir5', 'subdir6')
        os.makedirs(subdir56)
        nt.assert_equal(is_hidden(subdir56, root), True)
        nt.assert_equal(is_hidden(subdir56), True)
        nt.assert_equal(is_file_hidden(subdir56), False)
        nt.assert_equal(is_file_hidden(subdir56, os.stat(subdir56)), False)
Example #26
0
def test_find_connection_file():
    cfg = Config()
    with TemporaryDirectory() as d:
        cfg.ProfileDir.location = d
        cf = 'kernel.json'
        app = DummyConsoleApp(config=cfg, connection_file=cf)
        app.initialize()

        security_dir = app.runtime_dir
        profile_cf = os.path.join(security_dir, cf)

        with open(profile_cf, 'w') as f:
            f.write("{}")

        for query in (
            'kernel.json',
            'kern*',
            '*ernel*',
            'k*',
            ):
            nt.assert_equal(connect.find_connection_file(query, path=security_dir), profile_cf)

        JupyterApp._instance = None
Example #27
0
    def test_escape_root(self):
        with TemporaryDirectory() as td:
            cm = FileContentsManager(root_dir=td)
            # make foo, bar next to root
            with open(os.path.join(cm.root_dir, '..', 'foo'), 'w') as f:
                f.write('foo')
            with open(os.path.join(cm.root_dir, '..', 'bar'), 'w') as f:
                f.write('bar')

            with self.assertRaisesHTTPError(404):
                cm.get('..')
            with self.assertRaisesHTTPError(404):
                cm.get('foo/../../../bar')
            with self.assertRaisesHTTPError(404):
                cm.delete('../foo')
            with self.assertRaisesHTTPError(404):
                cm.rename('../foo', '../bar')
            with self.assertRaisesHTTPError(404):
                cm.save(model={
                    'type': 'file',
                    'content': u'',
                    'format': 'text',
                }, path='../foo')
Example #28
0
def test_server_info_file():
    import threading, tornado.ioloop as iom, tornado.platform.asyncio as torio
    td = TemporaryDirectory()

    if iom.asyncio is not None:
        iom.asyncio.set_event_loop_policy(torio.AnyThreadEventLoopPolicy())
        iom.IOLoop.configure("tornado.platform.asyncio.AsyncIOLoop")

    nbapp = NotebookApp(runtime_dir=td.name, log=logging.getLogger())
    nbapp.initialize(argv=[])
    nbapp.io_loop = iom.IOLoop.current()
    nbapp.open_browser = False
    super(NotebookApp, nbapp).start()
    nbapp.write_server_info_file()

    def check_thread():
        try:
            servers = list(notebookapp.list_running_servers(nbapp.runtime_dir))
            nt.assert_equal(len(servers), 1)
            nt.assert_equal(servers[0]['port'], nbapp.port)
            nt.assert_equal(servers[0]['url'], nbapp.connection_url)
        finally:
            nbapp.stop()

    nbapp.io_loop.add_callback(nbapp.io_loop.run_in_executor,
                               executor=None,
                               func=check_thread)

    if sys.platform.startswith("win"):
        pc = iom.PeriodicCallback(lambda: None, 5000)
        pc.start()
    try:
        nbapp.io_loop.start()
    except KeyboardInterrupt:
        print("Interrupted...")
    finally:
        nbapp.remove_server_info_file()
Example #29
0
    def test_loaded_config_files(self):
        app = MyApp()
        app.log = logging.getLogger()
        name = 'config.py'
        with TemporaryDirectory('_1') as td1:
            config_file = pjoin(td1, name)
            with open(config_file, 'w') as f:
                f.writelines(["c.MyApp.running = True\n"])

            app.load_config_file(name, path=[td1])
            self.assertEqual(len(app.loaded_config_files), 1)
            self.assertEquals(app.loaded_config_files[0], config_file)

            app.start()
            self.assertEqual(app.running, True)

            # emulate an app that allows dynamic updates and update config file
            with open(config_file, 'w') as f:
                f.writelines(["c.MyApp.running = False\n"])

            # reload and verify update, and that loaded_configs was not increased
            app.load_config_file(name, path=[td1])
            self.assertEqual(len(app.loaded_config_files), 1)
            self.assertEqual(app.running, False)

            # Attempt to update, ensure error...
            with self.assertRaises(AttributeError):
                app.loaded_config_files = "/foo"

            # ensure it can't be udpated via append
            app.loaded_config_files.append("/bar")
            self.assertEqual(len(app.loaded_config_files), 1)

            # repeat to ensure no unexpected changes occurred
            app.load_config_file(name, path=[td1])
            self.assertEqual(len(app.loaded_config_files), 1)
            self.assertEqual(app.running, False)
Example #30
0
    def test_ipython_cli_priority(self):
        # this test is almost entirely redundant with above,
        # but we can keep it around in case of subtle issues creeping into
        # the exact sequence IPython follows.
        name = 'config.py'

        class TestApp(Application):
            value = Unicode().tag(config=True)
            config_file_loaded = Bool().tag(config=True)
            aliases = {'v': 'TestApp.value'}

        app = TestApp()
        with TemporaryDirectory() as td:
            config_file = pjoin(td, name)
            with open(config_file, 'w') as f:
                f.writelines([
                    "c.TestApp.value = 'config file'\n",
                    "c.TestApp.config_file_loaded = True\n"
                ])
            # follow IPython's config-loading sequence to ensure CLI priority is preserved
            app.parse_command_line(['--v=cli'])
            # this is where IPython makes a mistake:
            # it assumes app.config will not be modified,
            # and storing a reference is storing a copy
            cli_config = app.config
            assert 'value' in app.config.TestApp
            assert app.config.TestApp.value == 'cli'
            assert app.value == 'cli'
            app.load_config_file(name, path=[td])
            assert app.config_file_loaded
            # enforce cl-opts override config file opts:
            # this is where IPython makes a mistake: it assumes
            # that cl_config is a different object, but it isn't.
            app.update_config(cli_config)
            assert app.config.TestApp.value == 'cli'
            assert app.value == 'cli'
Example #31
0
 def setUp(self):
     self._temp_dir = TemporaryDirectory()
     self.td = self._temp_dir.name
     self.contents_manager = FileContentsManager(
         root_dir=self.td,
     )
Example #32
0
class TestContentsManager(TestCase):
    @contextmanager
    def assertRaisesHTTPError(self, status, msg=None):
        msg = msg or "Should have raised HTTPError(%i)" % status
        try:
            yield
        except HTTPError as e:
            self.assertEqual(e.status_code, status)
        else:
            self.fail(msg)

    def make_populated_dir(self, api_path):
        cm = self.contents_manager

        self.make_dir(api_path)

        cm.new(path="/".join([api_path, "nb.ipynb"]))
        cm.new(path="/".join([api_path, "file.txt"]))

    def check_populated_dir_files(self, api_path):
        dir_model = self.contents_manager.get(api_path)

        self.assertEqual(dir_model['path'], api_path)
        self.assertEqual(dir_model['type'], "directory")

        for entry in dir_model['content']:
            if entry['type'] == "directory":
                continue
            elif entry['type'] == "file":
                self.assertEqual(entry['name'], "file.txt")
                complete_path = "/".join([api_path, "file.txt"])
                self.assertEqual(entry["path"], complete_path)
            elif entry['type'] == "notebook":
                self.assertEqual(entry['name'], "nb.ipynb")
                complete_path = "/".join([api_path, "nb.ipynb"])
                self.assertEqual(entry["path"], complete_path)

    def setUp(self):
        self._temp_dir = TemporaryDirectory()
        self.td = self._temp_dir.name
        self.contents_manager = FileContentsManager(
            root_dir=self.td,
        )

    def tearDown(self):
        self._temp_dir.cleanup()

    def make_dir(self, api_path):
        """make a subdirectory at api_path

        override in subclasses if contents are not on the filesystem.
        """
        _make_dir(self.contents_manager, api_path)

    def add_code_cell(self, nb):
        output = nbformat.new_output("display_data", {'application/javascript': "alert('hi');"})
        cell = nbformat.new_code_cell("print('hi')", outputs=[output])
        nb.cells.append(cell)

    def new_notebook(self):
        cm = self.contents_manager
        model = cm.new_untitled(type='notebook')
        name = model['name']
        path = model['path']

        full_model = cm.get(path)
        nb = full_model['content']
        nb['metadata']['counter'] = int(1e6 * time.time())
        self.add_code_cell(nb)

        cm.save(full_model, path)
        return nb, name, path

    def test_new_untitled(self):
        cm = self.contents_manager
        # Test in root directory
        model = cm.new_untitled(type='notebook')
        assert isinstance(model, dict)
        self.assertIn('name', model)
        self.assertIn('path', model)
        self.assertIn('type', model)
        self.assertEqual(model['type'], 'notebook')
        self.assertEqual(model['name'], 'Untitled.ipynb')
        self.assertEqual(model['path'], 'Untitled.ipynb')

        # Test in sub-directory
        model = cm.new_untitled(type='directory')
        assert isinstance(model, dict)
        self.assertIn('name', model)
        self.assertIn('path', model)
        self.assertIn('type', model)
        self.assertEqual(model['type'], 'directory')
        self.assertEqual(model['name'], 'Untitled Folder')
        self.assertEqual(model['path'], 'Untitled Folder')
        sub_dir = model['path']

        model = cm.new_untitled(path=sub_dir)
        assert isinstance(model, dict)
        self.assertIn('name', model)
        self.assertIn('path', model)
        self.assertIn('type', model)
        self.assertEqual(model['type'], 'file')
        self.assertEqual(model['name'], 'untitled')
        self.assertEqual(model['path'], '%s/untitled' % sub_dir)

        # Test with a compound extension
        model = cm.new_untitled(path=sub_dir, ext='.foo.bar')
        self.assertEqual(model['name'], 'untitled.foo.bar')
        model = cm.new_untitled(path=sub_dir, ext='.foo.bar')
        self.assertEqual(model['name'], 'untitled1.foo.bar')

    def test_modified_date(self):

        cm = self.contents_manager

        # Create a new notebook.
        nb, name, path = self.new_notebook()
        model = cm.get(path)

        # Add a cell and save.
        self.add_code_cell(model['content'])
        cm.save(model, path)

        # Reload notebook and verify that last_modified incremented.
        saved = cm.get(path)
        self.assertGreaterEqual(saved['last_modified'], model['last_modified'])

        # Move the notebook and verify that last_modified stayed the same.
        # (The frontend fires a warning if last_modified increases on the
        # renamed file.)
        new_path = 'renamed.ipynb'
        cm.rename(path, new_path)
        renamed = cm.get(new_path)
        self.assertGreaterEqual(
            renamed['last_modified'],
            saved['last_modified'],
        )

    def test_get(self):
        cm = self.contents_manager
        # Create a notebook
        model = cm.new_untitled(type='notebook')
        name = model['name']
        path = model['path']

        # Check that we 'get' on the notebook we just created
        model2 = cm.get(path)
        assert isinstance(model2, dict)
        self.assertIn('name', model2)
        self.assertIn('path', model2)
        self.assertEqual(model['name'], name)
        self.assertEqual(model['path'], path)

        nb_as_file = cm.get(path, content=True, type='file')
        self.assertEqual(nb_as_file['path'], path)
        self.assertEqual(nb_as_file['type'], 'file')
        self.assertEqual(nb_as_file['format'], 'text')
        self.assertNotIsInstance(nb_as_file['content'], dict)

        nb_as_bin_file = cm.get(path, content=True, type='file', format='base64')
        self.assertEqual(nb_as_bin_file['format'], 'base64')

        # Test in sub-directory
        sub_dir = '/foo/'
        self.make_dir('foo')
        model = cm.new_untitled(path=sub_dir, ext='.ipynb')
        model2 = cm.get(sub_dir + name)
        assert isinstance(model2, dict)
        self.assertIn('name', model2)
        self.assertIn('path', model2)
        self.assertIn('content', model2)
        self.assertEqual(model2['name'], 'Untitled.ipynb')
        self.assertEqual(model2['path'], '{0}/{1}'.format(sub_dir.strip('/'), name))

        # Test with a regular file.
        file_model_path = cm.new_untitled(path=sub_dir, ext='.txt')['path']
        file_model = cm.get(file_model_path)
        self.assertDictContainsSubset(
            {
                'content': u'',
                'format': u'text',
                'mimetype': u'text/plain',
                'name': u'untitled.txt',
                'path': u'foo/untitled.txt',
                'type': u'file',
                'writable': True,
            },
            file_model,
        )
        self.assertIn('created', file_model)
        self.assertIn('last_modified', file_model)

        # Test getting directory model

        # Create a sub-sub directory to test getting directory contents with a
        # subdir.
        self.make_dir('foo/bar')
        dirmodel = cm.get('foo')
        self.assertEqual(dirmodel['type'], 'directory')
        self.assertIsInstance(dirmodel['content'], list)
        self.assertEqual(len(dirmodel['content']), 3)
        self.assertEqual(dirmodel['path'], 'foo')
        self.assertEqual(dirmodel['name'], 'foo')

        # Directory contents should match the contents of each individual entry
        # when requested with content=False.
        model2_no_content = cm.get(sub_dir + name, content=False)
        file_model_no_content = cm.get(u'foo/untitled.txt', content=False)
        sub_sub_dir_no_content = cm.get('foo/bar', content=False)
        self.assertEqual(sub_sub_dir_no_content['path'], 'foo/bar')
        self.assertEqual(sub_sub_dir_no_content['name'], 'bar')

        for entry in dirmodel['content']:
            # Order isn't guaranteed by the spec, so this is a hacky way of
            # verifying that all entries are matched.
            if entry['path'] == sub_sub_dir_no_content['path']:
                self.assertEqual(entry, sub_sub_dir_no_content)
            elif entry['path'] == model2_no_content['path']:
                self.assertEqual(entry, model2_no_content)
            elif entry['path'] == file_model_no_content['path']:
                self.assertEqual(entry, file_model_no_content)
            else:
                self.fail("Unexpected directory entry: %s" % entry())

        with self.assertRaises(HTTPError):
            cm.get('foo', type='file')

    def test_update(self):
        cm = self.contents_manager
        # Create a notebook
        model = cm.new_untitled(type='notebook')
        name = model['name']
        path = model['path']

        # Change the name in the model for rename
        model['path'] = 'test.ipynb'
        model = cm.update(model, path)
        assert isinstance(model, dict)
        self.assertIn('name', model)
        self.assertIn('path', model)
        self.assertEqual(model['name'], 'test.ipynb')

        # Make sure the old name is gone
        self.assertRaises(HTTPError, cm.get, path)

        # Test in sub-directory
        # Create a directory and notebook in that directory
        sub_dir = '/foo/'
        self.make_dir('foo')
        model = cm.new_untitled(path=sub_dir, type='notebook')
        path = model['path']

        # Change the name in the model for rename
        d = path.rsplit('/', 1)[0]
        new_path = model['path'] = d + '/test_in_sub.ipynb'
        model = cm.update(model, path)
        assert isinstance(model, dict)
        self.assertIn('name', model)
        self.assertIn('path', model)
        self.assertEqual(model['name'], 'test_in_sub.ipynb')
        self.assertEqual(model['path'], new_path)

        # Make sure the old name is gone
        self.assertRaises(HTTPError, cm.get, path)

    def test_save(self):
        cm = self.contents_manager
        # Create a notebook
        model = cm.new_untitled(type='notebook')
        name = model['name']
        path = model['path']

        # Get the model with 'content'
        full_model = cm.get(path)

        # Save the notebook
        model = cm.save(full_model, path)
        assert isinstance(model, dict)
        self.assertIn('name', model)
        self.assertIn('path', model)
        self.assertEqual(model['name'], name)
        self.assertEqual(model['path'], path)

        # Test in sub-directory
        # Create a directory and notebook in that directory
        sub_dir = '/foo/'
        self.make_dir('foo')
        model = cm.new_untitled(path=sub_dir, type='notebook')
        name = model['name']
        path = model['path']
        model = cm.get(path)

        # Change the name in the model for rename
        model = cm.save(model, path)
        assert isinstance(model, dict)
        self.assertIn('name', model)
        self.assertIn('path', model)
        self.assertEqual(model['name'], 'Untitled.ipynb')
        self.assertEqual(model['path'], 'foo/Untitled.ipynb')

    def test_delete(self):
        cm = self.contents_manager
        # Create a notebook
        nb, name, path = self.new_notebook()

        # Delete the notebook
        cm.delete(path)

        # Check that deleting a non-existent path raises an error.
        self.assertRaises(HTTPError, cm.delete, path)

        # Check that a 'get' on the deleted notebook raises and error
        self.assertRaises(HTTPError, cm.get, path)

    def test_rename(self):
        cm = self.contents_manager
        # Create a new notebook
        nb, name, path = self.new_notebook()

        # Rename the notebook
        cm.rename(path, "changed_path")

        # Attempting to get the notebook under the old name raises an error
        self.assertRaises(HTTPError, cm.get, path)
        # Fetching the notebook under the new name is successful
        assert isinstance(cm.get("changed_path"), dict)

        # Ported tests on nested directory renaming from pgcontents
        all_dirs = ['foo', 'bar', 'foo/bar', 'foo/bar/foo', 'foo/bar/foo/bar']
        unchanged_dirs = all_dirs[:2]
        changed_dirs = all_dirs[2:]

        for _dir in all_dirs:
            self.make_populated_dir(_dir)
            self.check_populated_dir_files(_dir)

        # Renaming to an existing directory should fail
        for src, dest in combinations(all_dirs, 2):
            with self.assertRaisesHTTPError(409):
                cm.rename(src, dest)

        # Creating a notebook in a non_existant directory should fail
        with self.assertRaisesHTTPError(404):
            cm.new_untitled("foo/bar_diff", ext=".ipynb")

        cm.rename("foo/bar", "foo/bar_diff")

        # Assert that unchanged directories remain so
        for unchanged in unchanged_dirs:
            self.check_populated_dir_files(unchanged)

        # Assert changed directories can no longer be accessed under old names
        for changed_dirname in changed_dirs:
            with self.assertRaisesHTTPError(404):
                cm.get(changed_dirname)

            new_dirname = changed_dirname.replace("foo/bar", "foo/bar_diff", 1)

            self.check_populated_dir_files(new_dirname)

        # Created a notebook in the renamed directory should work
        cm.new_untitled("foo/bar_diff", ext=".ipynb")

    def test_delete_root(self):
        cm = self.contents_manager
        with self.assertRaises(HTTPError) as err:
            cm.delete('')
        self.assertEqual(err.exception.status_code, 400)

    def test_copy(self):
        cm = self.contents_manager
        parent = u'å b'
        name = u'nb √.ipynb'
        path = u'{0}/{1}'.format(parent, name)
        self.make_dir(parent)

        orig = cm.new(path=path)
        # copy with unspecified name
        copy = cm.copy(path)
        self.assertEqual(copy['name'], orig['name'].replace('.ipynb', '-Copy1.ipynb'))

        # copy with specified name
        copy2 = cm.copy(path, u'å b/copy 2.ipynb')
        self.assertEqual(copy2['name'], u'copy 2.ipynb')
        self.assertEqual(copy2['path'], u'å b/copy 2.ipynb')
        # copy with specified path
        copy2 = cm.copy(path, u'/')
        self.assertEqual(copy2['name'], name)
        self.assertEqual(copy2['path'], name)

    def test_trust_notebook(self):
        cm = self.contents_manager
        nb, name, path = self.new_notebook()

        untrusted = cm.get(path)['content']
        assert not cm.notary.check_cells(untrusted)

        # print(untrusted)
        cm.trust_notebook(path)
        trusted = cm.get(path)['content']
        # print(trusted)
        assert cm.notary.check_cells(trusted)

    def test_mark_trusted_cells(self):
        cm = self.contents_manager
        nb, name, path = self.new_notebook()

        cm.mark_trusted_cells(nb, path)
        for cell in nb.cells:
            if cell.cell_type == 'code':
                assert not cell.metadata.trusted

        cm.trust_notebook(path)
        nb = cm.get(path)['content']
        for cell in nb.cells:
            if cell.cell_type == 'code':
                assert cell.metadata.trusted

    def test_check_and_sign(self):
        cm = self.contents_manager
        nb, name, path = self.new_notebook()

        cm.mark_trusted_cells(nb, path)
        cm.check_and_sign(nb, path)
        assert not cm.notary.check_signature(nb)

        cm.trust_notebook(path)
        nb = cm.get(path)['content']
        cm.mark_trusted_cells(nb, path)
        cm.check_and_sign(nb, path)
        assert cm.notary.check_signature(nb)