def test_fields_cached(): # Try making two items with similar fields. # Note: the weird string construction here is meant to defeat # the built-in python logic of interning string literals since # that would defeat the purpose of the test... item1 = PushItem(name="item1", origin="some-origin", dest=["a", "b", "c"], signing_key="a1b2c3d4") item2 = PushItem( name="item2", origin="-".join(["some", "origin"]), dest=["a", "b", "c"], signing_key="2".join(["a1b", "c3d4"]), ) # Field values should be not only equal... for item in (item1, item2): assert item.origin == "some-origin" assert item.dest == ["a", "b", "c"] assert item.signing_key == "A1B2C3D4" # ...but they should also be *identical* assert item1.origin is item2.origin assert item1.dest is item2.dest assert item1.signing_key is item2.signing_key
def test_with_checksums_partial(tmpdir): """with_checksums only calculates checksums of missing types""" tmpfile = tmpdir.join("somefile") tmpfile.write(b"some data") item = PushItem(name="item", src=str(tmpfile), md5sum="1e50210a0202497fb79bc38b6ade6c34") hashlib_new = hashlib.new computed_types = [] def patched_hashlib_new(hash_type): computed_types.append(hash_type) return hashlib_new(hash_type) with patch("hashlib.new", new=patched_hashlib_new): item_sums = item.with_checksums() # with_checksums output should have correct sums assert item_sums.md5sum == "1e50210a0202497fb79bc38b6ade6c34" assert (item_sums.sha256sum == "1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee") # Only sha256 should have been calculated, since md5 was already present assert computed_types == ["sha256"]
def test_with_checksums_read_fails(): """with_checksums propagates error if referenced file can't be read""" with raises(Exception) as exc_info: PushItem(name="item", src="file-does-not-exist").with_checksums() # exact type and message is not verified due to py2 vs py3 differences. assert "file-does-not-exist" in str(exc_info.value)
def test_pushitem_obj_push(): """PushItem object passed to the update_push_items works fine.""" collector = Collector.get("dummy") pushitem = PushItem(name="test_pushitem") ret_val = collector.update_push_items([pushitem]) assert ret_val.result() is None
def test_with_checksums_noop(): """with_checksums does nothing if sums are already present""" item = PushItem( name="item", src="nonexistent-file", md5sum="d3b07384d113edec49eaa6238ad5ff00", sha256sum= "49ae93732fcf8d63fe1cce759664982dbd5b23161f007dba8561862adc96d063", ) assert item.with_checksums() is item
def test_partial_with_url_unbound(): Source.register_backend("returns-url", ReturnsUrlSource) # Let's say that I now overwrite this source with an argument (not url) bound partial = Source.get_partial("returns-url:", a=123) Source.register_backend("returns-url", partial) # Then I should be able to obtain an instance of this source, and it # should still stuff the path part of the below string into the 'url' arg items = [i for i in Source.get("returns-url:/foo/bar?b=88")] assert items == [PushItem(name="/foo/bar 123 88")]
def test_partial_with_url_bound_overwrite(): Source.register_backend("returns-url", ReturnsUrlSource) # Let's say that I now overwrite this source and I pre-fill a URL partial = Source.get_partial("returns-url:", url="/tmp") Source.register_backend("returns-url", partial) # Then I should be able to obtain an instance of this source, and # I can still override the bound URL by passing a new one in the # normal manner. items = [i for i in Source.get("returns-url:/other/url?a=1&b=2")] assert items == [PushItem(name="/other/url 1 2")]
def test_partial_with_url_bound(): Source.register_backend("returns-url", ReturnsUrlSource) # Let's say that I now overwrite this source and I pre-fill a URL partial = Source.get_partial("returns-url:", url="/tmp") Source.register_backend("returns-url", partial) # Then I should be able to obtain an instance of this source, with # the URL coming from the value previously bound and other arguments # still able to be overridden normally. items = [i for i in Source.get("returns-url:b=123")] assert items == [PushItem(name="/tmp a 123")]
def test_with_checksums_reads_content(tmpdir): """with_checksums reads file to calculate checksums""" tmpfile = tmpdir.join("somefile") tmpfile.write(b"some data") item = PushItem(name="item", src=str(tmpfile)) item_sums = item.with_checksums() # Original item should be untouched assert not item.md5sum assert not item.sha256sum # with_checksums output should have correct sums filled in assert item_sums.md5sum == "1e50210a0202497fb79bc38b6ade6c34" assert (item_sums.sha256sum == "1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee")
def test_empty_push(fake_controller, fake_push, fake_state_path, command_tester, stub_collector): """Test a push with no content.""" # Sanity check that the Pulp server is, initially, empty. client = fake_controller.client assert list(client.search_content()) == [] # Set up a pushsource backend which returns no supported items Source.register_backend("null", lambda: [PushItem(name="quux")]) compare_extra = { "pulp.yaml": { "filename": fake_state_path, "normalize": hide_unit_ids, } } args = [ "", "--source", "null:", "--pulp-url", "https://pulp.example.com/", ] run = functools.partial(entry_point, cls=lambda: fake_push) # It should be able to run without crashing. command_tester.test( run, args, compare_plaintext=False, compare_jsonl=False, compare_extra=compare_extra, ) # It should not record any push items at all. assert not stub_collector
def test_minimal_pushitem_obj(): """PushItem object with minimal attributes is translated to pushitem dict with destination and checksums as None along with other attributes as in the object""" mock = Mock() Collector.register_backend("mock", lambda: mock) collector = Collector.get("mock") pushitem = PushItem(name="test_push") collector.update_push_items([pushitem]) update_push_item_args = mock.update_push_items.call_args[0][0] assert len(update_push_item_args) == 1 push_args = update_push_item_args[0] assert push_args["filename"] == pushitem.name assert push_args["state"] == pushitem.state assert push_args["src"] == pushitem.src assert push_args["dest"] is None assert push_args["checksums"] is None assert push_args["origin"] == pushitem.origin assert push_args["build"] == pushitem.build assert push_args["signing_key"] == pushitem.signing_key
def test_pushitem_obj_attributes(): """PushItem object attributes are translated and available as expected in pushitem dict passed to update_push_items. A pushitem is generated for each destination""" mock = Mock() Collector.register_backend("mock", lambda: mock) collector = Collector.get("mock") pushitem = PushItem( name="test_push", origin="some_origin", src="source", dest=["dest1", "dest2"], md5sum="bb1b0d528129f47798006e73307ba7a7", sha256sum= "4fd23ae44f3366f12f769f82398e96dce72adab8e45dea4d721ddf43fdce31e2", build="test_build-1.0.0-1", signing_key="FD431D51", ) collector.update_push_items([pushitem]) update_push_item_args = mock.update_push_items.call_args[0][0] assert len(update_push_item_args) == 2 for i in range(len(update_push_item_args) - 1): push_args = update_push_item_args[i] assert push_args["filename"] == pushitem.name assert push_args["state"] == pushitem.state assert push_args["src"] == pushitem.src assert push_args["dest"] == pushitem.dest[i] assert push_args["checksums"] == { "md5": pushitem.md5sum, "sha256": pushitem.sha256sum, } assert push_args["origin"] == pushitem.origin assert push_args["build"] == pushitem.build assert push_args["signing_key"] == pushitem.signing_key
def test_sum_not_string(): """Can't supply non-string in checksum fields.""" with raises(TypeError) as exc_info: PushItem(name="item", md5sum=1234) assert "can't parse 1234 as a hex string" in str(exc_info.value)
def test_sum_lower(): """Valid sums are converted to lowercase.""" item = PushItem(name="item", md5sum="D3B07384D113EDEC49EAA6238AD5FF00") assert item.md5sum == "d3b07384d113edec49eaa6238ad5ff00"
def test_sum_bad_chars(): """Can't supply non hex strings in checksum fields.""" with raises(ValueError) as exc_info: PushItem(name="item", md5sum="fake7384d113edec49eaa6238ad5ff00") assert "can't parse" in str(exc_info.value)
def test_sum_incomplete(): """Can't supply truncated value in checksum fields.""" with raises(ValueError) as exc_info: PushItem(name="item", sha256sum="1234abc") assert "wrong length" in str(exc_info.value)
def __iter__(self): yield PushItem(name="%s %s %s" % (self._url, self._a, self._b))
from pushsource import Source, PushItem # Just some basic push items for test ITEMS = [PushItem(name="item1"), PushItem(name="item2")] class BasicInheritedSource(Source): # A source which simply yields some stuff and didn't implement enter/exit def __init__(self): pass def __iter__(self): for item in ITEMS: yield item class CustomSource(Source): # A more complex source for testing with get_partial and custom enter/exit def __init__(self, a, b, c, spy): self.a = a self.b = b self.c = c self.spy = spy def __enter__(self): self.spy.append("enter %s" % ([self.a, self.b, self.c])) return self def __exit__(self, *_args): self.spy.append("exit %s" % ([self.a, self.b, self.c]))
def test_with_checksums_nosrc(): """with_checksums does nothing on file-less item""" item = PushItem(name="item") assert item.with_checksums() is item