From d1a472ef06464cee3a1df0eeff5d88f05b32a0f6 Mon Sep 17 00:00:00 2001 From: danimtb Date: Tue, 5 Mar 2019 16:02:50 +0100 Subject: [PATCH 01/20] Added reproducible test --- conans/test/functional/command/upload_test.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/conans/test/functional/command/upload_test.py b/conans/test/functional/command/upload_test.py index f5a6c1304b3..f47ddcf9635 100644 --- a/conans/test/functional/command/upload_test.py +++ b/conans/test/functional/command/upload_test.py @@ -1,4 +1,6 @@ import itertools +import textwrap + import os import unittest @@ -540,3 +542,30 @@ def upload_login_prompt_disabled_user_authenticated_test(self): self.assertIn("Uploading conanmanifest.txt", client.out) self.assertIn("Uploading conanfile.py", client.out) self.assertIn("Uploading conan_export.tgz", client.out) + + def upload_with_corrupted_package_test(self): + """ + Simulate a connection failure or file corruption in the server with missing files for a + package and make sure the upload is possible even if the package in the server is not + accessible + """ + client = self._client() + conanfile = textwrap.dedent(""" + from conans import ConanFile + + class Pkg(ConanFile): + pass + """) + client.save({"conanfile.py": conanfile}) + client.run("create . Pkg/0.1@user/testing") + client.run("upload * --all --confirm") + server = self._servers["default"] + path = server.server_store.get_package_file_path( + PackageReference(ConanFileReference.loads("Pkg/0.1@user/testing#0"), + NO_SETTINGS_PACKAGE_ID, "0"), "conanmanifest.txt") + os.unlink(path) # Simulate conanmanifest.txt is not there + client.run("upload * --all --confirm --force") + self.assertNotIn("ERROR: Binary package not found", client.out) + self.assertIn("Uploading conanmanifest.txt", client.out) + self.assertIn("Uploading conaninfo.txt", client.out) + self.assertIn("Uploading conan_package.tgz", client.out) From e86a1e73c881bb0b915540c23fdf5a408c139cb2 Mon Sep 17 00:00:00 2001 From: danimtb Date: Tue, 5 Mar 2019 16:05:10 +0100 Subject: [PATCH 02/20] Check for conanmanifest in package files before getting the digest --- conans/client/cmd/uploader.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/conans/client/cmd/uploader.py b/conans/client/cmd/uploader.py index c6684e4700a..85afec67164 100644 --- a/conans/client/cmd/uploader.py +++ b/conans/client/cmd/uploader.py @@ -351,15 +351,16 @@ def _package_files_to_upload(self, pref, policy, the_files, remote): remote_snapshot = self._remote_manager.get_package_snapshot(pref, remote) if remote_snapshot: - remote_manifest, _ = self._remote_manager.get_package_manifest(pref, remote) - local_manifest = FileTreeManifest.loads(load(the_files["conanmanifest.txt"])) + if CONAN_MANIFEST in remote_snapshot.keys(): + remote_manifest, _ = self._remote_manager.get_package_manifest(pref, remote) + local_manifest = FileTreeManifest.loads(load(the_files["conanmanifest.txt"])) - if remote_manifest == local_manifest: - return None, None + if remote_manifest == local_manifest: + return None, None - if policy == UPLOAD_POLICY_NO_OVERWRITE: - raise ConanException("Local package is different from the remote package. " - "Forbidden overwrite.") + if policy == UPLOAD_POLICY_NO_OVERWRITE: + raise ConanException("Local package is different from the remote package. " + "Forbidden overwrite.") files_to_upload = the_files deleted = set(remote_snapshot).difference(the_files) From c775383d9c4891b568c4d32f4352840f7e58d416 Mon Sep 17 00:00:00 2001 From: danimtb Date: Tue, 5 Mar 2019 18:35:52 +0100 Subject: [PATCH 03/20] Removed test and created a dedicated set --- conans/test/functional/command/upload_test.py | 27 ----- .../functional/corrupted_packages_test.py | 108 ++++++++++++++++++ 2 files changed, 108 insertions(+), 27 deletions(-) create mode 100644 conans/test/functional/corrupted_packages_test.py diff --git a/conans/test/functional/command/upload_test.py b/conans/test/functional/command/upload_test.py index ffc92380042..e97daf59a92 100644 --- a/conans/test/functional/command/upload_test.py +++ b/conans/test/functional/command/upload_test.py @@ -574,30 +574,3 @@ def upload_key_error_test(self): client.run("remote remove server1") client.run("upload Hello0/1.2.1@user/testing --all -r server2") self.assertNotIn("ERROR: 'server1'", client.out) - - def upload_with_corrupted_package_test(self): - """ - Simulate a connection failure or file corruption in the server with missing files for a - package and make sure the upload is possible even if the package in the server is not - accessible - """ - client = self._client() - conanfile = textwrap.dedent(""" - from conans import ConanFile - - class Pkg(ConanFile): - pass - """) - client.save({"conanfile.py": conanfile}) - client.run("create . Pkg/0.1@user/testing") - client.run("upload * --all --confirm") - server = self._servers["default"] - path = server.server_store.get_package_file_path( - PackageReference(ConanFileReference.loads("Pkg/0.1@user/testing#0"), - NO_SETTINGS_PACKAGE_ID, "0"), "conanmanifest.txt") - os.unlink(path) # Simulate conanmanifest.txt is not there - client.run("upload * --all --confirm --force") - self.assertNotIn("ERROR: Binary package not found", client.out) - self.assertIn("Uploading conanmanifest.txt", client.out) - self.assertIn("Uploading conaninfo.txt", client.out) - self.assertIn("Uploading conan_package.tgz", client.out) diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py new file mode 100644 index 00000000000..c5bf4af5da2 --- /dev/null +++ b/conans/test/functional/corrupted_packages_test.py @@ -0,0 +1,108 @@ +import os +import textwrap +import unittest + +from conans.model.ref import ConanFileReference, PackageReference +from conans.test.utils.tools import TestClient, TestServer, NO_SETTINGS_PACKAGE_ID + + +class CorruptedPackagesTest(unittest.TestCase): + """ + Simulate a connection failure or file corruption in the server with missing files for a + package and make sure the search, install are possible. Check re-upload is always possible + even if the package in the server is not accessible + """ + + def setUp(self): + self.server = TestServer([("*/*@*/*", "*")], [("*/*@*/*", "*")]) + self.client = TestClient(servers={"default": self.server}) + conanfile = textwrap.dedent(""" + from conans import ConanFile + + class Pkg(ConanFile): + pass + """) + self.client.save({"conanfile.py": conanfile}) + self.client.run("create . Pkg/0.1@user/testing") + self.client.run("upload * --all --confirm -r default") + self.pref = pref = PackageReference(ConanFileReference.loads("Pkg/0.1@user/testing#0"), + NO_SETTINGS_PACKAGE_ID, "0") + self.manifest_path = self.server.server_store.get_package_file_path(pref, + "conanmanifest.txt") + self.info_path = self.server.server_store.get_package_file_path(pref, "conaninfo.txt") + self.tgz_path = self.server.server_store.get_package_file_path(pref, "conan_package.tgz") + + def _assert_all_package_files_in_server(self): + self.assertTrue(os.path.exists(self.manifest_path)) + self.assertTrue(os.path.exists(self.info_path)) + self.assertTrue(os.path.exists(self.tgz_path)) + + def info_manifest_missing_test(self): + os.unlink(self.info_path) + os.unlink(self.manifest_path) + # Try search + self.client.run("search Pkg/0.1@user/testing -r default") + self.assertIn("There are no packages for reference 'Pkg/0.1@user/testing', " + "but package recipe found", self.client.out) + # Try fresh install + self.client.run("remove * -f") + self.client.run("install Pkg/0.1@user/testing", assert_error=True) + self.assertIn("Pkg/0.1@user/testing:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Missing", + self.client.out) + # Try upload of fresh package + self.client.run("create . Pkg/0.1@user/testing") + self.client.run("upload * --all --confirm -r default") + self._assert_all_package_files_in_server() + + def manifest_missing_test(self): + os.unlink(self.manifest_path) + # Try search + self.client.run("search Pkg/0.1@user/testing -r default") + # Try fresh install + self.client.run("remove * -f") + self.client.run("install Pkg/0.1@user/testing") # FIXME: missing conanmanifest.txt does NOT fail? + self.assertIn(NO_SETTINGS_PACKAGE_ID, self.client.out) + # Try upload of installed package + self.client.run("upload * --all --confirm", assert_error=True) + self.assertIn("ERROR: Cannot upload corrupted package", self.client.out) + # Try upload of fresh package + self.client.run("create . Pkg/0.1@user/testing") + self.client.run("upload * --all --confirm") + self._assert_all_package_files_in_server() + + def tgz_info_missing_test(self): + os.unlink(self.tgz_path) + os.unlink(self.info_path) + # Try search + self.client.run("search Pkg/0.1@user/testing -r default") + self.assertIn("There are no packages for reference 'Pkg/0.1@user/testing', " + "but package recipe found", self.client.out) + # Try fresh install + self.client.run("remove * -f") + self.client.run("install Pkg/0.1@user/testing", assert_error=True) + self.assertIn("Pkg/0.1@user/testing:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Missing", + self.client.out) + # Try upload of fresh package + self.client.run("create . Pkg/0.1@user/testing") + self.client.run("upload * --all --confirm") + # FIXME: tgz and info are not in the server and not uploaded + self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) + # self._assert_all_package_files_in_server() + + def tgz_missing_test(self): + os.unlink(self.tgz_path) + # Try search + self.client.run("search Pkg/0.1@user/testing -r default") + # Try fresh install + self.client.run("remove * -f") + self.client.run("install Pkg/0.1@user/testing") # FIXME: missing conan_package.tgz does NOT fail? + print(self.client.out) + self.assertIn(NO_SETTINGS_PACKAGE_ID, self.client.out) + self.client.run("upload * --all --confirm") + print(self.client.out) # FIXME: Package up to date but actually the tgz is missing in the server + # Try upload of fresh package + self.client.run("create . Pkg/0.1@user/testing") + self.client.run("upload * --all --confirm") + # FIXME: tgz is not in the server and not uploaded + self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) + #self._assert_all_package_files_in_server() From 6f335a909e427ffb4bf3eb9aad29bf132762fd7a Mon Sep 17 00:00:00 2001 From: danimtb Date: Tue, 5 Mar 2019 19:18:58 +0100 Subject: [PATCH 04/20] review --- conans/client/cmd/uploader.py | 2 +- conans/test/functional/command/upload_test.py | 2 -- conans/test/functional/corrupted_packages_test.py | 5 +++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/conans/client/cmd/uploader.py b/conans/client/cmd/uploader.py index 277fc89745c..6a0f4c9aaff 100644 --- a/conans/client/cmd/uploader.py +++ b/conans/client/cmd/uploader.py @@ -360,7 +360,7 @@ def _package_files_to_upload(self, pref, policy, the_files, remote): remote_snapshot = self._remote_manager.get_package_snapshot(pref, remote) if remote_snapshot: - if CONAN_MANIFEST in remote_snapshot.keys(): + if CONAN_MANIFEST in remote_snapshot: remote_manifest, _ = self._remote_manager.get_package_manifest(pref, remote) local_manifest = FileTreeManifest.loads(load(the_files["conanmanifest.txt"])) diff --git a/conans/test/functional/command/upload_test.py b/conans/test/functional/command/upload_test.py index e97daf59a92..8064df46131 100644 --- a/conans/test/functional/command/upload_test.py +++ b/conans/test/functional/command/upload_test.py @@ -1,6 +1,4 @@ import itertools -import textwrap - import os import unittest from collections import OrderedDict diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index c5bf4af5da2..4faf0b498cf 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -58,6 +58,7 @@ def manifest_missing_test(self): os.unlink(self.manifest_path) # Try search self.client.run("search Pkg/0.1@user/testing -r default") + self.assertIn("Package_ID: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", self.client.out) # Try fresh install self.client.run("remove * -f") self.client.run("install Pkg/0.1@user/testing") # FIXME: missing conanmanifest.txt does NOT fail? @@ -95,8 +96,8 @@ def tgz_missing_test(self): self.client.run("search Pkg/0.1@user/testing -r default") # Try fresh install self.client.run("remove * -f") - self.client.run("install Pkg/0.1@user/testing") # FIXME: missing conan_package.tgz does NOT fail? - print(self.client.out) + self.client.run("install Pkg/0.1@user/testing") + print(self.client.out) # FIXME: missing conan_package.tgz does NOT fail? self.assertIn(NO_SETTINGS_PACKAGE_ID, self.client.out) self.client.run("upload * --all --confirm") print(self.client.out) # FIXME: Package up to date but actually the tgz is missing in the server From bd32bd2549c863f69fcb82ed04c3a2b576854fad Mon Sep 17 00:00:00 2001 From: danimtb Date: Wed, 6 Mar 2019 10:46:06 +0100 Subject: [PATCH 05/20] Added more tests --- .../functional/corrupted_packages_test.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index 4faf0b498cf..118365c0083 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -107,3 +107,38 @@ def tgz_missing_test(self): # FIXME: tgz is not in the server and not uploaded self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) #self._assert_all_package_files_in_server() + + def tgz_manifest_missing_test(self): + os.unlink(self.tgz_path) + os.unlink(self.manifest_path) + # Try search + self.client.run("search Pkg/0.1@user/testing -r default") + self.assertIn("Package_ID: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", self.client.out) + # Try fresh install + self.client.run("remove * -f") + self.client.run("install Pkg/0.1@user/testing") # FIXME: missing conan_package.tgz and conanmanifest.txt does NOT fail? + # Try upload of installed package + self.client.run("upload * --all --confirm", assert_error=True) + self.assertIn("ERROR: Cannot upload corrupted package", self.client.out) + # Try upload of fresh package + self.client.run("create . Pkg/0.1@user/testing") + self.client.run("upload * --all --confirm") + self._assert_all_package_files_in_server() + + def tgz_manifest_info_missing_test(self): + os.unlink(self.tgz_path) + os.unlink(self.manifest_path) + os.unlink(self.info_path) + # Try search + self.client.run("search Pkg/0.1@user/testing -r default") + self.assertIn("There are no packages for reference 'Pkg/0.1@user/testing', " + "but package recipe found", self.client.out) + # Try fresh install + self.client.run("remove * -f") + self.client.run("install Pkg/0.1@user/testing", assert_error=True) + self.assertIn("Pkg/0.1@user/testing:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Missing", + self.client.out) + # Try upload of fresh package + self.client.run("create . Pkg/0.1@user/testing") + self.client.run("upload * --all --confirm") + self._assert_all_package_files_in_server() From bc677afd5d1c67b8c4afbd4ca6649ff6ebd13ba4 Mon Sep 17 00:00:00 2001 From: danimtb Date: Wed, 13 Mar 2019 18:02:33 +0100 Subject: [PATCH 06/20] Test V2 too --- conans/client/rest/rest_client_v1.py | 4 +-- conans/client/rest/rest_client_v2.py | 4 +-- .../functional/corrupted_packages_test.py | 36 ++++++++++++++----- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/conans/client/rest/rest_client_v1.py b/conans/client/rest/rest_client_v1.py index 4db42a8bbb6..267d9bbc9d7 100644 --- a/conans/client/rest/rest_client_v1.py +++ b/conans/client/rest/rest_client_v1.py @@ -142,9 +142,7 @@ def _upload_files(self, file_urls, files, output, retry, retry_wait): t1 = time.time() failed = [] uploader = Uploader(self.requester, output, self.verify_ssl) - # Take advantage of filenames ordering, so that conan_package.tgz and conan_export.tgz - # can be < conanfile, conaninfo, and sent always the last, so smaller files go first - for filename, resource_url in sorted(file_urls.items(), reverse=True): + for filename, resource_url in sorted(file_urls.items()): output.rewrite_line("Uploading %s" % filename) auth, dedup = self._file_server_capabilities(resource_url) try: diff --git a/conans/client/rest/rest_client_v2.py b/conans/client/rest/rest_client_v2.py index 5362fbcbd63..08a9938fc34 100644 --- a/conans/client/rest/rest_client_v2.py +++ b/conans/client/rest/rest_client_v2.py @@ -174,9 +174,7 @@ def _upload_files(self, files, urls, retry, retry_wait): t1 = time.time() failed = [] uploader = Uploader(self.requester, self._output, self.verify_ssl) - # Take advantage of filenames ordering, so that conan_package.tgz and conan_export.tgz - # can be < conanfile, conaninfo, and sent always the last, so smaller files go first - for filename in sorted(files, reverse=True): + for filename in sorted(files): self._output.rewrite_line("Uploading %s" % filename) resource_url = urls[filename] try: diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index 118365c0083..78145b2aebe 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -2,6 +2,8 @@ import textwrap import unittest +from parameterized import parameterized + from conans.model.ref import ConanFileReference, PackageReference from conans.test.utils.tools import TestClient, TestServer, NO_SETTINGS_PACKAGE_ID @@ -13,9 +15,10 @@ class CorruptedPackagesTest(unittest.TestCase): even if the package in the server is not accessible """ - def setUp(self): + def _setUp(self, revisions_enabled): self.server = TestServer([("*/*@*/*", "*")], [("*/*@*/*", "*")]) - self.client = TestClient(servers={"default": self.server}) + self.client = TestClient(servers={"default": self.server}, + revisions_enabled=revisions_enabled) conanfile = textwrap.dedent(""" from conans import ConanFile @@ -25,6 +28,11 @@ class Pkg(ConanFile): self.client.save({"conanfile.py": conanfile}) self.client.run("create . Pkg/0.1@user/testing") self.client.run("upload * --all --confirm -r default") + # Check files are uploded in this order: conan_package.tgz, conaninfo.txt, conanmanifest.txt + order1 = str(self.client.out).find("Uploading conan_package.tgz") + order2 = str(self.client.out).find("Uploading conaninfo.txt", order1) + order3 = str(self.client.out).find("Uploading conanmanifest.txt", order2) + self.assertTrue(order1 < order2 < order3) self.pref = pref = PackageReference(ConanFileReference.loads("Pkg/0.1@user/testing#0"), NO_SETTINGS_PACKAGE_ID, "0") self.manifest_path = self.server.server_store.get_package_file_path(pref, @@ -37,7 +45,9 @@ def _assert_all_package_files_in_server(self): self.assertTrue(os.path.exists(self.info_path)) self.assertTrue(os.path.exists(self.tgz_path)) - def info_manifest_missing_test(self): + @parameterized.expand([(True,), (False,)]) + def info_manifest_missing_test(self, revisions_enabled): + self._setUp(revisions_enabled) os.unlink(self.info_path) os.unlink(self.manifest_path) # Try search @@ -54,7 +64,9 @@ def info_manifest_missing_test(self): self.client.run("upload * --all --confirm -r default") self._assert_all_package_files_in_server() - def manifest_missing_test(self): + @parameterized.expand([(True,), (False,)]) + def manifest_missing_test(self, revisions_enabled): + self._setUp(revisions_enabled) os.unlink(self.manifest_path) # Try search self.client.run("search Pkg/0.1@user/testing -r default") @@ -71,7 +83,9 @@ def manifest_missing_test(self): self.client.run("upload * --all --confirm") self._assert_all_package_files_in_server() - def tgz_info_missing_test(self): + @parameterized.expand([(True,), (False,)]) + def tgz_info_missing_test(self, revisions_enabled): + self._setUp(revisions_enabled) os.unlink(self.tgz_path) os.unlink(self.info_path) # Try search @@ -90,7 +104,9 @@ def tgz_info_missing_test(self): self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) # self._assert_all_package_files_in_server() - def tgz_missing_test(self): + @parameterized.expand([(True,), (False,)]) + def tgz_missing_test(self, revisions_enabled): + self._setUp(revisions_enabled) os.unlink(self.tgz_path) # Try search self.client.run("search Pkg/0.1@user/testing -r default") @@ -108,7 +124,9 @@ def tgz_missing_test(self): self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) #self._assert_all_package_files_in_server() - def tgz_manifest_missing_test(self): + @parameterized.expand([(True,), (False,)]) + def tgz_manifest_missing_test(self, revisions_enabled): + self._setUp(revisions_enabled) os.unlink(self.tgz_path) os.unlink(self.manifest_path) # Try search @@ -125,7 +143,9 @@ def tgz_manifest_missing_test(self): self.client.run("upload * --all --confirm") self._assert_all_package_files_in_server() - def tgz_manifest_info_missing_test(self): + @parameterized.expand([(True,), (False,)]) + def tgz_manifest_info_missing_test(self, revisions_enabled): + self._setUp(revisions_enabled) os.unlink(self.tgz_path) os.unlink(self.manifest_path) os.unlink(self.info_path) From c6d94e4edc162ea87c6382275df85f5f72cdde78 Mon Sep 17 00:00:00 2001 From: danimtb Date: Wed, 13 Mar 2019 18:09:17 +0100 Subject: [PATCH 07/20] fix test qith revisions --- conans/test/functional/corrupted_packages_test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index 78145b2aebe..5f21d3497e2 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -33,8 +33,11 @@ class Pkg(ConanFile): order2 = str(self.client.out).find("Uploading conaninfo.txt", order1) order3 = str(self.client.out).find("Uploading conanmanifest.txt", order2) self.assertTrue(order1 < order2 < order3) - self.pref = pref = PackageReference(ConanFileReference.loads("Pkg/0.1@user/testing#0"), - NO_SETTINGS_PACKAGE_ID, "0") + rrev = "210a4a16419aae28fea1f268a8e4f3d4" if revisions_enabled else "0" + pref_str = "Pkg/0.1@user/testing#%s" % rrev + prev = "11de80325e8db78617b05384825c6409" if revisions_enabled else "0" + self.pref = pref = PackageReference(ConanFileReference.loads(pref_str), + NO_SETTINGS_PACKAGE_ID, prev) self.manifest_path = self.server.server_store.get_package_file_path(pref, "conanmanifest.txt") self.info_path = self.server.server_store.get_package_file_path(pref, "conaninfo.txt") From afa639376874e62ec8ae22e30a5c2cab85b3922c Mon Sep 17 00:00:00 2001 From: danimtb Date: Wed, 13 Mar 2019 18:34:28 +0100 Subject: [PATCH 08/20] Check package snapshot is complete just before installing --- conans/client/remote_manager.py | 6 +++++- .../functional/corrupted_packages_test.py | 19 ++++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py index 713eacaf053..457cf5de1c7 100644 --- a/conans/client/remote_manager.py +++ b/conans/client/remote_manager.py @@ -11,7 +11,8 @@ from conans.errors import ConanConnectionError, ConanException, NotFoundException, \ NoRestV2Available, PackageNotFoundException from conans.paths import EXPORT_SOURCES_DIR_OLD, \ - EXPORT_SOURCES_TGZ_NAME, EXPORT_TGZ_NAME, PACKAGE_TGZ_NAME, rm_conandir + EXPORT_SOURCES_TGZ_NAME, EXPORT_TGZ_NAME, PACKAGE_TGZ_NAME, rm_conandir, CONANINFO, \ + CONAN_MANIFEST from conans.search.search import filter_packages from conans.util import progress_bar from conans.util.env_reader import get_env @@ -129,6 +130,9 @@ def get_package(self, pref, dest_folder, remote, output, recorder): t1 = time.time() try: pref = self._resolve_latest_pref(pref, remote) + snapshot = self._call_remote(remote, "get_package_snapshot", pref) + if [CONANINFO, CONAN_MANIFEST, PACKAGE_TGZ_NAME] != snapshot: + raise NotFoundException zipped_files = self._call_remote(remote, "get_package", pref, dest_folder) with self._cache.package_layout(pref.ref).update_metadata() as metadata: diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index 5f21d3497e2..5adfd293e1d 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -76,11 +76,9 @@ def manifest_missing_test(self, revisions_enabled): self.assertIn("Package_ID: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", self.client.out) # Try fresh install self.client.run("remove * -f") - self.client.run("install Pkg/0.1@user/testing") # FIXME: missing conanmanifest.txt does NOT fail? + self.client.run("install Pkg/0.1@user/testing", assert_error=True) + self.assertIn("ERROR: Binary package not found", self.client.out) self.assertIn(NO_SETTINGS_PACKAGE_ID, self.client.out) - # Try upload of installed package - self.client.run("upload * --all --confirm", assert_error=True) - self.assertIn("ERROR: Cannot upload corrupted package", self.client.out) # Try upload of fresh package self.client.run("create . Pkg/0.1@user/testing") self.client.run("upload * --all --confirm") @@ -115,11 +113,8 @@ def tgz_missing_test(self, revisions_enabled): self.client.run("search Pkg/0.1@user/testing -r default") # Try fresh install self.client.run("remove * -f") - self.client.run("install Pkg/0.1@user/testing") - print(self.client.out) # FIXME: missing conan_package.tgz does NOT fail? - self.assertIn(NO_SETTINGS_PACKAGE_ID, self.client.out) - self.client.run("upload * --all --confirm") - print(self.client.out) # FIXME: Package up to date but actually the tgz is missing in the server + self.client.run("install Pkg/0.1@user/testing", assert_error=True) + self.assertIn("ERROR: Binary package not found", self.client.out) # Try upload of fresh package self.client.run("create . Pkg/0.1@user/testing") self.client.run("upload * --all --confirm") @@ -137,10 +132,8 @@ def tgz_manifest_missing_test(self, revisions_enabled): self.assertIn("Package_ID: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", self.client.out) # Try fresh install self.client.run("remove * -f") - self.client.run("install Pkg/0.1@user/testing") # FIXME: missing conan_package.tgz and conanmanifest.txt does NOT fail? - # Try upload of installed package - self.client.run("upload * --all --confirm", assert_error=True) - self.assertIn("ERROR: Cannot upload corrupted package", self.client.out) + self.client.run("install Pkg/0.1@user/testing", assert_error=True) + self.assertIn("ERROR: Binary package not found", self.client.out) # Try upload of fresh package self.client.run("create . Pkg/0.1@user/testing") self.client.run("upload * --all --confirm") From 1e1fc8f1929c10a24a1664e2f7934c0affa03f54 Mon Sep 17 00:00:00 2001 From: danimtb Date: Fri, 15 Mar 2019 17:09:48 +0100 Subject: [PATCH 09/20] relax check --- conans/client/remote_manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py index 457cf5de1c7..9e6630554c4 100644 --- a/conans/client/remote_manager.py +++ b/conans/client/remote_manager.py @@ -131,7 +131,8 @@ def get_package(self, pref, dest_folder, remote, output, recorder): try: pref = self._resolve_latest_pref(pref, remote) snapshot = self._call_remote(remote, "get_package_snapshot", pref) - if [CONANINFO, CONAN_MANIFEST, PACKAGE_TGZ_NAME] != snapshot: + if any([keyword in key for keyword in ["conaninfo", "conanmanifest", "conan_package"] + for key in snapshot]): raise NotFoundException zipped_files = self._call_remote(remote, "get_package", pref, dest_folder) From 147af1f06427aab0bc74c9ac814521130be8f249 Mon Sep 17 00:00:00 2001 From: danimtb Date: Fri, 15 Mar 2019 17:15:24 +0100 Subject: [PATCH 10/20] Remove parameterized revisions not needed --- .../functional/corrupted_packages_test.py | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index 5adfd293e1d..14779c5b892 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -2,9 +2,8 @@ import textwrap import unittest -from parameterized import parameterized - from conans.model.ref import ConanFileReference, PackageReference +from conans.util.env_reader import get_env from conans.test.utils.tools import TestClient, TestServer, NO_SETTINGS_PACKAGE_ID @@ -15,10 +14,10 @@ class CorruptedPackagesTest(unittest.TestCase): even if the package in the server is not accessible """ - def _setUp(self, revisions_enabled): + def setUp(self): + revisions_enabled = get_env("CONAN_REVISIONS_ENABLED") self.server = TestServer([("*/*@*/*", "*")], [("*/*@*/*", "*")]) - self.client = TestClient(servers={"default": self.server}, - revisions_enabled=revisions_enabled) + self.client = TestClient(servers={"default": self.server}) conanfile = textwrap.dedent(""" from conans import ConanFile @@ -48,9 +47,7 @@ def _assert_all_package_files_in_server(self): self.assertTrue(os.path.exists(self.info_path)) self.assertTrue(os.path.exists(self.tgz_path)) - @parameterized.expand([(True,), (False,)]) - def info_manifest_missing_test(self, revisions_enabled): - self._setUp(revisions_enabled) + def info_manifest_missing_test(self): os.unlink(self.info_path) os.unlink(self.manifest_path) # Try search @@ -67,9 +64,7 @@ def info_manifest_missing_test(self, revisions_enabled): self.client.run("upload * --all --confirm -r default") self._assert_all_package_files_in_server() - @parameterized.expand([(True,), (False,)]) - def manifest_missing_test(self, revisions_enabled): - self._setUp(revisions_enabled) + def manifest_missing_test(self): os.unlink(self.manifest_path) # Try search self.client.run("search Pkg/0.1@user/testing -r default") @@ -84,9 +79,7 @@ def manifest_missing_test(self, revisions_enabled): self.client.run("upload * --all --confirm") self._assert_all_package_files_in_server() - @parameterized.expand([(True,), (False,)]) - def tgz_info_missing_test(self, revisions_enabled): - self._setUp(revisions_enabled) + def tgz_info_missing_test(self): os.unlink(self.tgz_path) os.unlink(self.info_path) # Try search @@ -105,9 +98,7 @@ def tgz_info_missing_test(self, revisions_enabled): self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) # self._assert_all_package_files_in_server() - @parameterized.expand([(True,), (False,)]) - def tgz_missing_test(self, revisions_enabled): - self._setUp(revisions_enabled) + def tgz_missing_test(self): os.unlink(self.tgz_path) # Try search self.client.run("search Pkg/0.1@user/testing -r default") @@ -122,9 +113,7 @@ def tgz_missing_test(self, revisions_enabled): self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) #self._assert_all_package_files_in_server() - @parameterized.expand([(True,), (False,)]) - def tgz_manifest_missing_test(self, revisions_enabled): - self._setUp(revisions_enabled) + def tgz_manifest_missing_test(self): os.unlink(self.tgz_path) os.unlink(self.manifest_path) # Try search @@ -139,9 +128,7 @@ def tgz_manifest_missing_test(self, revisions_enabled): self.client.run("upload * --all --confirm") self._assert_all_package_files_in_server() - @parameterized.expand([(True,), (False,)]) - def tgz_manifest_info_missing_test(self, revisions_enabled): - self._setUp(revisions_enabled) + def tgz_manifest_info_missing_test(self): os.unlink(self.tgz_path) os.unlink(self.manifest_path) os.unlink(self.info_path) From e9dfdf6e6582702090420267179b3df5ecef19cc Mon Sep 17 00:00:00 2001 From: danimtb Date: Fri, 15 Mar 2019 17:43:02 +0100 Subject: [PATCH 11/20] Fix condition --- conans/client/remote_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py index 9e6630554c4..6378b5fbb1b 100644 --- a/conans/client/remote_manager.py +++ b/conans/client/remote_manager.py @@ -131,8 +131,8 @@ def get_package(self, pref, dest_folder, remote, output, recorder): try: pref = self._resolve_latest_pref(pref, remote) snapshot = self._call_remote(remote, "get_package_snapshot", pref) - if any([keyword in key for keyword in ["conaninfo", "conanmanifest", "conan_package"] - for key in snapshot]): + if not any([keyword in key for keyword in ["conaninfo", "conanmanifest", "conan_package"] + for key in snapshot]): raise NotFoundException zipped_files = self._call_remote(remote, "get_package", pref, dest_folder) From c599f743c2730978c9a209b89c3ac4fadd1831a7 Mon Sep 17 00:00:00 2001 From: danimtb Date: Fri, 15 Mar 2019 17:43:19 +0100 Subject: [PATCH 12/20] Fix upload order in test --- conans/test/functional/command/upload_complete_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/conans/test/functional/command/upload_complete_test.py b/conans/test/functional/command/upload_complete_test.py index e3c199f2da2..20a23491721 100644 --- a/conans/test/functional/command/upload_complete_test.py +++ b/conans/test/functional/command/upload_complete_test.py @@ -175,7 +175,7 @@ def upload_error_test(self): client.run("upload Hello* --confirm --retry 1 --retry-wait=1", assert_error=True) self.assertNotIn("Waiting 1 seconds to retry...", client.user_io.out) self.assertIn("ERROR: Execute upload again to retry upload the failed files: " - "conanmanifest.txt. [Remote: default]", client.user_io.out) + "conan_export.tgz. [Remote: default]", client.user_io.out) # Try with broken connection even with 10 retries client = self._get_client(TerribleConnectionUploader) @@ -329,13 +329,13 @@ def upload_all_test(self): if line.startswith("Uploading")] self.assertEqual(lines, ["Uploading to remote 'default':", "Uploading Hello/1.2.1@frodo/stable to remote 'default'", - "Uploading conanmanifest.txt", - "Uploading conanfile.py", "Uploading conan_export.tgz", - "Uploading package 1/1: myfakeid to 'default'", + "Uploading conanfile.py", "Uploading conanmanifest.txt", - "Uploading conaninfo.txt", + "Uploading package 1/1: myfakeid to 'default'", "Uploading conan_package.tgz", + "Uploading conaninfo.txt", + "Uploading conanmanifest.txt", ]) if self.client.cache.config.revisions_enabled: layout = self.client.cache.package_layout(self.ref) From 96cc54e570d91b1d125f011e3439716a8ab101ba Mon Sep 17 00:00:00 2001 From: danimtb Date: Fri, 15 Mar 2019 18:13:27 +0100 Subject: [PATCH 13/20] method to check package integrity --- conans/client/remote_manager.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py index 6378b5fbb1b..eb56c329ac5 100644 --- a/conans/client/remote_manager.py +++ b/conans/client/remote_manager.py @@ -131,8 +131,7 @@ def get_package(self, pref, dest_folder, remote, output, recorder): try: pref = self._resolve_latest_pref(pref, remote) snapshot = self._call_remote(remote, "get_package_snapshot", pref) - if not any([keyword in key for keyword in ["conaninfo", "conanmanifest", "conan_package"] - for key in snapshot]): + if not self._snapshot_integrity(snapshot): raise NotFoundException zipped_files = self._call_remote(remote, "get_package", pref, dest_folder) @@ -245,6 +244,15 @@ def _call_remote(self, remote, method, *argc, **argv): logger.error(traceback.format_exc()) raise ConanException(exc, remote=remote) + @staticmethod + def _snapshot_integrity(snapshot): + integrity = True + for keyword in ["conaninfo", "conanmanifest", "conan_package"]: + if not any(keyword in key for key in snapshot): + integrity = False + break + return integrity + def check_compressed_files(tgz_name, files): bare_name = os.path.splitext(tgz_name)[0] From b6c454578cb2aaa7be7cfefe467ccdce14befc23 Mon Sep 17 00:00:00 2001 From: danimtb Date: Fri, 15 Mar 2019 19:10:37 +0100 Subject: [PATCH 14/20] Weird fix for test --- conans/test/integration/install_update_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conans/test/integration/install_update_test.py b/conans/test/integration/install_update_test.py index 2dda8410558..e1402a5d7a1 100644 --- a/conans/test/integration/install_update_test.py +++ b/conans/test/integration/install_update_test.py @@ -234,7 +234,7 @@ def reuse_test(self): self.client.run("install Hello0/1.0@lasote/stable --build") self.client.run("upload Hello0/1.0@lasote/stable --all") - client2 = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) + client2 = TestClient(servers=self.servers, users={"myremote": [("lasote", "mypass")]}) client2.run("install Hello0/1.0@lasote/stable") self.assertEquals(str(client2.out).count("Downloading conaninfo.txt"), 1) From e4b81d10d812db34c91a0a8f697e62f51529c41f Mon Sep 17 00:00:00 2001 From: danimtb Date: Fri, 15 Mar 2019 19:27:01 +0100 Subject: [PATCH 15/20] Check package snapshot in the upload --- conans/client/cmd/uploader.py | 3 +-- conans/client/remote_manager.py | 4 ++-- conans/test/functional/corrupted_packages_test.py | 11 +++++------ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/conans/client/cmd/uploader.py b/conans/client/cmd/uploader.py index 6a0f4c9aaff..f7df5bf99d9 100644 --- a/conans/client/cmd/uploader.py +++ b/conans/client/cmd/uploader.py @@ -360,7 +360,7 @@ def _package_files_to_upload(self, pref, policy, the_files, remote): remote_snapshot = self._remote_manager.get_package_snapshot(pref, remote) if remote_snapshot: - if CONAN_MANIFEST in remote_snapshot: + if self._remote_manager.package_snapshot_complete(remote_snapshot): remote_manifest, _ = self._remote_manager.get_package_manifest(pref, remote) local_manifest = FileTreeManifest.loads(load(the_files["conanmanifest.txt"])) @@ -372,7 +372,6 @@ def _package_files_to_upload(self, pref, policy, the_files, remote): "Forbidden overwrite.") files_to_upload = the_files deleted = set(remote_snapshot).difference(the_files) - return files_to_upload, deleted def _upload_recipe_end_msg(self, ref, remote): diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py index eb56c329ac5..30ee4ec4d67 100644 --- a/conans/client/remote_manager.py +++ b/conans/client/remote_manager.py @@ -131,7 +131,7 @@ def get_package(self, pref, dest_folder, remote, output, recorder): try: pref = self._resolve_latest_pref(pref, remote) snapshot = self._call_remote(remote, "get_package_snapshot", pref) - if not self._snapshot_integrity(snapshot): + if not self.package_snapshot_complete(snapshot): raise NotFoundException zipped_files = self._call_remote(remote, "get_package", pref, dest_folder) @@ -245,7 +245,7 @@ def _call_remote(self, remote, method, *argc, **argv): raise ConanException(exc, remote=remote) @staticmethod - def _snapshot_integrity(snapshot): + def package_snapshot_complete(snapshot): integrity = True for keyword in ["conaninfo", "conanmanifest", "conan_package"]: if not any(keyword in key for key in snapshot): diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index 14779c5b892..de744a79812 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -94,9 +94,9 @@ def tgz_info_missing_test(self): # Try upload of fresh package self.client.run("create . Pkg/0.1@user/testing") self.client.run("upload * --all --confirm") - # FIXME: tgz and info are not in the server and not uploaded - self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) - # self._assert_all_package_files_in_server() + self.assertIn("Uploading conan_package.tgz", self.client.out) + self.assertIn("Uploading conaninfo.txt", self.client.out) + self._assert_all_package_files_in_server() def tgz_missing_test(self): os.unlink(self.tgz_path) @@ -109,9 +109,8 @@ def tgz_missing_test(self): # Try upload of fresh package self.client.run("create . Pkg/0.1@user/testing") self.client.run("upload * --all --confirm") - # FIXME: tgz is not in the server and not uploaded - self.assertIn("Package is up to date, upload skipped", self.client.user_io.out) - #self._assert_all_package_files_in_server() + self.assertIn("Uploading conan_package.tgz", self.client.out) + self._assert_all_package_files_in_server() def tgz_manifest_missing_test(self): os.unlink(self.tgz_path) From 5bd7a80da8928b7d1479d0ea83729093697843ac Mon Sep 17 00:00:00 2001 From: danimtb Date: Fri, 15 Mar 2019 19:43:39 +0100 Subject: [PATCH 16/20] Added clarification --- conans/client/rest/rest_client_v1.py | 2 ++ conans/client/rest/rest_client_v2.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/conans/client/rest/rest_client_v1.py b/conans/client/rest/rest_client_v1.py index 267d9bbc9d7..9c3e1f06d1a 100644 --- a/conans/client/rest/rest_client_v1.py +++ b/conans/client/rest/rest_client_v1.py @@ -142,6 +142,8 @@ def _upload_files(self, file_urls, files, output, retry, retry_wait): t1 = time.time() failed = [] uploader = Uploader(self.requester, output, self.verify_ssl) + # conan_package.tgz and conan_export.tgz are uploaded first to avoid uploading conaninfo.txt + # or conanamanifest.txt with missing files due to a network failure for filename, resource_url in sorted(file_urls.items()): output.rewrite_line("Uploading %s" % filename) auth, dedup = self._file_server_capabilities(resource_url) diff --git a/conans/client/rest/rest_client_v2.py b/conans/client/rest/rest_client_v2.py index 08a9938fc34..c693fa5d9cd 100644 --- a/conans/client/rest/rest_client_v2.py +++ b/conans/client/rest/rest_client_v2.py @@ -174,6 +174,8 @@ def _upload_files(self, files, urls, retry, retry_wait): t1 = time.time() failed = [] uploader = Uploader(self.requester, self._output, self.verify_ssl) + # conan_package.tgz and conan_export.tgz are uploaded first to avoid uploading conaninfo.txt + # or conanamanifest.txt with missing files due to a network failure for filename in sorted(files): self._output.rewrite_line("Uploading %s" % filename) resource_url = urls[filename] From a707efdea265e5cc2170b9d7dc4282acad994ca6 Mon Sep 17 00:00:00 2001 From: danimtb Date: Mon, 18 Mar 2019 12:35:23 +0100 Subject: [PATCH 17/20] fix env var for revisions testing --- conans/test/functional/corrupted_packages_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index de744a79812..1388ba1edb3 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -15,7 +15,7 @@ class CorruptedPackagesTest(unittest.TestCase): """ def setUp(self): - revisions_enabled = get_env("CONAN_REVISIONS_ENABLED") + revisions_enabled = get_env("TESTING_REVISIONS_ENABLED") self.server = TestServer([("*/*@*/*", "*")], [("*/*@*/*", "*")]) self.client = TestClient(servers={"default": self.server}) conanfile = textwrap.dedent(""" From bc9b220758191ac0c1e55453192f5a6902afcb49 Mon Sep 17 00:00:00 2001 From: danimtb Date: Mon, 18 Mar 2019 16:37:11 +0100 Subject: [PATCH 18/20] get_env with false --- conans/test/functional/corrupted_packages_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conans/test/functional/corrupted_packages_test.py b/conans/test/functional/corrupted_packages_test.py index 1388ba1edb3..04a9611cdc7 100644 --- a/conans/test/functional/corrupted_packages_test.py +++ b/conans/test/functional/corrupted_packages_test.py @@ -15,7 +15,7 @@ class CorruptedPackagesTest(unittest.TestCase): """ def setUp(self): - revisions_enabled = get_env("TESTING_REVISIONS_ENABLED") + revisions_enabled = get_env("TESTING_REVISIONS_ENABLED", False) self.server = TestServer([("*/*@*/*", "*")], [("*/*@*/*", "*")]) self.client = TestClient(servers={"default": self.server}) conanfile = textwrap.dedent(""" @@ -36,7 +36,7 @@ class Pkg(ConanFile): pref_str = "Pkg/0.1@user/testing#%s" % rrev prev = "11de80325e8db78617b05384825c6409" if revisions_enabled else "0" self.pref = pref = PackageReference(ConanFileReference.loads(pref_str), - NO_SETTINGS_PACKAGE_ID, prev) + NO_SETTINGS_PACKAGE_ID, prev) self.manifest_path = self.server.server_store.get_package_file_path(pref, "conanmanifest.txt") self.info_path = self.server.server_store.get_package_file_path(pref, "conaninfo.txt") From ff00ddf4af7570b7f0627438910e046d05f8000c Mon Sep 17 00:00:00 2001 From: danimtb Date: Thu, 21 Mar 2019 19:35:35 +0100 Subject: [PATCH 19/20] review --- conans/client/cmd/uploader.py | 24 +++++++++++------------- conans/client/remote_manager.py | 20 ++++++++++---------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/conans/client/cmd/uploader.py b/conans/client/cmd/uploader.py index e472bb024c9..a1a7d3faaf1 100644 --- a/conans/client/cmd/uploader.py +++ b/conans/client/cmd/uploader.py @@ -4,6 +4,7 @@ import time from collections import defaultdict +from conans.client.remote_manager import is_package_snapshot_complete from conans.client.source import complete_recipe_sources from conans.errors import ConanException, NotFoundException from conans.model.manifest import gather_files, FileTreeManifest @@ -352,23 +353,20 @@ def _recipe_files_to_upload(self, ref, policy, the_files, remote, remote_manifes return files_to_upload, deleted def _package_files_to_upload(self, pref, policy, the_files, remote): - # Get the remote snapshot remote_snapshot = self._remote_manager.get_package_snapshot(pref, remote) if remote_snapshot: - if self._remote_manager.package_snapshot_complete(remote_snapshot): - remote_manifest, _ = self._remote_manager.get_package_manifest(pref, remote) - local_manifest = FileTreeManifest.loads(load(the_files["conanmanifest.txt"])) - - if remote_manifest == local_manifest: - return None, None - - if policy == UPLOAD_POLICY_NO_OVERWRITE: - raise ConanException("Local package is different from the remote package. " - "Forbidden overwrite.") - files_to_upload = the_files + if not is_package_snapshot_complete(remote_snapshot): + return the_files, set([]) + remote_manifest, _ = self._remote_manager.get_package_manifest(pref, remote) + local_manifest = FileTreeManifest.loads(load(the_files["conanmanifest.txt"])) + if remote_manifest == local_manifest: + return None, None + if policy == UPLOAD_POLICY_NO_OVERWRITE: + raise ConanException("Local package is different from the remote package. Forbidden " + "overwrite.") deleted = set(remote_snapshot).difference(the_files) - return files_to_upload, deleted + return the_files, deleted def _upload_recipe_end_msg(self, ref, remote): msg = "Uploaded conan recipe '%s' to '%s'" % (str(ref), remote.name) diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py index 30ee4ec4d67..a55667919cd 100644 --- a/conans/client/remote_manager.py +++ b/conans/client/remote_manager.py @@ -131,8 +131,8 @@ def get_package(self, pref, dest_folder, remote, output, recorder): try: pref = self._resolve_latest_pref(pref, remote) snapshot = self._call_remote(remote, "get_package_snapshot", pref) - if not self.package_snapshot_complete(snapshot): - raise NotFoundException + if not is_package_snapshot_complete(snapshot): + raise NotFoundException("") zipped_files = self._call_remote(remote, "get_package", pref, dest_folder) with self._cache.package_layout(pref.ref).update_metadata() as metadata: @@ -244,14 +244,14 @@ def _call_remote(self, remote, method, *argc, **argv): logger.error(traceback.format_exc()) raise ConanException(exc, remote=remote) - @staticmethod - def package_snapshot_complete(snapshot): - integrity = True - for keyword in ["conaninfo", "conanmanifest", "conan_package"]: - if not any(keyword in key for key in snapshot): - integrity = False - break - return integrity + +def is_package_snapshot_complete(snapshot): + integrity = True + for keyword in ["conaninfo", "conanmanifest", "conan_package"]: + if not any(keyword in key for key in snapshot): + integrity = False + break + return integrity def check_compressed_files(tgz_name, files): From db9155d17694c484ad01fc56e708f094adffd580 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 22 Mar 2019 10:27:50 +0100 Subject: [PATCH 20/20] Raise PackageNotFoundException with pref message --- conans/client/remote_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py index a55667919cd..8aea2cc3120 100644 --- a/conans/client/remote_manager.py +++ b/conans/client/remote_manager.py @@ -132,7 +132,7 @@ def get_package(self, pref, dest_folder, remote, output, recorder): pref = self._resolve_latest_pref(pref, remote) snapshot = self._call_remote(remote, "get_package_snapshot", pref) if not is_package_snapshot_complete(snapshot): - raise NotFoundException("") + raise PackageNotFoundException(pref) zipped_files = self._call_remote(remote, "get_package", pref, dest_folder) with self._cache.package_layout(pref.ref).update_metadata() as metadata: