__author__="Vanessa Sochat"__copyright__="Copyright The ORAS Authors."__license__="Apache-2.0"importosimportsubprocessfrompathlibimportPathimportpytestimportoras.clientimportoras.defaultsimportoras.ociimportoras.providerimportoras.utilshere=Path(__file__).resolve().parent
[docs]@pytest.mark.with_auth(False)deftest_annotated_registry_push(tmp_path,registry,credentials,target):""" Basic tests for oras push with annotations """# Direct access to registry functionsremote=oras.provider.Registry(hostname=registry,insecure=True)client=oras.client.OrasClient(hostname=registry,insecure=True)artifact=os.path.join(here,"artifact.txt")assertos.path.exists(artifact)# Custom manifest annotationsannots={"holiday":"Halloween","candy":"chocolate"}res=client.push(files=[artifact],target=target,manifest_annotations=annots)assertres.status_codein[200,201]# Get the manifestmanifest=remote.get_manifest(target)assert"annotations"inmanifestfork,vinannots.items():assertkinmanifest["annotations"]assertmanifest["annotations"][k]==v# Annotations from file with $manifestannotation_file=os.path.join(here,"annotations.json")file_annots=oras.utils.read_json(annotation_file)assert"$manifest"infile_annotsres=client.push(files=[artifact],target=target,annotation_file=annotation_file)assertres.status_codein[200,201]manifest=remote.get_manifest(target)assert"annotations"inmanifestfork,vinfile_annots["$manifest"].items():assertkinmanifest["annotations"]assertmanifest["annotations"][k]==v# File that doesn't existannotation_file=os.path.join(here,"annotations-nope.json")withpytest.raises(FileNotFoundError):res=client.push(files=[artifact],target=target,annotation_file=annotation_file)
[docs]@pytest.mark.with_auth(False)deftest_file_contains_column(tmp_path,registry,credentials,target):""" Test for file containing column symbol """client=oras.client.OrasClient(hostname=registry,insecure=True)artifact=os.path.join(here,"artifact.txt")assertos.path.exists(artifact)# file containing `:`try:contains_column=here/"some:file"withopen(contains_column,"w")asf:f.write("hello world some:file")res=client.push(files=[contains_column],target=target)assertres.status_codein[200,201]files=client.pull(target,outdir=tmp_path/"download")download=str(tmp_path/"download/some:file")assertdownloadinfilesassertoras.utils.get_file_hash(str(contains_column))==oras.utils.get_file_hash(download)finally:contains_column.unlink()# file containing `:` as prefix, pushed with typetry:contains_column=here/":somefile"withopen(contains_column,"w")asf:f.write("hello world :somefile")res=client.push(files=[f"{contains_column}:text/plain"],target=target)assertres.status_codein[200,201]files=client.pull(target,outdir=tmp_path/"download")download=str(tmp_path/"download/:somefile")assertdownloadinfilesassertoras.utils.get_file_hash(str(contains_column))==oras.utils.get_file_hash(download)finally:contains_column.unlink()# error: file does not existwithpytest.raises(FileNotFoundError):client.push(files=[".doesnotexist"],target=target)withpytest.raises(FileNotFoundError):client.push(files=[":doesnotexist"],target=target)withpytest.raises(FileNotFoundError,match=r".*does:not:exists .*"):client.push(files=["does:not:exists:text/plain"],target=target)withpytest.raises(FileNotFoundError,match=r".*does:not:exists .*"):client.push(files=["does:not:exists:text/plain+ext"],target=target)
[docs]@pytest.mark.with_auth(False)deftest_chunked_push(tmp_path,registry,credentials,target):""" Basic tests for oras chunked push """# Direct access to registry functionsclient=oras.client.OrasClient(hostname=registry,insecure=True)artifact=os.path.join(here,"artifact.txt")assertos.path.exists(artifact)res=client.push(files=[artifact],target=target,do_chunked=True)assertres.status_codein[200,201,202]files=client.pull(target,outdir=tmp_path)assertstr(tmp_path/"artifact.txt")infilesassertoras.utils.get_file_hash(artifact)==oras.utils.get_file_hash(files[0])# large file uploadbase_size=oras.defaults.default_chunksize*1024# 16GBtmp_chunked=here/"chunked"try:subprocess.run(["dd","if=/dev/null",f"of={tmp_chunked}","bs=1","count=0",f"seek={base_size}",],)res=client.push(files=[tmp_chunked],target=target,do_chunked=True,)assertres.status_codein[200,201,202]files=client.pull(target,outdir=tmp_path/"download")download=str(tmp_path/"download/chunked")assertdownloadinfilesassertoras.utils.get_file_hash(str(tmp_chunked))==oras.utils.get_file_hash(download)finally:tmp_chunked.unlink()# File that doesn't existwithpytest.raises(FileNotFoundError):res=client.push(files=[tmp_path/"none"],target=target)
[docs]deftest_parse_manifest(registry):""" Test parse manifest function. Parse manifest function has additional logic for Windows - this isn't included in these tests as they don't usually run on Windows. """testref="path/to/config:application/vnd.oci.image.config.v1+json"remote=oras.provider.Registry(hostname=registry,insecure=True)ref,content_type=remote._parse_manifest_ref(testref)assertref=="path/to/config"assertcontent_type=="application/vnd.oci.image.config.v1+json"testref="/dev/null:application/vnd.oci.image.manifest.v1+json"ref,content_type=remote._parse_manifest_ref(testref)assertref=="/dev/null"assertcontent_type=="application/vnd.oci.image.manifest.v1+json"testref="/dev/null"ref,content_type=remote._parse_manifest_ref(testref)assertref=="/dev/null"assertcontent_type==oras.defaults.unknown_config_media_typetestref="path/to/config.json"ref,content_type=remote._parse_manifest_ref(testref)assertref=="path/to/config.json"assertcontent_type==oras.defaults.unknown_config_media_type
[docs]deftest_sanitize_path():HOME_DIR=str(Path.home())assertstr(oras.utils.sanitize_path(HOME_DIR,HOME_DIR))==f"{HOME_DIR}"assert(str(oras.utils.sanitize_path(HOME_DIR,os.path.join(HOME_DIR,"username")))==f"{HOME_DIR}/username")assert(str(oras.utils.sanitize_path(HOME_DIR,os.path.join(HOME_DIR,".","username")))==f"{HOME_DIR}/username")withpytest.raises(Exception)ase:assertoras.utils.sanitize_path(HOME_DIR,os.path.join(HOME_DIR,".."))assert(str(e.value)==f"Filename {Path(os.path.join(HOME_DIR,'..')).resolve()} is not in {HOME_DIR} directory")assertoras.utils.sanitize_path("","")==str(Path(".").resolve())assertoras.utils.sanitize_path("/opt",os.path.join("/opt","image_name"))==str(Path("/opt/image_name").resolve())assertoras.utils.sanitize_path("/../../","/")==str(Path("/").resolve())assertoras.utils.sanitize_path(Path(os.getcwd()).parent.absolute(),os.path.join(os.getcwd(),".."))==str(Path("..").resolve())withpytest.raises(Exception)ase:assertoras.utils.sanitize_path(Path(os.getcwd()).parent.absolute(),os.path.join(os.getcwd(),"..",".."))!=str(Path("../..").resolve())assert(str(e.value)==f"Filename {Path(os.path.join(os.getcwd(),'..','..')).resolve()} is not in {Path('../').resolve()} directory")