def testSelect(self): out, err = self.run_0install(['select']) assert out.lower().startswith("usage:") assert '--xml' in out out, err = self.run_0install(['select', 'Local.xml']) assert not err, err assert 'Version: 0.1' in out out, err = self.run_0install(['select', 'Local.xml', '--command=']) assert not err, err assert 'Version: 0.1' in out local_uri = model.canonical_iface_uri('Local.xml') out, err = self.run_0install(['select', 'Local.xml']) assert not err, err assert 'Version: 0.1' in out out, err = self.run_0install(['select', 'Local.xml', '--xml']) sels = selections.Selections( qdom.parse(BytesIO(str(out).encode('utf-8')))) assert sels.selections[local_uri].version == '0.1' out, err = self.run_0install(['select', 'selections.xml']) assert not err, err assert 'Version: 1\n' in out assert '(not cached)' in out out, err = self.run_0install(['select', 'runnable/RunExec.xml']) assert not err, err assert 'Runner' in out, out
def test(top_xml, diag_xml, expected_error): root = qdom.parse( BytesIO("""<?xml version="1.0" ?> <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface" uri="{top}"> <name>Top-level</name> <summary>Top-level</summary> <group> {top_xml} </group> </interface>""".format(top=top_uri, top_xml=top_xml).encode("utf-8"))) self.import_feed(top_uri, root) root = qdom.parse( BytesIO("""<?xml version="1.0" ?> <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface" uri="{diag}"> <name>Diagnostics</name> <summary>Diagnostics</summary> <group> {impls} </group> </interface>""".format(diag=diag_uri, impls=diag_xml).encode("utf-8"))) self.import_feed(diag_uri, root) root = qdom.parse( BytesIO("""<?xml version="1.0" ?> <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface" uri="{old}"> <name>Old</name> <summary>Old</summary> <feed src='{diag}'/> <replaced-by interface='{diag}'/> </interface>""".format(diag=diag_uri, old=old_uri).encode("utf-8"))) self.import_feed(old_uri, root) r = Requirements(top_uri) r.os = "Windows" r.cpu = "x86_64" s = solver.DefaultSolver(self.config) s.solve_for(r) assert not s.ready, s.selections.selections if expected_error != str(s.get_failure_reason()): print(s.get_failure_reason()) self.assertEqual(expected_error, str(s.get_failure_reason())) return s
def testSelectOnly(self): os.environ['DISPLAY'] = ':foo' out, err = self.run_0install(['select', '--xml', 'Hello.xml']) self.assertEqual("", err) assert out.endswith("Finished\n"), out out = out[:-len("Finished\n")] root = qdom.parse(BytesIO(str(out).encode('utf-8'))) self.assertEqual(namespaces.XMLNS_IFACE, root.uri) sels = selections.Selections(root) sel, = sels.selections.values() self.assertEqual("sha1=3ce644dc725f1d21cfcf02562c76f375944b266a", sel.id)
def testDownload(self): out, err = self.run_0install(['download']) assert out.lower().startswith("usage:") assert '--show' in out assert 'file\n' in self.complete(["download", ""], 2) out, err = self.run_0install(['download', 'Local.xml', '--show']) assert not err, err assert 'Version: 0.1' in out local_uri = model.canonical_iface_uri('Local.xml') out, err = self.run_0install(['download', 'Local.xml', '--xml']) assert not err, err sels = selections.Selections( qdom.parse(BytesIO(str(out).encode('utf-8')))) assert sels.selections[local_uri].version == '0.1' out, err = self.run_0install( ['download', 'Local.xml', '--show', '--with-store=/foo']) assert not err, err assert self.config.stores.stores[-1].dir == '/foo' out, err = self.run_0install( ['download', '--offline', 'selections.xml']) assert 'Would download' in err self.config.network_use = model.network_full self.config.stores = TestStores() digest = 'sha1=3ce644dc725f1d21cfcf02562c76f375944b266a' self.config.fetcher.allow_download(digest) out, err = self.run_0install(['download', 'Hello.xml', '--show']) assert not err, err assert self.config.stores.lookup_any([digest]).startswith('/fake') assert 'Version: 1\n' in out out, err = self.run_0install( ['download', '--offline', 'selections.xml', '--show']) assert '/fake_store' in out self.config.network_use = model.network_full
def testBackgroundUnsolvable(self): my_dbus.system_services = {"org.freedesktop.NetworkManager": {"/org/freedesktop/NetworkManager": NetworkManager()}} trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') # Create new app run_server('Hello.xml', '6FCF121BE2390E0B.gpg', 'HelloWorld.tgz') out, err = self.run_ocaml(['add', 'test-app', 'http://example.com:8000/Hello.xml']) kill_server_process() assert not out, out assert not err, err # Delete cached implementation so we need to download it again out, err = self.run_ocaml(['select', '--xml', 'test-app'], binary = True) sels = selections.Selections(qdom.parse(BytesIO(out))) stored = sels.selections['http://example.com:8000/Hello.xml'].get_path(self.config.stores) assert os.path.basename(stored).startswith('sha1') ro_rmtree(stored) out, err = self.run_ocaml(['select', '--xml', 'test-app'], binary = True) assert not err, err sels = selections.Selections(qdom.parse(BytesIO(out))) # Replace the selection with a bogus and unusable <package-implementation> sel, = sels.selections.values() sel.attrs['id'] = "package:dummy:badpackage" sel.attrs['from-feed'] = "distribution:http://example.com:8000/Hello.xml" sel.attrs['package'] = "badpackage" sel.get_command('run').qdom.attrs['path'] = '/i/dont/exist' app = basedir.load_first_config(namespaces.config_site, "apps", 'test-app') with open(os.path.join(app, 'selections.xml'), 'wt') as stream: doc = sels.toDOM() doc.writexml(stream, addindent=" ", newl="\n", encoding = 'utf-8') # Not time for a background update yet, but the missing binary should trigger # an update anyway. self.config.freshness = 0 # Check we try to launch the GUI... os.environ['DISPLAY'] = 'dummy' run_server('Hello.xml', 'HelloWorld.tgz') out, err = self.run_ocaml(['download', '--xml', '-v', 'test-app'], binary = True) kill_server_process() err = err.decode('utf-8') assert 'get new selections; current ones are not usable' in err, err assert 'get-selections-gui' in err, err sels = selections.Selections(qdom.parse(BytesIO(out))) # Check we can also work without the GUI... del os.environ['DISPLAY'] # Delete cached implementation so we need to download it again out, err = self.run_ocaml(['select', '--xml', 'test-app'], binary = True) sels = selections.Selections(qdom.parse(BytesIO(out))) stored = sels.selections['http://example.com:8000/Hello.xml'].get_path(self.config.stores) assert os.path.basename(stored).startswith('sha1') ro_rmtree(stored) run_server('Hello.xml', 'HelloWorld.tgz') out, err = self.run_ocaml(['download', '--xml', '-v', 'test-app'], binary = True) kill_server_process() err = err.decode('utf-8') assert 'get new selections; current ones are not usable' in err, err assert 'get-selections-gui' not in err, err sels = selections.Selections(qdom.parse(BytesIO(out))) # Now trigger a background update which discovers that no solution is possible timestamp = os.path.join(app, 'last-checked') last_check_attempt = os.path.join(app, 'last-check-attempt') selections_path = os.path.join(app, 'selections.xml') def reset_timestamps(): global ran_gui ran_gui = False os.utime(timestamp, (1, 1)) # 1970 os.utime(selections_path, (1, 1)) if os.path.exists(last_check_attempt): os.unlink(last_check_attempt) reset_timestamps() out, err = self.run_ocaml(['destroy', 'test-app']) assert not out, out assert not err, err run_server('Hello.xml') out, err = self.run_ocaml(['add', '--source', 'test-app', 'http://example.com:8000/Hello.xml']) assert not out, out assert 'We want source and this is a binary' in err, err
def testBackgroundApp(self): my_dbus.system_services = {"org.freedesktop.NetworkManager": {"/org/freedesktop/NetworkManager": NetworkManager()}} trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') global ran_gui with output_suppressed(): # Create an app, downloading a version of Hello run_server('Hello.xml', '6FCF121BE2390E0B.gpg', 'HelloWorld.tgz') out, err = self.run_ocaml(['add', 'test-app', 'http://example.com:8000/Hello.xml']) assert not out, out assert not err, err kill_server_process() app = basedir.load_first_config(namespaces.config_site, "apps", 'test-app') timestamp = os.path.join(app, 'last-checked') last_check_attempt = os.path.join(app, 'last-check-attempt') selections_path = os.path.join(app, 'selections.xml') def reset_timestamps(): global ran_gui ran_gui = False os.utime(timestamp, (1, 1)) # 1970 os.utime(selections_path, (1, 1)) if os.path.exists(last_check_attempt): os.unlink(last_check_attempt) # Not time for a background update yet self.config.freshness = 100 self.run_ocaml(['download', 'test-app']) assert not ran_gui # Trigger a background update - no updates found os.environ['ZEROINSTALL_TEST_BACKGROUND'] = 'true' reset_timestamps() run_server('Hello.xml') # (-vv mode makes us wait for the background process to finish) out, err = self.run_ocaml(['download', '-vv', 'test-app']) assert not out, out assert 'Background update: no updates found for test-app' in err, err self.assertNotEqual(1, os.stat(timestamp).st_mtime) self.assertEqual(1, os.stat(selections_path).st_mtime) kill_server_process() # Change the selections sels_path = os.path.join(app, 'selections.xml') with open(sels_path) as stream: old = stream.read() with open(sels_path, 'w') as stream: stream.write(old.replace('Hello', 'Goodbye')) # Trigger another background update - metadata changes found reset_timestamps() run_server('Hello.xml') out, err = self.run_ocaml(['download', '-vv', 'test-app']) assert not out, out assert 'Quick solve succeeded; saving new selections' in err, err self.assertNotEqual(1, os.stat(timestamp).st_mtime) self.assertNotEqual(1, os.stat(selections_path).st_mtime) kill_server_process() # Trigger another background update - GUI needed now # Delete cached implementation so we need to download it again out, err = self.run_ocaml(['select', '--xml', 'test-app'], binary = True) sels = selections.Selections(qdom.parse(BytesIO(out))) stored = sels.selections['http://example.com:8000/Hello.xml'].get_path(self.config.stores) assert os.path.basename(stored).startswith('sha1') ro_rmtree(stored) # Replace with a valid local feed so we don't have to download immediately with open(sels_path, 'w') as stream: stream.write(local_hello) os.environ['DISPLAY'] = 'dummy' reset_timestamps() run_server('Hello.xml') out, err = self.run_ocaml(['download', '-vv', 'test-app']) assert not out, out assert 'get-selections-gui' in err, err kill_server_process() # Now again with no DISPLAY reset_timestamps() del os.environ['DISPLAY'] run_server('Hello.xml', 'HelloWorld.tgz') out, err = self.run_ocaml(['download', '-vv', 'test-app']) assert not out, out assert 'GUI unavailable; downloading with no UI' in err, err self.assertNotEqual(1, os.stat(timestamp).st_mtime) self.assertNotEqual(1, os.stat(selections_path).st_mtime) kill_server_process() out, err = self.run_ocaml(['select', '--xml', 'test-app'], binary = True) sels = selections.Selections(qdom.parse(BytesIO(out))) sel, = sels.selections.values() self.assertEqual("sha1=3ce644dc725f1d21cfcf02562c76f375944b266a", sel.id) # Untrust the key trust.trust_db.untrust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000') os.environ['DISPLAY'] = 'dummy' reset_timestamps() run_server('Hello.xml') out, err = self.run_ocaml(['download', '-vv', 'test-app']) assert not out, out assert 'need to switch to GUI to confirm keys' in err, err assert 'get-selections-gui' in err, err kill_server_process() # Update not triggered because of last-check-attempt ran_gui = False os.utime(timestamp, (1, 1)) # 1970 os.utime(selections_path, (1, 1)) out, err = self.run_ocaml(['download', '-vv', 'test-app']) assert not out, out assert 'Tried to check within last hour; not trying again now' in err, err