def install_artifacts(artifacts, dirstruct, installdir, basestaticurl): """ Install the artifacts. """ assert basestaticurl.endswith("/"), "Basestaticurl should end with /" installed = [] for reldir, artifactnames in dirstruct.items(): destdir = os.path.join(installdir, reldir) if not os.path.exists(destdir): log.warn(msg="Making install directory %s" % destdir) os.makedirs(destdir) else: assert os.path.isdir(destdir) for artifactname in artifactnames: destpath = os.path.abspath(os.path.join(destdir, artifactname)) if artifactname in artifacts.keys(): # The artifact must be loaded from jenkins theartifact = artifacts[artifactname] else: # It's probably a static file, we can get it from the static collection staticurl = urlparse.urljoin(basestaticurl, artifactname) theartifact = Artifact(artifactname, staticurl) theartifact.save(destpath) installed.append(destpath) return installed
def install_artifacts(artifacts, dirstruct, installdir, basestaticurl): """ Install the artifacts. """ assert basestaticurl.endswith("/"), "Basestaticurl should end with /" installed = [] for reldir, artifactnames in dirstruct.items(): destdir = os.path.join(installdir, reldir) if not os.path.exists(destdir): log.warn(msg="Making install directory %s" % destdir) os.makedirs(destdir) else: assert os.path.isdir(destdir) for artifactname in artifactnames: destpath = os.path.abspath(os.path.join(destdir, artifactname)) if artifactname in artifacts.keys(): # The artifact must be loaded from jenkins theartifact = artifacts[artifactname] else: # It's probably a static file, # we can get it from the static collection staticurl = urlparse.urljoin(basestaticurl, artifactname) theartifact = Artifact(artifactname, staticurl) theartifact.save(destpath) installed.append(destpath) return installed
def get_artifacts(build_number, build, dir='.', artifact=None, url=None): artifact_obj = Artifact( artifact, url.format(jenkins_url, job_name, build_number, artifact), build) print("Downloading {} to {}".format(artifact, dir + artifact)) artifact_obj.save("./" + artifact) return artifact_obj
def setUp(self): self._build = build = Mock() build.buildno = 9999 job = self._build.job job.jenkins.baseurl = 'http://localhost' job.name = 'TestJob' self._artifact = Artifact( 'artifact.zip', 'http://localhost/job/TestJob/9999/artifact/artifact.zip', build)
def setUp(self): self._build = build = Mock() build.buildno = 9999 job = self._build.job job.jenkins.baseurl = 'http://localhost' job.name = 'TestJob' self._artifact = Artifact('artifact.zip', 'http://localhost/job/TestJob/9999/artifact/artifact.zip', build)
def get_artifacts(self): data = self.poll(tree='artifacts[relativePath,fileName]') for afinfo in data["artifacts"]: url = "%s/artifact/%s" % (self.baseurl, quote(afinfo["relativePath"])) af = Artifact(afinfo["fileName"], url, self) yield af
def get_artifacts(self): data = self.poll(tree='artifacts[relativePath,fileName]') builds = self._get_artifact_builds() for afinfo in data["artifacts"]: url = "%s/artifact/%s" % (self.baseurl, quote(afinfo["relativePath"])) fn = afinfo["fileName"] af = Artifact(fn, url, builds.get(fn, self), relative_path=afinfo["relativePath"]) yield af
def get_artifacts(self): for afinfo in self._data["artifacts"]: url = "%s/artifact/%s" % (self.baseurl, afinfo["relativePath"]) af = Artifact(afinfo["fileName"], url, self) yield af
def artifact(mocker): return Artifact('artifact.zip', 'http://foo/job/TestJob/1/artifact/artifact.zip', mocker.MagicMock())
class ArtifactTest(unittest.TestCase): def setUp(self): self._build = build = Mock() build.buildno = 9999 job = self._build.job job.jenkins.baseurl = 'http://localhost' job.name = 'TestJob' self._artifact = Artifact('artifact.zip', 'http://localhost/job/TestJob/9999/artifact/artifact.zip', build) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) @patch('jenkinsapi.artifact.os.path.isdir', spec=True, return_value=True) def test_save_to_dir(self, mock_isdir, mock_exists): artifact = self._artifact artifact.save = Mock(spec=Artifact.save, return_value='/tmp/artifact.zip') self.assertEqual(artifact.save_to_dir('/tmp'), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp') mock_isdir.assert_called_once_with('/tmp') artifact.save.assert_called_once_with('/tmp/artifact.zip', False) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) @patch('jenkinsapi.artifact.os.path.isdir', spec=True, return_value=True) def test_save_to_dir_strict(self, mock_isdir, mock_exists): artifact = self._artifact artifact.save = Mock(return_value='/tmp/artifact.zip') self.assertEqual(artifact.save_to_dir('/tmp', strict_validation=True), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp') mock_isdir.assert_called_once_with('/tmp') artifact.save.assert_called_once_with('/tmp/artifact.zip', True) @patch('jenkinsapi.artifact.open', mock_open(), create=True) @patch('jenkinsapi.artifact.Fingerprint', spec=True) def test_verify_download_valid_positive(self, MockFingerprint): # mock_open() only mocks out f.read(), which reads all content at a time. # However, _verify_download() reads the file in chunks. f = jenkinsapi.artifact.open.return_value f.read.side_effect = [b'chunk1', b'chunk2', b''] # empty string indicates EOF fp = MockFingerprint.return_value fp.validate_for_build.return_value = True fp.unknown = False self.assertTrue(self._artifact._verify_download('/tmp/artifact.zip', False)) MockFingerprint.assert_called_once_with( 'http://localhost', '097c42989a9e5d9dcced7b35ec4b0486', # MD5 of 'chunk1chunk2' self._build.job.jenkins) fp.validate_for_build.assert_called_once_with('artifact.zip', 'TestJob', 9999) @patch('jenkinsapi.artifact.Fingerprint', spec=True) def test_verify_download_valid_negative(self, MockFingerprint): artifact = self._artifact artifact._md5sum = Mock(return_value='097c42989a9e5d9dcced7b35ec4b0486') fp = MockFingerprint.return_value fp.validate_for_build.return_value = True fp.unknown = True # negative self.assertTrue(self._artifact._verify_download('/tmp/artifact.zip', False)) # not strict @patch('jenkinsapi.artifact.Fingerprint', spec=True) def test_verify_download_valid_negative_strict(self, MockFingerprint): artifact = self._artifact artifact._md5sum = Mock(return_value='097c42989a9e5d9dcced7b35ec4b0486') fp = MockFingerprint.return_value fp.validate_for_build.return_value = True fp.unknown = True # negative with self.assertRaisesRegexp(ArtifactBroken, re.escape( 'Artifact 097c42989a9e5d9dcced7b35ec4b0486 seems to be broken, check http://localhost')): self._artifact._verify_download('/tmp/artifact.zip', True) # strict @patch('jenkinsapi.artifact.open', mock_open(), create=True) @patch('jenkinsapi.artifact.Fingerprint', spec=True) def test_verify_download_invalid(self, MockFingerprint): f = jenkinsapi.artifact.open.return_value f.read.side_effect = [b'chunk1', b'chunk2', b''] # empty string indicates EOF fp = MockFingerprint.return_value fp.validate_for_build.return_value = False fp.unknown = False with self.assertRaisesRegexp(ArtifactBroken, re.escape( 'Artifact 097c42989a9e5d9dcced7b35ec4b0486 seems to be broken, check http://localhost')): self._artifact._verify_download('/tmp/artifact.zip', False) MockFingerprint.assert_called_once_with( 'http://localhost', '097c42989a9e5d9dcced7b35ec4b0486', # MD5 of 'chunk1chunk2' self._build.job.jenkins) fp.validate_for_build.assert_called_once_with('artifact.zip', 'TestJob', 9999) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) def test_save_has_valid_local_copy(self, mock_exists): artifact = self._artifact artifact._verify_download = Mock(return_value=True) self.assertEqual(artifact.save('/tmp/artifact.zip'), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp/artifact.zip') artifact._verify_download.assert_called_once_with('/tmp/artifact.zip', False) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) def test_save_has_invalid_local_copy_download_again(self, mock_exists): artifact = self._artifact artifact._verify_download = Mock(side_effect=[ArtifactBroken, True]) artifact._do_download = Mock(return_value='/tmp/artifact.zip') self.assertEqual(artifact.save('/tmp/artifact.zip', True), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp/artifact.zip') artifact._do_download.assert_called_once_with('/tmp/artifact.zip') self.assertEqual(artifact._verify_download.mock_calls, [call('/tmp/artifact.zip', True)] * 2) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) def test_save_has_invalid_local_copy_download_but_invalid(self, mock_exists): artifact = self._artifact artifact._verify_download = Mock(side_effect=[ArtifactBroken, ArtifactBroken]) artifact._do_download = Mock(return_value='/tmp/artifact.zip') with self.assertRaises(ArtifactBroken): artifact.save('/tmp/artifact.zip', True) mock_exists.assert_called_once_with('/tmp/artifact.zip') artifact._do_download.assert_called_once_with('/tmp/artifact.zip') self.assertEqual(artifact._verify_download.mock_calls, [call('/tmp/artifact.zip', True)] * 2) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=False) def test_save_has_no_local_copy(self, mock_exists): artifact = self._artifact artifact._do_download = Mock(return_value='/tmp/artifact.zip') artifact._verify_download = Mock(return_value=True) self.assertEqual(artifact.save('/tmp/artifact.zip'), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp/artifact.zip') artifact._do_download.assert_called_once_with('/tmp/artifact.zip') artifact._verify_download.assert_called_once_with('/tmp/artifact.zip', False)
class ArtifactTest(unittest.TestCase): def setUp(self): self._build = build = Mock() build.buildno = 9999 job = self._build.job job.jenkins.baseurl = 'http://localhost' job.name = 'TestJob' self._artifact = Artifact( 'artifact.zip', 'http://localhost/job/TestJob/9999/artifact/artifact.zip', build) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) @patch('jenkinsapi.artifact.os.path.isdir', spec=True, return_value=True) def test_save_to_dir(self, mock_isdir, mock_exists): artifact = self._artifact artifact.save = Mock(spec=Artifact.save, return_value='/tmp/artifact.zip') self.assertEqual(artifact.save_to_dir('/tmp'), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp') mock_isdir.assert_called_once_with('/tmp') artifact.save.assert_called_once_with('/tmp/artifact.zip', False) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) @patch('jenkinsapi.artifact.os.path.isdir', spec=True, return_value=True) def test_save_to_dir_strict(self, mock_isdir, mock_exists): artifact = self._artifact artifact.save = Mock(return_value='/tmp/artifact.zip') self.assertEqual(artifact.save_to_dir('/tmp', strict_validation=True), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp') mock_isdir.assert_called_once_with('/tmp') artifact.save.assert_called_once_with('/tmp/artifact.zip', True) @patch('jenkinsapi.artifact.open', mock_open(), create=True) @patch('jenkinsapi.artifact.Fingerprint', spec=True) def test_verify_download_valid_positive(self, MockFingerprint): # mock_open() only mocks out f.read(), which reads all content at a time. # However, _verify_download() reads the file in chunks. f = jenkinsapi.artifact.open.return_value f.read.side_effect = [b'chunk1', b'chunk2', b''] # empty string indicates EOF fp = MockFingerprint.return_value fp.validate_for_build.return_value = True fp.unknown = False self.assertTrue( self._artifact._verify_download('/tmp/artifact.zip', False)) MockFingerprint.assert_called_once_with( 'http://localhost', '097c42989a9e5d9dcced7b35ec4b0486', # MD5 of 'chunk1chunk2' self._build.job.jenkins) fp.validate_for_build.assert_called_once_with('artifact.zip', 'TestJob', 9999) @patch('jenkinsapi.artifact.Fingerprint', spec=True) def test_verify_download_valid_negative(self, MockFingerprint): artifact = self._artifact artifact._md5sum = Mock( return_value='097c42989a9e5d9dcced7b35ec4b0486') fp = MockFingerprint.return_value fp.validate_for_build.return_value = True fp.unknown = True # negative self.assertTrue( self._artifact._verify_download('/tmp/artifact.zip', False)) # not strict @patch('jenkinsapi.artifact.Fingerprint', spec=True) def test_verify_download_valid_negative_strict(self, MockFingerprint): artifact = self._artifact artifact._md5sum = Mock( return_value='097c42989a9e5d9dcced7b35ec4b0486') fp = MockFingerprint.return_value fp.validate_for_build.return_value = True fp.unknown = True # negative with self.assertRaisesRegexp( ArtifactBroken, re.escape( 'Artifact 097c42989a9e5d9dcced7b35ec4b0486 seems to be broken, check http://localhost' )): self._artifact._verify_download('/tmp/artifact.zip', True) # strict @patch('jenkinsapi.artifact.open', mock_open(), create=True) @patch('jenkinsapi.artifact.Fingerprint', spec=True) def test_verify_download_invalid(self, MockFingerprint): f = jenkinsapi.artifact.open.return_value f.read.side_effect = [b'chunk1', b'chunk2', b''] # empty string indicates EOF fp = MockFingerprint.return_value fp.validate_for_build.return_value = False fp.unknown = False with self.assertRaisesRegexp( ArtifactBroken, re.escape( 'Artifact 097c42989a9e5d9dcced7b35ec4b0486 seems to be broken, check http://localhost' )): self._artifact._verify_download('/tmp/artifact.zip', False) MockFingerprint.assert_called_once_with( 'http://localhost', '097c42989a9e5d9dcced7b35ec4b0486', # MD5 of 'chunk1chunk2' self._build.job.jenkins) fp.validate_for_build.assert_called_once_with('artifact.zip', 'TestJob', 9999) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) def test_save_has_valid_local_copy(self, mock_exists): artifact = self._artifact artifact._verify_download = Mock(return_value=True) self.assertEqual(artifact.save('/tmp/artifact.zip'), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp/artifact.zip') artifact._verify_download.assert_called_once_with( '/tmp/artifact.zip', False) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) def test_save_has_invalid_local_copy_download_again(self, mock_exists): artifact = self._artifact artifact._verify_download = Mock(side_effect=[ArtifactBroken, True]) artifact._do_download = Mock(return_value='/tmp/artifact.zip') self.assertEqual(artifact.save('/tmp/artifact.zip', True), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp/artifact.zip') artifact._do_download.assert_called_once_with('/tmp/artifact.zip') self.assertEqual(artifact._verify_download.mock_calls, [call('/tmp/artifact.zip', True)] * 2) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=True) def test_save_has_invalid_local_copy_download_but_invalid( self, mock_exists): artifact = self._artifact artifact._verify_download = Mock( side_effect=[ArtifactBroken, ArtifactBroken]) artifact._do_download = Mock(return_value='/tmp/artifact.zip') with self.assertRaises(ArtifactBroken): artifact.save('/tmp/artifact.zip', True) mock_exists.assert_called_once_with('/tmp/artifact.zip') artifact._do_download.assert_called_once_with('/tmp/artifact.zip') self.assertEqual(artifact._verify_download.mock_calls, [call('/tmp/artifact.zip', True)] * 2) @patch('jenkinsapi.artifact.os.path.exists', spec=True, return_value=False) def test_save_has_no_local_copy(self, mock_exists): artifact = self._artifact artifact._do_download = Mock(return_value='/tmp/artifact.zip') artifact._verify_download = Mock(return_value=True) self.assertEqual(artifact.save('/tmp/artifact.zip'), '/tmp/artifact.zip') mock_exists.assert_called_once_with('/tmp/artifact.zip') artifact._do_download.assert_called_once_with('/tmp/artifact.zip') artifact._verify_download.assert_called_once_with( '/tmp/artifact.zip', False)