def testRecipeRemoveFile(self): with output_suppressed(): run_server(('HelloWorld.tar.bz2', )) requirements = Requirements(os.path.abspath('RecipeRemove.xml')) requirements.command = None driver = Driver(requirements=requirements, config=self.config) driver_download(driver) digests = driver.solver.selections[ requirements.interface_uri].digests path = self.config.stores.lookup_any(digests) assert os.path.exists(os.path.join(path, 'HelloWorld')) assert not os.path.exists(os.path.join(path, 'HelloWorld', 'main'))
def testBadConfig(self): path = basedir.save_config_path(namespaces.config_site, namespaces.config_prog) glob = os.path.join(path, 'global') assert not os.path.exists(glob) stream = open(glob, 'w') stream.write('hello!') stream.close() logger.setLevel(logging.ERROR) Driver(requirements=Requirements(foo_iface_uri), config=self.config) logger.setLevel(logging.WARN)
def testWrongSize(self): with output_suppressed(): run_server('Hello-wrong-size', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B', 'HelloWorld.tgz') driver = Driver(requirements = Requirements('http://localhost:8000/Hello-wrong-size'), config = self.config) assert driver.need_download() sys.stdin = Reply("Y\n") try: download_and_execute(driver, ['Hello'], main = 'Missing') assert 0 except model.SafeException as ex: if "Downloaded archive has incorrect size" not in str(ex): raise ex
def testAutoAcceptKey(self): self.config.auto_approve_keys = True with output_suppressed(): run_server('Hello', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B', 'HelloWorld.tgz') driver = Driver(requirements = Requirements('http://localhost:8000/Hello'), config = self.config) assert driver.need_download() sys.stdin = Reply("") try: download_and_execute(driver, ['Hello'], main = 'Missing') assert 0 except model.SafeException as ex: if "HelloWorld/Missing" not in str(ex): raise
def testArgs(self): p = Driver(requirements=Requirements(runnable), config=self.config) self.config.handler.wait_for_blocker(p.solve_with_downloads()) old_stdout = sys.stdout try: sys.stdout = StringIO() run.execute_selections(p.solver.selections, [], dry_run=True, stores=self.config.stores) out = sys.stdout.getvalue() finally: sys.stdout = old_stdout assert 'runner-arg' in out, out
def testRecipeSingleFile(self): with output_suppressed(): run_server(('HelloWorldMain', )) requirements = Requirements( os.path.abspath('RecipeSingleFile.xml')) requirements.command = None driver = Driver(requirements=requirements, config=self.config) driver_download(driver) digests = driver.solver.selections[ requirements.interface_uri].digests path = self.config.stores.lookup_any(digests) with open(os.path.join(path, 'bin', 'main'), 'rt') as stream: assert 'Hello World' in stream.read()
def testNoArchives(self): self.cache_iface(foo_iface_uri, """<?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> <implementation id='sha1=123' version='1.0' main='dummy'/> </interface>""" % foo_iface_uri) driver = Driver(requirements = Requirements(foo_iface_uri), config = self.config) recalculate(driver) assert not driver.solver.ready
def testRecipeFailure(self): with resourcewarnings_suppressed(): old_out = sys.stdout try: run_server('*') driver = Driver(requirements = Requirements(os.path.abspath('Recipe.xml')), config = self.config) try: download_and_execute(driver, []) assert False except download.DownloadError as ex: if "Connection" not in str(ex): raise finally: sys.stdout = old_out
def testAutopackage(self): old_out = sys.stdout try: sys.stdout = StringIO() run_server('HelloWorld.autopackage') driver = Driver(requirements = Requirements(os.path.abspath('Autopackage.xml')), config = self.config) try: download_and_execute(driver, []) assert False except model.SafeException as ex: if "HelloWorld/Missing" not in str(ex): raise finally: sys.stdout = old_out
def testRecipe(self): old_out = sys.stdout try: sys.stdout = StringIO() run_server(('HelloWorld.tar.bz2', 'redirect/dummy_1-1_all.deb', 'dummy_1-1_all.deb')) driver = Driver(requirements = Requirements(os.path.abspath('Recipe.xml')), config = self.config) try: download_and_execute(driver, []) assert False except model.SafeException as ex: if "HelloWorld/Missing" not in str(ex): raise ex finally: sys.stdout = old_out
def testArgList(self): d = Driver(requirements=Requirements(arglist), config=self.config) self.config.handler.wait_for_blocker(d.solve_with_downloads()) old_stdout = sys.stdout try: sys.stdout = StringIO() run.execute_selections(d.solver.selections, [], dry_run=True, stores=self.config.stores) out = sys.stdout.getvalue() finally: sys.stdout = old_stdout assert 'arg-for-runner -X ra1 -X ra2' in out, out assert 'command-arg ca1 ca2' in out, out
def testSymlink(self): old_out = sys.stdout try: sys.stdout = StringIO() run_server(('HelloWorld.tar.bz2', 'HelloSym.tgz')) driver = Driver(requirements = Requirements(os.path.abspath('RecipeSymlink.xml')), config = self.config) try: download_and_execute(driver, []) assert False except model.SafeException as ex: if 'Attempt to unpack dir over symlink "HelloWorld"' not in str(ex): raise self.assertEqual(None, basedir.load_first_cache('0install.net', 'implementations', 'main')) finally: sys.stdout = old_out
def testDryRun(self): with output_suppressed(): run_server('Hello', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B', 'HelloWorld.tgz') self.config.handler.dry_run = True driver = Driver(requirements = Requirements('http://localhost:8000/Hello'), config = self.config) assert driver.need_download() sys.stdin = Reply("Y\n") sys.stdout = StringIO() download_and_execute(driver, ['Hello'], main = 'Missing', dry_run = True) out = sys.stdout.getvalue() assert '[dry-run] would trust key DE937DD411906ACF7C263B396FCF121BE2390E0B for localhost:8000' in out, out assert '[dry-run] would cache feed http://localhost:8000/Hello as ' in out, out assert '[dry-run] would store implementation as ' in out, out assert '[dry-run] would execute:' in out, out
def testRejectKeyXML(self): with output_suppressed(): run_server('Hello.xml', '6FCF121BE2390E0B.gpg', '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B') driver = Driver(requirements = Requirements('http://example.com:8000/Hello.xml'), config = self.config) assert driver.need_download() sys.stdin = Reply("N\n") try: download_and_execute(driver, ['Hello']) assert 0 except model.SafeException as ex: if "No known implementations at all" not in str(ex): raise ex if "Not signed with a trusted key" not in str(self.config.handler.ex): raise self.config.handler.ex = None
def testRecipeExtractToExistingSubdirectory(self): with output_suppressed(): run_server(('HelloWorld.tar.bz2', 'HelloWorld.tar.bz2')) requirements = Requirements( os.path.abspath('RecipeExtractToExistingDest.xml')) requirements.command = None driver = Driver(requirements=requirements, config=self.config) driver_download(driver) digests = driver.solver.selections[ requirements.interface_uri].digests path = self.config.stores.lookup_any(digests) assert os.path.exists(os.path.join(path, 'HelloWorld', 'main')) # first archive's main assert os.path.exists( os.path.join( path, 'HelloWorld', 'HelloWorld', 'main')) # second archive, extracted to HelloWorld/
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 testCycle(self): self.cache_iface(foo_iface_uri, """<?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> <requires interface='%s'/> <implementation id='sha1=123' version='1.0'> <archive href='foo' size='10'/> </implementation> </group> </interface>""" % (foo_iface_uri, foo_iface_uri)) driver = Driver(requirements = Requirements(foo_iface_uri), config = self.config) recalculate(driver)
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 testBackground(self, verbose=False): r = Requirements('http://example.com:8000/Hello.xml') d = Driver(requirements=r, config=self.config) self.import_feed(r.interface_uri, 'Hello.xml') self.config.freshness = 0 self.config.network_use = model.network_minimal d.solver.solve(r.interface_uri, arch.get_host_architecture()) assert d.solver.ready, d.solver.get_failure_reason() @tasks. async def choose_download(registed_cb, nid, actions): try: assert actions == ['download', 'Download'], actions registed_cb(nid, 'download') except: import traceback traceback.print_exc() yield None global ran_gui ran_gui = False os.environ['DISPLAY'] = 'dummy' old_out = sys.stdout try: sys.stdout = StringIO() run_server('Hello.xml', '6FCF121BE2390E0B.gpg') my_dbus.system_services = { "org.freedesktop.NetworkManager": { "/org/freedesktop/NetworkManager": NetworkManager() } } my_dbus.user_callback = choose_download with trapped_exit(1): from zeroinstall.injector import config key_info = config.DEFAULT_KEY_LOOKUP_SERVER config.DEFAULT_KEY_LOOKUP_SERVER = None try: background.spawn_background_update(d, verbose) finally: config.DEFAULT_KEY_LOOKUP_SERVER = key_info finally: sys.stdout = old_out assert ran_gui
def testNoMain(self): tmp = tempfile.NamedTemporaryFile(mode = 'wt') tmp.write( """<?xml version="1.0" ?> <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation version='1.0' id='/bin'/> </interface>""") tmp.flush() driver = Driver(requirements = Requirements(tmp.name), config = self.config) try: download_and_execute(driver, ['Hello']) assert 0 except model.SafeException as ex: assert "No run command" in str(ex), ex tmp.close()
def testNeedDL(self): self.cache_iface(foo_iface_uri, """<?xml version="1.0" ?> <interface last-modified="0" uri="%s" main='ThisBetterNotExist' xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation version='1.0' id='sha1=123'> <archive href='http://foo/foo.tgz' size='100'/> </implementation> </interface>""" % foo_iface_uri) driver = Driver(requirements = Requirements(foo_iface_uri), config = self.config) self.config.network_use = model.network_full recalculate(driver) assert driver.need_download() assert driver.solver.ready
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 testUnknownAlg(self): self.cache_iface(foo_iface_uri, """<?xml version="1.0" ?> <interface uri="%s" xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation main='.' id='unknown=123' version='1.0'> <archive href='http://foo/foo.tgz' size='100'/> </implementation> </interface>""" % foo_iface_uri) self.config.fetcher = fetch.Fetcher(self.config) driver = Driver(requirements = Requirements(foo_iface_uri), config = self.config) try: assert driver.need_download() download_and_execute(driver, []) except model.SafeException as ex: assert "Use '_' not '=' for new algorithms, in unknown=123" in str(ex), ex
def testBestUnusable(self): self.cache_iface(foo_iface_uri, """<?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> <implementation id='sha1=123' version='1.0' arch='odd-weird' main='dummy'/> </interface>""" % foo_iface_uri) driver = Driver(requirements = Requirements(foo_iface_uri), config = self.config) self.config.network_use = model.network_offline recalculate(driver) assert not driver.solver.ready, driver.implementation try: download_and_execute(driver, []) assert False except model.SafeException as ex: assert "No usable implementations" in str(ex), ex
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 testLocalPath(self): # 0launch --get-selections Local.xml iface = os.path.join(mydir, "Local.xml") driver = Driver(requirements=Requirements(iface), config=self.config) driver.need_download() assert driver.solver.ready s1 = driver.solver.selections xml = s1.toDOM().toxml("utf-8") # Reload selections and check they're the same root = qdom.parse(BytesIO(xml)) s2 = selections.Selections(root) local_path = s2.selections[iface].local_path assert os.path.isdir(local_path), local_path assert not s2.selections[iface].digests, s2.selections[iface].digests # Add a newer implementation and try again feed = self.config.iface_cache.get_feed(iface) impl = model.ZeroInstallImplementation(feed, "foo bar=123", local_path=None) impl.version = model.parse_version('1.0') impl.commands["run"] = model.Command( qdom.Element(namespaces.XMLNS_IFACE, 'command', { 'path': 'dummy', 'name': 'run' }), None) impl.add_download_source('http://localhost/bar.tgz', 1000, None) feed.implementations = {impl.id: impl} assert driver.need_download() assert driver.solver.ready, driver.solver.get_failure_reason() s1 = driver.solver.selections xml = s1.toDOM().toxml("utf-8") root = qdom.parse(BytesIO(xml)) s2 = selections.Selections(root) xml = s2.toDOM().toxml("utf-8") qdom.parse(BytesIO(xml)) assert s2.selections[iface].local_path is None assert not s2.selections[iface].digests, s2.selections[iface].digests assert s2.selections[iface].id == 'foo bar=123'
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%23%23example.com%3A8000%23HelloWorld.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 testDownload(self): tmp = tempfile.NamedTemporaryFile(mode = 'wt') tmp.write( """<?xml version="1.0" ?> <interface main='ThisBetterNotExist' xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> <implementation version='1.0' id='/bin'/> </interface>""") tmp.flush() driver = Driver(requirements = Requirements(tmp.name), config = self.config) old, sys.stdout = sys.stdout, StringIO() try: download_and_execute(driver, ['Hello']) out = sys.stdout.getvalue() finally: sys.stdout = old assert "[dry-run] would execute: /bin/ThisBetterNotExist Hello\n" == out, out tmp.close()
def testDLfeed(self): self.cache_iface(foo_iface_uri, """<?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> <feed src='http://example.com'/> </interface>""" % foo_iface_uri) driver = Driver(requirements = Requirements(foo_iface_uri), config = self.config) self.config.network_use = model.network_full assert driver.need_download() feed = self.config.iface_cache.get_feed(foo_iface_uri) feed.feeds = [model.Feed('/BadFeed', None, False)] logger.setLevel(logging.ERROR) assert driver.need_download() # Triggers warning logger.setLevel(logging.WARN)
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[foo].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[foo].id == 'sha1=234' # The source assert driver.solver.selections[compiler].id == 'sha1=345' # A binary needed to compile it