Example #1
0
    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
Example #2
0
    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'))
Example #3
0
    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
Example #4
0
    def testAbsMain(self):
        p = Driver(requirements=Requirements(command_feed), 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, [],
                                   main='/runnable/runner',
                                   dry_run=True,
                                   stores=self.config.stores)
        finally:
            sys.stdout = old_stdout

        try:
            old_stdout = sys.stdout
            try:
                sys.stdout = StringIO()
                run.execute_selections(p.solver.selections, [],
                                       main='/runnable/not-there',
                                       dry_run=True,
                                       stores=self.config.stores)
            finally:
                sys.stdout = old_stdout
        except SafeException as ex:
            assert 'not-there' in unicode(ex)
Example #5
0
	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)
Example #6
0
	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
Example #7
0
    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'))
Example #8
0
	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
Example #9
0
	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
Example #10
0
 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
Example #11
0
 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
Example #12
0
	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
Example #13
0
	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
Example #14
0
	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
Example #15
0
	def testBadMain(self):
		r = Requirements(command_feed)
		r.command = None
		d = Driver(requirements = r, config = self.config)
		self.config.handler.wait_for_blocker(d.solve_with_downloads())

		try:
			run.execute_selections(d.solver.selections, [], dry_run = True, stores = self.config.stores)
			assert 0
		except SafeException as ex:
			self.assertEqual("Can't run: no command specified!", unicode(ex))

		try:
			run.execute_selections(d.solver.selections, [], main = 'relpath', dry_run = True, stores = self.config.stores)
			assert 0
		except SafeException as ex:
			self.assertEqual("Can't use a relative replacement main when there is no original one!", unicode(ex))
Example #16
0
    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
Example #17
0
	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'))
Example #18
0
	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'))
Example #19
0
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)
Example #20
0
	def testAbsMain(self):
		p = Driver(requirements = Requirements(command_feed), 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, [], main = '/runnable/runner', dry_run = True, stores = self.config.stores)
		finally:
			sys.stdout = old_stdout

		try:
			old_stdout = sys.stdout
			try:
				sys.stdout = StringIO()
				run.execute_selections(p.solver.selections, [], main = '/runnable/not-there', dry_run = True, stores = self.config.stores)
			finally:
				sys.stdout = old_stdout
		except SafeException as ex:
			assert 'not-there' in unicode(ex)
Example #21
0
	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'))
Example #22
0
	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'))
Example #23
0
    def testBadMain(self):
        r = Requirements(command_feed)
        r.command = None
        d = Driver(requirements=r, config=self.config)
        self.config.handler.wait_for_blocker(d.solve_with_downloads())

        try:
            run.execute_selections(d.solver.selections, [],
                                   dry_run=True,
                                   stores=self.config.stores)
            assert 0
        except SafeException as ex:
            self.assertEqual("Can't run: no command specified!", unicode(ex))

        try:
            run.execute_selections(d.solver.selections, [],
                                   main='relpath',
                                   dry_run=True,
                                   stores=self.config.stores)
            assert 0
        except SafeException as ex:
            self.assertEqual(
                "Can't use a relative replacement main when there is no original one!",
                unicode(ex))
