def testDistro(self): native_url = 'http://example.com:8000/Native.xml' # Initially, we don't have the feed at all... master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is None, master_feed trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') run_server('Native.xml', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B') out, err = self.run_ocaml(['download', native_url]) assert not out, out assert "Can't find all required implementations" in err, err master_feed = self.config.iface_cache.get_feed(native_url, force = True) assert master_feed is not None assert master_feed.implementations == {} blocker = self.config.iface_cache.distro.fetch_candidates(master_feed) if blocker: tasks.wait_for_blocker(blocker) distro_feed_url = master_feed.get_distro_feed() assert distro_feed_url is not None distro_feed = self.config.iface_cache.get_feed(distro_feed_url) assert distro_feed is not None assert len(distro_feed.implementations) == 2, distro_feed.implementations
def ensure_cached(uri, command='run', config=None): """Ensure that an implementation of uri is cached. If not, it downloads one. It uses the GUI if a display is available, or the console otherwise. @param uri: the required interface @type uri: str @return: the selected implementations, or None if the user cancelled @rtype: L{zeroinstall.injector.selections.Selections} """ from zeroinstall.injector import policy if config is None: from zeroinstall.injector.config import load_config config = load_config() p = policy.Policy(uri, command=command, config=config) p.freshness = 0 # Don't check for updates if p.need_download() or not p.ready: if os.environ.get('DISPLAY', None): return get_selections_gui(uri, ['--command', command]) else: done = p.solve_and_download_impls() tasks.wait_for_blocker(done) return p.solver.selections
def ensure_cached(uri, command = 'run', config = None): """Ensure that an implementation of uri is cached. If not, it downloads one. It uses the GUI if a display is available, or the console otherwise. @param uri: the required interface @type uri: str @return: the selected implementations, or None if the user cancelled @rtype: L{zeroinstall.injector.selections.Selections} """ from zeroinstall.injector.driver import Driver if config is None: from zeroinstall.injector.config import load_config config = load_config() from zeroinstall.injector.requirements import Requirements requirements = Requirements(uri) requirements.command = command d = Driver(config, requirements) if d.need_download() or not d.solver.ready: sels = get_selections_gui(uri, ['--command', command], use_gui = None) if sels != DontUseGUI: return sels done = d.solve_and_download_impls() tasks.wait_for_blocker(done) return d.solver.selections
def handle(config, options, args): if not args: raise UsageError() for x in args: if not os.path.isfile(x): raise SafeException(_("File '%s' does not exist") % x) logger.info(_("Importing from file '%s'"), x) with open(x, 'rb') as signed_data: data, sigs = gpg.check_stream(signed_data) doc = minidom.parseString(data.read()) uri = doc.documentElement.getAttribute('uri') if not uri: raise SafeException(_("Missing 'uri' attribute on root element in '%s'") % x) logger.info(_("Importing information about interface %s"), uri) signed_data.seek(0) pending = PendingFeed(uri, signed_data) def run(): keys_downloaded = tasks.Task(pending.download_keys(config.fetcher), "download keys") yield keys_downloaded.finished tasks.check(keys_downloaded.finished) if not config.iface_cache.update_feed_if_trusted(uri, pending.sigs, pending.new_xml): blocker = config.trust_mgr.confirm_keys(pending) if blocker: yield blocker tasks.check(blocker) if not config.iface_cache.update_feed_if_trusted(uri, pending.sigs, pending.new_xml): raise SafeException(_("No signing keys trusted; not importing")) task = tasks.Task(run(), "import feed") tasks.wait_for_blocker(task.finished)
def _foreground_update(self, driver, use_gui): """We can't run with saved selections or solved selections without downloading. Try to open the GUI for a blocking download. If we can't do that, download without the GUI. @type driver: L{zeroinstall.injector.driver.Driver} @rtype: L{zeroinstall.injector.selections.Selections}""" from zeroinstall import helpers from zeroinstall.support import tasks gui_args = driver.requirements.get_as_options() + [ '--download-only', '--refresh' ] sels = helpers.get_selections_gui(driver.requirements.interface_uri, gui_args, test_callback=None, use_gui=use_gui) if sels is None: raise SafeException("Aborted by user") if sels is helpers.DontUseGUI: downloaded = driver.solve_and_download_impls(refresh=True) if downloaded: tasks.wait_for_blocker(downloaded) sels = driver.solver.selections self.set_selections(sels, set_last_checked=True) return sels
def testAbsMain(self): with tempfile.NamedTemporaryFile(prefix='test-', delete=False) as tmp: tmp.write(("""<?xml version="1.0" ?> <interface last-modified="1110752708" uri="%s" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <group main='/bin/sh'> <implementation id='.' version='1'/> </group> </interface>""" % foo_iface_uri).encode('utf-8')) driver = Driver(requirements=Requirements(tmp.name), config=self.config) try: downloaded = driver.solve_and_download_impls() if downloaded: tasks.wait_for_blocker(downloaded) run.execute_selections(driver.solver.selections, [], stores=self.config.stores) assert False except SafeException as ex: assert 'Command path must be relative' in str(ex), ex
def add_digests(feed_path, implementation, config): root = qdom.Element(namespaces.XMLNS_IFACE, 'interface', {}) name = qdom.Element(namespaces.XMLNS_IFACE, 'name', {}) name.content = 'Test' summary = qdom.Element(namespaces.XMLNS_IFACE, 'summary', {}) summary.content = 'testing' test_impl = qdom.Element(namespaces.XMLNS_IFACE, 'implementation', {'id': 'sha1new=1', 'version': '0'}) root.childNodes = [name, summary, test_impl] for child in implementation.childNodes: if child.namespaceURI == namespaces.XMLNS_IFACE and child.localName in ('archive', 'file', 'recipe'): test_impl.childNodes.append(dom_to_qdom(child)) feed = model.ZeroInstallFeed(root, local_path = feed_path) impl, = feed.implementations.values() assert impl.download_sources, "No retrieval methods in implementation!" method, = impl.download_sources basename_hrefs(method) # When fetcher asks FakeStores to check the digest, FakeStores instead stores the actual # digest on implementation. fake_stores = FakeStores(implementation, config.stores) blocker = config.fetcher.download_impl(impl, method, fake_stores) tasks.wait_for_blocker(blocker)
def get_selections(config, options, iface_uri, select_only, download_only, test_callback): """Get selections for iface_uri, according to the options passed. Will switch to GUI mode if necessary. @param options: options from OptionParser @param iface_uri: canonical URI of the interface @param select_only: return immediately even if the selected versions aren't cached @param download_only: wait for stale feeds, and display GUI button as Download, not Run @return: the selected versions, or None if the user cancels @rtype: L{selections.Selections} | None """ if options.offline: config.network_use = model.network_offline iface_cache = config.iface_cache # Try to load it as a feed. If it is a feed, it'll get cached. If not, it's a # selections document and we return immediately. maybe_selections = iface_cache.get_feed(iface_uri, selections_ok = True) if isinstance(maybe_selections, selections.Selections): if not select_only: blocker = maybe_selections.download_missing(config) if blocker: logger.info(_("Waiting for selected implementations to be downloaded...")) tasks.wait_for_blocker(blocker) return maybe_selections r = requirements.Requirements(iface_uri) r.parse_options(options) return get_selections_for(r, config, options, select_only, download_only, test_callback)
def build(self): self.seen = {} import gtk try: tasks.wait_for_blocker(self.recursive_build(self.iface_uri)) except SafeException, ex: self.note_error(str(ex))
def testImplMirrorFails(self): with resourcewarnings_suppressed(): trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') run_server('/Hello.xml', '/6FCF121BE2390E0B.gpg', server.Give404('/HelloWorld.tgz'), server.Give404('/0mirror/archive/http%3A%23%23example.com%3A8000%23HelloWorld.tgz'), server.Give404('/0mirror/feeds/http/example.com:8000/Hello.xml/impl/sha1=3ce644dc725f1d21cfcf02562c76f375944b266a')) driver = Driver(requirements = Requirements('http://example.com:8000/Hello.xml'), config = self.config) self.config.mirror = 'http://example.com:8000/0mirror' refreshed = driver.solve_with_downloads() tasks.wait_for_blocker(refreshed) assert driver.solver.ready getLogger().setLevel(logging.ERROR) try: downloaded = driver.download_uncached_implementations() tasks.wait_for_blocker(downloaded) assert 0 except download.DownloadError as ex: assert 'Missing: HelloWorld.tgz' in str(ex), ex self.assertEqual([ 'http://example.com:8000/Hello.xml', 'http://example.com:8000/6FCF121BE2390E0B.gpg', # The original archive: 'http://example.com:8000/HelloWorld.tgz', # Mirror of original archive: 'http://example.com:8000/0mirror/archive/http%3A%23%23example.com%3A8000%23HelloWorld.tgz', # Mirror of implementation: 'http://example.com:8000/0mirror/feeds/http/example.com:8000/Hello.xml/impl/sha1=3ce644dc725f1d21cfcf02562c76f375944b266a' ], traced_downloads)
def testDistro(self): with output_suppressed(): native_url = 'http://example.com:8000/Native.xml' # Initially, we don't have the feed at all... master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is None, master_feed trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') run_server('Native.xml', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B') driver = Driver(requirements = Requirements(native_url), config = self.config) assert driver.need_download() solve = driver.solve_with_downloads() tasks.wait_for_blocker(solve) tasks.check(solve) master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is not None assert master_feed.implementations == {} distro_feed_url = master_feed.get_distro_feed() assert distro_feed_url is not None distro_feed = self.config.iface_cache.get_feed(distro_feed_url) assert distro_feed is not None assert len(distro_feed.implementations) == 2, distro_feed.implementations
def testMirrors(self): with resourcewarnings_suppressed(): getLogger().setLevel(logging.ERROR) trust.trust_db.trust_key( 'DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') run_server( server.Give404('/Hello.xml'), '/0mirror/feeds/http/example.com:8000/Hello.xml/latest.xml', '/0mirror/keys/6FCF121BE2390E0B.gpg', server.Give404('/HelloWorld.tgz'), '/0mirror/archive/http%3A%23%23example.com%3A8000%23HelloWorld.tgz' ) driver = Driver( requirements=Requirements('http://example.com:8000/Hello.xml'), config=self.config) self.config.mirror = 'http://example.com:8000/0mirror' refreshed = driver.solve_with_downloads() tasks.wait_for_blocker(refreshed) assert driver.solver.ready #getLogger().setLevel(logging.WARN) downloaded = driver.download_uncached_implementations() tasks.wait_for_blocker(downloaded) path = self.config.stores.lookup_any( driver.solver.selections. selections['http://example.com:8000/Hello.xml'].digests) assert os.path.exists(os.path.join(path, 'HelloWorld', 'main'))
def testDistro(self): with output_suppressed(): native_url = 'http://example.com:8000/Native.xml' # Initially, we don't have the feed at all... master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is None, master_feed trust.trust_db.trust_key( 'DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') run_server( 'Native.xml', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B') driver = Driver(requirements=Requirements(native_url), config=self.config) assert driver.need_download() solve = driver.solve_with_downloads() tasks.wait_for_blocker(solve) tasks.check(solve) master_feed = self.config.iface_cache.get_feed(native_url) assert master_feed is not None assert master_feed.implementations == {} distro_feed_url = master_feed.get_distro_feed() assert distro_feed_url is not None distro_feed = self.config.iface_cache.get_feed(distro_feed_url) assert distro_feed is not None assert len( distro_feed.implementations) == 2, distro_feed.implementations
def ensure_cached(uri, command = 'run', config = None): """Ensure that an implementation of uri is cached. If not, it downloads one. It uses the GUI if a display is available, or the console otherwise. @param uri: the required interface @type uri: str @return: the selected implementations, or None if the user cancelled @rtype: L{zeroinstall.injector.selections.Selections} """ from zeroinstall.injector import policy, selections if config is None: from zeroinstall.injector.config import load_config config = load_config() p = policy.Policy(uri, command = command, config = config) p.freshness = 0 # Don't check for updates if p.need_download() or not p.ready: if os.environ.get('DISPLAY', None): return get_selections_gui(uri, ['--command', command]) else: done = p.solve_and_download_impls() tasks.wait_for_blocker(done) return selections.Selections(p)
def get_selections(config, options, iface_uri, select_only, download_only, test_callback): """Get selections for iface_uri, according to the options passed. Will switch to GUI mode if necessary. @param options: options from OptionParser @param iface_uri: canonical URI of the interface @param select_only: return immediately even if the selected versions aren't cached @param download_only: wait for stale feeds, and display GUI button as Download, not Run @return: the selected versions, or None if the user cancels @rtype: L{selections.Selections} | None """ if options.offline: config.network_use = model.network_offline iface_cache = config.iface_cache # Try to load it as a feed. If it is a feed, it'll get cached. If not, it's a # selections document and we return immediately. maybe_selections = iface_cache.get_feed(iface_uri, selections_ok=True) if isinstance(maybe_selections, selections.Selections): if not select_only: blocker = maybe_selections.download_missing(config) if blocker: logger.info( _("Waiting for selected implementations to be downloaded..." )) tasks.wait_for_blocker(blocker) return maybe_selections r = requirements.Requirements(iface_uri) r.parse_options(options) return get_selections_for(r, config, options, select_only, download_only, test_callback)
def handle(config, options, args): if args: raise UsageError() if options.offline: config.network_use = model.network_offline def slave_raw_input(prompt=""): ticket = take_ticket() send_json(["invoke", ticket, ["input", prompt]]) while True: message = recv_json() if message[0] == 'return' and message[1] == ticket: reply = message[2] assert reply[0] == 'ok', reply return reply[1] else: handle_message(config, options, message) support.raw_input = slave_raw_input @tasks. async def handle_events(): while True: logger.debug("waiting for stdin") yield tasks.InputBlocker(stdin, 'wait for commands from master') logger.debug("reading JSON") message = recv_json() logger.debug("got %s", message) if message is None: break handle_message(config, options, message) tasks.wait_for_blocker(handle_events())
def handle(config, options, args): if args: raise UsageError() if options.offline: config.network_use = model.network_offline def slave_raw_input(prompt = ""): ticket = take_ticket() send_json(["invoke", ticket, ["input", prompt]]) while True: message = recv_json() if message[0] == 'return' and message[1] == ticket: reply = message[2] assert reply[0] == 'ok', reply return reply[1] else: handle_message(config, options, message) support.raw_input = slave_raw_input @tasks.async def handle_events(): while True: logger.debug("waiting for stdin") yield tasks.InputBlocker(stdin, 'wait for commands from master') logger.debug("reading JSON") message = recv_json() logger.debug("got %s", message) if message is None: break handle_message(config, options, message) tasks.wait_for_blocker(handle_events())
def testReplay(self): with resourcewarnings_suppressed(): old_out = sys.stdout try: sys.stdout = StringIO() getLogger().setLevel(ERROR) iface = self.config.iface_cache.get_interface('http://example.com:8000/Hello.xml') mtime = int(os.stat('Hello-new.xml').st_mtime) with open('Hello-new.xml', 'rb') as stream: self.config.iface_cache.update_feed_from_network(iface.uri, stream.read(), mtime + 10000) trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') run_server(server.Give404('/Hello.xml'), 'latest.xml', '/0mirror/keys/6FCF121BE2390E0B.gpg', 'Hello.xml') self.config.mirror = 'http://example.com:8000/0mirror' # Update from mirror (should ignore out-of-date timestamp) refreshed = self.config.fetcher.download_and_import_feed(iface.uri, self.config.iface_cache) tasks.wait_for_blocker(refreshed) # Update from upstream (should report an error) refreshed = self.config.fetcher.download_and_import_feed(iface.uri, self.config.iface_cache) try: tasks.wait_for_blocker(refreshed) raise Exception("Should have been rejected!") except model.SafeException as ex: assert "New feed's modification time is before old version" in str(ex) # Must finish with the newest version self.assertEqual(1342285569, self.config.iface_cache._get_signature_date(iface.uri)) finally: sys.stdout = old_out
def testSource(self): iface_cache = self.config.iface_cache foo = iface_cache.get_interface('http://foo/Binary.xml') self.import_feed(foo.uri, 'Binary.xml') foo_src = iface_cache.get_interface('http://foo/Source.xml') self.import_feed(foo_src.uri, 'Source.xml') compiler = iface_cache.get_interface('http://foo/Compiler.xml') self.import_feed(compiler.uri, 'Compiler.xml') self.config.freshness = 0 self.config.network_use = model.network_full driver = Driver(requirements=Requirements('http://foo/Binary.xml'), config=self.config) tasks.wait_for_blocker(driver.solve_with_downloads()) assert driver.solver.selections.selections[foo.uri].id == 'sha1=123' # Now ask for source instead driver.requirements.source = True driver.requirements.command = 'compile' tasks.wait_for_blocker(driver.solve_with_downloads()) assert driver.solver.ready, driver.solver.get_failure_reason() assert driver.solver.selections.selections[ foo.uri].id == 'sha1=234' # The source assert driver.solver.selections.selections[ compiler.uri].id == 'sha1=345' # A binary needed to compile it
def handle(config, options, args): """@type config: L{zeroinstall.injector.config.Config} @type args: [str]""" if len(args) != 1: raise UsageError() app = config.app_mgr.lookup_app(args[0], missing_ok = True) if app is not None: sels = app.get_selections() r = app.get_requirements() do_select = r.parse_update_options(options) or options.refresh iface_uri = sels.interface else: iface_uri = model.canonical_iface_uri(args[0]) r = None do_select = True if do_select or options.gui: sels = select.get_selections(config, options, iface_uri, select_only = False, download_only = True, test_callback = None, requirements = r) if not sels: sys.exit(1) # Aborted by user else: dl = app.download_selections(sels) if dl: tasks.wait_for_blocker(dl) tasks.check(dl) if options.xml: select.show_xml(sels) if options.show: select.show_human(sels, config.stores) if app is not None and do_select: print(_("(use '0install update' to save the new parameters)"))
def testImplMirror(self): with resourcewarnings_suppressed(): # This is like testMirror, except we have a different archive (that generates the same content), # rather than an exact copy of the unavailable archive. trust.trust_db.trust_key( 'DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') run_server( '/Hello.xml', '/6FCF121BE2390E0B.gpg', server.Give404('/HelloWorld.tgz'), server.Give404( '/0mirror/archive/http%3A%2F%2Flocalhost%3A8000%2FHelloWorld.tgz' ), '/0mirror/feeds/http/example.com:8000/Hello.xml/impl/sha1=3ce644dc725f1d21cfcf02562c76f375944b266a' ) driver = Driver( requirements=Requirements('http://example.com:8000/Hello.xml'), config=self.config) self.config.mirror = 'http://example.com:8000/0mirror' refreshed = driver.solve_with_downloads() tasks.wait_for_blocker(refreshed) assert driver.solver.ready getLogger().setLevel(logging.ERROR) downloaded = driver.download_uncached_implementations() tasks.wait_for_blocker(downloaded) path = self.config.stores.lookup_any( driver.solver.selections. selections['http://example.com:8000/Hello.xml'].digests) assert os.path.exists(os.path.join(path, 'HelloWorld', 'main'))
def downloadZeroFeed(url): tasks.wait_for_blocker(download_info(url)) try: zeroPath = ZeroFindPath(url) return zeroPath except: return False
def download_and_execute(driver, prog_args, main=None, dry_run=True): downloaded = driver.solve_and_download_impls() if downloaded: tasks.wait_for_blocker(downloaded) run.execute_selections(driver.solver.selections, prog_args, stores=driver.config.stores, main=main, dry_run=dry_run)
def testRenameFailure(self): recipe = model.Recipe() try: recipe.steps.append(model.RenameStep("missing-source", "dest")) blocker = self.config.fetcher.cook("sha256new_XXX", recipe, self.config.stores) tasks.wait_for_blocker(blocker) assert 0 except model.SafeException as ex: assert "<rename> source 'missing-source' does not exist" in str(ex), ex
def testDownloadIconFails(self): path = model.canonical_iface_uri(os.path.join(mydir, 'Binary.xml')) iface = self.config.iface_cache.get_interface(path) blocker = self.config.fetcher.download_icon(iface) try: tasks.wait_for_blocker(blocker) assert False except download.DownloadError as ex: assert "Error downloading http://localhost/missing.png" in str(ex), ex
def doTest(self): imp.reload(packagekit) pk = packagekit.PackageKit() assert pk.available # Check none is found yet factory = Exception("not called") pk.get_candidates('gimp', factory, 'package:test') blocker = pk.fetch_candidates(["gimp"]) blocker2 = pk.fetch_candidates(["gimp"]) # Check batching too @tasks.async def wait(): yield blocker, blocker2 if blocker.happened: tasks.check(blocker) else: tasks.check(blocker2) tasks.wait_for_blocker(wait()) impls = {} def factory(impl_id, only_if_missing, installed): assert impl_id.startswith('package:') assert only_if_missing is True assert installed is False feed = None impl = model.DistributionImplementation(feed, impl_id, self) impl.installed = installed impls[impl_id] = impl return impl pk.get_candidates('gimp', factory, 'package:test') self.assertEqual(["package:test:gimp:2.6.8-2:x86_64"], list(impls.keys())) self.assertEqual(False, list(impls.values())[0].installed) impl, = impls.values() self.config.handler.allow_downloads = True _pk = pk.pk rm, = impl.download_sources dl = packagekit.PackageKitDownload('packagekit:' + rm.packagekit_id, hint = None, pk = _pk, packagekit_id = rm.packagekit_id, expected_size = rm.size) self.config.handler.monitor_download(dl) b = dl.downloaded tasks.wait_for_blocker(b) tasks.check(b) #self.assertEqual("/usr/bin/fixed", list(impls.values())[0].main) # Fixup not used in Python now tasks.wait_for_blocker(blocker) tasks.wait_for_blocker(blocker2) # Don't fetch it again tasks.wait_for_blocker(pk.fetch_candidates(["gimp"]))
def download_missing_selections(sels): from zeroinstall.support import tasks from zeroinstall.injector.config import load_config config = load_config() blocker = sels.download_missing(config) if blocker: logging.info("Waiting for selected implementations to be downloaded...") tasks.wait_for_blocker(blocker)
def testChunked(self): if sys.version_info[0] < 3: return # not a problem with Python 2 run_server('chunked') dl = self.config.fetcher.download_url('http://localhost/chunked') tmp = dl.tempfile tasks.wait_for_blocker(dl.downloaded) tasks.check(dl.downloaded) tmp.seek(0) self.assertEqual(b'hello world', tmp.read()) kill_server_process()
def testRecipeLocal(self): recipe = model.Recipe() blocker = self.config.fetcher.cook("sha256new_4OYMIQUY7QOBJGX36TEJS35ZEQT24QPEMSNZGTFESWMRW6CSXBKQ", recipe, self.config.stores) tasks.wait_for_blocker(blocker) try: recipe.steps.append(model.RemoveStep(".")) blocker = self.config.fetcher.cook("sha256new_XXX", recipe, self.config.stores) tasks.wait_for_blocker(blocker) assert 0 except model.SafeException as ex: assert "path '.' is not within the base directory" in str(ex), ex
def _check_for_updates(old_policy, verbose): from zeroinstall.injector.policy import Policy from zeroinstall.injector.config import load_config iface_cache = old_policy.config.iface_cache root_iface = iface_cache.get_interface(old_policy.root).get_name() background_config = load_config( BackgroundHandler(root_iface, old_policy.root)) policy = Policy(config=background_config, requirements=old_policy.requirements) info(_("Checking for updates to '%s' in a background process"), root_iface) if verbose: policy.handler.notify("Zero Install", _("Checking for updates to '%s'...") % root_iface, timeout=1) network_state = policy.handler.get_network_state() if network_state != _NetworkState.NM_STATE_CONNECTED: info( _("Not yet connected to network (status = %d). Sleeping for a bit..." ), network_state) import time time.sleep(120) if network_state in (_NetworkState.NM_STATE_DISCONNECTED, _NetworkState.NM_STATE_ASLEEP): info(_("Still not connected to network. Giving up.")) sys.exit(1) else: info(_("NetworkManager says we're on-line. Good!")) policy.freshness = 0 # Don't bother trying to refresh when getting the interface refresh = policy.refresh_all() # (causes confusing log messages) tasks.wait_for_blocker(refresh) # We could even download the archives here, but for now just # update the interfaces. if not policy.need_download(): if verbose: policy.handler.notify("Zero Install", _("No updates to download."), timeout=1) sys.exit(0) policy.handler.notify("Zero Install", _("Updates ready to download for '%s'.") % root_iface, timeout=1) _exec_gui(policy.root, '--refresh', '--systray') sys.exit(1)
def build(self): self.seen = {} import gtk try: tasks.wait_for_blocker(self.recursive_build(self.iface_uri)) except SafeException as ex: self.note_error(str(ex)) else: self.heading('All builds completed successfully!') self.dialog.set_response_sensitive(gtk.RESPONSE_CANCEL, False) self.dialog.set_response_sensitive(gtk.RESPONSE_OK, True) tasks.wait_for_blocker(self.closed)
def tearDown(self): # Wait for all downloads to finish, otherwise they may interfere with other tests for dl in list(self.config.handler.monitored_downloads): try: tasks.wait_for_blocker(dl.downloaded) except: pass BaseTest.tearDown(self) kill_server_process() # Flush out ResourceWarnings import gc; gc.collect()
def doTest(self): imp.reload(packagekit) pk = packagekit.PackageKit() assert pk.available # Check none is found yet factory = Exception("not called") pk.get_candidates('gimp', factory, 'package:test') blocker = pk.fetch_candidates(["gimp"]) blocker2 = pk.fetch_candidates(["gimp"]) # Check batching too @tasks.async def wait(): yield blocker, blocker2 if blocker.happened: tasks.check(blocker) else: tasks.check(blocker2) tasks.wait_for_blocker(wait()) impls = {} def factory(impl_id, only_if_missing, installed): assert impl_id.startswith('package:') assert only_if_missing is True assert installed is False feed = None impl = model.DistributionImplementation(feed, impl_id, self) impl.installed = installed impls[impl_id] = impl return impl pk.get_candidates('gimp', factory, 'package:test') self.assertEqual(["package:test:gimp:2.6.8-2:x86_64"], list(impls.keys())) self.assertEqual(False, list(impls.values())[0].installed) impl, = impls.values() fetcher = fetch.Fetcher(config = self.config) self.config.handler.allow_downloads = True b = fetcher.download_impl(impl, impl.download_sources[0], stores = None) tasks.wait_for_blocker(b) tasks.check(b) self.assertEqual("/usr/bin/fixed", list(impls.values())[0].main) tasks.wait_for_blocker(blocker) tasks.wait_for_blocker(blocker2) # Don't fetch it again tasks.wait_for_blocker(pk.fetch_candidates(["gimp"]))
def testCommandBindings(self): if 'SELF_COMMAND' in os.environ: del os.environ['SELF_COMMAND'] p = Driver(requirements = Requirements(command_feed), config = self.config) tasks.wait_for_blocker(p.solve_with_downloads()) old_stdout = sys.stdout try: sys.stdout = StringIO() run.execute_selections(p.solver.selections, [], main = 'runnable/go.sh', dry_run = True, stores = self.config.stores) finally: sys.stdout = old_stdout assert 'local' in os.environ['LOCAL'], os.environ['LOCAL'] assert 'SELF_COMMAND' in os.environ
def tearDown(self): # Wait for all downloads to finish, otherwise they may interfere with other tests for dl in list(self.config.handler.monitored_downloads): try: tasks.wait_for_blocker(dl.downloaded) except: pass helpers.get_selections_gui = real_get_selections_gui BaseTest.tearDown(self) kill_server_process() # Flush out ResourceWarnings import gc; gc.collect()
def testMirrors(self): old_out = sys.stdout try: sys.stdout = StringIO() getLogger().setLevel(ERROR) trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') run_server(server.Give404('/Hello.xml'), 'latest.xml', '/0mirror/keys/6FCF121BE2390E0B.gpg') driver = Driver(requirements = Requirements('http://example.com:8000/Hello.xml'), config = self.config) self.config.feed_mirror = 'http://example.com:8000/0mirror' refreshed = driver.solve_with_downloads() tasks.wait_for_blocker(refreshed) assert driver.solver.ready finally: sys.stdout = old_out
def testLocalArchive(self): local_iface = os.path.join(mydir, 'LocalArchive.xml') with open(local_iface, 'rb') as stream: root = qdom.parse(stream) # Not local => error feed = model.ZeroInstallFeed(root) impl = feed.implementations['impl1'] blocker = self.config.fetcher.download_impls([impl], self.config.stores) try: tasks.wait_for_blocker(blocker) assert 0 except model.SafeException as ex: assert "Relative URL 'HelloWorld.tgz' in non-local feed" in str( ex), ex feed = model.ZeroInstallFeed(root, local_path=local_iface) # Missing file impl2 = feed.implementations['impl2'] blocker = self.config.fetcher.download_impls([impl2], self.config.stores) try: tasks.wait_for_blocker(blocker) assert 0 except model.SafeException as ex: assert 'tests/IDONTEXIST.tgz' in str(ex), ex # Wrong size impl3 = feed.implementations['impl3'] blocker = self.config.fetcher.download_impls([impl3], self.config.stores) try: tasks.wait_for_blocker(blocker) assert 0 except model.SafeException as ex: assert 'feed says 177, but actually 176 bytes' in str(ex), ex self.config.network_use = model.network_offline r = Requirements(local_iface) r.command = None driver = Driver(requirements=r, config=self.config) driver.need_download() assert driver.solver.ready, driver.solver.get_failure_reason() # Local => OK impl = feed.implementations['impl1'] path = self.config.stores.lookup_maybe(impl.digests) assert not path blocker = self.config.fetcher.download_impls([impl], self.config.stores) tasks.wait_for_blocker(blocker) path = self.config.stores.lookup_any(impl.digests) assert os.path.exists(os.path.join(path, 'HelloWorld'))
def testSelectionsWithFeed(self): from zeroinstall.injector import cli root = qdom.parse(open("selections.xml")) sels = selections.Selections(root) with output_suppressed(): run_server('Hello.xml', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B', 'HelloWorld.tgz') sys.stdin = Reply("Y\n") tasks.wait_for_blocker(self.config.fetcher.download_and_import_feed('http://example.com:8000/Hello.xml', self.config.iface_cache)) cli.main(['--download-only', 'selections.xml'], config = self.config) path = self.config.stores.lookup_any(sels.selections['http://example.com:8000/Hello.xml'].digests) assert os.path.exists(os.path.join(path, 'HelloWorld', 'main')) assert sels.download_missing(self.config) is None
def handle(config, options, args): if len(args) < 1: raise UsageError() prog_args = args[1:] def test_callback(sels): from zeroinstall.injector import run return run.test_selections( sels, prog_args, False, # dry-run options.main) app = config.app_mgr.lookup_app(args[0], missing_ok=True) if app is not None: sels = app.get_selections(may_update=True) r = app.get_requirements() do_select = r.parse_update_options(options) iface_uri = sels.interface else: iface_uri = model.canonical_iface_uri(args[0]) do_select = True if do_select or options.gui: sels = select.get_selections(config, options, iface_uri, select_only=False, download_only=False, test_callback=test_callback) if not sels: sys.exit(1) # Aborted by user else: dl = app.download_selections(sels) if dl: tasks.wait_for_blocker(dl) tasks.check(dl) from zeroinstall.injector import run run.execute_selections(sels, prog_args, dry_run=options.dry_run, main=options.main, wrapper=options.wrapper, stores=config.stores)
def testCommandBindings(self): if 'SELF_COMMAND' in os.environ: del os.environ['SELF_COMMAND'] p = Driver(requirements=Requirements(command_feed), config=self.config) tasks.wait_for_blocker(p.solve_with_downloads()) old_stdout = sys.stdout try: sys.stdout = StringIO() run.execute_selections(p.solver.selections, [], main='runnable/go.sh', dry_run=True, stores=self.config.stores) finally: sys.stdout = old_stdout assert 'local' in os.environ['LOCAL'], os.environ['LOCAL'] assert 'SELF_COMMAND' in os.environ
def testSelectionsWithFeed(self): with open("selections.xml", 'rb') as stream: root = qdom.parse(stream) sels = selections.Selections(root) with output_suppressed(): run_server('Hello.xml', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B', 'HelloWorld.tgz') sys.stdin = Reply("Y\n") tasks.wait_for_blocker(self.config.fetcher.download_and_import_feed('http://example.com:8000/Hello.xml', self.config.iface_cache)) out, err = self.run_ocaml(['download', 'selections.xml']) assert not out, out assert not err, err path = self.config.stores.lookup_any(sels.selections['http://example.com:8000/Hello.xml'].digests) assert os.path.exists(os.path.join(path, 'HelloWorld', 'main')) assert sels.download_missing(self.config) is None
def testLocalFeedMirror(self): with resourcewarnings_suppressed(): # This is like testImplMirror, except we have a local feed. run_server(server.Give404('/HelloWorld.tgz'), '/0mirror/archive/http%3A%23%23example.com%3A8000%23HelloWorld.tgz') iface_uri = model.canonical_iface_uri('Hello.xml') driver = Driver(requirements = Requirements(iface_uri), config = self.config) self.config.mirror = 'http://example.com:8000/0mirror' refreshed = driver.solve_with_downloads() tasks.wait_for_blocker(refreshed) assert driver.solver.ready getLogger().setLevel(logging.ERROR) downloaded = driver.download_uncached_implementations() tasks.wait_for_blocker(downloaded) path = self.config.stores.lookup_any(driver.solver.selections.selections[iface_uri].digests) assert os.path.exists(os.path.join(path, 'HelloWorld', 'main'))
def _check_for_updates(requirements, verbose): from zeroinstall.injector.driver import Driver from zeroinstall.injector.config import load_config background_handler = BackgroundHandler(requirements.interface_uri, requirements.interface_uri) background_config = load_config(background_handler) root_iface = background_config.iface_cache.get_interface(requirements.interface_uri).get_name() background_handler.title = root_iface driver = Driver(config = background_config, requirements = requirements) info(_("Checking for updates to '%s' in a background process"), root_iface) if verbose: background_handler.notify("Zero Install", _("Checking for updates to '%s'...") % root_iface, timeout = 1) network_state = background_handler.get_network_state() if network_state not in (_NetworkState.NM_STATE_CONNECTED_SITE, _NetworkState.NM_STATE_CONNECTED_GLOBAL): info(_("Not yet connected to network (status = %d). Sleeping for a bit..."), network_state) import time time.sleep(120) if network_state in (_NetworkState.NM_STATE_DISCONNECTED, _NetworkState.NM_STATE_ASLEEP): info(_("Still not connected to network. Giving up.")) sys.exit(1) else: info(_("NetworkManager says we're on-line. Good!")) background_config.freshness = 0 # Don't bother trying to refresh when getting the interface refresh = driver.solve_with_downloads(force = True) # (causes confusing log messages) tasks.wait_for_blocker(refresh) # We could even download the archives here, but for now just # update the interfaces. if not driver.need_download(): if verbose: background_handler.notify("Zero Install", _("No updates to download."), timeout = 1) sys.exit(0) background_handler.notify("Zero Install", _("Updates ready to download for '%s'.") % root_iface, timeout = 1) _exec_gui(requirements.interface_uri, '--refresh', '--systray') sys.exit(1)
def testPackageKit05(self): #import logging; logging.getLogger().setLevel(logging.DEBUG) dbus.system_services['org.freedesktop.PackageKit'] = { '/org/freedesktop/PackageKit': PackageKit05(), '/tid/1': PackageKit05.Tid1(), '/tid/2': PackageKit05.Tid2(), '/tid/3': PackageKit05.Install(), } reload(packagekit) pk = packagekit.PackageKit() assert pk.available factory = Exception("not called") pk.get_candidates('gimp', factory, 'package:test') blocker = pk.fetch_candidates(["gimp"]) tasks.wait_for_blocker(blocker) tasks.check(blocker) impls = {} def factory(impl_id, only_if_missing, installed): assert impl_id.startswith('package:') assert only_if_missing is True assert installed is False feed = None impl = model.DistributionImplementation(feed, impl_id, self) impl.installed = installed impls[impl_id] = impl return impl pk.get_candidates('gimp', factory, 'package:test') self.assertEquals(["package:test:gimp:2.6.8-2:x86_64"], impls.keys()) impl, = impls.values() fetcher = fetch.Fetcher(config=self.config) self.config.handler.allow_downloads = True b = fetcher.download_impl(impl, impl.download_sources[0], stores=None) tasks.wait_for_blocker(b) tasks.check(b)
def handle(config, options, args): if args: raise UsageError() if options.offline: config.network_use = model.network_offline @tasks.async def handle_events(): while True: logger.debug("waiting for stdin") yield tasks.InputBlocker(stdin, 'wait for commands from master') logger.debug("reading JSON") message = recv_json() logger.debug("got %s", message) if message is None: break handle_message(config, options, message) tasks.wait_for_blocker(handle_events())
def testPackageKit05(self): #import logging; logging.getLogger().setLevel(logging.DEBUG) dbus.system_services['org.freedesktop.PackageKit'] = { '/org/freedesktop/PackageKit': PackageKit05(), '/tid/1': PackageKit05.Tid1(), '/tid/2': PackageKit05.Tid2(), '/tid/3': PackageKit05.Install(), } imp.reload(packagekit) pk = packagekit.PackageKit() assert pk.available factory = Exception("not called") pk.get_candidates('gimp', factory, 'package:test') blocker = pk.fetch_candidates(["gimp"]) tasks.wait_for_blocker(blocker) tasks.check(blocker) impls = {} def factory(impl_id, only_if_missing, installed): assert impl_id.startswith('package:') assert only_if_missing is True assert installed is False feed = None impl = model.DistributionImplementation(feed, impl_id, self) impl.installed = installed impls[impl_id] = impl return impl pk.get_candidates('gimp', factory, 'package:test') self.assertEqual(["package:test:gimp:2.6.8-2:x86_64"], impls.keys()) impl, = impls.values() fetcher = fetch.Fetcher(config = self.config) self.config.handler.allow_downloads = True b = fetcher.download_impl(impl, impl.download_sources[0], stores = None) tasks.wait_for_blocker(b) tasks.check(b)
def _check_for_updates(old_policy, verbose): from zeroinstall.injector.policy import Policy from zeroinstall.injector.config import load_config iface_cache = old_policy.config.iface_cache root_iface = iface_cache.get_interface(old_policy.root).get_name() background_config = load_config(BackgroundHandler(root_iface, old_policy.root)) policy = Policy(config = background_config, requirements = old_policy.requirements) info(_("Checking for updates to '%s' in a background process"), root_iface) if verbose: policy.handler.notify("Zero Install", _("Checking for updates to '%s'...") % root_iface, timeout = 1) network_state = policy.handler.get_network_state() if network_state != _NetworkState.NM_STATE_CONNECTED: info(_("Not yet connected to network (status = %d). Sleeping for a bit..."), network_state) import time time.sleep(120) if network_state in (_NetworkState.NM_STATE_DISCONNECTED, _NetworkState.NM_STATE_ASLEEP): info(_("Still not connected to network. Giving up.")) sys.exit(1) else: info(_("NetworkManager says we're on-line. Good!")) policy.freshness = 0 # Don't bother trying to refresh when getting the interface refresh = policy.refresh_all() # (causes confusing log messages) tasks.wait_for_blocker(refresh) # We could even download the archives here, but for now just # update the interfaces. if not policy.need_download(): if verbose: policy.handler.notify("Zero Install", _("No updates to download."), timeout = 1) sys.exit(0) policy.handler.notify("Zero Install", _("Updates ready to download for '%s'.") % root_iface, timeout = 1) _exec_gui(policy.root, '--refresh', '--systray') sys.exit(1)
def testInputBlocker(self): r, w = os.pipe() b = tasks.InputBlocker(r, "waiting for input") t = tasks.TimeoutBlocker(0.01, "timeout") @tasks.async def run(): yield b, t assert t.happened assert not b.happened os.write(w, b"!") yield b assert b.happened os.close(r) os.close(w) tasks.wait_for_blocker(run())