def test_uninitialized_engine_error(local_engine_empty): # Test things like the audit triggers/splitgraph meta schema missing raise # uninitialized engine errors rather than generic SQL errors. try: local_engine_empty.run_sql("DROP SCHEMA splitgraph_meta CASCADE") with pytest.raises(EngineInitializationError) as e: lookup_repository("some/repo", include_local=True) assert "splitgraph_meta" in str(e.value) local_engine_empty.initialize() local_engine_empty.commit() local_engine_empty.run_sql("DROP SCHEMA splitgraph_api CASCADE") with pytest.raises(EngineInitializationError) as e: ObjectManager(local_engine_empty).get_downloaded_objects() assert "splitgraph_api" in str(e.value) local_engine_empty.initialize() local_engine_empty.commit() local_engine_empty.run_sql("DROP SCHEMA splitgraph_audit CASCADE") with pytest.raises(EngineInitializationError) as e: local_engine_empty.discard_pending_changes("some/repo") assert "Audit triggers" in str(e.value) finally: local_engine_empty.initialize() local_engine_empty.commit()
def test_repo_lookup_override(remote_engine): test_repo = Repository("overridden", "repo", engine=remote_engine) try: test_repo.init() assert lookup_repository("overridden/repo") == test_repo finally: test_repo.delete(unregister=True, uncheckout=True)
def _get_local_image_for_import(hash_or_tag: str, repository: Repository) -> Tuple[Image, bool]: """ Converts a remote repository and tag into an Image object that exists on the engine, optionally pulling the repository or cloning it into a temporary location. :param hash_or_tag: Hash/tag :param repository: Name of the repository (doesn't need to be local) :return: Image object and a boolean flag showing whether the repository should be deleted when the image is no longer needed. """ tmp_repo = Repository(repository.namespace, repository.repository + "_tmp_clone") repo_is_temporary = False logging.info("Resolving repository %s", repository) source_repo = lookup_repository(repository.to_schema(), include_local=True) if source_repo.engine.name != "LOCAL": clone(source_repo, local_repository=tmp_repo, download_all=False) source_image = tmp_repo.images[hash_or_tag] repo_is_temporary = True else: # For local repositories, first try to pull them to see if they are clones of a remote. if source_repo.upstream: source_repo.pull() source_image = source_repo.images[hash_or_tag] return source_image, repo_is_temporary
def _execute_from( node: Node, output: Repository) -> Tuple[Repository, Optional[ProvenanceLine]]: interesting_nodes = extract_nodes(node, ["repo_source", "repository"]) repo_source = get_first_or_none(interesting_nodes, "repo_source") output_node = get_first_or_none(interesting_nodes, "repository") provenance: Optional[ProvenanceLine] = None if output_node: # AS (output) detected, change the current output repository to it. output = Repository.from_schema(output_node.match.group(0)) logging.info("Changed output repository to %s" % str(output)) # NB this destroys all data in the case where we ran some commands in the Splitfile and then # did FROM (...) without AS repository if repository_exists(output): logging.info("Clearing all output from %s" % str(output)) output.delete() if not repository_exists(output): output.init() if repo_source: repository, tag_or_hash = parse_image_spec(repo_source) source_repo = lookup_repository(repository.to_schema(), include_local=True) if source_repo.engine.name == "LOCAL": # For local repositories, make sure to update them if they've an upstream if source_repo.upstream: source_repo.pull() # Get the target image hash from the source repo: otherwise, if the tag is, say, 'latest' and # the output has just had the base commit (000...) created in it, that commit will be the latest. clone(source_repo, local_repository=output, download_all=False) source_hash = source_repo.images[tag_or_hash].image_hash output.images.by_hash(source_hash).checkout() provenance = { "type": "FROM", "source_namespace": source_repo.namespace, "source": source_repo.repository, "source_hash": source_hash, } else: # FROM EMPTY AS repository -- initializes an empty repository (say to create a table or import # the results of a previous stage in a multistage build. # In this case, if AS repository has been specified, it's already been initialized. If not, this command # literally does nothing if not output_node: raise SplitfileError( "FROM EMPTY without AS (repository) does nothing!") return output, provenance
def test_repo_lookup_override_fail(): with pytest.raises(RepositoryNotFoundError) as e: lookup_repository("does/not_exist") assert "Unknown repository" in str(e.value)