def test_http_download_run(tmpdir): def reader(): yield b"hello" yield b"world" action = HttpDownloadAction("dtb", str(tmpdir), urlparse("https://example.com/dtb")) action.job = Job(1234, {"dispatcher": {}}, None) action.url = urlparse("https://example.com/dtb") action.parameters = { "to": "download", "images": { "dtb": { "url": "https://example.com/dtb", "md5sum": "fc5e038d38a57032085441e7fe7010b0", "sha256sum": "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af", "sha512sum": "1594244d52f2d8c12b142bb61f47bc2eaf503d6d9ca8480cae9fcf112f66e4967dc5e8fa98285e36db8af1b8ffa8b84cb15e0fbcf836c3deb803c13f37659a60", } }, "namespace": "common", } action.params = action.parameters["images"]["dtb"] action.reader = reader action.fname = str(tmpdir / "dtb/dtb") action.run(None, 4212) data = "" with open(str(tmpdir / "dtb/dtb")) as f_in: data = f_in.read() assert data == "helloworld" assert dict(action.results) == { "success": { "sha512": "1594244d52f2d8c12b142bb61f47bc2eaf503d6d9ca8480cae9fcf112f66e4967dc5e8fa98285e36db8af1b8ffa8b84cb15e0fbcf836c3deb803c13f37659a60" }, "label": "dtb", "size": 10, "md5sum": "fc5e038d38a57032085441e7fe7010b0", "sha256sum": "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af", "sha512sum": "1594244d52f2d8c12b142bb61f47bc2eaf503d6d9ca8480cae9fcf112f66e4967dc5e8fa98285e36db8af1b8ffa8b84cb15e0fbcf836c3deb803c13f37659a60", } assert action.data == { "common": { "download-action": { "dtb": { "decompressed": False, "file": "%s/dtb/dtb" % str(tmpdir), "md5": "fc5e038d38a57032085441e7fe7010b0", "sha256": "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af", "sha512": "1594244d52f2d8c12b142bb61f47bc2eaf503d6d9ca8480cae9fcf112f66e4967dc5e8fa98285e36db8af1b8ffa8b84cb15e0fbcf836c3deb803c13f37659a60", }, "file": {"dtb": "%s/dtb/dtb" % str(tmpdir)}, } } }
def test_http_download_reader(mocker): # Working class DummyResponse: status_code = requests.codes.OK headers = {"content-length": "4212"} def iter_content(self, size): assert size == HTTP_DOWNLOAD_CHUNK_SIZE yield b"hello" def close(self): pass def dummyget(url, allow_redirects, stream, headers): assert allow_redirects is True assert stream is True assert url == "https://example.com/dtb" return DummyResponse() mocker.patch("requests.get", dummyget) action = HttpDownloadAction( "image", "/path/to/file", urlparse("https://example.com/dtb") ) action.url = urlparse("https://example.com/dtb") ite = action.reader() assert next(ite) == b"hello" with pytest.raises(StopIteration): next(ite) # Not working def dummygetraise(url, allow_redirects, stream, headers): raise requests.RequestException("error") mocker.patch("requests.get", dummygetraise) action = HttpDownloadAction( "image", "/path/to/file", urlparse("https://example.com/dtb") ) action.url = urlparse("https://example.com/dtb") ite = action.reader() with pytest.raises(InfrastructureError) as exc: next(ite) assert exc.match("Unable to download 'https://example.com/dtb': error")
def test_http_download_run_compressed(tmpdir): def reader(): yield b"\xfd7zXZ\x00\x00\x04\xe6\xd6\xb4F\x02\x00!\x01\x16\x00\x00" yield b"\x00t/\xe5\xa3\x01\x00\x0bhello world\n\x00\xa1\xf2\xff\xc4j" yield b"\x7f\xbf\xcf\x00\x01$\x0c\xa6\x18\xd8\xd8\x1f\xb6\xf3}\x01" yield b"\x00\x00\x00\x00\x04YZ" action = HttpDownloadAction("rootfs", str(tmpdir), urlparse("https://example.com/rootfs.xz")) action.job = Job(1234, {}, None) action.url = urlparse("https://example.com/rootfs.xz") action.parameters = { "to": "download", "rootfs": { "url": "https://example.com/rootfs.xz", "compression": "xz", "md5sum": "0107d527acf9b8de628b7b4d103c89d1", "sha256sum": "3275a39be7b717d548b66f3c8f23d940603a63b0f13d84a596d979a7f66feb2c", "sha512sum": "d0850c3e0c45bdf74995907a04f69806a070d79a4f0b2dd82d6b96adafdbfd85ce6c1daaff916ff089bdf9b04eba7805041c49afecdbeabca69fef802e60de35", }, "namespace": "common", } action.params = action.parameters["rootfs"] action.reader = reader action.size = 68 action.fname = str(tmpdir / "rootfs/rootfs") action.run(None, 4212) data = "" with open(str(tmpdir / "rootfs/rootfs")) as f_in: data = f_in.read() assert data == "hello world\n" assert dict(action.results) == { "success": { "sha512": "d0850c3e0c45bdf74995907a04f69806a070d79a4f0b2dd82d6b96adafdbfd85ce6c1daaff916ff089bdf9b04eba7805041c49afecdbeabca69fef802e60de35" }, "label": "rootfs", "size": 68, "md5sum": "0107d527acf9b8de628b7b4d103c89d1", "sha256sum": "3275a39be7b717d548b66f3c8f23d940603a63b0f13d84a596d979a7f66feb2c", "sha512sum": "d0850c3e0c45bdf74995907a04f69806a070d79a4f0b2dd82d6b96adafdbfd85ce6c1daaff916ff089bdf9b04eba7805041c49afecdbeabca69fef802e60de35", } assert action.data == { "common": { "download-action": { "rootfs": { "decompressed": True, "file": "%s/rootfs/rootfs" % str(tmpdir), "md5": "0107d527acf9b8de628b7b4d103c89d1", "sha256": "3275a39be7b717d548b66f3c8f23d940603a63b0f13d84a596d979a7f66feb2c", "sha512": "d0850c3e0c45bdf74995907a04f69806a070d79a4f0b2dd82d6b96adafdbfd85ce6c1daaff916ff089bdf9b04eba7805041c49afecdbeabca69fef802e60de35", }, "file": { "rootfs": "%s/rootfs/rootfs" % str(tmpdir) }, } } }
def test_http_download_validate(mocker): class DummyResponseNOK: status_code = 404 def close(self): pass class DummyResponseOK: status_code = requests.codes.OK headers = {"content-length": "4212"} def close(self): pass def dummyhead(url, allow_redirects, headers): assert allow_redirects is True assert headers == {"Accept-Encoding": ""} if url == "https://example.com/kernel": return DummyResponseOK() elif url == "https://example.com/dtb": return DummyResponseNOK() assert 0 def dummyget(url, allow_redirects, stream, headers): assert allow_redirects is True assert stream is True assert headers == {"Accept-Encoding": ""} assert url == "https://example.com/dtb" return DummyResponseOK() mocker.patch("requests.head", dummyhead) mocker.patch("requests.get", dummyget) # HEAD is working action = HttpDownloadAction("image", "/path/to/file", urlparse("https://example.com/kernel")) action.section = "deploy" action.job = Job(1234, {"dispatcher": {}}, None) action.parameters = { "image": { "url": "https://example.com/kernel" }, "namespace": "common", } action.params = action.parameters["image"] action.validate() assert action.errors == [] assert action.size == 4212 # Only GET works action = HttpDownloadAction("image", "/path/to/file", urlparse("https://example.com/dtb")) action.section = "deploy" action.job = Job(1234, {"dispatcher": {}}, None) action.parameters = { "image": { "url": "https://example.com/dtb" }, "namespace": "common", } action.params = action.parameters["image"] action.validate() assert action.errors == [] assert action.size == 4212 # 404 def response404(*args, **kwargs): print(args) print(str(kwargs)) return DummyResponseNOK() mocker.patch("requests.head", response404) mocker.patch("requests.get", response404) action = HttpDownloadAction("image", "/path/to/file", urlparse("https://example.com/kernel")) action.section = "deploy" action.job = Job(1234, {"dispatcher": {}}, None) action.parameters = { "image": { "url": "https://example.com/kernel" }, "namespace": "common", } action.params = action.parameters["image"] action.validate() assert action.errors == [ "Resource unavailable at 'https://example.com/kernel' (404)" ] # Raising exceptions def raisinghead(url, allow_redirects, headers): raise requests.Timeout() mocker.patch("requests.head", raisinghead) action = HttpDownloadAction("image", "/path/to/file", urlparse("https://example.com/kernel")) action.section = "deploy" action.job = Job(1234, {"dispatcher": {}}, None) action.parameters = { "image": { "url": "https://example.com/kernel" }, "namespace": "common", } action.params = action.parameters["image"] action.validate() assert action.errors == ["'https://example.com/kernel' timed out"] def raisinghead2(url, allow_redirects, headers): raise requests.RequestException("an error occured") mocker.patch("requests.head", raisinghead2) action = HttpDownloadAction("image", "/path/to/file", urlparse("https://example.com/kernel")) action.section = "deploy" action.job = Job(1234, {"dispatcher": {}}, None) action.parameters = { "image": { "url": "https://example.com/kernel" }, "namespace": "common", } action.params = action.parameters["image"] action.validate() assert action.errors == [ "Unable to get 'https://example.com/kernel': an error occured" ]