def test_fetch_egg_refetch_invalid_md5(self): with mkdtemp() as d: egg = "dummy-1.0.0-1.egg" def _fetch_api_factory(): fp = MockedFailingFile(100000) remote = DummyRepository(d, [Entry(egg, fp)]) remote.connect() return fp, FetchAPI(remote, d) def _corrupt_file(target): with open(target, "wb") as fo: fo.write("") fp, fetch_api = _fetch_api_factory() fetch_api.fetch_egg(egg) target = os.path.join(d, egg) self.assertEqual(md5_file(target), fp.md5) _corrupt_file(target) self.assertNotEqual(md5_file(target), fp.md5) fp, fetch_api = _fetch_api_factory() fetch_api.fetch_egg(egg, force=True) self.assertEqual(md5_file(target), fp.md5)
def fetch_dist(self, dist, fetch_dir, force=False, dry_run=False): """ Get a distribution, i.e. copy or download the distribution into fetch_dir. force: force download or copy if MD5 mismatches """ info = self.index[dist] repo, fn = dist_naming.split_dist(dist) path = join(fetch_dir, fn) # if force is used, make sure the md5 is the expected, otherwise # only see if the file exists if isfile(path) and (not force or md5_file(path) == info.get('md5')): if self.verbose: print "Not forcing refetch, %r already matches MD5" % path return if dry_run: return if self.verbose: print "Fetching: %r" % dist print " to: %r" % path stream_to_file(self.repo_objs[repo].get_data(fn), path, info)
def index_section(zip_path): """ Returns a section corresponding to the zip-file, which can be appended to an index. """ return ('==> %s <==\n' % basename(zip_path) + 'size = %i\n' % getsize(zip_path) + 'md5 = %r\n' % md5_file(zip_path) + 'mtime = %r\n' % getmtime(zip_path) + commit_from_dist(zip_path) + '\n' + rawspec_from_dist(zip_path) + '\n')
def fetch_dist(self, dist, fetch_dir, force=False, check_md5=False, dry_run=False): """ Get a distribution, i.e. copy or download the distribution into fetch_dir. force: force download or copy check_md5: when determining if a file needs to be downloaded or copied, check it's MD5. This is, of course, slower but more reliable then just checking the file-size (which always done first). Note: * This option has option has nothing to do with checking the MD5 of a download. The md5 is always checked when files are downloaded (regardless of this option). * If force=True, this option is has no effect, because the file is forcefully downloaded, ignoring any existing file (as well as the MD5). """ md5 = self.index[dist].get('md5', None) size = self.index[dist].get('size', None) fn = dist_naming.filename_dist(dist) dst = join(fetch_dir, fn) # if force is not used, see if (i) the file exists (ii) its size is # the expected (iii) optionally, make sure the md5 is the expected. if (not force and isfile(dst) and getsize(dst) == size and (not check_md5 or md5_file(dst) == md5)): if self.verbose: print "Not forcing refetch, %r already exists" % dst return pprint_fn_action(fn, ['copying', 'downloading'][dist.startswith('http://')]) if dry_run: return if self.verbose: print "Copying: %r" % dist print " to: %r" % dst fo = open(dst + '.part', 'wb') write_data_from_url(fo, dist, md5, size) fo.close() rm_rf(dst) os.rename(dst + '.part', dst)
def test_fetch_simple(self): with mkdtemp() as d: filename = "dummy" fp = MockedFailingFile(100000) remote = DummyRepository(d, [Entry(filename, fp)]) remote.connect() fetch_api = FetchAPI(remote, d) fetch_api.fetch(filename) target = os.path.join(d, filename) self.assertTrue(os.path.exists(target)) self.assertEqual(md5_file(target), fp.md5)
def fetch_dist(self, dist, fetch_dir, force=False, check_md5=False, dry_run=False): """ Get a distribution, i.e. copy or download the distribution into fetch_dir. force: force download or copy check_md5: when determining if a file needs to be downloaded or copied, check it's MD5. This is, of course, slower but more reliable then just checking the file-size (which is always done first). Note: * This option has nothing to do with checking the MD5 of the download. The md5 is always checked when files are downloaded (regardless of this option). * If force=True, this option is has no effect, because the file is forcefully downloaded, ignoring any existing file (as well as the MD5). """ md5 = self.index[dist].get('md5') size = self.index[dist].get('size') fn = dist_naming.filename_dist(dist) dst = join(fetch_dir, fn) # if force is not used, see if (i) the file exists (ii) its size is # the expected (iii) optionally, make sure the md5 is the expected. if (not force and isfile(dst) and getsize(dst) == size and (not check_md5 or md5_file(dst) == md5)): if self.verbose: print "Not forcing refetch, %r already exists" % dst return self.file_action_callback(fn, ('copying', 'downloading') [dist.startswith(('http://', 'https://'))]) if dry_run: return if self.verbose: print "Copying: %r" % dist print " to: %r" % dst fo = open(dst + '.part', 'wb') write_data_from_url(fo, dist, md5, size, progress_callback=self.download_progress_callback) fo.close() rm_rf(dst) os.rename(dst + '.part', dst)
def test_proxy(self): """ Test we handle correctly entries of the form 'path PROXY'. """ r_python_proxy_data_template = """\ #!"{executable}" # This proxy was created by egginst from an egg with special instructions # import sys import subprocess src = '{src}' sys.exit(subprocess.call([src] + sys.argv[1:])) """ with mkdtemp() as prefix: with mock.patch("sys.executable", os.path.join(prefix, "python.exe")): proxy_path = os.path.join(prefix, "EGG-INFO", "dummy_with_proxy", "usr", "swig.exe") r_python_proxy_data = r_python_proxy_data_template.format( executable=os.path.join(prefix, "python.exe"), src=escape_win32_path(proxy_path)) egginst = EggInst(DUMMY_EGG_WITH_PROXY, prefix) with ZipFile(egginst.path) as zp: egginst.z = zp egginst.arcnames = zp.namelist() create_proxies(egginst) python_proxy = os.path.join(prefix, "Scripts", "swig-script.py") coff_proxy = os.path.join(prefix, "Scripts", "swig.exe") self.assertTrue(os.path.exists(python_proxy)) self.assertTrue(os.path.exists(coff_proxy)) self.assertTrue(md5_file(coff_proxy), hashlib.md5(exe_data.cli).hexdigest()) with open(python_proxy) as fp: python_proxy_data = fp.read() self.assertMultiLineEqual( python_proxy_data, r_python_proxy_data)
def test_simple_windows(self): python_executable = "C:\\Python27\\python.exe" pythonw_executable = "C:\\Python27\\pythonw.exe" r_cli_entry_point = """\ #!"{executable}" # This script was created by egginst when installing: # # dummy.egg # if __name__ == '__main__': import sys from dummy import main_cli sys.exit(main_cli()) """.format( executable=python_executable ) r_gui_entry_point = """\ #!"{executable}" # This script was created by egginst when installing: # # dummy.egg # if __name__ == '__main__': import sys from dummy import main_gui sys.exit(main_gui()) """.format( executable=pythonw_executable ) entry_points = """\ [console_scripts] dummy = dummy:main_cli [gui_scripts] dummy-gui = dummy:main_gui """ s = StringIO.StringIO(entry_points) config = ConfigParser.ConfigParser() config.readfp(s) with mock.patch("sys.executable", python_executable): with mkdtemp() as d: egginst = EggInst("dummy.egg", d) create(egginst, config) cli_entry_point_path = op.join(egginst.bin_dir, "dummy-script.py") gui_entry_point_path = op.join(egginst.bin_dir, "dummy-gui-script.pyw") entry_points = [ op.join(egginst.bin_dir, "dummy.exe"), op.join(egginst.bin_dir, "dummy-gui.exe"), cli_entry_point_path, gui_entry_point_path, ] for entry_point in entry_points: self.assertTrue(op.exists(entry_point)) with open(cli_entry_point_path, "rt") as fp: cli_entry_point = fp.read() self.assertMultiLineEqual(cli_entry_point, r_cli_entry_point) with open(gui_entry_point_path, "rt") as fp: gui_entry_point = fp.read() self.assertMultiLineEqual(gui_entry_point, r_gui_entry_point) self.assertEqual(md5_file(op.join(egginst.bin_dir, "dummy.exe")), hashlib.md5(exe_data.cli).hexdigest()) self.assertEqual( md5_file(op.join(egginst.bin_dir, "dummy-gui.exe")), hashlib.md5(exe_data.gui).hexdigest() )