def upload_dirty_test(self): test_server = TestServer([], users={"lasote": "mypass"}) client = TestClient(servers={"default": test_server}, users={"default": [("lasote", "mypass")]}) client.save({"conanfile.py": str(TestConanFile())}) client.run("export . lasote/testing") ref = ConanFileReference.loads("Hello/0.1@lasote/testing") pkg_ref = PackageReference(ref, "12345") package_folder = client.client_cache.package(pkg_ref) recipe_rev = client.get_revision(ref) p_rev = client.get_package_revision(pkg_ref) with client.client_cache.update_metadata(pkg_ref.conan) as metadata: metadata.packages[pkg_ref.package_id].revision = p_rev metadata.packages[pkg_ref.package_id].recipe_revision = recipe_rev save(os.path.join(package_folder, "conanmanifest.txt"), "888") set_dirty(package_folder) client.run("upload * --all --confirm", assert_error=True) self.assertIn( "ERROR: Package Hello/0.1@lasote/testing:12345 is corrupted, aborting upload", client.out) self.assertIn( "Remove it with 'conan remove Hello/0.1@lasote/testing -p=12345'", client.out) client.run("remove Hello/0.1@lasote/testing -p=12345 -f") client.run("upload * --all --confirm")
def test_v1_with_revisions_behavior(self): client_no_rev = TestClient(block_v2=True, servers=self.servers, users=self.users) conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): def build(self): self.output.warn("Hello") ''' client_no_rev.save({"conanfile.py": conanfile}) client_no_rev.run("create . %s" % str(self.ref)) client_no_rev.run("upload %s -c --all -r remote0" % str(self.ref)) rev1 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertEquals(rev1, DEFAULT_REVISION_V1) # An upload from the other client with revisions puts a new revision as latest self.client.save({"conanfile.py": conanfile.replace("Hello", "Bye")}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev1 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertNotEquals(rev1, DEFAULT_REVISION_V1) client_no_rev.run('remove "*" -f') client_no_rev.run("install %s --build" % str(self.ref)) # Client v1 never receives revision but 0 self.assertEquals(client_no_rev.get_revision(self.ref), DEFAULT_REVISION_V1) self.assertIn("Bye", client_no_rev.out) # If client v1 uploads again the recipe it is the latest again, but with rev0 client_no_rev.save({"conanfile.py": conanfile.replace("Hello", "Foo")}) client_no_rev.run("create . %s" % str(self.ref)) client_no_rev.run("upload %s -c --all -r remote0" % str(self.ref)) rev1 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertEquals(rev1, DEFAULT_REVISION_V1) # Even for the client with revision, now the latest is 0 self.client.run('remove "*" -f') self.client.run("install %s --build" % str(self.ref)) self.assertIn("Foo", self.client.out) self.assertEquals(self.client.get_revision(self.ref), DEFAULT_REVISION_V1)
def test_update_recipe(self): self.client.save({"conanfile.py": self.conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) self.client.run("remote list_ref") pref = PackageReference.loads( "lib/1.0@lasote/testing:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertIn("%s: remote0" % str(self.ref), self.client.out) self.client.run("remote list_pref %s" % str(self.ref)) self.assertIn("%s: remote0" % str(pref), self.client.out) rev = self.client.get_revision(self.ref) self.assertEquals(rev, "149570a812b46d87c7dfa6408809b370") sleep(1) client2 = TestClient(servers=self.servers, users=self.users) conanfile2 = self.conanfile + "# Holaaa " client2.save({"conanfile.py": conanfile2}) client2.run("create . %s" % str(self.ref)) client2.run("upload %s -c --all -r remote0" % str(self.ref)) client2.run("remote list_pref %s" % str(self.ref)) rev = client2.get_revision(self.ref) self.assertEquals(rev, "621568e8053761d685dcf1bfbe3b3f10") # install of the client1 (no-update) self.client.run("install %s" % str(self.ref)) self.assertIn("lib/1.0@lasote/testing from 'remote0' - Cache", self.client.out) self.assertIn("%s - Cache" % str(pref), self.client.out) self.client.run("remote list_pref %s" % str(self.ref)) self.assertIn("%s: remote0" % str(pref), self.client.out) rev = self.client.get_revision(self.ref) self.assertEquals(rev, "149570a812b46d87c7dfa6408809b370") # install with update self.client.run("install %s --update" % str(self.ref)) rev = self.client.get_revision(self.ref) self.assertEquals(rev, "621568e8053761d685dcf1bfbe3b3f10") self.assertNotIn("%s from 'remote0' - Newer" % str(self.ref), self.client.out) self.assertIn( "Outdated package! The package doesn't belong to the installed recipe " "revision:", self.client.out) self.assertIn("%s from 'remote0' - Updated" % str(self.ref), self.client.out) self.assertIn("%s - Update" % str(pref), self.client.out)
class SynchronizeTest(unittest.TestCase): def setUp(self): test_server = TestServer() self.servers = {"default": test_server} self.client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) def upload_test(self): conan_reference = ConanFileReference.loads( "Hello0/0.1@lasote/stable#%s" % DEFAULT_REVISION_V1) files = cpp_hello_conan_files("Hello0", "0.1") files["to_be_deleted.txt"] = "delete me" files["to_be_deleted2.txt"] = "delete me2" remote_paths = self.client.servers["default"].server_store self.client.save(files) self.client.run("export . lasote/stable") # Upload conan file self.client.run("upload %s" % str(conan_reference)) # Verify the files are there if not self.client.block_v2: rev = self.client.get_revision(conan_reference) conan_reference = conan_reference.copy_with_rev(rev) server_conan_path = remote_paths.export(conan_reference) self.assertTrue( os.path.exists(os.path.join(server_conan_path, EXPORT_TGZ_NAME))) tmp = temp_folder() untargz(os.path.join(server_conan_path, EXPORT_TGZ_NAME), tmp) self.assertTrue(load(os.path.join(tmp, "to_be_deleted.txt")), "delete me") self.assertTrue(load(os.path.join(tmp, "to_be_deleted2.txt")), "delete me2") # Now delete local files export and upload and check that they are not in server os.remove(os.path.join(self.client.current_folder, "to_be_deleted.txt")) self.client.run("export . lasote/stable") self.client.run("upload %s" % str(conan_reference)) if not self.client.block_v2: rev = self.client.get_revision(conan_reference) conan_reference = conan_reference.copy_with_rev(rev) server_conan_path = remote_paths.export(conan_reference) self.assertTrue( os.path.exists(os.path.join(server_conan_path, EXPORT_TGZ_NAME))) tmp = temp_folder() untargz(os.path.join(server_conan_path, EXPORT_TGZ_NAME), tmp) self.assertFalse(os.path.exists(os.path.join(tmp, "to_be_deleted.txt"))) self.assertTrue(os.path.exists(os.path.join(tmp, "to_be_deleted2.txt"))) # Now modify a file, and delete other, and put a new one. files["to_be_deleted2.txt"] = "modified content" files["new_file.lib"] = "new file" del files["to_be_deleted.txt"] self.client.save(files) self.client.run("export . lasote/stable") self.client.run("upload %s" % str(conan_reference)) if not self.client.block_v2: rev = self.client.get_revision(conan_reference) conan_reference = conan_reference.copy_with_rev(rev) server_conan_path = remote_paths.export(conan_reference) # Verify all is correct self.assertTrue( os.path.exists(os.path.join(server_conan_path, EXPORT_TGZ_NAME))) tmp = temp_folder() untargz(os.path.join(server_conan_path, EXPORT_TGZ_NAME), tmp) self.assertTrue(load(os.path.join(tmp, "to_be_deleted2.txt")), "modified content") self.assertTrue(load(os.path.join(tmp, "new_file.lib")), "new file") self.assertFalse(os.path.exists(os.path.join(tmp, "to_be_deleted.txt"))) ########################## # Now try with the package ########################## self.client.run("install %s --build missing" % str(conan_reference)) # Upload package package_ids = self.client.client_cache.conan_packages(conan_reference) self.client.run("upload %s -p %s" % (str(conan_reference), str(package_ids[0]))) # Check that conans exists on server package_reference = PackageReference(conan_reference, str(package_ids[0])) package_server_path = remote_paths.package(package_reference) self.assertTrue(os.path.exists(package_server_path)) # Add a new file to package (artificially), upload again and check pack_path = self.client.client_cache.package(package_reference) new_file_source_path = os.path.join(pack_path, "newlib.lib") save(new_file_source_path, "newlib") os.unlink(os.path.join(pack_path, PACKAGE_TGZ_NAME)) # Force new tgz self._create_manifest(package_reference) self.client.run("upload %s -p %s" % (str(conan_reference), str(package_ids[0]))) folder = uncompress_packaged_files(remote_paths, package_reference) remote_file_path = os.path.join(folder, "newlib.lib") self.assertTrue(os.path.exists(remote_file_path)) # Now modify the file and check again save(new_file_source_path, "othercontent") self._create_manifest(package_reference) self.client.run("upload %s -p %s" % (str(conan_reference), str(package_ids[0]))) folder = uncompress_packaged_files(remote_paths, package_reference) remote_file_path = os.path.join(folder, "newlib.lib") self.assertTrue(os.path.exists(remote_file_path)) self.assertTrue(load(remote_file_path), "othercontent") # Now delete the file and check again os.remove(new_file_source_path) self._create_manifest(package_reference) os.unlink(os.path.join(pack_path, PACKAGE_TGZ_NAME)) # Force new tgz self.client.run("upload %s -p %s" % (str(conan_reference), str(package_ids[0]))) folder = uncompress_packaged_files(remote_paths, package_reference) remote_file_path = os.path.join(folder, "newlib.lib") # With revisions makes no sense because there is a new revision always that sources change if not self.client.revisions: self.assertFalse(os.path.exists(remote_file_path)) self.assertNotEquals(remote_file_path, new_file_source_path) def _create_manifest(self, package_reference): # Create the manifest to be able to upload the package pack_path = self.client.client_cache.package(package_reference) expected_manifest = FileTreeManifest.create(pack_path) expected_manifest.save(pack_path)
class MultiRemoteTest(unittest.TestCase): def setUp(self): self.servers = OrderedDict() self.users = {} for i in range(3): test_server = TestServer() self.servers["remote%d" % i] = test_server self.users["remote%d" % i] = [("lasote", "mypass")] self.client = TestClient(servers=self.servers, users=self.users) def predefine_remote_test(self): files = cpp_hello_conan_files("Hello0", "0.1", build=False) self.client.save(files) self.client.run("export . lasote/stable") self.client.run("upload Hello0/0.1@lasote/stable -r=remote0") self.client.run("upload Hello0/0.1@lasote/stable -r=remote1") self.client.run("upload Hello0/0.1@lasote/stable -r=remote2") self.client.run('remove "*" -f') self.client.run("remote add_ref Hello0/0.1@lasote/stable remote1") self.client.run("install Hello0/0.1@lasote/stable --build=missing") self.assertIn( "Hello0/0.1@lasote/stable: Retrieving from predefined remote 'remote1'", self.client.user_io.out) self.client.run("remote list_ref") self.assertIn(": remote1", self.client.user_io.out) def upload_test(self): conan_reference = ConanFileReference.loads("Hello0/0.1@lasote/stable") files = cpp_hello_conan_files("Hello0", "0.1", build=False) self.client.save(files) self.client.run("export . lasote/stable") self.client.run("upload %s" % str(conan_reference)) self.client.run("info %s" % str(conan_reference)) self.assertIn("remote0=http://", self.client.user_io.out) # The remote, once fixed does not change self.client.run("upload %s -r=remote1" % str(conan_reference)) self.client.run("info %s" % str(conan_reference)) self.assertIn("remote0=http://", self.client.user_io.out) # Now install it in other machine from remote 0 client2 = TestClient(servers=self.servers, users=self.users) client2.run("install %s --build=missing" % str(conan_reference)) client2.run("info %s" % str(conan_reference)) self.assertIn("remote0=http://", client2.user_io.out) # Now install it in other machine from remote 1 servers = self.servers.copy() servers.pop("remote0") client3 = TestClient(servers=servers, users=self.users) client3.run("install %s --build=missing" % str(conan_reference)) client3.run("info %s" % str(conan_reference)) self.assertIn("remote1=http://", client3.user_io.out) def fail_when_not_notfound_test(self): """ If a remote fails with a 404 it has to keep looking in the next remote, but if it fails by any other reason it has to stop """ servers = OrderedDict() servers["s0"] = TestServer() servers["s1"] = TestServer() servers["s2"] = TestServer() client = TestClient(servers=servers, users=self.users) files = cpp_hello_conan_files("MyLib", "0.1", build=False) client.save(files) client.run("create . lasote/testing") client.run("user lasote -p mypass -r s1") client.run("upload MyLib* -r s1 -c") servers[ "s1"].fake_url = "http://asdlhaljksdhlajkshdljakhsd" # Do not exist client2 = TestClient(servers=servers, users=self.users) err = client2.run("install MyLib/0.1@conan/testing --build=missing", assert_error=True) self.assertTrue(err) self.assertIn("MyLib/0.1@conan/testing: Trying with 's0'...", client2.out) self.assertIn("MyLib/0.1@conan/testing: Trying with 's1'...", client2.out) self.assertIn( "Unable to connect to s1=http://asdlhaljksdhlajkshdljakhsd", client2.out) # s2 is not even tried self.assertNotIn("MyLib/0.1@conan/testing: Trying with 's2'...", client2.out) def install_from_remotes_test(self): for i in range(3): conan_reference = ConanFileReference.loads( "Hello%d/0.1@lasote/stable" % i) files = cpp_hello_conan_files("Hello%d" % i, "0.1", build=False) self.client.save(files) self.client.run("export . lasote/stable") self.client.run("upload %s -r=remote%d" % (str(conan_reference), i)) self.client.run("info %s" % str(conan_reference)) self.assertIn("remote%d=http://" % i, self.client.user_io.out) # Now install it in other machine from remote 0 client2 = TestClient(servers=self.servers, users=self.users) files = cpp_hello_conan_files("HelloX", "0.1", deps=[ "Hello0/0.1@lasote/stable", "Hello1/0.1@lasote/stable", "Hello2/0.1@lasote/stable" ]) files["conanfile.py"] = files["conanfile.py"].replace( "def build(", "def build2(") client2.save(files) client2.run("install . --build=missing") self.assertIn("Hello0/0.1@lasote/stable from 'remote0'", client2.user_io.out) self.assertIn("Hello1/0.1@lasote/stable from 'remote1'", client2.user_io.out) self.assertIn("Hello2/0.1@lasote/stable from 'remote2'", client2.user_io.out) client2.run("info .") self.assertIn("Remote: remote0=http://", client2.user_io.out) self.assertIn("Remote: remote1=http://", client2.user_io.out) self.assertIn("Remote: remote2=http://", client2.user_io.out) @unittest.skipIf( TestClient().revisions, "This test is not valid for revisions, where we keep iterating the remotes " "for searching a package for the same recipe revision") def package_binary_remote_test(self): # https://github.com/conan-io/conan/issues/3882 conanfile = """from conans import ConanFile class ConanFileToolsTest(ConanFile): pass """ # Upload recipe + package to remote1 and remote2 ref = "Hello/0.1@lasote/stable" self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s" % ref) self.client.run("upload %s -r=remote0 --all" % ref) self.client.run("upload %s -r=remote2 --all" % ref) rev1 = self.client.get_revision(ConanFileReference.loads(ref)) # Remove only binary from remote1 and everything in local self.client.run("remove -f %s -p -r remote0" % ref) self.client.run('remove "*" -f') self.servers.pop("remote1") # Now install it from a client, it won't find the binary in remote2 self.client.run("install %s" % ref, assert_error=True) self.assertIn("Can't find a 'Hello/0.1@lasote/stable' package", self.client.out) self.assertNotIn("remote2", self.client.out) self.client.run("install %s -r remote2" % ref) self.assertIn( "Package installed 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", self.client.out) self.assertIn("Hello/0.1@lasote/stable from 'remote0' - Cache", self.client.out) registry = load(self.client.client_cache.registry_path) registry = json.loads(registry) self.assertEquals(registry["references"], {"Hello/0.1@lasote/stable": "remote0"}) self.assertEquals( registry["package_references"], { "Hello/0.1@lasote/stable:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9": "remote2" }) client2 = TestClient(servers=self.servers, users=self.users) time.sleep(1) # Make sure timestamps increase client2.save({"conanfile.py": conanfile + " # Comment"}) client2.run("create . %s" % ref) client2.run("upload %s -r=remote2 --all" % ref) # Install from client, it should update the package from remote2 self.client.run("install %s --update" % ref) self.assertNotIn( "Hello/0.1@lasote/stable: WARN: Can't update, no package in remote", self.client.out) self.assertIn( "Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Update", self.client.out) self.assertIn("Downloading conan_package.tgz", self.client.out) if not self.client.revisions and not self.client.block_v2: self.client.run("install %s#%s --update" % (ref, rev1)) self.assertIn( "Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", self.client.out)
class CompatibilityRevisionsTest(unittest.TestCase): """Testing non breaking behavior from v1 and v2 with compatibility mode""" def setUp(self): self.servers = OrderedDict() self.servers["remote0"] = TestServer(server_capabilities=[REVISIONS]) self.users = { "remote0": [("lasote", "mypass")], "remote_norevisions": [("lasote", "mypass")] } self.servers["remote_norevisions"] = TestServer(server_capabilities=[]) self.client = TestClient(servers=self.servers, users=self.users) self.conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): def build(self): self.output.warn("Revision 1") ''' self.ref = ConanFileReference.loads("lib/1.0@lasote/testing") def test_search_v1_iterate_remotes(self): """Two recipe revisions, first with 1 binary, second with 1 binary, search v1 and v2 with compatibility, have to find both""" conanfile = """from conans import ConanFile class ConanFileToolsTest(ConanFile): settings = "os" """ # Upload recipe + package to remote0 ref = "Hello/0.1@lasote/stable" self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s -s os=Windows" % ref) self.client.run("upload %s -r=remote0 --all" % ref) conanfile += " " self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s -s os=Linux" % ref) self.client.run("upload %s -r=remote0 --all" % ref) client_no_rev = TestClient(block_v2=True, servers=self.servers, users=self.users) client_no_rev.run("search %s -r remote0" % ref) self.assertIn("3475bd55b91ae904ac96fde0f106a136ab951a5e", client_no_rev.out) self.assertIn("cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", client_no_rev.out) client_compatibility = TestClient(block_v2=True, revisions=False, servers=self.servers, users=self.users) client_compatibility.run("search %s -r remote0" % ref) self.assertIn("3475bd55b91ae904ac96fde0f106a136ab951a5e", client_compatibility.out) self.assertIn("cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", client_compatibility.out) # And not repeated even if duplicated in remote self.client.run("create . %s -s os=Windows" % ref) self.client.run("upload %s -r=remote0 --all" % ref) client_no_rev.run("search %s -r remote0" % ref) self.assertEquals( str(client_no_rev.out).count( "3475bd55b91ae904ac96fde0f106a136ab951a5e"), 1) self.assertEquals( str(client_no_rev.out).count( "cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31"), 1) def test_remove_packages_from_recipe_revision(self): """It shouldn't remove the packages for all recipe revisions but only for the specified if a recipe revision is specified""" conanfile = """from conans import ConanFile class ConanFileToolsTest(ConanFile): pass """ ref = ConanFileReference.loads("Hello/0.1@lasote/stable") # Upload recipe rev 1 + package to remote0 self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s" % str(ref)) self.client.run("upload %s -r=remote0 --all" % str(ref)) rev1 = self.client.get_revision(ref) # Upload recipe rev 2 + package to remote0 self.client.save({"conanfile.py": conanfile + "\n"}) self.client.run("create . %s" % str(ref)) self.client.run("upload %s -r=remote0 --all" % str(ref)) rev2 = self.client.get_revision(ref) # Remove the binaries from the recipe rev1 self.client.run("remove %s#%s -p -r=remote0 -f" % (str(ref), rev1)) self.client.run("remove %s -f" % str(ref)) # Try to install binaries from the rev1, it should fail self.client.run("install %s#%s" % (str(ref), rev1), assert_error=True) self.assertIn("Missing prebuilt package for 'Hello/0.1@lasote/stable", self.client.out) # Try to install binaries from the rev2, it should succeed self.client.run("install %s#%s" % (str(ref), rev2)) # Also try without specifying revision self.client.run("remove %s -f" % str(ref)) self.client.run("install %s" % str(ref)) def test_install_recipe_revision(self): """ Specifying the revision, it has to install that revision. """ conanfile = """from conans import ConanFile class ConanFileToolsTest(ConanFile): pass """ ref = ConanFileReference.loads("Hello/0.1@lasote/stable") # Upload recipe rev 1 + package to remote0 self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s" % str(ref)) self.client.run("upload %s -r=remote0 --all" % str(ref)) rev1 = self.client.get_revision(ref) # Upload recipe rev 2 + package to remote0 self.client.save({"conanfile.py": conanfile + "\n#Comment for rev2"}) self.client.run("create . %s" % str(ref)) self.client.run("upload %s -r=remote0 --all" % str(ref)) rev2 = self.client.get_revision(ref) self.assertNotEqual(rev1, rev2) # Remove all from local self.client.run("remove %s -f" % str(ref)) # Try to install rev1 and not rev2 self.client.run("install %s#%s" % (str(ref), rev1)) conanfile_path = self.client.client_cache.conanfile(ref) contents = load(conanfile_path) self.assertNotIn("#Comment for rev2", contents) # Remove all from local self.client.run("remove %s -f" % str(ref)) # Try to install rev2 and not rev1 self.client.run("install %s#%s" % (str(ref), rev2)) conanfile_path = self.client.client_cache.conanfile(ref) contents = load(conanfile_path) self.assertIn("#Comment for rev2", contents) def test_update_from_same_revision_test(self): """ If I specify conan install ref#revision --update it has to update to the latest binary of the same recipe. """ conanfile = """ import time import os from conans import ConanFile, tools class ConanFileToolsTest(ConanFile): def package(self): tools.save(os.path.join(self.package_folder, "file.txt"), str(time.time())) """ ref = ConanFileReference.loads("Hello/0.1@lasote/stable") # Generate recipe rev 1 + package rev1 to remote0 self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s" % str(ref)) self.client.run("upload %s -r=remote0 --all" % str(ref)) rev1 = self.client.get_revision(ref) package_ref = PackageReference(ref.copy_with_rev(rev1), NO_SETTINGS_PACKAGE_ID) prev1 = self.client.servers[ "remote0"].server_store.get_last_package_revision( package_ref).revision # Use another client to install the only binary revision for ref client2 = TestClient(servers=self.servers, users=self.users) client2.run("install %s" % str(ref)) # Generate recipe rev1 + package rev2 to remote0 time.sleep(1) self.client.run("remove %s -f" % str(ref)) self.client.run("create . %s" % str(ref)) self.client.run("upload %s -r=remote0 --all" % str(ref)) rev1_ = self.client.get_revision(ref) self.assertEquals(rev1, rev1_) package_ref = PackageReference(ref.copy_with_rev(rev1), NO_SETTINGS_PACKAGE_ID) prev2 = self.client.servers[ "remote0"].server_store.get_last_package_revision( package_ref).revision self.assertNotEqual(prev1, prev2) # Verify a new package revision is uploaded # Generate another recipe revision (and also bin revision) self.client.save({"conanfile.py": conanfile + "\n"}) self.client.run("create . %s" % str(ref)) self.client.run("upload %s -r=remote0 --all" % str(ref)) # So, from client2 I install --update pinning the first recipe revision, # I don't want the recipe to be updated but the binary client2.run("install %s#%s --update" % (str(ref), rev1)) self.assertNotIn("Hello/0.1@lasote/stable from 'remote0' - Updated", client2.out) self.assertIn( "Hello/0.1@lasote/stable:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Update", client2.out) prev_ = client2.get_package_revision(package_ref) self.assertEquals(prev_, prev2) def old_server_new_client_simple_test(self): """Use this test as an example to try some new behavior with revisions against a server without revisions""" old_server = TestServer(server_capabilities=[]) users = {"old_server": [("lasote", "mypass")]} client = TestClient(servers={"old_server": old_server}, users=users) conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): def build(self): self.output.warn("Revision 1") ''' ref = ConanFileReference.loads("lib/1.0@lasote/testing") client.save({"conanfile.py": conanfile + "\n"}) client.run("create . %s" % str(ref)) client.run("upload %s -r=old_server --all" % str(ref)) client.run("remove %s -f" % str(ref)) client.run("install %s" % str(ref)) package_ref = PackageReference(ref.copy_with_rev(DEFAULT_REVISION_V1), NO_SETTINGS_PACKAGE_ID) prev2 = client.servers[ "old_server"].server_store.get_last_package_revision(package_ref) self.assertEquals(prev2.revision, DEFAULT_REVISION_V1)
class RevisionsTest(unittest.TestCase): def setUp(self): self.servers = OrderedDict() self.users = {} for i in range(3): self.servers["remote%d" % i] = TestServer(server_capabilities=[REVISIONS]) self.users["remote%d" % i] = [("lasote", "mypass")] self.servers["remote_norevisions"] = TestServer(server_capabilities=[]) self.users["remote_norevisions"] = [("lasote", "mypass")] self.client = TestClient(servers=self.servers, users=self.users) self.conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): def build(self): self.output.warn("Revision 1") ''' self.ref = ConanFileReference.loads("lib/1.0@lasote/testing") def _create_and_upload(self, conanfile, reference, remote=None, args=""): remote = remote or "remote0" self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s %s" % (str(reference), args)) self.client.run("upload %s -c --all -r %s" % (str(reference), remote)) def test_revisions_recipes_without_scm(self): self._create_and_upload(self.conanfile, self.ref) rev = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertEquals(rev, "149570a812b46d87c7dfa6408809b370") # Create a new revision and upload conanfile = self.conanfile.replace("Revision 1", "Revision 2") self._create_and_upload(conanfile, self.ref) # Remove local and install latest self.client.run("remove %s -f" % str(self.ref)) self.client.run("install %s --build" % str(self.ref)) self.assertIn("Revision 2", self.client.out) # Remove local and install first self.client.run("remove %s -f" % str(self.ref)) self.client.run("install %s#149570a812b46d87c7dfa6408809b370 --build" % str(self.ref)) self.assertIn("Revision 1", self.client.out) def test_revision_with_fixed_scm(self): conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): scm = {"type": "git", "url": "auto", "revision": "fixed_revision"} ''' path, commit = create_local_git_repo( { "myfile": "contents", "conanfile.py": conanfile }, branch="my_release") self.client.current_folder = path self.client.runner('git remote add origin https://myrepo.com.git', cwd=path) self.client.save({"conanfile.py": conanfile}) self.client.run("export . %s " % str(self.ref)) rev = self.client.get_revision(self.ref) self.assertNotEqual(rev, "fixed_revision") def test_revisions_packages_download(self): conanfile = ''' import os from conans import ConanFile, tools class HelloConan(ConanFile): def build(self): tools.save("myfile.txt", os.getenv("PACKAGE_CONTENTS")) def package(self): self.copy("*") ''' with environment_append({"PACKAGE_CONTENTS": "1"}): self._create_and_upload(conanfile, self.ref) rev = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertEquals(rev, "202f9ce41808083a0f0c0d071fb5f398") self.ref = self.ref.copy_with_rev(rev) p_ref = PackageReference(self.ref, "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") pkg_rev = self.servers[ "remote0"].server_store.get_last_package_revision(p_ref).revision self.assertEquals(pkg_rev, "15ab113a16e2ac8c9ecffb4ba48306b2") # Create new package revision for the same recipe with environment_append({"PACKAGE_CONTENTS": "2"}): self._create_and_upload(conanfile, self.ref.copy_clear_rev()) pkg_rev = self.servers[ "remote0"].server_store.get_last_package_revision(p_ref).revision self.assertEquals(pkg_rev, "8e54c6ea967722f2f9bdcbacb21792f5") # Delete all from local self.client.run("remove %s -f" % str(self.ref.copy_clear_rev())) # Download specifying recipe with revisions and package with revisions self.client.run( "download %s -p 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9#" "8e54c6ea967722f2f9bdcbacb21792f5" % self.ref.full_repr()) contents = load( os.path.join(self.client.client_cache.package(p_ref), "myfile.txt")) self.assertEquals(contents, "2") # Download previous package revision self.client.run( "download %s -p 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9#" "15ab113a16e2ac8c9ecffb4ba48306b2" % self.ref.full_repr()) contents = load( os.path.join(self.client.client_cache.package(p_ref), "myfile.txt")) self.assertEquals(contents, "1") # Specify a package revision without a recipe revision self.client.run( "download %s -p 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9#" "15ab113a16e2ac8c9ecffb4ba48306b2" % str(self.ref), assert_error=True) self.assertIn( "It is needed to specify the recipe revision if " "you specify a package revision", self.client.out) def test_search_with_revision(self): conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): settings = "os" def build(self): self.output.warn("Revision 1") ''' self._create_and_upload(conanfile, self.ref, args="-s os=Linux") rev1 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self._create_and_upload(conanfile.replace('"os"', '"arch"'), self.ref, args="-s arch=x86") rev2 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertNotEqual(rev1, rev2) # Search every package in local cache (we get both binary packages) self.client.run("search lib/1.0@lasote/testing") self.assertIn("a363db07e8420d258dca5a64aad6a5b8ecbbdd66", self.client.out) self.assertIn("cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", self.client.out) # Search only revision 1 in local cache self.client.run("search lib/1.0@lasote/testing#%s" % rev1) self.assertNotIn("a363db07e8420d258dca5a64aad6a5b8ecbbdd66", self.client.out) self.assertIn("cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", self.client.out) # Search only revision 2 in local cache self.client.run("search lib/1.0@lasote/testing#%s" % rev2) self.assertIn("a363db07e8420d258dca5a64aad6a5b8ecbbdd66", self.client.out) self.assertNotIn("cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", self.client.out) # Search all in remote (will give us the latest) self.client.run("search lib/1.0@lasote/testing -r remote0") self.assertIn("a363db07e8420d258dca5a64aad6a5b8ecbbdd66", self.client.out) self.assertNotIn("cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", self.client.out) # Search rev1 in remote self.client.run("search lib/1.0@lasote/testing#%s -r remote0" % rev1) self.assertNotIn("a363db07e8420d258dca5a64aad6a5b8ecbbdd66", self.client.out) self.assertIn("cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", self.client.out) # Search rev2 in remote self.client.run("search lib/1.0@lasote/testing#%s -r remote0" % rev2) self.assertIn("a363db07e8420d258dca5a64aad6a5b8ecbbdd66", self.client.out) self.assertNotIn("cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", self.client.out) def test_with_scm(self): conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): scm = { "revision": "auto", "url": "auto", "type": "git" } def build(self): self.output.warn("Revision 1") ''' path, commit = create_local_git_repo( { "myfile": "contents", "conanfile.py": conanfile }, branch="my_release") self.client.runner('git remote add origin https://myrepo.com.git', cwd=path) self.client.current_folder = path self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev_server = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertEqual(commit, rev_server.revision) self.client.run("remove %s -f" % str(self.ref)) self.client.run("install %s#%s" % (str(self.ref), rev_server.revision)) self.assertIn( "Package installed 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", self.client.out) self.client.run("remove %s -f" % str(self.ref)) self.client.run("install %s" % str(self.ref)) self.assertIn( "Package installed 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", self.client.out) def test_info(self): conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): settings = "os" def build(self): self.output.warn("Revision 1") ''' self._create_and_upload(conanfile, self.ref, args="-s os=Linux") self.client.run("info %s" % str(self.ref)) self.assertIn("Revision: c5485544fd84cf85e45cc742feb8b34c", self.client.out) self.client.client_cache.registry.refs.remove(self.ref) # Upload to a non-revisions server, the revision should be always there in the registry self._create_and_upload(conanfile, self.ref, args="-s os=Linux", remote="remote_norevisions") self.client.run("info %s" % str(self.ref)) self.assertIn("Revision: c5485544fd84cf85e45cc742feb8b34c", self.client.out) def test_update_recipe(self): self.client.save({"conanfile.py": self.conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) self.client.run("remote list_ref") pref = PackageReference.loads( "lib/1.0@lasote/testing:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertIn("%s: remote0" % str(self.ref), self.client.out) self.client.run("remote list_pref %s" % str(self.ref)) self.assertIn("%s: remote0" % str(pref), self.client.out) rev = self.client.get_revision(self.ref) self.assertEquals(rev, "149570a812b46d87c7dfa6408809b370") sleep(1) client2 = TestClient(servers=self.servers, users=self.users) conanfile2 = self.conanfile + "# Holaaa " client2.save({"conanfile.py": conanfile2}) client2.run("create . %s" % str(self.ref)) client2.run("upload %s -c --all -r remote0" % str(self.ref)) client2.run("remote list_pref %s" % str(self.ref)) rev = client2.get_revision(self.ref) self.assertEquals(rev, "621568e8053761d685dcf1bfbe3b3f10") # install of the client1 (no-update) self.client.run("install %s" % str(self.ref)) self.assertIn("lib/1.0@lasote/testing from 'remote0' - Cache", self.client.out) self.assertIn("%s - Cache" % str(pref), self.client.out) self.client.run("remote list_pref %s" % str(self.ref)) self.assertIn("%s: remote0" % str(pref), self.client.out) rev = self.client.get_revision(self.ref) self.assertEquals(rev, "149570a812b46d87c7dfa6408809b370") # install with update self.client.run("install %s --update" % str(self.ref)) rev = self.client.get_revision(self.ref) self.assertEquals(rev, "621568e8053761d685dcf1bfbe3b3f10") self.assertNotIn("%s from 'remote0' - Newer" % str(self.ref), self.client.out) self.assertIn( "Outdated package! The package doesn't belong to the installed recipe " "revision:", self.client.out) self.assertIn("%s from 'remote0' - Updated" % str(self.ref), self.client.out) self.assertIn("%s - Update" % str(pref), self.client.out) def test_registry_revision_updated(self): self.client.save({"conanfile.py": self.conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev = self.client.get_revision(self.ref) remote_rev = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertEquals(remote_rev.revision, rev) self.client.save({"conanfile.py": self.conanfile + " "}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev2 = self.client.get_revision(self.ref) remote_rev2 = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertEquals(remote_rev2.revision, rev2) self.assertNotEquals(rev, rev2) def test_update_package(self): conanfile = ''' import time import os from conans import ConanFile, tools class HelloConan(ConanFile): def package(self): tools.save(os.path.join(self.package_folder, "file.txt"), str(time.time())) ''' self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) # Same recipe, but will generate different package sleep(1) client2 = TestClient(servers=self.servers, users=self.users) client2.save({"conanfile.py": conanfile}) client2.run("create . %s" % str(self.ref)) client2.run("upload %s -c --all -r remote0" % str(self.ref)) # install of the client1 (no-update) self.client.run("install %s" % str(self.ref)) self.assertIn("lib/1.0@lasote/testing from 'remote0' - Cache", self.client.out) self.assertIn( "lib/1.0@lasote/testing:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", self.client.out) # install with update self.client.run("install %s --update" % str(self.ref)) self.assertNotIn( "The current binary package doesn't belong to the current recipe revision:", self.client.out) self.assertIn("Current package is older than remote upstream one", self.client.out) self.assertIn("lib/1.0@lasote/testing from 'remote0' - Cache", self.client.out) self.assertIn( "lib/1.0@lasote/testing:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Update", self.client.out) def test_upload_outdated_packages(self): conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): settings = "os" ''' self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s -s os=Windows" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) conanfile2 = self.conanfile + " " self.client.save({"conanfile.py": conanfile2}) self.client.run("create . %s -s os=Linux" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) self.assertIn( "Skipping package '3475bd55b91ae904ac96fde0f106a136ab951a5e'", self.client.out) self.assertIn("Uploading package 1/1", self.client.out) def test_conflict_with_different_revisions_but_same_ref(self): """Diamond requiring different revisions in the reference""" conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): pass ''' ref_a = ConanFileReference.loads("libA/1.0@lasote/testing") self._create_and_upload(conanfile, ref_a) rev = self.servers["remote0"].server_store.get_last_revision( ref_a).revision self._create_and_upload(conanfile + " ", ref_a) # New revision rev2 = self.servers["remote0"].server_store.get_last_revision( ref_a).revision ref_b = ConanFileReference.loads("libB/1.0@lasote/testing") req = "%s#%s" % (ref_a, rev) self._create_and_upload( conanfile.replace("pass", 'requires = "%s"' % req), ref_b) ref_c = ConanFileReference.loads("libC/1.0@lasote/testing") req = "%s#%s" % (ref_a, rev2) self._create_and_upload( conanfile.replace("pass", 'requires = "%s"' % req), ref_c) ref_d = ConanFileReference.loads("libD/1.0@lasote/testing") repl = 'requires = "%s", "%s"' % (str(ref_c), str(ref_b)) self.client.save({"conanfile.py": conanfile.replace("pass", repl)}) self.client.run("create . %s" % str(ref_d), assert_error=True) self.assertIn( "Different revisions of libA/1.0@lasote/testing " "has been requested", self.client.out) self.client.run('remove "*" -f') self.client.run("create . %s" % str(ref_d), assert_error=True) self.client.run("create . %s" % str(ref_d), assert_error=True) self.assertIn( "Different revisions of libA/1.0@lasote/testing " "has been requested", self.client.out) def test_upload_not_overwrite(self): self.client.save({"conanfile.py": self.conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all --no-overwrite" % str(self.ref)) self.client.save({"conanfile.py": self.conanfile + " "}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all --no-overwrite" % str(self.ref)) def test_export_cleans_revision_in_registy(self): self.client.save({"conanfile.py": self.conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all --no-overwrite" % str(self.ref)) # No changes self.client.save({"conanfile.py": self.conanfile}) self.client.run("export . %s" % str(self.ref)) cur_rev = self.client.get_revision(self.ref) self.assertIsNotNone(cur_rev) # Export new recipe, the revision is not cleared but changed self.client.save({"conanfile.py": self.conanfile + " "}) self.client.run("export . %s" % str(self.ref)) new_rev = self.client.get_revision(self.ref) self.assertIsNotNone(new_rev) self.assertNotEqual(cur_rev, new_rev) def test_alias_with_revisions(self): self.client.save({"conanfile.py": self.conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev = self.client.get_revision(self.ref) full_ref = self.ref.copy_with_rev(rev) self.client.save({ "conanfile.py": self.conanfile.replace("Revision 1", "Revision 2") }) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) alias = """from conans import ConanFile class AliasConanfile(ConanFile): alias = "%s" """ % full_ref.full_repr() self.client.save({"conanfile.py": alias}) self.client.run("export . lib/snap@lasote/testing") # As we requested a different revision it will install the correct one self.client.run("install lib/snap@lasote/testing --build") self.assertIn("Revision 1", self.client.out) def test_recipe_revision_delete_all(self): self.client.save({"conanfile.py": self.conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) self.client.save({ "conanfile.py": self.conanfile.replace("Revision 1", "Revision 2") }) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) self.client.run("remove %s -r remote0 -f" % str(self.ref)) last_rev = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertIsNone(last_rev) def test_recipe_revision_delete_one(self): # Upload revision1 self.client.save({"conanfile.py": self.conanfile}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev = self.client.get_revision(self.ref) remote_rev = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertEquals(remote_rev.revision, rev) # Upload revision2 self.client.save({ "conanfile.py": self.conanfile.replace("Revision 1", "Revision 2") }) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev2 = self.client.get_revision(self.ref) remote_rev = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertEquals(remote_rev.revision, rev2) # Remove revision2 self.client.run("remove %s#%s -r remote0 -f" % (str(self.ref), rev2)) remote_rev = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertEquals(remote_rev.revision, rev) # Upload revision3 self.client.save({ "conanfile.py": self.conanfile.replace("Revision 1", "Revision 3") }) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev3 = self.client.get_revision(self.ref) self.assertNotEquals(rev3, rev2) remote_rev = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertEquals(remote_rev.revision, rev3) # Remove revision 3, remote is rev1 self.client.run("remove %s#%s -r remote0 -f" % (str(self.ref), rev3)) remote_rev = self.servers["remote0"].server_store.get_last_revision( self.ref) self.assertEquals(remote_rev.revision, rev) def test_remote_search(self): conanfile = ''' import time import os from conans import ConanFile, tools class HelloConan(ConanFile): settings = "os" def package(self): tools.save(os.path.join(self.package_folder, "file.txt"), str(time.time())) ''' self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s -s os=Windows" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev1 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision # Create other recipe revision with a different binary package self.client.save({"conanfile.py": conanfile + " "}) self.client.run("create . %s -s os=Linux" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev2 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision # Search with revision1 (only win package available) self.client.run("search %s#%s -r remote0" % (str(self.ref), rev1)) self.assertIn("Existing recipe in remote 'remote0'", self.client.out) self.assertIn("os: Windows", self.client.out) self.assertNotIn("os: Linux", self.client.out) # Search with revision2 (only linux package available) self.client.run("search %s#%s -r remote0" % (str(self.ref), rev2)) self.assertIn("Existing recipe in remote 'remote0'", self.client.out) self.assertIn("os: Linux", self.client.out) self.assertNotIn("os: Windows", self.client.out) def _upload_two_revisions(self, ref, different_binary=False): conanfile = ''' import os import uuid from conans import ConanFile, tools class HelloConan(ConanFile): pass ''' if different_binary: # Same pid but different binary hash conanfile += """ def package(self): tools.save(os.path.join(self.package_folder, "file"), str(uuid.uuid4())) """ self._create_and_upload(conanfile, ref) _rev1 = self.client.get_revision(ref) self._create_and_upload(conanfile + "\n", ref) _rev2 = self.client.get_revision(ref) return _rev1, _rev2 def test_remove_recipe_v2_test(self): ref = ConanFileReference.loads("lib/1.0@lasote/testing") rev1, rev2 = self._upload_two_revisions(ref) # If I specify rev2 only rev2 is removed self.client.run("remove %s#%s -f -r remote0" % (str(ref), rev2)) latestrev = self.servers["remote0"].server_store.get_last_revision( ref).revision self.assertEquals(latestrev, rev1) self._upload_two_revisions(ref) # If I don't specify revision all the revisions are removed self.client.run("remove %s -f -r remote0" % str(ref)) latestrev = self.servers["remote0"].server_store.get_last_revision(ref) self.assertIsNone(latestrev) def test_remove_packages_v2_test(self): # If I don't specify a recipe revision it will remove all the packages from all recipe # revisions pid = "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9" ref = ConanFileReference.loads("lib/1.0@lasote/testing") rev1, rev2 = self._upload_two_revisions(ref) full_pr1 = PackageReference(ref.copy_with_rev(rev1), pid) full_pr2 = PackageReference(ref.copy_with_rev(rev2), pid) path1 = self.servers["remote0"].server_store.package(full_pr1) path2 = self.servers["remote0"].server_store.package(full_pr2) self.assertTrue(os.path.exists(path1)) self.assertTrue(os.path.exists(path2)) self.client.run("remove %s -f -r remote0 -p %s" % (str(ref), pid)) self.assertFalse(os.path.exists(path1)) self.assertFalse(os.path.exists(path2)) # Now specify the recipe revision self._upload_two_revisions(ref) self.client.run("remove %s#%s -f -r remote0 -p %s" % (str(ref), rev1, pid)) self.assertFalse(os.path.exists(path1)) self.assertTrue(os.path.exists(path2)) # Now generate different package revisions also rev1, rev2 = self._upload_two_revisions(ref, different_binary=True) full_pr1 = PackageReference(ref.copy_with_rev(rev1), pid) prevs = [ el.revision for el in self.servers["remote0"].server_store. get_package_revisions(full_pr1) ] self.assertEquals(len(prevs), 1) self._upload_two_revisions(ref, different_binary=True) prevs = [ el.revision for el in self.servers["remote0"].server_store. get_package_revisions(full_pr1) ] self.assertEquals(len(prevs), 2) # Remove a concrete package reference self.client.run("remove %s#%s -f -r remote0 -p %s#%s" % (str(ref), rev1, pid, prevs[0])) prevs_now = [ el.revision for el in self.servers["remote0"].server_store. get_package_revisions(full_pr1) ] self.assertEquals(len(prevs_now), 1) self.assertEquals(prevs_now[0], prevs[1]) def test_remove_all_revs_with_v1(self): # Check if v1 with several versions in the server will: # Remove all the revisions and packages if I remove by reference conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): pass ''' ref = ConanFileReference.loads("lib/1.0@lasote/testing") # Upload three revisions of A and its packages self._create_and_upload(conanfile, ref) rev1 = self.client.get_revision(ref) self._create_and_upload(conanfile + "\n", ref) rev2 = self.client.get_revision(ref) self._create_and_upload(conanfile + "\n\n", ref) rev3 = self.client.get_revision(ref) self._create_and_upload(conanfile + "\n\n\n", ref) rev4 = self.client.get_revision(ref) self.assertNotEquals(rev1, rev2) self.assertNotEquals(rev2, rev3) self.assertNotEquals(rev1, rev3) # Remove all locally self.client.run("remove '*' -f") # First a pre-check, if I remove only the package for the rev4 the rest is there self.client.run("remove %s#%s -f -r remote0" % (ref, rev4)) latestrev = self.servers["remote0"].server_store.get_last_revision( ref).revision self.assertEquals(latestrev, rev3) self.client.run("install %s#%s" % (self.ref, rev3)) # Create a v1 client and remove the pid client_no_rev = TestClient(block_v2=True, servers=self.servers, users=self.users) client_no_rev.run( "remove %s -f -p 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 " "-r remote0" % str(ref)) # Remove all locally again self.client.run("remove '*' -f") # Use the regular v2 client and try to install specifying revisions self.client.run("install %s#%s" % (self.ref, rev1), assert_error=True) self.assertIn("Can't find a 'lib/1.0@lasote/testing' package", self.client.out) self.client.run("install %s#%s" % (self.ref, rev2), assert_error=True) self.assertIn("Can't find a 'lib/1.0@lasote/testing' package", self.client.out) self.client.run("install %s#%s" % (self.ref, rev3), assert_error=True) self.assertIn("Can't find a 'lib/1.0@lasote/testing' package", self.client.out) def test_v1_with_revisions_behavior(self): client_no_rev = TestClient(block_v2=True, servers=self.servers, users=self.users) conanfile = ''' from conans import ConanFile class HelloConan(ConanFile): def build(self): self.output.warn("Hello") ''' client_no_rev.save({"conanfile.py": conanfile}) client_no_rev.run("create . %s" % str(self.ref)) client_no_rev.run("upload %s -c --all -r remote0" % str(self.ref)) rev1 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertEquals(rev1, DEFAULT_REVISION_V1) # An upload from the other client with revisions puts a new revision as latest self.client.save({"conanfile.py": conanfile.replace("Hello", "Bye")}) self.client.run("create . %s" % str(self.ref)) self.client.run("upload %s -c --all -r remote0" % str(self.ref)) rev1 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertNotEquals(rev1, DEFAULT_REVISION_V1) client_no_rev.run('remove "*" -f') client_no_rev.run("install %s --build" % str(self.ref)) # Client v1 never receives revision but 0 self.assertEquals(client_no_rev.get_revision(self.ref), DEFAULT_REVISION_V1) self.assertIn("Bye", client_no_rev.out) # If client v1 uploads again the recipe it is the latest again, but with rev0 client_no_rev.save({"conanfile.py": conanfile.replace("Hello", "Foo")}) client_no_rev.run("create . %s" % str(self.ref)) client_no_rev.run("upload %s -c --all -r remote0" % str(self.ref)) rev1 = self.servers["remote0"].server_store.get_last_revision( self.ref).revision self.assertEquals(rev1, DEFAULT_REVISION_V1) # Even for the client with revision, now the latest is 0 self.client.run('remove "*" -f') self.client.run("install %s --build" % str(self.ref)) self.assertIn("Foo", self.client.out) self.assertEquals(self.client.get_revision(self.ref), DEFAULT_REVISION_V1) def package_iterating_remote_same_recipe_revision_test(self): """If remote1 and remote2 has the same recipe revisions it will look for binaries iterating""" pid = "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9" # https://github.com/conan-io/conan/issues/3882 conanfile = """from conans import ConanFile class ConanFileToolsTest(ConanFile): pass """ # Upload recipe + package to remote1 and remote2 ref = "Hello/0.1@lasote/stable" self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s" % ref) self.client.run("upload %s -r=remote0 --all" % ref) self.client.run("upload %s -r=remote2 --all" % ref) # Remove only binary from remote1 and everything in local self.client.run("remove -f %s -p -r remote0" % ref) self.client.run('remove "*" -f') # Now install it from a client, it will find the binary in remote2 # because the recipe revision is the same self.client.run("install %s" % ref) self.assertIn("Retrieving package %s from remote 'remote2' " % pid, self.client.out) def package_iterating_remote_different_recipe_revision_test(self): """If remote1 and remote2 has the same recipe revisions it wont look for binaries iterating""" # https://github.com/conan-io/conan/issues/3882 conanfile = """from conans import ConanFile class ConanFileToolsTest(ConanFile): pass """ # Upload recipe + package to remote1 and remote2 ref = "Hello/0.1@lasote/stable" self.client.save({"conanfile.py": conanfile}) self.client.run("create . %s" % ref) self.client.run("upload %s -r=remote0 --all" % ref) self.client.save({"conanfile.py": conanfile + "\n"}) self.client.run("create . %s" % ref) self.client.run("upload %s -r=remote2 --all" % ref) # Remove only binary from remote1 and everything in local self.client.run("remove -f %s -p -r remote0" % ref) self.client.run('remove "*" -f') # Now install it from a client, it won't find the binary in remote2 # because the recipe revision is NOT the same self.client.run("install %s" % ref, assert_error=True) self.assertIn("Can't find a 'Hello/0.1@lasote/stable' package", self.client.out)