def test_add_app_exists(self, mock_labbook): """Test adding an app that already exists (update it)""" bam = BundledAppManager(mock_labbook[2]) assert os.path.exists(bam.bundled_app_file) is False result = bam.add_bundled_app(8050, 'dash 1', 'a demo dash app', 'python app.py') assert os.path.exists(bam.bundled_app_file) is True assert 'dash 1' in result assert result['dash 1']['port'] == 8050 assert result['dash 1']['description'] == 'a demo dash app' assert result['dash 1']['command'] == 'python app.py' result2 = bam.add_bundled_app(9000, 'dash 1', 'updated demo dash app', 'python app.py') assert 'dash 1' in result assert result2['dash 1']['port'] == 9000 assert result2['dash 1']['description'] == 'updated demo dash app' assert result2['dash 1']['command'] == 'python app.py' loaded_apps = bam.get_bundled_apps() assert result2 != result assert result2 == loaded_apps
def test_invalid_props(self, mock_labbook): """Test creating an app with invalid props""" bam = BundledAppManager(mock_labbook[2]) with pytest.raises(ValueError): bam.add_bundled_app(8050, 'dash 1', '12345' * 100, 'python app.py') with pytest.raises(ValueError): bam.add_bundled_app(8050, 'dash 1', 'a demo dash app', 'python app.py' * 100)
def test_start_bundled_app(self, fixture_working_dir_env_repo_scoped, snapshot): """Test listing labbooks""" im = InventoryManager(fixture_working_dir_env_repo_scoped[0]) lb = im.create_labbook('default', 'default', 'test-app-1', description="testing 1") bam = BundledAppManager(lb) bam.add_bundled_app(9999, "dash app 1", "my example bundled app 1", "echo test") lookup_query = """ { labbook(owner: "default", name: "test-app-1"){ id environment { id bundledApps{ id appName description port command } } } } """ snapshot.assert_match( fixture_working_dir_env_repo_scoped[2].execute(lookup_query)) # Add a bundled app remove_query = """ mutation startDevTool { removeBundledApp (input: { owner: "default", labbookName: "test-app-1", appName: "dash app 2"}) { clientMutationId environment{ id bundledApps{ id appName description port command } } } } """ snapshot.assert_match( fixture_working_dir_env_repo_scoped[2].execute(remove_query))
def mutate_and_get_payload(cls, root, info, owner, labbook_name, app_name, description, port, command=None, client_mutation_id=None): username = get_logged_in_username() lb = InventoryManager().load_labbook(username, owner, labbook_name, author=get_logged_in_author()) bam = BundledAppManager(lb) with lb.lock(): bam.add_bundled_app(port, app_name, description, command) return SetBundledApp( environment=Environment(name=labbook_name, owner=owner))
def test_start_bundled_app(self, build_lb_image_for_jupyterlab): test_file_path = os.path.join('/mnt', 'share', 'test.txt') try: lb = build_lb_image_for_jupyterlab[0] assert os.path.exists(test_file_path) is False bam = BundledAppManager(lb) bam.add_bundled_app(9002, 'my app', 'tester', f"echo 'teststr' >> {test_file_path}") apps = bam.get_bundled_apps() start_bundled_app(lb, 'unittester', apps['my app']['command']) time.sleep(3) assert os.path.exists(test_file_path) is True except: raise finally: if os.path.exists(test_file_path): os.remove(test_file_path)
def test_bundled_app_lines(self, mock_labbook): """Test if the Dockerfile builds with bundled app ports""" lb = mock_labbook[2] bam = BundledAppManager(lb) bam.add_bundled_app(8050, 'dash 1', 'a demo dash app 1', 'python app1.py') bam.add_bundled_app(9000, 'dash 2', 'a demo dash app 2', 'python app2.py') bam.add_bundled_app(9001, 'dash 3', 'a demo dash app 3', 'python app3.py') erm = RepositoryManager(mock_labbook[0]) erm.update_repositories() erm.index_repositories() cm = ComponentManager(lb) cm.add_base(ENV_UNIT_TEST_REPO, ENV_UNIT_TEST_BASE, ENV_UNIT_TEST_REV) cm.add_packages("pip", [{ "manager": "pip", "package": "requests", "version": "2.18.4" }]) ib = ImageBuilder(lb) dockerfile_text = ib.assemble_dockerfile(write=False) test_lines = [ '# Bundled Application Ports', 'EXPOSE 8050', 'EXPOSE 9000', 'EXPOSE 9001' ] docker_lines = dockerfile_text.split(os.linesep) for line in test_lines: assert line in docker_lines
def test_remove_app(self, mock_labbook): """Test removing a bundled app""" bam = BundledAppManager(mock_labbook[2]) assert os.path.exists(bam.bundled_app_file) is False bam.add_bundled_app(8050, 'dash 1', 'a demo dash app 1', 'python app1.py') bam.add_bundled_app(9000, 'dash 2', 'a demo dash app 2', 'python app2.py') bam.add_bundled_app(9001, 'dash 3', 'a demo dash app 3', 'python app3.py') apps = bam.get_bundled_apps() assert os.path.exists(bam.bundled_app_file) is True assert 'dash 1' in apps assert apps['dash 1']['port'] == 8050 assert apps['dash 1']['description'] == 'a demo dash app 1' assert apps['dash 1']['command'] == 'python app1.py' assert 'dash 2' in apps assert apps['dash 2']['port'] == 9000 assert apps['dash 2']['description'] == 'a demo dash app 2' assert apps['dash 2']['command'] == 'python app2.py' assert 'dash 3' in apps assert apps['dash 3']['port'] == 9001 assert apps['dash 3']['description'] == 'a demo dash app 3' assert apps['dash 3']['command'] == 'python app3.py' bam.remove_bundled_app('dash 2') apps = bam.get_bundled_apps() assert 'dash 1' in apps assert 'dash 2' not in apps assert 'dash 3' in apps bam.remove_bundled_app('dash 3') apps = bam.get_bundled_apps() assert 'dash 1' in apps assert 'dash 2' not in apps assert 'dash 3' not in apps bam.remove_bundled_app('dash 1') apps = bam.get_bundled_apps() assert len(apps.keys()) == 0 assert isinstance(apps, OrderedDict)
def test_get_docker_lines(self, mock_labbook): """Test getting docker lines""" bam = BundledAppManager(mock_labbook[2]) assert os.path.exists(bam.bundled_app_file) is False bam.add_bundled_app(8050, 'dash 1', 'a demo dash app 1', 'python app1.py') bam.add_bundled_app(9000, 'dash 2', 'a demo dash app 2', 'python app2.py') bam.add_bundled_app(9001, 'dash 3', 'a demo dash app 3', 'python app3.py') docker_lines = bam.get_docker_lines() assert docker_lines[0] == "EXPOSE 8050" assert docker_lines[1] == "EXPOSE 9000" assert docker_lines[2] == "EXPOSE 9001"
def test_bundle_app_query(self, snapshot, fixture_working_dir_env_repo_scoped): """Test querying for bundled app info""" im = InventoryManager(fixture_working_dir_env_repo_scoped[0]) lb = im.create_labbook("default", "default", "labbook-bundle", description="my first df") query = """ { labbook(owner: "default", name: "labbook-bundle"){ id environment { bundledApps{ id appName description port command } } } } """ snapshot.assert_match( fixture_working_dir_env_repo_scoped[2].execute(query)) bam = BundledAppManager(lb) bam.add_bundled_app(8050, 'dash 1', 'a demo dash app 1', 'python app1.py') bam.add_bundled_app(9000, 'dash 2', 'a demo dash app 2', 'python app2.py') bam.add_bundled_app(9001, 'dash 3', 'a demo dash app 3', 'python app3.py') snapshot.assert_match( fixture_working_dir_env_repo_scoped[2].execute(query))
def test_invalid_port(self, mock_labbook): """Test creating an app with invalid name""" bam = BundledAppManager(mock_labbook[2]) assert os.path.exists(bam.bundled_app_file) is False with pytest.raises(ValueError): bam.add_bundled_app(8888, 'myapp', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(8787, 'myapp', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(8686, 'myapp', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(8585, 'myapp', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(8484, 'myapp', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(8383, 'myapp', 'asdf', 'cmd') assert os.path.exists(bam.bundled_app_file) is False bam.add_bundled_app(8050, 'dash 1', 'a demo dash app', 'python app.py') assert os.path.exists(bam.bundled_app_file) is True with pytest.raises(ValueError): bam.add_bundled_app(8050, 'myapp', 'asdf', 'cmd')
def test_invalid_name(self, mock_labbook): """Test creating an app with invalid name""" bam = BundledAppManager(mock_labbook[2]) with pytest.raises(ValueError): bam.add_bundled_app(1000, '', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(1000, 'asdfghjklasdfghjhfdd', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(1000, 'jupyter', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(1000, 'notebook', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(1000, 'jupyterlab', 'asdf', 'cmd') with pytest.raises(ValueError): bam.add_bundled_app(1000, 'rstudio', 'asdf', 'cmd')
def test_remove_bundled_app(self, fixture_working_dir_env_repo_scoped, snapshot): """Test removing a bundled app from a labbook""" im = InventoryManager(fixture_working_dir_env_repo_scoped[0]) lb = im.create_labbook('default', 'default', 'test-app-2', description="testing 1") bam = BundledAppManager(lb) bam.add_bundled_app(9999, "dash app 1", "my example bundled app 1", "python /mnt/labbook/code/dash1.py") bam.add_bundled_app(8822, "dash app 2", "my example bundled app 2", "python /mnt/labbook/code/dash2.py") bam.add_bundled_app(9966, "dash app 3", "my example bundled app 3", "python /mnt/labbook/code/dash3.py") lookup_query = """ { labbook(owner: "default", name: "test-app-2"){ id environment { id bundledApps{ id appName description port command } } } } """ snapshot.assert_match( fixture_working_dir_env_repo_scoped[2].execute(lookup_query)) # Add a bundled app remove_query = """ mutation myBundledAppMutation { removeBundledApp (input: { owner: "default", labbookName: "test-app-2", appName: "dash app 2"}) { clientMutationId environment{ id bundledApps{ id appName description port command } } } } """ snapshot.assert_match( fixture_working_dir_env_repo_scoped[2].execute(remove_query)) # Query again snapshot.assert_match( fixture_working_dir_env_repo_scoped[2].execute(lookup_query))
def build_image_for_jupyterlab(): # Create temp dir config_file, temp_dir = _create_temp_work_dir() # Create user identity insert_cached_identity(temp_dir) # Create test client schema = graphene.Schema(query=LabbookQuery, mutation=LabbookMutations) # get environment data and index erm = RepositoryManager(config_file) erm.update_repositories() erm.index_repositories() with patch.object(Configuration, 'find_default_config', lambda self: config_file): # Load User identity into app context app = Flask("lmsrvlabbook") app.config["LABMGR_CONFIG"] = Configuration() app.config["LABMGR_ID_MGR"] = get_identity_manager(Configuration()) with app.app_context(): # within this block, current_app points to app. Set current user explicitly (this is done in the middleware) flask.g.user_obj = app.config["LABMGR_ID_MGR"].get_user_profile() # Create a test client client = Client( schema, middleware=[DataloaderMiddleware(), error_middleware], context_value=ContextMock()) # Create a labook im = InventoryManager(config_file) lb = im.create_labbook('default', 'unittester', "containerunittestbook", description="Testing docker building.") cm = ComponentManager(lb) cm.add_base(ENV_UNIT_TEST_REPO, ENV_UNIT_TEST_BASE, ENV_UNIT_TEST_REV) cm.add_packages("pip3", [{ "manager": "pip3", "package": "requests", "version": "2.18.4" }]) bam = BundledAppManager(lb) bam.add_bundled_app(9999, 'share', 'A bundled app for testing', "cd /mnt; python3 -m http.server 9999") ib = ImageBuilder(lb) ib.assemble_dockerfile(write=True) docker_client = get_docker_client() try: lb, docker_image_id = ContainerOperations.build_image( labbook=lb, username="******") # Note: The final field is the owner yield lb, ib, docker_client, docker_image_id, client, "unittester" finally: try: docker_client.containers.get(docker_image_id).stop() docker_client.containers.get(docker_image_id).remove() except: pass try: docker_client.images.remove(docker_image_id, force=True, noprune=False) except: pass shutil.rmtree(lb.root_dir)