Example #24
0
	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():
			# Select a version of Hello
			run_server('Hello.xml', '6FCF121BE2390E0B.gpg', 'HelloWorld.tgz')
			r = Requirements('http://example.com:8000/Hello.xml')
			driver = Driver(requirements = r, config = self.config)
			tasks.wait_for_blocker(driver.solve_with_downloads())
			assert driver.solver.ready
			kill_server_process()

			# Save it as an app
			app = self.config.app_mgr.create_app('test-app', r)
			app.set_selections(driver.solver.selections)
			timestamp = os.path.join(app.path, 'last-checked')
			last_check_attempt = os.path.join(app.path, 'last-check-attempt')
			selections_path = os.path.join(app.path, '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)

			# Download the implementation
			sels = app.get_selections(may_update = True)
			run_server('HelloWorld.tgz')
			tasks.wait_for_blocker(app.download_selections(sels))
			kill_server_process()

			# Not time for a background update yet
			self.config.freshness = 100
			dl = app.download_selections(app.get_selections(may_update = True))
			assert dl == None
			assert not ran_gui

			# Trigger a background update - no updates found
			reset_timestamps()
			run_server('Hello.xml')
			with trapped_exit(1):
				dl = app.download_selections(app.get_selections(may_update = True))
				assert dl == None
			assert not ran_gui
			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.path, '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')
			with trapped_exit(1):
				dl = app.download_selections(app.get_selections(may_update = True))
				assert dl == None
			assert not ran_gui
			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
			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')
			with trapped_exit(1):
				dl = app.download_selections(app.get_selections(may_update = True))
				assert dl == None
			assert ran_gui	# (so doesn't actually update)
			kill_server_process()

			# Now again with no DISPLAY
			reset_timestamps()
			del os.environ['DISPLAY']
			run_server('Hello.xml', 'HelloWorld.tgz')
			with trapped_exit(1):
				dl = app.download_selections(app.get_selections(may_update = True))
				assert dl == None
			assert not ran_gui	# (so doesn't actually update)

			self.assertNotEqual(1, os.stat(timestamp).st_mtime)
			self.assertNotEqual(1, os.stat(selections_path).st_mtime)
			kill_server_process()

			sels = app.get_selections()
			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')
			with trapped_exit(1):
				#import logging; logging.getLogger().setLevel(logging.INFO)
				dl = app.download_selections(app.get_selections(may_update = True))
				assert dl == None
			assert ran_gui
			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))
			dl = app.download_selections(app.get_selections(may_update = True))
			assert dl == None
			assert not ran_gui
Example #25
0
	def testBackgroundUnsolvable(self):
		my_dbus.system_services = {"org.freedesktop.NetworkManager": {"/org/freedesktop/NetworkManager": NetworkManager()}}

		trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B', 'example.com:8000')

		global ran_gui

		# Select a version of Hello
		run_server('Hello.xml', '6FCF121BE2390E0B.gpg', 'HelloWorld.tgz')
		r = Requirements('http://example.com:8000/Hello.xml')
		driver = Driver(requirements = r, config = self.config)
		tasks.wait_for_blocker(driver.solve_with_downloads())
		assert driver.solver.ready
		kill_server_process()

		# Save it as an app
		app = self.config.app_mgr.create_app('test-app', r)

		# Replace the selection with a bogus and unusable <package-implementation>
		sels = driver.solver.selections
		sel, = sels.selections.values()
		sel.attrs['id'] = "package:dummy:badpackage"
		sel.attrs['package'] = "badpackage"
		sel.get_command('run').qdom.attrs['path'] = '/i/dont/exist'

		app.set_selections(driver.solver.selections)

		# 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'
		try:
			app.get_selections(may_update = True)
			assert 0
		except model.SafeException as ex:
			assert 'Aborted by user' in str(ex)
		assert ran_gui
		ran_gui = False

		# Check we can also work without the GUI...
		del os.environ['DISPLAY']

		run_server('Hello.xml', 'HelloWorld.tgz')
		sels = app.get_selections(may_update = True)
		kill_server_process()

		dl = app.download_selections(sels)
		assert dl == None

		assert not ran_gui

		# Now trigger a background update which discovers that no solution is possible
		timestamp = os.path.join(app.path, 'last-checked')
		last_check_attempt = os.path.join(app.path, 'last-check-attempt')
		selections_path = os.path.join(app.path, '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()

		r.source = True
		app.set_requirements(r)
		run_server('Hello.xml')
		with trapped_exit(1):
			sels = app.get_selections(may_update = True)
		kill_server_process()
Example #26
0
def _check_for_updates(requirements, verbose, app):
    """@type requirements: L{zeroinstall.injector.requirements.Requirements}
	@type verbose: bool
	@type app: L{zeroinstall.apps.App}"""
    if app is not None:
        old_sels = app.get_selections()

    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)

    logger.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):
        logger.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):
            logger.info(_("Still not connected to network. Giving up."))
            sys.exit(1)
    else:
        logger.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)

    if background_handler.need_gui or not driver.solver.ready or driver.get_uncached_implementations(
    ):
        if verbose:
            background_handler.notify(
                "Zero Install",
                _("Updates ready to download for '%s'.") % root_iface,
                timeout=1)

        # Run the GUI if possible...
        from zeroinstall import helpers
        gui_args = ['--refresh', '--systray', '--download'
                    ] + requirements.get_as_options()
        new_sels = helpers.get_selections_gui(requirements.interface_uri,
                                              gui_args,
                                              use_gui=None)
        if new_sels is None:
            sys.exit(0)  # Cancelled by user
        elif new_sels is helpers.DontUseGUI:
            if not driver.solver.ready:
                background_handler.notify("Zero Install",
                                          _("Can't update '%s'") % root_iface)
                sys.exit(1)

            tasks.wait_for_blocker(driver.download_uncached_implementations())
            new_sels = driver.solver.selections

        if app is None:
            background_handler.notify(
                "Zero Install",
                _("{name} updated.").format(name=root_iface),
                timeout=1)
    else:
        if verbose:
            background_handler.notify("Zero Install",
                                      _("No updates to download."),
                                      timeout=1)
        new_sels = driver.solver.selections

    if app is not None:
        assert driver.solver.ready
        from zeroinstall.support import xmltools
        if not xmltools.nodes_equal(new_sels.toDOM(), old_sels.toDOM()):
            app.set_selections(new_sels)
            background_handler.notify(
                "Zero Install",
                _("{app} updated.").format(app=app.get_name()),
                timeout=1)
        app.set_last_checked()
    sys.exit(0)
Example #27
0
def _check_for_updates(requirements, verbose, app):
	if app is not None:
		old_sels = app.get_selections()

	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)

	logger.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):
		logger.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):
			logger.info(_("Still not connected to network. Giving up."))
			sys.exit(1)
	else:
		logger.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)

	if background_handler.need_gui or driver.get_uncached_implementations():
		if verbose:
			background_handler.notify("Zero Install",
					      _("Updates ready to download for '%s'.") % root_iface,
					      timeout = 1)

		# Run the GUI if possible...
		from zeroinstall import helpers
		gui_args = ['--refresh', '--systray', '--download'] + requirements.get_as_options()
		new_sels = helpers.get_selections_gui(requirements.interface_uri, gui_args, use_gui = None)
		if new_sels is None:
			sys.exit(0)	# Cancelled by user
		elif new_sels is helpers.DontUseGUI:
			tasks.wait_for_blocker(driver.download_uncached_implementations())
			new_sels = driver.solver.selections

		if app is None:
			background_handler.notify("Zero Install",
					      _("{name} updated.").format(name = root_iface),
					      timeout = 1)
	else:
		if verbose:
			background_handler.notify("Zero Install", _("No updates to download."), timeout = 1)
		new_sels = driver.solver.selections

	if app is not None:
		assert driver.solver.ready
		from zeroinstall.support import xmltools
		if not xmltools.nodes_equal(new_sels.toDOM(), old_sels.toDOM()):
			app.set_selections(new_sels)
			background_handler.notify("Zero Install",
					      _("{app} updated.").format(app = app.get_name()),
					      timeout = 1)
		app.set_last_checked()
	sys.exit(0)
Example #28
0
    def testBackgroundUnsolvable(self):
        my_dbus.system_services = {
            "org.freedesktop.NetworkManager": {
                "/org/freedesktop/NetworkManager": NetworkManager()
            }
        }

        trust.trust_db.trust_key('DE937DD411906ACF7C263B396FCF121BE2390E0B',
                                 'example.com:8000')

        global ran_gui

        # Select a version of Hello
        run_server('Hello.xml', '6FCF121BE2390E0B.gpg', 'HelloWorld.tgz')
        r = Requirements('http://example.com:8000/Hello.xml')
        driver = Driver(requirements=r, config=self.config)
        tasks.wait_for_blocker(driver.solve_with_downloads())
        assert driver.solver.ready
        kill_server_process()

        # Save it as an app
        app = self.config.app_mgr.create_app('test-app', r)

        # Replace the selection with a bogus and unusable <package-implementation>
        sels = driver.solver.selections
        sel, = sels.selections.values()
        sel.attrs['id'] = "package:dummy:badpackage"
        sel.attrs['package'] = "badpackage"
        sel.get_command('run').qdom.attrs['path'] = '/i/dont/exist'

        app.set_selections(driver.solver.selections)

        # 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'
        try:
            app.get_selections(may_update=True)
            assert 0
        except model.SafeException as ex:
            assert 'Aborted by user' in str(ex)
        assert ran_gui
        ran_gui = False

        # Check we can also work without the GUI...
        del os.environ['DISPLAY']

        run_server('Hello.xml', 'HelloWorld.tgz')
        sels = app.get_selections(may_update=True)
        kill_server_process()

        dl = app.download_selections(sels)
        assert dl == None

        assert not ran_gui

        # Now trigger a background update which discovers that no solution is possible
        timestamp = os.path.join(app.path, 'last-checked')
        last_check_attempt = os.path.join(app.path, 'last-check-attempt')
        selections_path = os.path.join(app.path, '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()

        r.source = True
        app.set_requirements(r)
        run_server('Hello.xml')
        with trapped_exit(1):
            sels = app.get_selections(may_update=True)
        kill_server_process()
Example #29
0
    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():
            # Select a version of Hello
            run_server('Hello.xml', '6FCF121BE2390E0B.gpg', 'HelloWorld.tgz')
            r = Requirements('http://example.com:8000/Hello.xml')
            driver = Driver(requirements=r, config=self.config)
            tasks.wait_for_blocker(driver.solve_with_downloads())
            assert driver.solver.ready
            kill_server_process()

            # Save it as an app
            app = self.config.app_mgr.create_app('test-app', r)
            app.set_selections(driver.solver.selections)
            timestamp = os.path.join(app.path, 'last-checked')
            last_check_attempt = os.path.join(app.path, 'last-check-attempt')
            selections_path = os.path.join(app.path, '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)

            # Download the implementation
            sels = app.get_selections(may_update=True)
            run_server('HelloWorld.tgz')
            tasks.wait_for_blocker(app.download_selections(sels))
            kill_server_process()

            # Not time for a background update yet
            self.config.freshness = 100
            dl = app.download_selections(app.get_selections(may_update=True))
            assert dl == None
            assert not ran_gui

            # Trigger a background update - no updates found
            reset_timestamps()
            run_server('Hello.xml')
            with trapped_exit(1):
                dl = app.download_selections(
                    app.get_selections(may_update=True))
                assert dl == None
            assert not ran_gui
            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.path, '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')
            with trapped_exit(1):
                dl = app.download_selections(
                    app.get_selections(may_update=True))
                assert dl == None
            assert not ran_gui
            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
            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')
            with trapped_exit(1):
                dl = app.download_selections(
                    app.get_selections(may_update=True))
                assert dl == None
            assert ran_gui  # (so doesn't actually update)
            kill_server_process()

            # Now again with no DISPLAY
            reset_timestamps()
            del os.environ['DISPLAY']
            run_server('Hello.xml', 'HelloWorld.tgz')
            with trapped_exit(1):
                dl = app.download_selections(
                    app.get_selections(may_update=True))
                assert dl == None
            assert not ran_gui  # (so doesn't actually update)

            self.assertNotEqual(1, os.stat(timestamp).st_mtime)
            self.assertNotEqual(1, os.stat(selections_path).st_mtime)
            kill_server_process()

            sels = app.get_selections()
            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')
            with trapped_exit(1):
                #import logging; logging.getLogger().setLevel(logging.INFO)
                dl = app.download_selections(
                    app.get_selections(may_update=True))
                assert dl == None
            assert ran_gui
            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))
            dl = app.download_selections(app.get_selections(may_update=True))
            assert dl == None
            assert not ran_gui